mmap: let grow area less intense
[netsniff-ng-old.git] / src / dissector_eth.c
blob543226c5f7d0feaec9f890eeec1f9f6e3ac1098c
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 "oui.h"
12 #include "protos.h"
13 #include "pkt_buff.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;
22 static struct hash_table eth_ether_types;
23 static struct hash_table eth_ports_udp;
24 static struct hash_table eth_ports_tcp;
26 struct port_tcp {
27 unsigned int id;
28 char *port;
29 struct port_tcp *next;
32 struct port_udp {
33 unsigned int id;
34 char *port;
35 struct port_udp *next;
38 struct ether_type {
39 unsigned int id;
40 char *type;
41 struct ether_type *next;
44 /* Note: this macro only applies to the lookup_* functions here in this file,
45 * mainly to remove redundand code. */
46 #define __do_lookup_inline(id, struct_name, hash_ptr, struct_member) \
47 ({ \
48 struct struct_name *entry = lookup_hash(id, hash_ptr); \
49 while (entry && id != entry->id) \
50 entry = entry->next; \
51 (entry && id == entry->id ? entry->struct_member : 0);\
54 char *lookup_port_udp(unsigned int id)
56 return __do_lookup_inline(id, port_udp, &eth_ports_udp, port);
59 char *lookup_port_tcp(unsigned int id)
61 return __do_lookup_inline(id, port_tcp, &eth_ports_tcp, port);
64 char *lookup_ether_type(unsigned int id)
66 return __do_lookup_inline(id, ether_type, &eth_ether_types, type);
69 #ifdef __WITH_PROTOS
70 static inline void dissector_init_entry(int type)
72 dissector_set_print_type(&ethernet_ops, type);
75 static inline void dissector_init_exit(int type)
77 dissector_set_print_type(&none_ops, type);
80 static void dissector_init_layer_2(int type)
82 init_hash(&eth_lay2);
83 INSERT_HASH_PROTOS(arp_ops, eth_lay2);
84 INSERT_HASH_PROTOS(vlan_ops, eth_lay2);
85 INSERT_HASH_PROTOS(ipv4_ops, eth_lay2);
86 INSERT_HASH_PROTOS(ipv6_ops, eth_lay2);
87 INSERT_HASH_PROTOS(QinQ_ops, eth_lay2);
88 INSERT_HASH_PROTOS(mpls_uc_ops, eth_lay2);
89 for_each_hash_int(&eth_lay2, dissector_set_print_type, type);
92 static void dissector_init_layer_3(int type)
94 init_hash(&eth_lay3);
95 INSERT_HASH_PROTOS(icmpv4_ops, eth_lay3);
96 INSERT_HASH_PROTOS(icmpv6_ops, eth_lay3);
97 INSERT_HASH_PROTOS(igmp_ops, eth_lay3);
98 INSERT_HASH_PROTOS(ip_auth_ops, eth_lay3);
99 INSERT_HASH_PROTOS(ip_esp_ops, eth_lay3);
100 INSERT_HASH_PROTOS(ipv6_dest_opts_ops, eth_lay3);
101 INSERT_HASH_PROTOS(ipv6_fragm_ops, eth_lay3);
102 INSERT_HASH_PROTOS(ipv6_hop_by_hop_ops, eth_lay3);
103 INSERT_HASH_PROTOS(ipv6_in_ipv4_ops, eth_lay3);
104 INSERT_HASH_PROTOS(ipv6_mobility_ops, eth_lay3);
105 INSERT_HASH_PROTOS(ipv6_no_next_header_ops, eth_lay3);
106 INSERT_HASH_PROTOS(ipv6_routing_ops, eth_lay3);
107 INSERT_HASH_PROTOS(tcp_ops, eth_lay3);
108 INSERT_HASH_PROTOS(udp_ops, eth_lay3);
109 for_each_hash_int(&eth_lay3, dissector_set_print_type, type);
111 #else
112 static inline void dissector_init_entry(int type) {}
113 static inline void dissector_init_exit(int type) {}
114 static void dissector_init_layer_2(int type) {}
115 static void dissector_init_layer_3(int type) {}
116 #endif /* __WITH_PROTOS */
118 static void dissector_init_ports_udp(void)
120 FILE *fp;
121 char buff[512], *ptr;
122 struct port_udp *pudp;
123 void **pos;
124 fp = fopen("/etc/netsniff-ng/udp.conf", "r");
125 if (!fp)
126 panic("No /etc/netsniff-ng/udp.conf found!\n");
127 memset(buff, 0, sizeof(buff));
128 while (fgets(buff, sizeof(buff), fp) != NULL) {
129 buff[sizeof(buff) - 1] = 0;
130 pudp = xmalloc(sizeof(*pudp));
131 ptr = buff;
132 ptr = skips(ptr);
133 ptr = getuint(ptr, &pudp->id);
134 ptr = skips(ptr);
135 ptr = skipchar(ptr, ',');
136 ptr = skips(ptr);
137 ptr = strtrim_right(ptr, '\n');
138 ptr = strtrim_right(ptr, ' ');
139 pudp->port = xstrdup(ptr);
140 pudp->next = NULL;
141 pos = insert_hash(pudp->id, pudp, &eth_ports_udp);
142 if (pos) {
143 pudp->next = *pos;
144 *pos = pudp;
146 memset(buff, 0, sizeof(buff));
148 fclose(fp);
151 static int dissector_cleanup_ports_udp(void *ptr)
153 struct port_udp *tmp, *p = ptr;
154 if (!ptr)
155 return 0;
156 while ((tmp = p->next)) {
157 xfree(p->port);
158 xfree(p);
159 p = tmp;
161 xfree(p->port);
162 xfree(p);
163 return 0;
166 static void dissector_init_ports_tcp(void)
168 FILE *fp;
169 char buff[512], *ptr;
170 struct port_tcp *ptcp;
171 void **pos;
172 fp = fopen("/etc/netsniff-ng/tcp.conf", "r");
173 if (!fp)
174 panic("No /etc/netsniff-ng/tcp.conf found!\n");
175 memset(buff, 0, sizeof(buff));
176 while (fgets(buff, sizeof(buff), fp) != NULL) {
177 buff[sizeof(buff) - 1] = 0;
178 ptcp = xmalloc(sizeof(*ptcp));
179 ptr = buff;
180 ptr = skips(ptr);
181 ptr = getuint(ptr, &ptcp->id);
182 ptr = skips(ptr);
183 ptr = skipchar(ptr, ',');
184 ptr = skips(ptr);
185 ptr = strtrim_right(ptr, '\n');
186 ptr = strtrim_right(ptr, ' ');
187 ptcp->port = xstrdup(ptr);
188 ptcp->next = NULL;
189 pos = insert_hash(ptcp->id, ptcp, &eth_ports_tcp);
190 if (pos) {
191 ptcp->next = *pos;
192 *pos = ptcp;
194 memset(buff, 0, sizeof(buff));
196 fclose(fp);
199 static int dissector_cleanup_ports_tcp(void *ptr)
201 struct port_tcp *tmp, *p = ptr;
202 if (!ptr)
203 return 0;
204 while ((tmp = p->next)) {
205 xfree(p->port);
206 xfree(p);
207 p = tmp;
209 xfree(p->port);
210 xfree(p);
211 return 0;
214 static void dissector_init_ether_types(void)
216 FILE *fp;
217 char buff[512], *ptr;
218 struct ether_type *et;
219 void **pos;
220 fp = fopen("/etc/netsniff-ng/ether.conf", "r");
221 if (!fp)
222 panic("No /etc/netsniff-ng/ether.conf found!\n");
223 memset(buff, 0, sizeof(buff));
224 while (fgets(buff, sizeof(buff), fp) != NULL) {
225 buff[sizeof(buff) - 1] = 0;
226 et = xmalloc(sizeof(*et));
227 ptr = buff;
228 ptr = skips(ptr);
229 ptr = getuint(ptr, &et->id);
230 ptr = skips(ptr);
231 ptr = skipchar(ptr, ',');
232 ptr = skips(ptr);
233 ptr = strtrim_right(ptr, '\n');
234 ptr = strtrim_right(ptr, ' ');
235 et->type = xstrdup(ptr);
236 et->next = NULL;
237 pos = insert_hash(et->id, et, &eth_ether_types);
238 if (pos) {
239 et->next = *pos;
240 *pos = et;
242 memset(buff, 0, sizeof(buff));
244 fclose(fp);
247 static int dissector_cleanup_ether_types(void *ptr)
249 struct ether_type *tmp, *p = ptr;
250 if (!ptr)
251 return 0;
252 while ((tmp = p->next)) {
253 xfree(p->type);
254 xfree(p);
255 p = tmp;
257 xfree(p->type);
258 xfree(p);
259 return 0;
262 void dissector_init_ethernet(int fnttype)
264 dissector_init_entry(fnttype);
265 dissector_init_layer_2(fnttype);
266 dissector_init_layer_3(fnttype);
267 dissector_init_exit(fnttype);
268 #ifdef __WITH_PROTOS
269 dissector_init_oui();
270 #endif
271 dissector_init_ports_udp();
272 dissector_init_ports_tcp();
273 dissector_init_ether_types();
276 void dissector_cleanup_ethernet(void)
278 free_hash(&eth_lay2);
279 free_hash(&eth_lay3);
280 for_each_hash(&eth_ether_types, dissector_cleanup_ether_types);
281 free_hash(&eth_ether_types);
282 for_each_hash(&eth_ports_udp, dissector_cleanup_ports_udp);
283 free_hash(&eth_ports_udp);
284 for_each_hash(&eth_ports_tcp, dissector_cleanup_ports_tcp);
285 free_hash(&eth_ports_tcp);
286 #ifdef __WITH_PROTOS
287 dissector_cleanup_oui();
288 #endif