These two days in an experiment need to construct their own IP header, encountered a lot of problems, a day finally fix.
Introduction to the socket on the internet a lot of, I only record the construction of the IP header when I encountered problems. Because did not play the socket constructs the IP header, looked for the paragraph code research on the net, helpless code to run, all sorts of problems, the net collects the data to have no fruit, from the foundation study, adds own brain hole finally solves.
I want to construct a custom IP header of the ICMP echo request, the network to find a section of code, their own change, now look like this:
1 ImportSocket2 Importstruct3 defChecksum (source_string):4sum =05Countto = (len (source_string)/2) * *6Count =07 whilecount<Countto:8Thisval = Ord (Source_string[count + 1]) *256 +Ord (Source_string[count])9sum = sum +ThisvalTensum = sum & 0xFFFFFFFF OneCount = Count + 2 A ifcountto<Len (source_string): -sum = sum + ord (Source_string[len (source_string)-1]) -sum = sum & 0xFFFFFFFF thesum = (sum >> +) + (sum & 0xFFFF) -sum = sum + (sum >> 16) -Answer = ~sum -Answer = answer & 0xFFFF +Answer = Answer >> 8 | (Answer << 8 & 0xff00) - returnAnswer + defPing (IP): AS=socket.socket (Socket.af_inet,socket. sock_raw,255) -S.setsockopt (0, socket. IP_HDRINCL, 1) - #Now start constructing the packet - -SOURCE_IP =' 172.16.12.1' -DEST_IP =IP in - #IP Header fields toIHL = 5 +Version = 4 -TOS =0 theTot_len = 28 *ID =0 $Frag_off =0Panax NotoginsengTTL = 255 -protocol = 1 theCheck =0 +Saddr =socket.inet_aton (SOURCE_IP)#spoof the source IP address if you want to ADADDR =Socket.inet_aton (DEST_IP) -Ihl_version = (version << 4) +IHL $ #The! In the Pack format string means network order $Ip_header = Struct.pack ('! Bbhhhbbh4s4s', Ihl_version, TOS, Tot_len, ID, Frag_off, TTL, protocol, check, SADDR, daddr) -Packet =Struct.pack ( - "! Bbhhh", 8, 0, 0, 0, 0 the ) -chksum=checksum (packet)WuyiPacket =Struct.pack ( the "! Bbhhh", 8, 0, chksum, 0, 0 - ) Wupacket=ip_header+Packet -S.sendto (Packet, (ip,1)) About Print " Done" $ - if __name__=='__main__': -Ping' 172.31.0.1')
The step is very simple, is to create a socket, and then the head structure and then send the line, but the general socket is unable to change the IP header itself, only from the data portion of the IP datagram to start the construction, want to construct the IP header to use the original socket, with the original socket can be constructed from the IP header, But if you need root permission with the original socket, start I use the IDE under OS X, the program always error socket.error: [Errno 1] Operation not permitted, is because of the problem of permissions, in the terminal sudo run there is no permissions problem ( Ps: If you want to open the IDE with root privileges, and do not want to switch accounts, the terminal sudo./ide on the line) now have the permission to start reporting other errors, prompted Socket.error: [Errno 22]invalid argument.
This is the code that creates the original socket, the first row the third value 255 is the value of Ipproto_raw, if you want to construct the IP header, add the second line of code setting IP_HDRINCL, the first value 0 is the value of IPPROTO_IP
S=socket.socket (Socket.af_inet,socket. sock_raw,255)
S.setsockopt (0, socket. IP_HDRINCL, 1)
If this is set under OS X, the invalid argument error is reported in the location of the call to SendTo (), and then the problem is found on the third parameter 255 of the first line, which is tested
Under OS X, this parameter is set to 0 or 255 to be an error.
Under Windows, this parameter is set to 0 or 255 without error.
Under Linux, this parameter is set to 0 will be error, set to 255 will not error
It is now possible to construct an ICMP echo request for any source IP and destination IP, the ID of the IP header field, the length, the checksum set to 0, and the kernel protocol stack will be fixed.
On the Linux capture packet discovery destination IP for the same subnet does not exist under the host IP, is not able to catch ICMP packets, this is because the host sends ARP packet request destination IP MAC address is not responded to, and can not further send ICMP echo request, that is, ping command prompt Timeout for icmp_seq occurs because the ARP request is not answered.
Construction of the Python socket programming IP header and ICMP header