标题: TCPDUMP中文手册
无花果
技术专家
Rank: 14Rank: 14Rank: 14Rank: 14
吻下去爱上你



UID 1080
精华 1
积分 339
帖子 674
活跃指数 0
LU金币 5406 个
LU金条 0 个
阅读权限 200
注册 2003-10-28
来自 北京朝阳顺景园
 
发表于 2004-5-15 18:43  资料  个人空间  主页 短消息  加为好友 
在我刚接触网络的时候,其实对TCP/IP连一知半解都没有. 因为有linux,因为拥有linux下的tcpdump,许多网络方面的故障我都是用它来记录全过程, 在我学习ipchains/iptables的过程中,tcpdump是我最好的检测工具. 这两个工具让我慢慢了解了tcp/ip的工作原理,对网络有了更深一步的理解.

所以推荐这个tcpdump的中文手册给初学网络,初学unix的朋友们.


TCPDUMP

名称 (NAME)
tcpdump - 转储网络上的数据流
总览 (SYNOPSIS)
tcpdump [ -adeflnNOpqStvx ] [ -c count ] [ -F file ]
[ -i interface ] [ -r file ] [ -s snaplen ]
[ -T type ] [ -w file ] [ expression ]

描述 (DESCRIPTION)
Tcpdump 打印出 在某个 网络界面 上, 匹配 布尔表达式 expression 的 报头.
对于 SunOS 的 nit 或 bpf 界面: 要 运行 tcpdump , 你 必须 有 /dev/nit 或 /dev/bpf* 的 读访问 权限.
对于 Solaris 的 dlpi: 你 必须 有 网络仿真设备 (network pseudo device), 如 /dev/le 的 读访问 权限.
对于 HP-UX 的 dlpi: 你 必须 是 root, 或者 把它 安装成 root 的 设置uid 程序. 对于 IRIX 的 snoop: 你 必须 是 root, 或者 把它 安装成 root 的 设置uid 程序. 对于 Linux: 你 必须 是 root, 或者 把它 安装成 root 的 设置uid 程序.
对于 Ultrix 和 Digital UNIX: 一旦 超级用户 使用 pfconfig(8) 开放了 promiscuous 操作模式 (promiscuous-mode), 任何用户 都可以 运行 tcpdump.
对于 BSD: 你 必须 有 /dev/bpf* 的 读访问 权限.

