netkitty
Version:
Network tools kit
498 lines (497 loc) • 26.1 kB
JavaScript
"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;