Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/checksum.c

    raadf01e ra64c64d  
    4747#define CRC_DIVIDER_LE  0xEDB88320
    4848
    49 uint32_t compute_crc32_le(uint32_t seed, uint8_t * data, size_t length){
    50         size_t index;
     49uint16_t compact_checksum(uint32_t sum){
     50        // shorten to the 16 bits
     51        while(sum >> 16){
     52                sum = (sum &0xFFFF) + (sum >> 16);
     53        }
    5154
    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;
    76 }
    77 
    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;
     55        return (uint16_t) sum;
    10556}
    10657
     
    12172}
    12273
    123 uint16_t compact_checksum(uint32_t sum){
    124         // shorten to the 16 bits
    125         while(sum >> 16){
    126                 sum = (sum &0xFFFF) + (sum >> 16);
     74uint32_t compute_crc32_be(uint32_t seed, uint8_t * data, size_t length){
     75        size_t index;
     76
     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;
    12795        }
    12896
    129         return (uint16_t) sum;
     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;
     115}
     116
     117uint32_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;
    130157}
    131158
     
    137164
    138165uint16_t ip_checksum(uint8_t * data, size_t length){
     166        // compute, compact and flip the data checksum
    139167        return flip_checksum(compact_checksum(compute_checksum(0, data, length)));
    140168}
Note: See TracChangeset for help on using the changeset viewer.