linux tcpip协议栈分析

合集下载

LWIP协议栈详解

LWIP协议栈详解

LWIP协议栈详解LWIP(Lightweight IP)是一个轻量级的开源 TCP/IP 协议栈,旨在为嵌入式系统提供网络连接功能。

它非常适合资源受限的系统,如单片机和小型处理器,因为它非常小巧且具有很好的可移植性。

首先,让我们来看看LWIP的核心协议。

LWIP提供了IP协议、ARP协议、ICMP协议和UDP协议的实现。

IP协议层负责数据包的路由和分段,ARP协议层负责解析IP地址和MAC地址的映射,ICMP协议用于网络探测和错误报告,UDP协议提供简单的不可靠数据传输。

除了核心协议,LWIP还提供了一些可选的协议功能,如TCP协议和DHCP协议的实现。

TCP协议提供了可靠的数据传输,而DHCP协议用于自动获取IP地址。

LWIP的另一个重要特性是它的可移植性。

LWIP设计了一个适配层,将操作系统相关的功能与核心协议分离开来。

适配层提供了一组标准的API,操作系统只需要实现这些API就可以使用LWIP协议栈。

LWIP支持的平台非常广泛,包括常见的操作系统如Windows、Linux和FreeRTOS,以及嵌入式系统如ARM Cortex-M和Microchip PIC等。

最后,让我们来看看LWIP的应用协议扩展能力。

应用协议可以通过注册回调函数来扩展LWIP的功能。

例如,应用程序可以注册一个回调函数来处理HTTP请求,或者注册一个回调函数来处理自定义的应用层数据。

这种扩展机制使得LWIP非常灵活,可以满足各种应用需求。

总结起来,LWIP是一个轻量级的开源TCP/IP协议栈,适用于资源受限的嵌入式系统。

它将TCP/IP协议栈分为核心协议和应用协议两层,提供了IP、ARP、ICMP、UDP等核心协议的实现,并通过可移植的适配层支持各种平台。

此外,LWIP还提供了应用协议扩展的能力,通过注册回调函数来扩展功能。

无论是大型操作系统还是小型嵌入式系统,LWIP都是一个很好的选择。

linux协议栈

linux协议栈

linux协议栈Linux协议栈是Linux操作系统中网络通信的核心组件,也是实现网络通信的关键。

它基于TCP/IP协议栈,提供了一系列的网络协议和接口,负责数据在网络中的传输和接收。

Linux协议栈由多层协议组成,每层都有不同的功能和责任。

从底层到高层依次是链路层(Ethernet)、网络层(IP)、传输层(TCP/UDP)和应用层(HTTP/FTP等)。

每一层都有专门的协议来处理各自的任务,并通过各层之间的接口来传递数据。

在链路层,Linux协议栈使用网络接口卡(NIC)来将数据从计算机发送到网络,并从网络接收数据。

它负责将数据以数据帧的形式封装成网络包,并通过以太网协议(Ethernet)发送出去。

同时,它还负责接收数据帧,并将其解析成网络包交给上层协议处理。

在网络层,Linux协议栈使用IP协议来实现网络寻址和路由功能。

它负责将数据包从源地址发送到目标地址,同时还提供了一些其他的功能,如分片、重组和数据包的生存周期控制等等。

IP协议是整个互联网通信的基石,可以实现跨网络的通信。

在传输层,Linux协议栈提供了TCP和UDP两种协议来实现可靠传输和无连接传输。

TCP协议提供了可靠的、面向连接的数据传输,它通过采用滑动窗口、序号和确认机制来保证数据的可靠性。

而UDP协议则是一种无连接的传输协议,它只提供了数据传输的基本功能,不保证可靠性。

在应用层,Linux协议栈支持各种应用层协议,如HTTP、FTP、SMTP等,以满足不同的应用需求。

这些协议定义了应用程序与网络之间的通信规则和数据格式,让应用程序能够进行网络通信。

