---《计算机网络与控制》论文LWIP协议栈的分析摘要近些年来,随着互联网和通讯技术的迅猛发展,除了计算机之外,大量的嵌入式设备也需求接入网络。
目前,互联网中使用的通讯协议基本是TCP/IP协议族,可运行于不同的网络上,本文研究的就是嵌入式TCP/IP协议栈LWIP。
文章首先分析了LWIP的整体结构和协议栈的实现,再介绍协议栈的内存管理,最后讲解协议栈应用程序接口。
关键词: 嵌入式系统;协议;LWIP;以太网AbstractWith the rapid development of internet and communication technology, Not only computers but also embeded equipments are need to connect networks. At present, the basic communication protocol using in internet is TCP/IP, it can run in different network. This paper analyses the Light-Weight TCP/IP. The process model of a protocol implementation and processing of every layer are described first, and then gives the detailed management of Buffer and memory. At last, a reference lwIP API is given.Key words: Embedded System, Protocol, Light weight TCP/IP,Ethernet引言近期互联网络硬件、软件的迅猛发展,使得网络用户呈指数增长,在使用计算机进行网络互联的同时,各种家电设备、仪器仪表以及工业生产中的数据采集与控制设备在逐步地走向网络化,以便共享网络中庞大的信息资源。
在电子设备日趋网络化的背景下,引人TCP/IP 协议栈,以支持嵌人式设备接人网络,成为嵌人式领域重要的研究方向。
本文分析一个轻量级的嵌入式系统的TCP/IP 协议栈-LWIP,LWIP是一个比较完整和可靠的TCP/IP协议栈,具有开源,易用,系统资源要求不高等优点。
一、LWIP概览LWIP是瑞典计算机科学院(Swedish Institute of Computer Science)开发的一套用于嵌入式系统的开放源代码TCP/IP协议栈。
LWIP的含义是Light Weight(轻型)IP协议。
LWIP TCP/IP实现的重点是在保持TCP协议主要功能的基础上减少处理和内存需求,因为LWIP使用无顺数据复制并经裁剪的API,一般它只需要几十KB的RAM和40KB左右的ROM就可以运行。
同时LWIP可以移植到操作系统上,也可以在无操作系统的情况下独立运行。
这使LWIP协议栈适合在低端嵌入式系统中使用。
LWIP的特性如下:1.支持多网络接口下的IP转发;2.支持ICMP协议;3.支持主机和路由器进行多播的Internet组管理协议(IGMP);4.包括实验性扩展的UDP(用户数据报协议);5.包括阻塞控制,RTT估算和快速恢复和快速转发的TCP;6.提供专门的内部回调接口(raw API)用;7.支持DNS;8.支持SNMP;9.支持PPP;10.支持ARP;11.IP fragment的支持;12.支持DHCP协议,动态分配IP地址;13.可选择的Berkeley接口API(多线程情况下);LWIP的源代码从作者Adam Dunkels的官方网站上下载(网址为:www.sics.se/~adam/lwip/),版本号为1.3.1。
以下为解压后的目录结构。
LWIP的目录结构主要分为五个部分:1.Api\ : 应用程序接口文件,包括RAW,BSD以及正式提供的3种API。
2.Arch\ :与硬件和OS有关的文件,包括网络驱动,移植需要修改的文件。
3.Core\ :ICMP,IP,TCP,UDP协议的实现文件,以及一些辅助函数,LWIP实现的核心代码。
4.Include\ :LWIP的包括文件。
if\ :ARP协议和LWIP网络设备驱动程序的模板,用户为自己的网络接口设计的驱动程序应该与ethernetif.c中给出的驱动框架相同。
二、LwIP 的整体构架和进程模型:传统的TCP/IP协议栈的实现方法严格分层,一般每一层都是一个独立的进程。
这样方法虽然有利于协议栈的调试,但是,其最大的弊端为数据包跨层传递时会引起频繁的上下文的切换,尤其是在多任务系统中,这样导致时间的浪费而直接影响到系统的实时性。
LWIP 将所有TCP/IP 协议都放在在一个进程当中,这样TCP/IP 协议栈就和操作系统内核分开了。
而应用层程序既可以是单独的进程也可以驻留在TCP/IP 进程中。
如果应用程序是单独的进程,可以通过操作系统的邮箱、消息队列等通讯机制和 TCP/IP 进程进行通讯。
如果应用层程序驻留在 TCP/IP 程中,那应用层程序就利用内部回调函数接口(Raw API)和 TCP/IP 协议栈通讯。
LWIP进程模式的主要优点是可以很方便的移植到各种操作系统上去,进行应用程序的开发。
图2 - 1 LWIP的进程模型LwIP 的进程模型如图2-1。
在图2-1 中可以看到整个 TCP/IP 协议栈都在同一个名为“tcpip_thread”任务中,而位于图中最上方的“Application layer”(应用层)和下方的“Network interface layer”(网络接口驱动层)由用户自己来实现。
应用层程序既可以是独立的任务(如图中正上方的“tftp_thread”和“tcpecho_thread”),通过 mbox(消息队列)和 LWIP 进程通讯;也可以在“tcpip_thread”(如图左上角)中利用原始接口(Raw API)和 TCP/IP协议栈通讯。
LWIP的数据流程主要分为接收和发送两种情况。
●接收数据时:数据包从一个网络接口被接收,如果网络接口驱动通过low_level_input函数读到这个数据包,简单的区分是ARP包还是IP包。
如果是ARP包,将调用ARP的功能处理这个包。
通常将更新一个ARP地址映射表,然后将数据包发送给IP_input函数处理。
如是查一个IP包,将把数据包发送给ip_input函数处理。
IP_input函数将数据包进行简单的处理(如计算校验和)后,分析该包是发送到本机的正常数据包,IP_input则根据包的类型,分别发送给udp_input、tcp_input、icmp_input函数处理。
如果是发送给UDP或TCP协议的数据包,UDP、TCP协议的处理函数将做相应的处理,最后发送给应用程序。
●发送数据流程:当应用程序需要发送一个数据包的时候,它将调用UDP和TCP协议处理函数udp_sender或tcp_write函数发送该数据包。
UDP和TCP协议的处理函数接收数据后,将数据打包、分段,然后发送给IP层ip_output_if函数(需要时,将调用ip_route函数进行路由选择),该函数把数据打包、封装,然后调用网络接口驱动的low_level_output函数传给网络接口。
三、LWIP协议栈的实现3.1 网络接口LwIP使用一个与BSD中相似的网络接口结构来表示底层网络驱动,结构体的原型定义如下所示。
struct netif {struct netif *next;char name[2];int num;struct ip_addr ip_addr;struct ip_addr netmask;struct ip_addr gw;void (* input)(struct pbuf *p, struct netif *inp);int (* output)(struct netif *netif, struct pbuf *p,struct ip_addr *ipaddr);void *state;}next指针用于将网络接口链入到全局链表中。
Name域用于表示网络接口的类型,只用于这个接口在运行时由人工操作进行配置。
Name由设备驱动设置并且应该反映硬件的种类。
num用来区分相同类别的不同网络接口。
三个IP 地址ip_addr,netmask与gw分别用来表示IP地址,子网掩码,网关。
State表示设备驱动所包含的网络接口状态,由设备驱动设置。
当设备驱动接受到一个信息包的时候需要调用input指向的函数。
而网络接口通过output指针与设备驱动连接。
这个指针指向处于设备驱动中的发送信息包的函数,这个函数将在一个信息包发送出去后,被IP层调用。
指针output将在设备驱动初始化的时候赋值。
3.2 IP处理LwIP仅实现了IP层大部分的基本功能,能够发送、接收以及转发信息包,但是不能接收和发送 IP分片包,也不能处理携带 IP参数选项的信息包。
不过对大多数的应用来说,这不会引起任何问题。
●接收信息包收到的IP信息包,由网络设备驱动调用ip_input()函数开始处理。
在这里完成对IP版本字段及包头长度的初始完整性检查,同时还要计算和验证包头校验和。
协议栈假定代理会重新组合IP分片包为一个完整的包。
接下来,函数检查目的地址是否与网络接口的IP地址相符以确定信息包是否到达预定主机。
网络接口在链表中被排序并且采用了线性检索。
如果一个到达的信息包被发现已经到达了目的主机,则由协议字段来决定信息包应该传送到哪一个上层协议。
●发送信息包外发的信息包由ip_output()函数处理,该函数使用ip_route()函数查找适当的网络接口来传送信息包。
当外发的网络接口确定后,信息包传给以外发网络接口为参数的ip_output_if()函数。
在这里,所有的IP包头字段被填充,并且计算 IP包头校验和。
IP信息包的源及目标地址作为参数被传递给ip_output_if()函数。
●转发信息包如果没有网络接口的地址与到达的信息包的目标地址相同,信息包应该被转发。
这项工作由ip_forward()函数完成。
在这里,TTL字段值被减少(Time To Live的简写,生存时间的意思,译者注),当减为0 的时候,将会给IP 信息包的最初发送者发送ICMP错误信息,并抛弃该信息包。
最后,信息包被转发到适当的网络接口。
查找适当的网络接口的算法与发送信息包使用的算法相同。
●ICMP处理网际控制报文协议ICMP(Intemet Control Message Protoc01)总是与IP协议配置在一起,它运行在IP协议之上,发送一些控制信息,帮助Intemet处理差错。