获取本机IPv6信息命令:cat /proc/net/if_inet6
root@IT-PC-135:/home/user1/# cat /proc/net/if_inet6
fe80000000000000922b34fffe4e70f4 02 40 20 80 eth0
20010f80075400000000000000000050 02 40 00 80 eth0
00000000000000000000000000000001 01 80 10 80 lo
获取本机IPv6网关命令:ip -6 route show dev eth0
root@IT-PC-135:/home/user1/# ip -6 route show dev eth0
2001:f80:754::/64 proto kernel metric 256
fe80::/64 proto kernel metric 256
default via 2001:f80:754::1 proto static metric 1
完整demo
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <sys/prctl.h>
#include <sys/param.h>
#include <sys/wait.h>
#include <errno.h>
#include <paths.h>
#include <sys/syscall.h>
#include <sys/resource.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ifaddrs.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/route.h>
#define PROCNET_ROUTE_PATH "/proc/net/route"
#define PROCNET_IFINET6_PATH "/proc/net/if_inet6"
#define SCOPE_LINK_STR "fe80"
int net_get_ipv6_ifaddr(char type, const char *ifname, char *addr, int length, char *prefix, int length2)
{
int ret = 0;
FILE *fp;
char addr6[46] = {0}, dev_name[20] = {0};
char addr6p[8][5];
int length_of_prefix, scope_value, if_flags, if_index;
struct sockaddr_in6 sap = {0};
if (!ifname || !addr || length <= 0 || !prefix || length2 <= 0)
return -1;
fp = fopen(PROCNET_IFINET6_PATH, "r");
if (!fp) return -1;
lockf(fileno(fp), F_LOCK, 0);
while (fscanf(fp, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
addr6p[0], addr6p[1], addr6p[2], addr6p[3],
addr6p[4], addr6p[5], addr6p[6], addr6p[7],
&if_index, &length_of_prefix, &scope_value, &if_flags, dev_name) != EOF) {
if (!strcmp(dev_name, ifname)) {
sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
addr6p[0], addr6p[1], addr6p[2], addr6p[3],
addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
if (strncmp(addr6p[0], SCOPE_LINK_STR, strlen(SCOPE_LINK_STR)) == 0) {
//fe80 Scope:Link
if (type == 1) {
inet_pton(AF_INET6, addr6, &sap.sin6_addr);
inet_ntop(AF_INET6, &sap.sin6_addr, addr, length);
snprintf(prefix, length2, "%d", length_of_prefix);
lockf(fileno(fp), F_ULOCK, 0);
fclose(fp);
return 0;
}
} else {
//2001 Scope:Global
if (type == 0) {
inet_pton(AF_INET6, addr6, &sap.sin6_addr);
inet_ntop(AF_INET6, &sap.sin6_addr, addr, length);
snprintf(prefix, length2, "%d", length_of_prefix);
lockf(fileno(fp), F_ULOCK, 0);
fclose(fp);
return 0;
}
}
}
}
lockf(fileno(fp), F_ULOCK, 0);
fclose(fp);
return -1;
}
int net_get_ipv6_gateway(char type, const char *ifname, char *gateway, int length)
{
FILE *fp;
char buffer[80] = {'\0'};
char path[128] = {'\0'};
char flag = 0;
char *dfstr = "default via ";
char *p, *q;
if (!ifname || !gateway || length <= 0)
return -1;
//snprintf(path, sizeof(path), "/bin/ip -6 route show dev %s", ifname);
snprintf(path, sizeof(path), "ip -6 route show dev %s", ifname);//hi3798 have not /bin/ip
fp = popen(path, "r");
if (!fp) return -1;
lockf(fileno(fp), F_LOCK, 0);
while (fgets(buffer, sizeof(buffer), fp)) {
if (!strncmp(buffer, dfstr, strlen(dfstr))) {
p = (char *)&buffer[strlen(dfstr)];
if (p) {
q = strchr(p, ' ');
if (q) {
if (type == 1) {
if (strncmp(p, SCOPE_LINK_STR, strlen(SCOPE_LINK_STR)) == 0) {
snprintf(gateway, (int)(q - p + 1), "%s", p);
lockf(fileno(fp), F_ULOCK, 0);
pclose(fp);
return 0;
}
} else {
snprintf(gateway, (int)(q - p + 1), "%s", p);
lockf(fileno(fp), F_ULOCK, 0);
pclose(fp);
return 0;
}
}
}
}
}
lockf(fileno(fp), F_ULOCK, 0);
pclose(fp);
return -1;
}
int net_is_validipv6(const char *hostname)
{
struct sockaddr_in6 addr;
if (!hostname) return -1;
if (strchr(hostname, '.')) return -1;//暂时排除::ffff:204.152.189.116
if (inet_pton(AF_INET6, hostname, &addr.sin6_addr) != 1) return -1;
return 0;
}
int net_ipv4_trans_ipv6(const char *source, char *dest, int length)
{
if (!source || !dest || length <= 0)
return -1;
if (strncmp(source, "::ffff:", strlen("::ffff:")) == 0 && strchr(source, '.')) {
char ipv4[32] = {0};
snprintf(ipv4, sizeof(ipv4), "%s", source+strlen("::ffff:"));
struct in_addr s4 = {0};
if (inet_pton(AF_INET, ipv4, (void*)&s4) != 1)
return -1;
char s6[4] = {0};
s6[0] = s4.s_addr&0xff;
s6[1] = s4.s_addr>>8&0xff;
s6[2] = s4.s_addr>>16&0xff;
s6[3] = s4.s_addr>>24&0xff;
snprintf(dest, length, "::ffff:%x%.2x:%x%.2x", s6[0]&0xff, s6[1]&0xff, s6[2]&0xff, s6[3]&0xff);
return 0;
}
return -1;
}
int main(int argc, char *argv[])
{
int ret = 0;
int type = 0;
char ipv6[64] = {0};
char gateway[64] = {0};
/*ret = net_ipv4_trans_ipv6(argv[1], ipv6, sizeof(ipv6));
printf("ret = %d ipv6 = %s\n", ret, ipv6);*/
//get
char prefix_str[32] = {0};
ret = net_get_ipv6_ifaddr(type, "eth0", ipv6, 64, prefix_str, sizeof(prefix_str));
printf("type = %d, ret = %d ipv6 = %s, prefix = %s\n", type, ret, ipv6, prefix_str);
ret = net_get_ipv6_gateway(type, "eth0", gateway, sizeof(gateway));
printf("type = %d, ret = %d gateway = %s\n", type, ret, gateway);
return ret;
}