若通过wireshark抓取数据包来分析ZMODEM协议,可利用lrzsz软件支持的TCP连接方式来传输数据,这样数据为明文,方便分析。
首先启动接收端。“--tcp-server"命令行参数启动一个tcp服务器。启动后给出一个随机端口号。
:~$ rz --tcp-server
connect with lrz --tcp-client "localhost:34165"
然后根据给出的端口号(34165)启动wireshare抓包软件抓取这个端口的数据。
再启动发送程序将文件发送到出去。
sz -v --tcp-client localhost:34165 zreadline.c
connecting to [localhost] <34165>
Sending: zreadline.c
Transfer complete
第一个包是sz发送到rz的:
0000 72 7a 0d rz.
应为指定接收端程序需要为rz
第二个包是rz的响应。
0000 2a 2a 18 42 30 31 30 30 30 30 30 30 32 33 62 65 **.B0100000023be
0010 35 30 0d 8a 11 50...
解析如下:
2a 2a 18 42:ZPAD ZPAD ZDLE ZHEX
30 31: frame type(ZRINIT)
30 30 30 30 30 30 32 33: 00000023 Txhdr[ZF0] = CANFC32|CANFDX|CANOVIO;
62 65 35 30: crc
0d 8a 11: 同 ZRQINIT
第三个包是sz发出:
0000 2a 2a 18 42 30 30 30 30 30 30 30 30 30 30 30 30 **.B000000000000
0010 30 30 0d 8a 11 00...
2a 2a 18: ZPAD ZPAD ZDLE
42: ZHEX 十六进制报头
30 30:Frame type(ZRQINIT)
30 30 30 30 30 30 30 30: TxHdr
30 30 30 30: crc(因为的所有值为零,得到的CRC也为零)
0d 8a
11: XON(021)if (type != ZFIN && type != ZACK)
第四个包,rz再次发送ZRINIT包进行响应(与第二个包相同)。
0000 2a 2a 18 42 30 31 30 30 30 30 30 30 32 33 62 65 **.B0100000023be
0010 35 30 0d 8a 11 50...
第五个包,sz发送文件信息。
0000 2a 18 43 04 00 00 00 00 dd 51 a2 33 *.C......Q.3
2a 18: ZPAD ZDLE
43: C(ZBIN)
04: ZFILE
00 00 00 00: TxHdr
dd 51 a2 33: crc
第六个包,可视为第五个包的包体。
0000 7a 72 65 61 64 6c 69 6e 65 2e 63 00 33 31 36 32 zreadline.c.3162
0010 20 36 36 34 30 33 30 31 35 35 34 20 31 30 30 37 6640301554 1007
0020 37 37 20 30 20 31 20 33 31 36 32 00 18 6b 84 82 77 0 1 3162..k..
0030 0c 9b 11 ...
7a 72 65 61 64 6c 69 6e 65 2e 63 00: filename(zreadline.c)
33 31 36 32 20: st_size(3162)
36 36 34 30 33 30 31 35 35 34 20: st_mtime(6640301554)
31 30 30 37 37 37 20: st_mode(100777)
30 20: 0
31 20: Filesleft=1
33 31 36 32 00: Totalleft
18: ZDLE
6b: ZCRCW('k')
84 82 0c 9b: CRC
11: XON
第七个包,rz发送的响应。
0000 2a 2a 18 42 30 39 30 30 30 30 30 30 30 30 61 38 **.B0900000000a8
0010 37 63 0d 8a 11 7c...
rz -> sz
2a 2a 18
42
30 39: ZRPOS
30 30 30 30 30 30 30 30
61 38 37 63
0d 8a 11
第八个包,发送文件内容。共有1042字节。前12字节为包头,后六个字节为文件块的块尾,中间1024字节为文件内容。只有第一个块的开始有包头。
0000 2a 18: ZPAD ZDLE
43: ZBIN32('C')
0a: ZDATA
00 00 00 00
bc ef 92 8c: CRC
2f 2a 0a 20 此处开始为文件内容 /*.
0010 20 7a 72 65 61 64 6c 69 6e 65 2e 63 20 2d 20 6c zreadline.c - l
................
03f0 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 6c 69 62 #include <stdlib
0400 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 .h>.#include.iLn
18 69 4c 6e 33 30 每个文件块为1024字节,最后为六个字节为 ZDLE ZCRCE 外加 四个字节的CRC
第九个包,共有1448字节。前1030字节为第二个块(1024字节数据+6字节块尾)
后418字节为第三个块的前一部分。
第十个包,720字节。第三个数据块已经在前一个包发送了418字节,则还剩余1030-418=612字节,720-612=108。文件总长度为3162字节,3162-3x1024=90。108-(90+6)=12。
此12字节为表示文件传输完成的ZEOF帧
2a 18 43
0b: ZEOF
5a 0c 00 00: 传输文件长度。size=0xc5a(3162)
ae d0 58 1c CRC
文件分四个块传输完成。前三个块为1024字节,后一块为90字节。
rz -> sz
剩余四个帧比较简单,就不用再解释了。
0000 2a 2a 18 42 30 31 30 30 30 30 30 30 32 33 62 65 **.B0100000023be
0010 35 30 0d 8a 11 50...
sz -> rz
0000 2a 2a 18 42 30 38 30 30 30 30 30 30 30 30 30 32 **.B080000000002
0010 32 64 0d 8a 2d..
rz -> sz
0000 2a 2a 18 42 30 38 30 30 30 30 30 30 30 30 30 32 **.B080000000002
0010 32 64 0d 8a 2d..
sz -> rz
0000 4f 4f OO