ntp-packet-parser
Version:
A parser for NTP UDP packets
121 lines (120 loc) • 4.42 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.NtpPacketParser = void 0;
var NtpPacketParser = /** @class */ (function () {
function NtpPacketParser() {
}
Object.defineProperty(NtpPacketParser, "packetStruct", {
/**
* Returns the structure of the UDP packet for parsing
*/
get: function () {
var _this = this;
return [
{ name: "leapIndicator", bits: 2 },
{ name: "version", bits: 3 },
{ name: "mode", bits: 3 },
{ name: "stratum", bits: 8 },
{ name: "poll", bits: 8 },
{ name: "precision", bits: 8 },
{
name: "rootDelay",
bits: 32,
converter: NtpPacketParser._fromNtpTimestamp,
},
{
name: "rootDispersion",
bits: 32,
converter: NtpPacketParser._fromNtpTimestamp,
},
{
name: "referenceId",
bits: 32,
converter: function (value, packet) { return _this._ntpIdentifier(packet.stratum, value); },
},
{
name: "referenceTimestamp",
bits: 64,
converter: NtpPacketParser._fromNtpTimestamp,
},
{
name: "originTimestamp",
bits: 64,
converter: NtpPacketParser._fromNtpTimestamp,
},
{
name: "receiveTimestamp",
bits: 64,
converter: NtpPacketParser._fromNtpTimestamp,
},
{
name: "transmitTimestamp",
bits: 64,
converter: NtpPacketParser._fromNtpTimestamp,
},
];
},
enumerable: false,
configurable: true
});
/**
* Returns the selected bits in binary notation
*/
NtpPacketParser._getBits = function (msg, start, length) {
var bits = "";
var pad = "00000000";
for (var i = 0; i < msg.length; i++) {
var bitsUnpadded = (msg[i] >>> 0).toString(2);
bits += pad.substring(0, pad.length - bitsUnpadded.length) + bitsUnpadded;
}
return bits.slice(start, start + length);
};
/**
* Converts a NTP identifier from binary notation to ASCII
* @param {string} value Bits in binary notation
*/
NtpPacketParser._ntpIdentifier = function (stratum, value) {
if (stratum != 1) {
return parseInt(value, 2).toString();
}
var chars = [value.slice(0, 8), value.slice(8, 16), value.slice(16, 24), value.slice(24, 32)];
chars = chars.map(function (v) {
return String.fromCharCode(parseInt(v, 2));
});
return chars.join("").replace(/\0+$/, "");
};
/**
* Converts a NTP timestamp from binary notation to a Date object
* @param {string} value Bits in binary notation
*/
NtpPacketParser._fromNtpTimestamp = function (value) {
if (value.length % 2 !== 0) {
throw new Error("Invalid timestamp format, expected even number of characters");
}
var seconds = parseInt(value, 2) / Math.pow(2, value.length / 2), date = new Date("Jan 01 1900 GMT");
date.setUTCMilliseconds(date.getUTCMilliseconds() + seconds * 1000);
return date;
};
/**
* Parses an UDP packet buffer and returns a NtpPacket struct
*/
NtpPacketParser.parse = function (udpPacket) {
var data = {};
var offset = 0;
NtpPacketParser.packetStruct.forEach(function (struct) {
var baseRepresentation = NtpPacketParser._getBits(udpPacket, offset, struct.bits);
if (struct.converter) {
// @ts-ignore
data[struct.name] = struct.converter(baseRepresentation, data);
}
else {
// @ts-ignore
data[struct.name] = parseInt(baseRepresentation, 2);
}
offset += struct.bits;
});
return data;
};
return NtpPacketParser;
}());
exports.NtpPacketParser = NtpPacketParser;