我正在运行具有有线网络接口(interface)的 Linux 设备。该接口(interface)的另一端插入另一个配置为使用某些静态 IP 地址和网络掩码的网络感知设备。因此,我们有一个非常简单的网络,仅由两个设备和一根电缆组成,甚至没有它们之间的交换机,什么都没有。
任务是开始与另一台设备通信,我们需要
- 使用 ifconfig 等设置网络。
- 获取 IP 地址并启动我的程序,该程序使用该 IP 地址与 设备。
我知道我可以进行广播 ping 并获取电缆另一端设备的 IP 地址。这对我有用。但要激活网络并进行广播 ping,我需要知道网络地址和网络掩码。我当前的 bash 脚本看起来像
ifconfig 192.168.100.1 netmask 255.255.255.0 up
ping -b 192.168.100.255
设备响应。不幸的是,其中一些设备可能会因不可预测的网络和网络掩码而配置错误。有人能提出如何自动检索网络设置(网络库、网络掩码)的想法吗?即使是部分解决方案也会感激不尽。如果有帮助的话,我可以编译并安装一个自定义 C 工具。
最佳答案
对于第一部分,只要您能以某种方式限制范围,您就可以使用 nmap,根据您的评论,这已经应该为您提供您想要的主机:
sudo nmap -PR -sn 192.168.0-255.0-255 -e <interface-to-test>
这会基于 ARP 进行发现,如果成功,则会在之后进行额外的 ICMP ping 以确定 liveness 。在没有事件本地主机的范围内,我花了大约一秒钟的时间,在有 4 个事件主机的范围上花了 5 秒。因此,您甚至可以将其扩展到更大的范围,但不能扩展到完整的 IPv4 地址空间,除非您有一两天的时间。在这种情况下,我只需连接wireshark或tcpdump并等待免费的ARP。
编辑:为此,您必须使用要测试的子网中的 IP 配置“源计算机”。我以为它会在走出子网或未配置 ip 时使用 ARP 的 DAD 模式,但它只是不执行任何操作。我在为下面的算法编写的脚本中添加了一个更通用的版本,但它比简单地使用 nmap 获得此结果要慢一些。
检测配置的网络掩码有点棘手。但我认为这个过程是可行的,主要思想是主机将向其子网中的主机发送 ARP 请求,而对于不在其子网中的主机则不发送任何内容或对其 default-gw 发出 ARP 请求。
- 从倒数第二个子网开始
N=29
。 - 从由主机 IP 和子网掩码
N
构成的子网中选择一个 IPX
。确保选择的 IP 不是主机的 IP,也不是网络/广播的 IP。另请确保此 IP 不属于由主机 IP 和掩码N+1
形成的子网的一部分。 - 使用源
X
对其他主机执行 Ping 操作(您不关心它是否应答,只需发出请求即可) - 如果您看到
X
的 ARP 请求,请将N
减一。返回2 - 如果您没有看到
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
关于linux - 我可以使用静态 IP 检测已配置连接设备的网络和网络掩码吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14103535/