getifaddrs(3)

NUME
getifaddrs, freeifaddrs - obține adrese de interfațe

BIBLIOTECA
Biblioteca C standard (libc, -lc)

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

int getifaddrs(struct ifaddrs **ifap);
void freeifaddrs(struct ifaddrs *ifa);

DESCRIERE
Funcția getifaddrs() creează o listă legată de structuri care descriu interfețele de rețea ale sistemului local și stochează adresa primului element al listei în *ifap. Lista este formată din structuri ifaddrs, definite după cum urmează:

    struct ifaddrs {
        struct ifaddrs  *ifa_next;    /* Următorul element din listă */
        char            *ifa_name;    /* Numele interfeței */
        unsigned int     ifa_flags;   /* Fanioane de la SIOCGIFFLAGS */
        struct sockaddr *ifa_addr;    /* Adresa interfeței */
        struct sockaddr *ifa_netmask; /* Masca de rețea a interfeței */
        union {
            struct sockaddr *ifu_broadaddr;
                             /* Adresa de difuzare a interfeței */
            struct sockaddr *ifu_dstaddr;
                             /* Adresa de destinație punct-la-punct */
        } ifa_ifu;
    #define              ifa_broadaddr ifa_ifu.ifu_broadaddr
    #define              ifa_dstaddr   ifa_ifu.ifu_dstaddr
        void            *ifa_data;    /* Date specifice adresei */
    };

Câmpul ifa_next conține un indicator către următoarea structură din listă sau NULL dacă acesta este ultimul element din listă.

ifa_name indică numele interfeței terminat prin nul.

Câmpul ifa_flags conține fanioanele interfeței, astfel cum sunt returnate de operația SIOCGIFFLAGS ioctl(2) (a se vedea netdevice(7) pentru o listă a acestor fanioane).

Câmpul ifa_addr trimite la o structură care conține adresa interfeței; (subcâmpul sa_family trebuie consultat pentru a determina formatul structurii de adrese). Acest câmp poate conține un indicator nul.

Câmpul ifa_netmask indică către o structură care conține masca de rețea asociată cu ifa_addr, dacă este cazul pentru familia de adrese. Acest câmp poate conține un indicator nul.

În funcție de starea (activat/dezactivat) a bitului IFF_BROADCAST sau IFF_POINTOPOINT în ifa_flags (numai unul poate fi activat la un moment dat), ifa_broadaddr va conține adresa de difuzare asociată cu ifa_addr (dacă este aplicabilă pentru familia de adrese) sau ifa_dstaddr va conține adresa de destinație a interfeței punct-la-punct.

Câmpul ifa_data indică o memorie tampon care conține date specifice familiei de adrese; acest câmp poate fi NULL dacă nu există astfel de date pentru această interfață.

Datele returnate de getifaddrs() sunt alocate dinamic și ar trebui eliberate utilizând freeifaddrs() atunci când nu mai sunt necesare.

VALOAREA RETURNATĂ
În caz de succes, getifaddrs() returnează zero; în caz de eroare, este returnat -1, iar errno este configurată pentru a indica eroarea.

ERORI-IEȘIRE
getifaddrs() poate eșua și configura errno pentru oricare dintre erorile specificate pentru socket(2), bind(2), getsockname(2), recvmsg(2), sendto(2), malloc(3) sau realloc(3).

ATRIBUTE
Pentru o explicație a termenilor folosiți în această secțiune, a se vedea attributes(7).
Interfață | Atribut | Valoare
getifaddrs(), freeifaddrs() | Siguranța firelor | MT-Safe

STANDARDE
Niciunul.

ISTORIC
Această funcție a apărut pentru prima dată în BSDi și este prezentă pe sistemele BSD, dar cu o semantică ușor diferită, documentată-returnând o intrare pe interfață, nu pe adresă. Aceasta înseamnă că ifa_addr și alte câmpuri pot fi de fapt NULL dacă interfața nu are adresă și nu este returnată nicio adresă la nivel de legătură(conexiune) dacă interfața are o adresă IP atribuită. De asemenea, modul de alegere a ifa_broadaddr sau ifa_dstaddr diferă de la un sistem la altul.

getifaddrs() a apărut pentru prima dată în glibc 2.3, dar înainte de glibc 2.3.3, implementarea accepta numai adrese IPv4; suportul pentru IPv6 a fost adăugat în glibc 2.3.3. Suportul pentru alte familii de adrese decât IPv4 este disponibil numai pe nucleele care acceptă netlink.

NOTE
Adresele returnate pe Linux vor fi de obicei adresele IPv4 și IPv6 atribuite interfeței, dar și o adresă AF_PACKET pentru fiecare interfață care conține detalii de nivel inferior despre interfață și stratul său fizic. În acest caz, câmpul ifa_data poate conține un indicator către o structură struct rtnl_link_stats, definită în <linux/if_link.h> (în Linux 2.4 și anterior, struct net_device_stats, definită în <linux/netdevice.h>), care conține diverse atribute și statistici ale interfeței.

EXEMPLE
Programul de mai jos demonstrează utilizarea getifaddrs(), freeifaddrs() și getnameinfo(3). Iată ce vedem la rularea acestui program pe un sistem:

    $ ./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>

  Sursa programului
    #define _GNU_SOURCE     /* Pentru a obține definițiile NI_MAXSERV și 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);
        }

        /* Parcurgem lista legată, menținând indicatorul capului,
           astfel încât să putem elibera lista mai târziu. */

        for (struct ifaddrs *ifa = ifaddr; ifa != NULL;
                 ifa = ifa->ifa_next) {
            if (ifa->ifa_addr == NULL)
                continue;

            family = ifa->ifa_addr->sa_family;

            /* Afișează numele și familia interfeței (inclusiv forma
               simbolică a acesteia din urmă pentru familiile comune). */

            printf("%-8s %s (%d)\n",
                   ifa->ifa_name,
                   (family == AF_PACKET) ? "AF_PACKET" :
                   (family == AF_INET) ? "AF_INET" :
                   (family == AF_INET6) ? "AF_INET6" : "???",
                   family);

            /* Pentru o adresă de interfață AF_INET*, afișează adresa. */

            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() a eșuat: %s\n", gai_strerror(s));
                    exit(EXIT_FAILURE);
                }

                printf("\t\tadresa: <%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);
    }

CONSULTAȚI ȘI
bind(2), getsockname(2), socket(2), packet(7), ifconfig(8)

TRADUCERE
Traducerea în limba română a acestui manual a fost făcută de Remus-Gabriel Chelu <remusgabriel.chelu@disroot.org>

Această traducere este documentație gratuită; citiți Licența publică generală GNU Versiunea 3 (https://www.gnu.org/licenses/gpl-3.0.html) sau o versiune ulterioară cu privire la condiții privind drepturile de autor. NU se asumă NICIO RESPONSABILITATE.

Dacă găsiți erori în traducerea acestui manual, vă rugăm să trimiteți un e-mail la translation-team-ro@lists.sourceforge.net.