Skip to content

Commit

Permalink
fix: TCP packets in PCAP
Browse files Browse the repository at this point in the history
1
  • Loading branch information
AlexeyOplachko committed Mar 25, 2024
1 parent 3bc21b2 commit cfb9c37
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 22 deletions.
55 changes: 40 additions & 15 deletions src/components/SimplePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { Buffer } from 'buffer'
const ip = packets.ipPacket
const udp = packets.udpPacket
const tcp = packets.tcpPacket
const ethernet = packets.ethernetPacket


import {
Button,
Expand Down Expand Up @@ -215,7 +217,9 @@ function formattingDataAndSortIt(data: any, sortType = 'none') {

}


interface Labels {
[key: string]: string
}


export const SimplePanel: React.FC<Props> = ({ options, data, width, height }: any) => {
Expand Down Expand Up @@ -274,17 +278,25 @@ export const SimplePanel: React.FC<Props> = ({ options, data, width, height }: a
const [serie]: any = (data as any)?.series || [];
const fields = serie?.fields || [];
const lineField = fields.find((i: any) => i.name === 'Line') ?? [];
const packets2 = lineField?.values.map((field: string, index: number) => {

const labels = fields[0]?.values[index]
const values = fields[0]?.values.map((item: any, index: number) => {
item.line = lineField?.values[index];
return item
}).filter((packet: any) => packet.type === 'sip')
const sequenceMap = new Map<string, number>();
const ipv4_regex = /(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}/;
const packets2 = values.sort((a: any, b: any) => {
return a.timestamp - b.timestamp
}).map((labels: Labels, index: number) => {
let line = labels.line
let proto = ''
if (field.includes('UDP')) {
line = line?.replace('UDP', 'TCP')
if (line.includes('UDP')) {
proto += "UDP"
} else if (field.includes('TCP')) {
} else if (line.includes('TCP')) {
proto += "TCP"
}
const fieldObj = {
data: field,
data: line,
srcIp: labels.src_ip,
dstIp: labels.dst_ip,
srcPort: labels.src_port,
Expand All @@ -296,19 +308,25 @@ export const SimplePanel: React.FC<Props> = ({ options, data, width, height }: a
flowLabel: 0,
nextHeader: proto === 'UDP' ? 17 : 6
}
const ipv4_regex = /^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}$/gm;

const hash = `${fieldObj.srcIp}:${fieldObj.srcPort}->${fieldObj.dstIp}:${fieldObj.dstPort}`
const sequence = sequenceMap.get(hash) ?? 1
const packet_data = proto === 'UDP' ? udp.encode({
sourcePort: fieldObj.srcPort,
destinationPort: fieldObj.dstPort,
data: Buffer.from(fieldObj.data)
data: Buffer.from(line)
}) : tcp.encode({
sourcePort: fieldObj.srcPort,
destinationPort: fieldObj.dstPort,
data: Buffer.from(fieldObj.data)
data: Buffer.from(line),
sequenceNumber: sequence,
acknowledgmentNumber: 0,
ack: true,
psh: true,
syn: false,
})

let ip_packet = ip.encode({
version: ipv4_regex.test(fieldObj.srcIp) ? 4 : 6,
version: ipv4_regex.test(fieldObj.dstIp) ? 4 : 6,
protocol: fieldObj.proto,
sourceIp: fieldObj.srcIp,
destinationIp: fieldObj.dstIp,
Expand All @@ -318,13 +336,20 @@ export const SimplePanel: React.FC<Props> = ({ options, data, width, height }: a
trafficClass: fieldObj.trafficClass,
flowLabel: fieldObj.flowLabel
})
let ethernetPacket = ethernet.encode({
data: ip_packet,
type: ipv4_regex.test(fieldObj.dstIp) ? '0800' : '86dd'
})
if (proto === 'TCP') {
sequenceMap.set(hash, (sequenceMap.get(hash) ?? 1) + Buffer.from(line).length)
}
return {
timestamp: fieldObj.ts,
buffer: ip_packet,
buffer: ethernetPacket,
type: fields[0]?.values[index]?.type
}
}).filter((packet: any) => packet.type === 'sip')
const generator = configure({ Buffer: Buffer })
})
const generator = configure({ Buffer: Buffer, snapshotLength: 102400, linkLayerType: 1 })
const pcapFile = generator(packets2)
const blob = new Blob([pcapFile], { type: 'application/vnd.tcpdump.pcap' });
// // Create element with <a> tag
Expand Down
73 changes: 66 additions & 7 deletions src/libs/packets.js
Original file line number Diff line number Diff line change
Expand Up @@ -2028,9 +2028,10 @@
module.exports = {
'ipPacket': require('./ip-packet'),
'udpPacket': require('./udp-packet'),
'tcpPacket': require('./tcp-packet')
'tcpPacket': require('./tcp-packet'),
'ethernetPacket': require('./ethernet-packet')
}
}, { "./ip-packet": 5, "./tcp-packet": 6, "./udp-packet": 7 }], 5: [function (require, module, exports) {
}, { "./ip-packet": 5, "./tcp-packet": 6, "./udp-packet": 7, "./ethernet-packet": 8 }], 5: [function (require, module, exports) {
(function (Buffer) {
(function () {
module.exports = configure({})
Expand Down Expand Up @@ -2061,7 +2062,7 @@
buf.writeUInt32BE(packet.version << 28 | (packet.trafficClass << 20) | packet.flowLabel, offset);
buf.writeUInt16BE(packet.data.length, offset + 4);
buf[offset + 6] = packet.nextHeader;
buf[offset + 7] = packet.hopLimit;
buf[offset + 7] = packet.hopLimit || 64;
const sourceIpBuffer = Buffer.from(packet.sourceIp);
const destinationIpBuffer = Buffer.from(packet.destinationIp);

Expand Down Expand Up @@ -2158,16 +2159,56 @@
(function () {
exports.encode = encode
exports.decode = decode

function encode({ data, sourcePort, destinationPort, sequenceNumber = 0, acknowledgmentNumber = 0 }) {
function tcpChecksum(packet, buf) {
// pseudo header: srcip (16), dstip (16), 0 (8), proto (8), udp len (16)
let len = buf.length
let srcip = packet.sourceIp
let dstip = packet.destinationIp
if (!srcip || !dstip) { return 0xffff }
let protocol = packet.protocol === undefined ? 0x11 : packet.protocol
let sum = 0xffff
// pseudo header: srcip (16), dstip (16), 0 (8), proto (8), udp len (16)
if (srcip && dstip) {
if (typeof srcip === 'string') { srcip = Buffer.from(srcip.split('.')) }
if (typeof dstip === 'string') { dstip = Buffer.from(dstip.split('.')) }
sum = 0
let pad = len % 2
for (let i = 0; i < len + pad; i += 2) {
if (i === 6) { continue } // ignore the currently written checksum
sum += ((buf[i] << 8) & 0xff00) + ((buf[i + 1]) & 0xff)
}
for (let i = 0; i < 4; i += 2) {
sum += ((srcip[i] << 8) & 0xff00) + (srcip[i + 1] & 0xff)
}
for (let i = 0; i < 4; i += 2) {
sum += ((dstip[i] << 8) & 0xff00) + (dstip[i + 1] & 0xff)
}
sum += protocol + len
while (sum >> 16) {
sum = (sum & 0xffff) + (sum >> 16)
}
sum = 0xffff ^ sum
}
return sum
}
function encode({ data, sourcePort, destinationPort, sequenceNumber = 0, acknowledgmentNumber = 0, ack = false, psh = false, syn = false }) {
const dataLength = data ? data.length : 0
const packet = Buffer.alloc(dataLength)
const packet = Buffer.alloc(dataLength + 20)
packet.writeUInt16BE(sourcePort, 0)
packet.writeUInt16BE(destinationPort, 2)
packet.writeUInt32BE(sequenceNumber, 4)
packet.writeUInt32BE(acknowledgmentNumber, 8)
packet.writeUInt16BE(0x5000, 12)
packet.writeUInt16BE(((20 / 4) << 12), 12);
const setAck = (ack) ? (1 << 4) : (0 << 4)
const setPsh = (psh) ? (1 << 3) : (0 << 3)
const setSyn = (syn) ? (1 << 1) : (0 << 1)
const flags = setSyn | setPsh | setAck
packet.writeUInt8(flags, 13);
packet.writeUInt16BE(8235, 14);
packet.writeUInt16BE(0, 16);
if (data) { data.copy(packet, 20) }
const checksum = tcpChecksum(data, packet);
packet.writeUInt16BE(checksum, 16)
return packet
}

Expand Down Expand Up @@ -2264,6 +2305,24 @@

}).call(this)
}).call(this, require("buffer").Buffer)
}, { "buffer": 2 }], 8: [function (require, module, exports) {
(function (Buffer) {
(function () {
exports.encode = encodeEthernetFrame
function encodeEthernetFrame({ destinationMac = '11:22:33:44:55:66', sourceMac = 'aa:bb:cc:dd:ee:ff', type, data }) {
const ethernetFrameLength = 14; // Length of Ethernet frame header
const totalLength = ethernetFrameLength + data.length;
const frame = Buffer.alloc(totalLength);

destinationMac.split(':').forEach((byte, index) => frame.writeUInt8(parseInt(byte, 16), index));
sourceMac.split(':').forEach((byte, index) => frame.writeUInt8(parseInt(byte, 16), index + 6));
frame.writeUInt16BE(parseInt(type, 16), 12); // EtherType
data.copy(frame, ethernetFrameLength); // Copy payload to frame

return frame;
}
}).call(this)
}).call(this, require("buffer").Buffer)
}, { "buffer": 2 }]
}, {}, [4])(4)
});

0 comments on commit cfb9c37

Please sign in to comment.