getifaddrs, freeifaddrs - Renvoyer les adresses des interfaces
Bibliothèque C standard (
libc,
-lc)
#include <sys/types.h>
#include <ifaddrs.h>
int getifaddrs(struct ifaddrs **ifap);
void freeifaddrs(struct ifaddrs *ifa);
La fonction
getifaddrs() crée une liste chaînée de
structures décrivant les interfaces réseau du système
local et sauvegarde l'adresse du premier élément de la liste
dans
*ifap. La liste est constituée de structures
ifaddrs, comme définie ci-dessous :
struct ifaddrs {
struct ifaddrs *ifa_next; /* Next item in list */
char *ifa_name; /* Name of interface */
unsigned int ifa_flags; /* Flags from SIOCGIFFLAGS */
struct sockaddr *ifa_addr; /* Address of interface */
struct sockaddr *ifa_netmask; /* Netmask of interface */
union {
struct sockaddr *ifu_broadaddr;
/* Broadcast address of interface */
struct sockaddr *ifu_dstaddr;
/* Point-to-point destination address */
} ifa_ifu;
#define ifa_broadaddr ifa_ifu.ifu_broadaddr
#define ifa_dstaddr ifa_ifu.ifu_dstaddr
void *ifa_data; /* Address-specific data */
};
Le champ
ifa_next contient un pointeur vers la prochaine structure de la
liste ou NULL si c'est le dernier de la liste.
ifa_name pointe vers un nom d'interface terminé par un
caractère nul.
Le champ
ifa_flags contient les drapeaux de l'interface, comme
renvoyé par l'opération
ioctl(2) SIOCGUFFLAGS
(consultez
netdevice(7) pour la liste des drapeaux).
Le champ
ifa_addr pointe vers une structure contenant l'adresse de
l'interface (le sous-champ
sa_family devrait être
consulté afin de déterminer le format de la structure
d'adresse). Ce champ peut contenir un pointeur NULL.
Le champ
ifa_netmask pointe vers une structure contenant le masque
réseau associé à
ifa_addr, si cela est valable
pour cette famille d'adresse. Ce champ peut contenir un pointeur NULL.
Selon que le bit
IFF_BROADCAST ou
IFF_POINTOPOINT est
défini dans
ifa_flags (seul l'un des deux bit peut être
défini), soit
ifa_broadaddr contiendra l'adresse de diffusion
associée à
ifa_addr (si cela est applicable avec cette
famille d'adresse), ou soit
ifa_dstaddr contiendra l'adresse de
destination de l'interface point à point.
Le champ
ifa_data pointe vers un tampon contenant les données
spécifique de la famille d'adresse
(« address-family-specific data »). Ce champ peut
être NULL s'il n'y a aucune donnée de ce type pour cette
interface.
La donnée renvoyée par
getifaddrs() est dynamiquement
allouée et devrait être libérée avec
freeifaddrs().
On success,
getifaddrs() returns zero; on error, -1 is returned, and
errno is set to indicate the error.
getifaddrs() peut échouer et définir
errno pour
toutes erreurs spécifiées pour
socket(2),
bind(2),
getsockname(2),
recvmsg(2),
sendto(2),
malloc(3)
ou
realloc(3).
getifaddrs() est apparue dans la glibc 2.3. Les versions
antérieures à la glibc 2.3.3 n'implémentaient que l'IPv4.
La gestion de l'IPv6 a été ajoutée dans la
glibc 2.3.3. La gestion des familles d'adresse autre que IPv4 n'est
disponible que si le noyau gère netlink.
Pour une explication des termes utilisés dans cette section, consulter
attributes(7).
Interface |
Attribut |
Valeur |
getifaddrs(), freeifaddrs() |
Sécurité des threads |
MT-Safe |
Not in POSIX.1. This function first appeared in BSDi and is present on the BSD
systems, but with slightly different semantics documented—returning one
entry per interface, not per address. This means
ifa_addr and other
fields can actually be NULL if the interface has no address, and no link-level
address is returned if the interface has an IP address assigned. Also, the way
of choosing either
ifa_broadaddr or
ifa_dstaddr differs on
various systems.
Les adresses renvoyées sous Linux seront généralement les
adresses IPv4 et IPv6 de l'interface, et une adresse
AF_PACKET
contenant des détails bas niveau de l'interface et de sa couche
physique. Dans ce cas, le champ
ifa_data peut contenir un pointeur vers
une structure
struct rtnl_link_stats, définie dans
<linux/if_link.h> (pour les versions Linux 2.4 et
antérieures,
net_device_stats, définie dans
<linux/netdevice.h>), qui contient différents attributs et
statistiques sur les interfaces.
Le programme suivant décrit l'utilisation de
getifaddrs(),
freeifaddrs() et
getnameinfo(3). Ci-dessous, la sortie du
programme sur un système :
$ ./a.out
lo AF_PACKET (17)
tx_packets = 524; rx_packets = 524
tx_bytes = 38788; rx_bytes = 38788
wlp3s0 AF_PACKET (17)
tx_packets = 108391; rx_packets = 130245
tx_bytes = 30420659; rx_bytes = 94230014
em1 AF_PACKET (17)
tx_packets = 0; rx_packets = 0
tx_bytes = 0; rx_bytes = 0
lo AF_INET (2)
address: <127.0.0.1>
wlp3s0 AF_INET (2)
address: <192.168.235.137>
lo AF_INET6 (10)
address: <::1>
wlp3s0 AF_INET6 (10)
address: <fe80::7ee9:d3ff:fef5:1a91%wlp3s0>
#define _GNU_SOURCE /* Afin d'avoir accès aux définitions de NI_MAXSERV et de NI_MAXHOST */
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/if_link.h>
int main(int argc, char *argv[])
{
struct ifaddrs *ifaddr;
int family, s;
char host[NI_MAXHOST];
if (getifaddrs(&ifaddr) == -1) {
perror("getifaddrs");
exit(EXIT_FAILURE);
}
/* Walk through linked list, maintaining head pointer so we
can free list later. */
for (struct ifaddrs *ifa = ifaddr; ifa != NULL;
ifa = ifa->ifa_next) {
if (ifa->ifa_addr == NULL)
continue;
family = ifa->ifa_addr->sa_family;
/* Display interface name and family (including symbolic
form of the latter for the common families). */
printf("%-8s %s (%d)\n",
ifa->ifa_name,
(family == AF_PACKET) ? "AF_PACKET" :
(family == AF_INET) ? "AF_INET" :
(family == AF_INET6) ? "AF_INET6" : "???",
family);
/* For an AF_INET* interface address, display the address. */
if (family == AF_INET || family == AF_INET6) {
s = getnameinfo(ifa->ifa_addr,
(family == AF_INET) ? sizeof(struct sockaddr_in) :
sizeof(struct sockaddr_in6),
host, NI_MAXHOST,
NULL, 0, NI_NUMERICHOST);
if (s != 0) {
printf("getnameinfo() failed: %s\n", gai_strerror(s));
exit(EXIT_FAILURE);
}
printf("\t\taddress: <%s>\n", host);
} else if (family == AF_PACKET && ifa->ifa_data != NULL) {
struct rtnl_link_stats *stats = ifa->ifa_data;
printf("\t\ttx_packets = %10u; rx_packets = %10u\n"
"\t\ttx_bytes = %10u; rx_bytes = %10u\n",
stats->tx_packets, stats->rx_packets,
stats->tx_bytes, stats->rx_bytes);
}
}
freeifaddrs(ifaddr);
exit(EXIT_SUCCESS);
}
bind(2),
getsockname(2),
socket(2),
packet(7),
ifconfig(8)
La traduction française de cette page de manuel a été
créée par Christophe Blaess
<
https://www.blaess.fr/christophe/>, Stéphan Rafin
<
[email protected]>, Thierry Vignaud
<
[email protected]>, François Micaux, Alain Portal
<
[email protected]>, Jean-Philippe Guérard
<
[email protected]>, Jean-Luc Coulon (f5ibh)
<
[email protected]>, Julien Cristau
<
[email protected]>, Thomas Huriaux <
[email protected]>,
Nicolas François <
[email protected]>, Florentin
Duneau <
[email protected]>, Simon Paillard
<
[email protected]>, Denis Barbier
<
[email protected]>, David Prévot <
[email protected]>,
Cédric Boutillier <
[email protected]> et
Frédéric Hantrais <
[email protected]>
Cette traduction est une documentation libre ; veuillez vous reporter
à la
GNU
General Public License version 3 concernant les conditions de copie
et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.
Si vous découvrez un bogue dans la traduction de cette page de manuel,
veuillez envoyer un message à
[email protected]