![](https://img-blog.csdnimg.cn/2021011809504346.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
LWIP协议栈
文章平均质量分 86
转载老衲五木对于lwip的详细解释
cycy小陈
进一步有一步的欢喜。
展开
-
lwip --- (十八)TCP输入输出函数1
这节从tcp_receive函数入手,逐步深入了解控制块各个字段的意义以及整个TCP层的运行机制,足足600行,神想吐血。源码注释的该函数功能为:检查收到的数据段是不是对已发数据段的确认,如果是,则释放相应发送缓冲中的数据;接下来,如果该数据段中有数据,应将数据挂接到控制块的接收队列上(pcb->ooseq)。如果数据段同时也是对正在进行RTT估计的数据段的确认,则RTT计算也在这个函数中进行。我晕,陷入了恶性循环。越看越难,越看越说不清,TCP的东西太多了。要讲清楚tcp_receive还得说清转载 2021-12-13 19:40:03 · 947 阅读 · 0 评论 -
lwip --- (十七)TCP状态机
服务器端接收到SYN握手包,向客户端返回带SYN和ACK的握手包,并将相应TCP控制块置为SYN_RCVD状态,并挂在tcp_active_pcbs链表上。以后,继续等待客户端发送过来的握手包,这次,服务器期望的是接收一个ACK包以完成建立连接要求的三次握手操作。 还是和前几次一样,数据包进来通过ip_input传递给tcp_input,后者在三个链表中查找一个匹配的连接控制块。这次进来的是客户端发送的ACK握手包,服务器端相应的tcp控制块一定是在tcp_active_pcbs链表上。接下来,以查转载 2021-05-20 10:43:20 · 891 阅读 · 0 评论 -
lwip --- (十六)TCP建立流程
这一节我们就看看如何在我们的LWIP上实现一个http服务器的过程,结合连接建立过程来理解TCP状态转换图和TCP控制块中各个字段的意义。这里先讲解一些与TCP相关的最基础的函数,至于是怎样将这些函数合理高效的组织起来以方便实际应用,这里先不涉及。 第一个函数是tcp_new函数,该函数简单的调用tcp_alloc函数为一个连接分配一个TCP控制块tcp_pcb。tcp_alloc函数首先为新的tcp_pcb分配内存空间,若内存空间不够,则函数会释放处于TIME-WAIT状态的TCP或者优先级更低的转载 2021-05-15 16:50:10 · 1866 阅读 · 0 评论 -
lwip ---(十五)TCP控制块
这一节正式踏入LWIP协议TCP部分的大门。先来看看它是怎样来描述一个TCP连接的。这个结构非常的复杂,这里的简单描述,也并不全面,并不能清晰说明各个字段的作用,在后续的TCP相关内容中,会对每个用到的字段详加讲解。结构体tcp_pcb的源代码如下:struct tcp_pcb { IP_PCB; // 这是一个宏,描述了连接的IP相关信息,包括双方IP地址,TTL等信息 struct tcp_pcb *next; // 用于连接各个TCP控制块的链表指针 en转载 2021-04-08 13:21:58 · 588 阅读 · 0 评论 -
lwip ---(十四)TCP状态转换
在理解了TCP连接建立于断开的过程后,再来看TCP的状态转换图就相对容易了。 图中有两个典型的状态转换路径,第一个是客户端申请建立连接与断开连接的过程,如图中黑色粗线所示:与前面描述的一致,在客户端通过发送一个SYN包,主动向服务器申请一个连接,数据包发出后客户端进入SYN_SENT状态等待服务器的ACK和SYN包返回,当收到这个返回包后,客户端对服务器的SYN进行确认,然后自身进入ESTABLISHED状态,与前面描述的三次握手过程完全一致。 当客户端申请断开连接时,它要发送FIN包转载 2021-01-28 14:35:55 · 653 阅读 · 0 评论 -
lwip ---(十三)TCP建立与断开
TCP部分是整个LWIP最庞大也是难理解的部分,其代码将近占了整个协议栈代码量的一半。看到如此大的一个工程真的不知道从哪里下口才能将它讲清楚。郁闷,看到啥就写啥吧先,等写完了再来慢慢整理。但我想参考的基本主线还是标准协议的TCP部分。 TCP叫传输控制协议,它为上层提供一种面向连接的、可靠的字节流服务,(PS:这一段都剽窃自协议)。TCP通过下面的一系列机制来提供可靠性:应用数据被分割成TCP认为最适合发送的数据块;当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段,如果不能及时收转载 2021-01-28 13:29:22 · 2279 阅读 · 0 评论 -
lwip ---(十二)ICMP处理
目前,IP层的东西基本讲解完,数据包的发送或分片发送没有具体涉及到。数据包的发送,与上层协议密切相关,即传输层,后面的内容就是讨论传输层的东西了。这里先讲解传输层协议中比较简单的ICMP协议。ICMP(Internet Control Message Protocol)是Internet控制报文协议,用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户数据,但是对于用户数据的传递起着重要的作用。 在以前讲解IP层ip转载 2021-01-27 19:45:34 · 1123 阅读 · 0 评论 -
lwip---(十一)IP分片重装2
IP分片包是怎么被插入相应的组装链表的。这里用一个直观的图形来解释这一过程。 图中展示了有两个数据包正在被组装的过程,两个ip_reassdata结构分别用于两个数据包的组装过程。第一个数据包已经组装好了两个分片数据,第二个组装好了一个分片数据。LWIP并不像标准协议中描述的那样,另外分配一个数据结构来描述各个分片数据,而是直接利用各个分片数据,将数据中IP头部的前八个字节拿来存储组装过程中的相关信息,因此每个进来的IP分片数据包头都被改变了,也因此要使用ip_reassdata结构中的iph转载 2021-01-23 18:20:07 · 537 阅读 · 0 评论 -
lwip---(十)IP包分片与重装1
较低版本的LWIP协议并不支数据包持数据包的分片与重装功能,较高版本的LWIP协议,关于分片数据包的重装,采用了与标准协议中差别较大的方式来实现。它采用了一种更为简单的数据结构来组装分片包,但是这样导致的结果是组装过程源代码晦涩难懂,代码执行效率低。 需要注意的是,在一般的嵌入式产品中,数据量是比较小的,基本不会出现数据分片的情况,而且嵌入式产品也不会在网络中充当路由器,实现数据包的重组、转发等功能。因此,较低版本的LWIP依然能在大多数应用中发挥其功能。 首先,我们来看看标准协议中例举的BSD转载 2021-01-15 19:53:07 · 1315 阅读 · 0 评论 -
lwip---(九)IP层输入
对于IP层主要讨论信息包的接收、分片数据包重装、信息包的发送和转发三个内容。IP数据报头结构如下所示,其中,选项字段是可以没有的,所以通常的IP数据报头长度为20个字节。 第一个字段是4bit的版本号,对于IPv4,该值为4;对于IPv6,该值为6。 接下来的4bit字段用于记录首部长度,以字为单位。所以对于不含任何选项字段的IP报头,则该长度值为5,由于该字段最大值为15,所以其能描述的最大IP报头长度为15*4=60字节。 再下来是一个8bit的服务类型字段,该字段主要用于描述该IP数转载 2021-01-15 19:16:17 · 594 阅读 · 0 评论 -
lwip---(八)ARP层流程
前面一节重点说了ARP缓存表以及如何对其进行相关操作,关于ARP,一共想说三个函数,前面已经讲过了两个。 最后要讲的一个函数是update_arp_entry,该函数用于更新ARP缓存表中的表项或者在缓存表中插入一个新的表项。该函数会在收到一个IP数据包或ARP数据包后被调用。该函数原型如下,static err_tupdate_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8转载 2021-01-12 16:48:13 · 626 阅读 · 0 评论 -
lwip---(七)ARP表查询
ARP攻击,是针对以太网地址解析协议(ARP)的一种攻击技术。在局域网中,ARP病毒收到广播的ARP 请求包,能够解析出其它节点的 (IP, MAC) 地址, 然后病毒伪装为目的主机,告诉源主机一个假MAC地址,这样就使得源主机发送给目的主机的所有数据包都被病毒软件截取,而源主机和目的主机却浑然不知。ARP攻击通过伪造IP地址和MAC地址实现ARP欺骗,能够在网络中产生大量的ARP通信量使网络阻塞,攻击者只要持续不断的发出伪造的ARP响应包就能更改目标主机ARP缓存中的IP-MAC条目。ARP协议在设计转载 2021-01-08 17:04:58 · 844 阅读 · 0 评论 -
lwip---(六)ARP表
ARP,全称Address Resolution Protocol,译作地址解析协议,是位于TCP/IP协议栈底层的协议。任何网络的通信都是基于底层硬件链路的,底层的数据链路有着自己的一套寻址机制,在以太网中,往往是通过一个48位的MAC地址来标示不同的网络通信设备的。而 TCP/IP协议的上层是使用IP地址作为各个主机间通信寻址机制的。当源主机上层要向目标主机发送数据时,它只知道目标主机的IP地址,此时,源主机需要将该IP地址转换为目的主机对应的MAC地址,这样才能在数据链路上选择正确的通道将数据传送转载 2021-01-08 16:21:40 · 1913 阅读 · 0 评论 -
lwip---(五)以太网数据接收
low_level_init函数是与我们使用的与硬件密切相关初始化函数,代码如下:static void low_level_init(struct netif *netif){ netif->hwaddr_len = ETHARP_HWADDR_LEN; //设置变量enc28j60的hwaddr_len字段 netif->hwaddr[0] = 'F'; //初始化变量enc28j60的MAC地址 netif->hwaddr[1] = 'O'转载 2021-01-08 15:56:55 · 3695 阅读 · 0 评论 -
lwip---(四)网络接口结构
今天我们来讨论LWIP是怎样来处理与底层硬件,即网卡芯片间的关系的。 为什么要首先讨论这个问题呢?与许多其他的TCP/IP实现一样,LWIP也是以分层的协议为参照来设计实现TCP/IP的。LWIP从逻辑上看分为四层:链路层、网络层、传输层和应用层。注意,虽然LWIP也采用了分层机制,但它没有在各层之间进行严格的划分,各层协议之间可以进行或多或少的交叉存取,即上层可以意识到下层协议所使用的缓存处理机制。因此各层可以更有效地重用缓冲区。而且,应用进程和协议栈代码可以使用相同的内存,应用可以直接读写内部缓转载 2021-01-08 15:34:20 · 576 阅读 · 0 评论 -
lwip---(三)pbuf释放
由于pbuf的申请主要是通过内存堆分配和内存池分配来实现,所以,pbuf的释放也必须按照这两种情况分别讨论。 在展开讨论之前,还得说说某个pbuf能被释放的前提。 在LWIP中这点很容易判断,因为前节说到pbuf的ref字段表示该pbuf被引用的次数,当pbuf被创建时,该字段的初始值为1,由此可判断,当pbuf的ref字段为1时,该pbuf才可以被删除,所以位于pbufs链表中间的pbuf结构是不会被删除成功的,因为他们的ref值至少是2。 由此总之一下,能被删除的pbuf必然是某个pbu转载 2021-01-08 15:17:45 · 1423 阅读 · 0 评论 -
lwip---(二)数据包pbuf
总结一下,LWIP中常用到的内存分配策略有两种,一种是内存堆分配,一种是内存池分配。前者可以说能随心所欲的分配我们需要的合理大小的内存块,缺点是当经过多次的分配释放后,内存堆中间会出现很多碎片,使得需要分配较大内存块时分配失败;后者分配速度快,就是简单的链表操作,因为各种类型的POOL是我们事先建立好的,但是采用POOL会有些情况下会浪费掉一定的内存空间。在LWIP中,将这两种分配策略混合使用,达到了很好的内存使用效率。 下面我们将来看看LWIP中是怎样合理利用这两种分配策略的。这就顺利的过渡到了这转载 2021-01-08 14:56:19 · 792 阅读 · 0 评论 -
lwip---(一)动态内存管理
总的来说,LWIP的动态内存管理机制可以有三种:C运行时库自带的内存分配策略、动态内存堆(HEAP)分配策略和动态内存池(POOL)分配策略。 动态内存堆分配策略和C运行时库自带的内存分配策略具有很大的相似性,这是LWIP模拟运行时库分配策略实现的。这两种策略使用者只能从中选择一种,这通过头文件lwippools.h中的宏定义MEM_LIBC_MALLOC来实现的,当它被定义为1时则使用标准C运行时库自带的内存分配策略,而为0时则使用LWIP自身的动态内存堆分配策略。一般情况下,我们选择使用LWIP转载 2021-01-06 17:09:28 · 611 阅读 · 0 评论