Linux就这个范儿 第13章 打通任督二脉
0111010110……你有没有想过,数据从看得见或看不见的线缆上飞来飞去,是怎么实现的呢?数据传输业务的未来又在哪里?在前面两章中我们学习了Linux网络方面的各种工具,打造了形形色色的网络服务。然而我们并不满足于仅仅知道这些表面的知识,还希望深入了解它们的底层实现。那就来吧,打通任督二脉,探究不同类型的网络以及隐藏在网络后面的世界。
13.1 了解网络驱动
工欲善其事,必先利其器。二十年前我们还走在狭窄的乡间小道开着信息牛车。时至今日,信息高速公路已经初具规模,传输速度已经可达上Gb/s。牛车肯定不行了,那得是汽车才行。
物理层 一层:转发/中继器 延长物理介质
链路层 二层:网桥bridge 、交换机连接异种网络
网络层 三层:包 寻址、路由器或3层交换机
13.1.1 网络设备闲谈
在这里我就简单介绍一下主要有哪几种承载数据的“汽车”,让你先有个感性认识。
首先说转发/中继器。它工作在网络的第一层。它的主要作用是延长物理介质的传输距离或转换物理传输介质。目前在传输速度要求高的主干线上大都使用光纤作为传输介质。
然后就是网桥,它工作在网络的第二层,可以转换不同网络类型的数据帧。因此网桥可以用来分隔网段或连接部分异种网络,透明网桥使两个网段之间看起来像一个网段。多口网桥就是交换机。顺便解释一下两个基本概念:帧( Frame)和包(Packet)。帧一般指网络第二层的数据格式,而包则指的是网络第三层的数据格式。
估计你都看出了我的逻辑,该第三层了,是路由器,它处理的就是包。当然,它处理下面两层的工作也没问题。由于第三层完全是软件层,因此路由器可以做的事很多,除了可以
转换网络接口、连接异种网络、隔离网络广播、转换网络协议外,它的主要工作是路由寻径。一个简单的路由器上可以实现ARP、IP、ICMP、UDP、SNMP和RIP等协议。在稍大一些的网络里基本不可能存在任何两点直接连接或用广播方式来通信的情形。当然在小型网络中可以用子网化( subnetting)做一做,但是在中大型网络中必须仔细规划网络拓扑结构、选择合适的路由协议,这是很重要的事情!出于这种考虑,现在很多交换机把路由技术做在里面了,市面上也就有了三层交换机这种产品。
接着往上说,应该是网关了。网关按照定义应该是工作在网络第四层以上。但实际网络
应用中网关这个概念很宽泛,它是指连接两个网络之间的设备,比如你的Linux计算机上有两个网卡分别连接了两个不同的网段,你添加适当的路由规则使两个网段连通了,那么在这两个网络中你的Linux计算机就称为网关。如果按这种说法,路由器也算是网关,它可能连接了多个网络而实现了多个网关的功能。你在配置主机时,把网关这一项指向路由器,数据就能直接到达这个接口上。
网络离小开安全的考虑,这时候防火墙就派上用场了。防火墙是在内部网和外部网、专用网与公共网之间构造的保护屏障,使Internet与Intranet之间建立起一个安全网关(Security
Gateway),从而保护内部网免受非法用户的侵入。防火墙主要由服务访问规则、验证工具、包过滤和应用网关4个部分组成。
网络设备除了常用的以上几种外,还有调制解调器和VPN设备等。Linux这玩意儿支持很多种网络接口设备和网络协议,为中小公司提供了绝佳的平台以及基础知识库。
Linux 2.6的开发历程中,模块子系统有了重大改进,使系统更加透明,也使得越来越多的网络设备采用Linux作为其操作系统。
但是Linux在网络领域也不是全能的。基于以太网技术的交换机再快也只能适用于中小
规模的网络,因为它的交换吞吐能力和路由能力还是不行。构建广域骨干网时,网络层采用IP协议是无须质疑的,但是采用何种技术传输IP搬文则成为人们争执焦点问题。
目前,IP over ATM、IP over SONET/SDH是被广泛采用的两种技术,只是Linux对ATM的支持还属于pre-alpha阶段,目前还只是实验产品。
好了,咱们已经把各种网络设备摆在眼前了,但是这些设备可不是个个都很听话。Linux若要降服它们,必须得有把刷子才行。那么我们就看看这把刷子吧。
13.1.2 ioctl这把刷子
编写设备驱动的朋友对ioctl 一定不会陌生,它是设备驱动程序对设备的I/O通道进行管理的一个系统调用。所谓对I/O通道进行管理,就是对设备的一些特性进行控制,比如无线设备的信号强度和串口的传输波特率等。但实际上ioctl所处理的对象并不仅限于真正的I/O设备,还可以是其他的任何一个内核设备。ioctl以系统调用的形式为用户提供与内核交互的便利手段。我们可以利用ioctl设置IP地址、路由和防火墙等参数。
也许有人会问:“为什么要用ioctl实现I/O通道控制功能呢?用write方法也可以呀,把数据流标识出一个特殊的约定字符,这种特殊约定的字符后面就是控制命令不就行了吗?”是的,这种方法确实可以实现控制功能!但是利用ioctl实现控制能使程序结构更清晰,扩展性更好。
用户程序和驱动程序分工很明确。用户程序的任务是通过ioctl告诉驱动程序它
想做什么,至于完成这些命令就是驱动程序的责任了。
为了便于理解,根据功能,可以把和网络相关的请求划分为以下三个小类:
1. 改变路由表(例如SIOCADDRT、SIOCDELRT) 2. 读/更新ARP/RARP缓存(例如SIOCDARP、SIOCSRARP) 3. 一般的与网络接口有关的(例如SIOCGIFNAME、SIOCSIFADDR等等)
$ arp
Address HWtype HWaddress Flags Mask Iface
10.105.0.1 ether fe:ee:ff:ff:ff:ff C eth0 网关
10.105.9.115 ether fe:ee:ff:ff:ff:ff C eth0
$ arp -a
? (10.105.0.1) at fe:ee:ff:ff:ff:ff [ether] on eth0
? (10.105.9.115) at fe:ee:ff:ff:ff:ff [ether] on eth0
举例来说,与网络接口有关的ioctl调用使用的请求参数通常看起来像“SIOCxIFyyyy”的形式,这里的“x”要么是“S”(设定set,写write),要么是“G”(得到get,读read)。我们可能还会遇到类似这样的问题。例如在编写802.11无线网络设备管理工具时,有一些与之有关的额外参数需要设置与查询。在通用的网络接口ioctl命令中没有也不可能有这种定义。幸运的是,Linux操作系统中已经为实现这个目的内建了一种挂钩(hook)机制。当你翻看sockios.h文件时,你将发现每一种设备已经预先定义了SIOCDEVPRIVATE命令和SIOCDEVPRIVATE+15的命令,而它的实现将留给开发相应驱动程序的人去完成。例如有一个用户程序使用ioctl(sockid,SIOCDEVPRIVATE,(char*)&ifr)来调用与某种设备相关的ioctl命令,这里ifr的类型是struct ifreq。这个结构在/usr/include/net/if.h中定义,结构体的具体定义如下:
struct ifreq { # define IFHWADDRLEN 6 # define IFNAMSIZ IF_NAMESIZE union { char ifrn_name [IFNAMSIZ];/*Interface name,e.g. “en0”, */ } ifr_ifrn; union { struct sockaddr ifru_addr; struct sockaddr ifru_dstaddr; struct sockaddr ifru_broadaddr; struct sockaddr ifru_netmask; struct sockaddr ifru_hwaddr; short int ifru_flags; int ifru_ivalue; intifru_mtu; struct ifmap ifru_map; char ifru_slave [IFNAMSIZ]; /*Just fits the size*/ char ifru _newname [IFNAMSIZ]; _caddr_t ifru_data; }ifr_ifru; };
它被用来配置IP地址、激活接口和配置MTU等。用户程序应当在ifr.ifr_name中填充
与这个设备相关的名字,比如Atheros无线网络芯片的驱动设备名就是ath0。设置与查询
802.11的SSIDO①和认证加密方式等操作可烈通过ifr.ifr data这个变量来实现。
① SSID(Service Set ldentifier)是指服务装置ID.其实就足无线AP的MAC地址。
内核实现ioctl系统调用的是sys_ioctl()函数,图13.1展示了ioctl的基本框架,主要展
现了网络的ioctl控制部分。sys_ioctl通过filp->f_op->ioctl调用unlocked ioctl。在unlocked_ioctl之后呢?我们再顺藤摸瓜,沿着unlocked_ioctl多走儿步,我们就可以找到真正实现IO控制的实际函数。
为什么不直接在filp->f_op->ioctl函数指针指向的函数里面执行ioctl控制操作,而要做两次跳转呢?别着急,接下来我就说说其中的原因。
第一次跳转是为了实现与文件系统平级。从图中可以看出filp->f_op财ioctl的访问转化成为对unlocked_ ioctl函数的调用。
第二次跳转的原因是ipv4、ipv6套接字以及sock_raw原始套接字需要有不同的控制,通过跳转支持不同层次和类型的套接字。这种调用设计为x25、ipx、netlink、Unix域等地址族所对应的文件,提供属于自己的协议标准操作函数指针,从而达到支持不同的ioctl处理函数的目的。
接下来我们看到inet_ioctl函数内容分支很多。主要有路由选项操作、ARP系统高速缓
存操作、套接字操作、网桥控制和接口操作等。例如系统带有的命令工具ifconfig对IP地址的配置处理,基本都在devinet_ioctl函数中;arp命令的处理都在arp_ioctl中处理:路由配
置都在ip_rt_ioctl中处理。其中参数arg是用户空间传来的自定义的数据,可以是结构,可
以是联合或其他一些更复杂的类型。arg具体含义由具体的业务模块来解释处理。驱动程序
要实现的IO控制操作是在dev_ioctl函数中实现的,在后面小节中我们会有所涉及。
13.1.3设备驱动的秘密
网络层协议《-》网络协议接口层《-》网络设备接口层《-》设备驱动层《-》设备
ioctl那把刷子我们就先说到这,接下来我要告诉你一个秘密:网络设备驱动层就是连接网络堆栈协议层和网络硬件的中间层,也就是个中介。它本身可以分为三层,从上到下依次
是:网络协议接口层、网络设备接口层和设备驱动层。
网络协议接口层向网络层协议提供统一的数据收发服务,通过dev_queque_xmit()函数
发送数据,netif_rx()函数接收数据。
网络设备接口层提供了一个统一的用于描述设备属性和操作的结构体net- device。net device就像一个大罐子,在这个大罐子里装满了设备驱动层要实现的各种函数名。
设备驱动层实现设备接口层net_device里的具体成员函数,通过hard_start_xmit()函数启动发送操作,而接收操作则是利用网络设备上的中断来触发。程序员需要完成的工作主要集中在设备驱动层上。
网络驱动设计的结构允分体现了统一的思想。话说这种统一所产生的作用相当强大。战国时期的秦国就是采取统一货币、统一度量衡和统一文字这些举措推动了社会的进步,最终统一中国。驱动设计中这种统一对Linux的网络驱动实现也非常重要。
首先,不同协议的操作流程是统一的。应用程序通过内核从上层到下层添加不同的协议
到sk_buff中直至交给网络设备,驱动从网络设备接收数据转换为sk_buff数据结构传递给
上层,各层剥去相应的协议头直至交给用户。
其次,网络设备的数据结构定义是统一的。Net_ device是网络设备的代表,为了千变万化的网络设备定义了一个统一抽象的数据结构,涵盖了网络设备信息(设备名等)、硬件信息(I/O基地址和中断号等)、网络接口(MTU等)和设备操作函数等方面的统一定义,实现了多种硬件在软件上的统一。
再次,由于这种统一的模块设计,网络驱动开发采用的是一种较为固定的开发模式,降低了驱动开发的复杂性,使开发者更专注于与设备本身相关的程序开发。
通常来讲,Linux驱动程序有两种加载方式:一种是静态地编译进内核,内核启动时自(内核会变得很大,参考生死与共的兄弟)
动加载;另一种是编写为内核模块(IPVS模块也是动态加载到内核),使用insmod命令将模块动态加载到正在运行的内核,不需要时可用rmmod命令将模块卸载。Linux 2.6内核引入了kbuild机制,将外部内核模块的编译同内核源码树的编译统一起来,大大简化了特定的参数和宏的设置。这样要将编写好的驱动模块加入内核源码树,只需修改相应目录的Kconfig丈件,新的驱动就加入到了内核的配置菜单,然后修改相应子目录中与模块编译相关的Kbuild Makefile,即可使新的驱动在内核源码树中被编译。
Linux网络设备驱动的主要功能就是网络设备的初始化、网络设备的配置、数据包的收
发。例如,开发以太网驱动程序的过程,首先是理解网络驱动的实现原理和程序的结构框架,
然后参照内核源码树中相应的模板程序,结合具体物理设备的硬件手册改造涉及硬件部分的
代码,实现相应的操作函数。具体而言,网络驱动程序根据功能划分有驱动程序的注册和注
销、设备的打开和释放、数据的发送、数据的接收和中断处理以及控制操作四大部分。这里
我们就以在2.6.26内核上运行的Intel el000网卡为例简单说说网卡驱动程序的这几部分。
首先是网络设备初始化。如果网络设备是PCl规范的,则先是在module_ init模块所指的函数里向内核注册该PCI设备(pci_register- driver)。然后由pci_driver数据结构中的probe函数指针所指向的侦测函数(例如e1000_probe)来初始化该PCI设备,并且同时注册和初始化该网络设备。内核加载网络驱动模块时,就会调用初始化过程。
虽然我们完成了初始化设备,但是如果没有设备打开函数的支持,设备也无法开始正常工作。接下来我们就讲讲网络驱动程序的第二部分,即网络设备的打开(或关闭)的实现。为了更形象地说明,我们从ifconfig命令说起。当系统响应ifconfig命令时,系统会打开/关闭一个网络接口。ifconfig命令开始调用ioctI(SIOCSIFADDR)函数来将地址赋予接口。响应SIOCSIFADDR接口命令的任务是由内核来完成的,与设备无关。紧接着,ifconfig命令会调用ioctI(SIOCSIFFLAGS)设置dev->flag的IFF_UP位来打开设备,这个调用会使设备的open方法得到调用。当ifconfig调用ioctI(SIOCSIFFLAGS)清除dev->flag的IFF_ UP位时,设备的stop方法将被调用。
当设备被打开之后就可以开始数据的收发工作了。先说数据包的发送,它是网络驱动程序中需要实现的重要任务之一,也是驱动程序第三部分需要做的工作。通过调用net_device结构中的hard_ start_ xmit方法把存放在sk_buff中的数据发送到网络物理设备。如果发送成
功,则在hard_start_xmit中释放sk_buff并返回0;如果硬件设备忙暂时无法处理,则返回1。在e1000驱动中使用在hard_start_xmit方法中注册的函数来发送数据,也就是数据发送函数
el000_ xmit_frame()。该函数实现把数据发送到以太网上,由网络协议接口层函数dev_queue_xmit()对其调用。
第四部分要讲的是网络数据包的接收和中断处理,它是网络驱动程序中的最重要的部分,也是其中难度最大的开发任务。网络设备是异步地接收外来的数据包并且主动“请求”将硬件获得的数据包压入内核。网络设备接收数据包是通过中断实现的。网络接口在接收到新数据包、发送完成或者报告错误信息和连接状态等情况下都会触发中断,通常中断处理程序通过检测硬件状态寄存器来判断是哪种情况。当设备收到数据后会产生一个中断,由硬件通知驱动程序有数据包到达,然后把接收处理函数放入NAPI调度中。NAPI是一种软件方案,用来平衡CPU和网卡芯片的利用率,以poll形式接收数据包(select-》poll-》epoll),当第一次中断发生后,中断处理程序要禁止设备的数据包接收中断。在高负载的情况下,NAPI能产生更好的性能,避免了为每个传入的帧都产生中断。此外,当e1000驱动把网卡的数据导到系统的主内存时,它采用了DMA技术。网卡直接从主内存里读写数据,不需要CPU帮忙。驱动程序经常利用这种方法为CPU减负。
在上面几个部分实现后,网络驱动程序要实现的基本任务算是完成了。但是我们还需要为上层应用提供操作设备的接口。你会发现驱动注册函数中还包括IO控制函数,用它来完成硬件读写。在e1000驱动中IO控制函数注册有e1000_ioctl(),用它可以调用e1000_ mii_ioctl()以此实现对MII接口的读写设置。
至此我们完成了模块化的网络驱动程序的设计开发,然后就可以把这个模块编译进内核,并将这个自定义的内核模块作为Linux系统源码的一部分编译出新的系统。由于Linux 2.6内核引入了kbuild的新机制,使得编译新的内核模块或者将自己编写的内核模块集成到内核源码中的工作变得非常简单,具体过程如下:首先把需要版本的内核源码解压在/usr/src/路径下,然后内核源码的主目录下使用make menuconfig或者make gconfig命令配置内核。在配置选项中有三种状态可选:未选中(不编译)、选中(M)一编译为模块、选中(*)—编译为新系统一部分。在模块等选项配置完成并保存之后,我们使用make all来完整编译内核。
13.2 无线风光在险峰
………(嘀嘀嘀,嗒嗒嗒,嘀嘀嘀),你熟悉这个东西吗?它代表什么含义?
这是莫尔斯电码。当十九世纪第一台无线电发射器向外发送摩尔斯码时,就已经预示着无线通信时代的到来。到了20世纪末,调制解调披术使得利用无线电发射声音和图像成为可能,标志着人类从此步入了无线通信的时代。随着电视和数据通信的出现,无线有了更广泛的用途。不能不说无线风光在险峰,WLAN、Bluetooth、NFC、Infrared和3G等各种无线通信技术在不同应用场景下发挥着巨大的作用。各种通信方式的传输范围和传输速率可参考图13.2。
13.2.1 WLAN
WLAN为Wireless LAN的简称,即无线局域网。无线局域网是一种利用无线电技术实现接入以太网的方法。
我是在1998年接触WLAN的,当时跟随Tom Tsoulogiannis和Anil Sanwalka两位大师做WLAN AP。他们是IEEE 802.11的委员,参与了第一个802.11标准的制定,完成了第一个商用的802.11芯片上的同件。当时wifi芯片并没有那么普及,我们的设备还像玩具似的在博物馆里当作无线向导使用。不想十几年间,802. lla/b/g/n标准飞速发展,随着MIMO OFDM技术、智能天线技术和软件无线电技术的采用,传输速率从11Mbps提高到了300Mbps甚至高达600Mbps,其覆盖范围也扩大到了好几平方公里,并且实现WLAN与无线广域网络(3G等)的结合。是呀,不是我不知道,是这世界变化快。当802.11n规范刚刚尘埃落定不久,802.11ac的项目又开始了,不久我们将会迎来千兆级别的无线局域网传输速度。
WLAN的支持是由WLAN API实现与WLAN设备驱动程序共同完成的。在Linux平台上的无线网络管理工具种类确实不少,比较流行的有Gnome Network Manager、KDE NetworkManager、Wicd、Wifi-wiz,YaST2和Wireless Tools等,其实你自己可以用iwconfig、iwlist、ifconfig、ifup和ifdown等指令来完成对无线网卡运行模式、SSID①和认证②加密方式等方面的设置。
Linux内核对无线网}支持的种类越来越多,D-Link、Airgo、Bermai、Broadcom、Atheros、Cisco和Intel等公司提供的无线网卡已经大量在台式和笔记本电脑中应用。老实说,Linux上无线网络驱动开发比有线网络驱动开发的难度要大很多,没有对无线通信协议的深入了解基本上是搞不定的。无线网络驱动的设计也是层次化的,协议实现和硬件管理是在不同的模块中完成的。在2.6.14内核以后,IEEE 802.11协议栈加进了标准内核。回调函数在层次化的
结构中起到了重要作用,不同的驱动程序能够根据自身情况灵活选择部分或全部实现回调函数。比如你可以设置host_encrypt和host_decrypt为空,这样协议栈就会省略掉加解密操作,将这两项工作交给硬件完成。由于篇幅有限,很难把无线驱动谈论得很透,这里就不哕嗦了。感兴趣的同学可以阅读无线设备驱动源代码.它们的位置在内核源码drivers/net/wireless下。
在对WLAN有了初步的认识后,我们做一些实战讲解。我在迷你Raspberry Pi树莓派上装了一个小巧的ArchLinux操作系统,版本是Arch Linux 3.6.11-4-ARCH+。假设驱动模块已经在系统里安装好,我以TP-LINK公司出品的TL-WN823N网卡为例,看看怎样让网卡“跑”起来,然后通过它能无线上网。
①服务集的标识。在同一服务集( Service Set)内的所有无线客户端和AP必须具有相同的SSID,否则无法进行通信。
②AP提供开放系统身份(open-system authentication)、共享密钥(shared-key authentication)、WPA PSK( Pre-shared key)和802.IX EAP等几种认证方法。
③指数据传输速率,它的单位是bps,即每秒传输的比特数。还有一点需要注意,文件传输速度的单位足Bps,这个B是Byte,即字节。一个字节等于8个比特,即IB-8b。也就是说,数据传输速率300Mbps的网卡,理论上最大文件传输速度足300÷ 8= 37.5MBps。
TL-WN823N是300M③802.11n WiFi网卡,外壳打着TP-LrNK的字样,里面核心的WLAN芯片是Realtek(瑞昱)牛产的。不信的话,你用lsusb命令查查看,返回结果如下:
lsusb命令是一个学习usb驱动开发认识usb设备的助手-》usbutils软件包
Bus 001 Device 002 : ID 0424 : 9512 Standard Microsystems Corp . LAN9500 Ethernet 10/100 Adapter Bus 001 Device 001: ID 1d6b: 0002 Linux Foundation 2 . 0 root hub Bus 001 Device 003 : ID 0424 : ec00 Standard Microsystems Corp. Bus 001 Device 004 : ID 24ae : 2000 Bus 001 Device 005 : ID 0bda : 8178 Realtek Semiconductor Corp . RTL8192CU 802 . 11n WLAN Adapter
在返回结果中你看到Realtek Semiconductor Corp.的字样了吧。
在Linux系统启动的时候,udev管理你的硬件库存,它将负责为你的硬件加载合适的驱动模块。
随后驱动产生内核接口,不同芯片驱动提供的接口名称有所不同,例如Atheros WLAN芯片的无线网卡接口名称为ath0,而Realtek WLAN芯片的无线网卡接口名称为wlan0。你可以用iwconfig命令查看无线设备名: 不同网卡有不同设备名
# iwconfig wlano unassociated Nickname : "" Mode:Auto Frequency=2 . 412 GHz Access Point : Not-Associated Sensitivity: 0/0 Retry : off RTS thr : off Fragment thr : off Encryption key : off Power Management : off Link Quality: 0 Signal level : 0 Noise level: 0 Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0 Tx excessive retries : 0 Invalid misc : 0 Missed beacon : 0
从返回的结果中我们得到设备名称为wlan0。
有了设备名后,我们开始网卡的配置工作。首先用ifconfig wlano up打开无线网卡设备,还可以使用iwlist wlano scan命令检测和扫描一下WiFi信号,从中我们能获得很多很有用的WLAN信息,结果如下:
# ifconfig wlano up wlano Scan completed : Cell 01 - Address : EC : 17 : 2F : FO : 56 : 66 ESSID : " TP-LINK_PocketAP_F05666 " Protocol : IEEE 802 . 11bgn Mode : Master Frequency: 2 . 412 GHz (Channel l) Encryption key : off Bit Rates : 150 Mb/s Quality=81/100 Signal level=42 /100 Cell 02 - Address : 8C : 21 : OA : B6 : 1A : E8 ESSID : " yooyoo " Protocol : IEEE 802 . 11bgn Mode : Master① Frequency:2.412 GHz② (Channel 1) Encryption key : on Bit Rates③: 300 Mb/s Extra : wpa_ie=dd160050f20101000050f20401000050f20401000050f202 IE: WPA Version 1 Group Cipher : CCMP Pairwise Ciphers (1) : CCMP Authentication Suites (1) : PSK Extra : rsn_ie=30140100000fac040100000fac040100000fac020000 IE : IEEE 802 . 11i/WPA2 Version 1 Group Cipher : CCMP Pairwise Ciphers (1) : CCMP Authentication Suites (1) : PSK ......
从上面的信息中,我们发现了目标,附近有一个我们想要接入的无线接入点( Access Points,简称AP),它的SSID是yooyoo。然后使用iwconfig wlan0 essid“yooyoo”命令完成无线网络的接入。当然iwconfig还提供了其他连接方法,例如使用无线网络路由器物理地址接入:
# iwconfig wlan0 ap 8C : 21: OA : B6 :1A : E8
在连接没有设置密码的AP的情况下,无线网卡通过上面的命令可以算是完成了基本的无线接入。但是我们强烈建议你连接设置密码的AP。如果我们自己架设AP④的话,也一定要设置密码,而且设置的密码不能太简单。后面我们会讲AP设置密码的重要性。
①AP模式就是无线接入点模式,Master模式也就是AP模式。在Linux系统上需安装和启动hostapd服务以支持无线网卡工作在AP模式。不过巧妇难为无米之炊,有些无线网卡驱动是不支持AP模式的。如果无线网卡驱动不支持,你在Linux上架设AP基本没戏。建议在http://wireless.kemel.org/en/users/Drivers网站上查看无线网昔的相关信息确定网卡驱动是否支持AP模式。
②网卡工作频率。频率是非常宝贵的资源。国外拍卖移动牌照,其核心就是拍卖频率。802.11b/g/n工作于2.4GHz频带,这个频带是不需要执照的,该频段属于工业、教育、医疗筹专用频段,是公开的。微波炉的频率也是2.4GHz,所以网卡附近有开启的微波炉会对信号有较强的干扰。
③数据传输速率。802.11a工作在5.4G频段,最高速率54Mb/s,主要用在远距离的无线连接;802.11b工作在2.4G频段,最高速率11Mb/s,逐步被淘汰;802.11g工作在2.4G频段,最高速率54 Mb/s: 802.11n可以工作在2.4G/5.8G频段,最高速率能到300 Mb/s。
④在没有无线路由器AP的情况下,将TL-WN823N插到电脑上,并设置为AP模式,这时它就相当于一台无线AP,可以支持其他笔记本、智能手机、Pad等无线设衔的Wi-Fi共享。
在设置密码前请备份一下/etc/wpa_supplicant/wpa_supplicant.conf这个文件,然后我们使用wpa_passphrase工具进行连接密码转换,例如:
#wpa_passphrase yooyoo"xxxxxxxxxxxxx"> /etc/wpa_supplicant/wpa_supplicant.conf
密码转换后启动wpa_supplicant①协议做连接认证,命令如下:
# wpa_supplicant—i wlan0—c/etc/wpa_supplicant/wpa_supplicant.conf—B②
使用iwconfig查看,显示连接成功。
# iwconfig wlan0 IEEE 802.11bgn ESSID:“yooyoo“ Nickname:”” Mode: Managed Frequency:2.412 GHz Access Point: 8C:21:0A:B6:1A:E8 Bit Rate:300 Mb/s Sensitivity:0/0 Retry: off RTS thr: off Fragment thr: off Encryption key:****一****一****一****一****一****一****一****Security mode:open Power Management:off Link Quality=100/100 Signal level=100/100 Noise level=0/100 Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0 Tx excessive retries : 0 Invalid misc : 0 Missed beacon : 0
这时候我们再使用dhcpcd wlan0命令通过DHCP动态获取IP地址,得到IP地址以后,我们就可以用ping命令,例如ping www.sina.com.cn,测试网络是否可通。在没有DHCP服务器的无线局域网或DHCP分配IP失败的情况,可使用手工设置IP的方法。假设我的无线局域网默认网关是192.168.1.1,子网掩码是255.255.255.0,DNS:是8.8.8.8(google提供的DNS服务),命令操作如下:
设置IP地址和子网掩码:
# ifconfig wlan0 192. 168.1.16 netmask 255. 255 .255.0 up
用nano命令进入编辑功能,编辑配置文件/etc/resolv.conf。在所有nameserver前加上#,
然后添加一行:
nameserver 8.8.8.8
然后保存退出。
添加默认网关
#route add default gw 192.168.1.1
测试网络是否可通
#ping www.slna.com. cn
上网成功后,我们回过头来再强调设置密码的重要性,而且要求设置的密码不能有规律,
否则会被人暴力破解。你不信的话,我就给你讲个黑客的故事。黑客可以通过抓取“握手包”,
也就是网卡和路由器之间进行信息匹配验证的数据包,然后就可以破解握手包里含有的无线
网络密码的信息。玩无线的朋友应该都会知道绰号为“奶瓶”的Linux系统。它是一款基于
Tiny Core Linux搭建的无线网络安全测试系统。“奶瓶”系统是一个.ISO文件,短小强悍,使用镜像软件将其写入U盘。然后通过U盘启动制作好的“奶瓶”。有一些人利用这个系统向目标客户端发起攻击,发送Deauth控制包迫使目标客户端和路由器断开链接。当对方网络链接断开之后,路由器就会和“奶瓶”系统上的客户端互传握手包。当然“奶瓶”与对方无线路由器距离越近,信号就会越好,抓取成功的速度就越快。
由于“奶瓶”系统的分析能力不够强大,你可以把抓下来的包存好做后续处理,利用从俄罗斯进口的Windows系统上的Elcomsofi Wireless Security Auditor较件帮助你破解。这款软件利用GPU的运算性能协助攻破无线网络密码。当然,光有强悍的计算能力还不行,还需要有强悍的字典文件。字典文件一般包括生日、单词、常见人名、纪念曰和数字等信息。所以如果我们在设置密码的时候绕开这些字典文件的范围,网络安全性也会得到极大的提升。
我在这节告诉你WLAN的破解手段,可不是让你去做黑客。既然能用“奶瓶”攻破无线网络密码,我们也可以利用它来检查我们自己搭建的无线网络是否有安全漏洞,懂了吧?另外通过命令行配置无线网络还是比较麻烦的。君子善假于物也,通过无线网络管理工具(如netcfg、Wicd和NetworkManager等)来帮助我们管理和启动WLAN设备是个好方法。
①无线WiFi网络大多是WPA加密,需要使用wpa_supplicant工具完成认证过程。wpa_supplicant工具是开源项目,已被谷歌修改后加入Android移动平台,它主要是用来支持WEP和WPA/WPA2等无线加密认证。
②一B代表dacmonlise,使其后台运行。
奶瓶Linux
1 3.2.2 Bluetooth
提起蓝牙通信技术,我想到了最近发生在我女儿佳佳身上的故事。佳佳设计和制作了一个为社区老人送包裹的机器人志愿者,准备用这个作品参加青少年科技比赛(就这么轻描淡写地写出来,作者,你这是赤果果地挑衅,广大读者都是有尊严滴)。女承母业,她很快又想到通过无线网络使用手机控制机器人,跑来问我的意见。我告诉她,你的创意相当好,而
且可行,我们可以通道蓝牙通信技术把手机与机器人设备连接起来。
接下来我们讲讲蓝牙是什么。蓝牙是一种低功耗的无线技术,提供低成本、近距离的无
线通信,构成固定与移动设备、移动与移动设备之间通信环境的个人网络,使得近距离内各
种信息设备能够实现无缝资源共享。它的英文名称是Bluetooth,是1998年5月由爱立信、
IBM、英特尔、诺基亚、东芝等业界龙头联合制定的近距离无线通信技术标准。这项无线技
术的名称取自古代丹麦维京国王Harald Blaatand的名字,直接翻译成中文为“蓝牙”(Bla=蓝、Tand=牙)。这个国王以统一了因宗教战争和领土争议而分裂的挪威与丹麦而闻名于世。当时瑞典爱立信公司把这种无线技术用国王的名字命名,也许想借此抒发一下他们想一统天下的豪情壮志吧。
蓝牙技术是开放式通信规范,而Linux恰好是开放源码的操作系统。价廉设备与免费软件的结合促进了蓝牙技术和Linux的发展与融合。Linux最早的蓝牙协议栈是由Axis Communication Inc在1999年发布的OpenBT协议栈。随后,IBM发布了BlueDrekar用户协议栈,但没有完全公开其源码。幸运的是Qualcomm Incorporated在2001年发布的BlueZ协议栈被接纳为2.4.6内核的一部分。除了这几个有名的蓝牙协议栈外,Rappore Technology及Nokia的Affix Bluetooth Stack也都是Linux系统下的蓝牙协议栈。它们被应用在不同的设备和领域中。
淡Linux上的蓝牙协议栈,不谈BlueZ就说不过去了。它是Linux的官方蓝牙协议栈,也是目前应用最广泛的协议栈,几乎支持所有已通过认证的蓝牙设备,已成为一个开放性的源码工程。它可以很好她在Linux支持的各种体系的硬件平台下运行,包括各种单处理器平台、多处理器平台及超线程系统。它由多个独立的模块组成,内核空间主要包括设备驱动层、蓝牙核心及HCl层、L2CAP与SCO音频层、RFCOMM、BNEP、CMTP与HIDP层、通用蓝牙SDP库和后台服务及面向所有层的标准套接字接口;在用户空间提供了蓝牙配置、测试及协议分析等工具。其组织结构如图13.3所示。
Blue核心及HCI层在主机端的驱动程序上主要是为上层提供一个统一的接口,让上层
协议不依赖于具体硬件的实现。HCI在硬件中的固件与HCI在主机端的驱动通信方式有多种,比如像UART、USB和PC Card等等。L2CAP层是HCI之上的协议,提供诸如QoS、分组、多路复用、分段和组装之类的功能。SCO层也是运行在HCI之上的协议,它是面向连接的可靠的传输方式,主要用于声音数据传输。RFCOMM是基于L2CAP之上的协议,支持标准的套接字接口,并提供了串行仿真TTY接口,这使串行端口应用程序和协议可以不加更改地运行在蓝牙设备上,例如通过点对点协议PPP可实现基于TCP/IP协议簇的所有网络应用。BNE层实现了蓝牙的以太网仿真,TCP/IP可以直接运行于其上。
蓝牙的应用场景不少,例如使用手机通过蓝牙与电脑连接共享宽带上网,以及通过蓝牙连接电脑和移动终端实现文件共享,还有在使用即时聊天工具打电话时,在蓝牙耳机协助下完成通话,不必被拴在电脑前面……这里面蕴藏着相当丰富的应用空间,你就尽情地发挥自己的想象力吧。但是我们还得冷静一下,不管是什么样的蓝牙应用,连接是基础。找们还得先看看在Linux操作系统下实现蓝牙连通的操作方法和命令。假设我们的电脑上已经安装了一个USB接口的蓝牙设备。蓝牙的模块配置操作与以太网设备的配置操作类似,我们可以使用hciconfig命令查看蓝牙设备,如:
# hciconfig hci0:Type: USB BD Address:00:11: 67: 02: 1A: 03 ACL MTU:678:8 SCO MTU: 48:5 DOWN RX bytes: 142289 acl: 884 sco:0 events: 823 errors:0 TX bytes: 13302 acl:494 sco:0 commands: 151 errors:0
使用hciconfig hcio up可以激活接口。在/etc/bluetooth目录下有配置文件hcid.conf和rfcomm.conf。特别是在hcid.conf中有关配对信息的选项要多加注意。其中security user表示每次配对询问用户对方PIN,而auto则表示直接采用passkey中的PIN码。
options { #自动初始化新设备 autoinit yes; #安全管理模式 #none -安全管理被关闭 #auto -使用本地PIN连接 #user -每次向用户询问PIN # security user; #配对模式 #none - 配对被关闭 #multi -允许已经配对设备重新配对 #once - 配对一次,拒绝后续的连接尝试。 pairing multi; #默认的PIN码 Passkey”BlueZ”; }
配置修改好以后,我们使用/etc/rc.d/init.djbluetooth start重启bluetooth服务,然后运行hcitool scan扫描设备找到设备ID,例如我们有个蓝牙手机在电脑旁边,扫描设备后得到设备ID为00:21:19:A4:E0:F1,这时我们就把这个设备ID加入到/etc/bluetooth/rfcomm.conf的配置中,如下:
rfc omm0 { bind no; device 00: 21: 19:A4: E0: F1; channel 1: comment "Meizu M8”j }
接下来的操作是运行rfcomm_ create_ dev命令创建设备,运行:
# sdptool add --channel=l DID SP DUN LAN FAX OPUSH FTP HS HF\
SAP NAP GN PANU HID CIP CTP A2SRC A2SNK SYNCML\
NOKID PCSUITE SRI
命令增加SDP消息信息,运行:
#rfcomm bind /dev/rfcomm0 00:21:19:A4:EO:F1 1(在rfcomm. conf中的配置)
增加蓝牙串口绑定。经过上面几个命令后,我们终于可以用hcitool cc 00:21:19:A4:E0:F1
连接电脑旁边的手机了,同时你可以看到手机上的蓝牙连接呈联通状态。在享受成功连接的兴奋之余,我们不得不感叹一下,好麻烦呀!其实你也大可不必这么折磨自己,完全可以使用诸如GNOME Bluetooth等蓝牙管理工具帮助你搞定电脑与设备的连通。我之所以选择命令行讲述是为了让你更好地理解蓝牙的连通过程。
13.2.3 NFC——近距无线通信
NFC技术现在很火爆,已逐步应用到门禁管制、交通/活动检票、移动付费、下载音乐、交换图像、同步处理通信录等日常生活当中。
识时务者为俊杰,Linux做出了明智的选择,决定从3.1版本开始支持NFC芯片组。
NFC是Near Field Communication的缩写(近场通信),是一种近距离无线通信。它运行在13.56MHz,
速率从106 kbits/s到424kbits/s,传输距离不大于4cm。它支持三种工作模式Tag Read/Write、
Card Emulation年口Peer to Peer LLCP (OBEX over LLCP年口lP over LLCP)。
经常有的人把NFC和RFID这两个东西混淆了。实际上,NFC和RFID不是完全同一件事,但是它们之间有交集。RFID使用多种频率包括13.56MHz,如果NFC运行在Tag read/write模式,并且频率为13.56MHz,那它和某些工作在13.56 MHz上的RFID是一样的,但是RFID没有Card Emulation和P2P模式,RFID支持的其他频率也不在NFC支持的范围之内。
在理解了NFC和RFID的关系之后,我们再来看看NFC和Bluetooth酌区别。NFC和Bluetooth都是一种近距离通信。NFC比Bluetooth通信建立过程更快,距离更近,更省电。它简化了Bluetooth的配对,但是Bluetooth的传输速率会更快,并且定义了许多高级别的档案资料。所以NFC和Bluetooth之间不存在太多的竞争。它们是在不同场合下使用的技术。
Linux对Bluetooth支持得很好,对NFC的支持也越来越给力。NXP(恩智浦半导体,以前加油卡就是用NXP芯片)、Inside Securite和
i14p.fr组织在Linux平台上开发了运行在用户空间的NFC库,它们分别是lib-nxp、opennfc、
libnfc。当你拿到这些库的源码后,聪明的你或许已经发现这些库都有一些共同的缺点。那
就是与硬件捆绑得太紧,不够开放,没有实现供应商中立的原则:用户和内核空间没有分离,
还有不符合POSIX API标准等。所以在Linux 3.1以后,内核的NFC功能做了改进,提供了对NFC网络层的标准化,进行了统一的实现,并且把NXP(pn533和pn544)和TI芯片的驱动模块加入到发布包里。
首先我们看看NFC子系统的实现框架,如图13.5。
子系统已经实现了与硬件无关,新的芯片加入新的驱动模块就行。接口符合POSIX API。
控制命令使用netlink,数据交换使用socket。如上图所示,系统分为几个部分,其中“core”模块负责提供与驱动的接口,与其他三个handler共同完成控制操作和数据交换。
控制操作方面,用户空间是通过netlink下发控制命令的。例如NFC_CMD_START_POLL
和NFC_CMD_STOP_POLL是用来查询目标的操作,而NFC_EVENT_TARGETS_FOUND事件用来返回查询结果。有关netlink操作可参考代码4:
代码4:
Int nfcctl_init{struct nfcctl *ctx} { Int id; Int rc; printdbg { " IN " } ; ctx->nlsk = nl_socket_alloc ( ) ; if ( !ctx->nlsk) { printdbg ( " Invalid context " ) ; return -ENOMEM; } rc = genl_connect ( ctx->nlsk) ; if (rc) { rc = -nlerr2syserr ( -rc) ; printdbg ( " Error connecting to generic netlink : %s " , strerror ( -rc)} ; goto free_nlsk; } ctx- >nlf amily = genl_c trl_resolve ( ctx->nlsk, NFC_GENL_NAME ) ; if (ctx->nlfamily < 0) { rc = -nlerr2 syserr ( -ctx->nlfamily) ; printdbg ( " Error resolving genl NFC family: %s" , strerror (-rc)} ; goto free_nlsk; } id = get_multicast_id ( ctx , NFC_GENL_NAME , NFC_GENL_MCAST_EVENT_NAME); If (id<=0) { rc = id; goto free_nlsk; } rc = nl_socket_add membership (ctx->nlsk, id) ; if (rc) { printdbg ( " Error adding nl socket to membership " ) ; rc = -nlerr2syserr ( -rc ) ; goto free_nlsk } ......
用户空间和控制命令处理程序之间用的是netlink,在第15章“七种武器”中的“module
与用户通信:netlink方式”部分我们做了分析与讲解。最好的学习方法是贯彻理论与实践相结合的科学发展观,结合那节内容与这个NFC实例一起看。
数据交换方面,子系统设立了新的套接字PF_NFC,它提供了底层到用户空间的数据交
换。NFC_SOCKPROTO_RAW使用SOCK。SEQPACKET协议进行与NFC目标的raw通信。地址簇AF NFC的定义域里含有本地的设备id,NFC目标和NFC协议。PF NFC套接字通信代码如代码5所示:
代码5:
int nfcctl_target_init (struct nfcctl *ctx, uint32_t dev_idx, uint3 2_t tgt_idx , uint32_t protocol) { int fd; struct sockaddr_nfc addr; int rc; printdbg(“IN”); fd = socket (AF_NFC, SOCK_SEQPACKET, NFC_SOCKPROTO_RAW) ; if (fd == -1) return -errno; addr . sa_family = AF_NFC ; addr . dev_idx = dev_idx; addr . target_idx = tgt_idx; addr _ nfc_protocol = protocol; rc = connect ( fd. ( struct sockaddr *) &addr , sizeof ( addr)); if (rc) { rc = -errno ; goto close_sock; } ctx->target_fd=fd; return 0; Close_sock: close (fd); return rc; }
从图13.4中能看出处于核心地位的core不简单,它不仅提供了下层数据交换接口,而且还完成了LLCP协议。在这里我们颁发个任劳任怨奖给它,以表彰它对NFC数据交换方面所做出的贡献。
当然我们不会仅仅满足知道以上几个概念,接着我们要读一读NFC代码。在学习的过程中你酌脑海里又会浮现出许多新的问题。为什么不把几个handler和core整合在一起达到做好协议复用的目的呀?为什么还没有支持Card Emulation模式呀?为什么tag命令还是和厂商的芯片标准关联?……还有用户空间是怎么考虑的?NFC事件和属性由D-Bus导出来多好呀?能否提供SIM应用的工具,通过它把NFC与电话栈进行对接?这些都是相当不错的建议,我们拭目以待吧!
13.2.4谜底
无线网络通信技术还有3G、Infrared和Wimax等,Linux对这些流行的无线技术都有支
持,网上的各种资料也较为齐全。如果你有兴趣的话,自己动手搞一搞。
在本节结束时,我来告诉你………(嘀嘀嘀,嗒嗒嗒,嘀嘀嘀)到底是什么意思!它代
表SOS,熟悉摩尔斯电码的人一听就明白:这是有人在发“SOS”求救信号。
13.3奇迹是执着创造出来的
“几度风雨几度春秋,风霜雪雨搏激流。”1991年10月5日Linus Torvalds在新闻组comp.os.minix发布了Linux v0.01版本。虽然这个版本只有大约一万行代码,但它依然是一个坚实的起点。从那时起小企鹅经历了种种磨练,凭借着执着的进取心,从1.0、2.0、2.2、2.4、2.6和3.0 一步一个脚印地走过来,奠定了其在操作系统上王侯将相的地位。回望过去,细数往昔,太多太多的故事,我们无法一一表述。这里我就先讲讲离我们最近的两次重要的升级(从2.4到2.6,从2.6到3.0)当中网络方面的那些改进,让你领略一下这种执着的魅力。
13.3.1 从2.4到2.6
2001年1月4日社区发布了Linux 2.4.0; 2003午12月17日发布了Linux 2.6.0。经历了近三年的休整,小企鹅无论对相当大的系统还是相当小的系统(PDA等)的支持都有很大提升,更准确地讲应该叫“大跨越”。网络部分的改进和提升更是巨大的。
平时与我们面对面打交道的多是应用软件。当应用软件的界面和功能变化的时候,我们
总是能很容易地感知。Linux设备模型底层和驱动程序是无名英雄,它们的改进和升级一直是默默地进行着。例如,Linux 2.6提供一个独立的Ⅳni(媒体独立接口,或是IEEE 802.3u)子系统,它被许多网络设备驱动程序使用,消除了原先系统中多个驱动程序使用重复代码的
问题。为了提高系统的稳定性和透明性,模块予系统做了苇大改进,许多代码因此被重写。当然,Linux的改进并不只限于硬件及其他基础设施,如果没有文件系统及网络协议等支撑软件的改进,硬件支持也就是死木头一块。接下来我们就来看看网络协议改进方面的执着。
先进的网络支持一直是Linux的重要财富之一。Linux作为一种操作系统,已经可以支
持世界上大多数主流网络协议,包括TCP/IP(v4和v6)、AppleTalk、IPX等。Linux2.6内核除了对IPSec和IPComp昀扩展外,还提供了对IPv6隧道的支持以及对IPv6隐私的扩展。
IPsec被称为安全IP,是在网络协议层为IPv4和IPv6提供加密支持的一组协议。由于安全是在协议层提供的,对应用层是透明的。它与SSL协议及其他tunneling/security协议很相似,只是位于一个低得多的层面。当前内核支持的加密算法包括SHA(“安全散列算法”)和DES(“数据加密标准”)等。IPSec为IPv6提供了与IPv4相同级别的认证和安全。所包含的对IPv6到IPv6隧道的支持让两个端点之间可以进行安全无缝的通信,比如虚拟专用网络 ( Virtual Private Networks,VPN) 之上的传输。
IPv6隐私扩展这一特性尤其着重于提高Intemet的匿名性,让用户在使用IPv6地址时可以选择保护他们的身份。当前的无国界的地址自动配置模式是使用设备(换句话说,是以太网卡或者移动电话)的MAC地址来形式化128位IPv6地址的前缀。如果使用不变的标识符来形式化地址会使数据可以被迫踪,而这个缺陷可能被某些人以某种意想不到的动机所利用。例如,只要知道一台机器的MAC地址,网络嗅探器就可以追踪哪些机器以及在什么时候哪台机器与此机器通信。网络嗅探器的数据很容易收集,因为无论网络拓扑如何,MAC地址始终不变,即使机器是移动电话或者膝上电脑。记录这些数据的人可以通过这些信息来追踪工作模式和位置等等。IPv6隐私扩展让用户可以使用一个随机的接口标识符创建另外的IPv6全局地址。一台机器在特定的时间段内使用这些临时的地址,直到重新设置为另一个随机地址。重新设置之后,当前的连接可以继续保持通信;不过,所有的新连接必须用新的临时地址建立通信。
可以被多台计算机接收(传统的点对点网络每次只能有两方通信)。这一功能主要被即时通信系统(如Tibco)以及音频/视频会议软件使用。Linux 2.6现在支持若干新的SSM(定源多播)协议,包括MLDv2(multicast listener discovery多播侦听发现)协议以及IGMPv3(Intemet组管理)协议等。这些都是标准协议,被多数高端网络硬件提供商所支持,如思科。
除此之外,2.6.0内核增加了对SCTP的支持。“无心插柳柳成荫”,SCTP协议最初是为发送电话信号(在IP上进行七号信令的传输)而设计的,但它却带来了一个意外的收获,通过吸收UDP面向消息和TCP面向连接稳定的优点,成为新一代的通用IP传输协议(RFC 2960)。熟悉TCP/IP的人可以简单地将SCTP看作是“超级TCP”,因为SCTP不仅与TCP很像,而且扩展了TCP的许多功能。它的主要特点有:
● 多宿性(multihoming)支持在一点到多点的连接中使用多个IP地址,这样就保证
了在冗余的网络路径上透明地故障迁移。
● 与TCP字节流传输相比,与流无关的数据块传输消除了不必要的head-of-line阻塞。
● 通过路径选择和监控找出主要的数据传输通路并测试其连接性。即使某个流由于对
方处理不及附等原因阻塞了,其他流还可以继续传输。例如你可以把文字和视频放
在不同通道上,避免视频阻塞文字的传输。
● 验证和确认机制防止收到泛洪攻击,并且提供重复和丢失数据块的通知。
● 优化的错误检测很适合以太网的巨帧传输。
尽管加密不是最初SCTP的设计部分,但是它的设计确实提高了安全性和可靠性,例如4次握手(而TCP是3次握手)以及为了协商验证和确认使用的“甜饼”(cookie)机制有效地防止SYN泛洪攻击。cookie数据都是认证过的,通过密钥对数据进行签名,防止数据被篡改。
SCTP有两种风格的接口。一种是一对多的接口,例如:
sd=socket( PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
另一种是一对一的接口,它已存在于TCP应用中,很容易被移植变成一对一的SCTP应用,例如:sd= socket(PF_NET, SOCK_STREAM,IPPROTO_SCTP);如果你要想了解更多信息,可以参看RFC标准。RFC2960和RFC3309对SCTP进行了详细的定义和描述。当然SCTP在Linux平台上目前处于experimental阶段,如果你想为lksctp开源项目添砖加瓦的话,可以直接向[email protected]邮件组写邮件,向项目组抛橄榄枝或汇报问题,绝对有人会回复你。
Linux对网络文件系统的支持构建在Linux健壮的网络协议支持之上,它也同样健壮。安装或者输出(export) 一个网络文件系统,是需要内核直接参与的为数不多的几个上层网络相关操作之一,例如:
Network file Systems一一一> <*>NFS file system support nfs //客户端支持 [*]Provide NFSv3 client support [ ] Provide NFSv4 client support (EXPERIMENTAL) [ ]Allow direct I/O on NFS files (EXPERIMENTAL) <*>NFS server support nfs服务端支持 < >Secure RPC: Kerberos V mechanism( EXPERIMENTAL) < >Secure RPC: SPKM3 mechanism (EXPERIMENTAL) <*>SMB file system support (to mount Windows shares etc*) //samba支持 < >CIFS support(advanced network filesystem for Samba,Window and other CIFS compliant servers) < >NCP file system support (to mount NetWare volumes) < >Coda file system support (advanced network fs) < >Andrew File System Support (AFS) (Experimental)
在上述的内核配置菜单中我们选中了对NFS和SMB的支持。
在Linux和类UNIX世界中,最普遍的网络文件系统是一个名为Network File System的文件系统,简称NFS。Linux 2.6中,NFS文件系统得到了很大的更新和改进。最大的改进就是实验性地支持新的并且还没有被广泛接受的NFSv4协议(以前的Linux版本支持NFS2和NFS3两种协议)在客户端和服务器端的实现。新的版本有更强、更安全的身份认证(采用加密技术),支持更智能化的锁管理,支持伪文件系统等。基于Linux的NFS服务端的实现具有了更好的扩展性,不仅支持UDP还支持TCP,分离lockd和nfsd,支持零拷贝传输,文件系统在输出文件的时候能够进行调整以维持它们自有的一些特征,新的nfsd文件系统不再是系统调用。NFS客户端也因为底层RPC协议在缓存机制、UDP连接控制以及其他在TCP协议上的改进而受益。Linux支持NFS共享卷作为根文件系统的功能随着TCP协议上的NFS的改进而改进。
当然Linux用户不打算始终待在被遗忘的角落,除了改进对UNIX风格的网络文件系统的支持,Linux 2.6对于Windows类型的网络文件系统的支持也进行了改进。Windows服务器(也包括OS/2和其他一些操作系统)的标准共享文件系统是遵循SMB (server message block)协议的,Linux 2.6除了对SMB协议的很多版本都已经有了非常优秀的支持外,还对SMB的升级版CIFS做了较好的支持,增加了UNICODE支持,改善了文件锁,支持硬链接,彻底消除了对NetBIOS的依赖,并给Windows用户增加了一些新的特征。不仅如此,Linux2.6现在还支持SMB和CIFS的扩展-SMB-UNIX,该扩展使得Linux可以访问SMB服务器(比如Samba)上的可能存在的非Windows的文件类型(比如设备节点和符号链接 (快捷方式文件))。
Linux 2.6还加入了相对较新的一些分布式网络文件系统(即在一个逻辑卷上的文件可以分布在多个节点中)的支持。除了Linux 2.4中引入的CODA文件系统,Linux 2.6增加了对AFS的支持。AFS(Andrew File System)是芙国卡内基梅隆大学开发的一种分布式文件系统。Andrew是这所大学的赞助者。AFS的主要功能是用于管理分布在网络不同节点上的文件。
与普通文件系统相比,AFS的主要特点在于三个方面:分布式、跨平台、高安全性。Linux 2.6下的AFS特性还非常有限,在内核选项上还打着Experimental的标签。
13.3.2从2.6到3.0
“锲而不舍,金石可镂”。经过40次发布,Linux内核终于离开了2.6的命名,迎来了八年来重大的发布。多年来,Linux开发人员一直致力于2.6版本的改进工作,2011年,新版本提升到3.0是为了纪念Linux风雨走过的20年,同时也是为了精简越来越复杂的版本号。之前稳定的内核版本是2.6.39。Linux Kemel 3.0改进了对虚拟化和文件系统的艾持,在网络部分也做了大量的改进。巧合的是Microsoft从Windows 3.0的发布开始了它的辉煌历史,在这里衷心祝愿这只小企鹅从3.0开始,不仅能在服务器领域上成就霸业,将来还能在桌面系统和移动设备上称雄于世。
毋庸置疑,Linux设备驱动的改进一直没有停止,支持的无线网卡的种类越来越多。在linux 3.0增加了对Intel iwlwifi 105/135元线网卡、Intel C600 SAS控制器、雷凌Ralink RT5370无线网卡、多种Realtek RTL8lxx系列网卡以及多种Realtek RTL8lxx系列网卡的支持,而且更多的无线网卡一插就能用(udev)。我们知道无线移动设备在一般条件下能工作那不算牛,在节能状态下还能正常工作才能说明其超强的能力。802.11 stack增加了WLAN唤醒允许系统,在无线NIC进入能量消耗很低的节能状态,例如ACPI S3 suspend状态,在这种状态下无线网络芯片还能保持激活状态,实现搜寻网络或连接AP的功能。
关于Linux 3.0还有一件牛事,它支持BPF实时过滤。对你来说,BPF听起来可能有点陌生?不过你一定听说过tcpdump工具吧。它就是利用libpcap库执行任务的,而这个libpcap库就是靠BPF来完成各种复杂的数据包(网络层)过滤功能的。哈哈,你已经不知不觉地用到BPF程序了。BPF和libpcap结合在一起可以很容易地实现对网络通信异常和网络攻击等方面的sniffer功能。BPF有幸运成为Linux网络Stack的一部分,Eric Dumazet的补丁使BPF在64bit X86系统上运行得更快。内核支持柏克莱封包过滤器(Berkeley Packet Filter)的实时过滤,配合libpcap/tcpdump会极大地提升了包过滤规则的运行效率。
俗话说,害人之心不可有,防人之心不可无。在丹·布朗①的成名之作《数字城堡》里讲到美国国家安全局能够轻易看到私人的电子邮件,并通过扫描电子邮件和数码信息来搜索含有一些关键词的信息,如“杀”、“克林顿”的出现情况。这个情况绝不是空穴来风,在现实世界里美国联邦调查局(FBI)曾经安装过名为“食肉动物”的电子邮件监视软件。这就是利用包捕获机制和包过滤机制的一种黑客手段。
BPF是快速网络数据过滤机制,主要目的就是让应用指定过滤函数选择它想看到的网络数据包。除了tcpdump外还有其他网络过滤程序也在使用BPF。在Linux上,BPF独立于TCP/IP协议栈。它的基本思路是网卡驱动将接收到的数据包除了交给TCP/IP协议栈外,也复制一份交给BPF过滤器,过滤器根据用户定义的规则决定是否接牧此数据包以及需要拷贝该数据包的哪些内容,然后将过滤后的数据给予过滤器相关联的上层应用程序。另一方面,它为应用程序访问数据链路层提供了一个原始接口,在应用看到某种数据包之前就把此数据
包干掉,从而实现了针对每个应用的防火墙。
tcpdump-》libpcap-》BPF
f