您的位置:首页 > 其它

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

2017-04-05 17:37 288 查看
获取接口的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:
<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 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 getifaddr