选项 (OPTIONS)
-a 试着 把 网络和广播地址 转换成 名称.
-c 当 收到 count 报文 后 退出.
-d 把 编译好的 报文匹配模板 (packet-matching code) 翻译成 可读形式, 传往 标准输出, 然后退出.
-dd 把 报文匹配模板 (packet-matching code) 以 C 程序片断 的 形式 输出.
-ddd 把 报文匹配模板 (packet-matching code) 以 十进制数 形式 输出 (前面 加上 总数).
-e 每行 都 显示 链路层报头.
-f 用 数字形式 显示 '外部的' 互联网地址, 而不是 字符形式 (这个 选项 用来绕开 脑壳坏光的 SUN 黄页服务器 的 问题 --- 一般说来 它 翻译 外部网络数字地址 的时候 会 长期挂起).
-F 把 file 的内容 用作 过滤表达式. 忽略 命令行 上 的 表达式.
-i 监听 interface. 如果 不指定 接口, tcpdump 在 系统 的 接口 清单 中, 寻找 号码最小, 已经 配置好的 接口 (loopback 除外). 选中的时候 会 中断 连接.
-l 行缓冲 标准输出. 可用于 捕捉 数据 的 同时 查看 数据. 例如,
``tcpdump -l | tee dat'' or ``tcpdump -l > dat & tail -f dat''.
-n 别把 地址 转换成 名字 (就是说, 主机地址, 端口号等)
-N 不显示 主机名字 中的 域名 部分. 例如, 如果 使用 这个 选项, tcpdump 只显示 ``nic'', 而不是 ``nic.ddn.mil''.
-O 禁止运行 报文匹配模板 的 优化器. 只有 当你 怀疑 优化器 有 bug 时 才有用.
-p 禁止 把 接口 置成 promiscuous 模式. 注意, 接口 有可能 因 其他原因而 处于 promiscuous 模式; 因此, '-p' 不能 作为 `ether host {local-hw-addr} 或 ether broadcast' 的 简写.
-q 快速输出. 显示 较少的 协议信息, 输出行 会 短一点点.
-r 从 file 中 读入 数据报 (文件 是用 -w 选项 创建的). 如果 file 是 ``-'', 就 读 标准输入.
-s 从每个 报文 中 截取 snaplen 字节的数据, 而不是 缺省的 68 (如果是 SunOS 的 NIT, 最小值是 96). 68 个字节 适用于 IP, ICMP, TCP 和 UDP, 但是 有可能 截掉 名字服务器 和 NFS 报文 的 协议 信息 (见下面). 输出时 如果指定 ``[|proto]'', tcpdump 可以 指出 那些 捕捉量过小的 数据报, 这里的 proto 是 截断发生处 的 协议层 名称. 注意, 采用 更大的 捕捉范围 既增加了 处理 报文 的 时间, 又 相应的 减少了报文的 缓冲 数量, 可能 导致 报文的丢失. 你 应该 把 snaplen 设的尽量小, 只要 能够 容纳 你 需要 的 协议信息 就可以了.
-T 把 通过 "expression" 挑选出来的 报文 解释成 指定的 type. 目前 已知 的 类型 有: rpc (远程过程调用 Remote Procedure Call), rtp (实时应用协议 Real-Time Applications protocol), rtcp (实时应用控制协议 Real-Time Applications control protocol), vat (可视音频工具 Visual Audio Tool), 和 wb (分布式白板 distributed White Board).
-S 显示 绝对的, 而不是 相对的 TCP 序列号.
-t 禁止 显示 时戳标志.
-tt 显示 未格式化的 时戳标志.
-v (稍微多一点) 繁琐的输出. 例如, 显示 IP 数据报 中的 生存周期 和 服务类型.
-vv 更繁琐的输出. 例如, 显示 NFS 应答报文 的 附加域.
-w 把 原始报文 存进 file, 而不是 分析 和 显示. 它们 可以 以后 用 -r 选项 显示. 如果 file 是 ``-'', 就 写往 标准输出.
-x 以 16 进制数 形式 显示 每一个 报文 (去掉链路层报头后) . 可以 显示 较小的 完整 报文, 否则 只 显示 snaplen 个 字节 .
expression
用来 选择 要 转储 的 数据报. 如果 没有 指定 expression , 就 转储 网络的 全部 报文. 否则, 只转储 相对 expression 为 `true' 的 数据报.
expression 一个或多个 原语 (primitive) 组成. 原语 通常 由 一个 标识 (id, 名称或数字), 和 标识 前面的 一个或多个 修饰子(qualifier) 组成. 修饰子 有 三种 不同的类型:
type
类型修饰子 指出 标识名称 或 标识数字 代表 什么 类型的东西. 可以使用的 类型 有 host, net 和 port. 例如, `host foo', `net 128.3', `port 20'. 如果 不指定 类型修饰子, 就使用 缺省的 host .
dir
方向修饰子 指出 相对于 标识 的 传输方向 (数据是 传入还是传出 标识). 可以使用的 方向 有 src, dst, src or dst 和 src and dst. 例如, `src foo', `dst net 128.3', `src or dst port ftp-data'. 如果 不指定 方向修饰子, 就使用 缺省的 src or dst . 对于 `null' 链路层 (就是说 象 slip 之类的 点到点 协议), 用 inbound 和 outbound 修饰子 指定 所需的 传输方向.
proto
协议修饰子 要求 匹配 指定的协议. 可以使用的 协议 有: ether, fddi, ip, arp, rarp, decnet, lat, sca, moprc, mopdl, tcp 和 udp. 例如, `ether src foo', `arp net 128.3', `tcp port 21'. 如果 不指定协议修饰子, 就使用 所有 符合 类型 的 协议. 例如, `src foo' 指 `(ip 或 arp 或 rarp) src foo' (注意后者不符合语法), `net bar' 指 `(ip 或 arp 或 rarp) net bar', `port 53' 指 `(tcp 或 udp) port 53'.
[`fddi' 实际上 是 `ether' 的 别名; 分析器 把 它们 视为 ``用在 指定 网络接口 上的 数据链路层.'' FDDI 报头 包含 类似于 以太协议的 源目地址, 而且 通常 包含 类似于 以太协议 的 报文类型, 因此 你 可以过滤 FDDI 域, 就象 分析 以太协议 一样. FDDI 报头 也 包含 其他 域, 但是你 不能 在 过滤器 表达式 里 显式描述.]
作为 上述 的 补充, 有一些 特殊的 `原语' 关键字, 它们 不同于 上面的模式: gateway, broadcast, less, greater 和 数学表达式. 这些 在 后面 有 叙述.
更复杂的 过滤器表达式 可以 通过 and, or 和 not 连接 原语 来 组建. 例如, `host foo and not port ftp and not port ftp-data'. 为了少敲点键, 可以忽略 相同的 修饰子. 例如, `tcp dst port ftp or ftp-data or domain' 实际上 就是 `tcp dst port ftp or tcp dst port ftp-data or tcp dst port domain'.
允许的 原语 有:
dst host host
如果 报文中 IP 的 目的地址域 是 host, 则 逻辑 为 真. host 既可以 是 地址, 也可以 是 主机名.
src host host
如果 报文中 IP 的 源地址域 是 host, 则 逻辑 为 真.
host host
如果 报文中 IP 的 源地址域 或者 目的地址域 是 host, 则 逻辑 为 真. 上面 所有的 host 表达式 都可以 加上 ip, arp, 或 rarp 关键字 做 前缀, 就象:
ip host host
它等价于:
ether proto \ip and host host
如果 host 是 拥有 多个 IP 地址 的 主机名, 它的 每个地址 都会 被查验.
ether dst ehost
如果 报文的 以太目的地址 是 ehost, 则 逻辑 为 真. Ehost 既可以是 名字 (/etc/ethers 里有), 也可以是 数字 (有关 数字格式 另见 ethers(3N) ).
ether src ehost
如果 报文的 以太源地址 是 ehost, 则 逻辑 为 真.
ether host ehost
如果 报文的 以太源地址 或 以太目的地址 是 ehost, 则 逻辑 为 真.
gateway host
如果 报文 把 host 当做 网关, 则 逻辑 为 真. 也就是说, 报文的以太源或目的地址 是 host, 但是 IP 的 源目地址 都不是 host. host 必须 是个 主机名, 而且 必须 存在 /etc/hosts 和 /etc/ethers 中. (一个等价的表达式是
ether host ehost and not host host
对于 host / ehost, 它既可以是 名字, 也可以是 数字.)
dst net net
如果 报文的 IP 目的地址 属于 网络号 net, 则 逻辑 为 真. net 既可以 是 名字 (存在 /etc/networks 中), 也可以是 网络号. (详见 networks(4)).
src net net
如果 报文的 IP 源地址 属于 网络号 net, 则 逻辑 为 真.
net net
如果 报文的 IP 源地址 或 目的地址 属于 网络号 net, 则 逻辑 为 真.
net net mask mask
如果 IP 地址 匹配 指定 网络掩码(netmask) 的 net, 则 逻辑 为 真. 本原语 可以用 src 或 dst 修饰.
net net/len
如果 IP 地址 匹配 指定 网络掩码 的 net, 则 逻辑 为 真, 掩码 的 有效位宽 为 len. 本原语 可以用 src 或 dst 修饰.
dst port port
如果 报文 是 ip/tcp 或 ip/udp, 并且 目的端口 是 port, 则 逻辑 为 真. port 是一个 数字, 也可以是 /etc/services 中 说明过的 名字 (参看 tcp(4P) 和 udp(4P)). 如果 使用 名字, 则 检查 端口号 和 协议. 如果 使用 数字, 或者 有二义的名字, 则 只检查 端口号 (例如, dst port 513 将显示 tcp/login 的数据 和 udp/who 的数据, 而 port domain 将显示 tcp/domain 和 udp/domain 的数据).
src port port
如果 报文 的 源端口号 是 port, 则 逻辑 为 真.
port port
如果 报文 的 源端口 或 目的端口 是 port, 则 逻辑 为 真. 上述的 任意一个 端口表达式 都可以 用 关键字 tcp 或 udp 做 前缀, 就象:
tcp src port port
它 只匹配 源端口 是 port 的 TCP 报文.
less length
如果 报文 的 长度 小于等于 length, 则 逻辑 为 真. 它等同于:
len <= length.
greater length
如果 报文 的 长度 大于等于 length, 则 逻辑 为 真. 它等同于:
len >= length.
ip proto protocol
如果 报文 是 IP 数据报(参见 ip(4P)), 其 内容 的 协议类型 是 protocol, 则 逻辑 为 真. Protocol 可以是 数字, 也可以是 下列 名称 中的 一个: icmp, igrp, udp, nd, 或 tcp. 注意 这些 标识符 tcp, udp, 和 icmp 也同样是 关键字, 所以 必须 用 反斜杠(\) 转义, 在 C-shell 中 应该是 \\ .
ether broadcast
如果 报文 是 以太广播报文, 则 逻辑 为 真. 关键字 ether 是 可选的.
ip broadcast
如果 报文 是 IP广播报文, 则 逻辑 为 真. Tcpdump 检查 全0 和 全1 广播约定, 并且 检查 本地 的 子网掩码.
ether multicast
如果 报文 是 以太多目传送报文(multicast), 则 逻辑 为 真. 关键字 ether 是 可选的. 这实际上 是 `ether[0] & 1 != 0' 的简写.
ip multicast
如果 报文 是 IP多目传送报文, 则 逻辑 为 真.
ether proto protocol
如果 报文协议 属于 以太类型 的 protocol, 则 逻辑 为 真. Protocol 可以是 数字, 也可以是 名字, 如 ip, arp, 或 rarp. 注意 这些 标识符 也是 关键字, 所以 必须 用 反斜杠(\) 转义. [如果是 FDDI (例如, `fddi protocol arp'), 协议 标识 来自 802.2 逻辑链路控制(LLC)报头, 它 通常 位于 FDDI 报头 的 顶层. 当 根据 协议标识过滤 报文 时, Tcpdump 假设 所有的 FDDI 报文 含有 LLC 报头, 而且 LLC 报头 用的是 SNAP 格式.]
decnet src host
如果 DECNET 的 源地址 是 host, 则 逻辑 为 真, 该 主机地址 的 形式 可能 是 ``10.123'', 或者是 DECNET 主机名. [只有 配置成 运行 DECNET 的 Ultrix 系统 支持 DECNET 主机名.]
decnet dst host
如果 DECNET 的 目的地址 是 host, 则 逻辑 为 真.
decnet host host
如果 DECNET 的 源地址 或 目的地址 是 host, 则 逻辑 为 真.
ip, arp, rarp, decnet
是:
ether proto p
的 简写 形式, 其中 p 为 上述 协议 的 一种.
lat, moprc, mopdl
是:
ether proto p
的 简写 形式, 其中 p 为 上述 协议 的 一种. 注意 tcpdump 目前 不知道 如何 分析 这些 协议.
tcp, udp, icmp
是:
ip proto p
的 简写 形式, 其中 p 为 上述 协议 的 一种.
expr relop expr
如果 这个 关系 成立, 则 逻辑 为 真, 其中 relop 是 >, <, >=, <=, =, != 之一, expr 是 数学表达式, 由 常整数(标准C语法形式), 普通的 二进制运算符 [+, -, *, /, &, |], 一个 长度运算符, 和指定的报文数据访问算符组成. 要访问报文内的数据, 使用下面的语法:
proto [ expr : size ]
Proto 是 ether, fddi, ip, arp, rarp, tcp, udp, or icmp 之一, 同时也指出了下标操作的协议层. expr 给出 字节单位 的 偏移量, 该 偏移量 相对于 指定的 协议层. Size 是 可选项, 指出 感兴趣的 字节数; 它可以 是 1, 2, 4, 缺省为 1 字节. 由 关键字 len 给出的 长度运算符 指明 报文 的 长度.
例如, `ether[0] & 1 != 0' 捕捉 所有的 多目传送 报文. 表达式 `ip[0] & 0xf != 5' 捕捉 所有 带 可选域 的 IP 报文. 表达式 `ip[6:2] & 0x1fff = 0' 只捕捉 未分片 和 片偏移为0 的 数据报. 这种 检查 隐含在 tcp 和 udp 下标操作 中. 例如, tcp[0] 一定是 TCP 报头 的 第一个 字节, 而不是 其中 某个 IP片 的 第一个 字节.
原语 可以 用 下述 方法 结合使用:
园括弧 括起来的 原语 和 操作符 (园括弧 在 Shell 中 有专用, 所以必须转义).
取反操作 (`!' or `not').
连结操作 (`&&' or `and').
或操作 (`||' or `or').
取反操作 有 最高优先级. 或操作 和 连结操作 有 相同的 优先级, 运算时 从左到右 结合. 注意 连结操作 需要 显式的 and 算符, 而不是 并列放置.
如果 给出 标识符, 但没给 关键字, 那么 暗指 最近使用 的 关键字. 例如,
not host vs and ace
作为
not host vs and host ace
的 简写形式, 不应该 和
not ( host vs or ace )
混淆.
表达式参数 可以 作为 单个 参数 传给 tcpdump, 也可以 作为 复合参数, 后者 更方便 一些. 一般说来, 如果 表达式 包含 Shell 元字符(metacharacter), 传递 单个 括起来的 参数 要 容易 一些. 复合参数 在 被解析前 用 空格 联接 一起.

示例 (EXAMPLES)
显示 所有 进出 sundown 的 报文:
tcpdump host sundown
显示 helios 和 主机 hot, ace 之间 的 报文 传送:
tcpdump host helios and \( hot or ace \)
显示 ace 和 除了 helios 以外的 所有 主机 的 IP报文:
tcpdump ip host ace and not helios
显示 本地的主机 和 Berkeley的主机 之间 的 网络数据:
tcpdump net ucb-ether
显示 所有 通过 网关 snup 的 ftp 报文 (注意 这个 表达式 被 单引号 括起, 防止 shell 解释 园括弧):
tcpdump 'gateway snup and (port ftp or ftp-data)'
显示 既不是 来自 本地主机, 也不是 传往 本地主机 的 网络数据 (如果 你 把 网关 通往 某个 其他网络, 这个 做法 将不会 把 数据 发往 你的本地网络).
tcpdump ip and not net localnet
显示 每个 TCP会话 的 起始 和 结束 报文 (SYN 和 FIN 报文), 而且 会话方 中有一个 远程主机.
tcpdump 'tcp[13] & 3 != 0 and not src and dst net localnet'
显示 经过 网关 snup 中 大于 576 字节的 IP 数据报:
tcpdump 'gateway snup and ip[2:2] > 576'
显示 IP 广播 或 多目传送 的 数据报, 这些 报文 不是 通过 以太网 的 广播 或 多目传送 形式 传送的:
tcpdump 'ether[0] & 1 = 0 and ip[16] >= 224'
显示 所有 不是 回响请求/应答 的 ICMP 报文 (也就是说, 不是 ping 报文):
tcpdump 'icmp[0] != 8 and icmp[0] != 0"

输出格式 (OUTPUT FORMAT)
tcpdump 的 输出格式 取决于 协议. 下面的 描述 给出 大多数 格式 的简要说明 和 范例.
链路层报头 (Link Level Headers)
如果 给出 '-e' 选项 就 显示 链路层报头. 在 以太网上, 显示 报文的 源目地址, 协议 和 报文长度.
在 FDDI 网络上, '-e' 选项 导致 tcpdump 显示出`帧控制(frame control)'域, 源目地址 和报文长度. (`帧控制' 域负责解释其余的报文. 普通报文(比如说载有IP数据报)是`异步' 报文, 优先级介于0到7; 例如, `async4'. 这些被认为载有802.2逻辑链路控制(LLC) 报文; 如果它们不是ISO数据报或者所谓的SNAP报文, 就显示出LLC报头.
(注意:以下描述中假设你熟悉RFC-1144中说明的SLIP压缩算法.)
在SLIP链路上, tcpdump显示出方向指示(``I''指inbound, ``O''指outbound), 报文类型和 压缩信息. 首先显示的是报文类型. 有三种类型ip, utcp和ctcp. 对于ip报文不再显示更多的链路信息. 对于TCP报文, 在类型后面显示连接标识. 如果报文是压缩过的, 就显示出编码的报头. 特殊情形以*S+n和*SA+n的形式显示, 这里的n是顺序号(或顺序号及其确认)发生的改变总和. 如果不是特殊情形, 就显示0或多少个改变. 改变由U (urgent pointer), W (window), A (ack), S (sequence number)和I (packet ID)指明, 后跟一个变化量(+n or -n), 或另一个值(=n). 最后显示报文中的数据总和, 以及压缩报头的长度.
例如, 下面一行显示了一个传出的压缩的TCP报文, 有一个隐含的连接标识; 确认(ack)的 变化量是 6, 顺序号 是 49, 报文ID 是 6; 有三个字节的数据 和六个字节的压缩报头:
O ctcp * A+6 S+49 I+6 3 (6)
ARP/RARP报文
Arp/rarp报文的输出显示请求类型及其参数. 输出格式倾向于能够自我解释. 这里是一个 简单的例子, 来自主机rtsg到主机csam的'rlogin'开始部分:

arp who-has csam tell rtsg
arp reply csam is-at CSAM

第一行说明rtsg发出一个arp报文询问internet主机csam的以太网地址. Csam用它的以太地址作应答 (这个例子中, 以太地址是大写的, internet地址为小写).
如果用tcpdump -n看上去要清楚一些:

arp who-has 128.3.254.6 tell 128.3.254.68
arp reply 128.3.254.6 is-at 02:07:01:00:01:c4
如果用tcpdump -e, 可以看到实际上第一个报文是广播, 第二个报文是点到点的:

RTSG Broadcast 0806 64: arp who-has csam tell rtsg
CSAM RTSG 0806 64: arp reply csam is-at CSAM

这里第一个报文指出以太网源地址是RTSG, 目的地址是以太网广播地址, 类型域为16进制数0806 (类型ETHER_ARP), 报文全长 64 字节.
TCP报文
(注意: 以下的描述中假设你熟悉RFC-793中说明的TCP协议, 如果你不了解这个协议, 无论是本文还是tcpdump都对你用处不大)
一般说来tcp协议的输出格式是:

src > dst: flags data-seqno ack window urgent options

Src和dst是源目IP地址和端口. Flags是S (SYN), F (FIN), P (PUSH)或R (RST)或单独的`.'(无标志), 或者是它们的组合. Data-seqno说明了本报文中的数据在流序号中的位置(见下例). Ack是在这条连接上 信源机希望下一个接收的字节的流序号 (sequence number). Window是在这条连接上信源机接收缓冲区 的字节大小. Urg表明报文内是`紧急(urgent)' 数据. Options是tcp 可选报头, 用尖括号括起 (例如, <mss 1024>).
Src, dst 和flags 肯定存在. 其他域依据报文的tcp报头内容, 只输出有必要的部分.
下面是从主机rtsg rlogin到主机csam的开始部分.

rtsg.1023 > csam.login: S 768512:768512(0) win 4096 <mss 1024>
csam.login > rtsg.1023: S 947648:947648(0) ack 768513 win 4096 <mss 1024>
rtsg.1023 > csam.login: . ack 1 win 4096
rtsg.1023 > csam.login: P 1:2(1) ack 1 win 4096
csam.login > rtsg.1023: . ack 2 win 4096
rtsg.1023 > csam.login: P 2:21(19) ack 1 win 4096
csam.login > rtsg.1023: P 1:2(1) ack 21 win 4077
csam.login > rtsg.1023: P 2:3(1) ack 21 win 4077 urg 1
csam.login > rtsg.1023: P 3:4(1) ack 21 win 4077 urg 1

第一行 是说 从 rtsg 的 tcp 端口 1023 向 csam 的 login 端口 发送 报文. S 标志 表明 设置了 SYN 标志. 报文 的 流序号 是 768512, 没有 数据. (这个写成 `first:last(nbytes)', 意思是 `从 流序号 first 到 last, 不包括 last, 有 nbytes 字节的 用户数据'.) 此时 没有 捎带确认(piggy-backed ack), 有效的 接收窗口 是 4096 字节, 有一个 最大段大小(max-segment-size) 的 选项, 请求 设置 mss 为 1024 字节.
Csam用类似的形式应答, 只是增加了一个对rtsg SYN的捎带确认. 然后Rtsg确认csam的 SYN. `.' 意味着没有设置标志. 这个报文不包含数据, 因此也就没有数据的流序号. 注意这个确认流序号是一个 小整数(1). 当tcpdump第一次发现一个tcp会话时, 它显示报文携带的流序号. 在随后收到的报文里, 它显示当前报文和最初那个报文的流序号之差. 这意味着从第一个报文开始, 以后的流序号可以理解成 数据流中的相对位移 as relative byte positions in the conversation's data stream (with the first data byte each direction being `1'). `-S' 选项能够改变这个特性, 直接显示原始的流序号.
在第六行, rtsg传给csam19个字节的数据(字节2到20). 报文中设置了PUSH标志. 第七行csam表明它收到了rtsg的数据, 字节序号是21, 但不包括第21个字节. 显然大多数数据在socket的缓冲区内, 因为csam的接收窗口收到的数据小于19 个字节. 同时 csam 向rtsg发送了一个字节的数据. 第八和第九行显示csam发送了两个字节的紧急数据到 rtsg.
如果捕捉区设置的过小, 以至于tcpdump不能捕捉到完整的TCP报头, tcpdump会尽可能的翻译已捕获的部分, 然后显示``[|tcp]'', 表明无法翻译其余部分. 如果报头包含一个伪造的选项 (one with a length that's either too small or beyond the end of the header), tcpdump 显示 ``[bad opt]'' 并且不再翻译其他选项部分 (因为它不可能判断出从哪儿开始). 如果报头长度表明存在选项, 但是IP数据报长度不够, 不可能真的保存选项, tcpdump就显示``[bad hdr length]''.
UDP 报文
UDP 格式 就象 这个 rwho 报文 显示的:

actinide.who > broadcast.who: udp 84

就是说 把一个 udp 数据报 从 主机 actinide 的 who 端口 发送到 broadcast, Internet 广播地址 的 who 端口. 报文 包含 84字节 的 用户数据.
某些 UDP 服务 能够 识别出来(从 源目端口号 上), 因而 显示出 更高层的 协议信息. 特别是 域名服务请求(RFC-1034/1035) 和 NFS 的 RPC 调用(RFC-1050).
UDP 域名服务请求 (Name Server Requests)
(注意: 以下的描述中 假设 你 熟悉 RFC-1035 说明的 域名服务协议. 如果你 不熟悉 这个协议, 下面的内容 就象是 天书.)
域名服务请求 的 格式 是

src > dst: id op? flags qtype qclass name (len)

h2opolo.1538 > helios.domain: 3+ A? ucbvax.berkeley.edu. (37)

主机 h2opolo 访问 helios 上的 域名服务, 询问和 ucbvax.berkeley.edu. 关联的 地址记录(qtype=A). 查询号是 `3'. `+' 表明 设置了 递归请求 标志. 查询长度是 37 字节, 不包括 UDP 和 IP 头. 查询操作 是 普通的 Query 操作, 因此 op 域 可以 忽略. 如果 op 设置成 其他什么东西, 它应该 显示在 `3' 和 `+' 之间. 类似的, qclass 是 普通的 C_IN 类型, 也被 忽略了. 其他类型的 qclass 应该 在 `A' 后面 显示.
Tcpdump 会检查 一些 不规则 情况, 相应的 结果 作为 补充域 放在 方括号内: 如果 某个 查询 包含 回答, 名字服务 或 管理机构部分, 就把 ancount, nscount, 或 arcount 显示成 `[na]', `[nn]' 或 `[nau]', 这里的 n 代表 相应的 数量. 如果 在 第二和第三字节 中, 任何一个 回答位(AA, RA 或 rcode) 或 任何一个 `必须为零' 的位 被 置位, 就显示 `[b2&3=x]', 这里的 x 是 报头 第二和第三字节 的 16进制数.
UDP 名字服务回答
名字服务回答的 格式 是

src > dst: id op rcode flags a/n/au type class data (len)

helios.domain > h2opolo.1538: 3 3/3/7 A 128.32.137.3 (273)
helios.domain > h2opolo.1537: 2 NXDomain* 0/1/0 (97)

第一个例子里, helios 回答了 h2opolo 发出的 标识为3 的 询问, 一共是 3 个 回答记录, 3 个 名字服务记录 和 7 个管理结构记录. 第一个 回答纪录 的 类型是 A (地址), 数据是 internet 地址 128.32.137.3. 回答的 全长 为 273 字节, 不包括 UDP 和 IP 报头. 作为 A 记录的 class(C_IN) 可以 忽略 op (询问) 和 rcode (NoError).
在第二个例子里, helios 对 标识为2 的 询问 作出 域名不存在 (NXDomain) 的 回答, 没有 回答记录, 一个 名字服务记录, 而且 没有 管理结构.
`*' 表明 设置了 权威回答(authoritative answer). 由于 没有 回答记录, 这里就 不显示 type, class 和 data.
其他 标志 字符 可以 显示为 `-' (没有设置递归有效(RA)) 和 `|' (设置 消息截短(TC)). 如果 `问题' 部分 没有 有效的 内容, 就 显示 `[nq]'.
注意 名字服务的 询问和回答 一般说来 比较大, 68 字节的 snaplen 可能无法 捕捉到 足够的 报文内容. 如果 你 的确 在 研究 名字服务 的 情况, 可以使用 -s 选项 增大 捕捉缓冲区. `-s 128' 应该 效果 不错了.
NFS 请求和响应
Sun NFS (网络文件系统) 的 请求和响应 显示格式 是:

src.xid > dst.nfs: len op args
src.nfs > dst.xid: reply stat len op results


sushi.6709 > wrl.nfs: 112 readlink fh 21,24/10.73165
wrl.nfs > sushi.6709: reply ok 40 readlink "../var"
sushi.201b > wrl.nfs:
144 lookup fh 9,74/4096.6878 "xcolors"
wrl.nfs > sushi.201b:
reply ok 128 lookup fh 9,74/4134.3150


在第一行, 主机 sushi 向 wrl 发送 号码为 6709 的 交易会话 (注意源主机后面的数字是交易号, 不是 端口). 这项请求 长 112 字节, 不包括 UDP 和 IP 报头. 在文件句柄 (fh) 21,24/10.731657119上执行 readlink (读取 符号连接) 操作. (如果 运气 不错, 就象这种情况, 文件句柄可以依次翻译成主次设备号, i 节点号, 和 事件号(generation number). ) Wrl回答`ok' 和连接的内容.
在第三行, sushi 请求wrl 在目录文件 9,74/4096.6878中查找 `xcolors'. 注意数据的 打印格式取决于操作类型. 格式应该是可以自我说明的.
给出-v (verbose)选项可以显示附加信息. 例如:

sushi.1372a > wrl.nfs:
148 read fh 21,11/12.195 8192 bytes @ 24576
wrl.nfs > sushi.1372a:
reply ok 1472 read REG 100664 ids 417/0 sz 29388

(-v 同时使它显示IP报头的TTL, ID, 和分片域, 在这个例子里把它们省略了.) 在第一行, sushi 请求 wrl从文件21,11/12.195 的偏移位置24576开始, 读取8192字节. Wrl 回答 `ok'; 第二行显示的报文是 应答的第一个分片, 因此只有1472字节(其余数据在后续的分片中传过来, 但由于这些分片里没有NFS 甚至UDP报头, 因此根据所使用的过滤器表达式, 有可能不显示). -v 选项还会显示一些文件属性 (它们作为文件数据的附带部分传回来): 文件类型(普通文件``REG''), 存取模式(八进制数), uid和 gid, 以及文件大小.
如果再给一个-v选项(-vv), 还能显示更多的细节.
注意NFS请求的数据量非常大, 除非增加snaplen, 否则很多细节无法显示. 试一试`-s 192' 选项.
NFS应答报文没有明确标明RPC操作. 因此tcpdump保留有``近来的''请求记录, 根据交易号匹配应答报文. 如果应答报文没有相应的请求报文, 它就无法分析.
KIP Appletalk (UDP上的DDP)
Appletalk DDP报文封装在UDP数据报中, 解包后按DDP报文转储(也就是说, 忽略所有的UDP报头信息). 文件/etc/atalk.names用来把appletalk网络和节点号翻译成名字. 这个文件的行格式是

number name

1.254 ether
16.1 icsd-net
1.254.110 ace
前两行给出了appletalk的网络名称. 第三行给出某个主机的名字(主机和网络依据第三组数字区分 - 网络号一定是两组数字, 主机号一定是三组数字.) 号码和名字用空白符(空格或tab)隔开. /etc/atalk.names 文件可以包含空行或注释行(以`#'开始的行).
Appletalk地址按这个格式显示

net.host.port

144.1.209.2 > icsd-net.112.220
office.2 > icsd-net.112.220
jssmag.149.235 > icsd-net.2

(如果不存在/etc/atalk.names , 或者里面缺少有效项目, 就以数字形式显示地址.)第一个例子里, 网络 144.1的209节点的NBP (DDP端口2) 向网络icsd的112节点的220端口发送数据. 第二行和上面一样, 只是知道了源节点的全称(`office'). 第三行是从网络jssmag的149节点的235端口向icsd-net的NBP端口广播(注意广播地址(255)隐含在无主机号的网络名字中-所以在/etc/atalk.names中区分节点名和网络名 是个好主意).
Tcpdump可以翻译NBP(名字联结协议)和ATP(Appletalk交互协议)的报文内容. 其他协议 只转储协议名称(或号码, 如果还没给这个协议注册名称)和报文大小.
NBP 报文的输出格式就象下面的例子:

icsd-net.112.220 > jssmag.2: nbp-lkup 190: "=:LaserWriter@*"
jssmag.209.2 > icsd-net.112.220: nbp-reply 190: "RM1140:LaserWriter@*" 250
techpit.2 > icsd-net.112.220: nbp-reply 190: "techpit:LaserWriter@*" 186

第一行 是 网络 icsd 的 112 主机 在 网络 jssmag 上的 广播, 对 名字 laserwriter 做 名字查询请求. 名字查询请求 的 nbp 标识号 是 190. 第二行 显示的是 对 这个请求 的 回答 (注意 它们 有 同样的 标识号), 主机 jssmag.209 表示 在它的 250 端口 注册了 一个 laserwriter 的 资源, 名字是 "RM1140". 第三行 是 这个请求 的 其他回答, 主机 techpit 的 186 端口 有 laserwriter 注册的 "techpit".
ATP报文格式如下例所示:

jssmag.209.165 > helios.132: atp-req 12266<0-7> 0xae030001
helios.132 > jssmag.209.165: atp-resp 12266:0 (512) 0xae040000
helios.132 > jssmag.209.165: atp-resp 12266:1 (512) 0xae040000
helios.132 > jssmag.209.165: atp-resp 12266:2 (512) 0xae040000
helios.132 > jssmag.209.165: atp-resp 12266:3 (512) 0xae040000
helios.132 > jssmag.209.165: atp-resp 12266:4 (512) 0xae040000
helios.132 > jssmag.209.165: atp-resp 12266:5 (512) 0xae040000
helios.132 > jssmag.209.165: atp-resp 12266:6 (512) 0xae040000
helios.132 > jssmag.209.165: atp-resp*12266:7 (512) 0xae040000
jssmag.209.165 > helios.132: atp-req 12266<3,5> 0xae030001
helios.132 > jssmag.209.165: atp-resp 12266:3 (512) 0xae040000
helios.132 > jssmag.209.165: atp-resp 12266:5 (512) 0xae040000
jssmag.209.165 > helios.132: atp-rel 12266<0-7> 0xae030001
jssmag.209.133 > helios.132: atp-req* 12267<0-7> 0xae030002

Jssmag.209向主机helios发起12266号交易, 请求8个报文(`<0-7>'). 行尾的十六进制数是请求中 `userdata' 域的值.
Helios用8个512字节的报文应答. 跟在交易号后面的 `:digit' 给出了交易过程中报文的 序列号, 括弧内的数字是报文的数据量, 不包括atp报头. 报文7的`*'表明设置了EOM位.
然后Jssmag.209请求重传第3 & 5报文. Helios做了重传后jssmag.209结束这次交易. 最后, jssmag.209发起下一次交易请求. 请求中的`*'表明没有设置XO(只有一次)位.
IP分片
分片的Internet数据报显示为

(frag id:size@offset+)
(frag id:size@offset)

(第一种形式表明还有更多的分片. 第二种形式表明这是最后一片.)
Id是分片标识号. Size是分片大小(字节), 不包括IP报头. Offset 是该分片在原数据报中 的偏移(单位是字节).
每一个分片的信息都可以打印出来. 第一个分片包含了高层协议报头, 显示协议信息后 显示分片的信息. 第一个分片以后的分片不再含有高层协议报头, 所以在源目地址后面 只显示分片信息. 例如, 下面是从arizona.edu到lbl-rtsg.arpa的一部分ftp 传输, 途经的 CSNET看上去处理不了576字节的数据报:

arizona.ftp-data > rtsg.1170: . 1024:1332(308) ack 1 win 4096 (frag 595a:328@0+)
arizona > rtsg: (frag 595a:204@328)
rtsg.1170 > arizona.ftp-data: . ack 1536 win 2560

这里有几点需要注意: 首先, 第二行的地址不包括端口号. 这是因为TCP协议信息全部装到了第一个 分片内, 所以显示后续分片的时候不可能知道端口或流序号. 其次, 第一行的tcp 流序号部分看上去有 308字节的用户数据, 实际上是512 字节 (第一个分片的308 和第二个分片的 204 字节). 如果你正在 寻找流序号中的空洞, 或者试图匹配报文的确认(ack), 那你上当了.
如果报文的IP标有不要分片标志, 显示时在尾部加上(DF).
时戳
缺省情况下, 所有输出行的前面都有时戳. 时戳就是当前时间, 显示格式为
hh:mm:ss.frac
精度和内核时钟一样. 时戳反映了内核收到报文的时间. 从以太接口收到报文到内核响应 '报文就绪' 中断有一个滞后, 该滞后不被考虑.

另见 (SEE ALSO)
traffic(1C), nit(4P), bpf(4), pcap(3)

作者 (AUTHORS)
Van Jacobson, Craig Leres and Steven McCanne, all of the Lawrence Berkeley National Laboratory, University of California, Berkeley, CA.
当前版本可以从匿名ftp获得:
ftp://ftp.ee.lbl.gov/tcpdump.tar.Z

BUGS
请把臭虫报告传往 tcpdump@ee.lbl.gov.
NIT不允许监视你自己的传出数据, BPF可以. 我们建议你使用后者.
应该试着重组IP分片, 至少可以为更高层的协议计算出正确的长度.
名字服务逆向询问转储的不正确: 打印出(空的)问题部分, 而实际上询问放在了回答部分. 有人认为这种逆向询问本身就是bug, 应该修改产生问题的程序, 而非tcpdump.
苹果Ethertalk DDP的报文应该象KIP DDP的报文一样容易转储, 事实却不是这样. 即使 我们有意作点什么来促销Ethertalk (我们没有), LBL也不允许Ethertalk出现在它的任何网络上, 所以我们没办法测试这些代码.
如果报文的路径上出现夏时制时间变化, 可能导致时戳混乱. (这个时间变化将忽略)
操作FDDI报头的过滤器表达式假设所有的FDDI报文被封装在以太报文中. 这对IP, ARP 和DECNET Phase IV无疑是正确的, 但对某些协议如ISO CLNS不正确. 因此, 过滤器 有可能会糊里糊涂的接收一些并不真正匹配过滤器表达式的报文.

[中文版维护人]
徐明Email: xuming@bigfoot.com
[中文版最新更新]
2001/3/5
《中国Linux论坛man手册页翻译计划》
www.linuxforum.net/man-pages/





欲知前世因,今生受者是。
欲知来世果,今生作者是。
顶部
 



当前时区 GMT+8, 现在时间是 2008-12-5 08:28
乐悠LoveUnix论坛-京ICP备05005823号

Thanks to Discuz!  © 2001-2007    Power by LoveUnix.net
Processed in 0.050768 second(s), 6 queries , Gzip enabled

清除 Cookies - 联系我们 - 乐悠LoveUnix - Archiver