UNPKG

netkitty

Version:
148 lines (147 loc) 6.69 kB
"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;