2009-11-12 99 views
2

我有一些代碼,通過UDP多播監聽「通知」。我可以獲取發件人的IP地址,但我真正需要的是發件人的MAC地址(因爲IP地址可以並將會更改)。在Python中查找組播UDP消息發送者的MAC地址?

有沒有一種簡單的方法在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

應該可以用'scapy'的L2插座雖然可能需要一些工作:http://www.secdev.org/projects/scapy /doc/usage.html – Pierz 2016-12-07 18:10:15

回答

7

一般情況下,您無法獲取mac地址。你可能在局域網上使用ARP成功,但在互聯網上是不可能的。

考慮您收到的數據包具有發件人的NATting路由器的IP地址的情況。數據包可能沿途經過任意數量的中間機器,每個中間機器都有mac地址。應該支持你追求的那種查找的責任是誰?對於一路上的所有機器來說,發件人的mac地址是完全無用的,那麼爲什麼還要支持這種查找呢?

而且,btw,changing the mac address在很多網卡上都是微不足道的,因此將它用作某種獨特的ID並不是一個明智的想法。

+0

假設我不想獲取原始發件人的MAC,而是傳輸UDP數據包的以太網數據包的「源MAC」。是否有可能使用標準的Linux設施?至少我可以在Windows上的Wireshark中獲得這些信息。 – 2016-01-20 12:52:23

1

我不確定是否可以獲取發件人的MAC地址,因爲MAC地址是鏈接級別地址,而不是IP等網絡級別地址。由於包含UDP消息的數據包從發送方路由到接收方,MAC地址將在網絡中的每一跳都發生變化。

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