2 * netsniff-ng - the packet sniffing beast
3 * By Daniel Borkmann <daniel@netsniff-ng.org>
4 * Copyright 2009, 2010 Daniel Borkmann.
5 * Subject to the GPL, version 2.
13 #include "dissector.h"
14 #include "dissector_eth.h"
18 struct hash_table eth_lay2
;
19 struct hash_table eth_lay3
;
20 struct hash_table eth_lay4
;
22 static struct hash_table eth_ether_types
;
23 static struct hash_table eth_ports_udp
;
24 static struct hash_table eth_ports_tcp
;
25 static struct hash_table eth_oui
;
30 struct vendor_id
*next
;
36 struct port_tcp
*next
;
42 struct port_udp
*next
;
48 struct ether_type
*next
;
51 /* Note: this macro only applies to the lookup_* functions here in this file,
52 * mainly to remove redundand code. */
53 #define __do_lookup_inline(id, struct_name, hash_ptr, struct_member) \
55 struct struct_name *entry = lookup_hash(id, hash_ptr); \
56 while (entry && id != entry->id) \
57 entry = entry->next; \
58 (entry && id == entry->id ? entry->struct_member : "Unknown");\
61 char *lookup_vendor(unsigned int id
)
63 return __do_lookup_inline(id
, vendor_id
, ð_oui
, vendor
);
66 char *lookup_port_udp(unsigned int id
)
68 return __do_lookup_inline(id
, port_udp
, ð_ports_udp
, port
);
71 char *lookup_port_tcp(unsigned int id
)
73 return __do_lookup_inline(id
, port_tcp
, ð_ports_tcp
, port
);
76 char *lookup_ether_type(unsigned int id
)
78 return __do_lookup_inline(id
, ether_type
, ð_ether_types
, type
);
81 static inline void dissector_init_entry(int type
)
83 dissector_set_print_type(ðernet_ops
, type
);
86 static inline void dissector_init_exit(int type
)
88 dissector_set_print_type(&hex_ops
, type
);
91 static void dissector_init_layer_2(int type
)
94 INSERT_HASH_PROTOS(arp_ops
, eth_lay2
);
95 INSERT_HASH_PROTOS(vlan_ops
, eth_lay2
);
96 INSERT_HASH_PROTOS(ipv4_ops
, eth_lay2
);
97 INSERT_HASH_PROTOS(ipv6_ops
, eth_lay2
);
98 for_each_hash_int(ð_lay2
, dissector_set_print_type
, type
);
101 static void dissector_init_layer_3(int type
)
103 init_hash(ð_lay3
);
104 INSERT_HASH_PROTOS(igmp_ops
, eth_lay3
);
105 INSERT_HASH_PROTOS(ipv6_routing_ops
, eth_lay3
);
106 INSERT_HASH_PROTOS(ipv6_no_next_header_ops
, eth_lay3
);
107 for_each_hash_int(ð_lay3
, dissector_set_print_type
, type
);
110 static void dissector_init_layer_4(int type
)
112 init_hash(ð_lay4
);
113 for_each_hash_int(ð_lay4
, dissector_set_print_type
, type
);
116 static void dissector_init_oui(void)
119 char buff
[512], *ptr
;
120 struct vendor_id
*ven
;
122 fp
= fopen("/etc/netsniff-ng/oui.conf", "r");
124 panic("No /etc/netsniff-ng/oui.conf found!\n");
125 memset(buff
, 0, sizeof(buff
));
126 while (fgets(buff
, sizeof(buff
), fp
) != NULL
) {
127 buff
[sizeof(buff
) - 1] = 0;
128 ven
= xmalloc(sizeof(*ven
));
131 ptr
= getuint(ptr
, &ven
->id
);
133 ptr
= skipchar(ptr
, ',');
135 ptr
= strtrim_right(ptr
, '\n');
136 ptr
= strtrim_right(ptr
, ' ');
137 ven
->vendor
= xstrdup(ptr
);
139 pos
= insert_hash(ven
->id
, ven
, ð_oui
);
144 memset(buff
, 0, sizeof(buff
));
149 static int dissector_cleanup_oui(void *ptr
)
151 struct vendor_id
*tmp
, *v
= ptr
;
154 while ((tmp
= v
->next
)) {
164 static void dissector_init_ports_udp(void)
167 char buff
[512], *ptr
;
168 struct port_udp
*pudp
;
170 fp
= fopen("/etc/netsniff-ng/udp.conf", "r");
172 panic("No /etc/netsniff-ng/udp.conf found!\n");
173 memset(buff
, 0, sizeof(buff
));
174 while (fgets(buff
, sizeof(buff
), fp
) != NULL
) {
175 buff
[sizeof(buff
) - 1] = 0;
176 pudp
= xmalloc(sizeof(*pudp
));
179 ptr
= getuint(ptr
, &pudp
->id
);
181 ptr
= skipchar(ptr
, ',');
183 ptr
= strtrim_right(ptr
, '\n');
184 ptr
= strtrim_right(ptr
, ' ');
185 pudp
->port
= xstrdup(ptr
);
187 pos
= insert_hash(pudp
->id
, pudp
, ð_ports_udp
);
192 memset(buff
, 0, sizeof(buff
));
197 static int dissector_cleanup_ports_udp(void *ptr
)
199 struct port_udp
*tmp
, *p
= ptr
;
202 while ((tmp
= p
->next
)) {
212 static void dissector_init_ports_tcp(void)
215 char buff
[512], *ptr
;
216 struct port_tcp
*ptcp
;
218 fp
= fopen("/etc/netsniff-ng/tcp.conf", "r");
220 panic("No /etc/netsniff-ng/tcp.conf found!\n");
221 memset(buff
, 0, sizeof(buff
));
222 while (fgets(buff
, sizeof(buff
), fp
) != NULL
) {
223 buff
[sizeof(buff
) - 1] = 0;
224 ptcp
= xmalloc(sizeof(*ptcp
));
227 ptr
= getuint(ptr
, &ptcp
->id
);
229 ptr
= skipchar(ptr
, ',');
231 ptr
= strtrim_right(ptr
, '\n');
232 ptr
= strtrim_right(ptr
, ' ');
233 ptcp
->port
= xstrdup(ptr
);
235 pos
= insert_hash(ptcp
->id
, ptcp
, ð_ports_tcp
);
240 memset(buff
, 0, sizeof(buff
));
245 static int dissector_cleanup_ports_tcp(void *ptr
)
247 struct port_tcp
*tmp
, *p
= ptr
;
250 while ((tmp
= p
->next
)) {
260 static void dissector_init_ether_types(void)
263 char buff
[512], *ptr
;
264 struct ether_type
*et
;
266 fp
= fopen("/etc/netsniff-ng/ether.conf", "r");
268 panic("No /etc/netsniff-ng/ether.conf found!\n");
269 memset(buff
, 0, sizeof(buff
));
270 while (fgets(buff
, sizeof(buff
), fp
) != NULL
) {
271 buff
[sizeof(buff
) - 1] = 0;
272 et
= xmalloc(sizeof(*et
));
275 ptr
= getuint(ptr
, &et
->id
);
277 ptr
= skipchar(ptr
, ',');
279 ptr
= strtrim_right(ptr
, '\n');
280 ptr
= strtrim_right(ptr
, ' ');
281 et
->type
= xstrdup(ptr
);
283 pos
= insert_hash(et
->id
, et
, ð_ether_types
);
288 memset(buff
, 0, sizeof(buff
));
293 static int dissector_cleanup_ether_types(void *ptr
)
295 struct ether_type
*tmp
, *p
= ptr
;
298 while ((tmp
= p
->next
)) {
308 void dissector_init_ethernet(int fnttype
)
310 dissector_init_entry(fnttype
);
311 dissector_init_layer_2(fnttype
);
312 dissector_init_layer_3(fnttype
);
313 dissector_init_layer_4(fnttype
);
314 dissector_init_exit(fnttype
);
315 dissector_init_oui();
316 dissector_init_ports_udp();
317 dissector_init_ports_tcp();
318 dissector_init_ether_types();
321 void dissector_cleanup_ethernet(void)
323 free_hash(ð_lay2
);
324 free_hash(ð_lay3
);
325 free_hash(ð_lay4
);
326 for_each_hash(ð_ether_types
, dissector_cleanup_ether_types
);
327 free_hash(ð_ether_types
);
328 for_each_hash(ð_ports_udp
, dissector_cleanup_ports_udp
);
329 free_hash(ð_ports_udp
);
330 for_each_hash(ð_ports_tcp
, dissector_cleanup_ports_tcp
);
331 free_hash(ð_ports_tcp
);
332 for_each_hash(ð_oui
, dissector_cleanup_oui
);