2011-02-10 8 views
3

私はPython find first network hopの最初のホップを見つけようとしていましたが、私はそれについて考えていたほど、Pythonのルーティングテーブルのプロセスになるように思えました。私はプログラマーではない、私は何をしているのか分からない。 :pPython Linuxのルートテーブルの参照

これは私が思いついた最初の問題ですが、ループバックインターフェイスは/ 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

答えて

5

procファイルシステムのmanページには、それが与えられています。

/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または他の標準ツールを使用してください。これらのコマンドをサブプロセスモジュールを使用してをきれいに囲んでを探し、探している情報を取得します。 pyroute2 .IPRouteで

2

、ここではいくつかの遠くのホストへの途中で次のホップを取得 - 8.8.8.8:

from pyroute2 import IPRoute 

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