Como obter o endereço IP local associado ao gateway padrão

2

Pode haver várias interfaces de rede em um servidor, por exemplo, lo, eth0, eth1

Da tabela de rotas, sei que a eth0 está conectada ao gateway padrão. O endereço do gateway padrão, por exemplo, é 192.168.1.1. E o endereço da eth0 é, por exemplo, 192.168.1.100.

Como posso obter o endereço "192.168.1.100"? Qualquer abordagem é ok: Python, Shell, API C do UNIX ...

Atualmente, só consigo pensar em uma maneira:

  1. Execute o comando "route" e obtenha a última linha (padrão 192.168.1.1 0.0.0.0 ...)
  2. Execute o comando "ifconfig" e obtenha a lista de endereços (127.0.0.1, 192.168.1.100, ...)
  3. Encontre o endereço que está na mesma sub-rede com o gateway padrão (192.168.1.1)
  4. Em seguida, obtemos o endereço 192.168.1.100

Existem algumas soluções melhores?

PS: Foi sugerido que podemos chamar o connect () em um soquete do udp, e depois chamar o getsockname () para obter o endereço local. No entanto, funciona apenas em parte dos servidores.

@EEAA

Este é o meu script:

route -n | awk '$1 == "0.0.0.0" { print $2 }' > gateway.tmp
ip -4 addr show | grep inet | awk '{ print $2 }' > addrs.tmp

A primeira linha imprime o gateway padrão:

10.1.40.1

A segunda linha imprime uma lista de endereços de interface (na notação cidr):

127.0.0.1/8
10.1.46.122/21

Então eu tenho que decidir a qual rede 10.1.40.1 pertence. Então eu escrevo um script Python:

import sys

def ip_to_binary(ip):
    bytes = ip.split(".")
    a = int(bytes[0])
    b = int(bytes[1])
    c = int(bytes[2])
    d = int(bytes[3])
    return "{0:08b}{1:08b}{2:08b}{3:08b}".format(a, b, c, d)

def mask_to_binary(bits):
    return "1" * bits + "0" * (32 - bits)

def binary_and(a, b):
    if len(a) == len(b):
        result = ""
        for i in range(0, len(a)):
            if a[i] == "1" and b[i] == "1":
                result += "1"
            else:
                result += "0"
        return result
    return None

def ip_in_net(ip, net_cidr_notation):
    net_addr, bits = net_cidr_notation.split("/")
    bin_mask = mask_to_binary(int(bits))
    bin_net = ip_to_binary(net_addr)
    bin_ip = ip_to_binary(ip)

    if binary_and(bin_ip, bin_mask) == binary_and(bin_net, bin_mask):
        return True
    return False

# usage: python autoaddr.py gateway_file addrs_file
gateway = open(sys.argv[1]).readline().strip()
addrs = open(sys.argv[2]).readlines()

for addr in addrs:
    if ip_in_net(gateway, addr):
        print addr.split("/")[0]

Para evitar dependências extras, não usei bibliotecas como netaddr e ipaddress. Finalmente, eu tenho que adicionar o script Python ao script Shell:

python autoaddr.py gateway.tmp addrs.tmp > auto.tmp
rm -f gateway.tmp
rm -f addrs.tmp

Agora eu tenho um arquivo auto.tmp contendo o endereço gerado automaticamente:

10.1.46.122
    
por F32 30.07.2015 / 04:16

1 resposta

1

Por que não algo assim:

$ ip -4 addr show eth0 | grep inet | awk '{ print $2 }'
192.168.1.100/24

FYI, ifconfig está obsoleto. Você deve começar a usar os vários comandos ip no lugar do que usou ifconfig anteriormente.

    
por 30.07.2015 / 04:25