ipv6地址处理

(>^ω^<)喵上树 2014-01-15 03:45:11
代码的一部分::::
char host[NI_MAXHOST];

if(family == AF_INET6)
{
if(strcmp(ifa->ifa_name, eth) == 0)
{
s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
if (s != 0)
{
printf("getnameinfo() failed: %s\n", gai_strerror(s));
exit(EXIT_FAILURE);
}

printf("%s\n", host);
/* 结果是 fe80::20c:29ff:fe6b:2516%eth0 */
/**************************************
gdb 跟踪是-------------------:
(gdb) p host
$1="fe80::20c:29ff:fe6b:2516%eth0\000\000\000\a\000\000\000\000\000\000\000\260\354\260\367\377\177\000\000(\345\377\367\377\177\000\000\340\071\336\367\377\177\000\000X\246\377\367\377\177\000\000\001\331\336\367\377\177\000\000\000\000\000\000\377\177\000\000\000\000\000\000\000\000\000\000\b\350\377\377\377\177\000\000X\263\377\367\377\177\000\000\000\000\000\000\000\000\000\000\002", '\000' <repeats 15 times>"\300, \063\336\367\377\177\000\000 \340\377\367\377\177\000\000\000\060\336\367\377\177\000\000b7\336\367\377\177\000\000L'\337\367\377\177\000\000\060\063\336\367\377\177\000\000\320\065\336\367\377\177\000\000\020\350\377\377\377\177\000\000\341\030\337\367\000\000\000\000H8\336\367\377\177\000\000\260\001\000\000\000\000\000\000\000\000\000\000\377\177\000\000L'\337\367\377\177\000\000\000\000\000\000\000\000\000\000\360F\377\367\377\177\000\000\260M\377\367\377\177\000\000\270\276\252\367\377\177\000\000\000\000\000\000\000\000\000\000p\237\071W\000\000\000\000"...
******************************************************/

/* unsigned char ip_v6[16]; 现在要把 fe80::20c:29ff:fe6b:2516 这部分内容保存在ip_v6这个字符数组里。。 请问这里改怎么处理?????????????? */
}
}
...全文
399 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2014-01-15
  • 打赏
  • 举报
回复
//IPv6地址表示
//IPv6地址为128位长,但通常写作8组,每组为四个十六进制数的形式。例如:
//FE80:0000:0000:0000:AAAA:0000:00C2:0002 是一个合法的IPv6地址。
//要是嫌这个地址看起来还是太长,这里还有种办法来缩减其长度,叫做零压缩法。
//如果几个连续段位的值都是0,那么这些0就可以简单的以::来表示,上述地址就可以写成
//FE80::AAAA:0000:00C2:0002。这里要注意的是只能简化连续的段位的0,其前后的0都要保留,
//比如FE80的最后的这个0,不能被简化。还有这个只能用一次,在上例中的
//AAAA后面的0000就不能再次简化。当然也可以在AAAA后面使用::,这样的话前面的
//12个0就不能压缩了。这个限制的目的是为了能准确还原被压缩的0.不然就无法确定每个::代表了多少个0.
//2001:0DB8:0000:0000:0000:0000:1428:0000
//2001:0DB8:0000:0000:0000::1428:0000
//2001:0DB8:0:0:0:0:1428:0000
//2001:0DB8:0::0:0:1428:0000
//2001:0DB8::1428:0000都是合法的地址,并且他们是等价的。但
//2001:0DB8::1428::是非法的。(因为这样会使得搞不清楚每个压缩中有几个全零的分组)
//同时前导的零可以省略,因此:
//2001:0DB8:02de::0e13等价于2001:DB8:2de::e13
#include <stdio.h>
#include <string.h>
char ipv60[]="2001:0DB8:0000:0000:0000:0000:1428:0000";
char ipv61[]="1040::1";
char ipv62[]="fe80::20c:29ff:fe6b:2516";
char ipv63[]="::ffff:c0a8:5909";
unsigned char ip_v6[16];
void show(char *a) {
    int i;
    printf("%-39s=>",a);
    for (i=0;i<16;i++) printf("%02x ",ip_v6[i]);
    printf("\n");
}
void inet_addr6(char *a) {
    char *p;
    int n,i,r,k,j;
    short s;
    k=0;
    p=a;
    while (1) {
        if (*p==':') k++;
        p++;
        if (*p==0) break;
    }
    if (a[0]==':') k--;
    i=0;
    p=a;
    while (1) {
        r=sscanf(p,"%hx%n",&s,&n);
        if (1==r) {
            ip_v6[i]=*((unsigned char *)&s+1);
            ip_v6[i+1]=*((unsigned char *)(&s));
            i+=2;
            if (i>=16) break;
            p+=n;
        } else if (0==r) {
            if (p[0]==':') {
                if (p[1]==':') {
                    for (j=0;j<(8-k)*2;j++) ip_v6[i+j]=0;
                    i+=(8-k)*2;
                    if (i>=16) break;
                    p+=2;
                } else {
                    p++;
                }
            } else {
                printf("Format Error [%s]!\n",a);
            }
        } else break;
    }
}
int main() {
    inet_addr6(ipv60);show(ipv60);
    inet_addr6(ipv61);show(ipv61);
    inet_addr6(ipv62);show(ipv62);
    inet_addr6(ipv63);show(ipv63);
    return 0;
}
//2001:0DB8:0000:0000:0000:0000:1428:0000=>20 01 0d b8 00 00 00 00 00 00 00 00 14 28 00 00
//1040::1                                =>10 40 00 00 00 00 00 00 00 00 00 00 00 00 00 01
//fe80::20c:29ff:fe6b:2516               =>fe 80 00 00 00 00 00 00 02 0c 29 ff fe 6b 25 16
//::ffff:c0a8:5909                       =>00 00 00 00 00 00 00 00 00 00 ff ff c0 a8 59 09
//
(>^ω^<)喵上树 2014-01-15
  • 打赏
  • 举报
回复
引用 1 楼 zhao4zhong1 的回复:
IPv6 addresses are not so predictable, due to the IPv6 address convention that enables the use of a double-colon (::) to represent a series of zeros. As such, the following IPv6 address representations equate to the same IPv6 address: 1040:0:0:0:0:0:0:1 1040::1 so fe80::20c:29ff:fe6b:2516 fe80:0:0:0:20c:29ff:fe6b:2516 representations equate to the same IPv6 address so unsigned char ip_v6[16]={0xfe,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x0c,0x29,0xff,0xfe,0x6b,0x25,0x16};//byte order maybe error.
是的,,但是我总不能手写到ipv6[16]里吧!
赵4老师 2014-01-15
  • 打赏
  • 举报
回复
IPv6 addresses are not so predictable, due to the IPv6 address convention that enables the use of a double-colon (::) to represent a series of zeros. As such, the following IPv6 address representations equate to the same IPv6 address: 1040:0:0:0:0:0:0:1 1040::1 so fe80::20c:29ff:fe6b:2516 fe80:0:0:0:20c:29ff:fe6b:2516 representations equate to the same IPv6 address so unsigned char ip_v6[16]={0xfe,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x0c,0x29,0xff,0xfe,0x6b,0x25,0x16};//byte order maybe error.

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