Ejemplo n.º 1
0
def macaddr_from_ipv4(ipv4):
    """
    Given @ipv4, returns the @macaddr or None if unknown / lookup failed, etc.
    """
    if not is_ipv4_address_valid(ipv4):
        return None
    ipv4 = normalize_ipv4_address(ipv4)
    by_ipv4 = load(DHCPD_LEASES_FILENAME)[0]
    if ipv4 not in by_ipv4:
        return None
    else:
        return by_ipv4[ipv4].macaddr
Ejemplo n.º 2
0
def load(filename):
    """
    Load a dhcpd.leases file.
    
    WARNING: The parsing is _NOT_ done the same way dhcpd does it, for
    simplicity reasons.  Anyway it should work.  Maybe.
    
    Returns (by_ipv4, by_macaddr) where both are dictionaries in which values
    are LeaseEntry instances and keys are IPv4 in @by_ipv4 and mac address in
    @by_macaddr.
    
    TODO: check validity periods
    """
    by_ipv4 = {}
    by_macaddr = {}
    
    state = NOWHERE
    
    for line in file(filename):
        
        line = line.rstrip()
        fully_stripped_line = line.lstrip()
        
        if (not fully_stripped_line) or fully_stripped_line[0] == '#':
            continue
        
        if state is NOWHERE:
            if line.startswith("lease "):
                lease_header = line.split()
                if len(lease_header) == 3 and is_ipv4_address_valid(lease_header[1]) and lease_header[2] == "{":
                    current = LeaseEntry(lease_header[1])
                    state = LEASE
                else:
                    # XXX log that our parser is too dumb to correctly parse the file
                    state = UNKNOWN
        elif state is UNKNOWN:
            if fully_stripped_line == '}':
                state = NOWHERE
            else:
                pass # XXX log
        elif state is LEASE:
            for start, method in LEASE_ATTRS:
                remain = match_remain_and_strip_semicolon(fully_stripped_line, start)
                if remain is not None:
                    method(current, remain)
                    break
            else:
                if fully_stripped_line == '}':
                    if current.ipv4 in by_ipv4:
                        macaddr_to_rm = by_ipv4[current.ipv4].macaddr
                        del by_ipv4[current.ipv4]
                        del by_macaddr[macaddr_to_rm]
                    if is_mac_address_valid(getattr(current, 'macaddr', "")) \
                    and getattr(current, 'binding_state', None) == 'active':
                        if current.macaddr in by_macaddr:
                            ipv4_to_rm = by_macaddr[current.macaddr].ipv4
                            del by_ipv4[ipv4_to_rm]
                            del by_macaddr[current.macaddr]
                        by_ipv4[current.ipv4] = current
                        by_macaddr[current.macaddr] = current
                    else:
                        # log that this lease entry is useless for us if without a mac address or binding state isn't active
                        pass
                    del current
                    state = NOWHERE
                else:
                    # XXX count number of unknown lease lines
                    pass
    
    return by_ipv4, by_macaddr
Ejemplo n.º 3
0
 def is_ipv4_netmask_valid(netmask):
     "Verify if it is a valid netmask."
     return network.is_ipv4_address_valid(netmask) \
            and network.plausible_netmask(network.parse_ipv4(netmask))