4G杂项:lwip_nat机制简述(以8910平台为例)

目录

🍅点击这里查看所有博文

  随着自己工作的进行,接触到的技术栈也越来越多。给我一个很直观的感受就是,某一项技术/经验在刚开始接触的时候都记得很清楚。往往过了几个月都会忘记的差不多了,只有经常会用到的东西才有可能真正记下来。存在很多在特殊情况下有一点用处的技巧,用的不多的技巧可能一个星期就忘了。

  想了很久想通过一些手段把这些事情记录下来。也尝试过在书上记笔记,这也只是一时的,书不在手边的时候那些笔记就和没记一样,不是很方便。

  很多时候我们遇到了问题,一般情况下都是选择在搜索引擎检索相关内容,这样来的也更快一点,除非真的找不到才会去选择翻书。后来就想到了写博客,博客作为自己的一个笔记平台倒是挺合适的。随时可以查阅,不用随身携带。

  同时由于写博客是对外的,既然是对外的就不能随便写,任何人都可以看到。经验对于我来说那就只是经验而已,公布出来说不一定我的一些经验可以帮助到其他的人。遇到和我相同问题时可以少走一些弯路。

  既然决定了要写博客,那就只能认真去写。不管写的好不好,尽力就行。千里之行始于足下,一步一个脚印,慢慢来 ,写的多了慢慢也会变好的。权当是记录自己的成长的一个过程,等到以后再往回看时,就会发现自己以前原来这么菜😂。

  本系列博客所述资料均来自互联网,并不是本人原创(只有博客是自己写的)。出于热心,本人将自己的所学笔记整理并推出相对应的使用教程,方面其他人学习。为国内的物联网事业发展尽自己的一份绵薄之力,没有为自己谋取私利的想法。若出现侵权现象,请告知本人,本人会立即停止更新,并删除相应的文章和代码。

简介

  该记录基于RDA8910平台,主要记录NAT技术的使用。
在这里插入图片描述

步骤

1. 初始化

在这里插入图片描述

  1. 我们模块开启了自动注册功能,在net_thread中的CFW_NwSetFTA(0, 0); CFW_NwSetAutoAttachFlag(1, 0);就是开启自动注册,成功注册上网后,底层会上报EV_TCPIP_CFW_GPRS_ACT的消息。
  2. TCPIP_nat_wan_netif_create中主要做的是建立nat_wan的netif。获取PDP的主要信息用来绑定L2的接口。设置下行数据的回调函数lwip_nat_wan_pspathDataInput
  3. prvNdevLanSessionCreate
    1. 创建nat_lan网卡的netif(见名词解释),其中绑定了固定的IP地址和网关地址。
    2. 创建ndev_nat_entry,主要用于IP层的nat转换。在发送和接收的时候有大作用。
    3. 创建网卡上下文,该上下文作为USB网卡与模块之间的耦合层。用于USB设备与模块之间的数据通信。
  4. prvEthLanUploadDataCB 设置的设备端上行数据的回调函数。

2. 从设备端收到数据

