1. 程式人生 > >Linux 獲取IPv6閘道器

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));

 

[email protected]:/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