예제 #1
0
def get_ips_list(ranges):
    """Get the IP addresses list from a list of ranges.

    :param list ranges: List of ranges.
    :returns: List of IP addresses.
    :rtype: list of cidr ips
            (https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing)
    """
    ip_set = IPSet()

    for ip_range in ranges:
        try:
            # It's a glob
            if '*' in ip_range or '-' in ip_range:
                ip_set.add(IPGlob(ip_range))
            # It's a network
            elif '/' in ip_range:
                ip_set.add(IPNetwork(ip_range))
            # Simple IP
            else:
                ip_set.add(IPAddress(ip_range))
        except Exception:
            pass

    return [str(ip.cidr) for ip in ip_set.iter_cidrs()]
예제 #2
0
def is_ip_in_list(ip_address, addresses_list):
    """Check if address IP is in list.

    :param ip_address: Address IP to check
    :param addresses_list: Range of IP, network or simple IP.
    :returns: True if given IP is in list.
    """
    if not isinstance(addresses_list, list):
        raise Exception('Given parameter is not a list.')

    ip_set = IPSet()

    for ip_range in addresses_list:
        try:
            # It's a glob
            if '*' in ip_range or '-' in ip_range:
                ip_set.add(IPGlob(ip_range))
            # It's a network
            elif '/' in ip_range:
                ip_set.add(IPNetwork(ip_range))
            # Simple IP
            else:
                ip_set.add(IPAddress(ip_range))
        except Exception:
            pass

    try:
        return ip_address in ip_set
    except Exception:
        return False
예제 #3
0
    def _get_ips_from_glob(glob_ips):
        ip_glob = IPGlob(glob_ips)

        ips = set()

        for ip in ip_glob:
            ips.add(str(ip))

        return ips
예제 #4
0
    def ipglob(self, *args):
        """Returns a random address from within the given ip global
        https://pythonhosted.org/netaddr/api.html#ip-glob-ranges
            IPGLOB:GLOB

        %{IPGLOB:*.*.*.*} -> ''
        """
        call_args = list(args)
        return self.random.choice(IPGlob(call_args.pop(0)))
예제 #5
0
def proxy_list(human_readable):
    globs = []
    addrs = []
    for item in human_readable:
        if '*' in item or '-' in item:
            globs.append(IPGlob(item))
        else:
            addrs.append(item)
    return IPSet(chain(chain.from_iterable(globs), addrs))
