freeifaddrs(3) Renvoyer les adresses des interfaces

Other Alias

getifaddrs

SYNOPSIS

#include <sys/types.h>
#include <ifaddrs.h>


int getifaddrs(struct ifaddrs **ifap);

void freeifaddrs(struct ifaddrs *ifa);

DESCRIPTION

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().

VALEUR RENVOYÉE

En cas de réussite, getifaddrs() renvoie 0, en cas d'erreur, elle renvoie -1 et errno est rempli avec le code d'erreur.

ERREURS

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).

VERSIONS

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.

CONFORMITÉ

Pas dans POSIX.1-2001. Cette fonction est apparue en premier dans BSDi et elle est présente sur les systèmes BSD avec de légères différences sémantiques documentées ; elle renvoie une entrée par interface et non pas par adresse. Cela signifie que ifa_addr et d'autres champs peuvent être NULL si l'interface n'a pas d'adresse, et aucune adresse « link-level » (synonyme d'adresse MAC) n'est renvoyée si l'interface possède une adresse IP. De plus, la façon de choisir soit ifa_broadaddr ou soit ifa_dstaddr varie sur beaucoup de systèmes.

NOTES

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.

EXEMPLE

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>

Source du programme

#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, *ifa;
    int family, s, n;
    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 (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) {
        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);
}

COLOPHON

Cette page fait partie de la publication 3.65 du projet man-pages Linux. Une description du projet et des instructions pour signaler des anomalies peuvent être trouvées à l'adresse http://www.kernel.org/doc/man-pages/.

TRADUCTION

Depuis 2010, cette traduction est maintenue à l'aide de l'outil po4a <http://po4a.alioth.debian.org/> par l'équipe de traduction francophone au sein du projet perkamon <http://perkamon.alioth.debian.org/>.

Florentin Duneau et l'équipe francophone de traduction de Debian (2006-2009).

Veuillez signaler toute erreur de traduction en écrivant à <[email protected]> ou par un rapport de bogue sur le paquet manpages-fr.

Vous pouvez toujours avoir accès à la version anglaise de ce document en utilisant la commande « man -L C <section> <page_de_man> ».