在Python中查找多播UDP消息发送者的MAC地址?
我有一些代码通过 UDP 多播监听“公告”。我可以获得发件人的 IP 地址,但我真正需要的是发件人的 MAC 地址(因为 IP 地址可能并且将会改变)。
有没有一种简单的方法可以在Python中做到这一点?
包含一个代码片段供参考,但可能没有必要。
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
# Allow multiple sockets to use the same PORT number
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# Bind to the port that we know will receive multicast data
sock.bind((self.interface, MCAST_PORT))
# Tell API we are a multicast socket
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255)
# Tell API we want to add ourselves to a multicast group
# The address for the multicast group is the third param
status = sock.setsockopt(socket.IPPROTO_IP,
socket.IP_ADD_MEMBERSHIP,
socket.inet_aton(MCAST_ADDR) + socket.inet_aton(self.interface));
data, addr = sock.recvfrom(1024)
...
I have some code that listens for "announcements" via UDP multicast. I can get the IP address of the sender, but what I really need is the MAC address of the sender (since the IP address can and will change).
Is there an easy way to do this in Python?
A code snippet is included for reference, but likely unnecessary.
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
# Allow multiple sockets to use the same PORT number
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# Bind to the port that we know will receive multicast data
sock.bind((self.interface, MCAST_PORT))
# Tell API we are a multicast socket
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255)
# Tell API we want to add ourselves to a multicast group
# The address for the multicast group is the third param
status = sock.setsockopt(socket.IPPROTO_IP,
socket.IP_ADD_MEMBERSHIP,
socket.inet_aton(MCAST_ADDR) + socket.inet_aton(self.interface));
data, addr = sock.recvfrom(1024)
...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
一般来说,您无法获取 MAC 地址。在 LAN 上使用 ARP 可能会成功,但在 Internet 上则不可能。
考虑这样一种情况:您收到的数据包具有发送者的 NATting 路由器的 IP 地址。数据包沿途可能经过任意数量的中间机器,每个中间机器也有 MAC 地址。支持您所追求的查找类型应该由谁负责?对于沿途的所有机器,发送者的 MAC 地址完全没有用,那么为什么还要支持这种查找呢?
而且,顺便说一句,更改 mac 地址在许多网卡上都很简单,因此将其用作某些网卡那种唯一的ID并不是一个明智的想法。
You cannot, in general, get the mac address. You might succeed using ARP on a LAN, but across the Internet it's not possible.
Consider the case where the packet you receive has the IP address of the sender's NATting router. The packet may have traversed any number of intermediate machines along the way, each of which have mac addresses, too. Whose responsibility should it be to support the kind of lookup you're after? For all the machines along the way, the sender's mac address is completely useless, so why bother supporting that kind of lookup?
And, btw, changing the mac address is trivial on many network cards, so using it as some kind of unique ID is not a wise idea.
为此,您需要捕获原始以太网帧,而不仅仅是 UDP 数据包。
一些注意事项:
To do this, you need to capture the raw Ethernet frame, not just the UDP packet.
Some notes:
root
(or have theCAP_NET_RAW
capability) to do this. Not sure what you need on Windows, but assume something similar.您需要的协议是 ARP。查看此问题/答案了解详细信息
The protocol you need is ARP. Check this question/answer for details
我不确定是否可以获取发送者的 MAC 地址,因为 MAC 地址是链路级地址,而不是像 IP 那样的网络级地址。当包含 UDP 消息的数据包从发送方路由到接收方时,MAC 地址将在网络中的每一跳发生变化。
I'm not sure that it is possible to get the sender's MAC address since the MAC address is a link level address and not a network level address like IP. The MAC address will change at each hop in the network as the packet containing the UDP message is routed from the sender to the receiver.
我不知道如何在 python 中执行此操作,但可以获取 MAC 地址。例如,通过使用 tcpdump 我将所有数据包放入文件中:
然后在 python 中读取它:
您可以看到 mac 地址
编辑:
我找到了一种方法来做到这一点:
借助 sniff 函数,使用 scapy 嗅探所有包,然后过滤包以仅获取您需要的包。在那里你可以使用mac地址
例如我的项目:
I don't know how to do it in python but it is possible to get MAC address. For example by using tcpdump I put all packets into file:
then in python read it with:
you can see the mac address
edit:
I found one way to do this:
sniff all packages with scapy with the help of function sniff, then filter the packages to get only what you need. There you can use mac address
for example from my project: