UNPKG

netkitty

Version:
498 lines (497 loc) 26.1 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.IPv6HopByHopOptions = 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 node_tlv_1 = __importDefault(require("node-tlv")); const HexToNumber_1 = require("../../helper/HexToNumber"); //Type=1 PadN //Type=4 Tunnel Encapsulation Limit //Type=5 Router Alert //Type=7 CALIPSO //Type=8 SMF_DPD //Type=11 MPL Option //Type=12 ILNP Nonce //Type=13 Line-Identification Option //Type=30 IPv6 DFF Header //Type=138 Endpoint Identification var Type; (function (Type) { Type["PadN"] = "PadN"; Type["Tunnel_Encapsulation_Limit"] = "Tunnel-Encapsulation-Limit"; Type["Router_Alert"] = "Router-Alert"; Type["CALIPSO"] = "CALIPSO"; Type["SMF_DPD"] = "SMF_DPD"; Type["MPL_Option"] = "MPL-Option"; Type["ILNP_Nonce"] = "ILNP-Nonce"; Type["Line_Identification_Option"] = "Line-Identification-Option"; Type["IPv6_DFF_Header"] = "IPv6-DFF-Header"; Type["Endpoint_Identification"] = "Endpoint-Identification"; })(Type || (Type = {})); class IPv6HopByHopOptions extends BaseHeader_1.BaseHeader { constructor() { super(...arguments); this.items = []; this.SCHEMA = { type: 'object', properties: { nxt: { type: 'integer', label: 'Next Header', minimum: 0, maximum: 255, decode: () => { this.instance.nxt.setValue((0, BufferToNumber_1.BufferToUInt8)(this.readBytes(0, 1))); }, encode: () => { const nxt = this.instance.nxt.getValue(0, (nodePath) => this.recordError(nodePath, 'Not Found')); this.instance.nxt.setValue(nxt); this.writeBytes(0, (0, NumberToBuffer_1.UInt8ToBuffer)(nxt)); } }, len: { type: 'integer', label: 'Length', minimum: 0, maximum: 255, decode: () => { this.instance.len.setValue((0, BufferToNumber_1.BufferToUInt8)(this.readBytes(1, 1))); }, encode: () => { const len = this.instance.len.getValue(0); this.instance.len.setValue(len); this.writeBytes(1, (0, NumberToBuffer_1.UInt8ToBuffer)(len)); if (!len) { this.addPostSelfEncodeHandler(() => { let rawLength = 0; this.itemTLVs .map(tlv => Buffer.from(tlv.getTLV(), 'hex').length) .forEach(itemLength => rawLength += itemLength); const calcLength = Math.floor(rawLength / 8); this.instance.len.setValue(calcLength); this.writeBytes(1, (0, NumberToBuffer_1.UInt8ToBuffer)(calcLength)); }); } } }, items: { type: 'array', label: 'Option Items', items: { anyOf: [ //Type=1 PadN { type: 'object', label: 'PadN', properties: { type: { type: 'string', label: 'Type', contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.UTF8, enum: [Type.PadN] }, n: { type: 'integer', label: 'N' } } }, //Type=4 Tunnel Encapsulation Limit { type: 'object', label: 'Tunnel Encapsulation Limit', properties: { type: { type: 'string', label: 'Type', contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.UTF8, enum: [Type.Tunnel_Encapsulation_Limit] }, limit: { type: 'integer', label: 'Limit', minimum: 1, maximum: 255 } } }, //Type=5 Router Alert { type: 'object', label: 'Router Alert', properties: { type: { type: 'string', label: 'Type', contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.UTF8, enum: [Type.Router_Alert] }, alert: { type: 'string', label: 'Router Alert', contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.HEX, minLength: 4, maxLength: 4 } } }, //Type=7 CALIPSO { type: 'object', label: 'CALIPSO', properties: { type: { type: 'string', label: 'Type', contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.UTF8, enum: [Type.CALIPSO] }, tag: { type: 'string', label: 'Tag', contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.HEX, minLength: 16, maxLength: 16 } } }, //Type=8 SMF_DPD { type: 'object', label: 'SMF_DPD', properties: { type: { type: 'string', label: 'Type', contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.UTF8, enum: [Type.SMF_DPD] }, hash: { type: 'string', label: 'Hash', contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.UTF8 } } }, //Type=11 MPL Option { type: 'object', label: 'MPL Option', properties: { type: { type: 'string', label: 'Type', contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.UTF8, enum: [Type.MPL_Option] }, value: { type: 'string', label: 'Value', contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.HEX } } }, //Type=12 ILNP Nonce { type: 'object', label: 'ILNP Nonce', properties: { type: { type: 'string', label: 'Type', contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.UTF8, enum: [Type.ILNP_Nonce] }, nonce: { type: 'string', label: 'Nonce', minLength: 12, maxLength: 12, contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.HEX } } }, //Type=13 Line-Identification Option { type: 'object', label: 'Line-Identification Option', properties: { type: { type: 'string', label: 'Type', contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.UTF8, enum: [Type.Line_Identification_Option] }, id: { type: 'string', label: 'Identity', minLength: 8, maxLength: 8, contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.HEX } } }, //Type=30 IPv6 DFF Header { type: 'object', label: 'IPv6 DFF Header', properties: { type: { type: 'string', label: 'Type', contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.UTF8, enum: [Type.IPv6_DFF_Header] }, message: { type: 'string', label: 'Message', contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.HEX } } }, //Type=138 Endpoint Identification { type: 'object', label: 'Endpoint Identification', properties: { type: { type: 'string', label: 'Type', contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.UTF8, enum: [Type.Endpoint_Identification] }, id: { type: 'string', label: 'Identity', minLength: 32, maxLength: 32, contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.HEX } } }, //Custom { type: 'object', label: 'Custom', properties: { type: { type: 'integer', label: 'Type' }, data: { type: 'string', label: 'Data', contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.HEX } } } ] }, decode: () => { let length = this.instance.len.getValue(0) * 8 + 7; while (!this.itemTLVs) { try { const itemTLVs = node_tlv_1.default.parseList(this.readBytes(2, length, true)); const joinedHex = itemTLVs.map(value => value.getTLV()).join(''); if (this.readBytes(2, length, true).toString('hex').padStart(length * 2, '0').toUpperCase() !== joinedHex.toUpperCase()) { length -= 1; if (!length) break; continue; } this.itemTLVs = node_tlv_1.default.parseList(this.readBytes(2, length)); } catch (e) { length -= 1; if (!length) break; } } this.itemTLVs.forEach((itemTLV) => { switch (itemTLV.getTag('number')) { case 0x01: { this.items.push({ type: Type.PadN, n: itemTLV.getLength('number') }); } break; case 0x04: { this.items.push({ type: Type.Tunnel_Encapsulation_Limit, limit: (0, HexToNumber_1.HexToUInt8)(itemTLV.getValue('hex')) }); } break; case 0x05: { this.items.push({ type: Type.Router_Alert, alert: itemTLV.getValue('hex') }); } break; case 0x07: { this.items.push({ type: Type.CALIPSO, tag: itemTLV.getValue('hex') }); } break; case 0x08: { this.items.push({ type: Type.SMF_DPD, hash: itemTLV.getValue('hex') }); } break; case 0x0B: { this.items.push({ type: Type.MPL_Option, value: itemTLV.getValue('hex') }); } break; case 0x0C: { this.items.push({ type: Type.ILNP_Nonce, nonce: itemTLV.getValue('hex') }); } break; case 0x0D: { this.items.push({ type: Type.Line_Identification_Option, id: itemTLV.getValue('hex') }); } break; case 0x1E: { this.items.push({ type: Type.IPv6_DFF_Header, message: itemTLV.getValue('hex') }); } break; case 0x8A: { this.items.push({ type: Type.Endpoint_Identification, id: itemTLV.getValue('hex') }); } break; default: { this.items.push({ type: itemTLV.getTag('number'), data: itemTLV.getValue('hex') }); } } }); this.instance.items.setValue(this.items.length ? this.items : []); }, encode: () => { this.items = this.instance.items.getValue([]); this.itemTLVs = []; this.items.forEach(item => { switch (item.type) { case Type.PadN: { const typedItem = { ...item }; this.itemTLVs.push(new node_tlv_1.default(0x01, Buffer.alloc(typedItem.n, 0))); } break; case Type.Tunnel_Encapsulation_Limit: { const typedItem = { ...item }; this.itemTLVs.push(new node_tlv_1.default(0x04, (0, NumberToBuffer_1.UInt8ToBuffer)(typedItem.limit))); } break; case Type.Router_Alert: { const typedItem = { ...item }; this.itemTLVs.push(new node_tlv_1.default(0x05, (0, NumberToBuffer_1.UInt16ToBuffer)((0, HexToNumber_1.HexToUInt16)(typedItem.alert)))); } break; case Type.CALIPSO: { const typedItem = { ...item }; this.itemTLVs.push(new node_tlv_1.default(0x07, (0, NumberToBuffer_1.UInt64ToBuffer)((0, HexToNumber_1.HexToUInt64)(typedItem.tag)))); } break; case Type.SMF_DPD: { const typedItem = { ...item }; this.itemTLVs.push(new node_tlv_1.default(0x08, Buffer.from(typedItem.hash, 'hex'))); } break; case Type.MPL_Option: { const typedItem = { ...item }; this.itemTLVs.push(new node_tlv_1.default(0x0B, Buffer.from(typedItem.value, 'hex'))); } break; case Type.ILNP_Nonce: { const typedItem = { ...item }; this.itemTLVs.push(new node_tlv_1.default(0x0C, Buffer.from(typedItem.nonce.padStart(12, '0'), 'hex'))); } break; case Type.Line_Identification_Option: { const typedItem = { ...item }; this.itemTLVs.push(new node_tlv_1.default(0x0D, (0, NumberToBuffer_1.UInt32ToBuffer)((0, HexToNumber_1.HexToUInt32)(typedItem.id)))); } break; case Type.IPv6_DFF_Header: { const typedItem = { ...item }; this.itemTLVs.push(new node_tlv_1.default(0x1E, Buffer.from(typedItem.message, 'hex'))); } break; case Type.Endpoint_Identification: { const typedItem = { ...item }; this.itemTLVs.push(new node_tlv_1.default(0x0C, Buffer.from(typedItem.id.padStart(32, '0'), 'hex'))); } break; default: { if (typeof item.type !== 'number') return; const customItem = { ...item }; this.itemTLVs.push(new node_tlv_1.default(customItem.type, Buffer.from(customItem.data, 'hex'))); } } }); const itemsBuffer = Buffer.from(this.itemTLVs.map(value => value.getTLV()).join(''), 'hex'); this.writeBytes(2, itemsBuffer); } } } }; this.id = 'ipv6-hopopt'; this.name = 'IPv6 Hop-by-Hop Option'; this.nickname = 'HopOpt'; this.isProtocol = false; } match() { if (!this.prevCodecModule || this.prevCodecModule.id !== 'ipv6') return false; return this.prevCodecModule.instance.nxt.getValue() === 0x00; } } exports.IPv6HopByHopOptions = IPv6HopByHopOptions;