]> gitweb.fperrin.net Git - iftop.git/blob - addr_hash.c
Import iftop-1.0pre4
[iftop.git] / addr_hash.c
1 /* hash table */
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include "addr_hash.h"
7 #include "hash.h"
8 #include "iftop.h"
9
10 #define hash_table_size 256
11
12 int compare(void* a, void* b) {
13     addr_pair* aa = (addr_pair*)a;
14     addr_pair* bb = (addr_pair*)b;
15
16     if (aa->af != bb->af)
17         return 0;
18
19     if (aa->af == AF_INET6) {
20        return (IN6_ARE_ADDR_EQUAL(&aa->src6, &bb->src6)
21                && aa->src_port == bb->src_port
22                && IN6_ARE_ADDR_EQUAL(&aa->dst6, &bb->dst6)
23                && aa->dst_port == bb->dst_port
24                && aa->protocol == bb->protocol);
25     }
26
27     /* AF_INET or unknown. */
28     return (aa->src.s_addr == bb->src.s_addr 
29             && aa->src_port == bb->src_port
30             && aa->dst.s_addr == bb->dst.s_addr
31             && aa->dst_port == bb->dst_port
32             && aa->protocol == bb->protocol);
33 }
34
35 static int __inline__ hash_uint32(uint32_t n) {
36     return ((n & 0x000000FF)
37             + ((n & 0x0000FF00) >> 8)
38             + ((n & 0x00FF0000) >> 16)
39             + ((n & 0xFF000000) >> 24));
40 }
41
42 int hash(void* key) {
43     int hash;
44     addr_pair* ap = (addr_pair*)key;
45
46     if (ap->af == AF_INET6) {
47         uint32_t* addr6 = (uint32_t*)ap->src6.s6_addr;
48
49         hash = ( hash_uint32(addr6[0])
50                 + hash_uint32(addr6[1])
51                 + hash_uint32(addr6[2])
52                 + hash_uint32(addr6[3])
53                 + ap->src_port) % 0xFF;
54
55         addr6 = (uint32_t*)ap->dst6.s6_addr;
56         hash = ( hash + hash_uint32(addr6[0])
57                 + hash_uint32(addr6[1])
58                 + hash_uint32(addr6[2])
59                 + hash_uint32(addr6[3])
60                 + ap->dst_port) % 0xFF;
61     } else {
62         in_addr_t addr = ap->src.s_addr;
63
64         hash = ( hash_uint32(addr)
65                 + ap->src_port) % 0xFF;
66
67         addr = ap->dst.s_addr;
68         hash = ( hash + hash_uint32(addr)
69                 + ap->dst_port) % 0xFF;
70     }
71
72     return hash;
73 }
74
75 void* copy_key(void* orig) {
76     addr_pair* copy;
77     copy = xmalloc(sizeof *copy);
78     *copy = *(addr_pair*)orig;
79     return copy;
80 }
81
82 void delete_key(void* key) {
83     free(key);
84 }
85
86 /*
87  * Allocate and return a hash
88  */
89 hash_type* addr_hash_create() {
90     hash_type* hash_table;
91     hash_table = xcalloc(hash_table_size, sizeof *hash_table);
92     hash_table->size = hash_table_size;
93     hash_table->compare = &compare;
94     hash_table->hash = &hash;
95     hash_table->delete_key = &delete_key;
96     hash_table->copy_key = &copy_key;
97     hash_initialise(hash_table);
98     return hash_table;
99 }
100