2 * netsniff-ng - the packet sniffing beast
3 * By Daniel Borkmann <daniel@netsniff-ng.org>
4 * Copyright 2011 Daniel Borkmann.
5 * Subject to the GPL, version 2.
10 #include <netinet/in.h>
11 #include <asm/byteorder.h>
18 #if defined(__LITTLE_ENDIAN_BITFIELD)
19 __extension__
uint8_t h_ihl
:4,
21 #elif defined (__BIG_ENDIAN_BITFIELD)
22 __extension__
uint8_t h_version
:4,
25 # error "Please fix <asm/byteorder.h>"
36 } __attribute__((packed
));
39 #if defined(__LITTLE_ENDIAN_BITFIELD)
40 __extension__
uint8_t priority
:4,
42 #elif defined(__BIG_ENDIAN_BITFIELD)
43 __extension__
uint8_t version
:4,
46 # error "Please fix <asm/byteorder.h>"
52 struct in6_addr saddr
;
53 struct in6_addr daddr
;
54 } __attribute__((packed
));
56 static struct patricia_node
*tree
= NULL
;
58 static struct rwlock tree_lock
;
60 void trie_addr_lookup(char *buff
, size_t len
, int ipv4
, int *fd
,
61 struct sockaddr_storage
*addr
, size_t *alen
)
65 struct ipv4hdr
*hdr4
= (void *) buff
;
66 struct ipv6hdr
*hdr6
= (void *) buff
;
68 data
= ipv4
? (void *) &hdr4
->h_daddr
: (void *) &hdr6
->daddr
;
69 dlen
= ipv4
? sizeof(hdr4
->h_daddr
) : sizeof(hdr6
->daddr
);
71 if (unlikely((ipv4
&& ((struct ipv4hdr
*) buff
)->h_version
!= 4) ||
72 (!ipv4
&& ((struct ipv6hdr
*) buff
)->version
!= 6))) {
73 memset(addr
, 0, sizeof(*addr
));
79 /* Always happens on the dst address */
80 rwlock_rd_lock(&tree_lock
);
81 (*fd
) = ptree_search_data_exact(data
, dlen
, addr
, alen
, tree
);
82 rwlock_unlock(&tree_lock
);
85 int trie_addr_maybe_update(char *buff
, size_t len
, int ipv4
, int fd
,
86 struct sockaddr_storage
*addr
, size_t alen
)
91 struct ipv4hdr
*hdr4
= (void *) buff
;
92 struct ipv6hdr
*hdr6
= (void *) buff
;
94 data
= ipv4
? (void *) &hdr4
->h_saddr
: (void *) &hdr6
->saddr
;
95 dlen
= ipv4
? sizeof(hdr4
->h_saddr
) : sizeof(hdr6
->saddr
);
97 if (unlikely((ipv4
&& ((struct ipv4hdr
*) buff
)->h_version
!= 4) ||
98 (!ipv4
&& ((struct ipv6hdr
*) buff
)->version
!= 6)))
101 /* Always happens on the src address */
102 rwlock_wr_lock(&tree_lock
);
103 ret
= ptree_maybe_add_entry(data
, dlen
, fd
, addr
, alen
, &tree
);
104 rwlock_unlock(&tree_lock
);
109 void trie_addr_remove(int fd
)
112 struct patricia_node
*n
= NULL
;
114 rwlock_wr_lock(&tree_lock
);
117 ptree_get_key(fd
, tree
, &n
);
119 ptree_del_entry(n
->key
, n
->klen
, &tree
);
125 rwlock_unlock(&tree_lock
);
128 void trie_addr_remove_addr(struct sockaddr_storage
*addr
, size_t alen
)
131 struct patricia_node
*n
= NULL
;
133 rwlock_wr_lock(&tree_lock
);
136 ptree_get_key_addr(addr
, alen
, tree
, &n
);
138 ptree_del_entry(n
->key
, n
->klen
, &tree
);
144 rwlock_unlock(&tree_lock
);
149 rwlock_init(&tree_lock
);
152 void trie_cleanup(void)
154 rwlock_wr_lock(&tree_lock
);
156 rwlock_unlock(&tree_lock
);
158 rwlock_destroy(&tree_lock
);