[Git][NTPsec/ntpsec][master] 3 commits: Comment cleanup

Ian Bruene gitlab at mg.gitlab.com
Wed Dec 27 18:46:32 UTC 2017


Ian Bruene pushed to branch master at NTPsec / ntpsec


Commits:
7ba3a555 by Ian Bruene at 2017-12-27T08:48:01-06:00
Comment cleanup

- - - - -
fde7efee by Ian Bruene at 2017-12-27T08:48:01-06:00
Moved some functions around

- - - - -
64003e7d by Ian Bruene at 2017-12-27T12:45:06-06:00
Attempted ntpsnmpd notifications, currently non-functional

- - - - -


1 changed file:

- ntpclients/ntpsnmpd.py


Changes:

=====================================
ntpclients/ntpsnmpd.py
=====================================
--- a/ntpclients/ntpsnmpd.py
+++ b/ntpclients/ntpsnmpd.py
@@ -12,10 +12,10 @@ import select
 import subprocess
 
 try:
-    import ntp.agentx
-    ax = ntp.agentx
     import ntp.packet
     import ntp.util
+    import ntp.agentx
+    ax = ntp.agentx
 except ImportError as e:
     sys.stderr.write(
         "ntpsnmpd: can't find Python NTP library.\n")
@@ -34,10 +34,12 @@ timeout = 5  # default timeout, what shuold this be?
 
 ntpRootOID = (1, 3, 6, 1, 2, 1, 197)  # mib-2 . 197, aka: NTPv4-MIB
 
+snmpTrapOID = (1, 3, 6, 1, 6, 3, 1, 1, 4, 1)
+
 DEFHOST = "localhost"  # For now only know how to talk to the local ntp
 
 
-class DataSource:  # This may be broken up in future to be less NTP-specific
+class DataSource:  # This will be broken up in future to be less NTP-specific
     def __init__(self):
         node = ax.mibnode
         # This is defined as a dict tree because simpler, and avoids
@@ -249,12 +251,13 @@ class DataSource:  # This may be broken up in future to be less NTP-specific
         # Cache so we don't hammer ntpd, default 1 second timeout
         # timeout default pulled from a hat
         self.cache = ntp.util.Cache(1)
+        self.lastHeartbeat = 0
         # The undo system is only for the last operation
         self.inSetP = False  # Are we currently in the set procedure?
         self.setVarbinds = []  # Varbind of the current set operation
         self.setHandlers = []  # Handlers for commit/undo/cleanup of set
         self.setUndoData = []  # Previous values for undoing
-        self.heartbeatInterval = 0
+        self.heartbeatInterval = 10  # should save to disk
         self.sentNotifications = 0
         # Notify bits, these should be saved to disk
         # Also they currently have no effect
@@ -265,7 +268,7 @@ class DataSource:  # This may be broken up in future to be less NTP-specific
         self.notifyRMAssociation = False  # 5
         self.notifyConfigChange = False  # 6
         self.notifyLeapSecondAnnounced = False  # 7
-        self.notifyHeartbeat = False  # 8
+        self.notifyHeartbeat = True  # 8
 
     def getOID_core(self, nextP, searchoid, returnGenerator=False):
         gen = ax.walkMIBTree(self.oidTree, ntpRootOID)
@@ -390,8 +393,10 @@ class DataSource:  # This may be broken up in future to be less NTP-specific
             mode = 3  # No reference configured
         elif source == ntp.control.CTL_SST_TS_LOCAL:
             mode = 4  # Distributing local clock (low accuracy)
-        elif source in (ntp.control.CTL_SST_TS_ATOM, ntp.control.CTL_SST_TS_LF,
-                        ntp.control.CTL_SST_TS_HF, ntp.control.CTL_SST_TS_UHF):
+        elif source in (ntp.control.CTL_SST_TS_ATOM,
+                        ntp.control.CTL_SST_TS_LF,
+                        ntp.control.CTL_SST_TS_HF,
+                        ntp.control.CTL_SST_TS_UHF):
             # I am not sure if I should be including the radios in this
             mode = 5  # Synced to local refclock
         elif source == ntp.control.CTL_SST_TS_NTP:
@@ -420,7 +425,9 @@ class DataSource:  # This may be broken up in future to be less NTP-specific
 
     def cbr_statusActiveRefSourceName(self, oid):
         # utf8
-        data = self.session.readvar(0, ["peeradr"])
+        data = self.safeReadvar(0, ["peeradr"])
+        if data is None:
+            return ax.Varbind(ax.VALUE_NULL, oid)
         data = ntp.util.canonicalize_dns(data["peeradr"])
         return ax.Varbind(ax.VALUE_OCTET_STR, oid, data)
 