예제 #6
0
    def test_make_ip_set(self):
        def is_in(ipaddr, ipset):
            ipset = make_ip_set(ipset)
            return IPAddress(ipaddr) in ipset

        #  Test individual IPs
        self.assertTrue(is_in("127.0.0.1", "127.0.0.1"))
        self.assertFalse(is_in("127.0.0.2", "127.0.0.1"))
        #  Test globbing
        self.assertTrue(is_in("127.0.0.1", "127.0.0.*"))
        self.assertTrue(is_in("127.0.1.2", "127.0.*.*"))
        self.assertTrue(is_in("127.0.0.1", "127.0.0.*"))
        self.assertFalse(is_in("127.0.1.2", "127.0.0.*"))
        self.assertTrue(is_in("127.0.0.1", "127.0.0.1-5"))
        self.assertTrue(is_in("127.0.0.5", "127.0.0.1-5"))
        self.assertFalse(is_in("127.0.0.6", "127.0.0.1-5"))
        #  Test networks
        self.assertTrue(is_in("127.0.0.1", "127.0.0.0/8"))
        self.assertTrue(is_in("127.0.0.1", "127.0.0.0/16"))
        self.assertTrue(is_in("127.0.0.1", "127.0.0.0/24"))
        self.assertFalse(is_in("127.0.1.2", "127.0.0.0/24"))
        #  Test literal None
        self.assertFalse(is_in("127.0.0.1", None))
        #  Test special strings
        self.assertTrue(is_in("127.0.0.1", "local"))
        self.assertTrue(is_in("127.0.0.1", "all"))
        GOOGLE_DOT_COM = "74.125.237.20"
        self.assertFalse(is_in(GOOGLE_DOT_COM, "local"))
        self.assertTrue(is_in(GOOGLE_DOT_COM, "all"))
        #  Test with a list of stuff
        ips = ["127.0.0.1", "127.0.1.*"]
        self.assertTrue(is_in("127.0.0.1", ips))
        self.assertTrue(is_in("127.0.1.1", ips))
        self.assertFalse(is_in("127.0.0.2", ips))
        self.assertTrue(is_in("127.0.1.2", ips))
        #  Test with a string-list of stuff
        ips = "123.123.0.0/16 local"
        self.assertTrue(is_in("127.0.0.1", ips))
        self.assertTrue(is_in("127.0.1.1", ips))
        self.assertTrue(is_in("123.123.1.1", ips))
        self.assertFalse(is_in("124.0.0.1", ips))
        #  Test with list-splitting edge-cases
        self.assertTrue(is_in("127.0.0.1", "127.0.0.2,127.0.0.1"))
        self.assertTrue(is_in("127.0.0.1", "127.0.0.2,  127.0.0.1"))
        self.assertTrue(is_in("127.0.0.1", "127.0.0.2 127.0.0.1"))
        #  Test with various strange inputs to the parser
        self.assertTrue(is_in("127.0.0.1", IPAddress("127.0.0.1")))
        self.assertTrue(is_in("127.0.0.1", int(IPAddress("127.0.0.1"))))
        self.assertTrue(is_in("127.0.0.1", IPNetwork("127.0.0.1/8")))
        self.assertTrue(is_in("127.0.0.1", IPGlob("127.0.0.*")))
        self.assertTrue(is_in("127.0.0.1", IPRange("127.0.0.1", "127.0.0.2")))
        self.assertTrue(is_in("127.0.0.1", IPSet(["127.0.0.1/8"])))
        self.assertFalse(is_in("127.0.0.1", ""))
        self.assertFalse(is_in("127.0.0.1", None))
        self.assertRaises(ValueError, is_in, "127.0.0.1", 3.14159)
        self.assertRaises(ValueError, is_in, "127.0.0.1", Ellipsis)
예제 #7
0
파일: helpers.py 프로젝트: slsscs/ssoj
    def with_proxy_set(cls, ranges):
        from netaddr import IPSet, IPGlob
        from itertools import chain

        globs = []
        addrs = []
        for item in ranges:
            if '*' in item or '-' in item:
                globs.append(IPGlob(item))
            else:
                addrs.append(item)
        ipset = IPSet(chain(chain.from_iterable(globs), addrs))
        return type(cls.__name__, (cls, ), {'_REAL_IP_SET': ipset})
예제 #8
0
def ipglob(glob):
    """
    Returns an IPGlob object from the netaddr library.

    >>> glob = ipglob("192.168.32.*")
    >>> type(glob)
    <class 'netaddr.ip.glob.IPGlob'>
    >>> glob.is_private()
    True
    """

    from netaddr import IPGlob

    return IPGlob(glob)
 def ipstr2range(ip_str, format='range'):
     init = IPRange if format == 'range' else IPSet
     if ip_str == '*':
         ip_str = '0.0.0.0/0'
     if '*' in ip_str:
         ipglob = IPGlob(ip_str)
         iprange = IPRange(ipglob[0], ipglob[-1])
         return iprange if format == 'range' else init(iprange)
     if '-' in ip_str:
         start, end = ip_str.split('-')
         iprange = IPRange(start, end)  # start[:start.rindex('.') + 1] +
         return iprange if format == 'range' else init(iprange)
     else:
         if format == 'range':
             network = IPNetwork(ip_str)
             return init(network[0], network[-1])
         return init([ip_str])
