import socket
import os
import ipaddress
import struct


class IP:
    def __init__(self, buff):
        header = struct.unpack('<BBHHHBBH4s4s', buff)
        self.ver = header[0] >> 4
        self.ihl = header[0] & 0xF

        self.tos = header[1]
        self.len = header[2]
        self.id = header[3]
        self.offset = header[4]
        self.ttl = header[5]
        self.protocol_num = header[6]
        self.sum = header[7]
        self.src = header[8]
        self.dst = header[9]

        # IP-адруса, понятные человек
        self.src_address = ipaddress.ip_address(self.src)
        self.dst_address = ipaddress.ip_address(self.dst)

        # сопоставляем константы протоколов с их назначением
        self.protocol_map = {1: "ICMP", 6: "TCP", 17: "UDP"}


class ICMP:
    def __init__(self, buff):
        header = struct.unpack('<BBHHH', buff)
        self.type = header[0]
        self.code = header[1]
        self.sum = header[2]
        self.id = header[3]
        self.seq = header[4]


        

def sniffer():
    HOST = '192.168.31.181'

    # создаем сырой сокет и привязываем к общедоступному интерфейсу
    if os.name == 'nt':
        socket_protocol = socket.IPPROTO_IP
    else:
        socket_protokol = socket.IPPROTO_ICMP

    sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol)
    sniffer.bind((HOST, 0))
    # делаем так, чтобы захватывался IP-заголовок
    sniffer.setsockopt(socket.IPPROTO_IP, socket.RCVALL_ON, 1)
    
    if os.name == 'nt':
        sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)

    # читаем один пакет
    print(sniffer.recvfrom(65565))

    if os.name == 'nt':
        sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)

        

def main():
    sniffer()


if __name__ == '__main__':
    main()