pvl/syslog/dhcp.py
changeset 169 a81ca751664d
parent 168 4e120851ff52
child 170 455573d46a33
--- a/pvl/syslog/dhcp.py	Fri Jan 25 22:02:55 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,191 +0,0 @@
-"""
-    Parse ISC dhcpd messages in syslog.
-"""
-
-import re
-
-class DHCPSyslogFilter (object) :
-    """
-        Parse SyslogMessages from SyslogParser for ISC dhcp semantics.
-    """
-
-    ## various message types sent/recieved by dhcpd
-    # from server/dhcp.c
-    TYPE_NAMES = (
-        "DHCPDISCOVER",
-        "DHCPOFFER",
-        "DHCPREQUEST",
-        "DHCPDECLINE",
-        "DHCPACK",
-        "DHCPNAK",
-        "DHCPRELEASE",
-        "DHCPINFORM",
-        "type 9",
-        "DHCPLEASEQUERY",
-        "DHCPLEASEUNASSIGNED",
-        "DHCPLEASEUNKNOWN",
-        "DHCPLEASEACTIVE"
-    )
-
-    # message-parsing regexp..
-    RECV_MESSAGE_RE = (
-        # dhcpdiscover/ack_lease: info/error
-        #   hwaddr:     <no identifier>
-        #   hostname:   Hostname Unsuitable for Printing
-        #   error:
-        #               peer holds all free leases
-        #               network %s: no free leases
-        re.compile(r'(?P<type>DHCPDISCOVER) from (?P<hwaddr>.+?)( \((?P<hostname>.+?)\))? via (?P<gateway>.+?)(: (?P<error>.+?))?$'),
-
-        # dhcprequest
-        #   error:
-        #               wrong network.
-        #               ignored (not authoritative).
-        #               ignored (unknown subnet).
-        #               lease %s unavailable.
-        #               unknown lease %s.
-        re.compile(r'(?P<type>DHCPREQUEST) for (?P<lease>.+?)( \((?P<server>.+?)\))? from (?P<hwaddr>.+?)( \((?P<hostname>.+?)\))? via (?P<gateway>.+?)(: (?P<error>.+?))?$'),
-
-        # dhcprelease
-        re.compile(r'(?P<type>DHCPRELEASE) of (?P<lease>.+?) from (?P<hwaddr>.+?)( \((?P<hostname>.+?)\))? via (?P<gateway>.+?) \((?P<found>.+?)\)$'),
-
-        # dhcpdecline
-        #   status:
-        #       abandoned
-        #       not found
-        #       ignored
-        re.compile(r'(?P<type>DHCPDECLINE) of (?P<lease>.+?) from (?P<hwaddr>.+?)( \((?P<hostname>.+?)\))? via (?P<gateway>.+?): (?P<status>.+?)$'),
-
-        # dhcpinform
-        #   error:
-        #       ignored (null source address).
-        #       unknown subnet for relay address %s
-        #       unknown subnet for %s address %s
-        #       not authoritative for subnet %s
-        re.compile(r'(?P<type>DHCPINFORM) from (?P<lease>.+?) via (?P<gateway>.+?)(: (?P<error>.+?))?$'),
-        
-        # dhcpleasequery
-        re.compile(r'(?P<type>DHCPLEASEQUERY) from (?P<server>.+?)( for (?P<key_type>IP|client-id|MAC address) (?P<key>.+?))?(: (?P<error>.+?))?$'),
-
-        # dhcp: generic/unknown packet
-        re.compile(r'(?P<type>\w+) from (?P<hwaddr>.+?) via (?P<gateway>.+?): (?P<error>.+?)$'),
-    )
-
-    SEND_MESSAGE_RE = (
-        # dhcp_reply
-        re.compile(r'(?P<type>DHCPACK|DHCPOFFER|BOOTREPLY) on (?P<lease>.+?) to (?P<hwaddr>.+?)( \((?P<hostname>.+?)\))? via (?P<gateway>.+?)$'),
-
-        # dhcpinform
-        #   hwaddr:     <no client hardware address>
-        re.compile(r'(?P<type>DHCPACK) to (?P<lease>.+?) \((?P<hwaddr>.+?)\) via (?P<gateway>.+?)$'),
-
-        # nak_lease
-        re.compile(r'(?P<type>DHCPNAK) on (?P<lease>.+?) to (?P<hwaddr>.+?) via (?P<gateway>.+?)$'),
-
-        # dhcpleasequery
-        re.compile(r'(?P<type>DHCPLEASEUNKNOWN|DHCPLEASEACTIVE|DHCPLEASEUNASSIGNED) to (?P<lease>.+?) for (?P<key_type>IP|client-id|MAC address) (?P<key>.+?) \((?P<count>\d+) associated IPs\)$'),
-    )
-
-    MESSAGE_ERROR_RE = (
-        ('peer-all-free-leases',    re.compile('peer holds all free leases')),
-        ('no-free-leases',          re.compile(r'network (?P<network>.+?): no free leases')),
-        ('wrong-network',           re.compile(r'wrong network')),
-        ('ignored-not-auth',        re.compile(r'ignored \(not authoritative\)')),
-        ('ignored-unknown-subnet',  re.compile(r'ignored \(unknown subnet\)')),
-        ('lease-unavailable',       re.compile(r'lease (?P<lease>.+?) unavailable')),
-        ('lease-unknown',           re.compile(r'unknown lease (?P<lease>.+?).$')),
-    )
-
-    ERROR_RE = (
-        # find_lease
-        ('duplicate-uid-lease', 
-            re.compile(r'uid lease (?P<client>.+?) for client (?P<hwaddr>.+?) is duplicate on (?P<shared_network>.+?)$')),
-
-        # dhcprelease
-        ('dhcprelease-requested-address', 
-            re.compile(r'DHCPRELEASE from (?P<hwaddr>.+?) specified requested-address.')),
-
-        # ???
-        ('unexpected-icmp-echo-reply',
-            re.compile(r'unexpected ICMP Echo Reply from (?P<client>.+?)$')),
-        
-        ('host-unknown',
-            re.compile(r'(?P<host>.+?): host unknown.')),
-    )
-
-    IGNORE_RE = (
-        re.compile(r'Wrote (?P<count>\d+) (?P<what>.+?) to leases file.'),
-    )
-
-    def parse (self, line) :
-        """
-            Match line against our regexps, returning a
-
-                {
-                    tag:        send/recv/error,
-                    type:       ...,
-                    [error]:    ...,
-                    ...
-                }
-
-            dict if matched
-
-            Returns False if the message is ignored, or None if the no regexp matched.
-        """
-
-        for tag, re_list in (
-            ('recv',    self.RECV_MESSAGE_RE),
-            ('send',    self.SEND_MESSAGE_RE),
-        ) :
-            for re in re_list :
-                # test
-                match = re.match(line)
-
-                if match :
-                    data = match.groupdict()
-                    data['tag'] = tag
-
-                    return data
-                
-        # error?
-        for type, re in self.ERROR_RE:
-            match = re.match(line)
-
-            if match : 
-                data = match.groupdict()
-                data['tag'] = 'error'
-                data['type'] = type
-
-                return data
-
-        # ignore
-        for re in self.IGNORE_RE :
-            if re.match(line) :
-                # ignore
-                return False
-
-        # unknown
-        return None
-
-    def parse_error (self, error) :
-        """
-            Match given error status from send/recv against known types, returning a type name or None.
-        """
-
-        for type, re in self.MESSAGE_ERROR_RE :
-            match = re.match(error)
-
-            if match :
-                return type
-        
-        # nope
-        return None
-
-if __name__ == '__main__' :
-    import logging
-
-    logging.basicConfig()
-
-    import doctest
-    doctest.testmod()
-