您的位置:首页 > 理论基础 > 计算机网络

附录A tcpdump程序

2018-11-11 22:09 2531 查看

tcpdump程序是由Van Jacobson、Craig Leres和Steven McCanne编写的,他们都来自加利福尼亚大学伯克利分校的劳伦斯伯克利实验室。本书中使用的是2.2.1版(1992年6月)。

tcpdump通过将网络接口卡设置为混杂模式(promiscuous mode)来截获经过网络接口的每一个分组。正常情况下,用于诸如以太网媒体的接口卡只截获送往特定接口地址或广播地址的链路层的帧(2.2节)。

底层的操作系统必须允许将一个接口设置成混杂模式,并且允许一个用户进程截获帧。下列的操作系统可以支持tcpdump,或者可以加入对tcpdump的支持:4.4BSD、BSD/386、SunOS、Ultrix和HP-UX。参考一下随着tcpdump发布的README文件,了解它支持哪些操作系统以及哪些版本。

除了tcpdump还有其他一些选择。在图10-8中,我们使用了Solaris 2.2的程序snoop来查看一些分组。AIX 3.2.2提供了iptrace程序,该程序也提供了类似的功能。

A.1 BSD分组过滤器

当前由BSD演变而来的Unix内核提供了BSD分组过滤器BPF(BSD Packet Filter),tcpdump用它来截获和过滤来自一个被置为混杂模式的网络接口卡的分组。BPF也可以工作在点对点的链路上,如SLIP(2.4节),不需要什么特别的处理就可以截获所有通过接口的分组。BPF还可以工作在环回接口上(2.7节)。

BPF有一个很长的历史。1980年卡耐基梅隆大学的Mike Accetta和Rick Rashid创造了Enet分组过滤程序。斯坦福的Jeffrey Mogul将代码移植到BSD,从1983年开始继续开发。从那以后,它演变为DEC的Ultrix分组过滤器、SunOS 4.1下的一个STREAMS NIT模块和BPF。劳伦斯伯克利实验室的Steven McCanne在1990年的夏天实现了BPF。其中很多设计来自于Van Jacobson。[McCanne and Jacobson 1993]给出了最新版本的细节以及与Sun的NIT的一个比较。

图A-1显示了用于以太网的BPF的特征。

BPF将以太网设备驱动程序设置为混杂模式,然后从驱动程序那里接收每一个收到的分组和传输的分组。这些分组要通过一个用户指明的过滤器,使得只有那些用户进程感兴趣的分组才会传递给用户进程。

多个进程可以同时监视一个接口,每个进程指明了一个自己的过滤器。图A-1显示了tcpdump的两个实例进程和一个RARP守护进程(5.4节)监视同样的以太网接口。tcpdump的每个实例指明了一个自己的过滤器。tcpdump的过滤器可以由用户在命令行指明,而rarpd总是使用只截获RARP请求的过滤器。

除了指明一个过滤器,BPF的每个用户还指明了一个超时定时器的值。因为网络的数据传输率可以很容易地超过CPU的处理能力,而且一个用户进程从内核中只读小块数据的代价昂贵,因此,BPF试图将多个帧装载进一个读缓存,只有缓存满了或者用户指明的超时到期才将读缓存保存的帧返回。tcpdump将超时定时器置为1秒,因为它一般从BPF收到很多数据。而RARP守护进程收到的帧很少,所以rarpd将超时置为0(收到一个帧就返回)。

372TCP/IP详解,卷1:协议

图A-1 BSD分组过滤器

用户指明的过滤器告诉BPF用户进程对什么帧感兴趣,过滤器是对一个假想机器的一组指令。这些指令被内核中的BPF过滤器解释。在内核中过滤,而不在用户进程中,减少了必须从内核传递到用户进程的数据量。RARP守护进程总是使用绑定在程序里的、同样的过滤程序。另一方面,tcpdump在每次运行时,让用户在命令行指明一个过滤表达式。tcpdump将用户指明的表达式转换为相应的BPF的指令序列。tcpdump表达式的例子如下:

