Python Packet Sniffer and Sockets for Noobs

2019-08-12 02:03发布

问题:

So I have some questions about sockets and sniffer programming... I've just started programming and have a project where I would like to use information that is sent across my network.

I tried watching several videos on youtube that talk about this process a little, and tried to find better material to research it further, but I haven't been able to find a source that makes sense to me.

The code I included came from a video on youtube and seemed to make sense as they explained it, but I guess he might have been using Linux or something else because Windows did not support AF_PACKET. After some research I found that people use AF_INET, but I got the error:

OSError: [WinError 10043] The requested protocol has not been configured into the system, or no implementation for it exists

Is there a place or a way someone might be able to explain sockets a little bit for me? I don't plan to use windows for the final version of this project, and I also plan to modify it for bluetooth in the future, so I would like to learn the reasoning behind things if I can find a way to do that.

` import socket import struct import textwrap

def main():
    conn = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.ntohs(3))
        while True:
        raw_data, addr = conn.recvfrom(65535)
        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, data[:14]))


#unpack ethernet frame
def ethernet_frame(data):
     dest_mac, src_mac, proto = struct.unpack('! 6s 6s H', data[:14])
     return get_mac_addr(dest_mac), get_mac_addr(src_mac), socket.htons(proto), data[14:]

#Get Mac Address
def get_mac_addr(bytes_addr):
    bytes_str = map('{:02x}'.format, bytes_addr)
    return ':'.join(bytes_str).upper()

main()

`

回答1:

The OSes on which you use a socket for packet sniffing are:

  1. Linux
  2. Irix

Windows is not on that list (neither are anything with "BSD" in the name, OS X, Solaris, HP-UX, AIX, etc.). Linux and Irix both happen to use sockets to do sniffing, but that's just their choice (and they didn't choose the same type of socket, they just happened to choose sockets).

If you want to write a sniffer, you're probably best advised to use a wrapper around libpcap/WinPcap, and let them deal with the painful details of the way packet sniffing is done on a particular operating system. Wrappers for Python include pylibpcap and pcapy; I don't know whether either of them work on Windows with WinPcap.

(Note that you are not guaranteed to get Ethernet headers on sniffed packets; you should call pcap_datalink(), or whatever the wrapper's equivalent is, and check its return value - if it's not DLT_EN10MB, or the wrapper's equivalent, you won't be getting Ethernet headers.)

AF_INET raw sockets, on any platform, aren't going to give you Ethernet headers. I don't know what you'll get with a protocol argument of 3 - 3 is the Internet protocol number for GGP, as per RFC 823 Appendix A, and that protocol is ancient and not used as far as I know; you'll probably end up with a socket on which you can send GGP packets and from which you can receive GGP packets, for what that's worth (which is not much). (Also, the arguments to the socket() call in C are in host byte order, and Python probably works the same, so you probably don't want that socket.ntohs() in there, not that it'll make a difference.)