Using the underlying sockets to decode the underlying traffic is the focus of this effort.
First to capture the first package
1 #Coding:utf-8import Socket2 3 #host IP for listening4Host ="192.168.1.100"5 6Socket_protocol =socket. IPPROTO_ICMP7 8Sniffer =Socket.socket (socket.af_inet, socket. Sock_raw, Socket_protocol)9 Sniffer.bind (host, 0)TenSniffer.setsockopt (socket. IPPROTO_IP, Socket. IP_HDRINCL, 1) One ARaw_buffer = Sniffer.recvfrom (65535) - PrintRaw_buffer
The following line explains the meaning of the above code.
1. Import the Socket Package
2. Native IP address to listen on
3. Assigning an ICMP variable to a socket_protocol variable
4. Create a Soket object for the sniffer variable that is IPv4 the original socket and specifies that its protocol is ICMP
5. Bind to the specified address and port for listening
6. Set the option parameter for the sniffer socket to carry the IP header
7. Assign the original data received by the socket on the listening port to Raw_buffer
8. Print the value of the Raw_buffer
At this point, we run this script with root privileges, and open another terminal to send ICMP packets to any address, and the recvfrom of the interface we listen to will receive back the listener back to the specified address. Recvfrom differs from recv in that the Recvfrom will receive the package address at the same time. Format of (string, address)
At this time we can see the printed value, is a bunch of things completely do not understand, because there is no decoding state, the following we will decode the IP header.
This is accomplished using Python's struct and ctypes two libraries.
1 #Coding:utf-8import Socket2 Importstruct3 fromcTYPESImport*4 5 #Listening Host iphost = "192.168.1.100"6 7 #IP Header Definition8 classIP (Structure):9_fields_ = [Ten("IHL", C_ubyte, 4), One("version", C_ubyte, 4), A("TOS", C_ubyte), -("Len", C_ushort), -("ID", C_ushort), the("Offset", C_ushort), -("TTL", C_ubyte), -("Protocol_num", C_ubyte), -("sum", C_ushort), +("src", C_uint), -("DST", C_uint), + ] A at def __new__(Self, socket_buffer=None): - returnself.from_buffer_copy (Socket_buffer) - - def __init__(Self, socket_buffer=None): -Self.protocol_map = {1:"ICMP", 6:"TCP", 17:"UDP"} - in #Readable IP address -self.src_address = Socket.inet_ntoa (Struct.pack ("<i", SELF.SRC)) toself.dst_address = Socket.inet_ntoa (Struct.pack ("<i", SELF.DST)) + - #type of protocol the Try: *Self.protocol =Self.protocol_map[self.protocol_num] $ except:Panax NotoginsengSelf.protocol =Str (self.protocol_num) - theSocket_protocol =socket. IPPROTO_ICMP + ASniffer =Socket.socket (socket.af_inet, socket. Sock_raw, Socket_protocol) the Sniffer.bind (host, 0) +Sniffer.setsockopt (socket. IPPROTO_IP, Socket. IP_HDRINCL, 1) - $ Try: $ whileTrue: -Raw_buffer = Sniffer.recvfrom (65535) [0] - theIp_header = IP (raw_buffer[:20]) - Wuyi Print "Protocol: %s%s,%s"%(Ip_header.protocol, ip_header.src_address, ip_header.dst_address) the - exceptKeyboardinterrupt: Wu Pass
1. Import each module
2. The native IP address of the listener
3. Construct a struct (structure) IP that resolves IP headers using ctypes
4. Use the From_buffer_copy method to generate an instance of the IP class for the received data in the __new__ method
5. The __init__ method initializes part of the data to the corresponding instance property values.
6. In particular, the code below uses the pack method of the Python struct library to convert the SRC and DST long values to strings with the specified format parameters, and then uses the Socket.inet_ntoa method to convert a string of numbers of strings to the corresponding IP format. The last assignment to the corresponding SRC or DST variable
# readable IP addressself.src_address = socket.inet_ntoa (Struct.pack ("<i", self.src)) self.dst_address = Socket.inet _ntoa (Struct.pack ("<i", SELF.DST))
7. A server that receives ICMP packets, nothing to say.
8. An infinite loop listens on the specified port, passing the first part of the data received by Recvfrom to the part of the IP address to Raw_buffer
9. The first 20 bytes of the IP header Raw_buffer are passed to the struct for decoding.
10. Then print.
You can see the general idea is to take the prototype socket data, and then by simulating the C language structure, using the Python library to the format of the package one by one corresponding decoding, the decoded data printed out.
As you can see, the IP layer can already parse out where the packets are going from.
python resolves raw IP header data using raw sockets