ICMPヘッダの生成

Last-modified: 2008-04-20 (日) 14:31:11

[エコーメッセージ・エコーリプライメッセージ from RFC792]

   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |     Type      |     Code      |          Checksum             |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |           Identifier          |        Sequence Number        |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |     Data ...
  +-+-+-+-+-
 

[ICMPHeader構造体]

struct ICMPHeader {
   BYTE    type;
   BYTE    code;
   USHORT  checksum;
   USHORT  id;
   USHORT  seq;
   ULONG   timestamp;
};
 

[送信するパケットサイズの計算方法]

#define

#define
packet_size = max(sizeof(ICMPHeader), min(MAX_PING_DATA_SIZE, (unsigned int)packet_size));

 

[設定の例]
ICMPHeader *icmp_hdr = NULL;
icmp_hdr = (ICMPHeader *)malloc(sizeof(icmp_hdr));
icmp_hdr->type = ICMP_ECHO_REQUEST; //RFC792を参照します。
icmp_hdr->code = 0;
icmp_hdr->checksum = 0;
icmp_hdr->id = (USHORT)GetCurrentProcessId();
icmp_hdr->seq = 0;
icmp_hdr->timestamp = (ULONG)GetTickCount();

ICMPHeader == 送信データサイズならばパディングをする必要はありませんが、ICMPHeader < 送信データサイズ
のときにはICMPHeader以外をパディングします。

 

[チェックサムの計算]
RFC1071を参照

ヘッダチェックサム
The 16 bit one's complement of the one's complement sum of all 16 bit words in the header. For computing the checksum, the checksum field should be zero. This checksum may be replaced in the future.
ヘッダ内のすべての 16 ビットワードの 1 の補数の合計の、さらに 16 ビットの 1 の補数である。チェックサムを計算するとき、チェックサムフィールド自身はゼロとみなされるべきである。このチェックサムの計算方法は将来置き換えられる可能性がある。

 

[参照]
TCP/IPの教科書
Winsock Programmer's FAQ
RFC792
RFC1071
IP,ICMP,UDP のチェックサムの計算方法