icmpv4/icmpv6: renamed, start icmpv6 dissector
[netsniff-ng.git] / src / dissector_eth.c
blob1f44b7a16b29d93f22438d57a2a21e77cc92affb
1 /*
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.
6 */
8 #include <stdint.h>
10 #include "hash.h"
11 #include "protos.h"
12 #include "dissector.h"
13 #include "dissector_eth.h"
14 #include "xmalloc.h"
15 #include "xstring.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;
26 struct vendor_id {
27 unsigned int id;
28 char *vendor;
29 struct vendor_id *next;
32 struct port_tcp {
33 unsigned int id;
34 char *port;
35 struct port_tcp *next;
38 struct port_udp {
39 unsigned int id;
40 char *port;
41 struct port_udp *next;
44 struct ether_type {
45 unsigned int id;
46 char *type;
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) \
53 ({ \
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, &eth_oui, vendor);
65 char *lookup_port_udp(unsigned int id)
67 return __do_lookup_inline(id, port_udp, &eth_ports_udp, port);
70 char *lookup_port_tcp(unsigned int id)
72 return __do_lookup_inline(id, port_tcp, &eth_ports_tcp, port);
75 char *lookup_ether_type(unsigned int id)
77 return __do_lookup_inline(id, ether_type, &eth_ether_types, type);
80 static inline void dissector_init_entry(int type)
82 dissector_set_print_type(&ethernet_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)
92 init_hash(&eth_lay2);
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(&eth_lay2, dissector_set_print_type, type);
100 static void dissector_init_layer_3(int type)
102 init_hash(&eth_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(&eth_lay3, dissector_set_print_type, type);
119 static void dissector_init_layer_4(int type)
121 init_hash(&eth_lay4);
122 for_each_hash_int(&eth_lay4, dissector_set_print_type, type);
125 static void dissector_init_oui(void)
127 FILE *fp;
128 char buff[512], *ptr;
129 struct vendor_id *ven;
130 void **pos;
131 fp = fopen("/etc/netsniff-ng/oui.conf", "r");
132 if (!fp)
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));
138 ptr = buff;
139 ptr = skips(ptr);
140 ptr = getuint(ptr, &ven->id);
141 ptr = skips(ptr);
142 ptr = skipchar(ptr, ',');
143 ptr = skips(ptr);
144 ptr = strtrim_right(ptr, '\n');
145 ptr = strtrim_right(ptr, ' ');
146 ven->vendor = xstrdup(ptr);
147 ven->next = NULL;
148 pos = insert_hash(ven->id, ven, &eth_oui);
149 if (pos) {
150 ven->next = *pos;
151 *pos = ven;
153 memset(buff, 0, sizeof(buff));
155 fclose(fp);
158 static int dissector_cleanup_oui(void *ptr)
160 struct vendor_id *tmp, *v = ptr;
161 if (!ptr)
162 return 0;
163 while ((tmp = v->next)) {
164 xfree(v->vendor);
165 xfree(v);
166 v = tmp;
168 xfree(v->vendor);
169 xfree(v);
170 return 0;
173 static void dissector_init_ports_udp(void)
175 FILE *fp;
176 char buff[512], *ptr;
177 struct port_udp *pudp;
178 void **pos;
179 fp = fopen("/etc/netsniff-ng/udp.conf", "r");
180 if (!fp)
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));
186 ptr = buff;
187 ptr = skips(ptr);
188 ptr = getuint(ptr, &pudp->id);
189 ptr = skips(ptr);
190 ptr = skipchar(ptr, ',');
191 ptr = skips(ptr);
192 ptr = strtrim_right(ptr, '\n');
193 ptr = strtrim_right(ptr, ' ');
194 pudp->port = xstrdup(ptr);
195 pudp->next = NULL;
196 pos = insert_hash(pudp->id, pudp, &eth_ports_udp);
197 if (pos) {
198 pudp->next = *pos;
199 *pos = pudp;
201 memset(buff, 0, sizeof(buff));
203 fclose(fp);
206 static int dissector_cleanup_ports_udp(void *ptr)
208 struct port_udp *tmp, *p = ptr;
209 if (!ptr)
210 return 0;
211 while ((tmp = p->next)) {
212 xfree(p->port);
213 xfree(p);
214 p = tmp;
216 xfree(p->port);
217 xfree(p);
218 return 0;
221 static void dissector_init_ports_tcp(void)
223 FILE *fp;
224 char buff[512], *ptr;
225 struct port_tcp *ptcp;
226 void **pos;
227 fp = fopen("/etc/netsniff-ng/tcp.conf", "r");
228 if (!fp)
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));
234 ptr = buff;
235 ptr = skips(ptr);
236 ptr = getuint(ptr, &ptcp->id);
237 ptr = skips(ptr);
238 ptr = skipchar(ptr, ',');
239 ptr = skips(ptr);
240 ptr = strtrim_right(ptr, '\n');
241 ptr = strtrim_right(ptr, ' ');
242 ptcp->port = xstrdup(ptr);
243 ptcp->next = NULL;
244 pos = insert_hash(ptcp->id, ptcp, &eth_ports_tcp);
245 if (pos) {
246 ptcp->next = *pos;
247 *pos = ptcp;
249 memset(buff, 0, sizeof(buff));
251 fclose(fp);
254 static int dissector_cleanup_ports_tcp(void *ptr)
256 struct port_tcp *tmp, *p = ptr;
257 if (!ptr)
258 return 0;
259 while ((tmp = p->next)) {
260 xfree(p->port);
261 xfree(p);
262 p = tmp;
264 xfree(p->port);
265 xfree(p);
266 return 0;
269 static void dissector_init_ether_types(void)
271 FILE *fp;
272 char buff[512], *ptr;
273 struct ether_type *et;
274 void **pos;
275 fp = fopen("/etc/netsniff-ng/ether.conf", "r");
276 if (!fp)
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));
282 ptr = buff;
283 ptr = skips(ptr);
284 ptr = getuint(ptr, &et->id);
285 ptr = skips(ptr);
286 ptr = skipchar(ptr, ',');
287 ptr = skips(ptr);
288 ptr = strtrim_right(ptr, '\n');
289 ptr = strtrim_right(ptr, ' ');
290 et->type = xstrdup(ptr);
291 et->next = NULL;
292 pos = insert_hash(et->id, et, &eth_ether_types);
293 if (pos) {
294 et->next = *pos;
295 *pos = et;
297 memset(buff, 0, sizeof(buff));
299 fclose(fp);
302 static int dissector_cleanup_ether_types(void *ptr)
304 struct ether_type *tmp, *p = ptr;
305 if (!ptr)
306 return 0;
307 while ((tmp = p->next)) {
308 xfree(p->type);
309 xfree(p);
310 p = tmp;
312 xfree(p->type);
313 xfree(p);
314 return 0;
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(&eth_lay2);
333 free_hash(&eth_lay3);
334 free_hash(&eth_lay4);
335 for_each_hash(&eth_ether_types, dissector_cleanup_ether_types);
336 free_hash(&eth_ether_types);
337 for_each_hash(&eth_ports_udp, dissector_cleanup_ports_udp);
338 free_hash(&eth_ports_udp);
339 for_each_hash(&eth_ports_tcp, dissector_cleanup_ports_tcp);
340 free_hash(&eth_ports_tcp);
341 for_each_hash(&eth_oui, dissector_cleanup_oui);
342 free_hash(&eth_oui);