python中的TCP Traceroute

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python中的TCP Traceroute相关的知识,希望对你有一定的参考价值。

我正在编写一个python脚本来执行'TCP Traceroute'。我知道scapy是一个很有用的库,但是我没有得到我需要的结果。谁能帮我解决这个问题?我希望python脚本生成与命令行类似的结果。

我使用linux,python 2.7和scapy 2.4。我不确定为什么所有跳跃显示相同的IP地址。

from scapy.layers.inet import traceroute

result, unans = traceroute('172.217.17.46', maxttl=30)
   for snd, rcv in result:
   print snd.ttl, rcv.src, snd.sent_time, rcv.time

当我运行此代码时,我得到以下结果:

1 10.0.2.2 1541113255.58 1541113255.6
2 172.217.17.46 1541113255.58 1541113255.72
3 172.217.17.46 1541113255.58 1541113255.72
4 172.217.17.46 1541113255.58 1541113255.72
5 172.217.17.46 1541113255.59 1541113255.73
6 172.217.17.46 1541113255.59 1541113255.73
7 172.217.17.46 1541113255.6 1541113255.74
8 172.217.17.46 1541113255.6 1541113255.74
9 172.217.17.46 1541113255.6 1541113255.74
10 172.217.17.46 1541113255.61 1541113255.75
11 172.217.17.46 1541113255.61 1541113255.75
12 172.217.17.46 1541113255.61 1541113255.75
13 172.217.17.46 1541113255.62 1541113255.76
14 172.217.17.46 1541113255.62 1541113255.76
15 172.217.17.46 1541113255.62 1541113255.76
16 172.217.17.46 1541113255.62 1541113255.77
17 172.217.17.46 1541113255.63 1541113255.77
18 172.217.17.46 1541113255.63 1541113255.77
19 172.217.17.46 1541113255.63 1541113255.77
20 172.217.17.46 1541113255.63 1541113255.77
21 172.217.17.46 1541113255.64 1541113255.78
22 172.217.17.46 1541113255.64 1541113255.78
23 172.217.17.46 1541113255.64 1541113255.78
24 172.217.17.46 1541113255.64 1541113255.78
25 172.217.17.46 1541113255.65 1541113255.79
26 172.217.17.46 1541113255.65 1541113255.79
27 172.217.17.46 1541113255.65 1541113255.79
28 172.217.17.46 1541113255.66 1541113255.8
29 172.217.17.46 1541113255.66 1541113255.8
30 172.217.17.46 1541113255.66 1541113255.8

我希望从命令行运行tcptraceroute时获得相同的结果:tcptraceroute 172.217.17.46

命令行的结果:

Selected device en0, address 192.168.86.24, port 49618 for outgoing packets
Tracing the path to 172.217.17.46 on TCP port 80 (http), 30 hops max
 1  192.168.86.1  2.848 ms  1.224 ms  1.330 ms
 2  96.120.101.53  10.423 ms  13.646 ms  12.221 ms
 3  po-115-rur102.bellevue.wa.seattle.comcast.net (68.87.205.245)  18.877 ms  18.818 ms  12.593 ms
 4  be-103-ar01.seattle.wa.seattle.comcast.net (69.139.164.77)  15.188 ms  14.272 ms  14.005 ms
 5  be-33650-cr01.seattle.wa.ibone.comcast.net (68.86.93.165)  14.547 ms  15.273 ms  19.750 ms
 6  be-10846-pe01.seattle.wa.ibone.comcast.net (68.86.86.90)  14.546 ms  14.266 ms  13.521 ms
 7  50.242.150.242  14.159 ms  15.791 ms  14.037 ms
 8  74.125.243.195  14.635 ms  22.377 ms  13.558 ms
 9  72.14.236.174  15.051 ms  27.454 ms  14.312 ms
 10  108.170.235.60  66.430 ms  69.762 ms  68.606 ms
 11  216.239.58.255  85.531 ms  84.354 ms  85.303 ms
 12  172.253.51.157  153.310 ms  154.710 ms  153.375 ms
 13  209.85.142.166  157.376 ms  166.552 ms  157.562 ms
 14  216.239.43.37  170.523 ms  168.040 ms  158.182 ms
 15  108.170.241.225  158.953 ms  161.418 ms  169.103 ms
 16  108.170.236.137  158.561 ms  161.635 ms  157.510 ms
 17  ams16s29-in-f46.1e100.net (172.217.17.46) [open]  165.981 ms  160.451 ms  166.120 ms

问题1:scapy traceroute功能真的是TCP traceroute吗?问题2:我是scapy和traceroute的新手,代码中是否有遗漏的东西?如果scapy不适合,我还可以使用其他库吗?我真的很感激帮助和任何指针。

注意:我想为IPV6和IPV4执行TCP跟踪路由。

答案

scapy traceroute功能真的是TCP traceroute吗? 是的它确实做TCP traceroute(除其他外)。看看Scapy source-code

    @conf.commands.register
    def traceroute(target, dport=80, minttl=1, maxttl=30, sport=RandShort(), l4 = None, filter=None, timeout=2, verbose=None, **kargs):
        """Instant TCP traceroute traceroute(target, [maxttl=30,] [dport=80,] [sport=80,] [verbose=conf.verb]) -> None"""
        if verbose is None:
            verbose = conf.verb
        if filter is None:
            # we only consider ICMP error packets and TCP packets with at
            # least the ACK flag set *and* either the SYN or the RST flag
            # set
            filter="(icmp and (icmp[0]=3 or icmp[0]=4 or icmp[0]=5 or icmp[0]=11 or icmp[0]=12)) or (tcp and (tcp[13] & 0x16 > 0x10))"
        if l4 is None:
            a,b = sr(IP(dst=target, id=RandShort(), ttl=(minttl,maxttl))/TCP(seq=RandInt(),sport=sport, dport=dport),
                     timeout=timeout, filter=filter, verbose=verbose, **kargs)
        else:
            # this should always work
            filter="ip"
            a,b = sr(IP(dst=target, id=RandShort(), ttl=(minttl,maxttl))/l4,
                     timeout=timeout, filter=filter, verbose=verbose, **kargs)
        a = TracerouteResult(a.res)
        if verbose:
            a.show()
        return a,b


I want to perform tcp traceroute for both ipv6 and ipv4

Again looking at Scapy source code, traceroot6 can do the job:
def traceroute6(target, dport=80, minttl=1, maxttl=30, sport=RandShort(), 
                l4 = None, timeout=2, verbose=None, **kargs):
    """
    Instant TCP traceroute using IPv6 :
    traceroute6(target, [maxttl=30], [dport=80], [sport=80]) -> None
    """
    if verbose is None:
        verbose = conf.verb

    if l4 is None:
        a,b = sr(IPv6(dst=target, hlim=(minttl,maxttl))/TCP(seq=RandInt(),sport=sport, dport=dport),
                 timeout=timeout, filter="icmp6 or tcp", verbose=verbose, **kargs)
    else:
        a,b = sr(IPv6(dst=target, hlim=(minttl,maxttl))/l4,
                 timeout=timeout, verbose=verbose, **kargs)
    a = TracerouteResult6(a.res)
    if verbose:
        a.display()
    return a,b

traceroute ipv6的示例代码:

from scapy.all import *

waypoint = "2001:301:0:8002:203:47ff:fea5:3085"
target = "2001:5f9:4:7:2e0:81ff:fe52:9a6b"
traceroute6(waypoint, minttl=10, maxttl=40, l4=IPv6ExtHdrRouting(addresses=[target])/ICMPv6EchoRequest(data=RandString(7)))


I am not sure why same IP addresses are shown for all the hops.

通过在traceroute()函数的l4参数中指定完整数据包来使用DNS traceroute,您不会获得所有跃点的相同IP地址。

from scapy.all import *

target = ["172.217.17.46"]
result, unans = traceroute(target, l4=UDP(sport=RandShort())/DNS(qd=DNSQR(qname="www.google.com")))

或者您可以使用TCP SYN traceroute获得类似的结果:

from scapy.all import *

target = ["172.217.17.46"]
result, unans = sr(IP(dst=target, ttl=(1, 10)) / TCP(dport=53, flags="S"))
for snd, rcv in result:
  print(snd.ttl, rcv.src, snd.sent_time, rcv.time)

或者您可以使用IP and UDP packets创建traceroute来实现Scapy,如下所示:

