fuq_dddd
驱动老牛
驱动老牛
  • 注册日期2002-10-15
  • 最后登录2009-10-09
  • 粉丝0
  • 关注0
  • 积分331分
  • 威望57点
  • 贡献值0点
  • 好评度28点
  • 原创分0分
  • 专家分0分
阅读:1920回复:5

RFC3022 中 NAT Checksum 的计算方法部分的翻译 与大家分享

楼主#
更多 发布于:2002-12-04 17:30
4. Packet Translations ―― 数据包传输

Packets pertaining to NAT managed sessions undergo translation in either direction.  Individual packet translation issues are covered in detail in the following sub-sections.
隶属于NAT的数据包进行双向传输。单个的数据包传输内容包括以下详细叙述的部分。

4.1. IP, TCP, UDP and ICMP Header Manipulations ―― 协议头处理

In Basic NAT model, the IP header of every packet must be modified.  This modification includes IP address (source IP address for outbound packets and destination IP address for inbound packets) and the IP checksum.
在基本NAT模式下,每个数据包的IP头必须修改。修改内容包括IP地址和IP校验。

For TCP ([TCP]) and UDP ([UDP]) sessions, modifications must include update of checksum in the TCP/UDP headers.  This is because TCP/UDP checksum also covers a pseudo header which contains the source and destination IP addresses.  As an exception, UDP headers with 0 checksum should not be modified.  As for ICMP Query packets ([ICMP]), no further changes in ICMP header are required, as the checksum in ICMP header does not cover IP addresses.
对于TCP和UDP,修改必须包括TCP/UDP头中校验的更新,这是因为TCP/UDP校验也包括一个虚假的头,这个头包括源、目的IP地址。一种例外情况是:UDP头的校验为0时,UDP头就不需要更改。对于ICMP查询数据包,包头没有更多的变化要求,以为ICMP数据包头中的校验不包括IP地址。

In NAPT model, modifications to IP header are similar to that of Basic NAT.  For TCP/UDP sessions, modifications must be extended to include translation of TU port (source TU port for outbound packets and destination TU port for inbound packets) in the TCP/UDP header.  ICMP header in ICMP Query packets must also be modified to replace the query ID and ICMP header checksum.  Private host query ID must be translated into assigned ID on the outbound and the exact reverse on the inbound.  ICMP header checksum must be corrected to account for Query ID translation.
在NAPT模式下,IP头的修改和基本NAT模式下相同。对于TCP/UDP,改动范围要进行扩展,包括TV端口(向外传送数据包的源TV端口和向内传送的目的TV端口)

4.2. Checksum Adjustment ―― 校验调整

NAT modifications are per packet based and can be very compute intensive, as they involve one or more checksum modifications in addition to simple field translations.  Luckily, we have an algorithm below, which makes checksum adjustment to IP, TCP, UDP and ICMP headers very simple and efficient.  Since all these headers use a one\'s complement sum, it is sufficient to calculate the arithmetic difference between the before-translation and after-translation addresses and add this to the checksum.  The algorithm below is applicable only for even offsets (i.e., optr below must be at an even offset from start of header) and even lengths (i.e., olen and nlen below must be even).  Sample code (in C) for this is as follows.
NAT修改是对每个包进行的,因为除了简单的数据域内容转换之外,他们还包含一个或多个校验修改。幸运的是,我们有以下的算法,用它来计算IP,TCP,UDP和ICMP头的校验非常简单有效。既然这些协议头用一个补充校验足以估计出转换前和转换后地址的不同,将补充校验写入相应的数据域。下面的算法只适用于偶数偏移和偶数长度。C代码如下:

void checksumadjust(unsigned char *chksum, unsigned char *optr, int olen, unsigned char *nptr, int nlen)
   /* assuming: unsigned char is 8 bits, long is 32 bits.
     - chksum points to the chksum in the packet
     - optr points to the old data in the packet
     - nptr points to the new data in the packet
   */
   {
     long x, old, new;
     x=chksum[0]*256+chksum[1];
     x=~x & 0xFFFF;
     while (olen)
     {
         old=optr[0]*256+optr[1]; optr+=2;
         x-=old & 0xffff;
         if (x<=0) { x--; x&=0xffff; }
         olen-=2;
     }
     while (nlen)
     {
         new=nptr[0]*256+nptr[1]; nptr+=2;
         x+=new & 0xffff;
         if (x & 0x10000) { x++; x&=0xffff; }
         nlen-=2;
     }
     x=~x & 0xFFFF;
     chksum[0]=x/256; chksum[1]=x & 0xff;
   }

4.6. IP option handling ―― IP选项处理

An IP datagram with any of the IP options Record Route, Strict Source Route or Loose Source Route would involve recording or using IP addresses of intermediate routers.  A NAT intermediate router may choose not to support these options or leave the addresses untranslated while processing the options.  The result of leaving the addresses untranslated would be that private addresses along the source route are exposed end to end.  This should not jeopardize the traversal path of the packet, per se, as each router is supposed to look at the next hop router only.
一个IP数据包(自带寻址信息的,独立地从数据源行走到终点的数据包),带有任意IP选项(路由记录、严格源路由/松散源路由),将记录或用中继路由的IP地址。一个NAT中继路由在处理选项时,可能不支持这些选项或对地址不进行转换,对地址不进行转换将导致源路由前私有地址首尾相连。这本身不会危害数据包的传输路径,因为每个路由假定只指向下一个路由。

翻译过程中,不是很严禁,有不确切的地方希望得到各位的指正。


另外,哪位同仁有奇数偏移和奇数长度Checksum的算法,给我发一份行吗?

现在兄弟传输数据加解密的算法已经调好了,只欠缺协议头的检验部分的代码;
mail:qiang.fu@mwcard.com

[编辑 -  8/8/03 by  fuq_dddd]

最新喜欢:

jzyhummeljzyhum... raphyerraphye...
星星之火 可以燎原 每一个光亮 都可能是黎明 [img]http://joke.tom.com/img/assets/1/gaoxiao_80_910.gif[/img]
edust
驱动中牛
驱动中牛
  • 注册日期2002-04-02
  • 最后登录2003-06-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-12-04 17:38
呵呵,俺也译过,也贴上来凑凑热闹:

4.0. 包转换:

   属于 NAT 所管理的会话的包将在任一方向上被转换。个别包转换的细节在以下
   子章节中会详细讨论。

4.1. IP,TCP,UDP 和 ICMP 首部的处理:

   在基本 NAT 模型中,每个包的 IP 首部都必须被修改。这个修改包括 IP 地址
   (外出包的原地址和进入包的目的地址)和 IP 校验和。

   对于 TCP 和 UDP 会话,修改还必须包括更新 TCP/UDP 首部中的校验和。这是
   因为 TCP/UDP 的校验和还覆盖了一个包括源/目的 IP 地址的“假头”。有个
   例外,那就是校验和为 0 的 UDP 首部无需修改。对于 ICMP 查询包,ICMP 首
   部也不需要做进一步修改,因为在 ICMP 首部中的校验和没有覆盖 IP 地址。

   在 NAPT 模型中,对 IP 首部的修改类似于基本 NAT。对于 TCP/UDP 会话,首
   部中的端口(外出包的源端口和进入包的目的端口)也必须被修改。ICMP 查询包
   中的 ICMP 首部也必须被修改以替换查询 ID 和 ICMP 首部校验和。内部主机
   的查询 ID 在外出时必须被转换为一个分配的 ID,在进入时还要做相反的转换。
   由于查询 ID 做了转换,所以 ICMP 首部校验和也要被纠正。

4.2. 校验和调整

   NAT 修改是基于每一个包的,因为除了简单的域转换外,包中的一个或多个校
   验和也要被修改,所以运算量是很大的。幸运的是我们有下面的这个算法,它
   可以对 IP,TCP,UDP 和 ICMP 首部做非常简单而且高效的校验和调整。由于
   这些首部都使用它们的补码和,所以计算转换之前和转换之后的地址的算数差
   值,然后把这个差值加到校验和里面就足够了。下面的算法仅适用于偶数的偏
   移量(也就是说,下面的 optr 必须是一个从首部的开始位置算起的偶数偏移
   量) 和偶数的长度 (也就是说,下面的 olen 和 nlen 必须是偶数)。这个算
   法的实例代码(用 C 编写)如下:

略……

4.6 IP 选项处理

   带有任何 IP 选项的 IP 报文(比如 Record Route,Strict Source Route,
   Loose Source Route)都会包含一个记录或者是使用中途路由器的 IP 地址。一
   个 NAT 中间路由器可以选择不支持这些选项或者在处理选项时不转换地址。不
   转换地址的结果就是使源路径暴露于端到端之间。这应该不会危害到包的传输
   路径,因为每个路由器只支持查找它的下一跳路由器。
mikeluo
驱动老牛
驱动老牛
  • 注册日期2001-09-04
  • 最后登录2007-05-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-12-05 09:12
学习一下:)
学而不思则罔,思而不学则殆 学而思之,思而学之,岂非圣人乎?
bingjie
驱动小牛
驱动小牛
  • 注册日期2001-08-15
  • 最后登录2007-11-29
  • 粉丝0
  • 关注0
  • 积分36分
  • 威望5点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-12-05 09:27
下面是我用来计算IP包头校验和的函数,实际上也可以计算任意buffer,任意字节的校验和

// 计算IP包头校验和
USHORT
CalculateIPHeaderCheckSum(
IN OUT LPBYTE IpHeader,
IN USHORT IpHeaderSize
)
{
unsigned long sum = 0;
unsigned short n, chksum;
int i;

if ( IpHeaderSize < 20 )
return 0;

IpHeader[10] = 0xFF;
IpHeader[11] = 0xFF;

for ( i = 0; i < IpHeaderSize / 2; i++ )
{
n = IpHeader[i*2];
n <<= 8;
n += IpHeader[i*2+1];
sum += n;
}

if ( i * 2 < IpHeaderSize )
{
n = IpHeader[i*2];
sum += n;
}

while( sum >= 0x10000L )
sum = ( sum & 0xffffL ) + ( ( sum & 0xffff0000L ) >> 16 );

chksum = (unsigned short)( ~sum & 0xffffL );

          // 小端到大端转换
WORD_TO_BYTES( chksum, IpHeader + 10 );

return chksum;
}
activei
驱动牛犊
驱动牛犊
  • 注册日期2002-11-12
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-12-05 10:00
路在脚下
fuq_dddd
驱动老牛
驱动老牛
  • 注册日期2002-10-15
  • 最后登录2009-10-09
  • 粉丝0
  • 关注0
  • 积分331分
  • 威望57点
  • 贡献值0点
  • 好评度28点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-12-05 10:09
自己翻译一遍,印象深刻。

星星之火 可以燎原 每一个光亮 都可能是黎明 [img]http://joke.tom.com/img/assets/1/gaoxiao_80_910.gif[/img]
游客

返回顶部