Provided by: manpages-ru-dev_4.18.1-1_all bug

ИМЯ

       getifaddrs, freeifaddrs - возвращают адреса интерфейса

LIBRARY

       Standard C library (libc, -lc)

СИНТАКСИС

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

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

ОПИСАНИЕ

       Функция  getifaddrs()  создаёт  связный  список  структур,  описывающих сетевые интерфейсы
       локальной системы, и сохраняет адрес первого элемента списка в *ifap.  Список  состоит  из
       структур ifaddrs:

           struct ifaddrs {
               struct ifaddrs  *ifa_next;    /* след. элемент в списке */
               char            *ifa_name;    /* имя интерфейса */
               unsigned int     ifa_flags;   /* флаги из SIOCGIFFLAGS */
               struct sockaddr *ifa_addr;    /* адрес интерфейса */
               struct sockaddr *ifa_netmask; /* сетевая маска интерфейса */
               union {
                   struct sockaddr *ifu_broadaddr;
                                    /* широковещательный адрес интерфейса */
                   struct sockaddr *ifu_dstaddr;
                                    /* адрес назначения точка-точка */
               } ifa_ifu;
           #define              ifa_broadaddr ifa_ifu.ifu_broadaddr
           #define              ifa_dstaddr   ifa_ifu.ifu_dstaddr
               void            *ifa_data;    /* спец. данные для адреса */
           };

       В  поле  ifa_next  содержится указатель на следующую структуру в списке или NULL, если это
       последний элемент в списке.

       Поле ifa_name указывает на имя интерфейса (заканчивающееся null).

       В поле ifa_flags содержатся флаги интерфейса, полученные операцией  SIOCGIFFLAGS  ioctl(2)
       (список флагов приведён в netdevice(7)).

       Поле ifa_addr указывает на структуру, содержащую адрес интерфейса (для определения формата
       структуры адреса обратитесь к подполю sa_family). Это поле может содержать указатель null.

       Поле ifa_netmask указывает на структуру, содержащую маску  сети  для  ifa_addr  (если  она
       используется в адресном семействе). Это поле может содержать указатель null.

       В  зависимости  от наличия флага IFF_BROADCAST или IFF_POINTOPOINT в ifa_flags (может быть
       установлен какой-то один),  в  ifa_broadaddr  будет  содержаться  широковещательный  адрес
       ifa_addr (если он используется в адресном семействе) или ifa_dstaddr будет содержать адрес
       назначения интерфейса типа точка-точка.

       Поле ifa_data указывает на буфер, содержащий данные,  присущие  адресному  семейству;  это
       поле может быть равно NULL, если данных для этого интерфейса нет.

       Память  под  структуру  данных, возвращаемая getifaddrs(), выделяется динамически и должна
       освобождаться с помощью freeifaddrs(), когда больше не нужна.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

       On success, getifaddrs()  returns zero; on error, -1 is returned,  and  errno  is  set  to
       indicate the error.

ОШИБКИ

       Функция  getifaddrs()  может завершиться с ошибками и назначить переменной errno значения,
       перечисленные в socket(2), bind(2), getsockname(2), recvmsg(2), sendto(2),  malloc(3)  или
       realloc(3).

ВЕРСИИ

       Впервые  функция  getifaddrs()  появилась  в  glibc  2.3,  но  до  glibc  2.3.3 реализация
       поддерживала только интерфейсы с адресами IPv4; поддержка IPv6 добавлена  в  glibc  2.3.3.
       Поддержка семейств адресов не IPv4 доступна только в ядрах, поддерживающих netlink.

АТРИБУТЫ

       Описание терминов данного раздела смотрите в attributes(7).

       ┌───────────────────────────────────────────────────────┬──────────────────────┬──────────┐
       │ИнтерфейсАтрибутЗначение │
       ├───────────────────────────────────────────────────────┼──────────────────────┼──────────┤
       │getifaddrs(), freeifaddrs()                            │ Безвредность в нитях │ 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.

ЗАМЕЧАНИЯ

       Адреса, возвращаемые  в  Linux,  обычно,  являются  адресами  IPv4  и  IPv6,  назначенными
       интерфейсу,  но  также  есть  один  адрес  AF_PACKET  на  интерфейс,  содержащий канальные
       настройки интерфейса и его физический уровень. В этом случае поле ifa_data может содержать
       указатель на struct rtnl_link_stats, определённую в <linux/if_link.h> (в Linux 2.4 и ранее
       — struct net_device_stats, определена в <linux/netdevice.h>), которая  содержит  различные
       атрибуты интерфейса и статистику.

ПРИМЕРЫ

       В  программе, показанной далее, демонстрируется использование getifaddrs(), freeifaddrs(),
       и getnameinfo(3). Вот результат запуска этой программы:

           $ ./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)
                           адрес: <127.0.0.1>
           wlp3s0   AF_INET (2)
                           адрес: <192.168.235.137>
           lo       AF_INET6 (10)
                           адрес: <::1>
           wlp3s0   AF_INET6 (10)
                           адрес: <fe80::7ee9:d3ff:fef5:1a91%wlp3s0>

   Исходный код программы

       #define _GNU_SOURCE     /* чтобы получить NI_MAXSERV и 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(): %s\n", gai_strerror(s));
                       exit(EXIT_FAILURE);
                   }

                   printf("\t\tадрес: <%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)

ПЕРЕВОД

       Русский   перевод   этой    страницы    руководства    был    сделан    Azamat    Hackimov
       <azamat.hackimov@gmail.com>,    Dmitry   Bolkhovskikh   <d20052005@yandex.ru>,   Vladislav
       <ivladislavefimov@gmail.com>,   Yuri   Kozlov   <yuray@komyakino.ru>   и    Иван    Павлов
       <pavia00@gmail.com>

       Этот  перевод  является  бесплатной  документацией;  прочитайте  Стандартную  общественную
       лицензию GNU версии 3 ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ или более позднюю, чтобы
       узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

       Если  вы  обнаружите  ошибки  в  переводе этой страницы руководства, пожалуйста, отправьте
       электронное письмо на ⟨man-pages-ru-talks@lists.sourceforge.net⟩.