Construct IP and ICMP headers for Python socket programming, pythonicmp

Source: Internet
Author: User

Construct IP and ICMP headers for Python socket programming, pythonicmp

In the past two days, an experiment requires you to construct your own IP Address Header. If you encounter many problems, you have finally completed the experiment in one day.

There are a lot of questions about socket on the Internet. I only record the problems I encountered when constructing an IP header. Because I have never played the socket to construct the IP Address Header, I found some code on the Internet, but the Code does not work. Due to various problems, it is fruitless to collect information on the Internet, I finally solved the problem by adding my own brain holes.

I want to construct an ICMP return request with a custom IP Address Header. I found a code segment on the Internet and changed it. It looks like this:

 1 import socket 2 import struct 3 def checksum(source_string): 4     sum = 0 5     countTo = (len(source_string)/2)*2 6     count = 0 7     while count<countTo: 8         thisVal = ord(source_string[count + 1])*256 + ord(source_string[count]) 9         sum = sum + thisVal10         sum = sum & 0xffffffff 11         count = count + 212     if countTo<len(source_string):13         sum = sum + ord(source_string[len(source_string) - 1])14         sum = sum & 0xffffffff 15     sum = (sum >> 16)  +  (sum & 0xffff)16     sum = sum + (sum >> 16)17     answer = ~sum18     answer = answer & 0xffff19     answer = answer >> 8 | (answer << 8 & 0xff00)20     return answer21 def ping(ip):22     s=socket.socket(socket.AF_INET,socket.SOCK_RAW,255)24     s.setsockopt(0, socket.IP_HDRINCL, 1)25 # now start constructing the packet26  27     source_ip = '172.16.12.1'28     dest_ip = ip29  30 # ip header fields31     ihl = 532     version = 433     tos = 034     tot_len = 2835     id = 036     frag_off = 037     ttl = 25538     protocol = 139     check = 0  40     saddr =socket.inet_aton ( source_ip )  #Spoof the source ip address if you want to41     daddr = socket.inet_aton ( dest_ip )44     ihl_version = (version << 4) + ihl45     # the ! in the pack format string means network order46     ip_header = struct.pack('!BBHHHBBH4s4s', ihl_version, tos, tot_len, id, frag_off, ttl, protocol, check, saddr, daddr)47     packet = struct.pack(48             "!BBHHH", 8, 0, 0, 0, 049     )50     chksum=checksum(packet)51     packet = struct.pack(52             "!BBHHH", 8, 0, chksum, 0, 053     )54     packet=ip_header+packet55     s.sendto(packet,(ip,1))56     print "done"57     58 if __name__=='__main__':59     ping('172.31.0.1')

The procedure is very simple, that is, you can create a socket and then construct the header and then send it again. However, generally, the socket cannot change the IP header by yourself. It can only be constructed from the data part of the IP datagram, the original socket is required to construct the IP header. The original socket can be constructed from the IP header. However, if the original socket requires the root permission, I will use the IDE in OS X, the program always reports an error socket. error: [Errno 1] Operation not permitted. It is because of permission issues that sudo does have no permission to run on the terminal (Ps: If you want to open IDE with root permission, if you do not want to switch your account, sudo is in the terminal. /IDE on the line) Now you have the permission and start to report other errors, prompting socket. error: [Errno 22] Invalid argument.

This is the code for creating the original socket. The third value in the first line is the value of IPPROTO_RAW. To construct an IP header, add the second line of code to set 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 parameter is set to OS X, the Invalid argument error will be reported at the location where sendto () is called. Later, the error is found in the third parameter 255 in the first line. After testing, it is found that

In OS X, if this parameter is set to 0 or 255, an error is returned.

In WINDOWS, no error is reported if this parameter is set to 0 or 255.

In LINUX, if this parameter is set to 0, an error is returned. If this parameter is set to 255, no error is returned.

 

Now we can construct an ICMP return request for any source IP address and destination IP address. The ID, length, and checksum of the IP header field can be set to 0, and the kernel protocol stack can be corrected.

When packet capture on linux finds that the destination IP address is a Host IP address that does not exist in the same subnet, the ICMP packet cannot be captured because the host sends an ARP packet request to the MAC address of the destination IP address and does not receive a response, the Request timeout for icmp_seq prompted by the PING command is generated because the ARP Request is not answered.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.