2

I am going over thenewboston Python Network Packet Sniffer Tutorial Series. However i think he is doing it on Linux which explains why many people who did it on Windows had issues including me.

I replaced socket.AF_Socket with AF_INET and socket.htons(3) with socket.IPPROTO_IP so it can run on Windows.Then i had OSError: [WinError 10022] An invalid argument was supplied error. Upon researching it i seen that i had to bind the socket before using .recvfrom function. Now it compiles fine but in video he refreshes the browser on 6:12 and he can see all the traffic while my output window stays blank.Thanks for the help.

import socket
import struct
import textwrap


def main():
    # Create socket and make sure endian is handled
    host = socket.gethostname()

    port = 9999

    conn = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
    conn.bind((host, port))
    while True:
        # Whenever these is data coming through store it in raw_data and addr variable

        raw_data, addr = conn.recvfrom(65536)
        # Extract data from raw_data variable
        dest_mac, src_mac, eth_proto, data = ethernet_frame(raw_data)
        print('\nEthernet Frame:')
        print('Destination: {}, Source: {}, Protocol: {}'.format(dest_mac, src_mac, eth_proto))


# Unpack ethernet frame
def ethernet_frame(data):
    # Resolve endian transformation.Structure is 6 bytes for destination and source so it requires 6s and signed int
    # for protocol which is shown with H that has 2 bytes length
    # Sniff 14 bytes in packet starting from the beginning byte.
    dest_mac, src_mac, proto = struct.unpack('! 6s 6s H', data[:14])

    # Make extracted data human readable by formatting it.Convert to check that if we are big or little endian based
    # on the task. So it takes bytes and make it compatible so it is human readable
    return get_mac_addr(dest_mac), get_mac_addr(src_mac), socket.htons(proto), data[14:]


# Return properly formatted MAC Address (ie AA:BB:CC:DD:EE:FF)
def get_mac_addr(bytes_addr):
    # Run through the Mac Address
    bytes_str = map('{:02x}'.format, bytes_addr)
    # Return properly formatted MAC Address
    return ':'.join(bytes_str).upper()


main()
lemikistu
  • 61
  • 1
  • 6
  • I thought WinSock was highly compatible with Linux. But I see that Windows programmers might make it [difficult to port to Linux](https://stackoverflow.com/questions/4617478/porting-winsock-to-linux-sockets) so it probably just needs some initialization. See [this link](https://stackoverflow.com/a/4618477/198536) for what to add. – wallyk Dec 19 '18 at 19:38
  • Sorry i am very new to Python and not sure how to implement #ifndef _WIN32. Should i just put it as if statament before running the socket? Thanks. – lemikistu Dec 19 '18 at 19:50
  • Oh, sorry. If your code will only run on Windows, you don't need the `#ifndef`. Just add the call to `WSAStartup()` at startup and `WSACleanup()` at termination. I don't know about any parameters since I don't use Windows, but it should be easy to look up. – wallyk Dec 19 '18 at 22:42

0 Answers0