2012-12-31 102 views
2

我正在运行具有有线网络接口的Linux设备。此接口的另一端插入另一个配置为使用某个静态IP地址和某个网络掩码的网络感知设备。因此,我们有一个非常简单的网络,只包含两个设备和一个电缆,甚至没有它们之间的切换,什么都不是。我可以使用静态IP检测配置的连接设备的网络和网络掩码

的任务是开始与其他设备说话,而我们需要

  1. 将网络上去用ifconfig等。
  2. 获取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

DHCP是否可用?这是处理IP设置的动态分配的正确方法。既然你愿意编译和安装一个自定义的解决方案,我会考虑安装DHCP。 –

+2

设备是否响应ICMP网络掩码请求? – Keith

+0

另一端的设备配置为使用静态IP地址,即使我们提供此服务也不会使用DHCP – h22

回答

3

对于您可以nmap的使用,只要你能以某种方式限制范围,如您的评论本已应该给你的主机,你要第一部分:基于ARP

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

这确实发现和如果成功的话可以通过一次额外的ICMP查找活力。这一次在一个没有活跃的本地主机和5个有4个活动主机的系列上花了我大约一秒钟的时间。因此,您甚至可以将其扩展到更大的范围,但是除非您有一两天的时间,否则不会包含完整的IPv4地址空间。在这种情况下,我只需连接wireshark或tcpdump并等待无偿ARP。

编辑:为此,您必须在要测试的子网中使用IP配置“源计算机”。我认为在离开子网时或者没有配置IP时,它会使用ARP的DAD模式,但它不会做任何事情。我为下面的算法写了一个更通用的版本,但是比简单地使用nmap获得这个结果要慢一些。

检测配置的网络掩码有点棘手。但我认为这个过程是可行的,主要思想是主机将发送一个ARP请求给其子网中的主机,并且不发送任何ARP请求或者其默认gw的ARP请求给不在其子网中的主机。

  1. 从第二个到最小的子网N=29开始。
  2. 从该主机的IP和子网掩码N组成的子网中选取IP X。确保选取的IP不是主机的IP而不是网络/广播。还要确保这个IP不是由主机的IP和掩码N+1组成的子网的一部分。
  3. 平安其他主机与源X(你不介意它回答,只是发出一个请求)
  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 
+0

当界面上还没有IP地址时,nmap将不起作用。此外,您的掩码检测算法不起作用。它会返回您可以分配地址的最大遮罩,但这并不意味着您具有与邻近设备相同的遮罩。 –

+0

@将c。整个观点是,有一个配置但未知的地址。而我的算法与分配无关:S,唯一的缺点是目标主机可能从入局icmp学到Mac,根本不会ARP,但在这种情况下,您只需更改触发器即可检测数据包到另一个ip(即默认gw)。 – KillianDS

+0

*目标*机器上有一个配置但未知的地址,但* source *机器上没有IP地址。在源机器上没有IP地址的情况下,您无法使用nmap,所有的ARP回复将被丢弃到目标机器上。当我说分配时,我的意思是从该块中取出一个IP地址并将其放在源接口上。 –

-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

链路本地地址只能使用相同的物理或逻辑链路上的设备进行通信,所以如果你真的希望此设备在同一子网内,则必须手动配置界面。

+0

测试机器在他的控制下,他总是可以用一些地址来配置它。但是,ARP可以在没有配置地址(DAD模式)的情况下完成,甚至更多,这是在实际应用地址之前执行*的推荐步骤。没有其他设备和可能的其他IP,问题清楚地表明它是一个点对点链接。我在答案中提供了一个算法,如何检测工作正常的网络掩码(测试)。 – KillianDS

+0

同意,我从更广泛的意义上考虑这个问题(多设备,多个子网,共享相同的冲突域)。我仍然认为使用链接本地地址是解决这个问题的简单方法。 –