UNPKG

netkitty

Version:
193 lines (192 loc) 9.28 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.UDP = void 0; const BaseHeader_1 = require("../abstracts/BaseHeader"); const BufferToNumber_1 = require("../../helper/BufferToNumber"); const NumberToBuffer_1 = require("../../helper/NumberToBuffer"); const IPToBuffer_1 = require("../../helper/IPToBuffer"); class UDP extends BaseHeader_1.BaseHeader { constructor() { super(...arguments); this.SCHEMA = { type: 'object', properties: { srcport: { type: 'integer', label: 'Source Port', minimum: 0, maximum: 65535, decode: () => { this.instance.srcport.setValue((0, BufferToNumber_1.BufferToUInt16)(this.readBytes(0, 2))); }, encode: () => { let srcport = this.instance.srcport.getValue(0, (nodePath) => this.recordError(nodePath, 'Not Found')); if (srcport > 65535) { this.recordError(this.instance.srcport.getPath(), 'Maximum value is 65535'); srcport = 65535; } if (srcport < 0) { this.recordError(this.instance.srcport.getPath(), 'Minimum value is 0'); srcport = 0; } this.instance.srcport.setValue(srcport); this.writeBytes(0, (0, NumberToBuffer_1.UInt16ToBuffer)(srcport)); } }, dstport: { type: 'integer', label: 'Destination Port', minimum: 0, maximum: 65535, decode: () => { this.instance.dstport.setValue((0, BufferToNumber_1.BufferToUInt16)(this.readBytes(2, 2))); }, encode: () => { let dstport = this.instance.dstport.getValue(0, (nodePath) => this.recordError(nodePath, 'Not Found')); if (dstport > 65535) { this.recordError(this.instance.dstport.getPath(), 'Maximum value is 65535'); dstport = 65535; } if (dstport < 0) { this.recordError(this.instance.dstport.getPath(), 'Minimum value is 0'); dstport = 0; } this.instance.dstport.setValue(dstport); this.writeBytes(2, (0, NumberToBuffer_1.UInt16ToBuffer)(dstport)); } }, length: { type: 'integer', label: 'Length', minimum: 0, maximum: 65535, decode: () => { this.instance.length.setValue((0, BufferToNumber_1.BufferToUInt16)(this.readBytes(4, 2))); }, encode: () => { let length = this.instance.length.getValue(0); if (length) { this.instance.length.setValue(length); this.writeBytes(4, (0, NumberToBuffer_1.UInt16ToBuffer)(length)); } else { this.instance.length.setValue(length); this.writeBytes(4, (0, NumberToBuffer_1.UInt16ToBuffer)(length)); this.addPostPacketEncodeHandler(() => { let startCount = false; let udpLength = 0; this.codecModules.forEach((codecModule) => { if (codecModule === this) startCount = true; if (startCount) udpLength += codecModule.length; }); this.instance.length.setValue(udpLength); this.writeBytes(4, (0, NumberToBuffer_1.UInt16ToBuffer)(udpLength)); }, 1); } } }, checksum: { type: 'integer', label: 'Checksum', minimum: 0, maximum: 65535, decode: () => { this.instance.checksum.setValue((0, BufferToNumber_1.BufferToUInt16)(this.readBytes(6, 2))); }, encode: () => { const checksum = this.instance.checksum.getValue(0); if (checksum) { this.instance.checksum.setValue(checksum); this.writeBytes(6, (0, NumberToBuffer_1.UInt16ToBuffer)(checksum)); } else { this.writeBytes(6, (0, NumberToBuffer_1.UInt16ToBuffer)(checksum)); this.instance.checksum.setValue(checksum); this.addPostPacketEncodeHandler(() => { let startCount = false; let udpHeaderWithDataLength = 0; this.codecModules.forEach((codecModule) => { if (codecModule === this) startCount = true; if (startCount) udpHeaderWithDataLength += codecModule.length; }); const calcChecksum = this.calculateUDPChecksum(this.packet.subarray(this.startPos, this.startPos + udpHeaderWithDataLength)); this.instance.checksum.setValue(calcChecksum); this.writeBytes(6, (0, NumberToBuffer_1.UInt16ToBuffer)(calcChecksum)); }, 2); } } } } }; this.id = 'udp'; this.name = 'User Datagram Protocol'; this.nickname = 'UDP'; } /** * Calculate UDP Checksum * @protected * @param udpHeaderBuffer */ calculateUDPChecksum(udpHeaderBuffer) { const udpHeaderLength = udpHeaderBuffer.length; const ipVersion = this.prevCodecModule.instance.version.getValue(); let pseudoHeaderBuffer = Buffer.from([]); const sourceIp = this.prevCodecModule.instance.sip.getValue(); const destinationIp = this.prevCodecModule.instance.dip.getValue(); if (ipVersion === 4) { //4 Bytes const sourceIPv4Buffer = Buffer.from(sourceIp.split('.').map((value) => parseInt(value))); const destinationIPv4Buffer = Buffer.from(destinationIp.split('.').map((value) => parseInt(value))); //IPv4 Pseudo header pseudoHeaderBuffer = Buffer.concat([ sourceIPv4Buffer, destinationIPv4Buffer, (0, NumberToBuffer_1.UInt8ToBuffer)(0), //Reserved field (0, NumberToBuffer_1.UInt8ToBuffer)(17), //Protocol type (UDP = 17) Buffer.from([(udpHeaderLength >> 8) & 0xFF]), Buffer.from([udpHeaderLength & 0xFF]) ]); } else if (ipVersion === 6) { //16 Bytes const sourceIPv6Buffer = (0, IPToBuffer_1.IPv6ToBuffer)(sourceIp); const destinationIPv6Buffer = (0, IPToBuffer_1.IPv6ToBuffer)(destinationIp); //IPv6 Pseudo header pseudoHeaderBuffer = Buffer.concat([ sourceIPv6Buffer, destinationIPv6Buffer, (0, NumberToBuffer_1.UInt8ToBuffer)(0), //Reserved field (0, NumberToBuffer_1.UInt8ToBuffer)(0), //Reserved field (0, NumberToBuffer_1.UInt8ToBuffer)(0), //Reserved field (0, NumberToBuffer_1.UInt8ToBuffer)(17), //Protocol type (UDP = 17) Buffer.from([(udpHeaderLength >> 8) & 0xFF]), Buffer.from([udpHeaderLength & 0xFF]) ]); } else { return 0; } let dataBuffer = Buffer.concat([pseudoHeaderBuffer, udpHeaderBuffer]); if (dataBuffer.length % 2) dataBuffer = Buffer.concat([dataBuffer, Buffer.from('00', 'hex')]); const data = Uint8Array.from(dataBuffer); let sum = 0; for (let i = 0; i < data.length; i += 2) sum += (data[i] << 8) + (data[i + 1] || 0); while (sum > 0xFFFF) sum = (sum & 0xFFFF) + (sum >>> 16); return (~sum) & 0xFFFF; } match() { if (!this.prevCodecModule) return false; if (this.prevCodecModule.instance.protocol.getValue() === 0x11) return true; return false; } } exports.UDP = UDP;