|
| 1 | +import socket |
| 2 | +import os |
| 3 | +import struct |
| 4 | +from ctypes import * |
| 5 | + |
| 6 | +# Host to listen on |
| 7 | +host = "192.168.0.187" |
| 8 | + |
| 9 | + |
| 10 | +class IP(Structure): |
| 11 | + _fields_ = [ |
| 12 | + ("ihl_version", c_ubyte), |
| 13 | + ("tos", c_ubyte), |
| 14 | + ("len", c_ushort), |
| 15 | + ("id", c_ushort), |
| 16 | + ("offset", c_ushort), |
| 17 | + ("ttl", c_ubyte), |
| 18 | + ("protocol", c_ubyte), |
| 19 | + ("sum", c_ushort), |
| 20 | + ("src", c_uint32), |
| 21 | + ("dst", c_uint32) |
| 22 | + ] |
| 23 | + |
| 24 | + def __new__(cls, socket_buffer=None): |
| 25 | + return cls.from_buffer_copy(socket_buffer) |
| 26 | + |
| 27 | + def __init__(self, socket_buffer=None): |
| 28 | + self.socket_buffer = socket_buffer |
| 29 | + |
| 30 | + # Map protocol constants to their names |
| 31 | + self.protocol_map = {1: "ICMP", 6: "TCP", 17: "UDP"} |
| 32 | + |
| 33 | + # Human-readable IP addresses |
| 34 | + self.src_address = socket.inet_ntoa(struct.pack("@I", self.src)) |
| 35 | + self.dst_address = socket.inet_ntoa(struct.pack("@I", self.dst)) |
| 36 | + |
| 37 | + # Human-readable protocol |
| 38 | + self.protocol = self.protocol_map.get(self.protocol, str(self.protocol)) |
| 39 | + |
| 40 | + |
| 41 | +# Create a raw socket and bind it to the public interface |
| 42 | +socket_protocol = socket.IPPROTO_IP if os.name == "nt" else socket.IPPROTO_ICMP |
| 43 | +sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol) |
| 44 | +sniffer.bind((host, 0)) |
| 45 | + |
| 46 | +# We want the IP headers included in the capture |
| 47 | +sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) |
| 48 | + |
| 49 | +# If we're on Windows, we need to send some ioctl to set up promiscuous mode |
| 50 | +if os.name == "nt": |
| 51 | + sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON) |
| 52 | + |
| 53 | +try: |
| 54 | + while True: |
| 55 | + # Read in a single packet |
| 56 | + raw_buffer = sniffer.recvfrom(65535)[0] |
| 57 | + |
| 58 | + # Create an IP header from the first 20 bytes of the buffer |
| 59 | + ip_header = IP(raw_buffer[:20]) |
| 60 | + |
| 61 | + print(f"Protocol: {ip_header.protocol} {ip_header.src_address} -> {ip_header.dst_address}") |
| 62 | + |
| 63 | +except KeyboardInterrupt: |
| 64 | + # If we're on Windows, turn off promiscuous mode |
| 65 | + if os.name == "nt": |
| 66 | + sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF) |
0 commit comments