Have you ever wanted to create your own packet sniffer? Here is the code below on how that is possible!

#!/usr/bin/python

import socket
import os
import binascii
import struct


# Examples were obtained from http://www.bitforestinfo.com/2017/01/how-to-write-simple-packet-sniffer.htm
# and https://www.binarytides.com/python-packet-sniffer-code-linux/

# used for formating MAC address
def eth_addr(a):
    b = "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x" % (ord(a[0]), ord(a[1]), ord(a[2]), ord(a[3]), ord(a[4]), ord(a[5]))
    return b


# the script is designed to work on linux operating system with python 2.
# windows implementation was being problamatic with the socket implementation
if os.name == "nt":
    host = socket.gethostbyname(socket.gethostname())
    print('IP: {}'.format(host))
    s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
    s.bind((host, 0))
    s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
    s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
else:
    # PF_PACKET used for linux implementation. socket.ntohs(0x0800) used to obtain IPV4
    s = socket.socket(socket.PF_PACKET, socket.SOCK_RAW, socket.ntohs(0x0800))

# Continue as long as packets are being recieved
while True:
    packet = s.recvfrom(65565)
    packet = packet[0]

    # Prints out the packet content as hex bytes
    print("\n===>> [+] ------------ Packet ----------- [+]")
    print('Packet : ' + binascii.hexlify(packet))

    # parse ethernet header
    eth_length = 14
    eth_header = packet[:eth_length]
    eth = struct.unpack('!6s6sH', eth_header)
    eth_protocol = socket.ntohs(eth[2])
    print("\n===>> [+] ------------ Ethernet Header ------------[+]")
    print(
        "Destination MAC : " + eth_addr(packet[0:6]) + ' Source MAC : ' + eth_addr(packet[6:12]) + ' Protocol : ' + str(
            eth_protocol))

    # ip header starts at 14 and goes to 34. These bytes contain the IP Header Information
    ip_header = packet[eth_length:20 + eth_length]

    # Struct used to unpack the bytes and oder them properly. Example obtained from (http://www.bitforestinfo.com/2017/01/how-to-write-simple-packet-sniffer.html)
    iph = struct.unpack('!BBHHHBBH4s4s', ip_header)

    version_ihl = iph[0]
    version = version_ihl >> 4
    ihl = version_ihl & 0xF
    iph_length = ihl * 4

    ttl = iph[5]
    protocol = iph[6]
    s_addr = socket.inet_ntoa(iph[8])
    d_addr = socket.inet_ntoa(iph[9])
    print("\n===>> [+] ------------ IP Header ------------[+]")
    print('Version : ' + str(version) + ' IP Header Length : ' + str(ihl) + ' TTL : ' + str(ttl) + ' Protocol : ' + str(
        protocol) + ' Source Address : ' + str(s_addr) + ' Destination Address : ' + str(d_addr))

    # TCP protocol
    if protocol == 6:
        t = iph_length + eth_length
        # TCP Header bytes going from 34 to 54
        tcp_header = packet[t:t + 20]

        # Struct used to unpack the bytes and oder them properly. Example obtained from (http://www.bitforestinfo.com/2017/01/how-to-write-simple-packet-sniffer.html)
        tcph = struct.unpack('!HHLLBBHHH', tcp_header)

        source_port = tcph[0]
        dest_port = tcph[1]
        sequence = tcph[2]
        acknowledgement = tcph[3]
        doff_reserved = tcph[4]
        tcph_length = doff_reserved >> 4
        print("\n===>> [+] ------------ TCP Header ----------- [+]")
        print('Source Port : ' + str(source_port) + ' Dest Port : ' + str(dest_port) + ' Sequence Number : ' + str(
            sequence) + ' Acknowledgement : ' + str(acknowledgement) + ' TCP header length : ' + str(tcph_length))

        h_size = eth_length + iph_length + tcph_length * 4
        data_size = len(packet) - h_size

        # get data from the packet by going to the end of the header information
        data = packet[h_size:]
        # Display the data from the packet in hex form
        print("\n===>> [+] ------------ Data ----------- [+]")
        print('Data : ' + binascii.hexlify(data))

    # UDP packets
    elif protocol == 17:
        u = iph_length + eth_length
        udph_length = 8
        # UDP Header bytes going from 34 to 42
        udp_header = packet[u:u + 8]

        # Struct used to unpack the bytes and oder them properly. Example obtained from (http://www.bitforestinfo.com/2017/01/how-to-write-simple-packet-sniffer.html)
        udph = struct.unpack('!HHHH', udp_header)

        source_port = udph[0]
        dest_port = udph[1]
        length = udph[2]
        checksum = udph[3]
        print("\n===>> [+] ------------ UDP Header ----------- [+]")
        print('Source Port : ' + str(source_port) + ' Dest Port : ' + str(dest_port) + ' Length : ' + str(
            length) + ' Checksum : ' + str(checksum))

        h_size = eth_length + iph_length + udph_length
        data_size = len(packet) - h_size

        # get data from the packet by going to the end of the header information
        data = packet[h_size:]
        # Display the data from the packet in hex form
        print("\n===>> [+] ------------ Data ----------- [+]")
        print('Data : ' + binascii.hexlify(data))
    else:
        print("Protocol type not supported.")

Example screenshot of it in action:

TCP

TCP

UDP

UDP