Example #1
0
def in6_getRandomizedIfaceId(ifaceid, previous=None):
    """
    Implements the interface ID generation algorithm described in RFC 3041.
    The function takes the Modified EUI-64 interface identifier generated
    as described in RFC 4291 and an optional previous history value (the
    first element of the output of this function). If no previous interface
    identifier is provided, a random one is generated. The function returns
    a tuple containing the randomized interface identifier and the history
    value (for possible future use). Input and output values are provided in
    a "printable" format as depicted below.

    ex::
        >>> in6_getRandomizedIfaceId('20b:93ff:feeb:2d3')
        ('4c61:76ff:f46a:a5f3', 'd006:d540:db11:b092')
        >>> in6_getRandomizedIfaceId('20b:93ff:feeb:2d3',
                                     previous='d006:d540:db11:b092')
        ('fe97:46fe:9871:bd38', 'eeed:d79c:2e3f:62e')
    """

    s = b""
    if previous is None:
        d = b"".join(chb(x) for x in range(256))
        for _ in range(8):
            s += chb(random.choice(d))
        previous = s
    s = inet_pton(socket.AF_INET6, "::" + ifaceid)[8:] + previous
    import hashlib
    s = hashlib.md5(s).digest()
    s1, s2 = s[:8], s[8:]
    s1 = chb(orb(s1[0]) | 0x04) + s1[1:]
    s1 = inet_ntop(socket.AF_INET6, b"\xff" * 8 + s1)[20:]
    s2 = inet_ntop(socket.AF_INET6, b"\xff" * 8 + s2)[20:]
    return (s1, s2)
Example #2
0
def teredoAddrExtractInfo(x):
    """
    Extract information from a Teredo address. Return value is
    a 4-tuple made of IPv4 address of Teredo server, flag value (int),
    mapped address (non obfuscated) and mapped port (non obfuscated).
    No specific checks are performed on passed address.
    """
    addr = inet_pton(socket.AF_INET6, x)
    server = inet_ntop(socket.AF_INET, addr[4:8])
    flag = struct.unpack("!H", addr[8:10])[0]
    mappedport = struct.unpack("!H", strxor(addr[10:12], b'\xff' * 2))[0]
    mappedaddr = inet_ntop(socket.AF_INET, strxor(addr[12:16], b'\xff' * 4))
    return server, flag, mappedaddr, mappedport
Example #3
0
def in6_getAddrType(addr):
    naddr = inet_pton(socket.AF_INET6, addr)
    paddr = inet_ntop(socket.AF_INET6, naddr)  # normalize
    addrType = 0
    # _Assignable_ Global Unicast Address space
    # is defined in RFC 3513 as those in 2000::/3
    if ((orb(naddr[0]) & 0xE0) == 0x20):
        addrType = (IPV6_ADDR_UNICAST | IPV6_ADDR_GLOBAL)
        if naddr[:2] == b' \x02':  # Mark 6to4 @
            addrType |= IPV6_ADDR_6TO4
    elif orb(naddr[0]) == 0xff:  # multicast
        addrScope = paddr[3]
        if addrScope == '2':
            addrType = (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_MULTICAST)
        elif addrScope == 'e':
            addrType = (IPV6_ADDR_GLOBAL | IPV6_ADDR_MULTICAST)
        else:
            addrType = (IPV6_ADDR_GLOBAL | IPV6_ADDR_MULTICAST)
    elif ((orb(naddr[0]) == 0xfe) and ((int(paddr[2], 16) & 0xC) == 0x8)):
        addrType = (IPV6_ADDR_UNICAST | IPV6_ADDR_LINKLOCAL)
    elif paddr == "::1":
        addrType = IPV6_ADDR_LOOPBACK
    elif paddr == "::":
        addrType = IPV6_ADDR_UNSPECIFIED
    else:
        # Everything else is global unicast (RFC 3513)
        # Even old deprecated (RFC3879) Site-Local addresses
        addrType = (IPV6_ADDR_GLOBAL | IPV6_ADDR_UNICAST)

    return addrType
