Changeset 858fc90 in mainline for uspace/srv/net/checksum.c
- Timestamp:
- 2010-03-15T19:35:25Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 6092b56e
- Parents:
- 92307f1 (diff), 4684368 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/checksum.c
r92307f1 r858fc90 47 47 #define CRC_DIVIDER_LE 0xEDB88320 48 48 49 uint32_t compute_crc32_le( uint32_t seed, uint8_t * data, size_t length ){ 50 size_t index; 49 uint16_t compact_checksum(uint32_t sum){ 50 // shorten to the 16 bits 51 while(sum >> 16){ 52 sum = (sum &0xFFFF) + (sum >> 16); 53 } 51 54 52 while( length >= 8 ){ 53 seed ^= ( * data ); 54 for( index = 0; index < 8; ++ index ){ 55 if( seed & 1 ){ 56 seed = ( seed >> 1 ) ^ (( uint32_t ) CRC_DIVIDER_LE ); 57 }else{ 58 seed >>= 1; 59 } 60 } 61 ++ data; 62 length -= 8; 63 } 64 if( length > 0 ){ 65 seed ^= ( * data ) >> ( 8 - length ); 66 for( index = 0; index < length; ++ index ){ 67 if( seed & 1 ){ 68 seed = ( seed >> 1 ) ^ (( uint32_t ) CRC_DIVIDER_LE ); 69 }else{ 70 seed >>= 1; 71 } 72 } 73 length -= 8; 74 } 75 return seed; 55 return (uint16_t) sum; 76 56 } 77 57 78 uint32_t compute_crc32_be( uint32_t seed, uint8_t * data, size_t length ){ 79 size_t index; 80 81 while( length >= 8 ){ 82 seed ^= ( * data ) << 24; 83 for( index = 0; index < 8; ++ index ){ 84 if( seed & 0x80000000 ){ 85 seed = ( seed << 1 ) ^ (( uint32_t ) CRC_DIVIDER_BE ); 86 }else{ 87 seed <<= 1; 88 } 89 } 90 ++ data; 91 length -= 8; 92 } 93 if( length > 0 ){ 94 seed ^= (( * data ) & ( 0xFF << ( 8 - length ))) << 24; 95 for( index = 0; index < length; ++ index ){ 96 if( seed & 0x80000000 ){ 97 seed = ( seed << 1 ) ^ (( uint32_t ) CRC_DIVIDER_BE ); 98 }else{ 99 seed <<= 1; 100 } 101 } 102 length -= 8; 103 } 104 return seed; 105 } 106 107 uint32_t compute_checksum( uint32_t seed, uint8_t * data, size_t length ){ 108 size_t index; 58 uint32_t compute_checksum(uint32_t seed, uint8_t * data, size_t length){ 59 size_t index; 109 60 110 61 // sum all the 16 bit fields 111 for( index = 0; index + 1 < length; index += 2){112 seed += ( data[ index ] << 8 ) + data[ index + 1];62 for(index = 0; index + 1 < length; index += 2){ 63 seed += (data[index] << 8) + data[index + 1]; 113 64 } 114 65 115 66 // last odd byte with zero padding 116 if( index + 1 == length){117 seed += data[ index] << 8;67 if(index + 1 == length){ 68 seed += data[index] << 8; 118 69 } 119 70 … … 121 72 } 122 73 123 uint16_t compact_checksum( uint32_t sum ){ 124 // shorten to the 16 bits 125 while( sum >> 16 ) sum = ( sum & 0xFFFF ) + ( sum >> 16 ); 74 uint32_t compute_crc32_be(uint32_t seed, uint8_t * data, size_t length){ 75 size_t index; 126 76 127 return ( uint16_t ) sum; 77 // process full bytes 78 while(length >= 8){ 79 // add the data 80 seed ^= (*data) << 24; 81 // for each added bit 82 for(index = 0; index < 8; ++ index){ 83 // if the first bit is set 84 if(seed &0x80000000){ 85 // shift and divide the checksum 86 seed = (seed << 1) ^ ((uint32_t) CRC_DIVIDER_BE); 87 }else{ 88 // shift otherwise 89 seed <<= 1; 90 } 91 } 92 // move to the next byte 93 ++ data; 94 length -= 8; 95 } 96 97 // process the odd bits 98 if(length > 0){ 99 // add the data with zero padding 100 seed ^= ((*data) &(0xFF << (8 - length))) << 24; 101 // for each added bit 102 for(index = 0; index < length; ++ index){ 103 // if the first bit is set 104 if(seed &0x80000000){ 105 // shift and divide the checksum 106 seed = (seed << 1) ^ ((uint32_t) CRC_DIVIDER_BE); 107 }else{ 108 // shift otherwise 109 seed <<= 1; 110 } 111 } 112 } 113 114 return seed; 128 115 } 129 116 130 uint16_t flip_checksum( uint16_t checksum ){ 117 uint32_t compute_crc32_le(uint32_t seed, uint8_t * data, size_t length){ 118 size_t index; 119 120 // process full bytes 121 while(length >= 8){ 122 // add the data 123 seed ^= (*data); 124 // for each added bit 125 for(index = 0; index < 8; ++ index){ 126 // if the last bit is set 127 if(seed &1){ 128 // shift and divide the checksum 129 seed = (seed >> 1) ^ ((uint32_t) CRC_DIVIDER_LE); 130 }else{ 131 // shift otherwise 132 seed >>= 1; 133 } 134 } 135 // move to the next byte 136 ++ data; 137 length -= 8; 138 } 139 140 // process the odd bits 141 if(length > 0){ 142 // add the data with zero padding 143 seed ^= (*data) >> (8 - length); 144 for(index = 0; index < length; ++ index){ 145 // if the last bit is set 146 if(seed &1){ 147 // shift and divide the checksum 148 seed = (seed >> 1) ^ ((uint32_t) CRC_DIVIDER_LE); 149 }else{ 150 // shift otherwise 151 seed >>= 1; 152 } 153 } 154 } 155 156 return seed; 157 } 158 159 uint16_t flip_checksum(uint16_t checksum){ 131 160 // flip, zero is returned as 0xFFFF (not flipped) 132 161 checksum = ~ checksum; … … 134 163 } 135 164 136 uint16_t ip_checksum( uint8_t * data, size_t length ){ 137 return flip_checksum( compact_checksum( compute_checksum( 0, data, length ))); 165 uint16_t ip_checksum(uint8_t * data, size_t length){ 166 // compute, compact and flip the data checksum 167 return flip_checksum(compact_checksum(compute_checksum(0, data, length))); 138 168 } 139 169
Note:
See TracChangeset
for help on using the changeset viewer.