netkitty
Version:
Network tools kit
148 lines (147 loc) • 6.69 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ICMP = void 0;
const BaseHeader_1 = require("../abstracts/BaseHeader");
const BufferToNumber_1 = require("../../helper/BufferToNumber");
const NumberToBuffer_1 = require("../../helper/NumberToBuffer");
const StringContentEncodingEnum_1 = require("../lib/StringContentEncodingEnum");
const BufferToHex_1 = require("../../helper/BufferToHex");
class ICMP extends BaseHeader_1.BaseHeader {
constructor() {
super(...arguments);
this.SCHEMA = {
type: 'object',
properties: {
type: {
type: 'integer',
label: 'Type',
minimum: 0,
maximum: 255,
decode: () => {
this.instance.type.setValue((0, BufferToNumber_1.BufferToUInt8)(this.readBytes(0, 1)));
},
encode: () => {
const type = this.instance.type.getValue(0, (nodePath) => this.recordError(nodePath, 'Not Found'));
this.instance.type.setValue(type);
this.writeBytes(0, (0, NumberToBuffer_1.UInt8ToBuffer)(type));
}
},
code: {
type: 'integer',
label: 'Code',
minimum: 0,
maximum: 255,
decode: () => {
this.instance.code.setValue((0, BufferToNumber_1.BufferToUInt8)(this.readBytes(1, 1)));
},
encode: () => {
const code = this.instance.code.getValue(0, (nodePath) => this.recordError(nodePath, 'Not Found'));
this.instance.code.setValue(code);
this.writeBytes(1, (0, NumberToBuffer_1.UInt8ToBuffer)(code));
}
},
checksum: {
type: 'integer',
label: 'Checksum',
minimum: 0,
maximum: 65535,
decode: () => {
this.instance.checksum.setValue((0, BufferToNumber_1.BufferToUInt16)(this.readBytes(2, 2)));
},
encode: () => {
let checksum = this.instance.checksum.getValue(0);
this.instance.checksum.setValue(checksum);
this.writeBytes(2, (0, NumberToBuffer_1.UInt16ToBuffer)(checksum));
if (!checksum) {
checksum = this.calculateIcmpChecksum();
this.instance.checksum.setValue(checksum);
this.writeBytes(2, (0, NumberToBuffer_1.UInt16ToBuffer)(checksum));
}
}
},
ident: {
type: 'number',
label: 'Identifier (BE)',
minimum: 0,
maximum: 65535,
decode: () => {
this.instance.ident.setValue((0, BufferToNumber_1.BufferToUInt16)(this.readBytes(4, 2)));
},
encode: () => {
const ident = this.instance.ident.getValue(0, (nodePath) => this.recordError(nodePath, 'Not Found'));
this.instance.ident.setValue(ident);
this.writeBytes(4, (0, NumberToBuffer_1.UInt16ToBuffer)(ident));
}
},
seq: {
type: 'number',
label: 'Sequence Number (BE)',
minimum: 0,
maximum: 65535,
decode: () => {
this.instance.seq.setValue((0, BufferToNumber_1.BufferToUInt16)(this.readBytes(6, 2)));
},
encode: () => {
const seq = this.instance.seq.getValue(0, (nodePath) => this.recordError(nodePath, 'Not Found'));
this.instance.seq.setValue(seq);
this.writeBytes(6, (0, NumberToBuffer_1.UInt16ToBuffer)(seq));
}
},
message: {
type: 'string',
label: 'Message Body',
contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.HEX,
decode: () => {
const messageDataLength = this.packet.length - this.startPos - 8;
this.instance.message.setValue((0, BufferToHex_1.BufferToHex)(this.readBytes(8, messageDataLength)));
},
encode: () => {
const messageHex = this.instance.message.getValue('');
this.instance.message.setValue(messageHex);
this.writeBytes(8, Buffer.from(messageHex, 'hex'));
}
}
}
};
this.id = 'icmp';
this.name = 'Internet Control Message Protocol';
this.nickname = 'ICMP';
}
/**
* Calculate ICMPv4 checksum
* @protected
*/
calculateIcmpChecksum() {
const icmpHeader = Buffer.concat([
(0, NumberToBuffer_1.UInt8ToBuffer)(this.instance.type.getValue(0)),
(0, NumberToBuffer_1.UInt8ToBuffer)(this.instance.code.getValue(0)),
(0, NumberToBuffer_1.UInt16ToBuffer)(this.instance.checksum.getValue(0)),
(0, NumberToBuffer_1.UInt16ToBuffer)(this.instance.ident.getValue(0)),
(0, NumberToBuffer_1.UInt16ToBuffer)(this.instance.seq.getValue(0)),
Buffer.from(this.instance.message.getValue(''), 'hex')
]);
const paddedBuffer = icmpHeader.length % 2 === 1 ?
Buffer.concat([
icmpHeader,
(0, NumberToBuffer_1.UInt8ToBuffer)(0)
]) : icmpHeader;
// 4. 计算 checksum
let checksum = 0;
for (let i = 0; i < paddedBuffer.length; i += 2) {
const word = (paddedBuffer[i] << 8) | (paddedBuffer[i + 1] || 0);
checksum += word;
// 处理溢出
if (checksum > 0xFFFF) {
checksum = (checksum & 0xFFFF) + 1;
}
}
// 取反得到最终 checksum
return (~checksum) & 0xFFFF;
}
match() {
if (!this.prevCodecModule)
return false;
return this.prevCodecModule.instance.protocol.getValue() === 0x01;
}
}
exports.ICMP = ICMP;