国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

Pythonsocket編程之構(gòu)造IP首部和ICMP首部

2019-11-14 17:08:45
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

這兩天在做一個(gè)實(shí)驗(yàn)需要自己構(gòu)造ip首部,遇到諸多問(wèn)題,搞了一天終于搞定。

關(guān)于socket的介紹網(wǎng)上一大堆,我只記錄構(gòu)造IP頭時(shí)我遇到的問(wèn)題。由于沒(méi)玩過(guò)socket構(gòu)造IP首部,網(wǎng)上找了段代碼研究下,無(wú)奈代碼跑不動(dòng),各種問(wèn)題,網(wǎng)上搜集資料無(wú)果,從基礎(chǔ)學(xué)起,加上自己的腦洞總算解決了。

我想自己構(gòu)造一個(gè)自定義IP頭的ICMP回送請(qǐng)求,網(wǎng)上找了段代碼,自己改了改,現(xiàn)在長(zhǎng)這個(gè)樣子:

 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')

步驟很簡(jiǎn)單,就是自己創(chuàng)建個(gè)套接字,然后把頭構(gòu)造好再發(fā)送就行了,但是一般的套接字是無(wú)法自己更改IP頭的,只能從IP數(shù)據(jù)報(bào)的數(shù)據(jù)部分開(kāi)始構(gòu)造,想要構(gòu)造IP首部就要用到原始套接字,用原始套接字可以從IP首部開(kāi)始構(gòu)造,但是如果用原始套接字需要root權(quán)限,開(kāi)始我在OS X下用IDE,程序總是報(bào)錯(cuò)socket.error: [Errno 1] Operation not permitted,就是因?yàn)闄?quán)限的問(wèn)題,在終端里sudo運(yùn)行就沒(méi)有權(quán)限問(wèn)題了(Ps:如果想用root權(quán)限打開(kāi)IDE,又不想切換賬戶的話,終端里sudo ./IDE就行了)現(xiàn)在有了權(quán)限,開(kāi)始報(bào)別的錯(cuò)了,提示socket.error: [Errno 22]Invalid argument。

這是創(chuàng)建原始套接字的代碼,第一行第三個(gè)值255是IPPROTO_RAW的值,如果要構(gòu)造IP頭,就要加上第二行代碼設(shè)置IP_HDRINCL,第一個(gè)值0是IPPROTO_IP的值

s=socket.socket(socket.AF_INET,socket.SOCK_RAW,255)
s.setsockopt(0, socket.IP_HDRINCL, 1)

如果這樣設(shè)置在OS X下就會(huì)在調(diào)用sendto()的位置報(bào)Invalid argument錯(cuò)誤,后來(lái)發(fā)現(xiàn)問(wèn)題出在第一行的第三個(gè)參數(shù)255上,經(jīng)測(cè)試發(fā)現(xiàn)

在OS X下,這個(gè)參數(shù)置成0或255都會(huì)報(bào)錯(cuò)

在WINDOWS下 ,這個(gè)參數(shù)置成0或255都不會(huì)報(bào)錯(cuò)

linux下,這個(gè)參數(shù)置成0會(huì)報(bào)錯(cuò),置成255不會(huì)報(bào)錯(cuò)

 

現(xiàn)在可以構(gòu)造任意的源IP和目的IP的ICMP回送請(qǐng)求了,IP首部字段的ID,長(zhǎng)度,校驗(yàn)和置成0就可以,內(nèi)核協(xié)議棧會(huì)修正。

在linux上抓包發(fā)現(xiàn)目的IP為同子網(wǎng)下不存在的主機(jī)IP時(shí),是抓不到ICMP包的,這是因?yàn)橹鳈C(jī)先發(fā)送ARP包請(qǐng)求目的IP的MAC地址得不到回應(yīng),而不能進(jìn)一步發(fā)送ICMP回送請(qǐng)求,也就是說(shuō)PING命令中提示的Request timeout for icmp_seq是因?yàn)锳RP請(qǐng)求得不到應(yīng)答而產(chǎn)生的。


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 台北市| 黑水县| 寿阳县| 依兰县| 万山特区| 凉城县| 汝州市| 开化县| 无为县| 建德市| 易门县| 文化| 毕节市| 宜宾市| 宜城市| 平南县| 尉氏县| 明星| 九江县| 鄄城县| 罗定市| 樟树市| 平遥县| 兴义市| 康乐县| 清原| 炎陵县| 德令哈市| 大名县| 南澳县| 湾仔区| 泗水县| 县级市| 抚松县| 舞阳县| 阳信县| 太原市| 宝鸡市| 拜城县| 新巴尔虎右旗| 鹤壁市|