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