from scapy.all import *
hostname = "172.217.17.46"
for i in range(1, 28):
    pkt = IP(dst=hostname, ttl=i) / UDP(dport=33434)
    reply = sr1(pkt, verbose=0)
    if reply is None:
        break
    elif reply.type == 3:
        print("Done!", reply.src)
        break
    else:
        print("%d hops away: " % i, reply.src, reply.time)


Is there any other library which I can use if Scapy is not suitable?
  • 看看webb。我没有使用它,但你可以像这样使用它:
import webb
webb.traceroute("www.google.com")
webb.traceroute("www.google.com",'file-name.txt')
  • 此外,Thomas Guettler的check out this tcptraceroute
  • 或者这个由Addy Yeow(Ayeowch)执行的Multi-source traceroute with geolocation。 除其他外,使用-j参数(JSON_FILE),它将列出JSON文件格式的源。
  • 或克里斯蒂安克雷比奇的this implementation。它可以将traceroute信息解析为一系列跳跃对象,每个跳跃对象由一个或多个探测结果组成,同样也包括对象实例。此外,字符串格式化产生熟悉的traceroute输出。 (为了与Python 3合作,需要将cStringIO改为from io import StringIO

没有scapy(使用Windows控制台):

创建一个名为output.py的脚本,其中包含以下内容:

import sys
from subprocess import Popen

if len(sys.argv) < 2:
    print('Usage: output.py "command to watch"')
    sys.exit(1)

cmd_line = sys.argv[1:]

p = Popen(cmd_line)
p.communicate()[0]

用法示例:python output.py ping google.com

ping的示例输出:

Pinging google.com [216.58.209.14] with 32 bytes of data:
Reply from 216.58.209.14: bytes=32 time=50ms TTL=56
Reply from 216.58.209.14: bytes=32 time=45ms TTL=56
Reply from 216.58.209.14: bytes=32 time=45ms TTL=56
Reply from 216.58.209.14: bytes=32 time=45ms TTL=56

Ping statistics for 216.58.209.14:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 45ms, Maximum = 50ms, Average = 46ms

用法示例:python output.py tracert google.com

tracert的示例输出:

Tracing route to google.com [172.217.18.174]
over a maximum of 30 hops:

  1    <1 ms     1 ms     1 ms  192.168.0.1
  2     6 ms     8 ms     8 ms  xx.xx.xx.xx
  3     8 ms     8 ms     8 ms  [xx.xx.xxx.xxx]
  4    17 ms    16 ms    16 ms  be3549.ccr31.sof02.atlas.cogentco.com [154.54.59.138]
  5    18 ms    17 ms    20 ms  be3421.ccr51.beg03.atlas.cogentco.com [130.117.0.94]
  6    32 ms    31 ms    30 ms  be3464.ccr52.vie01.atlas.cogentco.com [154.54.59.189]
  7    39 ms    37 ms    44 ms  be3462.ccr22.muc03.atlas.cogentco.com [154.54.59.182]
  8    42 ms    48 ms    44 ms  be2960.ccr42.fra03.atlas.cogentco.com [154.54.36.253]
  9    44 ms    50 ms    50 ms  be3187.agr41.fra03.atlas.cogentco.com [130.117.1.117]
 10    43 ms    45 ms    46 ms  tata.fra03.atlas.cogentco.com [130.117.15.86]
 11    45 ms    45 ms    44 ms  72.14.196.162
 12    43 ms    41 ms    46 ms  108.170.251.129
 13    46 ms    46 ms    45 ms  74.125.37.167
 14    45 ms    52 ms    48 ms  fra15s29-in-f14.1e100.net [172.217.18.174]

如果您不希望解析名称,可以使用tracert -d


For OSX and Linux and with Python 2.7 you can use this parser.

以上是关于python中的TCP Traceroute的主要内容,如果未能解决你的问题,请参考以下文章

TCP/IP详解 卷1:协议—Traceroute程序

TCP/IP详解 卷1:协议—Traceroute程序

TCP/IP详解 卷1:协议—Traceroute程序

TCP/IP详解卷一08

TCP/IP详解,卷1:协议--第8章 Traceroute程序

TCP/IP协议之ping和traceroute