Je dois collecter tous les noms d'interface, même ceux qui ne sont pas actifs pour le moment. Comme ifconfig -a
.
getifaddrs()
parcourt plusieurs fois le même nom d'interface. Comment collecter tous les noms d'interface une seule fois avec getifaddrs()
?
Vous pouvez vérifier quelles entrées de getifaddrs appartiennent à la famille AF_PACKET. Sur mon système qui semble lister toutes les interfaces:
struct ifaddrs *addrs,*tmp;
getifaddrs(&addrs);
tmp = addrs;
while (tmp)
{
if (tmp->ifa_addr && tmp->ifa_addr->sa_family == AF_PACKET)
printf("%s\n", tmp->ifa_name);
tmp = tmp->ifa_next;
}
freeifaddrs(addrs);
getifaddrs () ne renverra que les adresses de vos interfaces, pas les interfaces elles-mêmes.
Que se passe-t-il si l'une de vos interfaces n'a pas d'adresse ou pas l'adresse de la famille demandée, comme suggéré avec celle 'AF_PACKET'?
Voici un exemple où j’ai une interface de tunnel (avec une connexion OpenVPN) et où je liste toutes les entrées de getifaddrs () pour chacune de mes interfaces réseau:
[0] 1: lo address family: 17 (AF_PACKET) b4:11:00:00:00:01
address family: 2 (AF_INET) address: <127.0.0.1>
address family: 10 (AF_INET6) address: <::1>
[...]
[5] 10: tun0 address family: 2 (AF_INET) address: <172.16.0.14>
[EOF]
Bam. Pas AF_PACKET sur l'interface "tun0", mais il existe sur le système.
Vous devriez plutôt utiliser if_nameindex () syscall, qui fait exactement ce que vous voulez. En d'autres termes, sans argument, il retourne une liste de toutes les interfaces de votre système:
#include <net/if.h>
void main (void)
{
struct if_nameindex *if_nidxs, *intf;
if_nidxs = if_nameindex();
if ( if_nidxs != NULL )
{
for (intf = if_nidxs; intf->if_index != 0 || intf->if_name != NULL; intf++)
{
printf("%s\n", intf->if_name);
}
}
return ;
}
Et voilà.
Il semble que ifconfig -a
ne répertorie que les interfaces actives (du moins sur Fedora 19). Je sais que j'ai au moins une autre carte réseau que je ne vois pas. En tout cas, je reçois la même liste que:
ls -1 /sys/class/net
Ce qui pourrait facilement être fait par programme.
Vous êtes sur la bonne voie (c'est getifaddrs). Il retourne chaque interface une fois par famille, vous obtenez donc eth0 pour ipv4 et un pour ipv6. Si vous voulez juste chaque interface une fois, vous devrez uniq la sortie vous-même.
Je pense que ça montre que vous êtes tous en interface, au moins pour moi
show lien ip
ls -1 /sys/class/net
afficher uniquement le nom de l'interface
lo
p4p1
J'ai besoin du périphérique principal utilisé par le système (en supposant qu'il n'en existe qu'un), tel que eth0 wlan0 ou tout ce que RHEL7 essaie de faire ...
Le meilleur que j'ai piraté était le suivant:
#!/bin/bash
# -- Get me the interface for the main ip on system
for each in $(ls -1 /sys/class/net) ;do
result=$(ip addr show $each | awk '$1 == "inet" {gsub(/\/.*$/, "", $2); print $2}' | grep "$(hostname -I | cut -d' ' -f1)")
if [ ! -z "${result// }" ] && [ -d /sys/class/net/${each// } ] ;then
echo "Device: $each IP: $result"
break;
fi
done
Exemple de sortie:
./maineth.sh
Device: enp0s25 IP: 192.168.1.6