00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00037 #include <sys/types.h>
00038
00039 #include <net_checksum.h>
00040
00042 #define CRC_DIVIDER_BE 0x04c11db7
00043
00045 #define CRC_DIVIDER_LE 0xedb88320
00046
00052 uint16_t compact_checksum(uint32_t sum)
00053 {
00054
00055 while (sum >> 16)
00056 sum = (sum & 0xffff) + (sum >> 16);
00057
00058 return (uint16_t) sum;
00059 }
00060
00070 uint32_t compute_checksum(uint32_t seed, uint8_t *data, size_t length)
00071 {
00072 size_t index;
00073
00074
00075 for (index = 0; index + 1 < length; index += 2)
00076 seed += (data[index] << 8) + data[index + 1];
00077
00078
00079 if (index + 1 == length)
00080 seed += data[index] << 8;
00081
00082 return seed;
00083 }
00084
00092 uint32_t compute_crc32_be(uint32_t seed, uint8_t * data, size_t length)
00093 {
00094 size_t index;
00095
00096
00097 while (length >= 8) {
00098
00099 seed ^= (*data) << 24;
00100
00101
00102 for (index = 0; index < 8; ++index) {
00103
00104 if (seed & 0x80000000) {
00105
00106 seed = (seed << 1) ^ ((uint32_t) CRC_DIVIDER_BE);
00107 } else {
00108
00109 seed <<= 1;
00110 }
00111 }
00112
00113
00114 ++data;
00115 length -= 8;
00116 }
00117
00118
00119 if (length > 0) {
00120
00121 seed ^= ((*data) & (0xff << (8 - length))) << 24;
00122
00123
00124 for (index = 0; index < length; ++index) {
00125
00126 if (seed & 0x80000000) {
00127
00128 seed = (seed << 1) ^ ((uint32_t) CRC_DIVIDER_BE);
00129 } else {
00130
00131 seed <<= 1;
00132 }
00133 }
00134 }
00135
00136 return seed;
00137 }
00138
00146 uint32_t compute_crc32_le(uint32_t seed, uint8_t * data, size_t length)
00147 {
00148 size_t index;
00149
00150
00151 while (length >= 8) {
00152
00153 seed ^= (*data);
00154
00155
00156 for (index = 0; index < 8; ++index) {
00157
00158 if (seed & 1) {
00159
00160 seed = (seed >> 1) ^ ((uint32_t) CRC_DIVIDER_LE);
00161 } else {
00162
00163 seed >>= 1;
00164 }
00165 }
00166
00167
00168 ++data;
00169 length -= 8;
00170 }
00171
00172
00173 if (length > 0) {
00174
00175 seed ^= (*data) >> (8 - length);
00176
00177 for (index = 0; index < length; ++index) {
00178
00179 if (seed & 1) {
00180
00181 seed = (seed >> 1) ^ ((uint32_t) CRC_DIVIDER_LE);
00182 } else {
00183
00184 seed >>= 1;
00185 }
00186 }
00187 }
00188
00189 return seed;
00190 }
00191
00198 uint16_t flip_checksum(uint16_t checksum)
00199 {
00200
00201 checksum = ~checksum;
00202 return checksum ? checksum : IP_CHECKSUM_ZERO;
00203 }
00204
00216 uint16_t ip_checksum(uint8_t *data, size_t length)
00217 {
00218
00219 return flip_checksum(compact_checksum(compute_checksum(0, data,
00220 length)));
00221 }
00222