Checksum_test.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. #include "util/Checksum.h"
  16. #include "util/Bits.h"
  17. #include "util/Endian.h"
  18. #include "util/Hex.h"
  19. #include "util/Assert.h"
  20. #include <stdio.h>
  21. #include <string.h>
  22. static void checksumAlgorithmTestCase(const char* hex, uint16_t expectedSum)
  23. {
  24. Assert_true(strlen(hex) < 512);
  25. uint8_t packetBuff[256];
  26. uint8_t* packet = packetBuff + ((uintptr_t)packetBuff % 2);
  27. Assert_true(Hex_decode(packet, 256, hex, strlen(hex)) == (int)(strlen(hex) / 2));
  28. uint16_t calcatedSum = Checksum_engine_be(packet, strlen(hex) / 2);
  29. uint16_t expected_be = Endian_hostToBigEndian16(expectedSum);
  30. if (calcatedSum != expected_be) {
  31. printf("%2x != %2x\n", calcatedSum, expected_be);
  32. Assert_true(calcatedSum == expected_be);
  33. }
  34. }
  35. static void checksumAlgorithmTest()
  36. {
  37. checksumAlgorithmTestCase("00", 0xffff);
  38. checksumAlgorithmTestCase("0001", 0xfffe);
  39. checksumAlgorithmTestCase("000102", 0xfdfe);
  40. checksumAlgorithmTestCase("00010203", 0xfdfb);
  41. checksumAlgorithmTestCase("ff", 0xff);
  42. checksumAlgorithmTestCase("fffe", 0x1);
  43. checksumAlgorithmTestCase("fffefd", 0x300);
  44. checksumAlgorithmTestCase("fffefdfc", 0x204);
  45. checksumAlgorithmTestCase("45000054ccf3000040010000c0a80001c0a8000b", 0x2c59);
  46. checksumAlgorithmTestCase("45000034fa4d400040064b8d0a4206015cde87c8", 0x0000);
  47. checksumAlgorithmTestCase("45000034fa4d4000400600000a4206015cde87c8", 0x4b8d);
  48. }
  49. #define UDP_PACKET_HEX /* vvvv --- IPv4 header checksum */\
  50. "4500""0033""7a95""4000""4011""f877""c0a8""0102""0402""0201" \
  51. /* UDP checksum -- vvvv */\
  52. "9e05""0035""001f""c7dd" \
  53. /* content */\
  54. "221a""0100""0001""0000""0000""0000""0564""6562""6f38""0000""1c00""01"
  55. static const uint8_t* udpPacketHex = (uint8_t*) UDP_PACKET_HEX;
  56. #define UDP_PACKET_SIZE ((sizeof(UDP_PACKET_HEX)-1)/2)
  57. static void checksumUDPTest()
  58. {
  59. uint8_t packetBuff[UDP_PACKET_SIZE + 1];
  60. uint8_t* packet = packetBuff + ((uintptr_t)packetBuff % 2);
  61. Hex_decode(packet, UDP_PACKET_SIZE, udpPacketHex, UDP_PACKET_SIZE * 2);
  62. //operating on the ip checksum which is easy to compute.
  63. uint16_t checksum;
  64. Bits_memcpy(&checksum, &packet[8], 2);
  65. packet[8] = 0;
  66. packet[9] = 0;
  67. uint16_t calcatedSum = Checksum_engine_be(packet, 20);
  68. //printf("%2x == %2x", checksum, calcatedSum);
  69. Assert_true(checksum == calcatedSum);
  70. }
  71. #define UDP6_PACKET_HEX \
  72. /* Packet type --- vv */ \
  73. "6000""0000""0019""1140" \
  74. /* Source addr. */ \
  75. "fce5""de17""cbde""c87b""5289""0556""8b83""c9c8" \
  76. /* Dest addr. */ \
  77. "fc00""0000""0000""0000""0000""0000""0000""0001" \
  78. /* UDP checksum -- vvvv */ \
  79. "b4a9""0035""0019""4972" \
  80. /* Content */ \
  81. "e4e4""0100""0001""0000""0000""0000""0000""0200" \
  82. "01"
  83. static const uint8_t* udp6PacketHex = (uint8_t*) UDP6_PACKET_HEX;
  84. #define UDP6_PACKET_SIZE ((sizeof(UDP6_PACKET_HEX)-1)/2)
  85. static void udp6ChecksumTest()
  86. {
  87. uint8_t packet[UDP6_PACKET_SIZE + 3];
  88. Hex_decode(packet, UDP6_PACKET_SIZE, udp6PacketHex, UDP6_PACKET_SIZE * 2);
  89. // add some evil at the end to check for buffer overrun
  90. packet[UDP6_PACKET_SIZE] = 0x00;
  91. packet[UDP6_PACKET_SIZE + 1] = 0x00;
  92. packet[UDP6_PACKET_SIZE + 2] = 0x00;
  93. uint16_t udp6Checksum;
  94. Bits_memcpy(&udp6Checksum, &packet[46], 2);
  95. packet[46] = 0;
  96. packet[47] = 0;
  97. uint16_t calcatedSum = Checksum_udpIp6_be(&packet[8], &packet[40], 25);
  98. printf("%2x == %2x", udp6Checksum, calcatedSum);
  99. Assert_true(udp6Checksum == calcatedSum);
  100. }
  101. #define PING6_PACKET_HEX \
  102. /* Packet type --- vv */ \
  103. "6000""0000""0040""3a40" \
  104. /* Source Addr. */\
  105. "fce5""de17""cbde""c87b""5289""0556""8b83""c9c8" \
  106. /* Dest Addr. */\
  107. "fc00""0000""0000""0000""0000""0000""0000""0001" \
  108. /* vvvv -- ICMP6 Checksum */\
  109. "8000""1d00" \
  110. /* Content */\
  111. "792e""0020""11d3""a04f""0000""0000""57bb""0800" \
  112. "0000""0000""1011""1213""1415""1617""1819""1a1b" \
  113. "1c1d""1e1f""2021""2223""2425""2627""2829""2a2b" \
  114. "2c2d""2e2f""3031""3233""3435""3637"
  115. static const uint8_t* ping6PacketHex = (uint8_t*) PING6_PACKET_HEX;
  116. #define PING6_PACKET_SIZE ((sizeof(PING6_PACKET_HEX)-1)/2)
  117. static void icmp6ChecksumTest()
  118. {
  119. uint8_t packet[PING6_PACKET_SIZE];
  120. Hex_decode(packet, PING6_PACKET_SIZE, ping6PacketHex, PING6_PACKET_SIZE * 2);
  121. uint16_t checksum;
  122. Bits_memcpy(&checksum, &packet[42], 2);
  123. packet[42] = 0;
  124. packet[43] = 0;
  125. uint16_t calcatedSum = Checksum_icmp6_be(&packet[8], &packet[40], 64);
  126. //printf("%2x == %2x", checksum, calcatedSum);
  127. Assert_true(checksum == calcatedSum);
  128. }
  129. int main()
  130. {
  131. checksumAlgorithmTest();
  132. checksumUDPTest();
  133. udp6ChecksumTest();
  134. icmp6ChecksumTest();
  135. return 0;
  136. }