diff options
author | Christian Weisgerber <naddy@cvs.openbsd.org> | 2004-06-26 06:01:15 +0000 |
---|---|---|
committer | Christian Weisgerber <naddy@cvs.openbsd.org> | 2004-06-26 06:01:15 +0000 |
commit | 765bffe505b88993ee28536233b1f65b871c7458 (patch) | |
tree | 3f7e4474c82e026ab9ca8ae518193e8c5eff3ad6 /sys | |
parent | 62350eff27061c491174f2640abe01f312d6b059 (diff) |
Add a table-driven implementation of ether_crc32_be().
From Seishi Hiragushi via FreeBSD PR kern/49957.
Also, while we're here, make the loop counter size_t.
ok mcbride@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/if_ethersubr.c | 60 |
1 files changed, 43 insertions, 17 deletions
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index 8e9e32c3e6d..e65362995e8 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ethersubr.c,v 1.77 2004/06/21 23:50:36 tholo Exp $ */ +/* $OpenBSD: if_ethersubr.c,v 1.78 2004/06/26 06:01:14 naddy Exp $ */ /* $NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $ */ /* @@ -1002,9 +1002,8 @@ ether_ifdetach(ifp) #if 0 /* - * This is for reference. We have a table-driven version - * of the little-endian crc32 generator, which is faster - * than the double-loop. + * This is for reference. We have table-driven versions of the + * crc32 generators, which are faster than the double-loop. */ u_int32_t ether_crc32_le(const u_int8_t *buf, size_t len) @@ -1027,6 +1026,28 @@ ether_crc32_le(const u_int8_t *buf, size_t len) return (crc); } + +u_int32_t +ether_crc32_be(const u_int8_t *buf, size_t len) +{ + u_int32_t c, crc, carry; + size_t i, j; + + crc = 0xffffffffU; /* initial value */ + + for (i = 0; i < len; i++) { + c = buf[i]; + for (j = 0; j < 8; j++) { + carry = ((crc & 0x80000000U) ? 1 : 0) ^ (c & 0x01); + crc <<= 1; + c >>= 1; + if (carry) + crc = (crc ^ ETHER_CRC_POLY_BE) | carry; + } + } + + return (crc); +} #else u_int32_t ether_crc32_le(const u_int8_t *buf, size_t len) @@ -1037,8 +1058,8 @@ ether_crc32_le(const u_int8_t *buf, size_t len) 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c }; + size_t i; u_int32_t crc; - int i; crc = 0xffffffffU; /* initial value */ @@ -1050,29 +1071,34 @@ ether_crc32_le(const u_int8_t *buf, size_t len) return (crc); } -#endif u_int32_t ether_crc32_be(const u_int8_t *buf, size_t len) { - u_int32_t c, crc, carry; - size_t i, j; + static const u_int8_t rev[] = { + 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe, + 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf + }; + static const u_int32_t crctab[] = { + 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, + 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, + 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, + 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd + }; + size_t i; + u_int32_t crc; + u_int8_t data; crc = 0xffffffffU; /* initial value */ - for (i = 0; i < len; i++) { - c = buf[i]; - for (j = 0; j < 8; j++) { - carry = ((crc & 0x80000000U) ? 1 : 0) ^ (c & 0x01); - crc <<= 1; - c >>= 1; - if (carry) - crc = (crc ^ ETHER_CRC_POLY_BE) | carry; - } + data = buf[i]; + crc = (crc << 4) ^ crctab[(crc >> 28) ^ rev[data & 0xf]]; + crc = (crc << 4) ^ crctab[(crc >> 28) ^ rev[data >> 4]]; } return (crc); } +#endif #ifdef INET u_char ether_ipmulticast_min[ETHER_ADDR_LEN] = |