除了以上的四层协议,Linux协议栈还包括了其他的功能模块,如网络设备驱动、socket接口和网络管理等,它们共同协同工作,完成网络通信的任务。

总之,Linux协议栈是Linux操作系统中网络通信的核心组件,它提供了一系列的网络协议和接口,负责数据在网络中的传输和接收。

它基于TCP/IP协议栈,包括链路层、网络层、传输层和应用层等多层协议,以及其他的功能模块。

linux 协议栈

linux 协议栈

linux 协议栈Linux协议栈,又称网络协议栈,是指在Linux操作系统中负责处理网络通信传输的一系列协议和软件集合。

它是实现网络通信的核心组件,负责在应用层和网络硬件之间进行数据传输和信息处理。

Linux协议栈由多个协议层组成,包括物理层、数据链路层、网络层、传输层和应用层。

物理层负责将数据从高层转化为物理信号进行传送,而数据链路层负责将数据在网络间的传递过程中进行帧的封装和解封装,以及网卡的驱动程序。

网络层则负责寻址和路由功能,传输层实现了可靠的端到端通信,应用层提供了各种网络服务。

在物理层的硬件设备中,网络接口卡(NIC)是协议栈与外部网络通信的接口。

协议栈通过驱动程序与NIC进行交互,将数据封装成数据包,并通过数据链路层将数据发往目的地。

在数据链路层,协议栈通过各种链路层协议(如以太网协议)进行数据帧的封装和解封装。

网络层则根据不同的网络协议(如IP协议)进行寻址和路由,将数据从源主机传送到目的主机。

传输层通过传输协议(如TCP或UDP)实现端到端的可靠数据传输。

而应用层则提供了各种网络服务,如HTTP、FTP、DNS等。

Linux协议栈的优点在于其开放源代码的特性和丰富的功能。

由于其开源的特性,用户可以自由地进行定制和修改。

并且,Linux协议栈支持多种网络协议和服务,如IP、TCP、UDP、FTP等。

这使得Linux操作系统具有很高的灵活性和可扩展性,能够满足不同的用户需求。

另外,由于众多开发者的贡献和不断的更新迭代,Linux协议栈也具有较高的稳定性和安全性。

然而,Linux协议栈也存在一些挑战和问题。

对于一些特殊的应用场景和网络需求,Linux协议栈可能无法提供最佳的性能和效果。

此外,在网络安全方面,由于Linux协议栈的复杂性和开放性,也面临着一些潜在的安全风险和漏洞。

总的来说,Linux协议栈是Linux操作系统中的重要组件,负责处理网络通信传输。

它由多个协议层组成,实现了从物理层到应用层的数据传输和处理。

计算机网络:TCPIP协议栈概述

计算机网络:TCPIP协议栈概述

计算机⽹络:TCPIP协议栈概述⽬录参考模型在⽹络刚刚被搞出来的年代,通常只有同⼀个⼚家⽣产的设备才能彼此通信,不同的⼚家的设备不能兼容。

这是因为没有统⼀的标准去要求不同的⼚家按照相同的⽅式进⾏通信,所以不同的⼚家都闭门造车。

为了解决这个问题,后来就产⽣出参考模型的概念。

参考模型是描述如何完成通信的概念模型,它指出了完成⾼效通信所需要的全部步骤,并将这些步骤划分为称之为“层”的逻辑组。

分层最⼤的优点是为上层隐藏下层的细节,即对于开发者来说,如果他们要开发或实现某⼀层的协议,则他们只需要考虑这⼀层的功能即可。

其它层都⽆需考虑,因为其它层的功能有其它层的协议来完成,上层只需要调⽤下层的接⼝即可。