@@ -625,7 +632,7 @@ class DataSource:  # This may be broken up in future to be less NTP-specific
             pdata = self.misc_getPeerData()
             if pdata is None:
                 return ax.Varbind(ax.VALUE_NULL, oid)
-            peername = pdata[associd]["srcadr"][1]  # TODO: DNS
+            peername = pdata[associd]["srcadr"][1]
             peername = ntp.util.canonicalize_dns(peername)
             return ax.Varbind(ax.VALUE_OCTET_STR, oid, peername)
         return self.dynamicCallbackSkeleton(handler)
@@ -768,6 +775,31 @@ class DataSource:  # This may be broken up in future to be less NTP-specific
         return self.dynamicCallbackSkeleton(handler)
 
     # =====================================
+    # Notification handlers
+    # =====================================
+
+    def checkNotifications(self, control):
+        if self.notifyHeartbeat is True:
+            if self.heartbeatInterval == 0:  # interval == 0 means send once
+                self.notifyHeartbeat = False
+                vl = [ax.Varbind(ax.VALUE_OID, snmpTrapOID,
+                                 ax.OID((1, 3, 6, 1, 2, 1, 197, 0, 8))),
+                      ax.Varbind(ax.VALUE_GAUGE32,
+                                 (1, 2, 6, 1, 2, 1, 197, 0, 1, 4, 1),
+                                 self.heartbeatInterval)]
+                control.sendNotify(vl, "public")
+            else:
+                current = ntp.util.monoclock()
+                if (current - self.lastHeartbeat) > self.heartbeatInterval:
+                    self.lastHeartbeat = current
+                    vl = [ax.Varbind(ax.VALUE_OID, snmpTrapOID,
+                                     ax.OID((1, 3, 6, 1, 2, 1, 197, 0, 8))),
+                          ax.Varbind(ax.VALUE_GAUGE32,
+                                     (1, 2, 6, 1, 2, 1, 197, 0, 1, 4, 1),
+                                     self.heartbeatInterval)]
+                    control.sendNotify(vl, "public")
+
+    # =====================================
     # Misc data helpers (not part of the MIB proper)
     # =====================================
 
@@ -824,21 +856,6 @@ class DataSource:  # This may be broken up in future to be less NTP-specific
         return peerdata
 
 
-def dolog(text, level):
-    if debug >= level:
-        logfp.write(text)
-
-
-def connect():
-    sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
-    try:
-        sock.connect("/var/agentx/master")
-    except socket.error as msg:
-        dolog(repr(msg) + "\n", 2)
-        sys.exit(1)
-    return sock
-
-
 class PacketControl:
     def __init__(self, sock, dbase, spinGap=0.001, timeout=5):
         # take a pre-made socket instead of making our own so that
@@ -868,7 +885,7 @@ class PacketControl:
             while True:
                 self._doloop()
                 if self.loopCallback is not None:
-                    self.loopCallback()
+                    self.loopCallback(self)
                 time.sleep(self.spinGap)
         else:
             self._doloop()
@@ -968,6 +985,11 @@ class PacketControl:
                      packet.packetID)
             self.packetLog[index] = packet
 
+    def sendNotify(self, varbinds, context=None):
+        # DUMMY: transactionID, packetID
+        pkt = ax.NotifyPDU(True, self.sessionID, 300, 1, varbinds, context)
+        self.sendPacket(pkt, True)
+
     def sendErrorResponse(self, errorHeader, errorType, errorIndex):
         err = ax.ResponsePDU(errorHeader["flags"]["bigEndian"],
                              errorHeader["session_id"],
@@ -1140,11 +1162,27 @@ class PacketControl:
         self.database.inSetP = False
 
 
+def dolog(text, level):
+    if debug >= level:
+        logfp.write(text)
+
+
+def connect():
+    sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+    try:
+        sock.connect("/var/agentx/master")
+    except socket.error as msg:
+        dolog(repr(msg) + "\n", 2)
+        sys.exit(1)
+    return sock
+
+
 def mainloop():
     dolog("initing loop\n", 1)
     sock = connect()
     dbase = DataSource()
     control = PacketControl(sock, dbase)
+    control.loopCallback = dbase.checkNotifications
     control.initNewSession()
     control.mainloop(True)
 



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/b4665e1084ac7e80995a5e0b726dcd7f28d4bc9a...64003e7dec63acdc456697b7c42e070d971dfb5a

---
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/b4665e1084ac7e80995a5e0b726dcd7f28d4bc9a...64003e7dec63acdc456697b7c42e070d971dfb5a
You're receiving this email because of your account on gitlab.com.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ntpsec.org/pipermail/vc/attachments/20171227/75a0034a/attachment.html>


More information about the vc mailing list