crc32.c revision 34447
155714Skris/*
255714Skris * This code implements the AUTODIN II polynomial used by Ethernet,
355714Skris * and can be used to calculate multicast address hash indices.
455714Skris * It assumes that the low order bits will be transmitted first,
555714Skris * and consequently the low byte should be sent first when
655714Skris * the crc computation is finished.  The crc should be complemented
755714Skris * before transmission.
8280297Sjkim * The variable corresponding to the macro argument "crc" should
955714Skris * be an unsigned long and should be preset to all ones for Ethernet
1055714Skris * use.  An error-free packet will leave 0xDEBB20E3 in the crc.
1155714Skris *			Spencer Garrett <srg@quick.com>
1255714Skris */
1355714Skris
1455714Skris#include <sys/types.h>
15280297Sjkim
1655714Skris#define CRC(crc, ch)	 (crc = (crc >> 8) ^ crctab[(crc ^ (ch)) & 0xff])
1755714Skris
1855714Skris/* generated using the AUTODIN II polynomial
1955714Skris *	x^32 + x^26 + x^23 + x^22 + x^16 +
2055714Skris *	x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1
2155714Skris */
22280297Sjkimstatic const u_int32_t crctab[256] = {
2355714Skris	0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
2455714Skris	0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
2555714Skris	0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
2655714Skris	0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
2755714Skris	0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
2855714Skris	0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
2955714Skris	0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
3055714Skris	0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
3155714Skris	0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
3255714Skris	0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
3355714Skris	0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
3455714Skris	0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
3555714Skris	0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
3655714Skris	0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
37280297Sjkim	0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
3855714Skris	0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
3955714Skris	0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
40280297Sjkim	0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
4155714Skris	0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
4255714Skris	0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
4355714Skris	0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
4455714Skris	0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
4555714Skris	0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
4655714Skris	0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
4755714Skris	0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
4855714Skris	0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
4955714Skris	0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
5055714Skris	0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
5155714Skris	0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
52280297Sjkim	0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
5355714Skris	0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
5455714Skris	0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
5555714Skris	0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
5655714Skris	0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
5755714Skris	0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
5855714Skris	0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
5955714Skris	0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
6055714Skris	0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
6155714Skris	0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
6255714Skris	0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
63109998Smarkm	0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
64109998Smarkm	0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
65109998Smarkm	0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
6655714Skris	0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
6755714Skris	0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
6855714Skris	0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
69280297Sjkim	0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
7055714Skris	0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
7155714Skris	0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
72280297Sjkim	0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
73280297Sjkim	0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
74280297Sjkim	0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
75280297Sjkim	0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
7655714Skris	0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
77280297Sjkim	0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
78280297Sjkim	0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
79280297Sjkim	0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
8055714Skris	0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
81280297Sjkim	0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
82280297Sjkim	0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
83280297Sjkim	0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
84280297Sjkim	0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
85280297Sjkim	0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
86280297Sjkim	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
87280297Sjkim};
88280297Sjkim
89280297Sjkim#include <stdio.h>
90280297Sjkim#include <sys/types.h>
91280297Sjkim#include <unistd.h>
92280297Sjkim
93280297Sjkimu_int32_t crc32_total = 0 ;
94280297Sjkim
95280297Sjkimint
96280297Sjkimcrc32(fd, cval, clen)
97280297Sjkim    register int fd;
98280297Sjkim    u_int32_t *cval, *clen;
99280297Sjkim{
100280297Sjkim    u_int32_t crc = ~0;
101280297Sjkim    char buf[BUFSIZ], *p ;
102280297Sjkim    int len, nr ;
103280297Sjkim
104280297Sjkim    len = 0 ;
105280297Sjkim    crc32_total = ~crc32_total ;
106280297Sjkim    while ((nr = read(fd, buf, sizeof(buf))))
107280297Sjkim        for (len += nr, p = buf; nr--; ++p) {
108280297Sjkim	    CRC(crc, *p) ;
109280297Sjkim	    CRC(crc32_total, *p) ;
110280297Sjkim	}
111280297Sjkim    if (nr < 0)
112280297Sjkim        return 1 ;
113280297Sjkim
114280297Sjkim    *clen = len ;
115280297Sjkim    *cval = ~crc ;
116280297Sjkim    crc32_total = ~crc32_total ;
117280297Sjkim    return 0 ;
11855714Skris}
11955714Skris