参考模型的优点如下:1. 将⽹络通信过程划分为更⼩、更简单的组件,使得组件的开发、设计和排错更为⽅便;2. 通过标准化⽹络组件,让不同的⼚商能够协作开发;3. 定义了模型每层执⾏的功能,从⽽⿎励了⾏业标准化;4. 让不同类型的⽹络硬件和软件能够彼此通信;5. 避免让对⼀层的修改影响其它层,从⽽避免妨碍开发⼯作。

协议计算机⽹络中的数据交换必须遵守事先约定好的规则,这些规则明确规定了所交换的数据的格式以及有关的同步问题,⽹络协议 (network protocol)是为进⾏⽹络中的数据交换⽽建⽴的规则、标准或约定。

⽹络协议有 3 个要素:1. 语法:数据与控制信息的结构或格式;2. 语义:需要发出何种控制信息,完成何种动作以及做出何种响应;3. 同步:事件实现顺序的详细说明。

OSI 模型OSI 模型旨在以协议的形式帮助⼚商⽣产兼容的⽹络设备和软件,让不同⼚商的⽹络能够协同⼯作。

同时对于⽤户⽽⾔,OSI 能帮助不同的主机之间传输数据。

OSI 并⾮是具体的模型,⽽是⼀组指导原则,开发者以此为依据开发⽹络应⽤。

同时它也提供了框架,指导如何制定和实施⽹络标准、制造设备,以及制定⽹络互联的⽅案。

OSI 模型包含 7 层,上三层指定了终端中应⽤程序如何彼此通信,以及如何与⽤户交互,下四层指定了如何进⾏端到端数据传输。

eth协议数据结构

eth协议数据结构

竭诚为您提供优质文档/双击可除eth协议数据结构篇一:linuxtcpip协议栈的关键数据结构socketbuffer linuxtcp/ip协议栈的关键数据结构socketbuffersk_buff结构可能是linux网络代码中最重要的数据结构,它表示接收或发送数据包的包头信息。

它在中定义,并包含很多成员变量供网络代码中的各子系统使用。

这个结构在linux内核的发展过程中改动过很多次,或者是增加新的选项,或者是重新组织已存在的成员变量以使得成员变量的布局更加清晰。

它的成员变量可以大致分为以下几类:layout布局general通用Feature-specific功能相关managementfunctions管理函数这个结构被不同的网络层(mac或者其他二层链路协议,三层的ip,四层的tcp或udp等)使用,并且其中的成员变量在结构从一层向另一层传递时改变。

l4向l3传递前会添加一个l4的头部,同样,l3向l2传递前,会添加一个l3的头部。

添加头部比在不同层之间拷贝数据的效率更高。

由于在缓冲区的头部添加数据意味着要修改指向缓冲区的指针,这是个复杂的操作,所以内核提供了一个函数skb_reserve(在后面的章节中描述)来完成这个功能。

协议栈中的每一层在往下一层传递缓冲区前,第一件事就是调用skb_reserve在缓冲区的头部给协议头预留一定的空间。

skb_reserve同样被设备驱动使用来对齐接收到包的包头。

如果缓冲区向上层协议传递,旧的协议层的头部信息就没什么用了。

例如,l2的头部只有在网络驱动处理l2的协议时有用,l3是不会关心它的信息的。

但是,内核并没有把l2的头部从缓冲区中删除,而是把有效荷载的指针指向l3的头部,这样做,可以节省cpu时间。

1.网络参数和内核数据结构就像你在浏览tcp/ip规范或者配置内核时所看到的一样,网络代码提供了很多有用的功能,但是这些功能并不是必须的,比如说,防火墙,多播,还有其他一些功能。

TCPIP协议知识科普

TCPIP协议知识科普

TCPIP协议知识科普简介本⽂主要介绍了⼯作中常⽤的TCP/IP对应协议栈相关基础知识,科普⽂。

