Ignore:
Timestamp:
2010-11-02T22:38:46Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
af894a21
Parents:
aab02fb (diff), e06ef614 (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.
Message:

Merge mainline changes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/net/generic/net_checksum.c

    raab02fb refedee77  
    2727 */
    2828
    29 /** @addtogroup net
    30  *  @{
     29/** @addtogroup libnet
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  General CRC and checksum computation implementation.
     34 * General CRC and checksum computation implementation.
    3535 */
    3636
     
    3939#include <net_checksum.h>
    4040
    41 /** Big-endian encoding CRC divider.
    42  */
    43 #define CRC_DIVIDER_BE  0x04C11DB7
    44 
    45 /** Little-endian encoding CRC divider.
    46  */
    47 #define CRC_DIVIDER_LE  0xEDB88320
    48 
    49 uint16_t compact_checksum(uint32_t sum){
     41/** Big-endian encoding CRC divider. */
     42#define CRC_DIVIDER_BE  0x04c11db7
     43
     44/** Little-endian encoding CRC divider. */
     45#define CRC_DIVIDER_LE  0xedb88320
     46
     47/** Compacts the computed checksum to the 16 bit number adding the carries.
     48 *
     49 * @param[in] sum       Computed checksum.
     50 * @returns             Compacted computed checksum to the 16 bits.
     51 */
     52uint16_t compact_checksum(uint32_t sum)
     53{
    5054        // shorten to the 16 bits
    51         while(sum >> 16){
    52                 sum = (sum &0xFFFF) + (sum >> 16);
    53         }
     55        while (sum >> 16)
     56                sum = (sum & 0xffff) + (sum >> 16);
    5457
    5558        return (uint16_t) sum;
    5659}
    5760
    58 uint32_t compute_checksum(uint32_t seed, uint8_t * data, size_t length){
     61/** Computes sum of the 2 byte fields.
     62 *
     63 * Padds one zero (0) byte if odd.
     64 *
     65 * @param[in] seed      Initial value. Often used as 0 or ~0.
     66 * @param[in] data      Pointer to the beginning of data to process.
     67 * @param[in] length    Length of the data in bytes.
     68 * @returns             The computed checksum of the length bytes of the data.
     69 */
     70uint32_t compute_checksum(uint32_t seed, uint8_t *data, size_t length)
     71{
    5972        size_t index;
    6073
    6174        // sum all the 16 bit fields
    62         for(index = 0; index + 1 < length; index += 2){
     75        for (index = 0; index + 1 < length; index += 2)
    6376                seed += (data[index] << 8) + data[index + 1];
    64         }
    6577
    6678        // last odd byte with zero padding
    67         if(index + 1 == length){
     79        if (index + 1 == length)
    6880                seed += data[index] << 8;
    69         }
    7081
    7182        return seed;
    7283}
    7384
    74 uint32_t compute_crc32_be(uint32_t seed, uint8_t * data, size_t length){
     85/** Computes CRC32 value in the big-endian environment.
     86 *
     87 * @param[in] seed      Initial value. Often used as 0 or ~0.
     88 * @param[in] data      Pointer to the beginning of data to process.
     89 * @param[in] length    Length of the data in bits.
     90 * @returns             The computed CRC32 of the length bits of the data.
     91 */
     92uint32_t compute_crc32_be(uint32_t seed, uint8_t * data, size_t length)
     93{
    7594        size_t index;
    7695
    7796        // process full bytes
    78         while(length >= 8){
     97        while (length >= 8) {
    7998                // add the data
    8099                seed ^= (*data) << 24;
     100               
    81101                // for each added bit
    82                 for(index = 0; index < 8; ++ index){
     102                for (index = 0; index < 8; ++index) {
    83103                        // if the first bit is set
    84                         if(seed &0x80000000){
     104                        if (seed & 0x80000000) {
    85105                                // shift and divide the checksum
    86106                                seed = (seed << 1) ^ ((uint32_t) CRC_DIVIDER_BE);
    87                         }else{
     107                        } else {
    88108                                // shift otherwise
    89109                                seed <<= 1;
    90110                        }
    91111                }
     112               
    92113                // move to the next byte
    93                 ++ data;
     114                ++data;
    94115                length -= 8;
    95116        }
    96117
    97118        // process the odd bits
    98         if(length > 0){
     119        if (length > 0) {
    99120                // add the data with zero padding
    100                 seed ^= ((*data) &(0xFF << (8 - length))) << 24;
     121                seed ^= ((*data) & (0xff << (8 - length))) << 24;
     122               
    101123                // for each added bit
    102                 for(index = 0; index < length; ++ index){
     124                for (index = 0; index < length; ++index) {
    103125                        // if the first bit is set
    104                         if(seed &0x80000000){
     126                        if (seed & 0x80000000) {
    105127                                // shift and divide the checksum
    106128                                seed = (seed << 1) ^ ((uint32_t) CRC_DIVIDER_BE);
    107                         }else{
     129                        } else {
    108130                                // shift otherwise
    109131                                seed <<= 1;
     
    115137}
    116138
    117 uint32_t compute_crc32_le(uint32_t seed, uint8_t * data, size_t length){
     139/** Computes CRC32 value in the little-endian environment.
     140 *
     141 * @param[in] seed      Initial value. Often used as 0 or ~0.
     142 * @param[in] data      Pointer to the beginning of data to process.
     143 * @param[in] length    Length of the data in bits.
     144 * @returns             The computed CRC32 of the length bits of the data.
     145 */
     146uint32_t compute_crc32_le(uint32_t seed, uint8_t * data, size_t length)
     147{
    118148        size_t index;
    119149
    120150        // process full bytes
    121         while(length >= 8){
     151        while (length >= 8) {
    122152                // add the data
    123153                seed ^= (*data);
     154               
    124155                // for each added bit
    125                 for(index = 0; index < 8; ++ index){
     156                for (index = 0; index < 8; ++index) {
    126157                        // if the last bit is set
    127                         if(seed &1){
     158                        if (seed & 1) {
    128159                                // shift and divide the checksum
    129160                                seed = (seed >> 1) ^ ((uint32_t) CRC_DIVIDER_LE);
    130                         }else{
     161                        } else {
    131162                                // shift otherwise
    132163                                seed >>= 1;
    133164                        }
    134165                }
     166               
    135167                // move to the next byte
    136                 ++ data;
     168                ++data;
    137169                length -= 8;
    138170        }
    139171
    140172        // process the odd bits
    141         if(length > 0){
     173        if (length > 0) {
    142174                // add the data with zero padding
    143175                seed ^= (*data) >> (8 - length);
    144                 for(index = 0; index < length; ++ index){
     176               
     177                for (index = 0; index < length; ++index) {
    145178                        // if the last bit is set
    146                         if(seed &1){
     179                        if (seed & 1) {
    147180                                // shift and divide the checksum
    148181                                seed = (seed >> 1) ^ ((uint32_t) CRC_DIVIDER_LE);
    149                         }else{
     182                        } else {
    150183                                // shift otherwise
    151184                                seed >>= 1;
     
    157190}
    158191
    159 uint16_t flip_checksum(uint16_t checksum){
     192/** Returns or flips the checksum if zero.
     193 *
     194 * @param[in] checksum  The computed checksum.
     195 * @returns             The internet protocol header checksum.
     196 * @returns             0xFFFF if the computed checksum is zero.
     197 */
     198uint16_t flip_checksum(uint16_t checksum)
     199{
    160200        // flip, zero is returned as 0xFFFF (not flipped)
    161         checksum = ~ checksum;
     201        checksum = ~checksum;
    162202        return checksum ? checksum : IP_CHECKSUM_ZERO;
    163203}
    164204
    165 uint16_t ip_checksum(uint8_t * data, size_t length){
     205/** Computes the ip header checksum.
     206 *
     207 * To compute the checksum of a new packet, the checksum header field must be
     208 * zero. To check the checksum of a received packet, the checksum may be left
     209 * set. Zero will be returned in this case if valid.
     210 *
     211 * @param[in] data      The header data.
     212 * @param[in] length    The header length in bytes.
     213 * @returns             The internet protocol header checksum.
     214 * @returns             0xFFFF if the computed checksum is zero.
     215 */
     216uint16_t ip_checksum(uint8_t *data, size_t length)
     217{
    166218        // compute, compact and flip the data checksum
    167         return flip_checksum(compact_checksum(compute_checksum(0, data, length)));
     219        return flip_checksum(compact_checksum(compute_checksum(0, data,
     220            length)));
    168221}
    169222
Note: See TracChangeset for help on using the changeset viewer.