Il peut y avoir plusieurs interfaces réseau sur un serveur, par exemple, lo, eth0, eth1
À partir de la table de routage, je sais que eth0 est connecté à la passerelle par défaut. L'adresse de la passerelle par défaut, par exemple, est 192.168.1.1. Et l'adresse de eth0 est, par exemple, 192.168.1.100.
Comment puis-je obtenir l'adresse "192.168.1.100"? Toute approche est ok : Python, Shell, UNIX C API...
Actuellement, je ne peux penser qu'à une seule façon:
- Exécuter la commande "route" et obtenir la dernière ligne (par défaut 192.168.1.1 0.0.0.0 ...)
- Exécuter la commande "ifconfig" et obtenir la liste des adresses (127.0.0.1, 192.168.1.100, ...)
- Trouver l'adresse qui est dans le même sous-réseau que la passerelle par défaut (192.168.1.1)
- Ensuite, nous obtenons l'adresse 192.168.1.100
Y a-t-il de meilleures solutions?
PS: Il a été suggéré que nous pouvons appeler connect() sur un socket udp, puis appeler getsockname() pour obtenir l'adresse locale. Cependant, cela fonctionne uniquement sur une partie des serveurs.
@EEAA
Voici mon script :
route -n | awk '$1 == "0.0.0.0" { print $2 }' > gateway.tmp
ip -4 addr show | grep inet | awk '{ print $2 }' > addrs.tmp
La première ligne imprime la passerelle par défaut :
10.1.40.1
La deuxième ligne imprime une liste d'adresses d'interface (en notation cidr) :
127.0.0.1/8
10.1.46.122/21
Ensuite, je dois décider à quel réseau appartient 10.1.40.1. J'écris donc un 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]
Pour éviter des dépendances supplémentaires, je n'ai pas utilisé de bibliothèques comme netaddr et ipaddress. Enfin, je dois ajouter le script Python au script Shell :
python autoaddr.py gateway.tmp addrs.tmp > auto.tmp
rm -f gateway.tmp
rm -f addrs.tmp
Maintenant, j'ai un fichier auto.tmp contenant l'adresse générée automatiquement :
10.1.46.122