本博客所有⽂章:TCP/IP⽹络协议栈TCP/IP⽹络协议栈分为四层, 从下⾄上依次是:1. 链路层其实在链路层下⾯还有物理层, 指的是电信号的传输⽅式, ⽐如常见的双绞线⽹线, 光纤, 以及早期的同轴电缆等, 物理层的设计决定了电信号传输的带宽, 速率, 传输距离, 抗⼲扰性等等。

在链路层本⾝, 主要负责将数据跟物理层交互, 常见⼯作包括⽹卡设备的驱动, 帧同步(检测什么信号算是⼀个新帧), 冲突检测(如果有冲突就⾃动重发), 数据差错校验等⼯作。

链路层常见的有以太⽹, 令牌环⽹的标准。

2. ⽹络层⽹络层的IP协议是构成Internet的基础。

该层次负责将数据发送到对应的⽬标地址, ⽹络中有⼤量的路由器来负责做这个事情, 路由器往往会拆掉链路层和⽹络层对应的数据头部并重新封装。

IP层不负责数据传输的可靠性, 传输的过程中数据可能会丢失, 需要由上层协议来保证这个事情。

3. 传输层⽹络层负责的是点到点的协议, 即只到某台主机, 传输层要负责端到端的协议, 即要到达某个进程。

典型的协议有TCP/UDP两种协议, 其中TCP协议是⼀种⾯向连接的, 稳定可靠的协议, 会负责做数据的检测, 分拆和重新按照顺序组装,⾃动重发等。

⽽UDP就只负责将数据送到对应进程, ⼏乎没有任何逻辑, 也就是说需要应⽤层⾃⼰来保证数据传输的可靠性。

4. 应⽤层即我们常见的HTTP, FTP协议等。

这四层协议对应的数据包封装如下图:四层协议对应的通信过程如下图:链路层以太⽹数据帧以太⽹数据帧格式如下:说明如下:1. ⽬的地址和源地址是指⽹卡的硬件地址(即MAC地址), 长度是48位, 出⼚的时候固化的。

2. 类型字段即上层协议类型, ⽬前有三种值: IP, ARP, RARP。

3. 数据对应了上层协议传输的数据, 以太⽹规定数据⼤⼩是46~1500字节, 最⼤值1500即以太⽹的最⼤传输单元(MTU), 不同⽹络类型有不同MTU, 如果需要跨不同类型链路传输的话, 就需要对数据进⾏重新分⽚。

详解TCPIP协议栈面临的五大网络安全问题

详解TCP/IP协议栈面临的五大网络安全问题TCP/IP协议栈面临的五大网络安全问题,也介绍到企业网络安全管理人员在面临问题时所能采取的应对措施。

下面是店铺收集整理的详解TCP/IP协议栈面临的五大网络安全问题,希望对大家有帮助~~ 详解TCP/IP协议栈面临的五大网络安全问题1. IP欺骗IP Spoof即IP 电子欺骗,可以理解为一台主机设备冒充另外一台主机的IP地址与其他设备通信,从而达到某种目的技术。

早在1985年,贝尔实验室的一名工程师Robbert Morris在他的一篇文章“A weakness in the 4.2bsd UNIX TCP/IP software”中提出了IP Spoof 的概念,有兴趣的读者可参见原文:/~emv/tubed/archives/Morris_weakness_in _ TCPIP.txt 。

但要注意:单纯凭借IP Spoof技术不可能很好地完成一次完整的攻击,因为现有IP Spoof技术是属于一种“盲人”式的入侵手段。

一般来说,IP欺骗攻击有6个步骤:(1)首先使被信任主机的网络暂时瘫痪,以免对攻击造成干扰;(2)然后连接到目标机的某个端口来猜测ISN基值和增加规律;(3)接下来把源地址伪装成被信任主机,发送带有SYN标志的数据段请求连接;(4)然后等待目标机发送SYN+ACK包给已经瘫痪的主机;(5)最后再次伪装成被信任主机向目标机发送的ACK,此时发送的数据段带有预测的目标机的ISN+1;(6)连接建立,发送命令请求。

