Python实现Tracert追踪TTL值的方法详解

今天早睡
今天早睡
发布时间:2026-10-16 | 6人浏览过
原创

本文详解如何利用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相关技巧,欢迎搜索本站往期文章或继续浏览后续内容。感谢大家的支持!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表