在这里插入图片描述

  1. 这里为什么要先介绍上行数据(也就是模块收到网卡的数据将数据发送给网络端)

    因为所有的链接都是由客户端先发起链接。

  2. usb收到数据后会通过其注册的event_cb回调函数调用相应event的处理函数,当收到数据的时候就会调用_usbeRxWork(注意该函数的处理是放在task里面处理的),_usbeRxWork又会调用创建网卡时设置的回调prvEthLanUploadDataCB函数。

    因为模块采用的是固定的IP分配,所以ARP还有DHCP都是固定的回复。这里注意一般设备都会先发DHCP包(动态主机配置协议)获取到IP地址,网关地址,再发ARP包(地址解析协议)获取网关和MAC地址的映射关系。

    如果不是这两个包,就会进入prvNdevLanDataToPs

  3. prvNdevLanDataToPs从名字就可以看出主要作用就是将数据传到L2层。这里会申请一个pbuf,并判断包的类型,如果是PIV6就直接发出去,如果是IP包就需要进行NAT转换。

  4. ip4_nat_out的主要作用就是进行NAT转换。

    1. 获取nat配置信息,根据IP报头的源ip地址和目的地址在nat配置表中查找。该项是在LAN网卡创建的时候(ndev_nat_entry)添加到表中的。
    2. 判断IP包中协议字段,进行相应的处理(这里只拿TCP举例)
    3. 获取到TCP首部,进行源地址,目的地址,源端口,目的端口的比较,如果存在就返回ip4_nat_entries_tcp_t结构体,如果不存在就创建相应的映射关系。并添加到ip4_nat_tcp_table表中。NAT表需要定时刷新,所以有个TTL字段(见名词解释),将IP
      包的源地址用WAN口替换,端口使用NAT映射后的端口地址。
  5. IP包和TCP报头重新计算校验后,在通过绑定的WAN口发送到L2层。

3. 从网络端收到数据

在这里插入图片描述

  1. 初始化的时候第一步绑定了L2层下行数据的回调函数。当外网数据过来的时候通过gprs_data_ipc_to_lwip_nat_wan传入协议栈。参数是与PS绑定的netif。新建pbuf,将pbuf传给ip4_nat_input
  2. ip4_nat_input就是进行IP地址转换,转为LAN的IP地址。判断相应的IP协议,将端口和IP地址进行转换,重新校验。再传入NAT_LAN的netif绑定的input函数。wan_to_netdev_lan_datainput发送给网卡设备

名词解释

1. 网卡

代码中表示网卡的结构体就是netif,每个设备要上网都需要一个或者多个网卡。多个网卡就会组成一个局域网,通常一个局域网都需要一个WAN,其它的设备可以称为LAN。WAN口连接着外部网络,连接LAN口的设备与外部网络通信都需要经过WAN口传输。

2. pbuf

协议栈中L2层以上所有的数据交替都使用同一个结构体就是pbuf,pbuf是个链表,该链表的大小是根据pbuf_alloc时传入的长度计算的。该结构体主要是:

/** Main packet buffer struct */
struct pbuf {
  struct pbuf *next; /*指向下一个pbuf*/
  /*该段pbuf的数据部分*/
  void *payload;
  /*该链表所有pbuf数据部分的总长度*/
  u16_t tot_len;
  /*改段pbuf的数据大小*/
  u16_t len;

  /** a bit field indicating pbuf type and allocation sources
      (see PBUF_TYPE_FLAG_*, PBUF_ALLOC_FLAG_* and PBUF_TYPE_ALLOC_SRC_MASK)
    */
  u8_t type_internal;

  /** misc flags */
  u8_t flags;

  /**
   该pbuf被引用次数,如果引用次数大于1,pbuf_free的时候就会出错
   */
  LWIP_PBUF_REF_T ref;
  /** For incoming packets, this contains the input netif's index */
  u8_t if_idx;
};
  1. TTL(NAT表项保活时间)

初始化nat的时候会创建一个循环定时器nat_timer,每隔LWIP_NAT_TMR_INTERVAL_SEC秒处理一下NAT表项,即将TTL减去30秒,如果TTL小于30秒就清除映射关系。默认TTL的值LWIP_NAT_DEFAULT_TCP_SOURCE_PORT为10分钟。每次发送的时候都会进行重置。

NAT的优缺点

优点

NAT最大的优点就是节省了大量的IP资源

缺点

问题

  1. 什么是NAT,有什么作用?
  2. 一个设备需要具备哪些最基本的配置?
  3. 为什么NAT转发的时候还需要进行端口转换,为什么不能直接使用源端口号?
  4. 什么是内网穿透?

  那么本篇博客就到此结束了,这里只是记录了一些我个人的学习笔记,其中存在大量我自己的理解。文中所述不一定是完全正确的,可能有的地方我自己也理解错了。如果有些错的地方,欢迎大家批评指正。如有问题直接在对应的博客评论区指出即可,不需要私聊我。我们交流的内容留下来也有助于其他人查看,说不一定也有其他人遇到了同样的问题呢😂。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
