我在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]))
答案 0 :(得分:0)
下载并测试了很多例子之后,我终于让它工作了,然后一分为二,并将代码组合起来,直到我在两个平台上都有最小的差异。
它只归结为一行:Linux必须绑定到特定的广播地址(以root身份),其中Windows可以绑定到预期广播数据包到达的本地接口地址(作为普通用户)。
以下是修改后的代码段:
bcast_addr = <IP addr of broadcast: Must end with at least one '.255'>
myip = <IP addr of local interface receiving from bcast_addr>
p = <broadcast port>
timeout = 0.150 # 150 ms
addresses = {}
# 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)
if "windows" in sys.platform.tolower():
bsock.bind((myip, p))
elif os.getuid() == 0: # Must be root for Linux!
bsock.bind((bcast_addr, 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]))