예제 #10
0
def parse_ip_set(ipaddrs):
    """Parse a string specification into an IPSet.

    This function takes a string representing a set of IP addresses and
    parses it into an IPSet object.  Acceptable formats for the string
    include:

        * "all":        all possible IPv4 and IPv6 addresses
        * "local":      all local addresses of the machine
        * "A.B.C.D"     a single IP address
        * "A.B.C.D/N"   a network address specification
        * "A.B.C.*"     a glob matching against all possible numbers
        * "A.B.C.D-E"   a glob matching against a range of numbers
        * a whitespace- or comma-separated string of the above

    """
    ipset = IPSet()
    ipaddrs = ipaddrs.lower().strip()
    if not ipaddrs:
        return ipset
    for ipspec in _COMMA_OR_WHITESPACE.split(ipaddrs):
        # The string "local" maps to all local addresses on the machine.
        if ipspec == "local":
            ipset.add(IPNetwork("127.0.0.0/8"))
            for addr in get_local_ip_addresses():
                ipset.add(addr)
        # The string "all" maps to app IPv4 and IPv6 addresses.
        elif ipspec == "all":
            ipset.add(IPNetwork("0.0.0.0/0"))
            ipset.add(IPNetwork("::"))
        # Strings containing a "/" are assumed to be network specs
        elif "/" in ipspec:
            ipset.add(IPNetwork(ipspec))
        # Strings containing a "*" or "-" are assumed to be glob patterns
        elif "*" in ipspec or "-" in ipspec:
            for cidr in IPGlob(ipspec).cidrs():
                ipset.add(cidr)
        # Anything else must be a single address
        else:
            ipset.add(IPAddress(ipspec))
    return ipset
예제 #11
0
    def __init__(self, ip_list=[], hostname_list=[], netblock_list=[], netrange_list=[], auto_coalesce_ip=True,
                 auto_resolve_hostnames=False):
        self._auto_coalesce = auto_coalesce_ip
        self._auto_resolve_hostnames = auto_resolve_hostnames

        not_ip = [x for x in ip_list if not Scope.is_ip(x)]
        if not_ip:
            raise ValueError('Value(s) ' + str(not_ip) + ' are provided as IP but cannot be casted as such')
        self._ip_list = IPSet(ip_list)

        not_hostname = [x for x in hostname_list if not Scope.is_hostname(x)]
        if not_hostname:
            raise ValueError('Value(s) ' + str(not_hostname) + ' are provided as hostnames but cannot be casted as such')
        self._hostname_list = set(hostname_list)

        not_netblock = [x for x in netblock_list if not Scope.is_netblock(x)]
        if not_netblock:
            raise ValueError('Value(s) ' + str(not_netblock) + ' are provided as netblocks but cannot be casted as such')
        self._netblock_list = set(IPNetwork(x) for x in set(netblock_list))

        not_netrange = [x for x in netrange_list if not Scope.is_netrange(x)]
        if not_netrange:
            raise ValueError('Value(s) ' + str(not_netrange) + ' are provided as netranges but cannot be casted as such')
        self._netrange_list = set()
        for netrange in set(netrange_list):
            if self._netrange_ip_to_int(netrange):
                self._netrange_list.add(IPGlob(netrange))
            else:
                (ip1, ip2) = (x.strip() for x in netrange.split('-'))
                self._netrange_list.add(IPRange(ip1, ip2))

        if self._auto_resolve_hostnames:
            self._resolve_hostnames()

        if self._auto_coalesce:
            self._coalesce_ip_list()
