Ignore:
Timestamp:
2011-04-13T14:45:41Z (14 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
88634420
Parents:
cefb126 (diff), 17279ead (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

    rcefb126 r89c57b6  
    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){
    50         // shorten to the 16 bits
    51         while(sum >> 16){
    52                 sum = (sum &0xFFFF) + (sum >> 16);
    53         }
     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 * @return              Compacted computed checksum to the 16 bits.
     51 */
     52uint16_t compact_checksum(uint32_t sum)
     53{
     54        /* Shorten to the 16 bits */
     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 * @return              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
    61         // sum all the 16 bit fields
    62         for(index = 0; index + 1 < length; index += 2){
     74        /* Sum all the 16 bit fields */
     75        for (index = 0; index + 1 < length; index += 2)
    6376                seed += (data[index] << 8) + data[index + 1];
    64         }
    65 
    66         // last odd byte with zero padding
    67         if(index + 1 == length){
     77
     78        /* Last odd byte with zero padding */
     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 * @return              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
    77         // process full bytes
    78         while(length >= 8){
    79                 // add the data
     96        /* Process full bytes */
     97        while (length >= 8) {
     98                /* Add the data */
    8099                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
     100               
     101                /* For each added bit */
     102                for (index = 0; index < 8; ++index) {
     103                        /* If the first bit is set */
     104                        if (seed & 0x80000000) {
     105                                /* Shift and divide the checksum */
    86106                                seed = (seed << 1) ^ ((uint32_t) CRC_DIVIDER_BE);
    87                         }else{
    88                                 // shift otherwise
     107                        } else {
     108                                /* Shift otherwise */
    89109                                seed <<= 1;
    90110                        }
    91111                }
    92                 // move to the next byte
    93                 ++ data;
     112               
     113                /* Move to the next byte */
     114                ++data;
    94115                length -= 8;
    95116        }
    96117
    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
     118        /* Process the odd bits */
     119        if (length > 0) {
     120                /* Add the data with zero padding */
     121                seed ^= ((*data) & (0xff << (8 - length))) << 24;
     122               
     123                /* For each added bit */
     124                for (index = 0; index < length; ++index) {
     125                        /* If the first bit is set */
     126                        if (seed & 0x80000000) {
     127                                /* Shift and divide the checksum */
    106128                                seed = (seed << 1) ^ ((uint32_t) CRC_DIVIDER_BE);
    107                         }else{
    108                                 // shift otherwise
     129                        } else {
     130                                /* Shift otherwise */
    109131                                seed <<= 1;
    110132                        }
     
    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 * @return              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
    120         // process full bytes
    121         while(length >= 8){
    122                 // add the data
     150        /* Process full bytes */
     151        while (length >= 8) {
     152                /* Add the data */
    123153                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
     154               
     155                /* For each added bit */
     156                for (index = 0; index < 8; ++index) {
     157                        /* If the last bit is set */
     158                        if (seed & 1) {
     159                                /* Shift and divide the checksum */
    129160                                seed = (seed >> 1) ^ ((uint32_t) CRC_DIVIDER_LE);
    130                         }else{
    131                                 // shift otherwise
     161                        } else {
     162                                /* Shift otherwise */
    132163                                seed >>= 1;
    133164                        }
    134165                }
    135                 // move to the next byte
    136                 ++ data;
     166               
     167                /* Move to the next byte */
     168                ++data;
    137169                length -= 8;
    138170        }
    139171
    140         // process the odd bits
    141         if(length > 0){
    142                 // add the data with zero padding
     172        /* Process the odd bits */
     173        if (length > 0) {
     174                /* Add the data with zero padding */
    143175                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
     176               
     177                for (index = 0; index < length; ++index) {
     178                        /* If the last bit is set */
     179                        if (seed & 1) {
     180                                /* Shift and divide the checksum */
    148181                                seed = (seed >> 1) ^ ((uint32_t) CRC_DIVIDER_LE);
    149                         }else{
    150                                 // shift otherwise
     182                        } else {
     183                                /* Shift otherwise */
    151184                                seed >>= 1;
    152185                        }
     
    157190}
    158191
    159 uint16_t flip_checksum(uint16_t checksum){
    160         // flip, zero is returned as 0xFFFF (not flipped)
    161         checksum = ~ checksum;
     192/** Returns or flips the checksum if zero.
     193 *
     194 * @param[in] checksum  The computed checksum.
     195 * @return              The internet protocol header checksum.
     196 * @return              0xFFFF if the computed checksum is zero.
     197 */
     198uint16_t flip_checksum(uint16_t checksum)
     199{
     200        /* Flip, zero is returned as 0xFFFF (not flipped) */
     201        checksum = ~checksum;
    162202        return checksum ? checksum : IP_CHECKSUM_ZERO;
    163203}
    164204
    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)));
     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 * @return              The internet protocol header checksum.
     214 * @return              0xFFFF if the computed checksum is zero.
     215 */
     216uint16_t ip_checksum(uint8_t *data, size_t length)
     217{
     218        /* Compute, compact and flip the data checksum */
     219        return flip_checksum(compact_checksum(compute_checksum(0, data,
     220            length)));
    168221}
    169222
Note: See TracChangeset for help on using the changeset viewer.