下面是它的两个关键步骤:(1)使被信任主机失去工作能力为了伪装成被信任主机而不露馅,需要使其完全失去工作能力。

由于攻击者将要代替真正的被信任主机,他必须确保真正的被信任主机不能收到任何有效的网络数据,否则将会被揭穿。

有许多方法可以达到这个目的(如SYN洪水攻击、Land等攻击)。

(2)序列号取样和猜测对目标主机进行攻击,必须知道目标主机的数据包序列号。

TCPIP四层模型和OSI七层模型[技巧]

1.1.2 TCP/IP四层模型和OSI七层模型表1-1是 TCP/IP四层模型和OSI七层模型对应表。

我们把OSI七层网络模型和Linux TCP/IP四层概念模型对应,然后将各种网络协议归类。

表1-1 TCP/IP四层模型和OSI七层模型对应表OSI七层网络模型Linux TCP/IP四层概念模型对应网络协议应用层(Application)应用层TFTP, FTP, NFS, WAIS表示层(Presentation)Telnet, Rlogin, SNMP, Gopher 会话层(Session)SMTP, DNS传输层(Transport)传输层TCP, UDP网络层(Network)网际层IP, ICMP, ARP, RARP, AKP, UUCP数据链路层(DataLink)网络接口FDDI, Ethernet, Arpanet, PDN, SLIP, PPP物理层(Physical)IEEE 802.1A, IEEE 802.2到IEEE 802.111.网络接口网络接口把数据链路层和物理层放在一起,对应TCP/IP概念模型的网络接口。

对应的网络协议主要是:Ethernet、FDDI和能传输IP数据包的任何协议。

2.网际层网络层对应Linux TCP/IP概念模型的网际层,网络层协议管理离散的计算机间的数据传输,如IP协议为用户和远程计算机提供了信息包的传输方法,确保信息包能正确地到达目的机器。

这一过程中,IP和其他网络层的协议共同用于数据传输,如果没有使用一些监视系统进程的工具,用户是看不到在系统里的IP的。

网络嗅探器 Sniffers是能看到这些过程的一个装置(它可以是软件,也可以是硬件),它能读取通过网络发送的每一个包,即能读取发生在网络层协议的任何活动,因此网络嗅探器Sniffers会对安全造成威胁。

重要的网络层协议包括ARP(地址解析协议)、ICMP(Internet控制消息协议)和IP协议(网际协议)等。

linux,ip协议栈源代码分析,pdf

竭诚为您提供优质文档/双击可除linux,ip协议栈源代码分析,pdf篇一:netfilter源代码分析详解一、概述filter/iptables框架简介netfilter/iptables是继2.0.x的ipfwadm、2.2.x的ipchains之后,新一代的linux防火墙机制。

netfilter采用模块化设计,具有良好的可扩充性。

其重要工具模块iptables连接到netfilter的架构中,并允许使用者对数据报进行过滤、地址转换、处理等操作。

netfilter提供了一个框架,将对网络代码的直接干涉降到最低,并允许用规定的接口将其他包处理代码以模块的形式添加到内核中,具有极强的灵活性。

