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

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

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

/************************************************************
  Copyright (C), 2017, Leon, All Rights Reserved.
FileName: get_if_addr.c
Description: 获取接口地址
Author: Leon
Version: 1.0
Date: 
Function:

History:
    

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

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 eth2
eth2 [0] 2006::1
ff ff ff ff ff ff fe 00 00 00 00 00 00 00 00 00 
mask len: 55
eth2 [0] ffff:ffff:ffff:fe00:: [netmask]
eth2 [1] 2005::1
ff ff ff ff ff ff ff 00 00 00 00 00 00 00 00 00 
mask len: 56
eth2 [1] ffff:ffff:ffff:ff00:: [netmask]
eth2 [2] 2003::1
ff ff ff ff ff ff 00 00 00 00 00 00 00 00 00 00 
mask len: 48
eth2 [2] ffff:ffff:ffff:: [netmask]
eth2 [3] 2001:5521::1
ff ff ff ff ff ff ff ff 00 00 00 00 00 00 00 00 
mask len: 64
eth2 [3] ffff:ffff:ffff:ffff:: [netmask]
eth2 [4] fe80::20c:29ff:fe8f:c17c
ff ff ff ff ff ff ff ff 00 00 00 00 00 00 00 00 
mask len: 64
eth2 [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 

你可能感兴趣的:(ipv6,ipv6,getifaddr)