예제 #12
0
def cidrize(ipstr, strict=False, modular=True):
    """
    This function tries to determine the best way to parse IP addresses correctly & has
    all the logic for trying to do the right thing!

    Returns a list of consolidated netaddr objects.

    Input can be several formats::

        '192.0.2.18'
        '192.0.2.64/26'
        '192.0.2.80-192.0.2.85'
        '192.0.2.170-175'
        '192.0.2.8[0-5]'
        '192.0.2.[0-29]'
        '192.168.4.6[1234]'
        '1.2.3.*'
        '192.0.2.170-175, 192.0.2.80-192.0.2.85, 192.0.2.64/26'

    Hyphenated ranges do not need to form a CIDR block. Netaddr does most of
    the heavy lifting for us here.

    Input can NOT be::

        192.0.2.0 0.0.0.255 (hostmask)
        192.0.2.0 255.255.255.0 (netmask)

    Does NOT accept network or host mask notation at this time!

    Defaults:

        * parsing exceptions will raise a CidrizeError (modular=True).
        * results will be returned as a spanning CIDR (strict=False).

    :param ipstr:
        IP string to be parsed.

    :param modular:
        Set to False to cause exceptions to be stripped & the error text will be
        returned as a list. This is intended for use with scripts or APIs
        out-of-the box.

    Example:
        >>> import cidrize as c
        >>> c.cidrize('1.2.3.4-1.2.3.1099')
        Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
          File "/home/j/jathan/sandbox/cidrize.py", line 153, in cidrize
            raise CidrizeError(err)
        cidrize.CidrizeError: base address '1.2.3.1099' is not IPv4

        >>> c.cidrize('1.2.3.4-1.2.3.1099', modular=False)
        ["base address '1.2.3.1099' is not IPv4"]

    :param strict:
        Set to True to return explicit networks based on start/end addresses.

    Example:
        >>> import cidrize as c
        >>> c.cidrize('1.2.3.4-1.2.3.10')
        [IPNetwork('1.2.3.0/28')]

        >>> c.cidrize('1.2.3.4-1.2.3.10', strict=True)
        [IPNetwork('1.2.3.4/30'), IPNetwork('1.2.3.8/31'), IPNetwork('1.2.3.10/32')]

    """
    ip = None

    # Short-circuit to parse commas since it calls back here anyway
    if ',' in ipstr:
        return parse_commas(ipstr, strict=strict, modular=modular)

    # Short-circuit for hostnames (we're assuming first char is alpha)
    if hostname_re.match(ipstr):
        raise CidrizeError('Cannot parse hostnames!')

    # Otherwise try everything else
    result = None
    try:
        # Parse "everything" & immediately return; strict/loose doesn't apply
        if ipstr in EVERYTHING:
            log.debug("Trying everything style...")
            return [IPNetwork('0.0.0.0/0')]

        # Parse old-fashioned CIDR notation & immediately return; strict/loose doesn't apply
        # Now with IPv6!
        elif cidr_re.match(ipstr) or is_ipv6(ipstr):
            log.debug("Trying CIDR style...")
            ip = IPNetwork(ipstr)
            return [ip.cidr]

        # Parse 1.2.3.118-1.2.3.121 range style
        elif range_re.match(ipstr):
            log.debug("Trying range style...")
            result = parse_range(ipstr)

        # Parse 1.2.3.4-70 hyphen style
        elif hyphen_re.match(ipstr):
            log.debug("Trying hyphen style...")
            result = parse_hyphen(ipstr)

        # Parse 1.2.3.* glob style
        elif glob_re.match(ipstr):
            log.debug("Trying glob style...")
            ipglob = IPGlob(ipstr)
            result = spanning_cidr(ipglob)

        # Parse 1.2.3.4[5-9] or 1.2.3.[49] bracket style as a last resort
        elif bracket_re.match(ipstr):
            log.debug("Trying bracket style...")
            result = parse_brackets(ipstr)

        # If result still isn't set, let's see if it's IPv6??
        elif result is None:
            log.debug("Trying bare IPv6 parse...")
            result = IPNetwork(ipstr)

        # This will probably fail 100% of the time. By design.
        else:
            raise CidrizeError("Could not determine parse style for '%s'" %
                               ipstr)

        # If it's a single host, just return it wrapped in a list
        if result.size == 1:
            log.debug("Returning a single host!")
            return [result.cidr]

        # Logic to honor strict/loose, except IPRange. Doing a spanning_cidr on
        # an IPRange can be super slow if the range is large (such as a /8), so
        # IPRange objects larger than MAX_RANGE_LEN will always be strict.
        if not strict:
            if isinstance(result, IPRange) and result.size >= MAX_RANGE_LEN:
                log.debug(
                    'IPRange objects larger than /18 will always be strict.')
                return result.cidrs()
            return [spanning_cidr(result)]
        else:
            try:
                return result.cidrs()  # IPGlob and IPRange have .cidrs()
            except AttributeError as err:
                return result.cidr  # IPNetwork has .cidr

    except (AddrFormatError, TypeError, ValueError) as err:
        if modular:
            raise CidrizeError(err)
        return [str(err)]
예제 #13
0
def test_ipglob_boolean_evaluation():
    assert bool(IPGlob('*.*.*.*'))
    assert bool(IPGlob('0.0.0.0'))
예제 #14
0
def test_ipglob_basic():
    #TODO: do the same testing on IPGlob as IPRange.
    assert IPGlob('192.0.2.*') == IPNetwork('192.0.2.0/24')