[Git][NTPsec/ntpsec][master] There can be only one. Packet analyzer in Python, that is.

Eric S. Raymond gitlab at mg.gitlab.com
Wed Nov 23 14:51:07 UTC 2016


Eric S. Raymond pushed to branch master at NTPsec / ntpsec


Commits:
d4762f1b by Eric S. Raymond at 2016-11-23T09:50:28-05:00
There can be only one.  Packet analyzer in Python, that is.

- - - - -


2 changed files:

- ntpdig/pyntpdig
- pylib/packet.py


Changes:

=====================================
ntpdig/pyntpdig
=====================================
--- a/ntpdig/pyntpdig
+++ b/ntpdig/pyntpdig
@@ -40,8 +40,6 @@ from __future__ import print_function, division
 
 import sys, socket, select, struct, time, getopt, datetime 
 
-# This code can run with a large subset of its capabilities
-# even when the ntp library is not available.
 try:
     import ntp.packet
     import ntp.util
@@ -49,51 +47,6 @@ except:
     sys.stderr.write("ntpdig: can't find Python NTP library -- check PYTHONPATH.\n")
     sys.exit(1)
 
-class SNTPPacket:
-    @staticmethod
-    def rescale(t):
-        "Scale from NTP time to POSIX time"
-        # Note: assumes we're in the same NTP era as the transmitter...
-        UNIX_EPOCH = 2208988800
-        return (t * 2**-32) - UNIX_EPOCH 
-    def __init__(self, data):
-        self.hostname = None
-        self.resolved = None
-        self.received = time.time()
-        self.data = data
-        (self.livnm, self.stratum, self.poll, self.precision,
-            self.root_delay, self.root_dispersion,
-            self.reference_id, self.reference_timestamp,
-            self.origin_timestamp, self.receive_timestamp,
-            self.transmit_timestamp) = struct.unpack("!BBBBIIIQQQQ", data[:48])
-        self.root_delay *= 2**-16
-        self.root_dispersion *= 2**-16
-        self.reference_timestamp = SNTPPacket.rescale(self.reference_timestamp)
-        self.origin_timestamp = SNTPPacket.rescale(self.origin_timestamp)
-        self.receive_timestamp = SNTPPacket.rescale(self.receive_timestamp)
-        self.transmit_timestamp = SNTPPacket.rescale(self.transmit_timestamp)
-        if len(data) > 192:
-            self.extension_data = data[-12:192]
-            self.auth_data = data[-12:]
-        else:
-            self.extension_data = None
-            self.auth_data = None
-        self.trusted = True
-    def delta(self):
-        return self.root_delay
-    def epsilon(self):
-        return self.root_dispersion
-    def synchd(self):
-        "Synchronization distance, estimates worst-case error in seconds"
-        # This is "lambda" in NTP-speak, but that's a Python keyword 
-        return abs(self.delta() - self.epsilon())
-    def adjust(self):
-        "Adjustment implied by this packet."
-        # FIXME: Clip low digits according to precision
-        return self.received - self.transmit_timestamp
-    def leap(self):
-        return ("no-leap", "add-leap", "del-leap", "unsync")[((self.livnm) >> 6) & 0x3]
-
 def queryhost(server, concurrent, timeout=5, port=123):
     "Query IP addresses associated with a specified host."
     try:
@@ -140,7 +93,7 @@ def queryhost(server, concurrent, timeout=5, port=123):
                     log("MAC verification on reply from %s failed" % sockaddr[0])
                 elif debug:
                     log("MAC verification on reply from %s succeeded" % sockaddr[0])
-            pkt = SNTPPacket(d)
+            pkt = ntp.packet.SyncPacket(d)
             pkt.hostname = server
             pkt.resolved = sockaddr[0]
             packets.append(pkt)


=====================================
pylib/packet.py
=====================================
--- a/pylib/packet.py
+++ b/pylib/packet.py
@@ -229,7 +229,7 @@ class Packet:
     @staticmethod
     def PKT_LI_VN_MODE(l, v, m):  return ((((l) & 3) << 6) | Packet.VN_MODE((v), (m)))
 
-    def __init__(self, session, version, mode):
+    def __init__(self, mode=MODE_CLIENT, version=NTP_VERSION, session=None):
         self.session = session  # Where to get session context
         self.li_vn_mode = 0     # leap, version, mode (uint8_t)
         # Subclasses have variable fields here
@@ -255,9 +255,12 @@ class Packet:
 
 class SyncPacket(Packet):
     "Mode 1-5 time-synchronization packet, including SNTP."
+    format = "!BBBBIIIQQQQ"
+    HEADER_LEN = 48
+    UNIX_EPOCH = 2208988800	# Midnight 1 Jan 1970 in secs since NTP epoch
 
-    def __init__(self, session=None):
-        Packet.__init__(self, session, session.pktversion, MODE_CONTROL)
+    def __init__(self, data= None):
+        Packet.__init__(self)
         self.status = 0         # status word for association (uint16_t)
         self.stratum = 0
         self.poll = 0
@@ -270,25 +273,64 @@ class SyncPacket(Packet):
         self.receive_timestamp = 0
         self.transmit_timestamp = 0
         self.extension = ''
-    format = "!BBBBIIIQQQQ"
-    HEADER_LEN = 48
-    UNIX_EPOCH = 2208988800	# Midnight 1 Jan 1970 in secs since NTP epoch
+        self.data = data
+        if self.data is not None:
+            self.analyze(self.data)
+            self.posixize()
+        self.hostname = None
+        self.resolved = None
+        self.received = time.time()
+        if len(self.data) > 192:
+            self.extension_data = data[-12:192]
+            self.auth_data = data[-12:]
+        else:
+            self.extension_data = None
+            self.auth_data = None
+        self.trusted = True
 
     def analyze(self, rawdata):
         (self.li_vn_mode,
          self.stratum,
          self.poll,
          self.precision,
-         self.rootdelay,
-         self.rootdispersion,
+         self.root_delay,
+         self.root_dispersion,
          self.refid,
          self.reference_timestamp,
          self.origin_timestamp,
          self.receive_timestamp,
          self.transmit_timestamp) \
-         = struct.unpack(ControlPacket.format, rawdata[:SyncPacket.HEADER_LEN])
+         = struct.unpack(SyncPacket.format, rawdata[:SyncPacket.HEADER_LEN])
         self.data = rawdata[SyncPacket.HEADER_LEN:]
 
+    @staticmethod
+    def ntp_to_posix(t):
+        "Scale from NTP time to POSIX time"
+        # Note: assumes we're in the same NTP era as the transmitter...
+        return (t * 2**-32) - SyncPacket.UNIX_EPOCH 
+
+    def posixize(self):
+        self.root_delay *= 2**-16
+        self.root_dispersion *= 2**-16
+        self.reference_timestamp = SyncPacket.ntp_to_posix(self.reference_timestamp)
+        self.origin_timestamp = SyncPacket.ntp_to_posix(self.origin_timestamp)
+        self.receive_timestamp = SyncPacket.ntp_to_posix(self.receive_timestamp)
+        self.transmit_timestamp = SyncPacket.ntp_to_posix(self.transmit_timestamp)
+
+    def delta(self):
+        return self.root_delay
+    def epsilon(self):
+        return self.root_dispersion
+    def synchd(self):
+        "Synchronization distance, estimates worst-case error in seconds"
+        # This is "lambda" in NTP-speak, but that's a Python keyword 
+        return abs(self.delta() - self.epsilon())
+    def adjust(self):
+        "Adjustment implied by this packet."
+        # FIXME: Clip low digits according to precision
+        return self.received - self.transmit_timestamp
+    def leap(self):
+        return ("no-leap", "add-leap", "del-leap", "unsync")[((self.li_vn_mode) >> 6) & 0x3]
     def flatten(self):
         "Flatten the packet into an octet sequence."
         body = struct.pack(ControlPacket.format,
@@ -305,15 +347,6 @@ class SyncPacket(Packet):
                            self.transmit_timestamp)
         return body + self.extension
 
-    def send(self):
-        self.session.sendpkt(self.flatten())
-
-    @staticmethod
-    def ntp_to_posix(t):
-        "Scale from NTP time to POSIX time"
-        # Note: assumes we're in the same NTP era as the transmitter...
-        return (t * 2**-32) - UNIX_EPOCH 
-
     def refid_octets(self):
         "Analyze refid into octets."
         return ((self.refid >> 24) & 0xff,
@@ -336,7 +369,9 @@ class ControlPacket(Packet):
     "Mode 6 request/response."
 
     def __init__(self, session, opcode=0, associd=0, qdata=''):
-        Packet.__init__(self, session, session.pktversion, MODE_CONTROL)
+        Packet.__init__(self, mode=MODE_CONTROL,
+                        version=session.pktversion,
+                        session=session)
         self.r_e_m_op = opcode  # ntpq operation code
         self.sequence = 1       # sequence number of request (uint16_t)
         self.status = 0         # status word for association (uint16_t)



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/commit/d4762f1ba4357ae81994b49e57057d94d0e9f983
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ntpsec.org/pipermail/vc/attachments/20161123/effcf4a5/attachment.html>


More information about the vc mailing list