温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

IPv6的NAT原理是什么

发布时间:2021-11-24 17:53:15 来源:亿速云 阅读:708 作者:柒染 栏目:互联网科技

IPv6的NAT原理是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

在亿万互联网用户享受着Internet带来便利的同时,IPv4地址即将耗尽的问题却早在20年前就被网络专家们意识到了,并采取了措施延缓IPv4的消耗,这项措施就是NAT(网络地址转换)技术。NAT主要作用在于节约IP地址,而非所谓的增加IP的方向性以及隐藏私有IP,且IPv4的NAT打破了互联网本身的“互联”特性,使得一部分IP地址不再双向可达,NAT为无方向的IP协议增加了一个方向,特别是stateful的NAT类型。此时,IPv6时代已逐渐到来。

而IPv6的标准中不建议使用NAT,这是何缘由呢?我们已知IPv6地址数量巨大,只要在地球上,都可为蚂蚁配置IP设备,因此IPv4的一些修补手段将不再需要,为了保持协议本身以及相关标准的纯洁性,在IPv6中几乎不再建议使用NAT。虽然不再建议使用,但在某些必要情况下,还是可能需要实现IPv6的NAT。在RFC6296的标题是IPv6-to-IPv6 Network Prefix Translation中,描述了IPv6下的NAT的实现要点,给出了一个合理的建议,既保持了IP的无方向性,又可以满足NAT的语义,这就是IPv6之NAT stateless的缘由。

IPv6地址有将近128个可随意调配的位,其庞大的地址空间,一般的单位都会被分配到一个拥有很大量地址的网段,此网段拥有足够多的地址来和内网主机进行映射,即可用于映射的IP地址池容量巨大,且既然不想再使用非IP层的信息来保持信息,又要保持映射,那就要用纯IP层的信息,这样对上层影响最小。对于IPv6而言,NAT利用checksum算法来保持流标识信息,丝毫不管这个checksum是谁的checksum,因为它根本就不改变数据包的checksum...

接下来给大家讲解一下checksum无关性和自动转换,就是考虑a+b+c+d=X。其中X就是checksum,我们把a,b当成源IP地址的两部分,c,d当成目的IP地址的两部分,我们作源地址转换,将a和b都改变,比如a改变成了A,那么将b改成多少才能保持checksum的值X不变,求解即可。IPv6的建议NAT实现亦是上文这个原理,只是将其换为计算机布尔数域求解。既然可以不触动第四层的checksum值,那么NAT对第四层协议的影响也就减小了,虽然它还是解决不了诸如ESP/AH等穿越NAT的问题。基于以上算法,IPv6在做NAT的时候,在给定的子网网段内,可以自动生成一个新的IP地址供映射之用,从算法本身来看,冲突的可能性非常之小致于0。

既然IPv6的NAT机制“自动”为一个连接选择了一个IP地址,那么当返回包到来的时候,如何把地址转换为原地址呢?IPv6的NAT把地址“转换回去”这件事完全靠算法本身,而算法本身就能将转换后的地址再转回原来的,具有解的唯一性,在IPv6的NAT实现中,算法只针对IP地址中16位的地址信息进行自动生成,而其它的则需要手工显式配置,由于内网IPv6地址可以使用MAC地址映射成唯一的地址,且转换后的地址是唯一的,将这一切反过来,最后还是能映射回原始的IP地址的。

如果抛开地址转换这一说,仅仅考虑算法本身,那还是可以给出一个实际可以运行的代码的,该代码使用了计算checksum的算法:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

//以下2个函数就是计算校验码的,具体的原理请参RFC1071/RFC1624/RFC1141。

static inline u_int16_t add16(

    u_int16_t a,

    u_int16_t b)

{

    a += b;

    return a + (a < b);

}

static inline u_int16_t csum16(const u_int16_t *buf, int len)

{

    u_int16_t csum = 0;

    while(len--) csum = add16(csum, *buf++);

    return csum;

}

int main(int argc, char **argv)

{

    u_int16_t buf[18] = {0};

    int i = 0;

    memcpy(buf, "efghhijk", 8);

    memcpy(buf+4, "12345678", 8);

    memcpy(buf+8, "xxyywert", 8);

    memcpy(buf+12, "zxcvkljh", 8);

    //正确做法是打印16进制数据,此处为了简单,打印了字符串

    printf("原始数据:%s  长度:%d\n", (char*)buf, strlen((char*)buf));    

    printf("原始数据的校验码:%X\n", csum16(buf, 16));    

    u_int16_t tip[3] = {0};

    memcpy(tip, "#$!%", 4);

    u_int16_t tip_sum = csum16(tip, 2);

    printf("\nNAT规则: efghhijk1234/12 -〉efghhijk#$!%/12\n\n");

    printf("固定从第9个字节开始修改4个字节为:%s 其校验码为:%X\n", (char*)tip, tip_sum);

    //定位固定修改后的动态修改的初始地址,注意,我们仅仅修改16位信息

    u_int16_t* pcsum = buf + 4+2;  

    //计算动态修改的值

    *pcsum = ~add16(

        add16(

            ~(*pcsum),

            ~csum16(buf+4, 2)

        ),

        tip_sum

    );

    printf("动态修改的值为:%X\n", *pcsum);

    memcpy(buf+4, tip, 4); //完成修改

    printf("当前数据:%s  长度:%d\n", buf, strlen((char*)buf));    

    printf("当前校验码:%X\n", csum16(buf, 16));    

    printf("-------------以下是还原操作-------------\n");

    printf("\n反向NAT规则: efghhijk#$!%/12 -〉efghhijk1234/12\n\n");

    u_int16_t tip2[3] = {0};

        memcpy(tip2, "1234", 4);

    printf("我们只需要记住原始数据被固定修改前的:%s\n", tip2);

    u_int16_t tip_sum2 = csum16(tip2, 2);

    u_int16_t* pcsum2 = buf+6;

    *pcsum2 = ~add16(

        add16(

            ~(*pcsum2),

            ~csum16(buf+4, 2)

        ),

        tip_sum2

    );

    //还原

    memcpy(buf+4, tip2, 4);

    printf("原始数据:%s\n", (char *)buf);

    printf("原始校验码:%X\n", csum16(buf, 16));    

}

运行结果如下:

IPv6的NAT原理是什么

把以上的原理套用在IPv6的NAT上,就是一种实现。

关于IPv6的NAT原理是什么问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI