获取接口所有IPV6地址和前缀的方法

来源:互联网 发布:淘宝是第三方活动平台 编辑:程序博客网 时间:2024/05/18 22:41

获取接口的IPV6地址和前缀一共有如下3种方法:
1. 通过ifconfig
2. 通过getifaddrs函数
3. 通过cat /proc/net/if_inet6

第一种和第三种都类似于读文件,下面主要看一下第二种方法的代码示例:

/************************************************************  Copyright (C), 2017, Leon, All Rights Reserved.FileName: get_if_addr.cDescription: 获取接口地址Author: LeonVersion: 1.0Date: Function:History:<author>    <time>  <version>   <description>Leon ************************************************************/#include <arpa/inet.h>#include <sys/socket.h>#include <netdb.h>#include <ifaddrs.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <netinet/in.h>int cale_prefix_len(struct in6_addr *mask){    int i = 0;    int len = 0;    int u = 0;    for(i = 0; i < 16; i++)    {        u = mask->s6_addr[i];        if(ffs(u) > 0)        {            len += 9 - ffs(u);        }        else        {            break;        }    }    return len;}int get_if_addr6(char *ifname, struct sockaddr_in6 *list, int len){       struct ifaddrs *ifaddr, *ifa;       int cnt = 0;    char ip_str[64];    if(!ifname || !list || !len)        return 0;    if (-1 == getifaddrs(&ifaddr))    {        perror("getifaddrs");        return;     }    for(ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)     {               if(ifa->ifa_name && !strcmp(ifa->ifa_name, ifname) &&                ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET6)        {               if(cnt > len)                break;            memcpy(&list[cnt], ifa->ifa_addr, sizeof(struct sockaddr_in6));            inet_ntop(AF_INET6, &list[cnt].sin6_addr, ip_str, sizeof(ip_str));            printf("%s [%d] %s\n", ifname, cnt, ip_str);            int i = 0;            for(i =0 ; i < 16; i++)            {                printf("%02x ",  (((struct sockaddr_in6*)(ifa->ifa_netmask))->sin6_addr).s6_addr[i] );            }            printf("\n");            printf("mask len: %d\n", cale_prefix_len(&((struct sockaddr_in6*)(ifa->ifa_netmask))->sin6_addr));            inet_ntop(AF_INET6, &((struct sockaddr_in6*)(ifa->ifa_netmask))->sin6_addr, ip_str, sizeof(ip_str));            printf("%s [%d] %s [netmask]\n", ifname, cnt, ip_str);            cnt++;        }    }       freeifaddrs(ifaddr);          return cnt;}int main(int argc, char *argv[]){    char buf[256] = {0};    struct sockaddr_in6 *list = malloc(16 * sizeof(struct sockaddr_in6));    get_if_addr6(argv[1], list, 16);    return 0;}

执行结果如下:

# ./a.out eth2eth2 [0] 2006::1ff ff ff ff ff ff fe 00 00 00 00 00 00 00 00 00 mask len: 55eth2 [0] ffff:ffff:ffff:fe00:: [netmask]eth2 [1] 2005::1ff ff ff ff ff ff ff 00 00 00 00 00 00 00 00 00 mask len: 56eth2 [1] ffff:ffff:ffff:ff00:: [netmask]eth2 [2] 2003::1ff ff ff ff ff ff 00 00 00 00 00 00 00 00 00 00 mask len: 48eth2 [2] ffff:ffff:ffff:: [netmask]eth2 [3] 2001:5521::1ff ff ff ff ff ff ff ff 00 00 00 00 00 00 00 00 mask len: 64eth2 [3] ffff:ffff:ffff:ffff:: [netmask]eth2 [4] fe80::20c:29ff:fe8f:c17cff ff ff ff ff ff ff ff 00 00 00 00 00 00 00 00 mask len: 64eth2 [4] ffff:ffff:ffff:ffff:: [netmask]

对应的ifconfig输出:

eth2      Link encap:Ethernet  HWaddr 00:0c:29:8f:c1:7c            inet6 addr: 2006::1/55 Scope:Global          inet6 addr: 2001:5521::1/64 Scope:Global          inet6 addr: 2003::1/48 Scope:Global          inet6 addr: fe80::20c:29ff:fe8f:c17c/64 Scope:Link          inet6 addr: 2005::1/56 Scope:Global          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1          RX packets:12983 errors:0 dropped:7 overruns:0 frame:0          TX packets:117 errors:0 dropped:0 overruns:0 carrier:0          collisions:0 txqueuelen:1000           RX bytes:1189601 (1.1 MB)  TX bytes:16596 (16.5 KB)          Interrupt:16 Base address:0x2400 
0 0
原创粉丝点击