Example #4
0
def in6_getLocalUniquePrefix():
    """
    Returns a pseudo-randomly generated Local Unique prefix. Function
    follows recommendation of Section 3.2.2 of RFC 4193 for prefix
    generation.
    """
    # Extracted from RFC 1305 (NTP) :
    # NTP timestamps are represented as a 64-bit unsigned fixed-point number,
    # in seconds relative to 0h on 1 January 1900. The integer part is in the
    # first 32 bits and the fraction part in the last 32 bits.

    # epoch = (1900, 1, 1, 0, 0, 0, 5, 1, 0)
    # x = time.time()
    # from time import gmtime, strftime, gmtime, mktime
    # delta = mktime(gmtime(0)) - mktime(self.epoch)
    # x = x-delta

    tod = time.time()  # time of day. Will bother with epoch later
    i = int(tod)
    j = int((tod - i) * (2**32))
    tod = struct.pack("!II", i, j)
    mac = RandMAC()
    # construct modified EUI-64 ID
    eui64 = inet_pton(socket.AF_INET6, '::' + in6_mactoifaceid(mac))[8:]
    import hashlib
    globalid = hashlib.sha1(tod + eui64).digest()[:5]
    return inet_ntop(socket.AF_INET6, b'\xfd' + globalid + b'\x00' * 10)
Example #5
0
def in6_getha(prefix):
    """
    Return the anycast address associated with all home agents on a given
    subnet.
    """
    r = in6_and(inet_pton(socket.AF_INET6, prefix), in6_cidr2mask(64))
    r = in6_or(r, inet_pton(socket.AF_INET6, '::fdff:ffff:ffff:fffe'))
    return inet_ntop(socket.AF_INET6, r)
Example #6
0
def in6_addrtomac(addr):
    """
    Extract the mac address from provided address. None is returned
    on error.
    """
    mask = inet_pton(socket.AF_INET6, "::ffff:ffff:ffff:ffff")
    x = in6_and(mask, inet_pton(socket.AF_INET6, addr))
    ifaceid = inet_ntop(socket.AF_INET6, x)[2:]
    return in6_ifaceidtomac(ifaceid)
Example #7
0
def in6_6to4ExtractAddr(addr):
    """
    Extract IPv4 address embedded in 6to4 address. Passed address must be
    a 6to4 address. None is returned on error.
    """
    try:
        addr = inet_pton(socket.AF_INET6, addr)
    except Exception:
        return None
    if addr[:2] != b" \x02":
        return None
    return inet_ntop(socket.AF_INET, addr[2:6])
Example #8
0
def in6_get6to4Prefix(addr):
    """
    Returns the /48 6to4 prefix associated with provided IPv4 address
    On error, None is returned. No check is performed on public/private
    status of the address
    """
    try:
        addr = inet_pton(socket.AF_INET, addr)
        addr = inet_ntop(socket.AF_INET6, b'\x20\x02' + addr + b'\x00' * 10)
    except Exception:
        return None
    return addr
Example #9
0
        def load_winpcapy():
            """This functions calls libpcap ``pcap_findalldevs`` function,
            and extracts and parse all the data scapy will need
            to build the Interface List.

            The date will be stored in ``conf.cache_iflist``, or accessible
            with ``get_if_list()``
            """
            err = create_string_buffer(PCAP_ERRBUF_SIZE)
            devs = POINTER(pcap_if_t)()
            if_list = {}
            if pcap_findalldevs(byref(devs), err) < 0:
                return
            try:
                p = devs
                # Iterate through the different interfaces
                while p:
                    name = plain_str(p.contents.name)  # GUID
                    description = plain_str(p.contents.description)  # NAME
                    flags = p.contents.flags  # FLAGS
                    ips = []
                    a = p.contents.addresses
                    while a:
                        # IPv4 address
                        family = a.contents.addr.contents.sa_family
                        ap = a.contents.addr
                        if family == socket.AF_INET:
                            val = cast(ap, POINTER(sockaddr_in))
                            val = val.contents.sin_addr[:]
                        elif family == socket.AF_INET6:
                            val = cast(ap, POINTER(sockaddr_in6))
                            val = val.contents.sin6_addr[:]
                        else:
                            # Unknown address family
                            # (AF_LINK isn't a thing on Windows)
                            a = a.contents.next
                            continue
                        addr = inet_ntop(family, bytes(bytearray(val)))
                        if addr != "0.0.0.0":
                            ips.append(addr)
                        a = a.contents.next
                    if_list[name] = (description, ips, flags)
                    p = p.contents.next
                conf.cache_iflist = if_list
            except Exception:
                raise
            finally:
                pcap_freealldevs(devs)
