【发布时间】:2014-03-24 20:15:35
【问题描述】:
我在 Wireshark 上看到了一些广播数据包,我希望能够使用一个简单的 Linux 命令行实用程序来检查这些数据包。它看起来像这样:
getsenders bcast_IP port timeout
它会简单地打印在超时期间遇到的每个新发件人 IP。
例如:
getsenders 192.168.0.255 12345 0.150
或(或者)
getsenders 192.168.0.0/8 12345 0.150
将侦听发送到 192.168.0.255:12345 的广播数据包,然后打印遇到的每个唯一发件人。为指定接口上的任何广播发送者列出了另一种方法。
不幸的是,我的 socket-fu 很弱。我所知道的是程序必须以 root 权限 (suid) 运行才能监听广播套接字。
我已经投入大量时间(几天)尝试从 Python 执行此操作,但看起来该路由需要使用原始套接字并解析数据包(数据包嗅探器,呃!)。我还研究了使用 socat/netcat(通过仅执行的 suid bash 脚本),但也无济于事。
是否有一些简单的 Linux 代码可以为我做到这一点?我不在乎工具或源语言是什么,只要可以设置 suid-root 并从命令行运行即可。
顺便说一句,我有一个简单的 Python 解决方案,可以在 MS Windows 下运行,但在 Linux 下死机:
myip = <IP address of local interface to listen on>
p = <broadcast port>
timeout = 0.150 # 150 ms
addresses = {}
if "windows" in sys.platform.tolower():
# Create the broadcast reception socket
bsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
bsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
bsock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
bsock.settimeout(timeout)
bsock.bind((myip, p))
while True: # Look for all senders
try:
__, address = bsock.recvfrom(1024) # Don't care about payload
except BaseException, e:
break # Nothing found
else: # A desired broadcast packet was detected
if address[0] not in addresses:
addresses[address[0]] = 1
else:
addresses[address[0]] += 1
if addresses[address[0]] >= 3:
break # Go until timeout or any sender is seen 3 times
finally:
bsock.close()
bsock = None
print(', '.join([k for k in addresses]))
【问题讨论】:
-
忘了说我还在广播地址的子网中为接口添加了一个别名。因此,如果我看到发送到 192.168.0.155 的数据包,我会添加一个别名,其空闲地址在 192.168.0.1 到 192.168.0.254 范围内。
-
您的代码有什么问题? recvfrom() 提供发件人地址。剩下的只是编程。
-
我的错:我应该强调我需要一个至少可以在 Windows 7+ 和 Linux 上运行的跨平台解决方案。问题是,要么绑定失败,要么什么也收不到,即使数据包已经到达接口。
-
更改标题以反映我不关心使用的语言。