0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【ICMPv6】チェックサム計算

Posted at
.c
/* https://alpha-netzilla.blogspot.com/2011/08/network.html */
/* Version + HeaderLength + ServiceType : 0x4500    */
/* TotalLength                  : 0x003C            */
/* Identifier                   : 0xF228            */
/* Flag + FragmentOffset        : 0x0000            */
/* TTL + Protocol               : 0x8001            */
/* CheckSum                     : 0xC140 → 0x0000   */
/* SourceIP                     : 0xC0A8            */
/*                                0x0303            */
/* DestIP                       : 0xC0A8            */
/*                                0x0304            */

/* icmpv6 checksum    */
/* Source Address     */
/* Destination Addres */
/* IpV6 Packet Length */
/* zero               */
/* Next Header = 0x3A */

# include <stdio.h>
# include <string.h>

typedef unsigned char  u_int8_t;
typedef unsigned char  u_char;
typedef unsigned short u_int16_t;
typedef unsigned long  u_int32_t;

u_int16_t checksum(u_char *data, int len);

int main( void )
{
    u_int16_t  checksum_gen = 0x0000;
    u_int16_t  checksum_ret = 0x0000;
    u_int16_t  data[] = {
        0x4500, 0x003C,
        0xF228, 0x0000,
        0x8001, checksum_gen,
        0xC0A8, 0x0303,
        0xC0A8, 0x0304,
    };
    
    /* checksum generate */
    checksum_gen = checksum((u_char*)&data[0], sizeof(data));
    
    /* checksum check */
    data[5] = checksum_gen;
    checksum_ret = checksum((u_char*)&data[0], sizeof(data));

    printf("checksum_len = %d\n", sizeof(data));
    printf("checksum_gen = 0x%04X\n", checksum_gen);
    printf("checksum_ret = 0x%04X\n", checksum_ret);
}

u_int16_t checksum(u_char *data, int len)
{
  register u_int32_t sum;
  register u_int16_t *ptr;
  register int       c;

  sum = 0;
  ptr = (u_int16_t *)data;

  for ( c = len; c > 1; c -= 2 )
  {
    sum += (*ptr);
    // sumは32bitなので0x80000000(2進数にしたら最上位bitが1)を超えると
    // 次の足し合わせ時に桁あふれする恐れがある。
    // よってこの段階でオーバーフロー分を加算しておく。
    if ( sum & 0x80000000 )
    {
      sum = (sum & 0xFFFF) + (sum >> 16);
    }
    ptr++;
  }

  if (c == 1)
  {
    u_int16_t val;
    val = 0;
    // 16bitの変数に8bitの値を前方に詰める。
    memcpy(&val, ptr, sizeof(u_int8_t));
    sum += val;
  }

  while (sum >> 16)
  {
    sum = (sum & 0xFFFF) + (sum >> 16);
  }
  // この結果が0または0xFFFFであればよい。
  return(~sum);
}

参考(引用)
https://alpha-netzilla.blogspot.com/2011/08/network.html

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?