我有一些代码通过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)
...
答案 0 :(得分:7)
通常,您无法获取mac地址。您可能在LAN上使用ARP成功,但在Internet上则不可能。
考虑您收到的数据包具有发件人NATting路由器的IP地址的情况。数据包可能已经遍历了任意数量的中间机器,每个中间机器也具有mac地址。谁应该支持你所追求的那种查询?对于沿途的所有机器,发件人的mac地址完全没用,为什么还要支持那种查找呢?
而且,顺便说一下,changing the mac address在很多网卡上都是微不足道的,所以将它用作某种独特的ID并不是一个明智的想法。
答案 1 :(得分:1)
您需要的协议是ARP。查看此question/answer了解详情
答案 2 :(得分:1)
我不确定是否可以获取发件人的MAC地址,因为MAC地址是链路级地址,而不是IP等网络级地址。当包含UDP消息的数据包从发送方路由到接收方时,MAC地址将在网络中的每一跳发生变化。
答案 3 :(得分:0)
我不知道如何在python中做到这一点,但有可能获得MAC地址。例如,通过使用tcpdump,我将所有数据包放入文件:
sudo tcpdump -i enp0s31f6 -w file_name port 6665
然后在python中用:
读取它 packetlist = rdpcap("./file_name")
for pkt in packetlist:
print pkt.src, pkt.load
你可以看到mac地址
编辑: 我找到了一种方法: 在函数嗅探的帮助下用scapy嗅探所有软件包,然后过滤软件包以获得你需要的东西。在那里你可以使用mac地址 例如,来自我的项目:
sniff(prn=self._pkt_callback, store=0)
def _pkt_callback(self, pkt):
if not self.sniffer_on:
return
if Ether not in pkt or pkt[Ether].type != 0x800:
return
if pkt[IP].proto != 17: # 17 means UDP package
return
if pkt[UDP].dport != 6665:
return
print pkt.src, pkt.load #src is mac address
答案 4 :(得分:0)
为此,您需要捕获原始以太网帧,而不仅仅是 UDP 数据包。
import socket
ETH_P_ALL=3
sock = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(ETH_P_ALL))
sock.bind((interface_name, 0))
data = sock.recv(2000)
dmac = data[:6]
smac = data[6:12]
udp_offset = 14
ethertype = data[12:14]
if ethertype == [0x81, 0x00]: # 802.1Q VLAN-tagged
udp_offset += 4
udp_pkt = data[udp_offset:]
一些注意事项:
root
(或具有 CAP_NET_RAW
能力)才能执行此操作。不确定您在 Windows 上需要什么,但假设类似。