[Git][NTPsec/ntpsec][master] pyntpq checkpoint before debugging packet-frag reassembly.

Eric S. Raymond gitlab at mg.gitlab.com
Tue Oct 18 13:34:44 UTC 2016


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


Commits:
28acd57e by Eric S. Raymond at 2016-10-18T09:33:02-04:00
pyntpq checkpoint before debugging packet-frag reassembly.

- - - - -


2 changed files:

- ntpq/pyntpq
- pylib/packet.py


Changes:

=====================================
ntpq/pyntpq
=====================================
--- a/ntpq/pyntpq
+++ b/ntpq/pyntpq
@@ -189,7 +189,7 @@ def prettydate(d):
     # FIXME: we need to unpack this date.
     return d[2:]
 
-class ntpq_interpreter(cmd.Cmd):
+class Ntpq(cmd.Cmd):
     "ntpq command interpreter"
 
     def __init__(self, session):
@@ -207,9 +207,9 @@ class ntpq_interpreter(cmd.Cmd):
         self.wideremote = False		# show wide remote names?
         self.ccmds = []			# Queued commands
         self.chosts = []		# Command-line hosts
+        self.peers = []			# Data from NTP peers.
         self.debug = 0
         self.pktversion = NTP_VERSION
-        self.peers = []
 
     def emptyline(self):
         "Called when an empty line is entered in response to the prompt."
@@ -281,20 +281,43 @@ usage: help [ command ]
 	"srchost",	# 15
         )
 
-    def __dopeers(showall, af, varlist, dstaddr):
+    def __dogetassoc(self):
+        try:
+            self.peers = self.session.readstat()
+        except Mode6Exception as e:
+            print(e.message)
+            return False
+
+        if len(self.peers) == 0:
+            if self.chosts:
+                sys.stdout.write("server=%s ", self.session.name);
+            sys.stdout.write("No association IDs returned\n");
+            return False;
+
+        if self.debug:
+            sys.stderr.write("\n%d associations total\n" % len(self.peers));
+	#sortassoc();
+	return True;
+
+    def __dogetpeers(self, varlist, associd, af):
+        variables = self.session.readvar(associd)
+        print(variables)
+        return True
+
+    def __dopeers(self, showall, af, varlist):
         af = socket.AF_INET6 if "-6" in af else socket.AF_INET
-        if not dogetassoc():
+        if not self.__dogetassoc():
             return;
         maxhostlen = 0
 	#for host in self.chosts:
-        #    if (getnetnum(chosts[u].name, &netnum, fullname, af))
+        #    if getnetnum(chosts[u].name, &netnum, fullname, af):
         #        name_or_num = nntohost(&netnum);
-        #        sl = strlen(name_or_num);
+        #        sl = len(name_or_num);
         #        maxhostlen = max(maxhostlen, sl);
 	if len(self.chosts) > 1:
             sys.stdout.write("%-*.*s " % (maxhostlen, maxhostlen,
                                           "server (local)"))
-	sys.stout.write(varlist[0])
+	sys.stdout.write(varlist[0])
 	sys.stdout.write(("=" * (maxhostlen + 78)) + "\n");
         for peer in self.peers:
             if not showall and \
@@ -302,9 +325,9 @@ usage: help [ command ]
 		      & (CTL_PST_CONFIG|CTL_PST_REACH)):
                 if self.debug:
                     sys.stderr.write(stderr, "eliding [%d]\n" % peer.associd)
-                    continue
-                if not self.dogetpeers(varlist[1:], peer.associd, af):
-                    return;
+                continue
+            if not self.__dogetpeers(varlist[1:], peer.associd, af):
+                return;
 
     # Unexposed helper tables and functions end here
 
@@ -376,7 +399,7 @@ usage: delay [ msec ]
             elif tokens[0] == '-6':
                 session.ai_family = socket.AF_INET6
                 tokens.pop(0)
-            if tokens and self.session.openhost(tokens[0],session.ai_family):
+            if tokens and self.session.openhost(tokens[0], session.ai_family):
                 print("current host set to %s" % self.session.name)
             elif self.session.havehost():
                 print("current host remains %s" % self.session.name)
@@ -853,7 +876,8 @@ usage: cv [ assocID ] [ name=value[,...] ]
         if associd not in [peer.associd for peer in self.peers]:
             sys.stderr.write("Unknown associd.\n")
             return
