获取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 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 ";// "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;
    char ipv6[64] = {0};
    
    ret = net_ipv4_trans_ipv6(argv[1], ipv6, sizeof(ipv6));
    printf("ret = %d ipv6 = %s\n", ret, ipv6);
    char type=1;
    char *ifname="eth0";
    char addr[64] = {0};
    int length=64;
    char prefix[32]={0};
    int length2=32;
    net_get_ipv6_ifaddr(type,ifname,addr,length,prefix,length2);
    printf("addr=%s\n",addr);
    printf("prefix=%s\n",prefix);
    char gateway[64] = {0};
    type=0;  //外网
    net_get_ipv6_gateway(type,ifname,gateway,length);
    printf("gateway=%s\n",gateway);
    return ret;
}

 

执行:
./ip6  ::ffff:192.168.1.181

### 如何在 WSL 中获取 IPv6 地址 为了确保能够成功获取并查看 WSL 环境中的 IPv6 地址,可以按照如下方法操作: #### 验证网络接口状态和支持情况 首先确认当前系统的网络适配器是否启用了 IPv6 支持。可以通过运行命令来检查所有可用的网络接口及其配置详情。 ```bash ip a show ``` 这条命令会显示所有的网络设备以及它们的状态,包括分配给这些设备的任何 IP 地址(无论是 IPv4 还是 IPv6)。如果看到类似于 `inet6` 的条目,则表示该接口已经获得了有效的全局或本地链路范围内的 IPv6 地址[^1]。 #### 获取特定网卡上的IPv6地址 如果有多个网络接口并且想要专门查询某个指定名称的网络接口所持有的 IPv6 地址,可执行下面这个更具体的指令: ```bash ifconfig eth0 | grep inet6 ``` 这里假设目标是以太网连接名为 "eth0";实际环境中应当替换为真实的网络接口名。此命令过滤出了仅含有关于选定网络接口的 IPv6 信息的部分[^2]。 #### 使用ping测试外部可达性和验证地址有效性 一旦找到了自己的机器被赋予的一个或几个 IPv6 地址之后,还可以通过向公共服务器发送 ICMPv6 请求来进行连通性的简单检测: ```bash ping6 -c 4 ipv6.google.com ``` 这将尝试与 Google 提供的服务建立联系,并返回四次往返时间的结果作为反馈。成功的响应意味着不仅本机具备正常工作的 IPv6 协议栈,而且也能顺利访问互联网资源[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值