0

Need to write a tool where i need to construct the whole ICMPv6 packet. I can't seem to get the code to generate correct ICMPv6 checksum. I have tried the checksum(void * buffer, int bytes) function from the following

Calculating checksum of ICMPv6 Packet in C

I have a wireshark capture that I am using to verify the checksum. The original packet content looks like

0000 33 33 00 00 00 01 38 ea a7 89 be 59 86 dd 60 00 0010 00 00 00 20 3a ff fe 80 00 00 00 00 00 00 88 c5 0020 75 41 aa 0c 58 ee ff 02 00 00 00 00 00 00 00 00 0030 00 00 00 00 00 01 88 00 b8 cc 20 00 00 00 fe 80 0040 00 00 00 00 00 00 88 c5 75 41 aa 0c 58 ee 02 01 0050 38 ea a7 89 be 59

The correct checksum ofcourse from the packet is 0xb8cc. The packet above is the whole IPv6 packet but the relevant content of the packet starts from source address which is fe 80 00 00 00 00 00 00 88 c5 75 41 aa 0c 58 ee . ICMPv6 header starts at 88 00.

I think the checksum function from the link above might be correct but the buffer I am constructing to calculate checksum on is probably incorrect. Following the RFCs, I constructed the buffer by concatenating source addr, dest addr, packet length (32 = 00 20), Next header (58 = 3a), rest of ICMPv6 packet which gives me the final buffer of

uint8_t packet[] = { 0xfe , 0x80 ,0x00 , 0x00 ,0x00 , 0x00 ,0x00 , 0x00 , 0x88 , 0xc5 ,0x75 , 0x41 ,0xaa , 0x0c ,0x58 , 0xee, 0xff , 0x02 ,0x00 , 0x00 ,0x00 , 0x00 ,0x00 , 0x00, 0x00 , 0x00 ,0x00 , 0x00 ,0x00 , 0x00 ,0x00 , 0x01, 0x00 , 0x20 ,0x3a , 0x88 ,0x00 , 0x00 ,0x00 , 0x20 , 0x00 ,0x00 , 0x00 ,0xfe , 0x80 ,0x00 , 0x00 , 0x00 , 0x00 ,0x00 , 0x00 ,0x88 , 0xc5 ,0x75 , 0x41 , 0xaa , 0x0c ,0x58 , 0xee ,0x02 , 0x01 ,0x38 , 0xea , 0xa7 , 0x89 ,0xbe , 0x59 }; I call the checksum function as

fprintf(stdout, "%x\n", ~checksum(packet, sizeof(packet)));

but checksum value I get is ffffd174. Neglecting the first 2 bytes, I am getting 7510.

Any ideas what I am doing wrong? I think that there might be an endian problem in the checksum function but also I might have constructed the psuedo-header incorrectly.

Community
  • 1
  • 1
quandrione
  • 61
  • 1
  • 4

1 Answers1

0

Figured out the problem, so posting the correction in case someone else is looking for it.

Problem was in how I added nextheader to the input data to checksum function. I needed to prefix Nextheader with one 0x00 byte. Last 32 bits in pseudo header part are supposed to be zeros followed by next header. Since first 16 bits only add to 0, it was sufficient to add only one zero byte before next header. So the input data to checksum function ended up being

    uint8_t packet[] = {
            0xfe , 0x80 ,0x00 , 0x00 ,0x00 , 0x00 ,0x00 , 0x00, // src
            0x88 , 0xc5 ,0x75 , 0x41 ,0xaa , 0x0c ,0x58 , 0xee,
            0xff , 0x02 ,0x00 , 0x00 ,0x00 , 0x00 ,0x00 , 0x00, // dst
            0x00 , 0x00 ,0x00 , 0x00 ,0x00 , 0x00 ,0x00 , 0x01,
            0x00 , 0x20 , // length 32
            0x00 , 0x3a , // next header 58
            0x88 , // type
            0x00 , // code
            0x00 , 0x00 , // checksum
            0x20 , 0x00 ,0x00 , 0x00 ,0xfe , 0x80 ,0x00 , 0x00 , // body
            0x00 , 0x00 ,0x00 , 0x00 ,0x88 , 0xc5 ,0x75 , 0x41 ,
            0xaa , 0x0c ,0x58 , 0xee ,0x02 , 0x01 ,0x38 , 0xea ,
            0xa7 , 0x89 ,0xbe , 0x59
    };
quandrione
  • 61
  • 1
  • 4