可以使用静态IP检测configuration的连接设备的networking和networking掩码吗?

我正在使用有线networking接口运行Linux设备。 此接口的另一端插入另一个configuration为使用某个静态IP地址和某个networking掩码的networking感知设备。 因此,我们有一个非常简单的networking,只有两个设备和一个电缆,甚至没有它们之间的切换,什么也没有。

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

  1. 把networking与ifconfig或类似的东西。
  2. 获取IP地址并启动使用此IP地址的程序以使用设备。

我知道我可以做广播ping,并在电缆的另一端获取设备的IP地址。 这对我有用。 但要激活networking并做广播ping我需要知道networking地址和networking掩码。 我目前的bash脚本看起来像

ifconfig 192.168.100.1 netmask 255.255.255.0 up ping -b 192.168.100.255 

设备响应。 不幸的是,这些设备中的一部分可能configuration有不可预知的networking和networking掩码。 任何人都可以提出一个想法如何自动检索networking设置(netbase,networking掩码)? 即使是部分解决scheme,也会感激。 一个自定义的C工具可以编译和安装在我身边,如果这有帮助。

对于第一部分你可以使用nmap,只要你能以某种方式限制范围,根据你的评论,这应该给你你想要的主机:

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

这做基于ARP的发现,并且如果成功的额外的ICMP ping以后活着。 这一个带我在一个范围内没有活跃的本地主机和5个4活跃的主机。 所以你甚至可以把它扩展到更大的范围,但是除非你有一两天的时间,否则不能包含完整的IPv4地址空间。 在这种情况下,我只需要连接wireshark或tcpdump,然后等待一个免费的ARP。

编辑 :为了这个工作,你必须在你想测试的子网中配置你的“源机器”。 我认为在离开子网的时候会使用ARP的DAD模式,或者没有配置IP,但是它什么也不做。 我为下面的算法写了一个更通用的版本,但是比使用nmap获得这个结果要慢一些。

检测配置的网络掩码有点棘手。 但是我认为这个过程是可行的,主要的想法是主机会发送一个ARP请求给它的子网中的主机,没有任何东西或者ARP请求为它的子网中的主机的默认gw。

  1. 从第二个到最小的子网N=29
  2. 从由主机的IP和子网掩码N组成的子网中选择一个IP X 确保选取的IP不是主机的IP而不是网络/广播。 还要确保这个IP不是由主机的IP和掩码N+1组成的子网的一部分。
  3. 用源码X ping其他主机(你不关心它是否回答,只是发送一个请求)
  4. 如果看到X的ARP请求,则减少N 回到2
  5. 如果您没有看到X的ARP请求, N+1是搜索到的子网。

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

我不知道是否有工具可以为你做,但是用ping,tcpdump和子网计算器手动操作应该很简单)。 或者,如果你觉得受到一些黑客攻击,用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 

你所要求的是不可能的。

最初,你有一个没有IP地址的接口。 因此,您发送的任何数据包将不知道应答的发送位置(ICMP或ARP请求将无法工作)。

由于发件人不知道如何到达这个接口,所以你可以在接口上监听任何广播的ARP请求(使用tcpdump,wireshark等)。这将告诉你哪些IP地址在网络中被解析,但是它确实不给你网络掩码(也就是网络地址)。 此外,它不仅为您提供直接连接的邻居的IP地址,还会为您提供在此广播域内发出的所有 ARP请求(因此您可能会看到很多IP地址)。

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

话虽如此,你可能想看看链接本地的IPv4地址。 在Linux上,有一个名为AVAHI的程序,在Windows上叫做APIPA。 两者均实施RFC 3927: http : //tools.ietf.org/html/rfc3927

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