示例#1
0
def get_if_raw_hwaddr(ifname):
    """Returns the packed MAC address configured on 'ifname'."""

    NULL_MAC_ADDRESS = b'\x00' * 6

    # Handle the loopback interface separately
    if ifname == conf.loopback_name:
        return (ARPHDR_LOOPBACK, NULL_MAC_ADDRESS)

    # Get ifconfig output
    subproc = subprocess.Popen([conf.prog.ifconfig, ifname],
                               close_fds=True,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)
    stdout, stderr = subproc.communicate()
    if subproc.returncode:
        raise Scapy_Exception("Failed to execute ifconfig: (%s)" %
                              (plain_str(stderr)))

    # Get MAC addresses
    addresses = [
        line for line in plain_str(stdout).splitlines()
        if ("ether" in line or "lladdr" in line or "address" in line)
    ]
    if not addresses:
        raise Scapy_Exception("No MAC address found on %s !" % ifname)

    # Pack and return the MAC address
    mac = addresses[0].split(' ')[1]
    mac = [chr(int(b, 16)) for b in mac.split(':')]
    return (ARPHDR_ETHER, ''.join(mac))
示例#2
0
def get_if_raw_addr(ifname):
    """Returns the IPv4 address configured on 'ifname', packed with inet_pton."""  # noqa: E501

    # Get ifconfig output
    subproc = subprocess.Popen([conf.prog.ifconfig, ifname],
                               close_fds=True,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)
    stdout, stderr = subproc.communicate()
    if subproc.returncode:
        warning("Failed to execute ifconfig: (%s)", plain_str(stderr))
        return b"\0\0\0\0"
    # Get IPv4 addresses

    addresses = [
        line for line in plain_str(stdout).splitlines() if "inet " in line
    ]

    if not addresses:
        warning("No IPv4 address found on %s !", ifname)
        return b"\0\0\0\0"

    # Pack the first address
    address = addresses[0].split(' ')[1]
    if '/' in address:  # NetBSD 8.0
        address = address.split("/")[0]
    return socket.inet_pton(socket.AF_INET, address)
示例#3
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)
示例#4
0
def get_if_list():
    """Returns a list containing all network interfaces."""

    # Get ifconfig output
    subproc = subprocess.Popen([conf.prog.ifconfig],
                               close_fds=True,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)
    stdout, stderr = subproc.communicate()
    if subproc.returncode:
        raise Scapy_Exception("Failed to execute ifconfig: (%s)" %
                              (plain_str(stderr)))

    interfaces = [
        line[:line.find(':')] for line in plain_str(stdout).splitlines()
        if ": flags" in line.lower()
    ]
    return interfaces
示例#5
0
def inet_pton(af, addr):
    """Convert an IP address from text representation into binary form."""
    # Will replace Net/Net6 objects
    addr = plain_str(addr)
    # Use inet_pton if available
    try:
        return socket.inet_pton(af, addr)
    except AttributeError:
        try:
            return _INET_PTON[af](addr)
        except KeyError:
            raise socket.error("Address family not supported by protocol")
示例#6
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
示例#7
0
def fixname(x):
    """
    Modifies a string to make sure it can be used as an attribute name.
    """
    x = plain_str(x)
    if x and str(x[0]) in "0123456789":
        x = "n_" + x
    return x.translate("________________________________________________"
                       "0123456789_______ABCDEFGHIJKLMNOPQRSTUVWXYZ______"
                       "abcdefghijklmnopqrstuvwxyz____________________________"
                       "______________________________________________________"
                       "___________________________________________________")
示例#8
0
def read_routes6():
    try:
        f = open("/proc/net/ipv6_route", "rb")
    except IOError:
        return []
    # 1. destination network
    # 2. destination prefix length
    # 3. source network displayed
    # 4. source prefix length
    # 5. next hop
    # 6. metric
    # 7. reference counter (?!?)
    # 8. use counter (?!?)
    # 9. flags
    # 10. device name
    routes = []

    def proc2r(p):
        ret = struct.unpack('4s4s4s4s4s4s4s4s', p)
        ret = b':'.join(ret).decode()
        return utils6.in6_ptop(ret)

    lifaddr = in6_getifaddr()
    for line in f.readlines():
        d, dp, _, _, nh, metric, rc, us, fl, dev = line.split()
        metric = int(metric, 16)
        fl = int(fl, 16)
        dev = plain_str(dev)

        if fl & RTF_UP == 0:
            continue
        if fl & RTF_REJECT:
            continue

        d = proc2r(d)
        dp = int(dp, 16)
        nh = proc2r(nh)

        cset = []  # candidate set (possible source addresses)
        if dev == conf.loopback_name:
            if d == '::':
                continue
            cset = ['::1']
        else:
            devaddrs = (x for x in lifaddr if x[2] == dev)
            cset = utils6.construct_source_candidate_set(d, dp, devaddrs)

        if len(cset) != 0:
            routes.append((d, dp, nh, dev, cset, metric))
    f.close()
    return routes
