# DHCPd Leases # # Douglas Thrift # # $Id$ from datetime import datetime from pyparsing import * import pytz open_brace = Suppress('{') close_brace = Suppress('}') date = oneOf(list('0123456')) \ + Combine(Word(nums, exact = 4) + '/' + Word(nums, exact = 2) + '/' + Word(nums, exact = 2)) \ + Combine(Word(nums, exact = 2) + ':' + Word(nums, exact = 2) + ':' + Word(nums, exact = 2)) \ | Literal('never') semi_colon = Suppress(';') my_state = Literal('my') \ + Suppress('state') \ + Word(alphas, alphas + '-') \ + Suppress('at') \ + date \ + semi_colon peer_state = Literal('partner') \ + Suppress('state') \ + Word(alphas, alphas + '-') \ + Suppress('at') \ + date \ + semi_colon mclt = Literal('mclt') + Word(nums) + semi_colon failover = Literal('failover') \ + Suppress('peer') \ + QuotedString('"') \ + Suppress('state') \ + open_brace \ + Dict(ZeroOrMore(Group(my_state | peer_state | mclt))) \ + close_brace ip_address = Combine(Word(nums) + '.' + Word(nums) + '.' + Word(nums) + '.' + Word(nums)) starts = Literal('starts') + date + semi_colon ends = Literal('ends') + date + semi_colon tstp = Literal('tstp') + date + semi_colon tsfp = Literal('tsfp') + date + semi_colon atsfp = Literal('atsfp') + date + semi_colon cltt = Literal('cltt') + date + semi_colon binding_state = Literal('active') \ | Literal('free') \ | Literal('backup') \ | Literal('expired') \ | Literal('abandoned') binding = Literal('binding') + Suppress('state') + binding_state + semi_colon next = Literal('next') + binding mac_address = Combine(Word(hexnums, exact = 2) + ':' + Word(hexnums, exact = 2) + ':' + Word(hexnums, exact = 2) + ':' + Word(hexnums, exact = 2) + ':' + Word(hexnums, exact = 2) + ':' + Word(hexnums, exact = 2)) hardware = Literal('hardware') \ + Suppress('ethernet') \ + mac_address \ + semi_colon uid = Literal('uid') + QuotedString('"', '\\') + semi_colon set = Literal('set') + Word(alphas, alphas + '-') + Suppress('=') + QuotedString('"') + semi_colon client_hostname = Literal('client-hostname') + QuotedString('"') + semi_colon statements = starts \ | ends \ | tstp \ | tsfp \ | atsfp \ | cltt \ | binding \ | next \ | hardware \ | uid \ | set \ | client_hostname lease = Literal('lease') \ + ip_address \ + open_brace \ + Dict(ZeroOrMore(Group(statements))) \ + close_brace server_duid = Literal('server-duid') + QuotedString('"', '\\') + semi_colon leases = Dict(ZeroOrMore(Group(failover | lease | server_duid))) comment = '#' + Optional(restOfLine) leases.ignore(comment) def date_parse_action(tokens): when = ' '.join(tokens) return pytz.utc.localize(datetime.strptime(when, '%w %Y/%m/%d %H:%M:%S')) if when != 'never' else datetime.max date.setParseAction(date_parse_action) if __name__ == '__main__': leases.parseFile('/var/db/dhcpd.leases', parseAll = True)