hepgen.js
Version:
HEP Message Generator
201 lines (181 loc) • 6.23 kB
JavaScript
/* PCAP TEXT to HEPGEN Convertor */
/* Modules import */
const os = require('os');
const fs = require('fs');
var args = process.argv.slice(2);
const parSIP = require('parsip');
const debug = false;
if (!args || !args[0]) {
if(debug)console.log('{}');
process.exit(1);
}
var cache = { previous: { time_sec:0, time_usec:0 } };
var net_regex = /([A-Z]+) ([0-9]+-[0-9]+-[0-9]+)T[0-9]+:[0-9]+:([0-9]+).([0-9]+)(.*)\s([0-9]+.[0-9]+.[0-9]+.[0-9]+):([0-9]+)(.*)\s([0-9]+.[0-9]+.[0-9]+.[0-9]+):([0-9]+)/i
var callids = [];
if(debug)console.log('Reading SIP from file: ',args[0] );
/* Moved to Async Sugar */
var fileContent = new Promise((res, rej) => {
//promisify readFile
fs.readFile(args[0], 'utf8', (err, contents)=>{
if(debug)console.log('read file about to resolve', err, contents.length);
if(err) {
rej(err);
return;
}
if(contents){
if(debug)console.log('resolving content');
res(contents);
return;
}
})
})
fileContent.then(handleContent).catch(handleError);
async function handleContent (contents) {
if(debug)console.log('handler Content called -----------------');
var parsed = contents.split('proto:');
//console.log('parsed array of promises?', parsed, parsed.length);
var messages = [];
for(let key in parsed) {
//console.log('trying row', key, parsed[key]);
try{
let msg = await handleRow(parsed[key])
messages.push(msg)
} catch (err) {
console.log('caught in promise', err)
}
}
var config = {
NAME: 'HEPGEN '+args[0],
HEP_SERVER: '127.0.0.1',
HEP_PORT: 9060,
HEP_ID: '2001',
HEP_AUTH: 'myHep',
// the Messages to send
MESSAGES: messages
};
var output = "/* HEPGEN Autogenerated from file => " + args[0] + " */\r\n"
output += 'var config = { \r\n';
for(let key of Object.keys(config)) {
console.log(key, key !== "MESSAGES")
if(key !== "MESSAGES"){
if(typeof config[key] == 'string') {
output += ' ' + key + ":" + '"' + config[key] + '",\r\n'
} else {
output += ' ' + key + ":" + config[key] + ",\r\n"
}
}
}
output += " MESSAGES: [ \r\n"
for(let item of config["MESSAGES"]) {
output += ' '
output += item
output += ',\r\n'
}
output += " ]\r\n};\r\n"
output += "module.exports = config;"
if(debug)console.log('writing to file',output);
fs.writeFile(args[1], output, console.log)
}
function handleError (err) {
throw err;
}
/* function to handle each SIP Row / Message */
async function handleRow (row) {
if(debug)console.log('handling row');
return new Promise(function (res, rej) {
if(debug)console.log('IN PROMISE');
var detectedEOL = '\r\n';
var detect = row.split(/[0-9]\n|[a-z]\n/);
if(detect.length > 1){detectedEOL = '\n'}
if(debug)console.log('detected following EOL in file', JSON.stringify(detectedEOL))
var tmp = row.split(/---> [0-9]+.[0-9]+.[0-9]+.[0-9]+:[0-9]+\r\n\r\n|---> [0-9]+.[0-9]+.[0-9]+.[0-9]+:[0-9]+\n\n/);
//if(debug)console.log('temp', tmp);
var match = [];
if (!tmp[1] || !row ) {
if(debug)console.log('stopped it', !tmp[1], !row);
rej('error');
}
else {
if(debug)console.log('parsing')
var rawSIP = tmp[1].split(detectedEOL).join('\r\n');
var mSIP = parSIP.getSIP( rawSIP );
//console.log(mSIP, '-----------------');
// Replace Session Identifiers need to be unique
if (mSIP) {
if (mSIP.call_id) {
if (!callids[mSIP.call_id]) { callids[mSIP.call_id] = Math.random().toString(36).substring(8) + mSIP.call_id }
if(debug)console.log('replacing call_id',mSIP.call_id, callids[mSIP.call_id]);
rawSIP = rawSIP.split(mSIP.call_id).join(callids[mSIP.call_id]);
};
if (mSIP.via_branch) {
if (!callids[mSIP.via_branch]) { callids[mSIP.via_branch] = Math.random().toString(36).substring(8) + mSIP.via_branch }
if(debug)console.log('replacing via_branch',mSIP.via_branch, callids[mSIP.via_branch]);
rawSIP = rawSIP.split(mSIP.via_branch).join(callids[mSIP.via_branch])
};
if (mSIP.from_tag) {
if (!callids[mSIP.from_tag]) { callids[mSIP.from_tag] = Math.random().toString(36).substring(8) + mSIP.from_tag }
if(debug)console.log('replacing from_tag',mSIP.from_tag, callids[mSIP.from_tag]);
rawSIP = rawSIP.split(mSIP.from_tag).join(callids[mSIP.from_tag])
};
if (mSIP.to_tag) {
if (!callids[mSIP.to_tag]) { callids[mSIP.to_tag] = Math.random().toString(36).substring(8) + mSIP.to_tag }
if(debug)console.log('replacing to_tag',mSIP.to_tag, callids[mSIP.to_tag]);
rawSIP = rawSIP.split(mSIP.to_tag).join(callids[mSIP.to_tag])
};
}
}
// create message block for configuration
if(debug)console.log('making a block from ', tmp[0]);
var block = row.replace(net_regex, function(match, proto, date, time, time_micro, unused, from_ip, from_port, divide, to_ip, to_port ) {
//console.log("args for replace", arguments);
time = parseInt(time); time_micro = parseInt(time_micro);
from_port = parseInt(from_port); to_port = parseInt(to_port);
var block = {
rcinfo: {
type: 'HEP',
version: 3,
//time_sec: (time),
//time_usec: (time_micro),
payload_type: 1,
captureId: '2001',
capturePass: 'myHep',
ip_family: 2,
protocol: proto === 'UDP' ? 17 : 6,
proto_type: 1,
srcIp: from_ip,
dstIp: to_ip,
srcPort: from_port,
dstPort: to_port
},
pause: parseInt(time - cache.previous.time_sec +''+ time_micro- cache.previous.time_usec) || 0,
payload: JSON.stringify(rawSIP || tmp[1])
};
cache.previous = { time_sec: time, time_usec: time_micro };
var string = '{\r\n';
for(let key of Object.keys(block)) {
if(key == 'rcinfo') {
string += ' rcinfo:{ \r\n'
for(let item2 of Object.keys(block.rcinfo)) {
string += ' ' + item2 + ":"
if(typeof block.rcinfo[item2] == 'string') {
string += '"' + block.rcinfo[item2] + '",\r\n'
} else {
string += block.rcinfo[item2] + ",\r\n"
}
}
string += ' },\r\n'
continue;
} else {
string += ' ' + key + ":" + block[key] + ",\r\n";
}
}
string += 'XXX'
return string;
});
var block = block.split('XXX')[0]
block += ' }'
if(debug)console.log('resolving', block);
res(block);
})
}