示例#9
0
def get_if_lists():
    """Returns a list containing all network interfaces."""

    # Get ifconfig output
    subproc = subprocess.Popen([conf.prog.ifconfig],
                               close_fds=True,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)
    stdout, stderr = subproc.communicate()
    if subproc.returncode:
        raise Scapy_Exception("Failed to execute ifconfig: (%s)" %
                              (plain_str(stderr)))

    interfaces = []
    ips = []
    for line in plain_str(stdout).splitlines():
        if ": flags" in line.lower():
            interfaces.append(line[:line.find(':')])
        elif "inet " in line.lower():
            ips.append(
                line.split("inet")[1].split("netmask")[0].replace(" ", ''))

    return interfaces, ips
示例#10
0
def _inet6_pton(addr):
    """Convert an IPv6 address from text representation into binary form,
used when socket.inet_pton is not available.

    """
    joker_pos = None
    result = b""
    addr = plain_str(addr)
    if addr == '::':
        return b'\x00' * 16
    if addr.startswith('::'):
        addr = addr[1:]
    if addr.endswith('::'):
        addr = addr[:-1]
    parts = addr.split(":")
    nparts = len(parts)
    for i, part in enumerate(parts):
        if not part:
            # "::" indicates one or more groups of 2 null bytes
            if joker_pos is None:
                joker_pos = len(result)
            else:
                # Wildcard is only allowed once
                raise _INET6_PTON_EXC
        elif i + 1 == nparts and '.' in part:
            # The last part of an IPv6 address can be an IPv4 address
            if part.count('.') != 3:
                # we have to do this since socket.inet_aton('1.2') ==
                # b'\x01\x00\x00\x02'
                raise _INET6_PTON_EXC
            try:
                result += socket.inet_aton(part)
            except socket.error:
                raise _INET6_PTON_EXC
        else:
            # Each part must be 16bit. Add missing zeroes before decoding.
            try:
                result += hex_bytes(part.rjust(4, "0"))
            except (binascii.Error, TypeError):
                raise _INET6_PTON_EXC
    # If there's a wildcard, fill up with zeros to reach 128bit (16 bytes)
    if joker_pos is not None:
        if len(result) == 16:
            raise _INET6_PTON_EXC
        result = (result[:joker_pos] + b"\x00" * (16 - len(result)) +
                  result[joker_pos:])
    if len(result) != 16:
        raise _INET6_PTON_EXC
    return result
示例#11
0
def load_manuf(filename):
    """
    Loads manuf file from Wireshark.

    :param filename: the file to load the manuf file from
    :returns: a ManufDA filled object
    """
    manufdb = ManufDA(_name=filename)
    with open(filename, "rb") as fdesc:
        for line in fdesc:
            try:
                line = line.strip()
                if not line or line.startswith(b"#"):
                    continue
                parts = line.split(None, 2)
                ouib, shrt = parts[:2]
                lng = parts[2].lstrip(b"#").strip() if len(parts) > 2 else b""
                lng = lng or shrt
                oui = plain_str(ouib)
                manufdb[oui] = plain_str(shrt), plain_str(lng)
            except Exception:
                log_loading.warning("Couldn't parse one line from [%s] [%r]",
                                    filename, line, exc_info=True)
    return manufdb
示例#12
0
def get_if_list():
    try:
        f = open("/proc/net/dev", "rb")
    except IOError:
        try:
            f.close()
        except Exception:
            pass
        warning("Can't open /proc/net/dev !")
        return []
    lst = []
    f.readline()
    f.readline()
    for line in f:
        line = plain_str(line)
        lst.append(line.split(":")[0].strip())
    f.close()
    return lst
