LWIP 协议栈解析(1)

时间:2021-12-04 16:21:20

lwip 源文件结构分析

 

inlcude: 各源文件对应的头文件。

api:提供上层应用api接口源文件,包括有socket接口,netifapi接口的实现机制。

core:包含ip层和传输层协议,如ip,tcp,udp,dns,dhcp等。

netif:网络接口层,包括与底层驱动的接口,防火墙,ppp等。

 

为实现lwip移植,按lwip文档说明,我这添加了一个

arch:文件目录,里面包括lwip所需资源的实现,如邮箱,信号量,任务,超时机制等。

另外我添加了一个

app_lwip: 里面为lwip的一些应用和测试程序。

 

 

///看一下lwip的配置选项文件:include/lwip/opt.h

首先需要来了解的是lwip中的几个重要数据结构:

1. netif  // 描述一个网络设备,即通常所说的网卡

struct netif {
  /** pointer to next in linked list */
  struct netif *next;

  /** IP address configuration in network byte order */
  struct ip_addr ip_addr;
  struct ip_addr netmask;
  struct ip_addr gw;

  /** This function is called by the network device driver to pass a packet up the TCP/IP stack. */
  err_t (* input)(struct pbuf *p, struct netif *inp);   //接收到一个ip包后传递给上层进行 tcp_ip 处理
  /** This function is called by the IP module when it wants to send a packet on the interface. This function typically
   *  first resolves the hardware address, then sends the packet. */
  err_t (* output)(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr);//发送数据时,ip层调用它发送一个ip包
  /** This function is called by the ARP module when it wants to send a packet on the interface. This function outputs
   *  the pbuf as-is on the link medium. */
  err_t (* linkoutput)(struct netif *netif, struct pbuf *p); //被用于arp发送一个数据包到网络,比方说ping命令
  /** This field can be set by the device driver and could point to state information for the device. */
  void *state;          //设备信息,比方说 MAC地址等
#if LWIP_DHCP
  /** the DHCP client state information for this netif */
  struct dhcp *dhcp;
#endif
  /** number of bytes used in hwaddr */
  u8_t hwaddr_len; 
  /** link level hardware address of this interface */
  u8_t hwaddr[NETIF_MAX_HWADDR_LEN];
  /** maximum transfer unit (in bytes) */
  u16_t mtu;        //???
  /** flags (see NETIF_FLAG_ above) */
  u8_t flags;
  /** link type */
  u8_t link_type; //???
  /** descriptive abbreviation */
  char name[2];
  /** number of this interface */
  u8_t num;
};
即说到这里,就来先看下 netif.c

里面实现有网卡的一些基本操作函数,添加,删除,查找,参数设置,状态转换等。

其通过一个  struct netif *netif_list ,全局变量指向最新加入的netif实现了一个单向链表,方便,并且资源利用小.

 

2.  pbuf   lwip中数据接受存储传递数据结构

struct pbuf {
  /** next pbuf in singly linked pbuf chain */
  struct pbuf *next;

  /** pointer to the actual data in the buffer */
  void *payload;
 
  /**
   * total length of this buffer and all next buffers in chain belonging to the same packet.
   * For non-queue packet chains this is the invariant:
   * p->tot_len == p->len + (p->next? p->next->tot_len: 0)
   */
  u16_t tot_len;
 
  /** length of this buffer */
  u16_t len; 

  /** flags telling the type of pbuf, see PBUF_FLAG_ */
  u16_t flags;
 
  /**
   * the reference count always equals the number of pointers
   * that refer to this pbuf. This can be pointers from an application,
   * the stack itself, or pbuf->next pointers from a chain.
   */
  u16_t ref;
};

在pbuf.c 中  static u8_t pbuf_pool_memory[MEM_ALIGNMENT - 1 + PBUF_POOL_SIZE * MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE + sizeof(struct pbuf))];定义了pool类型的pbuf缓存区。

 

在mem.c中   static u8_t ram[MEM_SIZE + sizeof(struct mem) + MEM_ALIGNMENT];定义了ram类型的pbuf缓存区,搞死了,这个文件真难理解,看了一个下午。

 

在memp.c中,包括了各数据结构的的内存分配,如,pbuf. raw_pcb, udp_pcb, tcp_pcb, tcp_pcb_listen, tcp_seg, netbuf, netconn, api_msg, tcpip_msg, sys_timeout.