Python Linux 路由表查询
我在StackOverflow上发了一个关于如何找到第一个网络跳点的问题。越想越觉得用Python处理路由表其实挺简单的。不过我不是程序员,对这些也不是很懂。:p
这是我想到的,首先我发现一个问题,就是回环接口在/proc/net/route文件中是看不见的,所以如果你评估127.0.0.0/8的话,会得到默认路由……对我这个应用来说,这个问题不大。
还有什么我可能忽略的重要问题吗?解析ip route get <ip>
这个命令是不是更好一些?
import re
import struct
import socket
'''
Read all the routes into a list. Most specific first.
# eth0 000219AC 04001EAC 0003 0 0 0 00FFFFFF ...
'''
def _RtTable():
_rt = []
rt_m = re.compile('^[a-z0-9]*\W([0-9A-F]{8})\W([0-9A-F]{8})[\W0-9]*([0-9A-F]{8})')
rt = open('/proc/net/route', 'r')
for line in rt.read().split('\n'):
if rt_m.match(line):
_rt.append(rt_m.findall(line)[0])
rt.close()
return _rt
'''
Create a temp ip (tip) that is the entered ip with the host
section striped off. Matching to routers in order,
the first match should be the most specific.
If we get 0.0.0.0 as the next hop, the network is likely(?)
directly attached- the entered IP is the next (only) hop
'''
def FindGw(ip):
int_ip = struct.unpack("I", socket.inet_aton(ip))[0]
for entry in _RtTable():
tip = int_ip & int(entry[2], 16)
if tip == int(entry[0], 16):
gw_s = socket.inet_ntoa(struct.pack("I", int(entry[1], 16)))
if gw_s == '0.0.0.0':
return ip
else:
return gw_s
if __name__ == '__main__':
import sys
print FindGw(sys.argv[1])
2 个回答
7
使用 pyroute2 的 IPRoute,可以获取到通往某个远程主机的下一跳,这里以 8.8.8.8 为例:
from pyroute2 import IPRoute
with IPRoute() as ipr:
print(ipr.route('get', dst='8.8.8.8'))
7
在proc文件系统的手册中提到:
/proc/net
various net pseudo-files, all of which give the status of some part of
the networking layer. These files contain ASCII structures and are,
there‐fore, readable with cat(1).
However, the standard netstat(8) suite provides much
cleaner access to these files.
只需要依靠那些专门为此设计的工具。可以使用netstat、traceroute或者其他任何标准工具。通过子进程模块将这些命令整洁地封装起来,这样就能获取你想要的信息。