blob: 5b0a7fcde2dfeb581c878fc4be3c38666753905b [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function readRawBytes(size, transit) {
var buffer = new Buffer(size);
var bytesRead = 0;
var bytesLeft, dataLeft, len, leftOver;
var data, offset;
while (bytesRead < size) {
if (!data || offset >= data.length) {
offset = 0;
data = transit.shift();
}
bytesLeft = size - bytesRead;
dataLeft = data.length - offset;
len = bytesLeft < dataLeft ? bytesLeft : dataLeft;
data.copy(buffer, bytesRead, offset, offset + len);
bytesRead += len;
offset += len;
}
if (offset < data.length) {
dataLeft = data.length - offset;
leftOver = new Buffer(dataLeft);
data.copy(leftOver, 0, offset, offset + dataLeft);
transit.unshift(leftOver);
}
return buffer;
}
exports = module.exports = function(app, config) {
var _ = require("lodash");
var fs = require("fs");
var spawn = require('child_process').spawn;
var querystring = require('querystring');
var XmlStream = require('xml-stream');
// Mock pcap service for use in development
if (config.pcap.mock) {
app.get('/sample/pcap/:command', function(req, res) {
res.sendfile('/vagrant/seed/hbot.pcap');
});
}
app.get('/pcap/:command', function(req, res) {
if (!req.user || !req.user.permissions.pcap) {
res.send(403, 'Forbidden!');
return;
}
var transit = [];
var pcapUrl = config.pcap.url + '/' + req.param('command');
pcapUrl += '?' + querystring.stringify(req.query);
var curl = spawn('curl', ['-s', pcapUrl]);
var tshark = spawn('tshark', ['-i', '-', '-T', 'pdml']);
var xml = new XmlStream(tshark.stdout);
xml.collect('proto');
xml.collect('field');
curl.stdout.pipe(tshark.stdin);
curl.stdout.on('data', function (data) {
transit.push(data);
});
var npcaps = 0;
xml.on('end', function() {
res.end(']}');
curl.stdout.unpipe(tshark.stdin);
curl.kill('SIGKILL');
tshark.kill('SIGKILL');
});
xml.on('endElement: packet', function(packet) {
var psize = parseInt(packet.proto[0].$.size);
if (!npcaps) {
res.set('Content-Type', 'application/json');
res.write('{objects: [\n');
// skip global header
readRawBytes(24, transit);
} else {
res.write(',\n');
}
// skip packet header
readRawBytes(16, transit);
packet.hexdump = readRawBytes(psize, transit).toString('hex');
res.write(JSON.stringify(packet));
npcaps++;
});
});
};