Python: get default gateway for a local interface/ip address in linux

人盡茶涼 提交于 2019-11-28 09:15:38

For those people who don't want an extra dependency and don't like calling subprocesses, here's how you do it yourself by reading /proc/net/route directly:

import socket, struct

def get_default_gateway_linux():
    """Read the default gateway directly from /proc."""
    with open("/proc/net/route") as fh:
        for line in fh:
            fields = line.strip().split()
            if fields[1] != '00000000' or not int(fields[3], 16) & 2:
                continue

            return socket.inet_ntoa(struct.pack("<L", int(fields[2], 16)))

I don't have a big-endian machine to test on, so I'm not sure whether the endianness is dependent on your processor architecture, but if it is, replace the < in struct.pack('<L', ... with = so the code will use the machine's native endianness.

For completeness (and to expand on alastair's answer), here is an example that uses "netifaces" (tested under Ubuntu 10.04, but this should be portable):

$ sudo easy_install netifaces
Python 2.6.5 (r265:79063, Oct  1 2012, 22:04:36)
...
$ ipython
...
In [8]: import netifaces
In [9]: gws=netifaces.gateways()
In [10]: gws
Out[10]:
{2: [('192.168.0.254', 'eth0', True)],
 'default': {2: ('192.168.0.254', 'eth0')}}
In [11]: gws['default'][netifaces.AF_INET][0]
Out[11]: '192.168.0.254'

Documentation for 'netifaces': https://pypi.python.org/pypi/netifaces/

It seems http://pypi.python.org/pypi/pynetinfo/0.1.9 can do this, but I haven't tested it.

The latest version of netifaces can do this too, but unlike pynetinfo, it will work on systems other than Linux (including Windows, OS X, FreeBSD and Solaris).

def get_ip():
    file=os.popen("ifconfig | grep 'addr:'")
    data=file.read()
    file.close()
    bits=data.strip().split('\n')
    addresses=[]
    for bit in bits:
        if bit.strip().startswith("inet "):
            other_bits=bit.replace(':', ' ').strip().split(' ')
            for obit in other_bits:
                if (obit.count('.')==3):
                    if not obit.startswith("127."):
                        addresses.append(obit)
                    break
    return addresses

You can get it like this (Tested with python 2.7 and Mac OS X Capitain but should work on GNU/Linux too): import subprocess

def system_call(command):
    p = subprocess.Popen([command], stdout=subprocess.PIPE, shell=True)
    return p.stdout.read()


def get_gateway_address():
    return system_call("route -n get default | grep 'gateway' | awk '{print $2}'")

print get_gateway_address()

here my solution to get default gateway for Mac and Linux with python:

import subprocess
import re
import platform

def get_default_gateway_and_interface():
    if platform.system() == "Darwin":
        route_default_result = subprocess.check_output(["route", "get", "default"])
        gateway = re.search(r"\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}", route_default_result).group(0)
        default_interface = re.search(r"(?:interface:.)(.*)", route_default_result).group(1)

    elif platform.system() == "Linux":
        route_default_result = re.findall(r"([\w.][\w.]*'?\w?)", subprocess.check_output(["ip", "route"]))
        gateway = route_default_result[2]
        default_interface = route_default_result[4]

    if route_default_result:
        return(gateway, default_interface)
    else:
        print("(x) Could not read default routes.")

gateway, default_interface = get_default_gateway_and_interface()
print(gateway)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!