从本文开始来学习一下lwip这款协议栈,主要参考资料为朱升林的《嵌入式网络那些事儿》
LwIP是TCP/IP协议中一种独立、简单的实现,其设计目的在于:在保证嵌入式产品拥有完整TCP/IP功能的同时,又能保证协议栈对处理器资源的有嫌消耗,其运行一般仅需要几十kB的RAM和40kb的ROM。LwIP有很多版本,我们使用的是1.4.1版本。
源代码结构
源代码src包括下面几个文件夹:
api:包含了sequential API和socket api两类接口函数及实现相关的代码,需要操作系统的支持
core:lwip的内核源码,可以在裸机上运行,不用操作系统
include:协议栈的头文件
netif:与底层网络接口相关的文件
再来详细看看每个文件夹下的内容,netif文件夹下:
ppp文件夹:包含了ppp协议实现的源代码
etharp.c:ARP协议实现的相关函数
ethnetif.c:文件包含了与以太网密切相关的初始化、发送、接收函数的实现。lwip裸机的移植基本上都在这个文件中实现。
slipif.c:串行链路IP
core文件夹是协议栈的重点,包含了多个核心协议以及上层应用协议
ipv4文件夹:IPv4标准中与IP层数据包处理相关的代码。
ipv6文件夹:IPv6标准中与IP层数据包处理相关的代码。
snmp:与snmp协议实现相关的代码文件
def.c:包含了IP层使用到的一些功能函数的定义,例如IP地址的转换、网络字节序与主机字节序转换等。
dhcp.c:实现DHCP客户端的代码。
dns.c:DNS客户端的代码
init.c:包含了一个与LWIP协议栈初始化密切相关的函数
mem.c:协议栈内存堆管理函数的实现。
memp.c:包含了协议栈内存池管理函数的实现。
LWIP使用上述两种特有的内存管理方式来实现协议栈内存的有效管理。
netif.c:包含了协议栈网络接口管理的相关函数,协议栈支持多个网络接口,例如前面所说的以太网接口。SLIP接口。有几个接口,就需要几个netif的数据结构来进行描述。有的硬件可以带多个以太网接口,我们就需要创建多个netif接口来描述。
pbuf.c:包含了协议栈内核使用的数据包管理函数,采用特殊的数据包pbuf结构,可以避免数据在各个层次之间递交时的拷贝,这既提高了数据递交效率,也节省了内存空间。
raw.c:为应用层提供了一种直接和IP数据包交互的方式。类似于socket编程中原始套接字的概念。
status:包含了协议栈内部数据统计与显示的相关函数,如内存使用情况、邮箱、信号量等信息。
tcp.c:包含了对TCP控制块操作的函数,也包括了TCP定时处理函数
tcp_in.c:包含TCP协议中数据接收、处理相关函数,最重要的TCP状态机函数也在这个文件当中。
tcp_out.c:TCP协议中数据发送相关函数
udp.c:UDP协议的相关函数。
sys.c:文件实现一个简单的函数sys_sleep,该函数主要在PPP中使用,只有在有操作系统的情况下才会使用该文件。
timer.c:统一完成了对内核各个协议定时事件处理函数的封装,同时对各个注册的定时事件进行处理。有无操作系统会采用不同的机制。
再来看看ipv4文件夹下的文件,
autoip.c:ip地址自动配置相关的函数,若主机从DHCP服务器处获取IP地址失败,则主机可以选择启动AUTOIP功能来配置自身的IP地址。
icmp.c:包含了ICMP协议实现的相关函数,ICMP协议为IP数据包传递过程中的差错报文、差错纠正以及目的地址可达性测试提供了支持。常见的ping命令就属于ICMP应用的一种
igmp.c:包含了网络组管理协议IGMP的实现,IGMP为网络中的多播数据传输提供了支持。
inet_chksum.c:文件包含了同IP数据校验相关的函数
ip.c:包含了ipv4协议实现的相关函数,如数据包的接收、递交、发送等等。
ip_addr.c:实现几个比较简单的IP地址处理函数,如IP地址是否为广播地址,以及32位IP地址与点分十进制间的转换函数。
ip_frag.c:提供了IP层数据包分片与重组相关的函数。
再来看看api文件夹下的内容:在raw.c中提供给用户一种和内核直接交互编程的方式,除此之外呢,还提供了两种上层API接口,一种叫sequential API,另一种是更常见的socket编程。这两种编程都需要操作系统的支持,所以都需要先完成将协议栈移植到操作系统上。
api_lib.c:预留给用户的编程接口
api_msg.c:API消息的封装与处理函数
netbuf.c:上层数据包管理函数的实现
netdb.c:与主机名字转换相关的函数,主要在socket中被使用
netifapi.c:包含了上层网络接口管理函数的实现
socket.c:包含了socket API函数的实现
tcpip.c:提供了上层API与协议栈内核交互的函数
include文件夹下:
最重要的是opt.h,它包含了所有lwip内核参数的默认配置项;
init.h:包含了与当前lwip源代码信息相关的宏定义。