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 diffplot(self, f, delay=1, lfilter=None, **kargs):
        # type: (Callable, int, Optional[Callable], Any) -> Line2D
        """diffplot(f, delay=1, lfilter=None)
        Applies a function to couples (l[i],l[i+delay])

        A list of matplotlib.lines.Line2D is returned.
        """

        # Get the list of packets
        if lfilter is None:
            lst_pkts = [
                f(self.res[i], self.res[i + 1])
                for i in range(len(self.res) - delay)
            ]
        else:
            lst_pkts = [
                f(self.res[i], self.res[i + 1])
                for i in range(len(self.res) - delay) if lfilter(self.res[i])
            ]

        # Mimic the default gnuplot output
        if kargs == {}:
            kargs = MATPLOTLIB_DEFAULT_PLOT_KARGS
        lines = plt.plot(lst_pkts, **kargs)

        # Call show() if matplotlib is not inlined
        if not MATPLOTLIB_INLINED:
            plt.show()

        return lines
Example #3
0
 def rec(n, li):
     sep = ':' if n and n % 2 == 0 else ''
     if n == 16:
         return li
     return rec(
         n + 1,
         [
             y + sep + '%.2x' % i
             # faster than '%s%s%.2x' % (y, sep, i)
             for i in range(*self.parsed[n]) for y in li
         ])
Example #4
0
def get_alias_address(iface_name, ip_mask, gw_str, metric):
    """
    Get the correct source IP address of an interface alias
    """

    # Detect the architecture
    if consts.IS_64BITS:
        offset, name_len = 16, 40
    else:
        offset, name_len = 32, 32

    # Retrieve interfaces structures
    sck = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    names = array.array('B', b'\0' * 4096)
    ifreq = ioctl(sck.fileno(), SIOCGIFCONF,
                  struct.pack("iL", len(names),
                              names.buffer_info()[0]))

    # Extract interfaces names
    out = struct.unpack("iL", ifreq)[0]
    names = names.tobytes() if six.PY3 else names.tostring()
    names = [
        names[i:i + offset].split(b'\0', 1)[0]
        for i in range(0, out, name_len)
    ]  # noqa: E501

    # Look for the IP address
    for ifname in names:
        # Only look for a matching interface name
        if not ifname.decode("utf8").startswith(iface_name):
            continue

        # Retrieve and convert addresses
        ifreq = ioctl(sck, SIOCGIFADDR, struct.pack("16s16x", ifname))
        ifaddr = struct.unpack(">I", ifreq[20:24])[0]
        ifreq = ioctl(sck, SIOCGIFNETMASK, struct.pack("16s16x", ifname))
        msk = struct.unpack(">I", ifreq[20:24])[0]

        # Get the full interface name
        ifname = plain_str(ifname)
        if ':' in ifname:
            ifname = ifname[:ifname.index(':')]
        else:
            continue

        # Check if the source address is included in the network
        if (ifaddr & msk) == ip_mask:
            sck.close()
            return (ifaddr & msk, msk, gw_str, ifname, utils.ltoa(ifaddr),
                    metric)

    sck.close()
    return
Example #5
0
def _get_values(value):
    """Generate a range object from (start, stop[, step]) tuples, or
    return value.

    """
    if (isinstance(value, tuple) and (2 <= len(value) <= 3)
            and all(hasattr(i, "__int__") for i in value)):
        # We use values[1] + 1 as stop value for (x)range to maintain
        # the behavior of using tuples as field `values`
        return range(*((int(value[0]), int(value[1]) + 1) +
                       tuple(int(v) for v in value[2:])))
    return value
Example #6
0
    def _parse(self):
        def parse_digit(value, netmask):
            netmask = min(8, max(netmask, 0))
            value = int(value)
            return (value & (0xff << netmask), (value | (0xff >>
                                                         (8 - netmask))) + 1)

        self.parsed = [
            parse_digit(x, y) for x, y in zip(
                struct.unpack("16B", in6_and(self.net, self.mask)),
                (x - self.plen for x in range(8, 129, 8)),
            )
        ]
Example #7
0
def in6_get_common_plen(a, b):
    """
    Return common prefix length of IPv6 addresses a and b.
    """
    def matching_bits(byte1, byte2):
        for i in range(8):
            cur_mask = 0x80 >> i
            if (byte1 & cur_mask) != (byte2 & cur_mask):
                return i
        return 8

    tmpA = inet_pton(socket.AF_INET6, a)
    tmpB = inet_pton(socket.AF_INET6, b)
    for i in range(16):
        mbits = matching_bits(orb(tmpA[i]), orb(tmpB[i]))
        if mbits != 8:
            return 8 * i + mbits
    return 128
Example #8
0
def in6_cidr2mask(m):
    """
    Return the mask (bitstring) associated with provided length
    value. For instance if function is called on 48, return value is
    b'\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'.

    """
    if m > 128 or m < 0:
        raise Scapy_Exception(
            "value provided to in6_cidr2mask outside [0, 128] domain (%d)" %
            m)  # noqa: E501

    t = []
    for i in range(0, 4):
        t.append(max(0, 2**32 - 2**(32 - min(32, m))))
        m -= 32

    return b"".join(struct.pack('!I', x) for x in t)
Example #9
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))
Example #10
0
def in6_ptoc(addr):
    """
    Converts an IPv6 address in printable representation to RFC
    1924 Compact Representation ;-)
    Returns None on error.
    """
    try:
        d = struct.unpack("!IIII", inet_pton(socket.AF_INET6, addr))
    except Exception:
        return None
    res = 0
    m = [2**96, 2**64, 2**32, 1]
    for i in range(4):
        res += d[i] * m[i]
    rem = res
    res = []
    while rem:
        res.append(_rfc1924map[rem % 85])
        rem = rem // 85
    res.reverse()
    return "".join(res)
Example #11
0
def _inet6_ntop(addr):
    """Convert an IPv6 address from binary form into text representation,
used when socket.inet_pton is not available.

    """
    # IPv6 addresses have 128bits (16 bytes)
    if len(addr) != 16:
        raise ValueError("invalid length of packed IP address string")

    # Decode to hex representation
    address = ":".join(plain_str(bytes_hex(addr[idx:idx + 2])).lstrip('0') or '0'  # noqa: E501
                       for idx in range(0, 16, 2))

    try:
        # Get the longest set of zero blocks. We need to take a look
        # at group 1 regarding the length, as 0:0:1:0:0:2:3:4 would
        # have two matches: 0:0: and :0:0: where the latter is longer,
        # though the first one should be taken. Group 1 is in both
        # cases 0:0.
        match = max(_IP6_ZEROS.finditer(address),
                    key=lambda m: m.end(1) - m.start(1))
        return '{}::{}'.format(address[:match.start()], address[match.end():])
    except ValueError:
        return address
Example #12
0
 def matching_bits(byte1, byte2):
     for i in range(8):
         cur_mask = 0x80 >> i
         if (byte1 & cur_mask) != (byte2 & cur_mask):
             return i
     return 8
Example #13
0
 def __iter__(self):
     for d in range(*self.parsed[3]):
         for c in range(*self.parsed[2]):
             for b in range(*self.parsed[1]):
                 for a in range(*self.parsed[0]):
                     yield "%i.%i.%i.%i" % (a, b, c, d)