html: some further minor tweaks on the index page
[netsniff-ng.git] / src / dissector_eth.c
blobc0bea2d0b9b6964a3414e0a4a6b881bd52fc8f9a
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 /* Needs a better rewrite! */
10 #include <stdint.h>
12 #include "hash.h"
13 #include "protos.h"
14 #include "dissector.h"
15 #include "dissector_eth.h"
16 #include "xmalloc.h"
17 #include "xstring.h"
19 struct hash_table eth_lay2;
20 struct hash_table eth_lay3;
21 struct hash_table eth_lay4;
23 static struct hash_table eth_ether_types;
24 static struct hash_table eth_ports_udp;
25 static struct hash_table eth_ports_tcp;
26 static struct hash_table eth_oui;
28 struct vendor_id {
29 unsigned int id;
30 char *vendor;
31 struct vendor_id *next;
34 struct port_tcp {
35 unsigned int id;
36 char *port;
37 struct port_tcp *next;
40 struct port_udp {
41 unsigned int id;
42 char *port;
43 struct port_udp *next;
46 struct ether_type {
47 unsigned int id;
48 char *type;
49 struct ether_type *next;
52 char *lookup_vendor(unsigned int id)
54 struct vendor_id *entry = lookup_hash(id, &eth_oui);
55 while (entry && id != entry->id)
56 entry = entry->next;
57 return (entry && id == entry->id ? entry->vendor : "Unknown");
60 char *lookup_port_udp(unsigned int id)
62 struct port_udp *entry = lookup_hash(id, &eth_ports_udp);
63 while (entry && id != entry->id)
64 entry = entry->next;
65 return (entry && id == entry->id ? entry->port : "Unknown");
68 char *lookup_port_tcp(unsigned int id)
70 struct port_tcp *entry = lookup_hash(id, &eth_ports_tcp);
71 while (entry && id != entry->id)
72 entry = entry->next;
73 return (entry && id == entry->id ? entry->port : "Unknown");
76 char *lookup_ether_type(unsigned int id)
78 struct ether_type *entry = lookup_hash(id, &eth_ether_types);
79 while (entry && id != entry->id)
80 entry = entry->next;
81 return (entry && id == entry->id ? entry->type : "Unknown");
84 static inline void dissector_init_entry(int (*fnt)(void *ptr))
86 fnt(&ethernet_ops);
89 static inline void dissector_init_exit(int (*fnt)(void *ptr))
91 fnt(&hex_ops);
94 static void dissector_init_lay2(int (*fnt)(void *ptr))
96 init_hash(&eth_lay2);
97 INSERT_HASH_PROTOS(arp_ops, eth_lay2);
98 INSERT_HASH_PROTOS(vlan_ops, eth_lay2);
99 INSERT_HASH_PROTOS(ipv4_ops, eth_lay2);
100 INSERT_HASH_PROTOS(ipv6_ops, eth_lay2);
101 for_each_hash(&eth_lay2, fnt);
104 static void dissector_init_lay3(int (*fnt)(void *ptr))
106 init_hash(&eth_lay3);
107 INSERT_HASH_PROTOS(icmp_ops, eth_lay3);
108 INSERT_HASH_PROTOS(udp_ops, eth_lay3);
109 INSERT_HASH_PROTOS(tcp_ops, eth_lay3);
110 for_each_hash(&eth_lay3, fnt);
113 static void dissector_init_lay4(int (*fnt)(void *ptr))
115 init_hash(&eth_lay4);
116 for_each_hash(&eth_lay4, fnt);
119 static void dissector_init_oui(void)
121 FILE *fp;
122 char buff[512], *ptr;
123 struct vendor_id *ven;
124 void **pos;
126 fp = fopen("/etc/netsniff-ng/oui.conf", "r");
127 if (!fp)
128 panic("No /etc/netsniff-ng/oui.conf found!\n");
129 memset(buff, 0, sizeof(buff));
130 while (fgets(buff, sizeof(buff), fp) != NULL) {
131 buff[sizeof(buff) - 1] = 0;
132 ven = xmalloc(sizeof(*ven));
133 ptr = buff;
134 ptr = skips(ptr);
135 ptr = getuint(ptr, &ven->id);
136 ptr = skips(ptr);
137 ptr = skipchar(ptr, ',');
138 ptr = skips(ptr);
139 ptr = strtrim_right(ptr, '\n');
140 ptr = strtrim_right(ptr, ' ');
141 ven->vendor = xstrdup(ptr);
142 ven->next = NULL;
143 pos = insert_hash(ven->id, ven, &eth_oui);
144 if (pos) {
145 ven->next = *pos;
146 *pos = ven;
148 memset(buff, 0, sizeof(buff));
151 fclose(fp);
154 static int dissector_cleanup_oui(void *ptr)
156 struct vendor_id *tmp, *v = ptr;
158 if (!ptr)
159 return 0;
161 while ((tmp = v->next)) {
162 xfree(v->vendor);
163 xfree(v);
164 v = tmp;
167 xfree(v->vendor);
168 xfree(v);
169 return 0;
172 static void dissector_init_ports_udp(void)
174 FILE *fp;
175 char buff[512], *ptr;
176 struct port_udp *pudp;
177 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));
204 fclose(fp);
207 static int dissector_cleanup_ports_udp(void *ptr)
209 struct port_udp *tmp, *p = ptr;
211 if (!ptr)
212 return 0;
214 while ((tmp = p->next)) {
215 xfree(p->port);
216 xfree(p);
217 p = tmp;
220 xfree(p->port);
221 xfree(p);
222 return 0;
225 static void dissector_init_ports_tcp(void)
227 FILE *fp;
228 char buff[512], *ptr;
229 struct port_tcp *ptcp;
230 void **pos;
232 fp = fopen("/etc/netsniff-ng/tcp.conf", "r");
233 if (!fp)
234 panic("No /etc/netsniff-ng/tcp.conf found!\n");
235 memset(buff, 0, sizeof(buff));
236 while (fgets(buff, sizeof(buff), fp) != NULL) {
237 buff[sizeof(buff) - 1] = 0;
238 ptcp = xmalloc(sizeof(*ptcp));
239 ptr = buff;
240 ptr = skips(ptr);
241 ptr = getuint(ptr, &ptcp->id);
242 ptr = skips(ptr);
243 ptr = skipchar(ptr, ',');
244 ptr = skips(ptr);
245 ptr = strtrim_right(ptr, '\n');
246 ptr = strtrim_right(ptr, ' ');
247 ptcp->port = xstrdup(ptr);
248 ptcp->next = NULL;
249 pos = insert_hash(ptcp->id, ptcp, &eth_ports_tcp);
250 if (pos) {
251 ptcp->next = *pos;
252 *pos = ptcp;
254 memset(buff, 0, sizeof(buff));
257 fclose(fp);
260 static int dissector_cleanup_ports_tcp(void *ptr)
262 struct port_tcp *tmp, *p = ptr;
264 if (!ptr)
265 return 0;
267 while ((tmp = p->next)) {
268 xfree(p->port);
269 xfree(p);
270 p = tmp;
273 xfree(p->port);
274 xfree(p);
275 return 0;
278 static void dissector_init_ether_types(void)
280 FILE *fp;
281 char buff[512], *ptr;
282 struct ether_type *et;
283 void **pos;
285 fp = fopen("/etc/netsniff-ng/ether.conf", "r");
286 if (!fp)
287 panic("No /etc/netsniff-ng/ether.conf found!\n");
288 memset(buff, 0, sizeof(buff));
289 while (fgets(buff, sizeof(buff), fp) != NULL) {
290 buff[sizeof(buff) - 1] = 0;
291 et = xmalloc(sizeof(*et));
292 ptr = buff;
293 ptr = skips(ptr);
294 ptr = getuint(ptr, &et->id);
295 ptr = skips(ptr);
296 ptr = skipchar(ptr, ',');
297 ptr = skips(ptr);
298 ptr = strtrim_right(ptr, '\n');
299 ptr = strtrim_right(ptr, ' ');
300 et->type = xstrdup(ptr);
301 et->next = NULL;
302 pos = insert_hash(et->id, et, &eth_ether_types);
303 if (pos) {
304 et->next = *pos;
305 *pos = et;
307 memset(buff, 0, sizeof(buff));
310 fclose(fp);
313 static int dissector_cleanup_ether_types(void *ptr)
315 struct ether_type *tmp, *p = ptr;
317 if (!ptr)
318 return 0;
320 while ((tmp = p->next)) {
321 xfree(p->type);
322 xfree(p);
323 p = tmp;
326 xfree(p->type);
327 xfree(p);
328 return 0;
331 void dissector_init_ethernet(int fnttype)
333 int (*fnt)(void *ptr) = NULL;
335 switch (fnttype) {
336 case FNTTYPE_PRINT_NORM:
337 fnt = dissector_set_print_norm;
338 break;
339 case FNTTYPE_PRINT_LESS:
340 fnt = dissector_set_print_less;
341 break;
342 case FNTTYPE_PRINT_HEX1:
343 fnt = dissector_set_print_payload_hex;
344 break;
345 case FNTTYPE_PRINT_HEX2:
346 fnt = dissector_set_print_all_hex;
347 break;
348 case FNTTYPE_PRINT_CHR1:
349 fnt = dissector_set_print_payload;
350 break;
351 case FNTTYPE_PRINT_NOPA:
352 fnt = dissector_set_print_no_payload;
353 break;
354 case FNTTYPE_PRINT_PAAC:
355 fnt = dissector_set_print_c_style;
356 break;
357 default:
358 case FNTTYPE_PRINT_NONE:
359 fnt = dissector_set_print_none;
360 break;
363 dissector_init_entry(fnt);
364 dissector_init_lay2(fnt);
365 dissector_init_lay3(fnt);
366 dissector_init_lay4(fnt);
367 dissector_init_exit(fnt);
369 info("OUI "); fflush(stdout);
370 dissector_init_oui();
371 info("UDP "); fflush(stdout);
372 dissector_init_ports_udp();
373 info("TCP "); fflush(stdout);
374 dissector_init_ports_tcp();
375 info("ETH "); fflush(stdout);
376 dissector_init_ether_types();
377 info("\n"); fflush(stdout);
380 void dissector_cleanup_ethernet(void)
382 free_hash(&eth_lay2);
383 free_hash(&eth_lay3);
384 free_hash(&eth_lay4);
386 for_each_hash(&eth_ether_types, dissector_cleanup_ether_types);
387 free_hash(&eth_ether_types);
388 for_each_hash(&eth_ports_udp, dissector_cleanup_ports_udp);
389 free_hash(&eth_ports_udp);
390 for_each_hash(&eth_ports_tcp, dissector_cleanup_ports_tcp);
391 free_hash(&eth_ports_tcp);
392 for_each_hash(&eth_oui, dissector_cleanup_oui);
393 free_hash(&eth_oui);