2011-02-10 93 views
3

我發佈了Python find first network hop關於試圖找到第一跳,我對它的想法越多,越容易看起來像它是一個進程的Python路由表。我不是程序員,我不知道我在做什麼。 :pPython的Linux路由表查找

這就是我想到的,我注意到的第一個問題是loopback接口沒有顯示在/ 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]) 
+0

看起來像一個有趣的練習(和我有偏見,當然),但我仍然建議使用`ip route get`代替。好處:有人已經爲您完成了所有的調試工作。 =)例如,他們知道如何處理路線類型之間的差異,包括您已經使用本地路線發現的拐角案例。 (想想其他類型:單播,本地,廣播,黑洞等)另外,當你開始支持IPv6時,`ip`將繼續爲你工作! – mpontillo 2011-02-10 08:38:39

回答

5

在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或任何其他標準工具。將這些命令打包成乾淨地使用子進程模塊,並獲得您正在尋找的信息。

2

隨着pyroute2 .IPRoute,讓在路上的下一跳一些遙遠的主機,在這裏 - 8.8.8.8:

from pyroute2 import IPRoute 

with IPRoute() as ipr: 
    print(ipr.route('get', dst='8.8.8.8'))