UNPKG

@babblevoice/projectrtp

Version:
185 lines (165 loc) 8.89 kB
const fs = require( "fs" ) /** * Formats number as hex * @ignore * @param { number } d * @returns { string } */ function toHex( d ) { return ( "0" + ( Number( d ).toString( 16 ) ) ).slice( -2 ).toUpperCase() } /** * * @param { string } file * @param { number } maxnumberofpackets * @returns { Promise< Array< object > > } */ // For now disable - this is only used in test. // eslint-disable-next-line complexity module.exports.readpcap = async ( file, maxnumberofpackets = 5000 ) => { /* Buffer */ const data = fs.readFileSync( file ) if( !data ) return let fileposition = 0 let ts_sec = 0 let ts_usec = 0 let ts_firstether = -1 let frame = 0 const ipv4hosts = [] const etherframes = [] // Do we need version info for now? //var uint16array = new Uint16Array(data) /* Magic number */ /* if ( 2712847316 == data.readUInt32LE( 0 ) ) { // Native byte order console.log( "Native byte order" ) } else if ( 3569595041 == data.readUInt32LE( 0 ) ) { // Swapped byte order console.log( "Swapped byte order" ) } else if ( 2712812621 == data.readUInt32LE( 0 ) ) { // Native byte order nano second timing console.log( "Native byte order nano second timing" ) } else if ( 1295823521 == data.readUInt32LE( 0 ) ) { // Swapped byte order nano second timing console.log( "Swapped byte order nano second timing" ) } */ /* http://www.tcpdump.org/linktypes.html */ if ( 1 != data.readUInt32LE( 5 * 4 ) ) { console.error( "Link layer should be LINKTYPE_ETHERNET" ) return } //console.log( "LINKTYPE_ETHERNET" ) /* Read our first packet header */ fileposition += 24 for( let i = 0; i < maxnumberofpackets; i ++ ) { /* read packet header */ ts_sec = data.readUInt32LE( fileposition ) ts_usec = data.readUInt32LE( 4 + fileposition ) const incl_len = data.readUInt32LE( 12 + fileposition ) //var orig_len fileposition += 16 if ( 0 == incl_len ) { continue } const etherpacket = {} etherpacket.frame = frame frame++ etherpacket.ts_sec = ts_sec + ( ts_usec / 1000000 ) if ( -1 == ts_firstether ) { ts_firstether = etherpacket.ts_sec } etherpacket.ts_sec_offset = ( ts_sec + ( ts_usec / 1000000 ) ) - ts_firstether //etherpacket.ts_usec = ts_usec etherpacket.src = "" + toHex( data.readUInt8( fileposition ) ) + ":" + toHex( data.readUInt8( fileposition + 1 ) ) + ":" + toHex( data.readUInt8( fileposition + 2 ) ) + ":" + toHex( data.readUInt8( fileposition + 3 ) ) + ":" + toHex( data.readUInt8( fileposition + 4 ) ) + ":" + toHex( data.readUInt8( fileposition + 5 ) ) etherpacket.dst = "" + toHex( data.readUInt8( fileposition + 6 ) ) + ":" + toHex( data.readUInt8( fileposition + 7 ) ) + ":" + toHex( data.readUInt8( fileposition + 8 ) ) + ":" + toHex( data.readUInt8( fileposition + 9 ) ) + ":" + toHex( data.readUInt8( fileposition + 10 ) ) + ":" + toHex( data.readUInt8( fileposition + 11 ) ) etherpacket.ethertype = "" + toHex( data.readUInt8( fileposition + 12 ) ) + toHex( data.readUInt8( fileposition + 13 ) ) if ( 1536 < parseInt( etherpacket.ethertype, 16 ) ) { let hostid // Ref: https://en.wikipedia.org/wiki/EtherType switch ( etherpacket.ethertype ) { case "0800": /* IPV4 */ etherpacket.ipv4 = {} etherpacket.ipv4.data = data.subarray( fileposition + 14, fileposition + 14 + incl_len )//uint8array.slice( 14, uint8array.length ) etherpacket.ipv4.version = parseInt( toHex( ( etherpacket.ipv4.data[ 0 ] >> 4 ) & 0xf ), 16 ) etherpacket.ipv4.ihl = parseInt( toHex( etherpacket.ipv4.data[ 0 ] & 0xf ), 16 ) etherpacket.ipv4.dscp = toHex( ( etherpacket.ipv4.data[ 1 ] >> 2 ) & 0x3f ) etherpacket.ipv4.ecn = toHex( etherpacket.ipv4.data[ 1 ] & 0x3 ) etherpacket.ipv4.totallength = parseInt( toHex( etherpacket.ipv4.data[ 2 ] ) + toHex( etherpacket.ipv4.data[ 3 ] ), 16 ) etherpacket.ipv4.identification = parseInt( toHex( etherpacket.ipv4.data[ 4 ] ) + toHex( etherpacket.ipv4.data[ 5 ] ), 16 ) etherpacket.ipv4.flags = toHex( ( etherpacket.ipv4.data[ 6 ] >> 5 ) & 7 ) etherpacket.ipv4.fragmentoffset = "" + toHex( etherpacket.ipv4.data[ 6 ] & 0x1f ) + toHex( etherpacket.ipv4.data[ 7 ] ) etherpacket.ipv4.ttl = etherpacket.ipv4.data[ 8 ] etherpacket.ipv4.protocol = etherpacket.ipv4.data[ 9 ] etherpacket.ipv4.checksum = "" + toHex( etherpacket.ipv4.data[ 10 ] ) + toHex( etherpacket.ipv4.data[ 11 ] ) etherpacket.ipv4.src = "" + etherpacket.ipv4.data[ 12 ] + "." + etherpacket.ipv4.data[ 13 ] + "." + etherpacket.ipv4.data[ 14 ] + "." + etherpacket.ipv4.data[ 15 ] etherpacket.ipv4.dst = "" + etherpacket.ipv4.data[ 16 ] + "." + etherpacket.ipv4.data[ 17 ] + "." + etherpacket.ipv4.data[ 18 ] + "." + etherpacket.ipv4.data[ 19 ] hostid = -1 if ( -1 == ( hostid = ipv4hosts.indexOf( etherpacket.ipv4.src ) ) ) { etherpacket.ipv4.srchostid = ipv4hosts.length ipv4hosts.push( etherpacket.ipv4.src ) } else { etherpacket.ipv4.srchostid = hostid } if ( -1 == ( hostid = ipv4hosts.indexOf( etherpacket.ipv4.dst ) ) ) { etherpacket.ipv4.dsthostid = ipv4hosts.length ipv4hosts.push( etherpacket.ipv4.dst ) } else { etherpacket.ipv4.dsthostid = hostid } switch ( etherpacket.ipv4.protocol ) { case 17: /* UDP */ etherpacket.ipv4.udp = {} etherpacket.ipv4.udp.srcport = parseInt( toHex( etherpacket.ipv4.data[ 20 ] ) + toHex( etherpacket.ipv4.data[ 21 ] ), 16 ) etherpacket.ipv4.udp.dstport = parseInt( toHex( etherpacket.ipv4.data[ 22 ] ) + toHex( etherpacket.ipv4.data[ 23 ] ), 16 ) etherpacket.ipv4.udp.length = parseInt( toHex( etherpacket.ipv4.data[ 24 ] ) + toHex( etherpacket.ipv4.data[ 25 ] ), 16 ) - /* udp header */ 8 etherpacket.ipv4.udp.checksum = parseInt( toHex( etherpacket.ipv4.data[ 26 ] ) + toHex( etherpacket.ipv4.data[ 27 ] ), 16 ) etherpacket.ipv4.udp.data = etherpacket.ipv4.data.subarray( 28, 28 + etherpacket.ipv4.udp.length ) break case 6: /* TCP */ etherpacket.ipv4.tcp = {} etherpacket.ipv4.tcp.srcport = parseInt( toHex( etherpacket.ipv4.data[ 20 ] ) + toHex( etherpacket.ipv4.data[ 21 ] ), 16 ) etherpacket.ipv4.tcp.dstport = parseInt( toHex( etherpacket.ipv4.data[ 22 ] ) + toHex( etherpacket.ipv4.data[ 23 ] ), 16 ) etherpacket.ipv4.tcp.sequencenumber = parseInt( toHex( etherpacket.ipv4.data[ 24 ] ) + toHex( etherpacket.ipv4.data[ 25 ] ) + toHex( etherpacket.ipv4.data[ 26 ] ) + toHex( etherpacket.ipv4.data[ 27 ] ), 16 ) etherpacket.ipv4.tcp.acknowledgmentnumber = parseInt( toHex( etherpacket.ipv4.data[ 28 ] ) + toHex( etherpacket.ipv4.data[ 29 ] ) + toHex( etherpacket.ipv4.data[ 30 ] ) + toHex( etherpacket.ipv4.data[ 31 ] ), 16 ) etherpacket.ipv4.tcp.dataoffset = ( etherpacket.ipv4.data[ 32 ] >> 4 ) & 0xf etherpacket.ipv4.tcp.flags = {} etherpacket.ipv4.tcp.flags.ns = etherpacket.ipv4.data[ 32 ] & 1 etherpacket.ipv4.tcp.flags.cwr = ( etherpacket.ipv4.data[ 33 ] >> 7 ) & 1 etherpacket.ipv4.tcp.flags.ece = ( etherpacket.ipv4.data[ 33 ] >> 6 ) & 1 etherpacket.ipv4.tcp.flags.urg = ( etherpacket.ipv4.data[ 33 ] >> 5 ) & 1 etherpacket.ipv4.tcp.flags.ack = ( etherpacket.ipv4.data[ 33 ] >> 4 ) & 1 etherpacket.ipv4.tcp.flags.psh = ( etherpacket.ipv4.data[ 33 ] >> 3 ) & 1 etherpacket.ipv4.tcp.flags.rst = ( etherpacket.ipv4.data[ 33 ] >> 2 ) & 1 etherpacket.ipv4.tcp.flags.syn = ( etherpacket.ipv4.data[ 33 ] >> 1 ) & 1 etherpacket.ipv4.tcp.flags.fin = etherpacket.ipv4.data[ 33 ] & 1 etherpacket.ipv4.tcp.windowsize = parseInt( toHex( etherpacket.ipv4.data[ 34 ] ) + toHex( etherpacket.ipv4.data[ 35 ] ), 16 ) etherpacket.ipv4.tcp.checksum = parseInt( toHex( etherpacket.ipv4.data[ 36 ] ) + toHex( etherpacket.ipv4.data[ 37 ] ), 16 ) etherpacket.ipv4.tcp.urgentpointer = parseInt( toHex( etherpacket.ipv4.data[ 38 ] ) + toHex( etherpacket.ipv4.data[ 39 ] ), 16 ) etherpacket.ipv4.tcp.data = etherpacket.ipv4.data.subarray( 20 + ( etherpacket.ipv4.tcp.dataoffset * 4 ), 20 + ( etherpacket.ipv4.tcp.dataoffset * 4 ) + etherpacket.ipv4.data.length ) break } break case "86DD": /* IPV6 */ break case "0806": /* ARP */ break case "9100": /* VLAN tagged */ break } } else { // We probbaly won't need this as is raw length. } etherframes.push( etherpacket ) fileposition += incl_len if( fileposition >= data.length ) break } return etherframes }