首页 文章

是否可以使用静态IP检测已配置连接设备的网络和网络掩码

提问于
浏览
2

我正在运行带有线网络接口的Linux设备 . 此接口的另一端插入另一个网络感知设备,该设备配置为使用某些静态IP地址和一些网络掩码 . 因此,我们有一个非常简单的网络,由两个设备和一个电缆组成,甚至不在它们之间切换,什么也没有 .

任务是开始与另一台设备交谈,我们需要

  • 使用ifconfig等 Build 网络 .

  • 获取IP地址并启动使用此IP地址的程序以使用该设备 .

我知道我可以进行广播ping,并在电缆的另一端获取设备的IP地址 . 这适合我 . 但是要激活网络并进行广播ping,我需要知道网络地址和网络掩码 . 我当前的bash脚本看起来像

ifconfig 192.168.100.1 netmask 255.255.255.0 up
ping -b 192.168.100.255

并且设备响应 . 不幸的是,其中一些设备可能配置错误,网络和网络掩码不可预测 . 任何人都可以提出如何自动检索网络设置(netbase,netmask)的想法吗?即使是部分解决方案,也要感恩 . 可以编译和安装自定义C工具,如果这有帮助的话 .

2 回答

  • 3

    对于第一部分,您可以使用nmap,只要您可以以某种方式限制范围,根据您的评论,这已经应该为您提供所需的主机:

    sudo nmap -PR -sn 192.168.0-255.0-255 -e <interface-to-test>
    

    这可以基于ARP进行发现,并且如果成功,则会在之后为活动提供额外的ICMP ping . 这个让我在没有活动本地主机的范围和5个有4个活动主机的范围内花了大约一秒钟 . 所以你甚至可以将它扩展到更大的范围,但不是完整的IPv4地址空间,除非你有一两天 . 在那种情况下,我只是挂起wireshark或tcpdump并等待无偿ARP .

    edit :为此,您必须使用要测试的子网中的IP配置"source machine" . 我假设它在离开子网时或者没有配置ip时会使用ARP的DAD模式,但它不会做任何事情 . 我在为下面的算法编写的脚本中添加了一个更通用的版本,但它比使用nmap获得此结果要慢一些 .

    检测配置的网络掩码有点棘手 . 但我认为这个程序会起作用,主要的想法是主机会发送一个针对其子网中主机的ARP请求,并且对于不在其子网中的主机,它的默认gw的ARP请求 .

    • 从第二个到最小的子网 N=29 开始 .

    • 从主机IP和子网掩码 N 形成的子网中选择IP X . 确保选择的IP不是主机's IP and not network/broadcast. Also make sure this IP is not a part of the subnet formed by the host'的IP和掩码 N+1 .

    • 使用源 X ping其他主机(您不关心它是否应答,只是发出请求)

    • 如果您看到 X 的ARP请求,请将 N 减少一个 . 回到2

    • 如果没有看到 X 的ARP请求,则 N+1 是搜索到的子网 .

    一个缺陷可能是一个过于雄心勃勃的网络堆栈实现可能从传入的ICMP请求中学习MAC,但我个人不知道任何以这种方式工作的终端设备堆栈 .

    我不能用scapy来实现这个目标 .

    我自己写了一个完整的python scapy脚本应该可以工作,我在我的家庭网络上在linksys homegw,另一台linux机器和一个android设备上测试它:

    from __future__ import print_function, absolute_import, unicode_literals
    from scapy.base_classes import Net
    from scapy.config import conf
    from scapy.layers.inet import Ether, ARP, ICMP, IP
    from scapy.sendrecv import srp, debug
    import scapy.route
    
    iface = b'eth0'
    subnet_to_test = b'192.168.1.0/24'
    #or:
    subnet_to_test = b'192.168.1.*'
    
    #IP/MAC discovery
    pkt = Ether(dst=b'ff:ff:ff:ff:ff:ff') / ARP(psrc=b'0.0.0.0', pdst=subnet_to_test, hwdst=b'ff:ff:ff:ff:ff:ff')
    responses = srp(pkt, timeout=1, retry=0, verbose=0, iface=iface)
    for r in responses[0]:
        found = r[1].getfieldval('psrc')
        foundmac = r[1].getfieldval('hwsrc')
    
    n = 29
    conf.debug_match = 1
    while n > -1:
        net = Net("{}/{}".format(found, n))
        my_src = net.choice()
        while my_src in Net("{}/{}".format(found, n + 1)):
            my_src = net.choice()
        pkt = Ether(dst=foundmac) / IP(dst=found, src=my_src) / ICMP(type=8)
        resp = srp(pkt, timeout=1, retry=0, verbose=0, iface=iface, filter=b'ether dst FF:FF:FF:FF:FF:FF and arp')
        received = [x for x in debug.recv if x.haslayer(ARP) and x.getfieldval('pdst') == my_src]
        received.extend(x[1] for x in resp[0] if x[1].haslayer(ARP) and x[1].getfieldval('pdst') == my_src)
        if len(received) == 0:
            print("Found host: {}/{} on mac {}".format(found, n + 1, foundmac))
            break
        n -= 1
    
  • -1

    你要求的是不可能的 .

    最初,您有一个没有IP地址的接口 . 因此,您发送的任何数据包都不知道在何处发送回复(因此ICMP或ARP请求将不起作用) .

    由于发件人知道如何访问此接口,您可以在接口上侦听任何广播ARP请求(使用tcpdump,wireshark等) . 这将显示网络中正在解析的IP地址,但它没有给出你是网络掩码(以及网络地址) . 此外,它不仅为您提供直接连接的邻居的IP地址,它还将为您提供在此广播域内发出的所有ARP请求(因此您可能会看到许多IP地址) .

    现在,至于确定设备正在使用的网络掩码,在使用CIDR时是不可能的(前缀可能在/ 16和/ 32之间的任何地方,并且无法准确知道邻居设备正在使用哪一个) . )

    话虽这么说,你可能想看看到链接本地IPv4地址 . 在Linux上,有一个名为AVAHI的程序,在Windows上称为APIPA . 两者都实现RFC 3927:http://tools.ietf.org/html/rfc3927

    链路本地地址只能用于与同一物理或逻辑链路上的设备通信,因此,如果您确实希望此设备位于同一子网上,则必须手动配置该接口 .

相关问题