第一个只打印源端口和目的端口为25的TCP报文段。第二个只打印不是回送请求和回送应答的ICMP报文(也就是非ping的分组)。这个表达式指明了ICMP报文的第一个字节,图6-2中的type字段,不等于8或0,即图6-3中的回送请求和回送应答。正像你所看到的,设计过滤器需要有底层分组结构的知识。第二个例子中的表达式被放在一对单引号中,防止Unix外壳程序解释特殊字符。

参考tcpdump(1)的手册,了解用户可以指明的表达式的全部细节。bpf(4)的手册详细描述了BPF使用的假想机器指令。[McCanne and Jacobson 1993]比较了这个假想机器方法与其他方法的设计与性能。

A.2 SunOS的网络接口分接头

附录A tcpdump程序373

图A-2 SunOS的网络接口分接头

用户指明的过滤由流模块nit_pf处理。在图A-2中,我们注意到这个模块被RARP守护进程所用,但没有被tcpdump使用。在SunOS操作系统中,tcpdump代之以在用户进程中完成自己的过滤操作。这么做的理由是nit_pf使用的假想机器的指令与BPF所支持的指令不同(不如BPF所支持的功能强大)。这就意味着当用户对tcpdump指明了一个过滤表达式时,与BPF相比较,使用NIT就会有更多的数据在内核与用户进程之间交换。

A.3 SVR4数据链路提供者接口

SVR4支持数据链路提供者接口DLPI(Data Link Provider Interface),它是OSI数据链路服务定义的一个流实现。SVR4的大多数版本支持第1版的DLPI,SVR4.2同时支持第1版和第2版,Sun的Solaris 2.x支持第2版,但是增强了一些功能。

tcpdump的网络监视程序必须使用DLPI来直接访问数据链路设备驱动程序。在Solaris2.x中,分组过滤的流模块被改名为pfmod,缓存模块被改名为bufmod

374TCP/IP详解,卷1:协议

图A-3 图4-4的tcpdump的输出

附录A tcpdump程序375

A.5 安全性考虑

很明显,截获网络中传输的数据流使我们可以看到很多不应该看到的东西。例如,TelnetFTP用户输入的口令在网络中传输的内容和用户输入的一样(与口令的加密表示相比,这称为口令的明文表示。在Unix口令文件中,一般是/etc/passwd/etc/shadow,存储的是加密的表示)。然而,很多时候一个网络管理员需要使用一个类似于tcpdump的工具来分析网络中出现的问题。

我们是把tcpdump作为一个学习的工具,用来查看网络中实际传输的东西。对tcpdump以及其他厂商提供的类似工具的访问权限依赖于具体系统。例如,在SunOS,对NIT设备的访问只限于超级用户。BSD的分组过滤器使用了一种不同的技术:通过对/dev/bpfXX设备的授权来控制访问。一般来说,只有属主才能读写这些设备(属主应该是超级用户),对于同组用户是可读的(经常是系统管理组)。这就是说如果系统管理员不对程序设置用户的ID,一般的用户是不能运行类似于tcpdump的程序的。

A.6 插口排错选项

查看一个TCP连接上发生的事情的另一种方法是使能插口排错选项,当然是在支持这一特征的系统中。这个特征只能工作在TCP上(其他协议都不行),并且需要应用程序支持(当应用程序启动时,使能一个插口排错选项)。

大多数伯克利演变的实现都支持这个特征,包括SunOS、4.4BSD和SVR4。

程序使能了一个插口选项,内核就会保留在那个连接上发生的事情的一个痕迹记录。在这之后,所有记录的信息都可以使用trpt(8)程序打印出来。使能一个插口排错选项不需要特别的许可,但是因为trpt程序访问了内核的内存,所以运行trpt需要特别的权限。

sock程序(附录C)的-D选项支持这个特征,但是输出的信息比相应的tcpdump的输出更难解析和理解。然而,我们在21.4节确实使用它查看了TCP连接上tcpdump不能访问的内核变量。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