2 #include <sys/socket.h>
5 #include <netinet/in.h>
18 static uint8_t toeplitz_key[KEYLEN];
19 static uint32_t hash_table[HASHLEN][256];
21 static void toeplitz_init(uint32_t[][256], int, const uint8_t[], int);
22 static void getaddrport(char *, uint32_t *, uint16_t *);
25 usage(const char *cmd)
27 fprintf(stderr, "%s [-s s1_hex [-s s2_hex]] [-p] [-m mask] [-d div] "
28 "addr1.port1 addr2.port2\n", cmd);
33 main(int argc, char *argv[])
35 uint32_t saddr, daddr;
36 uint16_t sport, dport;
37 uint32_t res, mask, divisor;
39 const char *cmd = argv[0];
40 uint8_t seeds[2] = { 0x6d, 0x5a };
48 while ((opt = getopt(argc, argv, "d:m:ps:")) != -1) {
51 divisor = strtoul(optarg, NULL, 10);
55 mask = strtoul(optarg, NULL, 16);
65 seeds[i++] = strtoul(optarg, NULL, 16);
78 for (i = 0; i < KEYLEN; ++i) {
80 toeplitz_key[i] = seeds[1];
82 toeplitz_key[i] = seeds[0];
85 getaddrport(argv[0], &saddr, &sport);
86 getaddrport(argv[1], &daddr, &dport);
88 toeplitz_init(hash_table, HASHLEN, toeplitz_key, KEYLEN);
90 res = hash_table[0][(saddr >> 0) & 0xff];
91 res ^= hash_table[1][(saddr >> 8) & 0xff];
92 res ^= hash_table[2][(saddr >> 16) & 0xff];
93 res ^= hash_table[3][(saddr >> 24) & 0xff];
94 res ^= hash_table[4][(daddr >> 0) & 0xff];
95 res ^= hash_table[5][(daddr >> 8) & 0xff];
96 res ^= hash_table[6][(daddr >> 16) & 0xff];
97 res ^= hash_table[7][(daddr >> 24) & 0xff];
99 res ^= hash_table[8][(sport >> 0) & 0xff];
100 res ^= hash_table[9][(sport >> 8) & 0xff];
101 res ^= hash_table[10][(dport >> 0) & 0xff];
102 res ^= hash_table[11][(dport >> 8) & 0xff];
105 printf("0x%08x, masked 0x%08x", res, res & mask);
109 printf(", modulo %u\n", (res & HASHMASK) % divisor);
114 toeplitz_init(uint32_t cache[][256], int cache_len,
115 const uint8_t key_str[], int key_strlen)
119 if (key_strlen < cache_len + (int)sizeof(uint32_t))
122 for (i = 0; i < cache_len; ++i) {
124 int j, b, shift, val;
126 bzero(key, sizeof(key));
129 * Calculate 32bit keys for one byte; one key for each bit.
131 for (b = 0; b < NBBY; ++b) {
132 for (j = 0; j < 32; ++j) {
136 bit = (i * NBBY) + b + j;
138 k = key_str[bit / NBBY];
139 shift = NBBY - (bit % NBBY) - 1;
140 if (k & (1 << shift))
141 key[b] |= 1 << (31 - j);
146 * Cache the results of all possible bit combination of
149 for (val = 0; val < 256; ++val) {
152 for (b = 0; b < NBBY; ++b) {
153 shift = NBBY - b - 1;
154 if (val & (1 << shift))
163 getaddrport(char *ap_str, uint32_t *addr, uint16_t *port0)
168 p = strrchr(ap_str, '.');
170 fprintf(stderr, "invalid addr.port %s\n", ap_str);
177 port = strtoul(p, NULL, 10);
178 *port0 = htons(port);
180 if (inet_pton(AF_INET, ap_str, addr) <= 0) {
181 fprintf(stderr, "invalid addr %s\n", ap_str);