• 【Atheros】pktgen的ipv6地址处理函数参考及ipv6基本知识


    pktgen有很多函数可以作为很好的网络相关的工具函数,这里列出ipv6中1:0:0:0:0:0:0:1和1::1这两种地址形式相互转化的工具函数。

    第一个函数,用于把一个1:0:0:0:0:0:0:1形式的地址转化为1::1

    /*
     * scan_ip6, fmt_ip taken from dietlibc-0.21
     * Author Felix von Leitner <felix-dietlibc@fefe.de>
     *
     * Slightly modified for kernel.
     * Should be candidate for net/ipv4/utils.c
     * --ro
     */
    
    static unsigned int scan_ip6(const char *s, char ip[16])
    {
        unsigned int i;
        unsigned int len = 0;
        unsigned long u;
        char suffix[16];
        unsigned int prefixlen = 0;
        unsigned int suffixlen = 0;
        __be32 tmp;
        char *pos;
    
        for (i = 0; i < 16; i++)
            ip[i] = 0;
    
        for (;;) {
            if (*s == ':') {
                len++;
                if (s[1] == ':') {    /* Found "::", skip to part 2 */
                    s += 2;
                    len++;
                    break;
                }
                s++;
            }
    
            u = simple_strtoul(s, &pos, 16);
            i = pos - s;
            if (!i)
                return 0;
            if (prefixlen == 12 && s[i] == '.') {
    
                /* the last 4 bytes may be written as IPv4 address */
    
                tmp = in_aton(s);
                memcpy((struct in_addr *)(ip + 12), &tmp, sizeof(tmp));
                return i + len;
            }
            ip[prefixlen++] = (u >> 8);
            ip[prefixlen++] = (u & 255);
            s += i;
            len += i;
            if (prefixlen == 16)
                return len;
        }
    
    /* part 2, after "::" */
        for (;;) {
            if (*s == ':') {
                if (suffixlen == 0)
                    break;
                s++;
                len++;
            } else if (suffixlen != 0)
                break;
    
            u = simple_strtol(s, &pos, 16);
            i = pos - s;
            if (!i) {
                if (*s)
                    len--;
                break;
            }
            if (suffixlen + prefixlen <= 12 && s[i] == '.') {
                tmp = in_aton(s);
                memcpy((struct in_addr *)(suffix + suffixlen), &tmp,
                       sizeof(tmp));
                suffixlen += 4;
                len += strlen(s);
                break;
            }
            suffix[suffixlen++] = (u >> 8);
            suffix[suffixlen++] = (u & 255);
            s += i;
            len += i;
            if (prefixlen + suffixlen == 16)
                break;
        }
        for (i = 0; i < suffixlen; i++)
            ip[16 - suffixlen + i] = suffix[i];
        return len;
    }

    第二个函数完成反向的转换,把1::1恢复成完成的地址:

    static unsigned int fmt_ip6(char *s, const char ip[16])
    {
        unsigned int len;
        unsigned int i;
        unsigned int temp;
        unsigned int compressing;
        int j;
    
        len = 0;
        compressing = 0;
        for (j = 0; j < 16; j += 2) {
    
    #ifdef V4MAPPEDPREFIX
            if (j == 12 && !memcmp(ip, V4mappedprefix, 12)) {
                inet_ntoa_r(*(struct in_addr *)(ip + 12), s);
                temp = strlen(s);
                return len + temp;
            }
    #endif
            temp = ((unsigned long)(unsigned char)ip[j] << 8) +
                (unsigned long)(unsigned char)ip[j + 1];
            if (temp == 0) {
                if (!compressing) {
                    compressing = 1;
                    if (j == 0) {
                        *s++ = ':';
                        ++len;
                    }
                }
            } else {
                if (compressing) {
                    compressing = 0;
                    *s++ = ':';
                    ++len;
                }
                i = fmt_xlong(s, temp);
                len += i;
                s += i;
                if (j < 14) {
                    *s++ = ':';
                    ++len;
                }
            }
        }
        if (compressing) {
            *s++ = ':';
            ++len;
        }
        *s = 0;
        return len;
    }

    下面附上ipv6的一些相关的基础知识,看懂这些也更有助于理解上面的两个函数,ps:这好像是我之前在一些网站上截的,我当时也记了源地址,但是源网站已经挂掉了:

    IPv4地址是类似 A.B.C.D 的格式,它是32位,用.分成四段,用10进制表示;而IPv6地址类似X:X:X:X:X:X:X:X的格式,它是128位的,用:分 成8段,用16进制表示,每一段的值从8位扩充到16位。

    RFC2373 中定义了完整的IPv6地址表示:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx

    例如: 2001:0000: 1F 1F :0000:0000:0100: 11A 0:ADDF

    为简化表示, rfc2373提出每段中前面的0可以省略,连续的0可省略为::,但只能出现一次。例如:

    1080:0:0:0:8:800: 200C : 417A 可简写为 1080::8:800: 200C : 417A

    FF01:0:0:0:0:0:0:101 可简写为 FF01::101

    0:0:0:0:0:0:0:1 可简写为 ::1

    0:0:0:0:0:0:0:0 可简写为 ::

    这里给出一个表格,以比较IPv4和IPv6地址对应关系和区别。

    IPv4

    IPv6

    组播地址(224.0.0.0/4)

    IPv6组播地址(FF00::/8)

    有广播地址

    无广播,只有任播(anycast)

    未指定地址为 0.0.0 .0

    未指定地址为 ::

    回路地址为 127.0.0.1

    回路地址为 ::1

    私有地址( 10.0.0 .0/8、172.16.0.0/12和192.168.0.0/16)

    本地站点地址( FEC0::/48)

    Microsoft自动专用IP寻址自动配置的地址(169.254.0.0/16)

    本地链路地址( FE80::/64)

    表达方式:点分十进制

    表达方式:冒号十六进制式

    子网掩码表示:以点阵十进制表示法或前缀长度表示法( CIDR)

    子网掩码表示:仅使用前缀长度表示法( CIDR)

    常见的IPv6地址及其前缀:

    ::/128  即0:0:0:0:0:0:0:0,只能作为尚未获得正式地址的主机的源地址,不能作为目的地址,不能分配给真实的网络接口。

    ::1/128 即0:0:0:0:0:0:0:1,回环地址,相当于IPv4中的localhost(127.0.0.1),ping locahost可得到此地址。

    2001::/16  全球可聚合地址,由 IANA 按地域和ISP进行分配,是最常用的IPv6地址,属于单播地址。

    2002::/16  6 to 4 地址,用于6to4自动构造隧道技术的地址,属于单播地址。

    3ffe::/16   早期开始的IPv6 6bone试验网 地址,属于单播地址。

    fe80::/10   本地链路地址,用于单一链路,适用于自动配置、邻机发现等,路由器不转发以fe80开头的地址。

    ff00::/8  组播地址。

    ::A.B.C.D  兼容IPv4的IPv6地址,其中<A.B.C.D>代表IPv4地址。自动将IPv6包以隧道方式在IPv4网络中传送的IPv4/IPv6节点将使用这些地址。

    ::FFFF:A.B.C.D   是IPv4映射过来的IPv6地址,其中<A.B.C.D>代表IPv4地址,例如 ::ffff:202.120.2.30 ,它是在不支持IPv6的网上用于表示IPv4节点。

  • 相关阅读:
    方便的使用单击和双击更新DataGrid中的数据的例子 (转)
    针对 .NET 开发人员的存储过程评估(转)
    ASP.NET创建Web服务之XML基础结构(转)
    移动业务咨询系统--用VoiceXML开发语音应用程序(转)
    创建动态数据输入用户界面 (转)
    ASP.NET缓存:方法和最佳实践(转)
    ASP.NET 应用程序性能优化(转)
    出色图形用户界面(GUI)设计规范(转,中英对比)
    五种常见的ASP.NET安全缺陷(转)
    ASP.net控件开发系列之(一)开篇(转)
  • 原文地址:https://www.cnblogs.com/smarterplanet/p/4083292.html
Copyright © 2020-2023  润新知