数据包接收系列 — 上半部实现(网卡驱动)
- 格式:pdf
- 大小:142.29 KB
- 文档页数:5
嵌入式Linux虚拟网卡驱动中数据包的提取及转发技术曹志龙;郑日荣【期刊名称】《工业控制计算机》【年(卷),期】2015(0)5【摘要】This paper introduces a method which can write virtual network card drive program with Linux system,and extracts the data packets from it,then handle packets according to the pre-arranged rule,at last sent the data packet by Linux kernel socket.Through this technology,people can reach the goal of dealing with and forwarding the data packets which fetched in virtual network card drive.%网络设备是完成用户数据包在网络媒介上发送和接收的设备,它将上层协议传递下来的数据包以特定的媒介访问控制方式进行发送,并将接收到的数据传递给上层协议。
提出了一种在Linux系统下编写虚拟网卡驱动程序,并在虚拟网卡驱动中提取出数据包,再根据事先约定好的规则对数据包做处理,最后通过Linux内核socket机制将数据包发送出去的技术。
在工程项目中,采用此种技术,可以实现在虚拟网卡驱动中抓取出数据包,然后根据具体要求处理及转发数据包。
【总页数】2页(P31-32)【作者】曹志龙;郑日荣【作者单位】广东工业大学自动化学院,广东广州 510006;广东工业大学自动化学院,广东广州 510006【正文语种】中文【相关文献】1.基于ARM的数据包提取转发机制的研究 [J], 张功萱;王平立;何广生;张冲2.基于嵌入式Linux的以太网卡驱动设计与实现 [J], 龙新辉;陈俊杰3.嵌入式Linux的USB Chirp无线网卡驱动设计 [J], 叶学程;郑霖4.嵌入式linux下DM9000网卡驱动的移植与实现 [J], 贺金平5.基于嵌入式linux的无线网卡驱动程序 [J], 钱晓华;郭继红因版权原因,仅展示原文概要,查看原文内容请购买。
2011年研发二部工作周报月报作者:***时间:2012-6-13目录一、整理漏扫系统的结构 (1)1、整理NetScan目录中的程序。
(1)2、整理proftpd目录中内容(插件的检测信息)。
(4)3、整理proxyd目录中的安管(安管平台)。
(8)二、熟悉Nessus的工作原理 (8)1、Nessus扫描引擎的工作原理.... 错误!未定义书签。
三、整理运行的整个流程............... 错误!未定义书签。
1、通过客户端下发策略,上传到服务器上。
错误!未定义书签。
2、服务端:接收客户端下发的策略。
错误!未定义书签。
3、服务端进行身份的认证........ 错误!未定义书签。
一、整理漏扫系统的结构网卡是Linux服务器中最重要网络设备。
据统计,Linux网络故障有35%在物理层、25%在数据链路层、10%在网络层、10%在传输层、10%在对话、7%在表示层、3%在应用层。
由此可以看出,网络故障通常发生在网络七层模型的下三层,即物理层、链路层和网络层。
对应于实际网络也就是使用的网络线缆、网卡、交换机、路由器等设备故障。
Linux的网络实现是模仿FreeBSD的,它支持FreeBSD 的带有扩展的Sockets(套接字)和TCP/IP协议。
它支持两个主机间的网络连接和Sockets通讯模型,实现了两种类型的Sockets:BSD Sockets和INET Sockets。
它为不同的通信模型和服务质量提供了两种传输协议,即不可靠的、基于消息的UDP传输协议和可靠的、基于流的传输协议TCP,并且都是在IP网络协议上实现的。
INET sockets 是在以上两个协议及IP协议之上实现的。
由于交换机、路由器通常独立于Linux或者其他操作系统。
网卡设置故障是造成Linux 服务器故障最主要原因。
可能因为硬件的质量或性能、磨损老化、人为误操作、不正确的网络设置、管理问题、Linux软件的BUG、系统受到黑客攻击和Linux病毒等原因造成。
Python选择⽹卡发包及接收数据包当⼀台计算机上有多个⽹卡时,需要选择对应IP地址的⽹卡进⾏发送数据包或者接受数据包。
1、选择⽹卡发包(应⽤scapy):plface=conf.route.route("××.××.××.××")[0]#××.××.××.××为对应⽹卡⽹络中存在设备的IP地址。
不能是需要发送数据包的⽹卡的IP地址(会报“result too large”)pkt=conf.L2socket(plface)pack_ip,pack_udp,pack_ether=self.udp_pack()t= str(pack_ether/pack_ip/pack_udp/udp_packdata)udp_pack = Ether(t)pkt.send(udp_pack)2、选择⽹卡进⾏包的接收1)如下⽅法,只能获得⼀个⽹卡的ip地址(选择哪个⽹卡,优先级未知)socket.getaddrinfo(socket.gethostname(),None)[-1][4][0]2)如下⽅法,可根据ip地址确定⽹卡:HOST = socket.gethostbyname(socket.gethostname())s=socket.socket(socket.AF_INET,socket.SOCK_RAW,socket.IPPROTO_IP)s.bind((HOST,0))host可以直接⽤⽹卡ip地址代替,这样就可以选择⽹卡进⾏包的接受了总结以上就是这篇⽂章的全部内容了,希望本⽂的内容对⼤家的学习或者⼯作具有⼀定的参考学习价值,谢谢⼤家对的⽀持。
如果你想了解更多相关内容请查看下⾯相关链接。
Linux⽹卡驱动架构分析⼀、⽹卡驱动架构 由上到下层次依次为:应⽤程序→系统调⽤接⼝→协议⽆关接⼝→⽹络协议栈→设备⽆关接⼝→设备驱动。
⼆、重要数据结构 1、Linux内核中每⼀个⽹卡由⼀个net_device结构来描述。
2、⽹卡操作函数集:net_device_ops,这个数据结构是上⾯net_device的⼀个成员。
3、⽹络数据包:sk_buff。
三、⽹卡驱动代码分析 所⽤⽂件为cs89x0.c,主要分析三个部分:⽹卡初始化、发送数据、接收数据。
㈠⽹卡初始化 ⽹卡驱动初始化主要在函数init_module中完成,部分代码如下:int __init init_module(void){ struct net_device *dev = alloc_etherdev(sizeof(struct net_local)); struct net_local *lp; int ret = 0; ... dev->irq = irq; dev->base_addr = io; ... ret = cs89x0_probe1(dev, io, 1); ...} cs89x0_probe1函数部分代码如下:static int __init cs89x0_probe1(struct net_device *dev, int ioaddr, int modular){ struct net_local *lp = netdev_priv(dev); static unsigned version_printed; int i; int tmp; unsigned rev_type = 0; int eeprom_buff[CHKSUM_LEN]; int retval; ... writeword(ioaddr, ADD_PORT, PP_ChipID); tmp = readword(ioaddr, DATA_PORT); //对硬件的初始化 ... for (i = 0; i < ETH_ALEN/2; i++) //初始化MAC地址 { dev->dev_addr[i*2] = eeprom_buff[i]; dev->dev_addr[i*2+1] = eeprom_buff[i] >> 8; } ... dev->netdev_ops = &net_ops; //初始化netdev_ops ... retval = register_netdev(dev); //注册⽹卡驱动} 由代码可以看出 1、定义并分配net_device结构,使⽤alloc_etherdev函数。
网络数据包收发流程(1):从驱动到协议栈2013-06-26 14:47:19标签:控制器数据包以太网网络流量原文出处:/uid-24148050-id-464587.html一、硬件环境intel82546:PHY与MAC集成在一起的PCI网卡芯片,很强大bcm5461:PHY芯片,与之对应的MAC是TSECTSEC:Three Speed Ethernet Controller,三速以太网控制器,PowerPc 架构CPU里面的MAC 模块注意,TSEC内部有DMA子模块话说现在的CPU越来越牛叉了,什么功能都往里面加,最常见的如MAC功能。
TSEC只是MAC功能模块的一种,其他架构的cpu也有和TSEC类似的MAC功能模块。
这些集成到CPU芯片上的功能模块有个学名,叫平台设备,即platform device。
二、网络收包原理网络驱动收包大致有3种情况:no NAPI:mac每收到一个以太网包,都会产生一个接收中断给cpu,即完全靠中断方式来收包缺点是当网络流量很大时,cpu大部分时间都耗在了处理mac的中断。
netpoll:在网络和I/O子系统尚不能完整可用时,模拟了来自指定设备的中断,即轮询收包。
缺点是实时性差NAPI:采用中断+ 轮询的方式:mac收到一个包来后会产生接收中断,但是马上关闭。
直到收够了netdev_max_backlog个包(默认300),或者收完mac上所有包后,才再打开接收中断通过sysctl来修改dev_max_backlog或者通过proc修改/proc/sys/net/core/netdev_max_backlog下面只写内核配置成使用NAPI的情况,只写TSEC驱动。
(非NAPI的情况和PCI网卡驱动以后再说)内核版本linux 2.6.24三、NAPI 相关数据结构每个网络设备(MAC层)都有自己的net_device数据结构,这个结构上有napi_struct。
网络通信技术与故障排除指南第1章网络通信基础 (4)1.1 网络通信原理 (4)1.1.1 通信模型 (4)1.1.2 数据封装与解封装 (4)1.1.3 数据传输方式 (4)1.2 网络协议与标准 (4)1.2.1 TCP/IP协议族 (4)1.2.2 常用网络协议 (5)1.2.3 网络标准组织 (5)1.3 网络设备与布线 (5)1.3.1 网络设备 (5)1.3.2 布线技术 (5)1.3.3 网络拓扑结构 (5)第2章传输介质与接口技术 (5)2.1 有线传输介质 (5)2.1.1 双绞线 (6)2.1.2 同轴电缆 (6)2.1.3 光纤 (6)2.1.4 电力线通信 (6)2.2 无线传输介质 (6)2.2.1 无线局域网 (6)2.2.2 蓝牙 (6)2.2.3 无线广域网 (6)2.2.4 卫星通信 (7)2.3 网络接口卡与驱动程序 (7)2.3.1 网络接口卡 (7)2.3.2 驱动程序 (7)2.3.3 网络接口卡与驱动程序的故障排除 (7)第3章 IP地址与子网划分 (7)3.1 IP地址基础知识 (7)3.1.1 IP地址的格式与表示 (7)3.1.2 IP地址类型 (7)3.1.3 IP地址分配 (7)3.2 子网划分与VLSM (8)3.2.1 子网划分的基础知识 (8)3.2.2 子网掩码 (8)3.2.3 VLSM的应用 (8)3.3 公私网地址与NAT技术 (8)3.3.1 公私网地址 (8)3.3.2 私网地址范围 (8)10.0.0.0 ~ 10.255.255.255 (8)172.16.0.0 ~ 172.31.255.255 (8)192.168.0.0 ~ 192.168.255.255 (8)3.3.3 NAT技术 (8)第4章路由与交换技术 (9)4.1 路由原理与路由器配置 (9)4.1.1 路由基本概念 (9)4.1.2 路由器工作原理 (9)4.1.3 路由器配置方法 (9)4.1.4 路由器故障排除 (9)4.2 交换原理与交换机配置 (9)4.2.1 交换基本概念 (9)4.2.2 交换机工作原理 (9)4.2.3 交换机配置方法 (9)4.2.4 交换机故障排除 (9)4.3 路由协议与网络收敛 (10)4.3.1 路由协议概述 (10)4.3.2 常见路由协议 (10)4.3.3 网络收敛 (10)4.3.4 路由协议故障排除 (10)第5章网络安全策略 (10)5.1 防火墙配置与管理 (10)5.1.1 防火墙概述 (10)5.1.2 防火墙类型及选择 (10)5.1.3 防火墙配置方法 (10)5.1.4 防火墙管理策略 (10)5.2 VPN技术与应用 (11)5.2.1 VPN概述 (11)5.2.2 VPN关键技术 (11)5.2.3 VPN配置与应用 (11)5.3 入侵检测与防护系统 (11)5.3.1 入侵检测系统概述 (11)5.3.2 入侵防护系统 (11)5.3.3 入侵检测与防护系统配置与管理 (11)5.3.4 入侵检测与防护系统应用实践 (11)第6章常见网络故障排除方法 (11)6.1 故障排除流程与技巧 (11)6.1.1 故障排除的基本流程 (11)6.1.2 故障排除的技巧 (12)6.2 网络诊断工具与命令 (12)6.2.1 常用网络诊断工具 (12)6.2.2 常用网络诊断命令 (12)6.3 网络功能分析与优化 (12)6.3.1 网络功能分析 (12)6.3.2 网络优化措施 (13)第7章局域网故障排除 (13)7.1 拓扑结构与VLAN问题 (13)7.1.1 拓扑结构问题 (13)7.1.1.1 拓扑结构错误识别 (13)7.1.1.2 网络环路处理 (13)7.1.2 VLAN问题 (13)7.1.2.1 VLAN配置错误 (13)7.1.2.2 VLAN间路由问题 (13)7.2 交换机故障分析与处理 (14)7.2.1 交换机硬件故障 (14)7.2.2 交换机软件故障 (14)7.2.3 交换机功能问题 (14)7.3 无线网络故障分析与处理 (14)7.3.1 无线信号覆盖问题 (14)7.3.2 无线认证故障 (14)7.3.3 无线网络功能问题 (14)第8章广域网故障排除 (14)8.1 路由器故障分析与处理 (14)8.1.1 故障现象及原因 (14)8.1.2 故障排除方法 (15)8.2 公网连接与运营商问题 (15)8.2.1 故障现象及原因 (15)8.2.2 故障排除方法 (15)8.3 VPN故障分析与处理 (16)8.3.1 故障现象及原因 (16)8.3.2 故障排除方法 (16)第9章网络服务故障排除 (17)9.1 DNS服务故障分析与处理 (17)9.1.1 故障现象 (17)9.1.2 故障原因 (17)9.1.3 故障排除方法 (17)9.2 DHCP服务故障分析与处理 (17)9.2.1 故障现象 (17)9.2.2 故障原因 (17)9.2.3 故障排除方法 (17)9.3 邮件服务器故障分析与处理 (18)9.3.1 故障现象 (18)9.3.2 故障原因 (18)9.3.3 故障排除方法 (18)第10章网络安全事件处理 (18)10.1 安全事件分析与应急响应 (18)10.1.1 安全事件分类 (18)10.1.2 安全事件分析 (18)10.1.3 应急响应流程 (18)10.1.4 应急响应团队建设 (19)10.2 恶意软件与病毒防护 (19)10.2.1 恶意软件分类 (19)10.2.2 病毒防护策略 (19)10.2.3 恶意软件防护技术 (19)10.2.4 恶意软件防范意识 (19)10.3 数据泄露与防护措施 (19)10.3.1 数据泄露途径 (19)10.3.2 数据泄露防护策略 (19)10.3.3 数据泄露防护技术 (19)10.3.4 数据泄露应对措施 (20)第1章网络通信基础1.1 网络通信原理网络通信是现代信息技术的基础,它通过一系列的通信协议和设备实现数据在不同计算机之间的传输。
windowsnt环境下fddi网卡驱动程序设计(2)【摘要】本文介绍了在Windows NT环境下设计FDDI网卡驱动程序的相关内容。
在先概述了本文要讨论的内容,然后介绍了研究背景。
在分别讨论了驱动程序框架设计、硬件抽象层设计、设备管理器设计、中断处理设计和数据传输设计。
通过这些设计,可以有效地实现FDDI网卡在Windows NT环境下的驱动程序功能。
在结论部分总结了本文的主要内容,展望了未来可能的研究方向。
本文的设计和讨论为开发者提供了实用的指导,帮助他们更好地理解和应用FDDI网卡驱动程序设计。
【关键词】关键词:Windows NT、FDDI网卡、驱动程序设计、框架设计、硬件抽象层、设备管理器、中断处理、数据传输、总结、展望未来。
1. 引言1.1 概述Windows NT环境下FDDI网卡驱动程序的设计是一个重要的工作,它涉及到计算机网络领域中的硬件和软件技术。
FDDI(Fiber Distributed Data Interface)是一种用于局域网的高速传输技术,通过光纤传输数据,具有高带宽和低延迟的特点。
而在Windows NT操作系统中,网络设备的驱动程序是连接硬件设备和操作系统之间的桥梁,是实现设备功能的重要组成部分。
本文将围绕着Windows NT环境下FDDI网卡驱动程序的设计展开讨论,首先对驱动程序的框架进行设计,确定整体架构和功能模块。
然后针对硬件抽象层进行设计,实现与具体硬件设备的通信和控制。
接着对设备管理器进行设计,实现对设备的注册和管理。
同时还将探讨中断处理的设计和数据传输的设计,保证数据的高效传输和处理。
通过对Windows NT环境下FDDI网卡驱动程序的设计与实现,可以提高网络设备的性能和稳定性,同时扩展网络功能和提升用户体验。
本文的研究将为未来网络设备驱动程序设计提供参考,并为网络技术的发展做出贡献。
1.2 研究背景在当今数字化社会中,网络通信扮演着至关重要的角色。
软中断/tasklet/工作队列______整理软中断、tasklet和工作队列并不是Linux内核中一直存在的机制,而是由更早版本的内核中的“下半部”(bottom half)演变而来。
下半部的机制实际上包括五种,但2.6版本的内核中,下半部和任务队列的函数都消失了,只剩下了前三者。
本文重点在于介绍这三者之间的关系。
(函数细节将不会在本文中出现,可以参考文献,点这里)(1)上半部和下半部的区别上半部指的是中断处理程序,下半部则指的是一些虽然与中断有相关性但是可以延后执行的任务。
举个例子:在网络传输中,网卡接收到数据包这个事件不一定需要马上被处理,适合用下半部去实现;但是用户敲击键盘这样的事件就必须马上被响应,应该用中断实现。
两者的主要区别在于:中断不能被相同类型的中断打断,而下半部依然可以被中断打断;中断对于时间非常敏感,而下半部基本上都是一些可以延迟的工作。
由于二者的这种区别,所以对于一个工作是放在上半部还是放在下半部去执行,可以参考下面四条:a)如果一个任务对时间非常敏感,将其放在中断处理程序中执行。
b)如果一个任务和硬件相关,将其放在中断处理程序中执行。
c)如果一个任务要保证不被其他中断(特别是相同的中断)打断,将其放在中断处理程序中执行。
d)其他所有任务,考虑放在下半部去执行。
(2)为什么要使用软中断?软中断作为下半部机制的代表,是随着SMP(share memory processor)的出现应运而生的,它也是tasklet实现的基础(tasklet实际上只是在软中断的基础上添加了一定的机制)。
软中断一般是“可延迟函数”的总称,有时候也包括了tasklet(请读者在遇到的时候根据上下文推断是否包含tasklet)。
它的出现就是因为要满足上面所提出的上半部和下半部的区别,使得对时间不敏感的任务延后执行,而且可以在多个CPU上并行执行,使得总的系统效率可以更高。
它的特性包括:a)产生后并不是马上可以执行,必须要等待内核的调度才能执行。
linux中断处理上半部下半部实例Linux中断处理是操作系统中非常重要的一个功能,它负责处理硬件设备的中断请求。
中断处理过程可以分为上半部和下半部两个阶段。
本文将通过一个实例来详细介绍Linux中断处理的上半部和下半部。
让我们来了解一下什么是中断。
在计算机系统中,中断是指硬件设备向CPU发送信号,通知CPU需要进行处理的事件。
当CPU接收到中断信号时,会暂停当前正在执行的任务,并转而处理中断请求。
这样可以提高系统的响应速度和效率。
在Linux中,中断处理分为上半部和下半部。
上半部是指中断处理程序的第一阶段,它需要尽快地完成一些关键的任务,以确保系统的稳定性。
下半部是指中断处理程序的第二阶段,它可以在上半部完成的基础上进行更复杂、耗时的操作。
下面我们通过一个实例来说明中断处理的上半部和下半部。
假设我们有一个网络设备,它负责接收和发送网络数据包。
当有数据包到达时,设备会发送一个中断请求给CPU,通知CPU有数据包需要处理。
在中断处理的上半部,首先需要读取网络设备的状态寄存器,以确定中断的原因。
然后,根据中断的原因,执行相应的处理操作。
例如,如果是接收到数据包的中断,那么上半部需要将数据包从设备的接收缓冲区中读取出来,并且进行一些必要的校验和处理。
上半部的任务还包括更新设备的状态、清除中断标志等。
这些任务需要尽快完成,以确保系统的稳定性和实时性。
因此,在上半部的处理过程中,需要尽量避免长时间的延迟和阻塞操作。
当上半部的任务完成后,中断处理程序就会进入下半部。
下半部的任务可以是一些比较耗时的操作,例如将数据包交给上层协议栈进行处理、更新网络设备的缓冲区等。
由于下半部的任务可能会比较耗时,所以通常会通过软中断或工作队列的方式来延迟执行。
在Linux中,可以使用软中断来实现下半部的延迟执行。
软中断是一种由内核触发的中断,它可以在合适的时机执行下半部的任务。
通过软中断,可以将下半部的任务延迟到合适的时间点执行,以避免对系统的影响。
关于网卡名称运算机与外界的连接是通过主机箱内插入一块网络接口板(或是在电脑中插入一块)。
网络接口板又称为通信适配器或(adapter)或网络接口卡(Network Interface Card)可是此刻更多的人情愿利用更为简单的名称“网卡”。
安装网卡是需要有必然的网卡驱动,网卡也能够独立安装在主办的PCI插槽里面。
功能简述网卡是工作在的网路组件,是局域网中连接运算机和的接口,不仅能实现与局域网传输介质之间的物理连接和电信号匹配,还涉及帧的发送与接收、帧的封装与拆封、介质访问操纵、数据的编码与解码和数据缓存的功能等。
功能详解网卡上面装有处置器和存储器(包括RAM和ROM)。
网卡和局域网之间的通信是通过电缆或双绞线以串行传输方式进行的。
而网卡和运算机之间的通信那么是通过运算机上的I/O总线以并行传输方式进行。
因此,网卡的一个重要功能确实是要进行串行/并行转换。
由于网络上的数据率和运算机总线上的数据率并非相同,因此在网卡中必需装有对数据进行缓存的存储芯片。
在安装网卡时必须将管理网卡的设备安装在计算机的操作系统中。
这个驱动程序以后就会告诉网卡,应当从存储器的什么位置上将局域网传送过来的数据块存储下来。
网卡还要能够实现协议。
网卡并不是独立的自治单元,因为网卡本身不带电源而是必须使用所插入的计算机的电源,并受该计算机的控制。
因此网卡可看成为一个半自治的单元。
当网卡收到一个有差错的帧时,它就将这个帧丢弃而不必通知它所插入的计算机。
当网卡收到一个正确的帧时,它就使用中断来通知该计算机并交付给协议栈中的网络层。
当计算机要发送一个IP数据报时,它就由协议栈向下交给网卡组装成帧后发送到局域网。
随着集成度的不断提高,网卡上的芯片的个数不断的减少,虽然现在个厂家生产的网卡种类繁多,但其功能大同小异。
网卡的主要功能有以下三个:1.数据的封装与解封:发送时将上一层交下来的数据加上首部和尾部,成为以太网的帧。
接收时将以太网的帧剥去首部和尾部,然后送交上一层;2.链路管理:主要是CSMA/CD协议的实现;3.编码与译码:即曼彻斯特编码与译码。
DPDK收发包处理流程-----(⼀)⽹卡初始化本⽂基于DPDK-1.8.0分析。
⽹卡驱动模型⼀般包含三层,即,PCI总线设备、⽹卡设备以及⽹卡设备的私有数据结构,即将设备的共性⼀层层的抽象,PCI总线设备包含⽹卡设备,⽹卡设备⼜包含其私有数据结构。
在DPDK中,⾸先会注册设备驱动,然后查找当前系统有哪些PCI设备,并通过PCI_ID为PCI设备找到对应的驱动,最后调⽤驱动初始化设备。
⼀、⽹卡驱动注册以e1000⽹卡驱动为例说明。
在1.8.0版本中,⽹卡驱动的注册使⽤了⼀种奇技淫巧的⽅法,使⽤GCC attribute扩展属性的constructor属性,使得⽹卡驱动的注册在程序MAIN函数之前就执⾏了。
static struct rte_driver pmd_igb_drv = {.type = PMD_PDEV,.init = rte_igb_pmd_init,};static struct rte_driver pmd_igbvf_drv = {.type = PMD_PDEV,.init = rte_igbvf_pmd_init,};PMD_REGISTER_DRIVER(pmd_igb_drv);PMD_REGISTER_DRIVER(pmd_igbvf_drv);其中PMD_REGISTER_DRIVER()宏的定义如下:#define PMD_REGISTER_DRIVER(d)\void devinitfn_ ##d(void);\void __attribute__((constructor, used)) devinitfn_ ##d(void)\{\rte_eal_driver_register(&d);\}使⽤attribute的constructor属性,在MAIN函数执⾏前,就执⾏rte_eal_driver_register()函数,将pmd_igb_drv驱动挂到全局dev_driver_list链表上。
计算机网络课程设计一数据包发送和接受程序的实现《计算机网络》课程设计数据包发送和接受程序的实现计算机学院软件工程10级⑷班3110006379陈泳蒸2012年12月21日数据包发送和接受程序的实现一、设计题目与要求1.设计题目发送TCP数据包2.设计要求本设计的功能孚填充一个TCP数据包,并发送给目的主机。
1)以命令行形式运行:SendTCP sourcejp source_port destjp dest_port, 其中SendTCP是程序名,source_ip为源端IP地址,source_port为源端口号, destjp为目的地址,dest_port为目的端口号。
2)其他的TCP头部参数请自行设定。
3)数据字段为a Thls is my homework of network J am happy!4)成功发送后在屏幕上输出"send OK”。
三、详细设计本课程设计的目标是发送一个TCP数据包,可以利用原始套接字来完成这个工作。
整个程序由初始化原始套接字和发送TCP数据包两个部分组成。
当应用进程需要通过TCP发送时,它就将此应用层报文传送给执行TCP协议的传输实体。
TCP 传输实体将用户数据加上TCP报头,形成TCP数据包,在TCP数据包上增加IP头部,形成IP包。
如图-1显示的是TCP数据包和IP包得关系。
TCP 协议的数据传输单位称为报文段,其格式如图-2所示。
报文段报头的长度是20B~60B,选项部分长度最多为40Bo TCP报文段主要包括以下字段。
端口号:端口号字段包括源端口号和目的端口号。
每个端口号的长度是16位,分别表示发送该TCP包的应用进程的端口号和接收该TCP包的应用进程的端口号。
-1 TCP IP IP序号:长度为32位。
由于TCP协议是面向数据流的,它所传送的报文段可以视为连续的数据流,因此需要给每一字节编号。
序号字段的“序号”指的是本报文段数据的第一个字节的序号。
数据包接收系列 — 上半部实现(网卡驱动) 数据包接收系列 — 上半部实现(网卡驱动)网卡概述
(1) 网卡收包
网线上的物理帧首先被网卡芯片获取,网卡芯片会检查物理帧的CRC,保证完整性。然后网卡芯片将物理帧头去掉,得到MAC包。网卡芯片会检查MAC包内的目的MAC地址,如果和本网卡的MAC地址不一样则丢弃(混杂模式除外)。之后网卡芯片将MAC帧拷贝到网卡内部的缓冲区,触发硬中断。网卡的驱动程序通过硬中断处理函数,构建sk_buff,把它拷贝到内存中,接下来交给内核处理。在这个过程中,网卡芯片对物理帧进行了MAC匹配过滤,以减小系统负荷。
(2) 网卡发包
网卡驱动程序将IP包添加14字节的MAC头,构成MAC包。MAC包中含有发送端和接收端的MAC地址,由于是驱动程序创建MAC头,所以可以随便输入地址
进行主机伪装。驱动程序将MAC包拷贝到网卡芯片内部的缓冲区,接下来由网卡芯片处理。网卡芯片将MAC包再次封装为物理帧,添加头部同步信息和CRC校验,然后丢到网线上,就完成一个IP报的发送了,所有接到网线上的网卡都可以看到该物理帧。
(3) 网卡数据结构
网卡用net_device来表示,用register_netdevice()注册到系统中,注册过的网卡可以通过unregister_netdevice()注销掉。
[java] view plain copy 1. struct net_device { 2. char name[IFNAME]; /* 网卡名称,如eth0 */ 3. ... 4. unsigned long mem_end; /* shared mem end,共享内存结束地址 */ 5. unsigned long mem_start; /* shared mem start ,共享内存起始地址 */ 6. unsigned long base_addr; /* device I/O address,设备内存映射到I/O内存的起始地址 */ 7. unsigned int irq; /* device IRQ number,硬中断编号 */ 8. ... 9. unsigned long state; /* 网卡的状态 */ 10. ... 11. struct list_head dev_list; 12. struct list_head napi_list; /* NAPI使用 */ 13. ... 14. unsigned long features; /* 网卡功能标识 */ 15. ... 16. int ifindex; /* Interface index. Unique device identifier. 设备ID */ 17. ... 18. struct net_device_stats stats; /* 统计变量 */ 19. /* dropped packets by core network. 20. * Do not use this in drivers. 21. * 被内核丢弃的数据包个数。 22. */ 23. atomic_long_t rx_dropped; 24. ... 25. /* Management operations */ 26. const struct net_device_ops *netdev_ops; /* 网卡的操作函数集 */ 27. const struct ethtool_ops *ethtool_ops; /* 配置网卡 */ 28. ... 29. unsigned int promiscuity; /* 混杂模式计数器 */ 30. ... 31. struct netdev_queue *ingress_queue; 32. struct netdev_queue *_tx; 33. ... 34. }; 35. 36. /* 网卡的操作函数集 */ 37. struct net_device_ops { 38. int (*ndo_init) (struct net_device *dev); 39. void (*ndo_uninit) (struct net_device *dev); 40. int (*ndo_open) (struct net_device *dev); 41. int (*ndo_stop) (struct net_device *dev); 42. /* Called when a packet needs to be transmitted */ 43. netdev_tx_t (*ndo_start_xmit) (struct sk_buff *skb, struct net_device *dev); 44. ... 45. };
(4) 网卡中断处理函数
产生中断的每个设备都有一个相应的中断处理程序,是设备驱动程序的一部分。每个网卡都有一个中断处理程序,用于通知网卡该中断已经被接收了,以及把网卡缓冲区的数据包拷贝到内存中。当网卡接收来自网络的数据包时,需要通知内核数据包到了。网卡立即发出中断:嗨,内核,我这里有最新的数据包了。内核通过执行网卡已注册的中断处理函数来做出应答。中断处理程序开始执行,通知硬件,拷贝最新的网络数据包到内存,然后读取网卡更多的数据包。这些都是重要、紧迫而又与硬件相关的工作。内核通常需要快速的拷贝网络数据包到系统内存,因为网卡上接收网络数据包的缓存大小固定,而且相比系统内存也要小得多。所以上述拷贝动作一旦被延迟,必然造成网卡缓存溢出 - 进入的数据包占满了网卡的缓存,后续的包只能被丢弃。当网络数据包被拷贝到系统内存后,中断的任务算是完成了,这时它把控制权交还给被系统中断前运行的程序。处理和操作数据包的其他工作在随后的下半部中进行。
上半部的实现 接收数据包的上半部处理流程为:el_interrupt() // 网卡驱动
|--> el_receive() // 网卡驱动
|--> netif_rx() // 内核接口
|--> enqueue_to_backlog() // 内核接口
这里以3c501网卡驱动为例来进行分析(这是个古董级网卡,实现简单:) el_interrupt
3c501的网卡中断处理函数为el_interrupt(),调用inb()来获取当前中断处理结果,如果是RX_GOOD,
表明网卡成功接收了数据包,则调用el_receive()来进行接收处理。[java] view plain copy 1. /** 2. * el_interrupt: 3. * @irq: Interrupt number 4. * @dev_id: The 3c501 that burped 5. */ 6. 7. static irqreturn_t el_interrupt(int irq, void *dev_id) 8. { 9. struct net_device *dev = dev_id; 10. struct net_local *lp; 11. int ioaddr; 12. int axsr; /* Aux. status reg. */ 13. 14. ioaddr = dev->base_addr; /* I/O映射地址 */ 15. lp = netdev_priv(dev); /* 网卡的私有数据 */ 16. spin_lock(&lp->lock); /* 上锁 */ 17. 18. /* What happened? */ 19. axsr = inb(AX_STATUS); 20. 21. /* log it */ 22. if (el_debug > 3) 23. pr_debug("%s: el_interrupt() aux = %#02x\n", dev->name, axsr); 24. if (lp->loading == 1 && ! lp->txing) 25. pr_warning("%s: Inconsistent state loading while not in tx\n", dev->name); 26. 27. if (lp->txing) { /* 处于发送模式,这里不研究 */ 28. /* Board in transmit mode. */ 29. ... 30. 31. } else { 32. /* In receive mode. 处于接收模式 */ 33. int rxsr = inb(RX_STATUS); /* 获取中断处理的结果 */ 34. if (el_debug > 5) 35. pr_debug("%s: rxsr=%02x txsr=%02x rp=%04x\n", dev->name, rxsr, 36. inb(TX_STATUS), inw(RX_LOW)); 37. 38. /* Just reading rx_status fixes most errors. */ 39. if (rxsr & RX_MISSED) /* 没有接收到数据包 */ 40. dev->stats.rx_missed_errors++; 41. else if (rxsr & RX_RUNT) { /* 数据包长度错误 */ 42. /* Handled to avoid board lock-up. */ 43. dev->stats.rx_length_errors++; 44. if (el_debug > 5) 45. pr_debug("%s: runt.\n", dev->name); 46. 47. } else if (rxsr & RX_GOOD) { 48. /* Receive worked, 成功接收数据包 */ 49. el_receive(dev); /* 接收函数 */ 50. 51. } else { 52. /* Nothing? Something is broken! */ 53. if (el_debug > 2) 54. pr_debug("%s: No packet seen, rxsr=%02x **resetting 3c501***\n", dev->name, rxsr); 55. 56. el_reset(dev); /* 网卡出错,重置 */ 57. } 58. } 59. 60. /* Move into receive mode */ 61. outb(AX_RX, AX_CMD); 62. outw(0x00, RX_BUF_CLR); 63. inb(RX_STATUS); 64. inb(TX_STATUS); 65. spin_unlock(&lp->lock); 66. out: 67. return IRQ_HANDLED; 68. }