Python实现Tracert追踪TTL值的方法详解
本文详解如何利用Python的Scapy库实现Tracert路由追踪功能。通过构造不同TTL值的ICMP数据包,利用路由器TTL减一后超时返回ICMP不可达报文的原理,逐跳获取中间节点IP。文章提供了完整的Python代码示例,包括单包探测与自动化追踪逻辑,帮助开发者理解并实现网络路径探测工具。
Tracert原理与Scapy基础
Tracert命令的核心原理在于IP路由机制:数据包每经过一个路由节点,其TTL(Time To Live)值便会减一。若TTL值归零时数据包仍未抵达目标主机,当前路由节点会向源主机返回一个“数据包不可达”的响应。借此机制,我们可以获取沿途各路由节点的IP地址。下文将展示如何使用Scapy库构造一个简单的路由追踪工具,并完成一次完整的追踪过程。
- 在开始之前,需要安装必要的扩展库:
- pip install scapy
首先,我们需要了解Scapy如何发送和接收数据包。以下案例演示了基本的发包与收包过程。
>>> from random import randint
>>>
>>> RandomID=randint(1,65534)
>>> packet = IP(dst="8.141.58.64", ttl=1, id=RandomID) / ICMP(id=RandomID, seq=RandomID) / "hello lyshark"
>>> respon = sr1(packet,timeout=3,verbose=0)
>>>
>>> respon
<IP version=4 ihl=5 tos=0xc0 len=61 id=14866 flags= frag=0 ttl=64 proto=icmp chksum=0xbc9a src=192.168.1.1 dst=192.168.1.2 |<ICMP type=time-exceeded code=ttl-zero-during-transit chksum=0xf4ff reserved=0 length=0 unused=None |<IPerror version=4 ihl=5 tos=0x0 len=33 id=49588 flags= frag=0 ttl=1 proto=icmp chksum=0x4f79 src=192.168.1.2 dst=61.135.169.125 |<ICMPerror type=echo-request code=0 chksum=0x30c4 id=0xc1b4 seq=0xc1b4 |<Raw load='hello lyshark' |>>>>>
路由追踪的基本原理(参考互联网通用机制):初始发送一个TTL值为1的数据包。当该包到达第一个路由器时,TTL减为0导致超时,路由器随即发送ICMP超时通知,从而记录下第一个路由器的IP。随后将TTL值加1,数据包安全通过第一个节点;第二个路由器的处理逻辑相同,即丢弃包并发送超时通知,进而记录其IP。此过程循环进行,直到数据包最终抵达目标主机,从而打印出所有经过的路由器列表。

将上述手动过程自动化,即可实现数据包的自动跟踪。Python实现代码如下所示:
Python实现路由追踪代码
from scapy.all import *
from random import randint
import time,ipaddress,threading
from optparse import OptionParser
def ICMP_Ping(addr):
RandomID=randint(1,65534)
packet = IP(dst=addr, ttl=64, id=RandomID) / ICMP(id=RandomID, seq=RandomID) / "lyshark"
respon = sr1(packet,timeout=3,verbose=0)
if respon:
print("[+] --> {}".format(str(respon[IP].src)))
# By: LyShark.com
def TraceRouteTTL(addr):
for item in range(1,128):
RandomID=randint(1,65534)
packet = IP(dst=addr, ttl=item, id=RandomID) / ICMP(id=RandomID, seq=RandomID)
respon = sr1(packet,timeout=3,verbose=0)
if respon != None:
ip_src = str(respon[IP].src)
if ip_src != addr:
print("[+] --> {}".format(str(respon[IP].src)))
else:
print("[+] --> {}".format(str(respon[IP].src)))
return 1
else:
print("[-] --> TimeOut")
time.sleep(1)
def Banner():
print(" _ ____ _ _ ")
print(" | | _ _/ ___|| |__ __ _ _ __| | __")
print(" | | | | | \___ \| '_ \ / _` | '__| |/ /")
print(" | |__| |_| |___) | | | | (_| | | | < ")
print(" |_____\__, |____/|_| |_|\__,_|_| |_|\_\\")
print(" |___/ \n")
print("E-Mail: me@lyshark.com")
if __name__== "__main__":
Banner()
parser = OptionParser()
parser.add_option("--mode",dest="mode",help="选择使用的工具模式<ping/trace>")
parser.add_option("-a","--addr",dest="addr",help="指定一个IP地址或范围")
(options,args) = parser.parse_args()
print("By: LyShark.com")
# 使用方式: lyshark.py --mode=ping -a 192.168.1.0/24
if options.mode == "ping":
net = ipaddress.ip_network(str(options.addr))
for item in net:
t = threading.Thread(target=ICMP_Ping,args=(str(item),))
t.start()
# 使用方式: lyshark.py --mode=trace -a 8.141.58.64
elif options.mode == "trace":
TraceRouteTTL(str(options.addr))
else:
parser.print_help()
追踪探测的实际效果如下所示:

至此,关于Python实现Tracert追踪TTL值的方法详解已介绍完毕。如需了解更多Python Tracert相关技巧,欢迎搜索本站往期文章或继续浏览后续内容。感谢大家的支持!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









