python 中的 TCP 跟踪路由
TCP Traceroute in python
我正在编写 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
我想为 ipv6
和 ipv4
[= 执行 tcp
traceroute 107=]
再看Scapy
源码,traceroot6
可以做到:
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)))
我不确定为什么所有跃点都显示相同的 IP 地址。
使用 DNS traceroute
通过在 traceroute() 函数的 l4 参数中指定一个完整的数据包你不为所有跃点获取相同的 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
以使用 Scapy
实现 traceroute
,如下所示:
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)
如果Scapy
不合适,还有其他库可以使用吗?
- 查看 webb。我没用过,不过你可以这样用:
import webb
webb.traceroute("www.google.com")
webb.traceroute("www.google.com",'file-name.txt')
此外,check out this tcptraceroute
Thomas Guettler。
或 Addy Yeow (Ayeowch) 的 Multi-source traceroute with geolocation 实现。
除其他外,使用 -j
参数 (JSON_FILE),它将以 JSON 文件格式列出来源。
或 Christian Kreibich 的 this implementation。它可以将 traceroute 信息解析为一系列跃点对象,每个跃点对象由一个或多个探测结果组成,同样,对象实例。此外,字符串格式化会产生熟悉的 traceroute 输出。
(为了与 Python 3
一起工作,需要将 cStringIO
更改为 from io import StringIO
没有scapy
(使用windows控制台):
Create a script named output.py
containing the following:
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]
Example usage: python output.py ping google.com
Example output for 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
Example usage: python output.py tracert google.com
Example output for 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
。
对于 OSX
和 Linux
以及 Python 2.7
你可以使用这个 parser.
我正在编写 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
我想为
ipv6
和 ipv4
[= 执行
tcp
traceroute 107=]
再看Scapy
源码,traceroot6
可以做到:
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)))
我不确定为什么所有跃点都显示相同的 IP 地址。
使用 DNS traceroute
通过在 traceroute() 函数的 l4 参数中指定一个完整的数据包你不为所有跃点获取相同的 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
以使用 Scapy
实现 traceroute
,如下所示:
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)
如果
Scapy
不合适,还有其他库可以使用吗?- 查看 webb。我没用过,不过你可以这样用:
import webb webb.traceroute("www.google.com") webb.traceroute("www.google.com",'file-name.txt')
此外,check out this
tcptraceroute
Thomas Guettler。或 Addy Yeow (Ayeowch) 的 Multi-source traceroute with geolocation 实现。
除其他外,使用-j
参数 (JSON_FILE),它将以 JSON 文件格式列出来源。或 Christian Kreibich 的 this implementation。它可以将 traceroute 信息解析为一系列跃点对象,每个跃点对象由一个或多个探测结果组成,同样,对象实例。此外,字符串格式化会产生熟悉的 traceroute 输出。
(为了与Python 3
一起工作,需要将cStringIO
更改为from io import StringIO
没有scapy
(使用windows控制台):
Create a script named
output.py
containing the following:
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]
Example usage: python output.py ping google.com
Example output for
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
Example usage: python output.py tracert google.com
Example output for
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
。
对于
OSX
和 Linux
以及 Python 2.7
你可以使用这个 parser.