Exemplo n.º 1
0
def parse_subnetport(s):

    if s.count(':') > 1:
        rx = r'(?:\[?([\w\:]+)(?:/(\d+))?]?)(?::(\d+)(?:-(\d+))?)?$'
    else:
        rx = r'([\w\.\-]+)(?:/(\d+))?(?::(\d+)(?:-(\d+))?)?$'

    m = re.match(rx, s)
    if not m:
        raise Fatal('%r is not a valid address/mask:port format' % s)

    # Ports range from fport to lport. If only one port is specified,
    # fport is defined and lport is None.
    #
    # cidr is the mask defined with the slash notation
    host, cidr, fport, lport = m.groups()
    try:
        addrinfo = socket.getaddrinfo(host, 0, 0, socket.SOCK_STREAM)
    except socket.gaierror:
        raise Fatal('Unable to resolve address: %s' % host)

    # If the address is a domain with multiple IPs and a mask is also
    # provided, proceed cautiously:
    if cidr is not None:
        addr_v6 = [a for a in addrinfo if a[0] == socket.AF_INET6]
        addr_v4 = [a for a in addrinfo if a[0] == socket.AF_INET]

        # Refuse to proceed if IPv4 and IPv6 addresses are present:
        if len(addr_v6) > 0 and len(addr_v4) > 0:
            raise Fatal("%s has IPv4 and IPv6 addresses, so the mask "
                        "of /%s is not supported. Specify the IP "
                        "addresses directly if you wish to specify "
                        "a mask." % (host, cidr))

        # Warn if a domain has multiple IPs of the same type (IPv4 vs
        # IPv6) and the mask is applied to all of the IPs.
        if len(addr_v4) > 1 or len(addr_v6) > 1:
            print("WARNING: %s has multiple IP addresses. The "
                  "mask of /%s is applied to all of the addresses." %
                  (host, cidr))

    rv = []
    for a in addrinfo:
        family, _, _, _, addr = a

        # Largest possible slash value we can use with this IP:
        max_cidr = 32 if family == socket.AF_INET else 128

        if cidr is None:  # if no mask, use largest mask
            cidr_to_use = max_cidr
        else:  # verify user-provided mask is appropriate
            cidr_to_use = int(cidr)
            if not 0 <= cidr_to_use <= max_cidr:
                raise Fatal('Slash in CIDR notation (/%d) is '
                            'not between 0 and %d' % (cidr_to_use, max_cidr))

        rv.append((family, addr[0], cidr_to_use, int(fport or 0),
                   int(lport or fport or 0)))

    return rv
Exemplo n.º 2
0
def parse_ipport(s):
    s = str(s)
    if s.isdigit():
        rx = r'()(\d+)$'
    elif ']' in s:
        rx = r'(?:\[([^]]+)])(?::(\d+))?$'
    else:
        rx = r'([\w\.\-]+)(?::(\d+))?$'

    m = re.match(rx, s)
    if not m:
        raise Fatal('%r is not a valid IP:port format' % s)

    host, port = m.groups()
    host = host or '0.0.0.0'
    port = int(port or 0)

    try:
        addrinfo = socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM)
    except socket.gaierror:
        raise Fatal('Unable to resolve address: %s' % host)

    if len(addrinfo) > 1:
        print(
            "WARNING: Host %s has more than one IP, only using one of them." %
            host)

    family, _, _, _, addr = min(addrinfo)
    # Note: addr contains (ip, port)
    return (family, ) + addr[:2]
Exemplo n.º 3
0
def parse_subnet6(s):
    m = re.match(r'(?:([a-fA-F\d:]+))?(?:/(\d+))?$', s)
    if not m:
        raise Fatal('%r is not a valid IP subnet format' % s)
    (net, width) = m.groups()
    if width is None:
        width = 128
    else:
        width = int(width)
    if width > 128:
        raise Fatal('*/%d is greater than the maximum of 128' % width)
    return (socket.AF_INET6, net, width)
