Linux网络设备分析(netdriver)

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

Linux网络设备分析潘纲〖1〗Linux网络设备分析潘纲9811536浙江大学计算机系pg@ccnt.zju.edu.cn[摘要]在本文中,首先概括了网络设备总体特征和工作原理,接着在分析了一个重要的数据结构device后,重点剖析了网络设备的整个初始化工作过程;简单地分析了设备的打开和关闭的操作后,是有关数据包的传输和接收的分析;在最后,本文对写网络设备驱动程序做了一个总结。以上的每部分的分析,都是在NE2000以太网卡的基础上进行的。在附录中是一个虚拟的字符设备驱动程序以及写这个程序的体会,该程序已成功使用过,它是在网络设备分析之前本人做的一个小小的试验。一.网络设备概述在LINUX中,为了简化对设备的管理,所有外围的硬件设备被归结为三类:字符设备(如键盘、鼠标等)、块设备(如硬盘、光驱、软驱等)和网络设备(也称为网络接口,networkinferface),如以太网卡。在本文中,我们将等效使用“网络设备”和“网络接口”这两个概念,而对某个具体的网络设备,我们将称之为“物理设备”或“物理网络设备”。为了屏蔽网络环境中物理网络设备的多样性,LINUX对所有的物理设备进行抽象并定义了一个统一的概念,称之为接口(Interface)。所有对网络硬件的访问都是通过接口进行的,接口提供了一个对所有类型的硬件一致化的操作集合来处理基本数据的发送和接收。一个网络接口被看作是一个发送和接收数据包(packets)的实体。对于每个网络接口,都用一个device的数据结构表示,有关该数据结构的具体内容,将在本文的后面详细介绍。通常,网络设备是一个物理设备如以太网卡,但软件也可以作为网络设备,如回送设备(loopback)。在内核启动时,通过网络设备驱动程序,将登记存在的网络设备。设备用标准的支持网络的机制来转递收到的数据到相应的网络层。所有被发送和接收的包都用数据结构sk_buff表示。这是一个具有很好的灵活性的数据结构,可以很容易增加或删除网络协议数据包的首部。网络设备作为其中的三类设备之一,它有其非常特殊的地方。它与字符设备及块设备都有很大的不同:网络接口不存在于Linux的文件系统中,而是在核心中用一个device数据结构表示的。每一个字符设备或块设备则在文件系统中都存在一个相应的特殊设备文件来表示该设备,如/dev/hda1、/dev/sda1、/dev/tty1等。网络设备在做数据包发送和接收时,直接通过接口访问,不需要进行文件的操作;而对字符设备和块设备的访问都需通过文件操作界面。网络接口是在系统初始化时实时生成的,对于核心支持的但不存在的物理网络设备,将不可能有与之相对应的device结构。而对于字符设备和块设备,即使该物理设备不存在,在/dev下也必定有相应的特殊文件与之相对应。且在系统初始化时,核心将会对所有内核支持的字符设备和块设备进行登记,初始化该设备的文件操作界面(structfile_operations),而不管该设备在物理上是否存在。以上两点是网络设备与其他设备之间存在的最主要的不同。然而,它们之间又有一些共同之处,如在系统中一个网络设备的角色和一个安装的块设备相似。一个块设备在blk_dev数组及核心其他的数据结构中登记自己,然后根据请求,通过自己的request_function函数“发送”和“接收”数据块。相似地,为了能与外面世界进行数据交流,一个网络接口也必须在一个特殊的数据结构中登记自己。在系统内核中,存在字符设备管理表chardevs和块设备管理表blkdevs,这两张保存着指向file_operations结构的指针的设备管理表,分别用来描述各种字符驱动程序和块设备驱动程序。Linux网络设备分析潘纲〖2〗类似地,在内核中也存在着一张网络接口管理表dev_base,但与前两张表不同,dev_base是指向device结构的指针,因为网络设备是通过device数据结构来表示的。dev_base实际上是一条device结构链表的表头,在系统初始化完成以后,系统检测到的网络设备将自动地保存在这张链表中,其中每一个链表单元表示一个存在的物理网络设备。当要发送数据时,网络子系统将根据系统路由表选择相应的网络接口进行数据传输,而当接收到数据包时,通过驱动程序登记的中断服务程序进行数据的接收处理(软件网络接口除外)。以下是网络设备工作原理图:dev_queue_xmit()上层下传数据netif_rx()向上层传送数据DEVICE结构的变量和方法(设备接口)mydev_interrupt()(中断服务程序)从硬件接收数据hard_start_xmit()向硬件发送数据初始化程序网络物理设备和媒介图一Linux网络设备工作原理图每一个具体的网络接口都应该有一个名字,以在系统中能唯一标识一个网络接口。通常一个名字仅表明该接口的类型。Linux对网络设备命名有以下约定:(其中N为一个非负整数)ethN以太网接口,包括10Mbps和100Mbps;trN令牌环接口;slNSLIP网络接口;pppNPPP网络接口,包括同步和异步;plipNPLIP网络接口,其中N与打印端口号相同;tunlNIPIP压缩频道网络接口;nrNNetROM虚拟设备接口;isdnNISDN网络接口;dummyN空设备;lo回送网络接口。二.重要数据结构——structdevice结构device存储一个网络接口的重要信息,是网络驱动程序的核心。在逻辑上,它可以分割为两个部分:可见部分和隐藏部分。可见部分是由外部赋值;隐藏部分的域段仅面向系统内部,它们可以随时被改变。下面我们将对之进行详细的分析和解剖。/*frominclude/linux/netdevice.h*/structdevice{1.属性char*name;设备的名字。如果第一字符为NULL(即’\0’),register_netdev(drivers/net/net_init.c)将Linux网络设备分析潘纲〖3〗会赋给它一个n最小的可用网络设备名ethn。unsignedlongrmem_end;/*shmemrecvend*/unsignedlongrmem_start;/*shmemrecvstart*/unsignedlongmem_end;/*sharedmemend*/unsignedlongmem_start;/*sharedmemstart*/这些域段标识被设备使用的共享内存的首地址及尾地址。如果设备用来接收和发送的内存块不同,则mem域段用来标识发送的内存位置,rmem用来标识接收的内存位置。mem_start和mem_end可在系统启动时用内核的命令行指定,用ifconfig可以查看它们的值。rmem域段从来不被驱动程序以外的程序所引用。unsignedlongbase_addr;/*deviceI/Oaddress*/unsignedcharirq;/*deviceIRQnumber*/I/O基地址和中断号。它们都是在设备检测期间被赋值的,但也可以在系统启动时指定传入(如传给LILO)。ifconfig命令可显示及修改他们的当前值。volatileunsignedcharstart;/*startanoperation*/volatileunsignedcharinterrupt;/*interruptarrived*/这是两个二值的低层状态标志。通常在设备打开时置start标志,在设备关闭时清start标志。当interrupt置位时,表示有一个中断已到达且正在进行中断服务程序理。unsignedlongtbusy;/*transmitterbusymustbelongforbitops*/标识“发送忙”。在驱动程序不能接受一个新的需传输的包时,该域段应该为非零。structdevice*next;指向下一个网络设备,用于维护链表。unsignedcharif_port;记录哪个硬件I/O端口正在被接口所用,如BNC,AUI,TP等(drivers/net/de4x5.h)。unsignedchardma;设备用的DMA通道。一些设备可能需要以上两个域段,但非必需的。unsignedlongtrans_start;/*Time(injiffies)oflastTx*/上次传输的时间点(injiffies)unsignedlonglast_rx;/*TimeoflastRx*/上次接收的时间点(injiffies)。如trans_start可用来帮助内核检测数据传输的死锁(lockup)。unsignedshortflags;/*interfaceflags(alaBSD)*/该域描述了网络设备的能力和特性。它包括以下flags:(include/linux/if.h)IFF_UP表示接口在运行中。当接口被激活时,内核将置该标志位。IFF_BROADCAST表示设备中的广播地址时有效的。以太网支持广播。IFF_DEBUG调试模式,表示设备调试打开。当想控制printk及其他一些基于调试目的的信息显示时,可利用这个标志位。虽然当前没有正式的驱动程序使用它,但它可以在程序中通过ioctl来设置从而使用它。IFF_LOOPBACK表示这是一个回送(loopback)设备,回送接口应该置该标志位。核心是通过检查此标志位来判断设备是否是回送设备的,而不是看设备的名字是否是lo。IFF_POINTTOPOINT表示这是一个点对点链接(SLIPandPPP),点对点接口必须置该标志位。Ifconfig也可Linux网络设备分析潘纲〖4〗以置此标志位及清除它。若置上该标志位,则dev-dstaddr应也相应的置为链接对方的地址。IFF_MASTER/*masterofaloadbalancer*/IFF_SLAVE/*slaveofaloadbalancer*/此两个标志位在装入平等化中要用到。IFF_NOARP表示不支持ARP协议。通常的网络接口能传输ARP包,如果想让接口不执行ARP,可置上该标志位。如点对点接口不需要运行ARP。IFF_PROMISC全局接受模式。在该模式下,设备将接受所有的包,而不关这些包是发给谁的。在缺省情况下,以太网接口会使用硬件过滤,以保证只接受广播包及发给本网络接口的包。Sniff的原理就是通过设置网络接口为全局接受模式,接受所有到达本接口媒介的包,来“偷听”本子网的“秘密”。IFF_MULTICAST能接收多点传送的IP包,具有多点传输的能力。ether_setup缺省是置该标志位的,故若不想支持多点传送,必须在初始化时清除该标志位。IFF_ALLMULTI接收所有多点传送的IP包。IFF_NOTRAILERS/*无网络TRAILER*/IFF_RUNNING/*资源被分配*/此标志在Linux中没什么用,只是为了与BSD兼容。unsignedshortfamily;/*addressfamilyID(AF_INET)*/该域段标识本设备支持的协议地址簇。大部分为AF_INET(英特网IP协议),接口通常不需要用这个域段或赋值给它。unsignedshortmetric;/*routingmetric(notused)*/unsignedshortmtu;不包括数据链路层帧首帧尾的最大传输单位(MaximumTransferUnit)。网络层在包传输时要用到。对以太网而言,该域段为1500,不包括MAC帧的帧首和帧尾(MAC帧格式稍后所示)。unsignedshorttype;/*interfacehardwaretype*/接口的硬件类型,描述了与该网络接口绑在一起的媒介类型。Linux网络设备支持许多不同种类的媒介,如以太网,X.25,令牌环,SLIP,PPP,AppleLocaltalk等。ARP在判定接口支持哪种类型的物理地址时要用到该域段。若是以太网接口,则在ether_setup中将之设为ARPHRD_ETHER(Ethernet10Mbps)。unsignedshorthard_header_len;/*

1 / 29
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功