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.
12 #include "dissector.h"
13 #include "dissector_eth.h"
17 struct hash_table eth_lay2
;
18 struct hash_table eth_lay3
;
19 struct hash_table eth_lay4
;
21 static struct hash_table eth_ether_types
;
22 static struct hash_table eth_ports_udp
;
23 static struct hash_table eth_ports_tcp
;
24 static struct hash_table eth_oui
;
29 struct vendor_id
*next
;
35 struct port_tcp
*next
;
41 struct port_udp
*next
;
47 struct ether_type
*next
;
50 /* Note: this macro only applies to the lookup_* functions here in this file,
51 * mainly to remove redundand code. */
52 #define __do_lookup_inline(id, struct_name, hash_ptr, struct_member) \
54 struct struct_name *entry = lookup_hash(id, hash_ptr); \
55 while (entry && id != entry->id) \
56 entry = entry->next; \
57 (entry && id == entry->id ? entry->struct_member : "Unknown");\
60 char *lookup_vendor(unsigned int id
)
62 return __do_lookup_inline(id
, vendor_id
, ð_oui
, vendor
);
65 char *lookup_port_udp(unsigned int id
)
67 return __do_lookup_inline(id
, port_udp
, ð_ports_udp
, port
);
70 char *lookup_port_tcp(unsigned int id
)
72 return __do_lookup_inline(id
, port_tcp
, ð_ports_tcp
, port
);
75 char *lookup_ether_type(unsigned int id
)
77 return __do_lookup_inline(id
, ether_type
, ð_ether_types
, type
);
80 static inline void dissector_init_entry(int type
)
82 dissector_set_print_type(ðernet_ops
, type
);
85 static inline void dissector_init_exit(int type
)
87 dissector_set_print_type(&hex_ops
, type
);
90 static void dissector_init_layer_2(int type
)
93 INSERT_HASH_PROTOS(arp_ops
, eth_lay2
);
94 INSERT_HASH_PROTOS(vlan_ops
, eth_lay2
);
95 INSERT_HASH_PROTOS(ipv4_ops
, eth_lay2
);
96 INSERT_HASH_PROTOS(ipv6_ops
, eth_lay2
);
97 for_each_hash_int(ð_lay2
, dissector_set_print_type
, type
);
100 static void dissector_init_layer_3(int type
)
102 init_hash(ð_lay3
);
103 INSERT_HASH_PROTOS(ipv6_fragm_ops
, eth_lay3
);
104 INSERT_HASH_PROTOS(ipv6_in_ipv4_ops
, eth_lay3
);
105 INSERT_HASH_PROTOS(ipv6_hop_by_hop_ops
, eth_lay3
);
106 INSERT_HASH_PROTOS(ipv6_routing_ops
, eth_lay3
);
107 INSERT_HASH_PROTOS(ipv6_dest_opts_ops
, eth_lay3
);
108 INSERT_HASH_PROTOS(ipv6_no_next_header_ops
, eth_lay3
);
109 INSERT_HASH_PROTOS(ip_auth_hdr_ops
, eth_lay3
);
110 INSERT_HASH_PROTOS(ipv6_mobility_hdr_ops
, eth_lay3
);
111 INSERT_HASH_PROTOS(esp_ops
, eth_lay3
);
112 INSERT_HASH_PROTOS(icmp_ops
, eth_lay3
);
113 INSERT_HASH_PROTOS(icmpv6_ops
, eth_lay3
);
114 INSERT_HASH_PROTOS(udp_ops
, eth_lay3
);
115 INSERT_HASH_PROTOS(tcp_ops
, eth_lay3
);
116 for_each_hash_int(ð_lay3
, dissector_set_print_type
, type
);
119 static void dissector_init_layer_4(int type
)
121 init_hash(ð_lay4
);
122 for_each_hash_int(ð_lay4
, dissector_set_print_type
, type
);
125 static void dissector_init_oui(void)
128 char buff
[512], *ptr
;
129 struct vendor_id
*ven
;
131 fp
= fopen("/etc/netsniff-ng/oui.conf", "r");
133 panic("No /etc/netsniff-ng/oui.conf found!\n");
134 memset(buff
, 0, sizeof(buff
));
135 while (fgets(buff
, sizeof(buff
), fp
) != NULL
) {
136 buff
[sizeof(buff
) - 1] = 0;
137 ven
= xmalloc(sizeof(*ven
));
140 ptr
= getuint(ptr
, &ven
->id
);
142 ptr
= skipchar(ptr
, ',');
144 ptr
= strtrim_right(ptr
, '\n');
145 ptr
= strtrim_right(ptr
, ' ');
146 ven
->vendor
= xstrdup(ptr
);
148 pos
= insert_hash(ven
->id
, ven
, ð_oui
);
153 memset(buff
, 0, sizeof(buff
));
158 static int dissector_cleanup_oui(void *ptr
)
160 struct vendor_id
*tmp
, *v
= ptr
;
163 while ((tmp
= v
->next
)) {
173 static void dissector_init_ports_udp(void)
176 char buff
[512], *ptr
;
177 struct port_udp
*pudp
;
179 fp
= fopen("/etc/netsniff-ng/udp.conf", "r");
181 panic("No /etc/netsniff-ng/udp.conf found!\n");
182 memset(buff
, 0, sizeof(buff
));
183 while (fgets(buff
, sizeof(buff
), fp
) != NULL
) {
184 buff
[sizeof(buff
) - 1] = 0;
185 pudp
= xmalloc(sizeof(*pudp
));
188 ptr
= getuint(ptr
, &pudp
->id
);
190 ptr
= skipchar(ptr
, ',');
192 ptr
= strtrim_right(ptr
, '\n');
193 ptr
= strtrim_right(ptr
, ' ');
194 pudp
->port
= xstrdup(ptr
);
196 pos
= insert_hash(pudp
->id
, pudp
, ð_ports_udp
);
201 memset(buff
, 0, sizeof(buff
));
206 static int dissector_cleanup_ports_udp(void *ptr
)
208 struct port_udp
*tmp
, *p
= ptr
;
211 while ((tmp
= p
->next
)) {
221 static void dissector_init_ports_tcp(void)
224 char buff
[512], *ptr
;
225 struct port_tcp
*ptcp
;
227 fp
= fopen("/etc/netsniff-ng/tcp.conf", "r");
229 panic("No /etc/netsniff-ng/tcp.conf found!\n");
230 memset(buff
, 0, sizeof(buff
));
231 while (fgets(buff
, sizeof(buff
), fp
) != NULL
) {
232 buff
[sizeof(buff
) - 1] = 0;
233 ptcp
= xmalloc(sizeof(*ptcp
));
236 ptr
= getuint(ptr
, &ptcp
->id
);
238 ptr
= skipchar(ptr
, ',');
240 ptr
= strtrim_right(ptr
, '\n');
241 ptr
= strtrim_right(ptr
, ' ');
242 ptcp
->port
= xstrdup(ptr
);
244 pos
= insert_hash(ptcp
->id
, ptcp
, ð_ports_tcp
);
249 memset(buff
, 0, sizeof(buff
));
254 static int dissector_cleanup_ports_tcp(void *ptr
)
256 struct port_tcp
*tmp
, *p
= ptr
;
259 while ((tmp
= p
->next
)) {
269 static void dissector_init_ether_types(void)
272 char buff
[512], *ptr
;
273 struct ether_type
*et
;
275 fp
= fopen("/etc/netsniff-ng/ether.conf", "r");
277 panic("No /etc/netsniff-ng/ether.conf found!\n");
278 memset(buff
, 0, sizeof(buff
));
279 while (fgets(buff
, sizeof(buff
), fp
) != NULL
) {
280 buff
[sizeof(buff
) - 1] = 0;
281 et
= xmalloc(sizeof(*et
));
284 ptr
= getuint(ptr
, &et
->id
);
286 ptr
= skipchar(ptr
, ',');
288 ptr
= strtrim_right(ptr
, '\n');
289 ptr
= strtrim_right(ptr
, ' ');
290 et
->type
= xstrdup(ptr
);
292 pos
= insert_hash(et
->id
, et
, ð_ether_types
);
297 memset(buff
, 0, sizeof(buff
));
302 static int dissector_cleanup_ether_types(void *ptr
)
304 struct ether_type
*tmp
, *p
= ptr
;
307 while ((tmp
= p
->next
)) {
317 void dissector_init_ethernet(int fnttype
)
319 dissector_init_entry(fnttype
);
320 dissector_init_layer_2(fnttype
);
321 dissector_init_layer_3(fnttype
);
322 dissector_init_layer_4(fnttype
);
323 dissector_init_exit(fnttype
);
324 dissector_init_oui();
325 dissector_init_ports_udp();
326 dissector_init_ports_tcp();
327 dissector_init_ether_types();
330 void dissector_cleanup_ethernet(void)
332 free_hash(ð_lay2
);
333 free_hash(ð_lay3
);
334 free_hash(ð_lay4
);
335 for_each_hash(ð_ether_types
, dissector_cleanup_ether_types
);
336 free_hash(ð_ether_types
);
337 for_each_hash(ð_ports_udp
, dissector_cleanup_ports_udp
);
338 free_hash(ð_ports_udp
);
339 for_each_hash(ð_ports_tcp
, dissector_cleanup_ports_tcp
);
340 free_hash(ð_ports_tcp
);
341 for_each_hash(ð_oui
, dissector_cleanup_oui
);