python中跟踪路由的实现
我一直在尝试为python编写一个简单的跟踪路由实现;请在下面查找代码python中跟踪路由的实现,python,python-3.x,sockets,networking,Python,Python 3.x,Sockets,Networking,我一直在尝试为python编写一个简单的跟踪路由实现;请在下面查找代码 import socket def main (HostName): dest_addr = socket.gethostbyname(HostName) TTL = 1 #Define the time to live as 1. Will be incremented by one after each UDP message has been sent Max = 30 while
import socket
def main (HostName):
dest_addr = socket.gethostbyname(HostName)
TTL = 1 #Define the time to live as 1. Will be incremented by one after each UDP message has been sent
Max = 30
while True:
ICMP_socket = socket.socket(socket.AF_INET,socket.SOCK_RAW, socket.IPPROTO_ICMP) #Create socket that can receive ICMP
UDP = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) #Create socket that will send UDP messages
UDP.setsockopt(0,4,TTL)
ICMP_socket.bind(("",33434)) #33434 is the default port used for traceroute
message = "Hi" #The message we send is an empty string
UDP.sendto(message.encode(),(dest_addr, 33434))
Receiver = (0,"")
Router_addr = None
try:
Receiver = ICMP_socket.recvfrom(1024)
Router_addr = Receiver[1]
if Router_addr == None:
print("*")
else:
print(Router_addr)
except:
pass
finally:
ICMP_socket.close()
UDP.close()
TTL = TTL + 1
if Router_addr == dest_addr or TTL == Max:
break
if __name__ =="__main__":
main('google.com')
我用sudo在macOS终端上运行它,因为它需要root权限。然而,我得到的输出似乎是错误的。第一个IP是我的本地IP,第二个是我不知道的IP,其余的都是谷歌的IP。它不输出中间IP,只有在达到TTL限制30时才断开
这是输出(我删除了第一个Ip,即本地Ip地址):
有人能帮忙吗?我似乎找不到问题所在
谢谢大家! 为什么程序不停止 程序在“到达”目的地时不会停止,因为您忽略了
地址
,您称之为路由器地址
,因为AF\u INET
是一个元组
(请参阅中的“套接字系列”)。您在问题中包含的输出也可以看出这一点(这是打印(Router\u addr)
的结果)
如果您将路由器地址==dest\u addr或TTL==Max:更新为如下所示,您的程序将停止
如果路由器地址[0]==dest\u addr或TTL==Max:
输出显示了什么
我不知道你的网络拓扑结构,也不知道你是如何进入互联网的,尤其是谷歌。根据您在输出中描述和看到的内容
是供应商路由器内部接口(很可能)的专用IP地址;回想一下,响应是从离您“更近”的接口发送到您的计算机的,而不是从离Internet“更近”的接口发送到您的计算机的(我假设,正如您所提到的,您不认为此IP地址属于您的[例如,家庭、大学]路由器/网络)172.30.224.110
- 谷歌IP地址(172.217.19.46)和上面的路由器之间可能没有多跳;例如,如果谷歌的服务器位于您的提供商的网络上(对于大型内容提供商和CDN来说,实现对大型眼球提供商终端用户的高性能是一种非常常见的做法),则可能出现这种情况;在我的机器上,我看到运行你的程序的多个google跳转(也许你想检查另一个目的地)
- 最不清楚的一点是,为什么在第一行看到机器的IP地址;这可能是因为您将Mac用作路由器(可能用于Internet共享)或处于涉及转发的“奇怪”配置中(因此第一个路由器就是您的机器);我在此假设,当您谈论您的本地IP地址时,您不是指环回IP地址(否则请阅读下文)
如果路由器地址==无:
打印(“*”)
当网络节点没有响应时,socket.recvfrom()返回('127.0.0.1',0)
,它不是None
。这是因为对于UDP
而言,当目标端口上没有任何内容侦听时,localhost
会生成一个ICMP目标不可访问
(类型3)端口不可访问
(代码3)。顺便说一下,这就是为什么ICMP\u socket.recvfrom(1024)
不会被阻止的原因
您的更正程序经过轻微修改以打印TTL
s和ICMP
类型和代码,给出了(请参见,TTL:[6]
):
$sudo python3 trorig.py
('192.168.178.1',0)TTL:[1]类型:[11]代码:[0]
('62.245.142.131',0)TTL:[2]类型:[11]代码:[0]
('62.245.142.130',0)TTL:[3]类型:[11]代码:[0]
('82.135.16.226',0)TTL:[4]类型:[11]代码:[0]
('142.250.161.214',0)TTL:[5]类型:[11]代码:[0]
('127.0.0.1',0)TTL:[6]类型:[3]代码:[3]
('172.253.75.128',0)TTL:[7]类型:[11]代码:[0]
('172.253.75.143',0)TTL:[8]类型:[11]代码:[0]
('74.125.244.81',0)TTL:[9]类型:[11]代码:[0]
('172.253.75.141',0)TTL:[10]类型:[11]代码:[0]
('172.217.23.78',0)TTL:[11]类型:[3]代码:[3]
相应的tcpdump输出为(请注意,无响应的网络主机没有行,142.250.161.214后跟172.253.75.128,):
相应的traceroute输出是(与上述路径相比,路径存在一些差异,因为没有同时运行它,但要点仍然是,TTL:[6]处的网络主机没有响应):
因此,您在中检查无响应网络主机的方式是不正确的。您可能希望将其更新为以下内容:
if Router_addr == ('127.0.0.1', 0) :
print("*")
您可能需要考虑的最后两点:
- 如上所述,并非每个主机(或网络)都会向您发回响应,并且响应可能会丢失或丢失。在放弃并声明网络主机没有响应之前,您可能希望在
中包含您愿意等待多长时间的超时。您可以查看socket.SO\u RCVTIMEOICMP\u socket.recvfrom(1024)
- 如上所述,在一个给定的
上,可能有多个网络主机从您的机器向目标移动。您可能需要考虑发送多个包来发现它们(如果它们是可发现的)。TTL
导入套接字
导入结构
def主(主机名):
dest_addr=socket.gethostbyname(主机名)
TTL=1
最大值=30
尽管如此:
ICMP_socket=socket.socket(socket.AF_INET,socket.SOCK_RAW,socket.IPPROTO_ICMP)
$ sudo tcpdump -i en0 -nnn icmp
Password:
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on en0, link-type EN10MB (Ethernet), capture size 262144 bytes
14:30:45.720700 IP 192.168.178.1 > 192.168.178.20: ICMP time exceeded in-transit, length 38
14:30:45.740808 IP 62.245.142.131 > 192.168.178.20: ICMP time exceeded in-transit, length 38
14:30:45.761857 IP 62.245.142.130 > 192.168.178.20: ICMP time exceeded in-transit, length 36
14:30:45.782603 IP 82.135.16.226 > 192.168.178.20: ICMP time exceeded in-transit, length 36
14:30:45.803874 IP 142.250.161.214 > 192.168.178.20: ICMP time exceeded in-transit, length 38
14:30:53.454002 IP 172.253.75.128 > 192.168.178.20: ICMP time exceeded in-transit, length 76
14:30:53.476512 IP 172.253.75.143 > 192.168.178.20: ICMP time exceeded in-transit, length 38
14:30:53.496455 IP 74.125.244.81 > 192.168.178.20: ICMP time exceeded in-transit, length 38
14:30:53.519329 IP 172.253.75.141 > 192.168.178.20: ICMP time exceeded in-transit, length 38
14:30:53.541726 IP 172.217.23.78 > 192.168.178.20: ICMP 172.217.23.78 udp port 33434 unreachable, length 36
$ traceroute -n google.com
traceroute to google.com (172.217.23.78), 64 hops max, 52 byte packets
1 192.168.178.1 8.694 ms 2.893 ms 3.095 ms
2 62.245.142.131 17.545 ms 17.361 ms 19.010 ms
3 62.245.142.130 25.948 ms 20.302 ms 26.077 ms
4 82.135.16.226 20.418 ms 19.967 ms 21.411 ms
5 142.250.161.214 29.145 ms 25.573 ms 19.979 ms
6 * * *
7 108.170.247.113 26.875 ms
172.253.75.146 21.736 ms
108.170.247.113 21.987 ms
8 172.253.75.143 22.435 ms
172.253.75.141 20.617 ms
108.170.247.120 21.670 ms
9 172.217.23.78 19.538 ms
74.125.244.97 18.503 ms
74.125.244.81 18.907 ms
if Router_addr == ('127.0.0.1', 0) :
print("*")