#include #include #include #include #include #include #include #define RSS_KEYSIZE 40 static uint8_t rss_key[RSS_KEYSIZE] = { 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, }; static uint32_t toeplitz_hash(unsigned int keylen, const uint8_t *key, unsigned int datalen, const uint8_t *data) { uint32_t hash = 0, v; unsigned int i, b; /* XXXRW: Perhaps an assertion about key length vs. data length? */ v = (key[0] << 24) + (key[1] << 16) + (key[2] << 8) + key[3]; for (i = 0; i < datalen; i++) { for (b = 0; b < 8; b++) { if (data[i] & (1 << (7 - b))) hash ^= v; v <<= 1; if ((i + 4) < RSS_KEYSIZE && (key[i + 4] & (1 << (7 - b)))) v |= 1; } } return (hash); } static uint32_t rss_hash(unsigned int datalen, const uint8_t *data) { return (toeplitz_hash(sizeof(rss_key), rss_key, datalen, data)); } static uint32_t rss_hash_ip4_4tuple(in_addr_t src, uint16_t srcport, in_addr_t dst, uint16_t dstport) { uint8_t data[sizeof(src) + sizeof(dst) + sizeof(srcport) + sizeof(dstport)]; unsigned int datalen; datalen = 0; bcopy(&src, &data[datalen], sizeof(src)); datalen += sizeof(src); bcopy(&dst, &data[datalen], sizeof(dst)); datalen += sizeof(dst); bcopy(&srcport, &data[datalen], sizeof(srcport)); datalen += sizeof(srcport); bcopy(&dstport, &data[datalen], sizeof(dstport)); datalen += sizeof(dstport); return (rss_hash(datalen, data)); } int main(int argc, char *argv[]) { in_addr_t src, dst; uint16_t srcport, dstport; int val; char *p; if (argc != 3) exit(1); printf("[%s] [%s]\n", argv[1], argv[2]); p = strchr(argv[1], ':'); assert(p != NULL); *p = '\0'; src = inet_addr(argv[1]); val = atoi(p + 1); assert(val >= 0 && val <= 65535); srcport = (uint16_t)val; p = strchr(argv[2], ':'); assert(p != NULL); *p = '\0'; dst = inet_addr(argv[2]); val = atoi(p + 1); assert(val >= 0 && val <= 65535); dstport = (uint16_t)val; printf("%u\n", rss_hash_ip4_4tuple(src, srcport, dst, dstport) & 0x3); printf("%u\n", rss_hash_ip4_4tuple(ntohl(src), ntohs(srcport), ntohl(dst), ntohs(dstport)) & 0x3); return (0); }