使用 getifaddrs函数获取Linux的IPV6地址

c++ c++ 1874 人阅读 | 0 人回复

发表于 2023-5-23 14:59:38 | 显示全部楼层 |阅读模式

getifaddrs()函数
头文件:
#include <sys/types.h>
#include <ifaddrs.h>
函数说明:获取本地网络接口的信息。在路由器上可以用这个接口来获取wan/lan等接口当前的ip地址,广播地址等信息。
int getifaddrs(struct ifaddrs **ifap);
getifaddrs创建一个链表,链表上的每个节点都是一个struct ifaddrs结构,getifaddrs()返回链表第一个元素的指针

返回值:成功返回0, 失败返回-1,同时errno会被赋允相应错误码。
事例:
  1. #include <arpa/inet.h>
  2. #include <sys/socket.h>
  3. #include <netdb.h>
  4. #include <ifaddrs.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <unistd.h>
  8. #include <net/if.h>

  9. int
  10. main(int argc, char *argv[])
  11. {
  12.         struct ifaddrs *ifaddr, *ifa;
  13.         int family, s;
  14.         char host[NI_MAXHOST];

  15.         if (getifaddrs(&ifaddr) == -1) {
  16.                 perror("getifaddrs");
  17.                 exit(EXIT_FAILURE);
  18.         }

  19.         /* Walk through linked list, maintaining head pointer so we
  20.            can free list later */

  21.         for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
  22.                 if (ifa->ifa_addr == NULL)
  23.                         continue;
  24.                 family = ifa->ifa_addr->sa_family;

  25.                 /* Display interface name and family (including symbolic
  26.                    form of the latter for the common families) */

  27.                 printf("%s  address family: %d%s\n",
  28.                        ifa->ifa_name, family,
  29.                        (family == AF_PACKET) ? " (AF_PACKET)" :
  30.                        (family == AF_INET) ?   " (AF_INET)" :
  31.                        (family == AF_INET6) ?  " (AF_INET6)" : "");

  32.                 if (ifa->ifa_flags & IFF_BROADCAST)

  33.                 /* For an AF_INET* interface address, display the address */

  34.                 if (family == AF_INET || family == AF_INET6) {
  35.                         s = getnameinfo(ifa->ifa_addr,
  36.                                         (family == AF_INET) ? sizeof(struct sockaddr_in) :
  37.                                         sizeof(struct sockaddr_in6),
  38.                                         host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
  39.                         if (s != 0) {
  40.                                 printf("getnameinfo() failed: %s\n", gai_strerror(s));
  41.                                 exit(EXIT_FAILURE);
  42.                         }
  43.                         printf("\taddress: <%s>\n", host);

  44.                         if (ifa->ifa_flags & IFF_BROADCAST) {
  45.                                 s = getnameinfo(ifa->ifa_broadaddr,
  46.                                                 (family == AF_INET) ? sizeof(struct sockaddr_in) :
  47.                                                 sizeof(struct sockaddr_in6),
  48.                                                 host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
  49.                                 printf("\tbroadcast address: <%s>\n", host);
  50.                         }
  51.                         if (ifa->ifa_flags & IFF_POINTOPOINT) {
  52.                                 s = getnameinfo(ifa->ifa_dstaddr,
  53.                                                 (family == AF_INET) ? sizeof(struct sockaddr_in) :
  54.                                                 sizeof(struct sockaddr_in6),
  55.                                                 host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
  56.                                 printf("\tbroadcast address: <%s>\n", host);
  57.                         }
  58.                 }
  59.         }

  60.         freeifaddrs(ifaddr);
  61.         exit(EXIT_SUCCESS);
  62. }
复制代码
struct ifaddrs结构体:
  1. struct ifaddrs
  2. {
  3.     struct ifaddrs  *ifa_next;    /* Next item in list */
  4.     char            *ifa_name;    /* Name of interface */
  5.     unsigned int     ifa_flags;   /* Flags from SIOCGIFFLAGS */
  6.     struct sockaddr *ifa_addr;    /* Address of interface */
  7.     struct sockaddr *ifa_netmask; /* Netmask of interface */
  8.     union
  9.     {
  10.         struct sockaddr *ifu_broadaddr; /* Broadcast address of interface */
  11.         struct sockaddr *ifu_dstaddr; /* Point-to-point destination address */
  12.     } ifa_ifu;
  13.     #define              ifa_broadaddr ifa_ifu.ifu_broadaddr
  14.     #define              ifa_dstaddr   ifa_ifu.ifu_dstaddr
  15.     void            *ifa_data;    /* Address-specific data */
  16. };
复制代码
ifa_next 指向链表中下一个struct ifaddr结构
ifa_name 网络接口名
ifa_flags 网络接口标志,这些标志见下面描述。
ifa_addr 指向一个包含网络地址的sockaddr结构
ifa_netmask 指向一个包含网络掩码的结构
ifu_broadaddr 如果(ifa_flags&IFF_BROADCAST)有效,ifu_broadaddr指向一个包含广播地址的结构。
ifu_dstaddr 如果(ifa_flags&IFF_POINTOPOINT)有效,ifu_dstaddr指向一个包含p2p目的地址的结构。
ifa_addr 指向一个缓冲区,其中包含地址族私有数据。没有私有数据则为NULL。

ifa_flags 标志位:
Device flags
IFF_UP Interface is running.
IFF_BROADCAST Valid broadcast address set.
  1.                 IFF_DEBUG         Internal debugging flag.
  2.                               IFF_LOOPBACK      Interface is a loopback interface.
  3.                               IFF_POINTOPOINT   Interface is a point-to-point link.
  4.                               IFF_RUNNING       Resources allocated.
  5.                               IFF_NOARP         No arp protocol, L2 destination address not
  6.                                                 set.
  7.                               IFF_PROMISC       Interface is in promiscuous mode.
  8.                               IFF_NOTRAILERS    Avoid use of trailers.
  9.                               IFF_ALLMULTI      Receive all multicast packets.
  10.                               IFF_MASTER        Master of a load balancing bundle.
  11.                               IFF_SLAVE         Slave of a load balancing bundle.
  12.                               IFF_MULTICAST     Supports multicast
  13.                               IFF_PORTSEL       Is able to select media type via ifmap.
  14.                               IFF_AUTOMEDIA     Auto media selection active.
  15.                               IFF_DYNAMIC       The addresses are lost when the interface
  16.                                                 goes down.
  17.                               IFF_LOWER_UP      Driver signals L1 up (since Linux 2.6.17)
  18.                               IFF_DORMANT       Driver signals dormant (since Linux 2.6.17)
  19.                               IFF_ECHO          Echo sent packets (since Linux 2.6.25)
复制代码


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则