2.主要源代码文件linux内核版本:2.4.21netfilter主文件:net/core/netfilter.cnetfilter主头文件:include/linux/netfilter.hipv4相关:c文件:net/ipv4/netfilter/*.c头文件:include/linux/netfilter_ipv4.hinclude/linux/netfilter_ipv4/*.hipv4协议栈主体的部分c文件,特别是与数据报传送过程有关的部分:ip_input.c,ip_forward.c,ip_output.c,ip_fragment.c等二、netfilter/iptables-ipv4总体架构netfilter主要通过表、链实现规则,可以这么说,netfilter是表的容器,表是链的容器,链是规则的容器,最终形成对数据报处理规则的实现。

详细地说,netfilter/iptables的体系结构可以分为三个大部分:filter的hook机制netfilter的通用框架不依赖于具体的协议,而是为每种网络协议定义一套hook函数。

这些hook函数在数据报经过协议栈的几个关键点时被调用,在这几个点中,协议栈将数据报及hook函数标号作为参数,传递给netfilter框架。

LINUX内核网络协议栈

LINUX内核网络协议栈Linux内核网络协议栈是一个关键的软件组件,它实现了Linux操作系统的网络功能。

网络协议栈位于操作系统内核中,负责处理网络传输的各个层级。

Linux内核网络协议栈包括多个层级,从物理层到应用层。

每个层级都有特定的功能和协议。

下面是对每个层级的详细介绍:1.物理层:物理层是网络协议栈的最低层,负责传输数据的物理介质,如电缆、光纤等。

物理层由硬件设备支持,并通过设备驱动程序与内核进行通信。

2.数据链路层:数据链路层负责将数据转换为数据帧,并通过物理介质进行传输。

它包括两个子层:逻辑链路控制层和介质访问控制层。

逻辑链路控制层处理数据的流控制和错误检测,介质访问控制层则管理多个设备的访问冲突。

3.网络层:网络层处理数据包的路由和分组。

它使用IP协议进行路由和寻址,并通过路由表决定数据包的最佳路径。

网络层还可以处理一些附加功能,如分片和重新组装。

4.传输层:传输层负责在不同主机之间的进程之间提供可靠的数据传输。

它使用TCP协议和UDP协议来实现,TCP协议提供可靠的数据传输,而UDP协议提供不可靠但高效的传输。

5.会话层:会话层负责建立、管理和终止网络会话。

它处理会话标识符的生成和管理,并提供可靠的会话传输。

6.表示层:表示层负责数据的编码和解码,以确保数据在不同系统之间的互通。

它处理数据的格式、加密和压缩。

7.应用层:应用层是网络协议栈的最高层,提供用户与网络之间的接口。

它包括多个协议,如HTTP、FTP和SMTP,用于实现各种应用程序的网络功能。

Linux内核网络协议栈的功能包括数据传输、路由、安全、流量控制和错误检测。

内核通过各个层级的协议来实现这些功能。

内核还提供各种工具和接口,使用户可以配置网络设置、监控网络流量和诊断网络问题。

除了基本功能,Linux内核网络协议栈还支持各种高级功能,如多路复用、多队列和嵌入式系统。

它还可以通过加载额外的模块来支持特定的网络协议或功能。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

sk_buff结构可能是linux网络代码中最重要的数据结构,它表示接收或发送数据包的包头信息。

它在<include/linux/skbuff.h>中定义,并包含很多成员变量供网络代码中的各子系统使用。

这个结构在linux内核的发展过程中改动过很多次,或者是增加新的选项,或者是重新组织已存在的成员变量以使得成员变量的布局更加清晰。

它的成员变量可以大致分为以下几类:∙Layout 布局∙General 通用∙Feature-specific功能相关∙Management functions管理函数这个结构被不同的网络层(MAC或者其他二层链路协议,三层的IP,四层的TCP或UDP等)使用,并且其中的成员变量在结构从一层向另一层传递时改变。

L4向L3传递前会添加一个L4的头部,同样,L3向L2传递前,会添加一个L3的头部。

添加头部比在不同层之间拷贝数据的效率更高。

由于在缓冲区的头部添加数据意味着要修改指向缓冲区的指针,这是个复杂的操作,所以内核提供了一个函数skb_reserve (在后面的章节中描述)来完成这个功能。

协议栈中的每一层在往下一层传递缓冲区前,第一件事就是调用skb_reserve在缓冲区的头部给协议头预留一定的空间。

skb_reserve同样被设备驱动使用来对齐接收到包的包头。

如果缓冲区向上层协议传递,旧的协议层的头部信息就没什么用了。

例如,L2的头部只有在网络驱动处理L2的协议时有用,L3是不会关心它的信息的。

但是,内核并没有把L2的头部从缓冲区中删除,而是把有效荷载的指针指向L3的头部,这样做,可以节省CPU时间。

1. 网络参数和内核数据结构就像你在浏览TCP/IP规范或者配置内核时所看到的一样,网络代码提供了很多有用的功能,但是这些功能并不是必须的,比如说,防火墙,多播,还有其他一些功能。

大部分的功能都需要在内核数据结构中添加自己的成员变量。

因此,sk_buff里面包含了很多像#ifdef这样的预编译指令。

例如,在sk_buff结构的最后,你可以找到:struct sk_buff {... ... ...#ifdef CONFIG_NET_SCHED_ _u32 tc_index;#ifdef CONFIG_NET_CLS_ACT_ _u32 tc_verd;_ _u32 tc_classid;#endif#endif}它表明,tc_index只有在编译时定义了CONFIG_NET_SCHED符号才有效。

这个符号可以通过选择特定的编译选项来定义(例如:"Device Drivers Networking supportNetworking options QoS and/orfair queueing")。

这些编译选项可以由管理员通过make config来选择,或者通过一些自动安装工具来选择。

前面的例子有两个嵌套的选项:CONFIG_NET_CLS_ACT(包分类器)只有在选择支持“QoS and/or fair queueing”时才能生效。

顺便提一下,QoS选项不能被编译成内核模块。

原因就是,内核编译之后,由某个选项所控制的数据结构是不能动态变化的。

一般来说,如果某个选项会修改内核数据结构(比如说,在sk_buff里面增加一个项tc_index),那么,包含这个选项的组件就不能被编译成内核模块。

你可能经常需要查找是哪个make config编译选项或者变种定义了某个#ifdef标记,以便理解内核中包含的某段代码。

在2.6内核中,最快的,查找它们之间关联关系的方法,就是查找分布在内核源代码树中的kconfig文件中是否定义了相应的符号(每个目录都有一个这样的文件)。

在2.4内核中,你需要查看Documentation/Configure.help文件。

2. Layout Fields有些sk_buff成员变量的作用是方便查找或者是连接数据结构本身。

内核可以把sk_buff组织成一个双向链表。

当然,这个链表的结构要比常见的双向链表的结构复杂一点。

就像任何一个双向链表一样,sk_buff中有两个指针next和prev,其中,next指向下一个节点,而prev指向上一个节点。

但是,这个链表还有另一个需求:每个sk_buff结构都必须能够很快找到链表头节点。

为了满足这个需求,在第一个节点前面会插入另一个结构sk_buff_head,这是一个辅助节点,它的定义如下:struct sk_buff_head {/* These two members must be first. */ struct sk_buff * next;struct sk_buff * prev;_ _u32 qlen;spinlock_t lock;};qlen代表链表元素的个数。

