ADSL接入及共享技术的实现(二)(4)

2025-04-26

int hlen                   /* IP 头的长度 */

)

返回值: 为 FALSE时表示报文处理正常,协议栈可继续转发或处理

为TRUE 时指示系统丢弃该报文

  由于无法找到协议栈输出报文的钩子,我们打算把输出报文 NAT 转换放在 _ipFilterHook 的 LAN 口钩子中处理,即在 LAN口报文进入协议栈之前就更改源IP和端口地址。但这样做的缺点是:此时系统还没有检索过该报文的路由目的接口,需要人为增加查找路由表算法,当发现是发往指定 WAN 口时再行转换,处理的效率较低。

  为充分利用协议栈的报文路由处理功能,决定采用更改协议栈代码的方式,在 ip_output 函数适当位置处人为增加一个钩子 _func_natOutput,重新编译 vxworks 协议栈库函数。 这样,NAT 模块初始化时即可将NAT输出报文处理函数绑定至该钩子。函数的输入输出关系格式如下:

int NatOutput

(

struct mbuf** m0,     /* 数据报文地址 */

struct ip **ip,       /* IP 头部地址 */

struct in_ifaddr* ia  /* 报文目的接口 */

)

返回值:  OK 或 ERROR (ERROR 时将丢弃并释放该报文)

 

7.3        NAT模块主要算法

7.3.1  NAT 端口地址转换HASH算法

NAPT 转换表查找算法可分为按端口查找和按地址查找两种。在实际的 ADSL接入环境中,局端很少会为一个连接分配多个 IP,因此我们采用按端口查找的算法来简单实现。

1) session 结构数组的初始化

  NAT初始化时根据系统支持的最大转换数目建立一个按端口分布的 nat_session结构数组(nat_session 节点的定义见7.2.1), 同时建立一个指向nat_session 的空 hash 表。Hash节点结构如下:

typedef struct nat_hash_bucket_

{

     struct nat_hash_bucket_ *next;    //指向下一个节点

     struct nat_hash_bucket_ *prev;    //指向前一个节点

     unsigned nat_session   *pSession; //指向nat链表中相应的节点

}nat_hash_bucket;

  2) 新建 session

  get_free_session 在session静态表(结构数组)中获得一个free session,并将其从Hash表中unlink出来。查找的依据为时间戳, 顺序遍历session表,直到找到第一个超时的session。若未找到,则覆盖当前指针指向的session。

  填充该 session 结构,返回该session 所对应的端口号。根据 TCP/UDP 报文的源 IP 和源端口号计算出 hash 头,增加到 hash 头所对应的链表后。其中,hash 头的算法如下:

LOCAL UINT16 ipnat_hash_fn(ipaddrtype addr1,

ipaddrtype addr2,

UINT16 port1,

UINT16 port2)

{

       UINT16 bucket;

      

       bucket = addr1 >> 16;

       bucket ^= addr1 & 0xffff;

       bucket ^= port1;

       bucket ^= addr2 >> 16;

       bucket ^= addr2 & 0xffff;

       bucket ^= port2;

       bucket = bucket % IPNAT_HASHLEN;

ADSL接入及共享技术的实现(二)(4).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:浅析如何加强局域网络信息安全的建设

相关阅读
本类排行
× 游客快捷下载通道(下载后可以自由复制和排版)

下载本文档需要支付 7

支付方式:

开通VIP包月会员 特价:29元/月

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信:xuecool-com QQ:370150219