LWIP_DEBUGF是一个宏定义,用于在lwIP协议栈中输出调试信息。它的定义如下: ```c #define LWIP_DEBUGF(debug, message) \ do { \ if ((debug) && (lwip_debug)) { \ LWIP_PLATFORM_DIAG((_U32)"lwIP: ", message); \ } \ } while (0) ``` 其中,debug是一个表示调试级别的参数,message则是要输出的调试信息。在使用LWIP_DEBUGF输出调试信息时,需要先定义LWIP_DEBUG宏来开启调试功能,并设置输出级别。在lwipopts.h文件中,可以找到如下代码: ```c #define LWIP_DEBUG 0 ``` 将LWIP_DEBUG的值设置为1,即可开启调试功能。同时,还需要根据需要设置输出级别,可以在lwipopts.h文件中找到类似如下代码: ```c #define ETHARP_DEBUG LWIP_DBG_OFF #define NETIF_DEBUG LWIP_DBG_ON #define PBUF_DEBUG LWIP_DBG_OFF #define API_LIB_DEBUG LWIP_DBG_OFF #define API_MSG_DEBUG LWIP_DBG_OFF #define SOCKETS_DEBUG LWIP_DBG_OFF #define ICMP_DEBUG LWIP_DBG_OFF #define IGMP_DEBUG LWIP_DBG_OFF #define INET_DEBUG LWIP_DBG_OFF #define IP_DEBUG LWIP_DBG_OFF #define IP_REASS_DEBUG LWIP_DBG_OFF #define RAW_DEBUG LWIP_DBG_OFF #define MEM_DEBUG LWIP_DBG_OFF #define MEMP_DEBUG LWIP_DBG_OFF #define SYS_DEBUG LWIP_DBG_OFF #define TCP_DEBUG LWIP_DBG_OFF #define TCP_INPUT_DEBUG LWIP_DBG_OFF #define TCP_FR_DEBUG LWIP_DBG_OFF #define TCP_RTO_DEBUG LWIP_DBG_OFF #define TCP_CWND_DEBUG LWIP_DBG_OFF #define TCP_WND_DEBUG LWIP_DBG_OFF #define TCP_OUTPUT_DEBUG LWIP_DBG_OFF #define TCP_RST_DEBUG LWIP_DBG_OFF #define TCP_QLEN_DEBUG LWIP_DBG_OFF #define UDP_DEBUG LWIP_DBG_OFF #define TCPIP_DEBUG LWIP_DBG_OFF #define SLIP_DEBUG LWIP_DBG_OFF #define DHCP_DEBUG LWIP_DBG_OFF #define AUTOIP_DEBUG LWIP_DBG_OFF #define DNS_DEBUG LWIP_DBG_OFF #define IP6_DEBUG LWIP_DBG_OFF #define DHCP6_DEBUG LWIP_DBG_OFF #define MLD6_DEBUG LWIP_DBG_OFF #define ICMP6_DEBUG LWIP_DBG_OFF #define ND6_DEBUG LWIP_DBG_OFF #define UDP6_DEBUG LWIP_DBG_OFF #define TCP6_DEBUG LWIP_DBG_OFF ``` 其中,每个宏定义了一个调试输出级别,可以根据需要将其设置为LWIP_DBG_ON、LWIP_DBG_OFF或LWIP_DBG_TRACE。例如,将IP_DEBUG的值设置为LWIP_DBG_ON,则可以开启IP协议相关的调试输出。在需要输出调试信息的地方,可以使用LWIP_DEBUGF宏来输出信息。例如: ```c LWIP_DEBUGF(IP_DEBUG, ("Received packet of length %d\n", p->tot_len)); ``` 这条语句将输出一个类似于“lwIP: Received packet of length 128”这样的调试信息,其中128是p->tot_len的值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值