netkitty
Version:
Network tools kit
193 lines (192 loc) • 9.28 kB
JavaScript
"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;