Example #10
0
def in6_ctop(addr):
    """
    Convert an IPv6 address in Compact Representation Notation
    (RFC 1924) to printable representation ;-)
    Returns None on error.
    """
    if len(addr) != 20 or not reduce(lambda x, y: x and y,
                                     [x in _rfc1924map for x in addr]):
        return None
    i = 0
    for c in addr:
        j = _rfc1924map.index(c)
        i = 85 * i + j
    res = []
    for j in range(4):
        res.append(struct.pack("!I", i % 2**32))
        i = i // (2**32)
    res.reverse()
    return inet_ntop(socket.AF_INET6, b"".join(res))
 def _resolve_ips(y):
     if not isinstance(y, list):
         return []
     ips = []
     for ip in y:
         addr = ip['address']['address'].contents
         if addr.si_family == socket.AF_INET6:
             ip_key = "Ipv6"
             si_key = "sin6_addr"
         else:
             ip_key = "Ipv4"
             si_key = "sin_addr"
         data = getattr(addr, ip_key)
         data = getattr(data, si_key)
         data = bytes(bytearray(data.byte))
         # Build IP
         if data:
             ips.append(inet_ntop(addr.si_family, data))
     return ips
Example #12
0
def get_if_addr(iff):
    return inet_ntop(socket.AF_INET, get_if_raw_addr(iff))
Example #13
0
def in6_ptop(str):
    """
    Normalizes IPv6 addresses provided in printable format, returning the
    same address in printable format. (2001:0db8:0:0::1 -> 2001:db8::1)
    """
    return inet_ntop(socket.AF_INET6, inet_pton(socket.AF_INET6, str))
Example #14
0
def in6_getLinkScopedMcastAddr(addr, grpid=None, scope=2):
    """
    Generate a Link-Scoped Multicast Address as described in RFC 4489.
    Returned value is in printable notation.

    'addr' parameter specifies the link-local address to use for generating
    Link-scoped multicast address IID.

    By default, the function returns a ::/96 prefix (aka last 32 bits of
    returned address are null). If a group id is provided through 'grpid'
    parameter, last 32 bits of the address are set to that value (accepted
    formats : b'\x12\x34\x56\x78' or '12345678' or 0x12345678 or 305419896).

    By default, generated address scope is Link-Local (2). That value can
    be modified by passing a specific 'scope' value as an argument of the
    function. RFC 4489 only authorizes scope values <= 2. Enforcement
    is performed by the function (None will be returned).

    If no link-local address can be used to generate the Link-Scoped IPv6
    Multicast address, or if another error occurs, None is returned.
    """
    if scope not in [0, 1, 2]:
        return None
    try:
        if not in6_islladdr(addr):
            return None
        addr = inet_pton(socket.AF_INET6, addr)
    except Exception:
        warning("in6_getLinkScopedMcastPrefix(): Invalid address provided")
        return None

    iid = addr[8:]

    if grpid is None:
        grpid = b'\x00\x00\x00\x00'
    else:
        if isinstance(grpid, (bytes, str)):
            if len(grpid) == 8:
                try:
                    grpid = int(grpid, 16) & 0xffffffff
                except Exception:
                    warning(
                        "in6_getLinkScopedMcastPrefix(): Invalid group id provided"
                    )  # noqa: E501
                    return None
            elif len(grpid) == 4:
                try:
                    grpid = struct.unpack("!I", grpid)[0]
                except Exception:
                    warning(
                        "in6_getLinkScopedMcastPrefix(): Invalid group id provided"
                    )  # noqa: E501
                    return None
        grpid = struct.pack("!I", grpid)

    flgscope = struct.pack("B", 0xff & ((0x3 << 4) | scope))
    plen = b'\xff'
    res = b'\x00'
    a = b'\xff' + flgscope + res + plen + iid + grpid

    return inet_ntop(socket.AF_INET6, a)