Linux 获取IPv6网关

#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 PROCNET_ROUTE_IPV6_PATH   "/proc/net/ipv6_route"
#define SCOPE_LINK_STR            "fe80"
int net_get_ipv6_gateway2(char type, const char *ifname, char *addr, int length)
{
    FILE *fp;
    char addr6[46] = {0};
    char tmpAdd6[8][5];
    char tmpOther[9][64];
    struct sockaddr_in6 sap = {0};
    
    if (!ifname || !addr || length <= 0)
        return -1;

    fp = fopen(PROCNET_ROUTE_IPV6_PATH, "r");
    if (!fp) return -1;
    
    lockf(fileno(fp), F_LOCK, 0);
    while (fscanf(fp, "%s %02s %s %s %4s%4s%4s%4s%4s%4s%4s%4s %s %s %s %s %20s\n",
        tmpOther[0], tmpOther[1], tmpOther[2], tmpOther[3],
        tmpAdd6[0], tmpAdd6[1], tmpAdd6[2], tmpAdd6[3],
        tmpAdd6[4], tmpAdd6[5], tmpAdd6[6], tmpAdd6[7],
        tmpOther[4], tmpOther[5], tmpOther[6], tmpOther[7], tmpOther[8]) != EOF) {
        
        if (!strcmp(tmpOther[8], ifname) && atoi(tmpOther[1]) == 0) {
            sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
                tmpAdd6[0], tmpAdd6[1], tmpAdd6[2], tmpAdd6[3],
                tmpAdd6[4], tmpAdd6[5], tmpAdd6[6], tmpAdd6[7]);
            if (strncmp(tmpAdd6[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);
                    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);
                    lockf(fileno(fp), F_ULOCK, 0);
                    fclose(fp);
                    return 0;
                }
            }
        }
    }
    lockf(fileno(fp), F_ULOCK, 0);
    fclose(fp);
    return -1;
}

//demo
char ip6Addr[64] = {0};
net_get_ipv6_gateway2(0, "eth0", ip6Addr, sizeof(ip6Addr));
root@IT-PC-135:/home/user1/# cat /proc/net/ipv6_route
20010f80075400000000000000000000 40 00000000000000000000000000000000 00 00000000000000000000000000000000 00000100 00000000 00000001 00000001     eth0
fe800000000000000000000000000000 40 00000000000000000000000000000000 00 00000000000000000000000000000000 00000100 00000000 00000000 00000001     eth0
00000000000000000000000000000000 00 00000000000000000000000000000000 00 20010f80075400000000000000000001 00000001 00000000 00000000 00000003     eth0
00000000000000000000000000000000 00 00000000000000000000000000000000 00 00000000000000000000000000000000 ffffffff 00000001 000001d6 00200200       lo
00000000000000000000000000000001 80 00000000000000000000000000000000 00 00000000000000000000000000000000 00000000 00000001 00000476 80200001       lo
20010f80075400000000000000000050 80 00000000000000000000000000000000 00 00000000000000000000000000000000 00000000 00000001 00000268 80200001       lo
fe80000000000000922b34fffe4e70f4 80 00000000000000000000000000000000 00 00000000000000000000000000000000 00000000 00000001 0000003d 80200001       lo
ff000000000000000000000000000000 08 00000000000000000000000000000000 00 00000000000000000000000000000000 00000100 00000000 00000000 00000001     eth0
00000000000000000000000000000000 00 00000000000000000000000000000000 00 00000000000000000000000000000000 ffffffff 00000001 000001d6 00200200       lo
# cat /proc/net/ipv6_route   --查看设备的ipv6路由信息,以一个条目为例。
 fe80000000000000023439fffea33934 80 00000000000000000000000000000000 00 00000000000000000000000000000000 00000000 00000001 00000000 80200001
解释:
fe80000000000000023439fffea33934 80 :为目的网络及前缀。
00000000000000000000000000000000 00:只有主路由表,则默认0。
00000000000000000000000000000000:网关地址。
00000000:rt->rt6i_metric  rt6_select时使用,路由选择的条件。
00000001:rt->dst.__refcnt 路由表管理时使用。
       * __refcnt wants to be on a different cache line from
       * input/output/ops or performance tanks badly
00000000:rt->dst.__use 路由被使用次数。
80200001:rt->rt6i_flags 是否刷新等。

参考:http://blog.csdn.net/eleven_xiy/article/details/72777931

猜你喜欢

转载自blog.csdn.net/y7u8t6/article/details/79531622