Reputation: 868
I am trying to simply get and process my ethernet frame in python to do it i wrotte this simple code in python (helped by a tutorial):
import socket
import struct
def ethernet_frame_fct(data):
dest_mac, src_mac, proto = struct.unpack('! 6s 6s H', data[:14])
return get_mac_addr_fct(dest_mac), get_mac_addr_fct(src_mac), socket.htons(proto), data[14:]
def get_mac_addr_fct(bytes_addr):
bytes_str = map('{:02x}'.format, bytes_addr)
mac_addr = ':'.join(bytes_str).upper()
return mac_addr
def main_fct():
# if platform == "linux" or platform == "linux2":
# conn = socket.socket(socket.AF_PACKET, socket.SOCKET_RAW, socket.ntohs(3))
# if platform == "win32":
HOST = socket.gethostbyname(socket.gethostname()) # the public network interface
conn = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP) # create a raw socket and bind it to the public interface
conn.bind((HOST, 0))
conn.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) # Include IP headers
conn.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON) # receives all packets
while True:
raw_data, addr = conn.recvfrom(65536)
dest_mac, src_mac, eth_proto, data = ethernet_frame_fct(raw_data)
print("\n-Ethernet Frame:")
print('\t' + "MAC addr Destination= {}, MAC addr Source= {}, Protocol= {}".format(dest_mac, src_mac, eth_proto))
#
main_fct()
The proble is that i get those results when i am running the program:
But the Source MAC address that should be MY mac address is not at all my MAC ADDRESS and the Protocole is not the one of an expected tag.
For exemple: 6=TCP, 17=UDP ...etc... but 17796 is not at all a value that i expected to get.
Concerning this last value for times to times i get different value as i run this programm on my laptot (so the wifi changes) but I NEVER got something logic.
As the usual ethernet frame should look like this:
I absolutely don't know where i am wrong.
For days i am really confused and stuck on this problem and so i will very appreciate if someone will be able to help me.
Thank you.
Upvotes: 0
Views: 609
Reputation: 1050
I'm on Linux and the following code based entirely on your code works for me if run as root:
import socket
ETH_P_ALL = 3
s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(ETH_P_ALL))
s.bind(('wlp4s0', 0)) # your WiFi interface, on Linux found using `ifconfig` or similar
eth_packet = s.recv(2048) # get a sample packet
ethernet_frame_fct(eth_packet)
This gives me the correct MAC address of my WiFi card. The EtherType (proto) in my sample eth_packet
should have been ETH_P_IP
(IPv4 packet) which is defined as 0x0800
, but I got 8
instead. So it seems you can remove the socket.htons()
call to get the correct value.
Upvotes: 1