示例#13
0
def in6_getifaddr():
    """
    Returns a list of 3-tuples of the form (addr, scope, iface) where
    'addr' is the address of scope 'scope' associated to the interface
    'iface'.

    This is the list of all addresses of all interfaces available on
    the system.
    """
    ret = []
    try:
        fdesc = open("/proc/net/if_inet6", "rb")
    except IOError:
        return ret
    for line in fdesc:
        # addr, index, plen, scope, flags, ifname
        tmp = plain_str(line).split()
        addr = utils6.in6_ptop(b':'.join(
            struct.unpack('4s4s4s4s4s4s4s4s', tmp[0].encode())).decode())
        # (addr, scope, iface)
        ret.append((addr, int(tmp[3], 16), tmp[5]))
    fdesc.close()
    return ret
示例#14
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
示例#15
0
def read_routes():
    try:
        f = open("/proc/net/route", "rb")
    except IOError:
        warning("Can't open /proc/net/route !")
        return []
    routes = []
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        ifreq = ioctl(
            s, SIOCGIFADDR,
            struct.pack("16s16x",
                        conf.loopback_name.encode("utf8")))  # noqa: E501
        addrfamily = struct.unpack("h", ifreq[16:18])[0]
        if addrfamily == socket.AF_INET:
            ifreq2 = ioctl(
                s, SIOCGIFNETMASK,
                struct.pack("16s16x",
                            conf.loopback_name.encode("utf8")))  # noqa: E501
            msk = socket.ntohl(struct.unpack("I", ifreq2[20:24])[0])
            dst = socket.ntohl(struct.unpack("I", ifreq[20:24])[0]) & msk
            ifaddr = utils.inet_ntoa(ifreq[20:24])
            routes.append((dst, msk, "0.0.0.0", conf.loopback_name, ifaddr,
                           1))  # noqa: E501
        else:
            warning("Interface %s: unknown address family (%i)" %
                    (conf.loopback_name, addrfamily))  # noqa: E501
    except IOError as err:
        if err.errno == 99:
            warning("Interface %s: no address assigned" %
                    conf.loopback_name)  # noqa: E501
        else:
            warning("Interface %s: failed to get address config (%s)" %
                    (conf.loopback_name, str(err)))  # noqa: E501

    for line in f.readlines()[1:]:
        line = plain_str(line)
        iff, dst, gw, flags, _, _, metric, msk, _, _, _ = line.split()
        flags = int(flags, 16)
        if flags & RTF_UP == 0:
            continue
        if flags & RTF_REJECT:
            continue
        try:
            ifreq = ioctl(s, SIOCGIFADDR,
                          struct.pack("16s16x",
                                      iff.encode("utf8")))  # noqa: E501
        except IOError:  # interface is present in routing tables but does not have any assigned IP  # noqa: E501
            ifaddr = "0.0.0.0"
            ifaddr_int = 0
        else:
            addrfamily = struct.unpack("h", ifreq[16:18])[0]
            if addrfamily == socket.AF_INET:
                ifaddr = utils.inet_ntoa(ifreq[20:24])
                ifaddr_int = struct.unpack("!I", ifreq[20:24])[0]
            else:
                warning("Interface %s: unknown address family (%i)", iff,
                        addrfamily)  # noqa: E501
                continue

        # Attempt to detect an interface alias based on addresses inconsistencies  # noqa: E501
        dst_int = socket.htonl(int(dst, 16)) & 0xffffffff
        msk_int = socket.htonl(int(msk, 16)) & 0xffffffff
        gw_str = utils.inet_ntoa(struct.pack("I", int(gw, 16)))
        metric = int(metric)

        if ifaddr_int & msk_int != dst_int:
            tmp_route = get_alias_address(iff, dst_int, gw_str, metric)
            if tmp_route:
                routes.append(tmp_route)
            else:
                routes.append((dst_int, msk_int, gw_str, iff, ifaddr, metric))

        else:
            routes.append((dst_int, msk_int, gw_str, iff, ifaddr, metric))

    f.close()
    s.close()
    return routes
示例#16
0
 def _npcap_get(self, key):
     res, code = _exec_cmd(" ".join([_WlanHelper, self.guid[1:-1], key]))
     _windows_title()  # Reset title of the window
     if code != 0:
         raise OSError(res.decode("utf8", errors="ignore"))
     return plain_str(res.strip())