dns-packet-typescript
Version:
An abstract-encoding compliant module for encoding / decoding DNS packets
170 lines • 6.21 kB
JavaScript
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.encodingLength = exports.decode = exports.encode = void 0;
var optioncodes = require("./optioncodes");
var ip = require("ip");
function encode(option, buf, offset) {
var e_1, _a;
var _b, _c, _d, _e;
if (offset === void 0) { offset = 0; }
if (!buf) {
buf = Buffer.allocUnsafe(encodingLength(option));
}
if (!offset) {
offset = 0;
}
var oldOffset = offset;
var code = optioncodes.toCode(option.code);
buf.writeUInt16BE(code, offset);
offset += 2;
if (option.data) {
buf.writeUInt16BE(option.data.length, offset);
offset += 2;
option.data.copy(buf, offset);
offset += option.data.length;
}
else {
switch (code) {
// case 3: NSID. No encode makes sense.
// case 5,6,7: Not implementable
case 8: // ECS
// note: do IP math before calling
var spl = (_b = option.sourcePrefixLength) !== null && _b !== void 0 ? _b : 0;
var fam = (_c = option.family) !== null && _c !== void 0 ? _c : (ip.isV4Format(option.ip) ? 1 : 2);
var ipBuf = ip.toBuffer(option.ip);
var ipLen = Math.ceil(spl / 8);
buf.writeUInt16BE(ipLen + 4, offset);
offset += 2;
buf.writeUInt16BE(fam, offset);
offset += 2;
buf.writeUInt8(spl, offset++);
buf.writeUInt8((_d = option.scopePrefixLength) !== null && _d !== void 0 ? _d : 0, offset++);
ipBuf.copy(buf, offset, 0, ipLen);
offset += ipLen;
break;
// case 9: EXPIRE (experimental)
// case 10: COOKIE. No encode makes sense.
case 11: // KEEP-ALIVE
if (option.timeout) {
buf.writeUInt16BE(2, offset);
offset += 2;
buf.writeUInt16BE(option.timeout, offset);
offset += 2;
}
else {
buf.writeUInt16BE(0, offset);
offset += 2;
}
break;
case 12: // PADDING
var len = (_e = option.length) !== null && _e !== void 0 ? _e : 0;
buf.writeUInt16BE(len, offset);
offset += 2;
buf.fill(0, offset, offset + len);
offset += len;
break;
// case 13: CHAIN. Experimental.
case 14: // KEY-TAG
var tagsLen = option.tags.length * 2;
buf.writeUInt16BE(tagsLen, offset);
offset += 2;
try {
for (var _f = __values(option.tags), _g = _f.next(); !_g.done; _g = _f.next()) {
var tag = _g.value;
buf.writeUInt16BE(tag, offset);
offset += 2;
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_g && !_g.done && (_a = _f.return)) _a.call(_f);
}
finally { if (e_1) throw e_1.error; }
}
break;
default:
throw new Error("Unknown roption code: " + option.code);
}
}
encode.bytes = offset - oldOffset;
return buf;
}
exports.encode = encode;
;
encode.bytes = 0;
function decode(buf, offset) {
if (offset === void 0) { offset = 0; }
if (!offset) {
offset = 0;
}
var option = {};
option.code = buf.readUInt16BE(offset);
option.type = optioncodes.toString(option.code);
offset += 2;
var len = buf.readUInt16BE(offset);
offset += 2;
option.data = buf.slice(offset, offset + len);
switch (option.code) {
// case 3: NSID. No decode makes sense.
case 8: // ECS
option.family = buf.readUInt16BE(offset);
offset += 2;
option.sourcePrefixLength = buf.readUInt8(offset++);
option.scopePrefixLength = buf.readUInt8(offset++);
var padded = Buffer.alloc((option.family === 1) ? 4 : 16);
buf.copy(padded, 0, offset, offset + len - 4);
option.ip = ip.toString(padded);
break;
// case 12: Padding. No decode makes sense.
case 11: // KEEP-ALIVE
if (len > 0) {
option.timeout = buf.readUInt16BE(offset);
offset += 2;
}
break;
case 14:
option.tags = [];
for (var i = 0; i < len; i += 2) {
option.tags.push(buf.readUInt16BE(offset));
offset += 2;
}
// don't worry about default. caller will use data if desired
}
decode.bytes = len + 4;
return option;
}
exports.decode = decode;
decode.bytes = 0;
function encodingLength(option) {
var _a;
if (option.data) {
return option.data.length + 4;
}
var code = optioncodes.toCode(option.code);
switch (code) {
case 8: // ECS
var spl = (_a = option.sourcePrefixLength) !== null && _a !== void 0 ? _a : 0;
return Math.ceil(spl / 8) + 8;
case 11: // KEEP-ALIVE
return (typeof option.timeout === 'number') ? 6 : 4;
case 12: // PADDING
return option.length + 4;
case 14: // KEY-TAG
return 4 + (option.tags.length * 2);
}
throw new Error("Unknown roption code: " + option.code);
}
exports.encodingLength = encodingLength;
//# sourceMappingURL=roption.js.map
;