Raw socket packet sniffer in Python 3.6 on Windows
Solution 1
The hint is that all your Destination Mac addresses start with 0x45
. That's the first byte of the IP header. So your code is getting all the IP packets, but not the MAC header for those frames.
Solution 2
Ok thanks to selbi i understand the problem, thank you very much
But to catch Ethernet header with Python in windows you have to use:
1. PyPCap
2. Dpkt
-
To install dpkt just open cmd as admin and type:
py -2 -m pip install dpkt
Here references of Python Docs
3. Python 2.7
But you need to install Python 3.4> to get pip
And finally that's the code:
#!/usr/bin/env python
import getopt, sys
import dpkt, pcap
import socket
import struct
import binascii
import textwrap
def main():
# Get host
host = socket.gethostbyname(socket.gethostname())
print('IP: {}'.format(host))
name = None
pc = pcap.pcap(name)
decode = { pcap.DLT_LOOP:dpkt.loopback.Loopback,
pcap.DLT_NULL:dpkt.loopback.Loopback,
pcap.DLT_EN10MB:dpkt.ethernet.Ethernet }[pc.datalink()]
try:
print 'listening on %s: %s' % (pc.name, pc.filter)
for ts, pkt in pc:
pkt = str(decode(pkt))
dest_mac, src_mac, eth_proto, data = ethernet_frame(pkt)
print '\nEthernet Frame:'
print "Destination MAC: {}".format(dest_mac)
print "Source: {}".format(src_mac)
print "Protocol: {}".format(eth_proto)
except KeyboardInterrupt:
nrecv, ndrop, nifdrop = pc.stats()
print '\n%d packets received by filter' % nrecv
print '%d packets dropped by kernel' % ndrop
# Unpack ethernet frame
def ethernet_frame(data):
dest_mac, src_mac, proto = struct.unpack('!6s6s2s', data[:14])
return binascii.hexlify(dest_mac), binascii.hexlify(src_mac), binascii.hexlify(proto), data[14:]
if __name__ == '__main__':
main()
Output:
Ethernet Frame:
Destination MAC: 5404a6f2740c <- My NIC MAC
Source: 6459f81dc690
Protocol: 0800 <- Right protocol
Ethernet Frame:
Destination MAC: 6459f81dc690
Source: 5404a6f2740c
Protocol: 0800
Ethernet Frame:
Destination MAC: 5404a6f2740c
Source: 6459f81dc690
Protocol: 0800
I hope you enjoy thanks again selbie
(Sorry i can't put more links cause of my reputation)
Alessandro Lodi
"Information: the negative reciprocal value of probability" - Claude Shannon
Updated on June 14, 2022Comments
-
Alessandro Lodi almost 2 years
I am trying to sniff packets but i am getting strange output and i don't understand the reason..
So that's my code please help me
(I'm using Python 3.6 on Windows 8.1)Code:
import socket import struct import binascii import textwrap def main(): # Get host host = socket.gethostbyname(socket.gethostname()) print('IP: {}'.format(host)) # Create a raw socket and bind it conn = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP) conn.bind((host, 0)) # Include IP headers conn.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) # Enable promiscuous mode conn.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON) while True: # Recive data raw_data, addr = conn.recvfrom(65536) # Unpack data dest_mac, src_mac, eth_proto, data = ethernet_frame(raw_data) print('\nEthernet Frame:') print("Destination MAC: {}".format(dest_mac)) print("Source MAC: {}".format(src_mac)) print("Protocol: {}".format(eth_proto)) # Unpack ethernet frame def ethernet_frame(data): dest_mac, src_mac, proto = struct.unpack('!6s6s2s', data[:14]) return get_mac_addr(dest_mac), get_mac_addr(src_mac), get_protocol(proto), data[14:] # Return formatted MAC address AA:BB:CC:DD:EE:FF def get_mac_addr(bytes_addr): bytes_str = map('{:02x}'.format, bytes_addr) mac_address = ':'.join(bytes_str).upper() return mac_address # Return formatted protocol ABCD def get_protocol(bytes_proto): bytes_str = map('{:02x}'.format, bytes_proto) protocol = ''.join(bytes_str).upper() return protocol main()
From this code i get this output:
IP: 192.168.1.12
Ethernet Frame:
Destination MAC: 45:00:00:43:00:00
Source MAC: 40:00:2C:11:48:D3
Protocol: 4266Ethernet Frame:
Destination MAC: 45:00:00:42:11:E7
Source MAC: 00:00:80:11:00:00
Protocol: C0A8Ethernet Frame:
Destination MAC: 45:00:00:33:04:D6
Source MAC: 00:00:80:11:00:00
Protocol: C0A8.
.
.According to EtherType list this protocols don't exist and analysing my traffic with Wireshark i am sure that this MACs don't exist in my LAN
So I'm definitely doing something wrong but I do not understand what
Thanks in advance -
Alessandro Lodi over 7 yearsBut how can i get MAC header? (i am new with Python)
-
Saurav Seth over 7 yearsInstead of opening an AF_INET socket, open an AF_PACKET socket. opensourceforu.com/2015/03/a-guide-to-using-raw-sockets
-
krish over 3 yearsI have tried the above same packet sniffer code. it was not working on my windows 10.
-
Alessandro Lodi over 3 years@krish the question is old.. I will try to fix it as soon as possible. Which errors do you get?
-
krish over 3 yearsThe total Ethernet frame is mismatched. it has not given proper source mac and des mac