07python實現traceroute程序


# 這個腳本是實現Linux中traceroute程序的,是探測從我們這個機器到我們要探測的IP地址中間都需要經過那些路由。
# 原理:我們的機器發送UDP高端口的數據包,發送給目的地址,首先設置ttl為1,然后逐次增加,在沒有到達我們的目的IP
# 地址的路由,會發送ICMP的超時報文,然后我們從中提取IP地址,因為我們發送的是高端口的報文,到達目的地址的時候,
# 目的地址會發送ICMP的端口不可達報文,這樣我們就探測出從我們源端口到目的端口的路由。
from scapy.all import *
import struct,re,random

# 跟我們實現ping程序的想法是一樣的,首先構造一個發送一個UDP報文的函數,
# 入參為目的地址,ttl數。
def traceroute_one(dst,ttl_no,dport):
# 定義發包時間。
send_time = time.time()
try:
# 發送一個包,接收一個包。
traceroute_one_reply = sr1(IP(dst=dst, ttl=ttl_no) / UDP(dport=dport) / b'hello world', timeout=1,
verbose=False)
# 判斷ICMP包是不是超時回答。
if traceroute_one_reply.getlayer(ICMP).type == 11 and traceroute_one_reply.getlayer(ICMP).code == 0:
# 提取源地址
src_ip = traceroute_one_reply.getlayer(IP).src
# 定義接收時間。
recv_time = time.time()
# 計算時間ms數
mid_time = (recv_time - send_time) * 1000
# 返回。
return 1,src_ip,mid_time
# 這里接接收的是最后一跳。ICMP應該是端口不可達。
elif traceroute_one_reply.getlayer(ICMP).type == 3 and traceroute_one_reply.getlayer(ICMP).code == 3:
# 下邊處理是一樣的。
src_ip = traceroute_one_reply.getlayer(IP).src
recv_time = time.time()
mid_time = (recv_time - send_time) * 1000
return 2, src_ip, mid_time
except Exception as e:
return None


def traceroute(dst,hops):
# 目的端口從33434開始算起,入參為目的地址,我們想要查找的路由的條數。
dport = 33434
hop = 0
# 進行循環包。
while hop < hops:
hop += 1
# 這里需要改變端口。
dport += hop
# 發送一個包,獲取返回值。
traceroute_result = traceroute_one(dst,hop,dport)
# 如果出現了錯誤,打印*號。
if traceroute_result == None:
print('*')
# 這里代表中間路由,我們進行打印信息。
elif traceroute_result[0] == 1:
print("%d %s %4.2fms" % (hop,traceroute_result[1],traceroute_result[2]))
# 最后一個包,為端口不可達,打印信息后,需要退出循環,因為已經到達目的地址了,雖然可能沒有達到我們定義的條數。
elif traceroute_result[0] == 2:
print("%d %s %4.2fms" % (hop, traceroute_result[1], traceroute_result[2]))
break
time.sleep(1)
if __name__ == "__main__":
traceroute('180.101.49.12',10)
# 接下來我們就可以使用wirshark進行抓包來看一下。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM