在 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 可选报头, 用 尖括号 括起 (例如, ).
Src, dst 和 flags 肯定 存在. 其他域 依据 报文的 tcp 报头 内容, 只输出 有必要 的 部分.
下面 是 从 主机 rtsg rlogin 到 主机 csam 的 开始部分.
rtsg.1023 csam.login: S 768512:768512(0) win 4096
csam.login rtsg.1023: S 947648:947648(0) ack 768513 win 4096
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 传给 csam 19 个字节 的 数据 (字节 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)