corvvs / ding

a ping.
0 stars 0 forks source link

bug?: macOSでICMP Time Exceededのチェックサムが合わない問題 #101

Open corvvs opened 1 year ago

corvvs commented 1 year ago

サンプルデータ

コマンド$ ./ft_ping -c1 -m2 -xX kantei.go.jp

出力(抜粋)

[D] [srcs/pong_receiver.c:14 receive_reply] recvmsg rv: 56
[received message] dumping 56 of 56 bytes
000000:  4500 2400 9940 0000 fe01 9499 6705 8e3c 
0x0010:  0a12 8f97 0b00 4125 0000 0000 4500 5400 
0x0020:  9940 0000 0101 f0f5 0a12 8f97 6354 3276 
0x0030:  0800 728d 394d 0000 
[D] [srcs/validator.c:43 validate_received_ip_preliminary] ip_header_len: 20
[D] [srcs/validator.c:52 validate_received_ip_preliminary] icmp_whole_len: 36
[before cksum] dumping 36 of 36 bytes
000000:  0b00 4125 0000 0000 4500 5400 9940 0000 
0x0010:  0101 f0f5 0a12 8f97 6354 3276 0800 728d 
0x0020:  394d 0000 
[cksum] dumping 36 of 36 bytes
000000:  0b00 0000 0000 0000 4500 0054 4099 0000 
0x0010:  0101 f5f0 0a12 8f97 6354 3276 0800 728d 
0x0020:  394d 0000 
[D] [srcs/protocol_icmp.c:25 derive_icmp_checksum] datagram: 0x16f78a994, len: 36
[D] [srcs/protocol_icmp.c:44 derive_icmp_checksum] ans: 53652 d194
[D] [srcs/protocol_icmp.c:73 is_valid_icmp_checksum] checksum: received: 9537(2541) derived: 53652(d194) diffrence: 4294923181(ffff53ad) icmp_whole_len: 36
[W] [srcs/validator.c:126 validate_received_icmp_echo_reply] checksum is bad
[I] [srcs/protocol_icmp.c:7 flip_endian_icmp] FLIP: 0x16f78a994
8 bytes from 103.5.142.60: Time to live exceeded

Wiresharkで受信したICMP Time ExceededのICMP部分

0000   0b 00 41 25 00 00 00 00 45 00 00 54 99 40 00 00
0010   01 01 f0 f5 0a 12 8f 97 63 54 32 76 08 00 72 8d
0020   39 4d 00 00

Wiresharkデータと受信データを比べる

Wiresharkのデータを2バイト区切りに直す:

000000:  0b00 4125 0000 0000 4500 0054 9940 0000
0x0010:  0101 f0f5 0a12 8f97 6354 3276 0800 728d
0x0020:  394d 0000

これと比べるのは, チェックサム計算前のデータ

[before cksum] dumping 36 of 36 bytes
000000:  0b00 4125 0000 0000 4500 5400 9940 0000 
0x0010:  0101 f0f5 0a12 8f97 6354 3276 0800 728d 
0x0020:  394d 0000

両者の差異は 0054(5400)の2バイトのみ。\ これは「ICMP Time Exceededを発生させたIPデータグラム(以下"オリジナルIP")のIPヘッダのTotal Length」(長えな)にあたる。

チェックサム計算の際は、「チェックサム計算前のデータ」に対して

を行う。

この時のデータは:

[cksum] dumping 36 of 36 bytes
000000:  0b00 0000 0000 0000 4500 0054 4099 0000 
0x0010:  0101 f5f0 0a12 8f97 6354 3276 0800 728d 
0x0020:  394d 0000 

Total Lengthに加えて2箇所の差異がある:

→ この2つはIPヘッダのエンディアン変換の対象外??

試しにIPヘッダのエンディアン変換からこの2つ(ID, ヘッダーチェックサム)を除外してみたらICMPチェックサムがGoodになった! → 当たり

corvvs commented 1 year ago

「一般論としてIPのID, ヘッダーチェックサムはエンディアン変換しない」という話ではないことに注意。

corvvs commented 1 year ago

これどうしようか・・・