-	self.collect_display(associd=associd,variables=pstats,decodestatus=True);
+	self.collect_display(associd=associd,
+                             variables=pstats, decodestatus=True);
 
     def help_pstats(self):
         sys.stdout.write("""\
@@ -863,7 +887,7 @@ usage: pstats assocID
 
     def do_peers(self, line):
         "obtain and print a list of the server's peers [IP version]"
-        self.__dopeers(showall=False, af=line, varlist=__peervarlist)
+        self.__dopeers(showall=False, af=line, varlist=Ntpq.__peervarlist)
 
     def help_peers(self):
         sys.stdout.write("""\
@@ -873,7 +897,7 @@ usage: peers [ -4|-6 ]
 
     def do_apeers(self, line):
         "obtain and print a list of the server's peers and their assocIDs [IP version]"
-        self.__dopeers(showall=False, af=line, varlist=__apeervarlist)
+        self.__dopeers(showall=False, af=line, varlist=Ntpq.__apeervarlist)
 
     def help_apeers(self):
         sys.stdout.write("""\
@@ -883,7 +907,7 @@ usage: apeers [ -4|-6 ]
 
     def do_lpeers(self, line):
         "obtain and print a list of all peers and clients [IP version]"
-        self.__dopeers(showall=True, af=line, varlist=__peervarlist)
+        self.__dopeers(showall=True, af=line, varlist=Ntpq.__peervarlist)
 
     def help_lpeers(self):
         sys.stdout.write("""\
@@ -893,7 +917,7 @@ usage: lpeers [ -4|-6 ]
 
     def do_opeers(self, line):
         "print peer list the old way, with dstadr shown rather than refid [IP version]"
-        self.__dopeers(showall=False, af=line, varlist=__opeervarlist)
+        self.__dopeers(showall=False, af=line, varlist=Ntpq.__opeervarlist)
 
     def help_opeers(self):
         sys.stdout.write("""\
@@ -903,7 +927,7 @@ usage: opeers [ -4|-6 ]
 
     def do_lopeers(self, line):
         "obtain and print a list of all peers and clients showing dstadr [IP version]"
-        self.__dopeers(showall=True, af=line, varlist=__opeervarlist)
+        self.__dopeers(showall=True, af=line, varlist=Ntpq.__opeervarlist)
 
     def help_lopeers(self):
         sys.stdout.write("""\
@@ -1180,10 +1204,10 @@ if __name__ == '__main__':
     try:
         (options, arguments) = getopt.getopt(sys.argv[1:],
                                              "46c:dD:hinOpVw",
-                                             ["ipv4","ipv6","command",
-                                              "debug","set-debug-level",
+                                             ["ipv4","ipv6", "command",
+                                              "debug", "set-debug-level",
                                               "help", "interactive", "numeric",
-                                              "old-rv","peers","version",
+                                              "old-rv", "peers", "version",
                                               "wide"])
     except getopt.GetoptError as e:
         print(e)
@@ -1191,7 +1215,7 @@ if __name__ == '__main__':
     progname = sys.argv[0]
 
     session = Mode6Session()
-    interpreter = ntpq_interpreter(session)
+    interpreter = Ntpq(session)
 
     for (switch, val) in options:
         if switch in ("-4", "--ipv4"):


=====================================
pylib/packet.py
=====================================
--- a/pylib/packet.py
+++ b/pylib/packet.py
@@ -104,7 +104,7 @@ class Packet:
         return (self.li_vn_mode >> 3) & 0x7
 
 class Mode6Packet(Packet):
-    "ntpq request/response "
+    "Mode 6 request/response "
 
     def __init__(self, session, opcode=0, associd=0, qdata=''):
         Packet.__init__(self, session, session.pktversion, MODE_CONTROL)
@@ -134,6 +134,9 @@ class Mode6Packet(Packet):
         "Return statistics on a fragment."
         return "%5d %5d\t%3d octets\n" % (self.offset, self.end(), self.count)
 
+    def endpoint(self):
+        return self.offset + len(self.extension)
+
     def send(self):
         self.session.sequence += 1
         self.sequence = self.session.sequence
@@ -156,7 +159,7 @@ class Peer:
     def readvars(self):
         self.variables = self.session.readvars()
     def __str__(self):
-        return "<Peer: associd=%s status=%s>" % (self.associd, self.status)
+        return "<Peer: associd=%s status=%0x>" % (self.associd, self.status)
     __repr__ = __str__
 
 SERR_BADFMT = "***Server reports a bad format request packet\n"
@@ -171,6 +174,7 @@ SERR_INCOMPLETE = "***Response from server was incomplete\n"
 SERR_TOOMUCH = "***Buffer size exceeded for returned data\n"
 SERR_SELECT = "***Select call failed\n"
 SERR_NOHOST = "***No host open, use `host' command\n"
+SERR_BADLENGTH = "***Response length shuld have been a multiple of 4"
 
 def dump_hex_printable(xdata):
     "Dump a packet in hex, in a familiar hex format"
@@ -479,7 +483,7 @@ class Mode6Session:
             # Record status info out of the last packet.
             if not rpkt.more():
                 seenlastfrag = True
-                self.rstatus = rpkt.status
+                self.rstatus = socket.ntohs(rpkt.status)
 
             # If we've seen the last fragment, look for holes in the sequence.
             # If there aren't any, we're done.
@@ -519,11 +523,10 @@ class Mode6Session:
         return res
 
     def readstat(self, associd=0):
-        "Read peer status."
-        try:
-            self.doquery(opcode=CTL_OP_READSTAT, associd=associd)
-        except Mode6Exception as e:
-            return e.message
+        "Read peer status, or throw an exception."
+        self.doquery(opcode=CTL_OP_READSTAT, associd=associd)
+        if len(self.response) % 4:
+            raise Mode6Exception(SERR_BADLENGTH)
         idlist = []
         if associd == 0:
             for i in range(len(self.response)//4):



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


More information about the vc mailing list