lock用于防止对链表的并发访问。

sk_buff和sk_buff_head的前两个元素是一样的:next和prev指针。

这使得它们可以放到同一个链表中,尽管sk_buff_head要比sk_buff小得多。

另外,相同的函数可以同样应用于sk_buff和sk_buff_head。

为了使这个数据结构更灵活,每个sk_buff结构都包含一个指向sk_buff_head的指针。

这个指针的名字是list。

图1会帮助你理解它们之间的关系。

Figure 1. List of sk_buff elements其他有趣的成员变量如下:struct sock *sk这是一个指向拥有这个sk_buff的sock结构的指针。

这个指针在网络包由本机发出或者由本机进程接收时有效,因为插口相关的信息被L4(TCP或UDP)或者用户空间程序使用。

如果sk_buff只在转发中使用(这意味着,源地址和目的地址都不是本机地址),这个指针是NULL。

unsigned int len这是缓冲区中数据部分的长度。

它包括主缓冲区中的数据长度(data指针指向它)和分片中的数据长度。

它的值在缓冲区从一个层向另一个层传递时改变,因为往上层传递,旧的头部就没有用了,而往下层传递,需要添加本层的头部。

len同样包含了协议头的长度。

unsigned int data_len和len不同,data_len只计算分片中数据的长度。