Exemplo n.º 4
0
def parse_subnet4(s):
    m = re.match(r'(\d+)(?:\.(\d+)\.(\d+)\.(\d+))?(?:/(\d+))?$', s)
    if not m:
        raise Fatal('%r is not a valid IP subnet format' % s)
    (a, b, c, d, width) = m.groups()
    (a, b, c, d) = (int(a or 0), int(b or 0), int(c or 0), int(d or 0))
    if width is None:
        width = 32
    else:
        width = int(width)
    if a > 255 or b > 255 or c > 255 or d > 255:
        raise Fatal('%d.%d.%d.%d has numbers > 255' % (a, b, c, d))
    if width > 32:
        raise Fatal('*/%d is greater than the maximum of 32' % width)
    return (socket.AF_INET, '%d.%d.%d.%d' % (a, b, c, d), width)
Exemplo n.º 5
0
def parse_ipport4(s):
    s = str(s)
    m = re.match(r'(?:(\d+)\.(\d+)\.(\d+)\.(\d+))?(?::)?(?:(\d+))?$', s)
    if not m:
        raise Fatal('%r is not a valid IP:port format' % s)
    (a, b, c, d, port) = m.groups()
    (a, b, c, d, port) = (int(a or 0), int(b or 0), int(c or 0), int(d or 0),
                          int(port or 0))
    if a > 255 or b > 255 or c > 255 or d > 255:
        raise Fatal('%d.%d.%d.%d has numbers > 255' % (a, b, c, d))
    if port > 65535:
        raise Fatal('*:%d is greater than the maximum of 65535' % port)
    if a is None:
        a = b = c = d = 0
    return ('%d.%d.%d.%d' % (a, b, c, d), port)
Exemplo n.º 6
0
def parse_ipport6(s):
    s = str(s)
    m = re.match(r'(?:\[([^]]*)])?(?::)?(?:(\d+))?$', s)
    if not m:
        raise Fatal('%s is not a valid IP:port format' % s)
    (ip, port) = m.groups()
    (ip, port) = (ip or '::', int(port or 0))
    return (ip, port)
Exemplo n.º 7
0
def parse_subnetport(s):
    if s.count(':') > 1:
        rx = r'(?:\[?([\w\:]+)(?:/(\d+))?]?)(?::(\d+)(?:-(\d+))?)?$'
    else:
        rx = r'([\w\.\-]+)(?:/(\d+))?(?::(\d+)(?:-(\d+))?)?$'

    m = re.match(rx, s)
    if not m:
        raise Fatal('%r is not a valid address/mask:port format' % s)

    addr, width, fport, lport = m.groups()
    try:
        addrinfo = socket.getaddrinfo(addr, 0, 0, socket.SOCK_STREAM)
    except socket.gaierror:
        raise Fatal('Unable to resolve address: %s' % addr)

    family, _, _, _, addr = min(addrinfo)
    max_width = 32 if family == socket.AF_INET else 128
    width = int(width or max_width)
    if not 0 <= width <= max_width:
        raise Fatal('width %d is not between 0 and %d' % (width, max_width))

    return (family, addr[0], width, int(fport or 0), int(lport or fport or 0))
Exemplo n.º 8
0
def parse_ipport(s):
    s = str(s)
    if s.isdigit():
        rx = r'()(\d+)$'
    elif ']' in s:
        rx = r'(?:\[([^]]+)])(?::(\d+))?$'
    else:
        rx = r'([\w\.\-]+)(?::(\d+))?$'

    m = re.match(rx, s)
    if not m:
        raise Fatal('%r is not a valid IP:port format' % s)

    ip, port = m.groups()
    ip = ip or '0.0.0.0'
    port = int(port or 0)

    try:
        addrinfo = socket.getaddrinfo(ip, port, 0, socket.SOCK_STREAM)
    except socket.gaierror:
        raise Fatal('%r is not a valid IP:port format' % s)

    family, _, _, _, addr = min(addrinfo)
    return (family,) + addr[:2]
Exemplo n.º 9
0
def parse_subnet_file(s):
    try:
        handle = open(s, 'r')
    except OSError:
        raise Fatal('Unable to open subnet file: %s' % s)

    raw_config_lines = handle.readlines()
    subnets = []
    for line_no, line in enumerate(raw_config_lines):
        line = line.strip()
        if len(line) == 0:
            continue
        if line[0] == '#':
            continue
        subnets.append(parse_subnet(line))

    return subnets