ntp-packet-parser
Advanced tools
Comparing version 0.1.0 to 0.2.0
"use strict"; | ||
/** | ||
* @typedef {Object} NTPPacket | ||
* @property {int} leapIndicator | ||
* @property {int} version | ||
* @property {int} mode | ||
* @property {int} stratum | ||
* @property {int} poll | ||
* @property {int} precision | ||
* @property {Date} rootDelay | ||
* @property {Date} rootDispersion | ||
* @property {String} referenceId | ||
* @property {Date} referenceTimestamp | ||
* @property {Date} originTimestamp | ||
* @property {Date} receiveTimestamp | ||
* @property {Date} transmitTimestamp | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
var _createClass = (function() { | ||
function defineProperties(target, props) { | ||
for (var i = 0; i < props.length; i++) { | ||
var descriptor = props[i]; | ||
descriptor.enumerable = descriptor.enumerable || false; | ||
descriptor.configurable = true; | ||
if ("value" in descriptor) descriptor.writable = true; | ||
Object.defineProperty(target, descriptor.key, descriptor); | ||
} | ||
} | ||
return function(Constructor, protoProps, staticProps) { | ||
if (protoProps) defineProperties(Constructor.prototype, protoProps); | ||
if (staticProps) defineProperties(Constructor, staticProps); | ||
return Constructor; | ||
}; | ||
})(); | ||
function _classCallCheck(instance, Constructor) { | ||
if (!(instance instanceof Constructor)) { | ||
throw new TypeError("Cannot call a class as a function"); | ||
} | ||
} | ||
var NtpPacketParser = (function() { | ||
function NtpPacketParser() { | ||
_classCallCheck(this, NtpPacketParser); | ||
} | ||
_createClass(NtpPacketParser, null, [ | ||
{ | ||
key: "_getBits", | ||
/** | ||
* Returns the selected bits in binary notation | ||
* @param msg | ||
* @param {int} start | ||
* @param {int} length | ||
* @returns {string} Bits in binary notation | ||
* @private | ||
*/ | ||
value: function _getBits(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 {int} stratum | ||
* @param {String} value Bits in binary notation | ||
* @returns {string} | ||
* @private | ||
*/ | ||
}, | ||
{ | ||
key: "_ntpIdentifier", | ||
value: function _ntpIdentifier(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 | ||
* @returns {Date} | ||
* @private | ||
*/ | ||
}, | ||
{ | ||
key: "_fromNtpTimestamp", | ||
value: function _fromNtpTimestamp(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 | ||
* @param {Buffer} udpPacket | ||
* @returns {NTPPacket} | ||
*/ | ||
}, | ||
{ | ||
key: "parse", | ||
value: function parse(udpPacket) { | ||
var data = []; | ||
NtpPacketParser.packetStruct.forEach(function(item) { | ||
data[item.name] = undefined; | ||
}); | ||
var offset = 0; | ||
NtpPacketParser.packetStruct.forEach(function(item) { | ||
data[item.name] = NtpPacketParser._getBits( | ||
udpPacket, | ||
offset, | ||
item.bits | ||
); | ||
if (item.converter) { | ||
data[item.name] = item.converter(data[item.name], data); | ||
} else { | ||
data[item.name] = parseInt(data[item.name], 2); | ||
} | ||
offset += item.bits; | ||
}); | ||
return data; | ||
} | ||
}, | ||
{ | ||
key: "packetStruct", | ||
/** | ||
* Returns the structure of the UDP packet for parsing | ||
* @returns {Object} | ||
*/ | ||
get: function get() { | ||
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 converter(v, s) { | ||
return _this._ntpIdentifier(s.stratum, v); | ||
} | ||
}, | ||
{ | ||
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 | ||
} | ||
]; | ||
} | ||
} | ||
]); | ||
return NtpPacketParser; | ||
})(); | ||
exports.default = NtpPacketParser; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
__exportStar(require("./NtpPacketParser"), exports); | ||
__exportStar(require("./NtpPacket"), exports); | ||
__exportStar(require("./PacketStruct"), exports); |
{ | ||
"name": "ntp-packet-parser", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"description": "A parser for NTP UDP packets", | ||
@@ -8,6 +8,6 @@ "main": "dist/index.js", | ||
"prepublishOnly": "yarn prettier:lint && yarn build", | ||
"test": "mocha --compilers js:babel-core/register --recursive test", | ||
"build": "babel --presets babel-preset-es2015 --out-dir dist src && prettier --write dist/**/*.js", | ||
"prettier": "prettier --write src/**/*.js test/**/*.js", | ||
"prettier:lint": "prettier --list-different src/**/*.js" | ||
"test": "ts-mocha --recursive test/**/*.spec.ts", | ||
"build": "tsc", | ||
"prettier": "prettier --write src/**/*.ts test/**/*.{js,ts}", | ||
"prettier:lint": "prettier --list-different src/**/*.ts test/**/*.{js,ts}" | ||
}, | ||
@@ -27,8 +27,20 @@ "keywords": [ | ||
"devDependencies": { | ||
"babel-cli": "6", | ||
"babel-preset-es2015": "6", | ||
"mocha": "^3.5.0", | ||
"prettier": "^1.6.1" | ||
"@types/mocha": "^8.2.2", | ||
"@types/node": "^15.3.0", | ||
"mocha": "^8.4.0", | ||
"prettier": "^2.3.0", | ||
"ts-mocha": "^8.0.0", | ||
"ts-node": "^9.1.1", | ||
"typescript": "^4.2.4" | ||
}, | ||
"license": "GPL-3.0" | ||
"files": [ | ||
"dist", | ||
"src", | ||
"package.json", | ||
"tsconfig.json" | ||
], | ||
"license": "GPL-3.0", | ||
"prettier": { | ||
"printWidth": 120 | ||
} | ||
} |
![NPM downloads](https://img.shields.io/npm/dt/ntp-packet-parser.svg) | ||
[![Build Status](https://travis-ci.org/buffcode/ntp-packet-parser.svg?branch=master)](https://travis-ci.org/buffcode/ntp-packet-parser) | ||
![GitHub release](https://img.shields.io/github/release/buffcode/npm-packet-parser.svg) | ||
[![Build Status](https://github.com/buffcode/ntp-packet-parser/actions/workflows/nodejs.yml/badge.svg)](https://github.com/buffcode/ntp-packet-parser/actions) | ||
![NPM version](https://img.shields.io/npm/v/ntp-packet-parser) | ||
@@ -8,4 +8,6 @@ # NTP packet parser | ||
Library to parse NTP response packets according to [RFC 5905](https://www.ietf.org/rfc/rfc5905.txt) into a easy-to-use structure. | ||
It does not apply any validations or calculations regarding the time but solely parses the data. | ||
It does not apply any validations or calculations regarding the time but solely parses the data. | ||
See [buffcode/ntp-time-sync](https://github.com/buffcode/ntp-time-sync) for an implementation. | ||
## Installation | ||
@@ -19,3 +21,3 @@ ```bash | ||
```js | ||
import NtpPacketParser from "ntp-packet-parser"; | ||
import { NtpPacketParser } from "ntp-packet-parser"; | ||
@@ -28,3 +30,3 @@ /** const udpPacket = new Buffer(...); **/ | ||
```js | ||
var NtpPacketParser = require("ntp-packet-parser"); | ||
var NtpPacketParser = require("ntp-packet-parser").NtpPacketParser; | ||
@@ -36,3 +38,3 @@ /** const udpPacket = new Buffer(...); **/ | ||
## Structure | ||
The response from `NtpPacketParser.parse` will always return the following object structure: | ||
The response from `NtpPacketParser.parse` will return the following object structure: | ||
@@ -45,4 +47,4 @@ | Property | Type | Description | | ||
| stratum | `Integer` | Stratum of the server | | ||
| poll | `Integer` | Integer representing the maximum interval between successive messages (Note: you need to apply `Math.log2` to get the real value) | | ||
| precision | `Integer` | Integer representing the precision of the system clock (Note: you need to apply `Math.log2` to get the real value) | | ||
| poll | `Integer` | Integer representing the maximum interval in log2 seconds between successive messages (Note: you need to apply `Math.pow(2, <value>)` to get the real value) | | ||
| precision | `Integer` | Integer representing the precision of the system clock in log2 seconds (Note: you need to apply `Math.pow(2, <value>)` to get the real value) | | ||
| rootDelay | `Date` | Total round-trip delay to the reference clock | | ||
@@ -74,2 +76,2 @@ | rootDispersion | `Date` | Total dispersion to the reference clock | | ||
## License | ||
[GNU General Public License Version 3](LICENSE) | ||
[GNU General Public License Version 3](LICENSE) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
16
72
50692
7
337
1