Login
升级VIP 登录 注册 安全退出
当前位置: 首页 > word文档 > 合同模板 > lwip各层协议栈详解,lwip协议栈源码详解

lwip各层协议栈详解,lwip协议栈源码详解

收藏

本作品内容为lwip各层协议栈详解,格式为 docx ,大小 40145 KB ,页数为 32页

lwip各层协议栈详解


('第1页共32页竭诚为您提供优质文档/双击可除lwip各层协议栈详解篇一:lwip协议栈源码分析lwip源码分析-----caoxw1lwip的结构lwip(lightweightinternetprotocol)的主要模块包括:配置模块、初始化模块、netif模块、mem(memp)模块、netarp模块、ip模块、udp模块、icmp模块、igmp模块、dhcp模块、tcp模块、snmp模块等。下面主要对我们需要关心的协议处理进行说明和梳理。配置模块:第2页共32页配置模块通过各种宏定义的方式对系统、子模块进行了配置。比如,通过宏,配置了mem管理模块的参数。该配置模块还通过宏,配置了协议栈所支持的协议簇,通过宏定制的方式,决定了支持那些协议。主要的文件是opt.h。初始化模块:初始化模块入口的文件为tcpip.c,其初始化入口函数为:voidtcpip_init(void(initfunc)(void),voidarg)该入口通过调用lwip_init()函数,初始化了所有的子模块,并启动了协议栈管理进程。同时,该函数还带有回调钩子及其参数。可以在需要的地方进行调用。协议栈数据分发管理进程负责了输入报文的处理、超时处理、api函数以及回调的处理,原型如下:staticvoidtcpip_thread(voidarg)netif模块:第3页共32页netif模块为协议栈与底层驱动的接口模块,其将底层的一个网口设备描述成协议栈的一个接口设备(netinterface)。该模块的主要文件为netif.c。其通过链表的方式描述了系统中的所有网口设备。netif的数据结构描述了网口的参数,包括ip地址、mac地址、link状态、网口号、收发函数等等参数。一个网口设备的数据收发主要通过该结构进行。mem(memp)模块:mem模块同一管理了协议栈使用的内容缓冲区,并管理pbuf结构以及报文的字段处理。主要的文件包括mem.c、memp.c、pbuf.c。netarp模块:netarp模块是处理arp协议的模块,主要源文件为etharp.c。其主要入口函数为:err_tethernet_input(structpbufp,structnetifnetif)第4页共32页该入口函数通过判断输入报文p的协议类型来决定是按照arp协议进行处理还是将该报文提交到ip协议。如果报文是arp报文,该接口则调用etharp_arp_input,进行arp请求处理。如果是ip报文,该接口就调用etharp_ip_input进行arp更新,并调用ip_input接口,将报文提交给ip层。在该模块中,创建了设备的地址映射arp表,并提供地址映射关系查询接口。同时还提供了arp报文的发送接口。如下:err_tetharp_output(structnetifnetif,structpbufq,structip_addripaddr)该接口需要注册到netif的output字段,ip层在输出报文时,通过该接口获取目标机的mac地址,组合最终报文后,由该接口调用底层设备的驱动接口发送数据。第5页共32页在etharp_output接口中,判断报文类型,如果是广播包或者组播包,就调用etharp_send_ip(组装目标mac和源mac)接口,etharp_send_ip调用netif结构中的设备驱动注册的linkoutput钩子函数发送最终报文。如果是单播包,etharp_output接口就调用etharp_query进行ip地址和mac地址的映射,来获取到目标机的mac地址。并在etharp_query中调用etharp_send_ip来发送最终组合报文。ip模块:ip模块实现了协议的ip层处理,主要文件为ip.c。其主要入口函数为:err_tip_input(structpbufp,structnetifinp)该接口通过判断输入报文的协议类型,将其输入到相应的上层协议模块中去。比如,将udp报文送到udp_input。第6页共32页该模块另外一个接口是输入函数,原型如下:err_tip_output(structpbufp,structip_addrsrc,structip_addrdest,u8_tttl,u8_ttos,u8_tproto)该接口通过路由表或者传输ip后,调用netif的output字段函数钩子发送报文。udp模块:udp模块实现了udp协议层的协议处理,主要文件为udp.c。该模块通过pcb控制块将应用端口跟应用程序做了绑定。在接收到新报文时,分析其对应的pcb,找到对应的处理钩子,进行应用的处理。主要入口函数为:voidudp_input(structpbufp,structnetifinp)该模块负责输出的接口如下:err_tudp_send(structudp_pcbpcb,structpbufp)第7页共32页该模块负责将一个pcb跟一个本地端口进行绑定的接口如下:err_tudp_bind(structudp_pcbpcb,structip_addripaddr,u16_tport)该模块负责将一个pcb跟一个远端端口绑定的接口如下:err_tudp_connect(structudp_pcbpcb,structip_addripaddr,u16_tport)icmp模块:该模块负责icmp协议的处理,其比较简单。主要的处理接口如下:Voidicmp_input(structpbufp,structnetifinp)上述接口负责icmp输入报文的分析和处理。第8页共32页igmp模块:igmp模块负责分组管理。其主要的接口函数如下:voidigmp_input(structpbufp,structnetifinp,structip_addrdest)该接口负责igmp协议报文的处理,比如分析当前报文是请求还是应答。err_tigmp_joingroup(structip_addrifaddr,structip_addrgroupaddr)该接口将一个网口加入一个组。err_tigmp_leavegroup(structip_addrifaddr,structip_addrgroupaddr)该接口将一个网口从一个组中移出。第9页共32页dhcp模块:dhcp模块用于获取设备ip地址的相关信息。其处理入口主要有这么几个:dpch的启动、dpch的接收报文处理以及定时器模块的处理。主要的接口原型如下:err_tdhcp_start(structnetifnetif)该接口用于设备启动dhcp模块,主要是客户端的功能。该模块实现设备dhcp描述结构生成,并将dhcp的端口绑定到udp协议中,以及将本dhcp模块跟远端服务器端口进行绑定。最后启动dhcp申请。staticvoiddhcp_recv(voidarg,structudp_pcbpcb,structpbufp,structip_addraddr,u16_tport)该接口为一个注册接口,用于dhcp报文接收。在startdhcp时,该接口通过dhcp的udppcb注册到udp协议第10页共32页层。udp进行报文处理后,根据端口调用该注册接口。该接口中,实现dhcp报文的协议处理。Voiddhcp_fine_tmr()Voiddhcp_coarse_tmr()这两个函数接口实现了dhcp的相关超时处理监控。上面一个用于请求应答超时处理。下面一个用于地址租用情况的到期处理。从源码分析看,上述的接口在应用lwip的协议栈时,需要重点关注。对于小内存应用的场合,该协议栈的内存管理以及pbuf应用部分需要自行改写。2lwip的协议流程下面这张图比较清楚的描述了lwip的报文处理流程,呵呵,借用一下。不过,其对netif->output描述不够。从代码看,该output实际是arp层的输出,最后通过arp层调用netif中的底层输出接口发送报文。第11页共32页篇二:lwip模块详细分析lwip模块只要包括:(1)、配置模块;(2)、初始化模块;(3)、netif模块;(4)mem模块(5)、netarp模块(6)ip模块(7)icmp模块(8)dhcp模块(9)tcp模块(10)snmp模块(1)、配置模块:通过各种宏定义的方式对系统和子系统进行配置。主要文件是opt.h(2)、初始化模块:初始化模块入口文件tcpip.c,其初始化入口函数Voidtcpip_init(void(initfunc)(void),voidarg);通过调用lwip_init(),初始化所有的子模块,并启动协议栈管理进程。staticvoidtcpip_thread(voidarg):协议栈数据分发管理进程负责输入报文的处理,超时处理、api函数及回第12页共32页调的处理。Voidtcpip_init(void(initfunc)(void),voidarg){tcpip_init_done=initfunc;tcpip_init_done_arg=arg;mbox=sys_mbox_new(tcpip_mbox_size);lwip_init();#iflwip_tcpip_coRe_lockinglock_tcpip_core=sys_sem_new(1);#endif/lwip_tcpip_coRe_locking/sys_thread_new(tcpip_thRead_name,tcpip_thread,null,lwip_stk_size,tcpip_thRead_pRio);}(3)、netif模块:netif模块是协议栈与底层驱动的接口模块。该模块的第13页共32页主要文件是netif.c,通过链表的形式描述了所有的网口设备。netif的数据结构描述了网口的参数,包括ip地址、mac地址、link状态、网口号、收发函数等等参数。一个网口设备的数据收发主要通过该结构进行(4)mem模块mem模块同一管理了协议栈使用的内容缓冲区,并管理pbuf结构以及报文的字段处理。主要的文件包括mem.c、memp.c、pbuf.c。(5)、netarp模块netarp模块是处理arp协议的模块,主要源文件为etharp.c。其主要入口函数:ethernet_input(structpbufp,structnetifnetif)该入口函数通过判断输入报文p的协议类型来决定是按照arp协第14页共32页议进处理还是将该报文提交到ip协议。ethernet_input(structpbufp,structnetifnetif){structeth_hdrethhdr;u16_ttype;ethhdr=p->payload;switch(type){caseethtype_ip:ippacketetharp_ip_input(netif,p);caseethtype_aRp:passptoaRpmoduleetharp_arp_input(netif,(structeth_addr)(netif->hwaddr),p);caseethtype_pppoedisc:pppoe_suppoRtpppoe_disc_input(netif,p);第15页共32页caseethtype_pppoe:/pppoverethernetsessionstage/pppoe_data_input(netif,p);default:ethaRp_stats_inc(etharp.proterr);ethaRp_stats_inc(etharp.drop);}returneRR_ok;}if如果报文是aRp报文,该接口则调用etharp_arp_input,进行arp请求处理。if如果是ip报文,该接口就调用etharp_ip_input进行arp更新,并调用ip_input接口,将报文提交给ip层。//在该模块中,创建了设备的地址映射arp表,并提供地址映射关系查询接口。同时还提供了第16页共32页arp报文的发送接口。如下:err_tetharp_output(structnetifnetif,structpbufq,structip_addripaddr)该接口需要注册到netif的output字段,ip层在输出报文时,通过该接口获取目标机的mac地址,组合最终报文后,由该接口调用底层设备的驱动接口发送数据。在etharp_output接口中,判断报文类型:如果是广播包或者组播包,就调用etharp_send_ip(组装目标mac和源mac)接口,etharp_send_ip调用netif结构中的设备驱动注册的linkoutput钩子函数,发送最终报文。如果是单播包,etharp_output接口就调用etharp_query进行ip地址和mac地址的映射,来获取到目标机的mac地址。并在etharp_query中调用第17页共32页etharp_send_ip来发送最终组合报文。(6)、ip模块ip模块实现了协议的ip层处理,主要文件为ip.c。其主要入口函数为:err_tip_input(structpbufp,structnetifinp)该接口通过判断输入报文的协议类型,将其输入到相应的上层协议模块中去。比如,将udp报文送到udp_input。该模块另外一个接口是输入函数,原型如下:err_tip_output(structpbuf(lwip各层协议栈详解)p,structip_addrsrc,structip_addrdest,u8_tttl,u8_ttos,u8_tproto)该接口通过路由表或者传输ip后,调用netif的output字段函数钩子发送报文。第18页共32页(7)udp模块udp模块实现了udp协议层的协议处理,主要文件为udp.c。该模块通过pcb控制块将应用端口跟应用程序做了绑定。在接收到新报文时,分析其对应的pcb,找到对应的处理钩子,进行应用的处理。主要入口函数为:voidudp_input(structpbufp,structnetifinp)该模块负责输出的接口如下:err_tudp_send(structudp_pcbpcb,structpbufp)该模块负责将一个pcb跟一个本地端口进行绑定的接口如下:err_tudp_bind(structudp_pcbpcb,structip_addripaddr,u16_tport)该模块负责将一个pcb跟一个远端端口绑定的接口如下:第19页共32页err_tudp_connect(structudp_pcbpcb,structip_addripaddr,u16_t(8)、icmp模块该模块负责icmp协议的处理,其比较简单。主要的处理接口如下:Voidicmp_input(structpbufp,structnetifinp)上述接口负责icmp输入报文的分析和处理。(9)、igmp模块igmp模块负责分组管理。其主要的接口函数如下:voidigmp_input(structpbufp,structnetifinp,structip_addrdest)该接口负责igmp协议报文的处理,比如分析当前报文是请求还是应答。第20页共32页err_tigmp_joingroup(structip_addrifaddr,structip_addrgroupaddr)该接口将一个网口加入一个组。err_tigmp_leavegroup(structip_addrifaddr,structip_addrgroupaddr)该接口将一个网口从一个组中移出。(10)、dhcp模块dhcp模块用于获取设备ip地址的相关信息。其处理入口主要有这么几个:dpch的启动、dpch的接收报文处理以及定时器模块的处理。主要的接口原型如下:err_tdhcp_start(structnetifnetif)该接口用于设备启动dhcp模块,主要是客户端的功能。该模块实现设备dhcp描述结构生成,并将dhcp的端口绑定到udp协议中,以及将本dhcp模块跟远端服务器端口第21页共32页进行绑定。最后启动dhcp申请。staticvoiddhcp_recv(voidarg,structudp_pcbpcb,structpbufp,structip_addraddr,u16_tport)该接口为一个注册接口,用于dhcp报文接收。在startdhcp时,该接口通过dhcp的udppcb注册到udp协议层。udp进行报文处理后,根据端口调用该注册接口。该接口中,实现dhcp报文的协议处理。Voiddhcp_fine_tmr()Voiddhcp_coarse_tmr()这两个函数接口实现了dhcp的相关超时处理监控。上面一个用于请求应答超时处理。下面一个用于地址租用情况的到期处理。从源码分析看,上述的接口在应用lwip的协议栈时,需要重点关注。对于小内存应用的场合,该协议栈的内存管理以及pbuf应用部分需要自行改写。第22页共32页关于lwip源码的理解学习,请大家自己多看看相关资料。水好深,篇三:嵌入式协议栈lwip的特点经过对网上资料的总结,发现lwip协议栈的参考资料比较多,特别是lwip在uc/os-ii上的移植,步骤很详细,利于我们共同研究讨论。而uc/ip的资料明显比lwip少,并且它的版本更新很慢。所以,在uc/os-ii上移植lwip会比较容易,遇到问题可探讨的空间比较大。不过要实现我们所要求的功能才是最重要的。lwip可以移植到操作系统上,也可以在无操作系统的情况下独立运行。lwip实现的重点是在保持tcp/ip协议主要功能的基础上减少对Ram的占用,这使得lwip协议栈很适合在嵌入式系统中使用。以下是从网络上搜集并整理的一些资料,来说明lwip的特点,看这个协议栈能否满足我们的应用。lwip协议栈的特点:第23页共32页(1)支持多网络接口下的ip转发(2)支持icmp协议(3)包括实验性扩展的的udp(用户数据报协议)(4)包括阻塞控制,Rtt估算和快速恢复和快速转发的tcp(传输控制协议)(5)提供专门的内部回调接口(Rawapi)用于提高应用程序性能(6)可选择的berkeley接口api(多线程情况下)(7)在最新的版本中支持ppp(这很适合我们的实际应用,避免重写ppp协议)(8)新版本中增加了的ipfragment的支持.(9)支持dhcp协议,动态分配ip地址.由以上的这些特点可看出,lwiplwip的进程模式:所有tcp/ip协议栈都在一个进程当中,这样tcp/ip协第24页共32页议栈就和操作系统内核分开了。而应用层程序既可以是单独的进程也可以驻留在tcp/ip进程中。如果应用程序是单独的进程可以通过操作系统的邮箱,消息队列等和tcp/ip进程进行通讯。如果应用层程序驻留tcp/ip进程中,那应用层程序就利用内部回调函数口(Rawapi)和tcp/ip协议栈通讯.对于ucos-ii来说进程就是一个系统任务。lwip的整个tcp/ip协议栈都在同一个任务(tcpip_thread)中。应用层程序既可以是独立的任务(tftp_thread,tcpecho_thread),也可以在tcpip_thread中,利用内部函数口(Rawapi)和tcp/ip协议栈通讯。需要说明的一点是lwip会为每个网络连接动态分配一些信号量(semaphone)和消息队列(messagequeue),当连接断开时会删掉这些semaphone和queue。lwip提供三种api:1)Rawapi2)lwipapi3)bsdapi。(1)Rawapi把协议栈和应用程序放到一个进程里边,第25页共32页该接口基于函数回调技术,使用该接口的应用程序可以不用进行连续操作。不过,这会使应用程序编写难度加大且代码不易被理解。为了接收数据,应用程序会向协议栈注册一个回调函数。该回调函数与特定的连接相关联,当该关联的连接到达一个信息包,该回调函数就会被协议栈调用。这即有优点也有缺点。优点是既然应用程序和tcp/ip协议栈驻留在同一个进程中,那么发送和接收数据就不再产生进程切换。主要缺点是应用程序不能使自己陷入长期的连续运算中,这样会导致通讯性能下降,原因是tcp/ip处理与连续运算是不能并行发生的。这个缺点可以通过把应用程序分为两部分来克服,一部分处理通讯,一部分处理运算。(2)lwipapi把接收与处理放在一个线程里面。这样只要处理流程稍微被延迟,接收就会被阻塞,直接造成频繁丢包、响应不及时等严重问题。因此,接收与协议处理第26页共32页必须分开。lwip的作者显然已经考虑到了这一点,他为我们提供了tcpip_input()函数来处理这个问题,虽然他并没有在rawapi一文中说明。讲到这里,读者应该知道tcpip_input()函数投递的消息从哪里来的答案了吧,没错,它们来自于由底层网络驱动组成的接收线程。我们在编写网络驱动时,其接收部分以任务的形式创建。数据包到达后,去掉以太网包头得到ip包,然后直接调用tcpip_input()函数将其投递到mbox邮箱。投递结束,接收任务继续下一个数据包的接收,而被投递得ip包将由tcpip线程继续处理。这样,即使某个ip包的处理时间过长也不会造成频繁丢包现象的发生。这就是lwipapi。(3)bsdapi提供了基于open-read-write-close模型的unix标准api,它的最大特点是使应用程序移植到其它系统时比较容易,但用在嵌入式系统中效率比较低,占用第27页共32页资源多。这对于嵌入式应用有时是不能容忍的。基于以上的考虑,应采用lwipapi,嵌入式应用讲求效率高和资源省。用嵌入式操作系统最难把握的时进程堆栈的大小,要求我们能较准确地估算,如果在任务中使用递归,必须能够预料最坏情况下的递归层数!最理想的是能够通过一种方法测试出系统占用堆栈的大小。lwip协议栈有自己的内存区,用于协议栈相关变量对内存的使用。因此,在协议栈相关的应用程序中,我们尽量使用这一部分内存。避免造成内存空间的浪费!并且注意:用完之后一定要释放,否则你不是一个合格的程序员!为了保护内存缓冲区的完整性,防止因多个进程同时访问破坏数据,lwip使用ucos-ii提供的os_enteR_cRitical和os_exit_cRitical来保护临界资源!当然也可以用信号量来实现,但其效能不如前者!第28页共32页lwip包含好几个模块,除了那些实现tcp/ip协议族(ip,icmp,udp,tcp)的模块外,也实现了其他一些支持的模块。这些支持的模块包括操作系统仿真层,缓冲及内存管理子系统,网络接口函数,和计算检验和的函数。让lwip实现为用户空间的进程而不是驻留操作系统内核有其优缺点。主要优点是这种实现在不同操作系统间是可移植的。因为lwip被设计为运行在小的操作系统上,这些操作系统不支持交换进出进程和虚拟内存,所以由不得不等待磁盘操作(假如部分lwip进程被交换出到磁盘中)引起的延迟不再是个问题。在有机会服务一个请求前必须等待一定的调度这仍然是个问题,但在lwip的设计中并没有什么去排除将来会在操作系统内核中实现。为了使lwip可移植,操作系统特定函数调用及数据结构并没直接在代码中使用。当需要这样的函数时,操作系统仿真层就被使用。操作系统仿真层向操作系统服务提供了统一的接口,第29页共32页这些服务有定时器,进程同步,消息传递机制,等等。原理上,要移植lwip到其他操作系统时,只需实现该特定操作系统的仿真层就可以了。操作系统仿真层提供了一个功能性定时器让tcp使用。该定时器是一个时间间隔至少200ms的一次性定时,它在定时结束时将调用一个已注册的函数。信号量是进程同步机制的唯一一个实现。即使下层的操作系统并不提供信号量实现,它也能由其他的同步原语如临界变量或锁机制实现。消息传递的实现是一个抽象为“邮箱”的简单机制。一个邮箱有两种操作:邮递和收取。邮递操作不会阻塞该进程,而邮递给一个邮箱的信息会由操作系统仿真层列入队列,直到另外的进程收取该信息。即使下层操作系统不支持邮箱机制,它也能容易地由信号量实现。缓冲及内存管理在一个通信系统中,缓冲及内存管理系统必须能准备第30页共32页好分配不同大小的缓冲区,从包含有几百字节有用数据的全长tcp报文段,到只含几个字节的icmp应答响应。同时,为了避免拷贝,应该尽可能地让数据类型缓冲区驻留在内存中,而不是由网络子系统,如应用内存或Rom来管理。为了节省内存空间,不使用ip碎片的重组。lwip的存储管理是这样的:收到的pbufs是pbuFpool类型,发送出的pbufs是pbuFRom或pbuFRam类型。pbuFRom由memp分配structpbuf,而pbuFRam和pbuFpool在它们占用的内存中。内存管理只是简单地支持pbuf机制。它处理连续内存的分配和释放,并能收缩先前分配的内存块。内存管理使用系统总内存贡献出的小部分,这确保网络系统不会使用所有可用的内存,并且其他程序的操作不会因为网络系统使用完所有内存而受打断。在内部,内存管理在每个分配的内存块头部记录一个小的结构以跟踪所有已分配的内存。内存分配是通过搜索一个未使用的足够第31页共32页大小的内存块给所请求的空间分配。首次适应法使搜索时第一块足够大小的内存被分配出去。当一内存块被释放时,已用标志被设为0。为了防止碎片,通过检查前一个和后一个内存块的已用标志,可以把未用的块结合起来形成更大的未用的块。网络层接口:lwip中物理网络硬件的设备驱动被表示为一个像bsd中那样的一个网络接口结构。图5显示了网路接口结构。网络接口被保存在一个全局的链表中,通过结构中的next指针连接起来。每个网络接口都有一个名字,存在name字段中。两字符名字指示网路接口使用的设备驱动种类,只在运行时通过人工操作完成接口配置。name字段由设备驱动设置,并且能反映出由网络接口表示的硬件类型。以上从几个方面说了一下lwip的特点,不是很全。由于tcp/ip协议栈一般都比较大,即使是嵌入式tcp/ip协议第32页共32页栈,所以我想我们应当侧重于移植和应用,资料的搜集也应当侧重这两点。',)


  • 编号:1700665994
  • 分类:合同模板
  • 软件: wps,office word
  • 大小:32页
  • 格式:docx
  • 风格:商务
  • PPT页数:40145 KB
  • 标签:

广告位推荐

相关合同模板更多>