unsigned int mac_len这是mac头的长度。

atomic_t users这是一个引用计数,用于计算有多少实体引用了这个sk_buff缓冲区。

它的主要用途是防止释放sk_buff 后,还有其他实体引用这个sk_buff。

因此,每个引用这个缓冲区的实体都必须在适当的时候增加或减小这个变量。

这个计数器只保护sk_buff结构本身,而缓冲区的数据部分由类似的计数器(dataref)来保护. 有时可以用atomic_inc和atomic_dec函数来直接增加或减小users,但是,通常还是使用函数skb_get 和kfree_skb来操作这个变量。

unsigned int truesize这是缓冲区的总长度,包括sk_buff结构和数据部分。

如果申请一个len字节的缓冲区,alloc_skb函数会把它初始化成len+sizeof(sk_buff)。

struct sk_buff *alloc_skb(unsigned int size,int gfp_mask){... ... ...skb->truesize = size + sizeof(struct sk_buff);... ... ...}当skb->len变化时,这个变量也会变化。

unsigned char *headunsigned char *endunsigned char *dataunsigned char *tail它们表示缓冲区和数据部分的边界。

在每一层申请缓冲区时,它会分配比协议头或协议数据大的空间。

head 和end指向缓冲区的头部和尾部,而data和tail指向实际数据的头部和尾部,参见图2。

每一层会在head 和data之间填充协议头,或者在tail和end之间添加新的协议数据。

图2中右边数据部分会在尾部包含一个附加的头部。

Figure 2. head/end versus data/tail pointersvoid (*destructor)(...)这个函数指针可以初始化成一个在缓冲区释放时完成某些动作的函数。

如果缓冲区不属于一个socket,这个函数指针通常是不会被赋值的。

如果缓冲区属于一个socket,这个函数指针会被赋值为sock_rfree 或sock_wfree(分别由skb_set_owner_r或skb_set_owner_w函数初始化)。

这两个sock_xxx函数用于更新socket的队列中的内存容量。

3. General Fields本节描述sk_buff的主要成员变量,这些成员变量与特定的内核功能无关:struct timeval stamp这个变量只对接收到的包有意义。

它代表包接收时的时间戳,或者有时代表包准备发出时的时间戳。

它在netif_rx里面由函数net_timestamp设置,而netif_rx是设备驱动收到一个包后调用的函数。

struct net_device *dev这个变量的类型是net_device,net_device它代表一个网络设备。

dev的作用与这个包是准备发出的包还是刚接收的包有关。

当收到一个包时,设备驱动会把sk_buff的dev指针指向收到这个包的设备的数据结构,就像下面的vortex_rx里的一段代码所做的一样,这个函数属于3c59x系列以太网卡驱动,用于接收一个帧。

(drivers/net/3c59x.c):static int vortex_rx(struct net_device *dev){... ... ...skb->dev = dev;... ... ...skb->protocol = eth_type_trans(skb, dev);netif_rx(skb); /* Pass the packet to the higher layer*/... ... ...}当一个包被发送时,这个变量代表将要发送这个包的设备。

在发送网络包时设置这个值的代码要比接收网络包时设置这个值的代码复杂。

有些网络功能可以把多个网络设备组成一个虚拟的网络设备(也就是说,这些设备没有和物理设备直接关联),并由一个虚拟网络设备驱动管理。

当虚拟设备被使用时,dev指针指向虚拟设备的net_device结构。

而虚拟设备驱动会在一组设备中选择一个设备并把dev指针修改为这个设备的net_device结构。

因此,在某些情况下,指向传输设备的指针会在包处理过程中被改变。

相关文档
最新文档