129868Sphk/* 229868Sphk * This code implements the AUTODIN II polynomial used by Ethernet, 329868Sphk * and can be used to calculate multicast address hash indices. 429868Sphk * It assumes that the low order bits will be transmitted first, 529868Sphk * and consequently the low byte should be sent first when 629868Sphk * the crc computation is finished. The crc should be complemented 729868Sphk * before transmission. 829868Sphk * The variable corresponding to the macro argument "crc" should 929868Sphk * be an unsigned long and should be preset to all ones for Ethernet 1029868Sphk * use. An error-free packet will leave 0xDEBB20E3 in the crc. 1129868Sphk * Spencer Garrett <srg@quick.com> 1229868Sphk */ 1329868Sphk 1499112Sobrien#include <sys/cdefs.h> 1599112Sobrien__FBSDID("$FreeBSD$"); 1654162Scharnier 1734447Sjb#include <sys/types.h> 1834447Sjb 19112212Srobert#include <stdio.h> 20200462Sdelphij#include <stdint.h> 21112212Srobert#include <unistd.h> 22112212Srobert 2387212Smarkm#include "extern.h" 2487212Smarkm 2529868Sphk#define CRC(crc, ch) (crc = (crc >> 8) ^ crctab[(crc ^ (ch)) & 0xff]) 2629868Sphk 2729868Sphk/* generated using the AUTODIN II polynomial 2829868Sphk * x^32 + x^26 + x^23 + x^22 + x^16 + 2929868Sphk * x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1 3029868Sphk */ 31112212Srobertstatic const uint32_t crctab[256] = { 3229868Sphk 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 3329868Sphk 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 3429868Sphk 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 3529868Sphk 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 3629868Sphk 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 3729868Sphk 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 3829868Sphk 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 3929868Sphk 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 4029868Sphk 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 4129868Sphk 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 4229868Sphk 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 4329868Sphk 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 4429868Sphk 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 4529868Sphk 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 4629868Sphk 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 4729868Sphk 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 4829868Sphk 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 4929868Sphk 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 5029868Sphk 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 5129868Sphk 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 5229868Sphk 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 5329868Sphk 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 5429868Sphk 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 5529868Sphk 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 5629868Sphk 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 5729868Sphk 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 5829868Sphk 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 5929868Sphk 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 6029868Sphk 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 6129868Sphk 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 6229868Sphk 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 6329868Sphk 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 6429868Sphk 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 6529868Sphk 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 6629868Sphk 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 6729868Sphk 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 6829868Sphk 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 6929868Sphk 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 7029868Sphk 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 7129868Sphk 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 7229868Sphk 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 7329868Sphk 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 7429868Sphk 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 7529868Sphk 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 7629868Sphk 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 7729868Sphk 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 7829868Sphk 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 7929868Sphk 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 8029868Sphk 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 8129868Sphk 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 8229868Sphk 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 8329868Sphk 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 8429868Sphk 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 8529868Sphk 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 8629868Sphk 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 8729868Sphk 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 8829868Sphk 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 8929868Sphk 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 9029868Sphk 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 9129868Sphk 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 9229868Sphk 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 9329868Sphk 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 9429868Sphk 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 9529868Sphk 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, 9629868Sphk}; 9729868Sphk 98112212Srobertuint32_t crc32_total = 0; 9929868Sphk 10032069Salexint 101112212Srobertcrc32(int fd, uint32_t *cval, off_t *clen) 10229868Sphk{ 103112212Srobert uint32_t lcrc = ~0; 104112212Srobert int nr ; 105112212Srobert off_t len ; 10629868Sphk char buf[BUFSIZ], *p ; 10729868Sphk 10829868Sphk len = 0 ; 10929868Sphk crc32_total = ~crc32_total ; 11039363Sdes while ((nr = read(fd, buf, sizeof(buf))) > 0) 11129868Sphk for (len += nr, p = buf; nr--; ++p) { 11287212Smarkm CRC(lcrc, *p) ; 11329868Sphk CRC(crc32_total, *p) ; 11429868Sphk } 11529868Sphk if (nr < 0) 11629868Sphk return 1 ; 11729868Sphk 11829868Sphk *clen = len ; 11987212Smarkm *cval = ~lcrc ; 12029868Sphk crc32_total = ~crc32_total ; 12129868Sphk return 0 ; 12229868Sphk} 123