lwip协议栈源码详解说明
  1、LWIP的结构
  lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的⼀个⼩型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占⽤。
  LWIP(Light weight internet protocol)的主要模块包括:配置模块、初始化模块、Ne TI f模块、mem(memp)模块、netarp模块、ip模块、udp模块、icmp 模块、igmp模块、dhcp模块、tcp模块、snmp模块等。下⾯主要对我们需要关⼼的协议处理进⾏说明和梳理。
  配置模块:
  配置模块通过各种宏定义的⽅式对系统、⼦模块进⾏了配置。⽐如,通过宏,配置了mem 管理模块的参数。该配置模块还通过宏,配置了协议栈所⽀持的协议簇,通过宏定制的⽅式,决定了⽀持那些协议。主要的⽂件是opt.h。
  初始化模块:
  初始化模块⼊⼝的⽂件为tcpip.c,其初始化⼊⼝函数为: void tcpip_init(void (* initfunc)(void *), void *arg)
  该⼊⼝通过调⽤lwip_init()函数,初始化了所有的⼦模块,并启动了协议栈管理进程。同时,该函数还带有回调钩⼦及其参数。可以在需要的地⽅进⾏调⽤。
  协议栈数据分发管理进程负责了输⼊报⽂的处理、超时处理、API函数以及回调的处理,原型如下:
  sta TI c void tcpip_thread(void *arg)
  Ne TI f模块:
  Ne TI f模块为协议栈与底层驱动的接⼝模块,其将底层的⼀个⽹⼝设备描述成协议栈的⼀个接⼝设备(net interface)。该模块的主要⽂件为netif.c。其通过链表的⽅式描述了系统中的所有⽹⼝设备。
  Netif的数据结构描述了⽹⼝的参数,包括IP地址、MAC地址、link状态、⽹⼝号、收发函数等等参数。⼀个⽹⼝设备的数据收发主要通过该结构进⾏。
  Mem(memp)模块:
  Mem模块同⼀管理了协议栈使⽤的内容缓冲区,并管理pbuf结构以及报⽂的字段处理。主要的⽂件包括mem.c、memp.c、pbuf.c。
  netarp模块:
  netarp模块是处理arp协议的模块,主要源⽂件为etharp.c。其主要⼊⼝函数为: err_t ethernet_input(struct pbuf *p, struct netif *netif)
  该⼊⼝函数通过判断输⼊报⽂p的协议类型来决定是按照arp协议进⾏处理还是将该报⽂提交到IP协议。如果报⽂是arp报⽂,该接⼝则调⽤etharp_arp_input,进⾏arp请求处理。
  如果是ip报⽂,该接⼝就调⽤etharp_ip_input进⾏arp更新,并调⽤ip_input接⼝,将报⽂提交给ip层。
  在该模块中,创建了设备的地址映射arp表,并提供地址映射关系查询接⼝。同时还提供了arp报⽂的发送接⼝。如下
  err_t etharp_output(struct netif *netif, struct pbuf *q, struct ip_addr *ipaddr)
  该接⼝需要注册到netif的output字段,ip层在输出报⽂时,通过该接⼝获取⽬标机的MAC地址,组合最终报⽂后,由该接⼝调⽤底层设备的驱动接⼝发送数据。
  在etharp_output接⼝中,判断报⽂类型,如果是⼴播包或者组播包,就调⽤
etharp_send_ip(组装⽬标mac和源mac)接⼝,etharp_send_ip调⽤netif结构中的设备驱动注册的lin
koutput钩⼦函数发送最终报⽂。如果是单播包,etharp_output接⼝就调⽤etharp_query 进⾏ip地址和MAC地址的映射,来获取到⽬标机的MAC地址。并在etharp_query中调⽤etharp_send_ip来发送最终组合报⽂。
  ip模块:
tcpip路由协议
  ip模块实现了协议的ip层处理,主要⽂件为ip.c。其主要⼊⼝函数为: err_t ip_input(struct pbuf *p, struct netif *inp)
  该接⼝通过判断输⼊报⽂的协议类型,将其输⼊到相应的上层协议模块中去。⽐如,将udp 报⽂送到udp_input。
  该模块另外⼀个接⼝是输⼊函数,原型如下:
  err_t ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, u8_t ttl, u8_t
  tos, u8_t proto)
  该接⼝通过路由表或者传输ip后,调⽤netif的output字段函数钩⼦发送报⽂。
  udp模块:
  udp模块实现了udp协议层的协议处理,主要⽂件为udp.c。该模块通过PCB控制块将应⽤端⼝跟应⽤程序做了绑定。在接收到新报⽂时,分析其对应的PCB,到对应的处理钩⼦,进⾏应⽤的处理。主要⼊⼝函数为:
  void udp_input(struct pbuf *p, struct netif *inp)该模块负责输出的接⼝如下:
  err_t udp_send(struct udp_pcb *pcb, struct pbuf *p)
  该模块负责将⼀个PCB跟⼀个本地端⼝进⾏绑定的接⼝如下:
  err_t udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)该模块负责将⼀个PCB跟⼀个远端端⼝绑定的接⼝如下:
  err_t udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
  igmp模块:
  igmp模块负责分组管理。其主要的接⼝函数如下:
  void igmp_input(struct pbuf *p, struct netif *inp, struct ip_addr *dest)该接⼝负责IGMP协议报⽂的处理,⽐如分析当前报⽂是请求还是应答。 err_t igmp_joingroup(struct
ip_addr *ifaddr, struct ip_addr *groupaddr)该接⼝将⼀个⽹⼝加⼊⼀个组。
  err_t igmp_leavegroup(struct ip_addr *ifaddr, struct ip_addr *groupaddr)该接⼝将⼀个⽹⼝从⼀个组中移出。
  dhcp模块:
  dhcp模块⽤于获取设备ip地址的相关信息。其处理⼊⼝主要有这么⼏个:dpch的启动、dpch的接收报⽂处理以及定时器模块的处理。
  主要的接⼝原型如下:
  err_t dhcp_start(struct netif *netif)
  该接⼝⽤于设备启动dhcp模块,主要是客户端的功能。该模块实现设备dhcp描述结构⽣成,并将dhcp的端⼝绑定到udp协议中,以及将本dhcp模块跟远端服务器端⼝进⾏绑定。最后启动dhcp申请。
  static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port)
  该接⼝为⼀个注册接⼝,⽤于dhcp报⽂接收。在start dhcp时,该接⼝通过dhcp的udp pcb

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。