trafgen: allow to schedule packets on specific CPUs
[netsniff-ng.git] / src / dissector_eth.c
blobb0fdd549df4687e8f1b4062e9ca87501a03ae621
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"
18 struct hash_table eth_lay2;
19 struct hash_table eth_lay3;
21 static struct hash_table eth_ether_types;
22 static struct hash_table eth_ports_udp;
23 static struct hash_table eth_ports_tcp;
25 struct port_tcp {
26 unsigned int id;
27 char *port;
28 struct port_tcp *next;
31 struct port_udp {
32 unsigned int id;
33 char *port;
34 struct port_udp *next;
37 struct ether_type {
38 unsigned int id;
39 char *type;
40 struct ether_type *next;
43 /* Note: this macro only applies to the lookup_* functions here in this file,
44 * mainly to remove redundand code. */
45 #define __do_lookup_inline(id, struct_name, hash_ptr, struct_member) \
46 ({ \
47 struct struct_name *entry = lookup_hash(id, hash_ptr); \
48 while (entry && id != entry->id) \
49 entry = entry->next; \
50 (entry && id == entry->id ? entry->struct_member : 0);\
53 char *lookup_port_udp(unsigned int id)
55 return __do_lookup_inline(id, port_udp, &eth_ports_udp, port);
58 char *lookup_port_tcp(unsigned int id)
60 return __do_lookup_inline(id, port_tcp, &eth_ports_tcp, port);
63 char *lookup_ether_type(unsigned int id)
65 return __do_lookup_inline(id, ether_type, &eth_ether_types, type);
68 #ifdef __WITH_PROTOS
69 static inline void dissector_init_entry(int type)
71 dissector_set_print_type(&ethernet_ops, type);
74 static inline void dissector_init_exit(int type)
76 dissector_set_print_type(&none_ops, type);
79 static void dissector_init_layer_2(int type)
81 init_hash(&eth_lay2);
82 INSERT_HASH_PROTOS(arp_ops, eth_lay2);
83 INSERT_HASH_PROTOS(vlan_ops, eth_lay2);
84 INSERT_HASH_PROTOS(ipv4_ops, eth_lay2);
85 INSERT_HASH_PROTOS(ipv6_ops, eth_lay2);
86 INSERT_HASH_PROTOS(QinQ_ops, eth_lay2);
87 INSERT_HASH_PROTOS(mpls_uc_ops, eth_lay2);
88 for_each_hash_int(&eth_lay2, dissector_set_print_type, type);
91 static void dissector_init_layer_3(int type)
93 init_hash(&eth_lay3);
94 INSERT_HASH_PROTOS(icmpv4_ops, eth_lay3);
95 INSERT_HASH_PROTOS(icmpv6_ops, eth_lay3);
96 INSERT_HASH_PROTOS(igmp_ops, eth_lay3);
97 INSERT_HASH_PROTOS(ip_auth_ops, eth_lay3);
98 INSERT_HASH_PROTOS(ip_esp_ops, eth_lay3);
99 INSERT_HASH_PROTOS(ipv6_dest_opts_ops, eth_lay3);
100 INSERT_HASH_PROTOS(ipv6_fragm_ops, eth_lay3);
101 INSERT_HASH_PROTOS(ipv6_hop_by_hop_ops, eth_lay3);
102 INSERT_HASH_PROTOS(ipv6_in_ipv4_ops, eth_lay3);
103 INSERT_HASH_PROTOS(ipv6_mobility_ops, eth_lay3);
104 INSERT_HASH_PROTOS(ipv6_no_next_header_ops, eth_lay3);
105 INSERT_HASH_PROTOS(ipv6_routing_ops, eth_lay3);
106 INSERT_HASH_PROTOS(tcp_ops, eth_lay3);
107 INSERT_HASH_PROTOS(udp_ops, eth_lay3);
108 for_each_hash_int(&eth_lay3, dissector_set_print_type, type);
110 #else
111 static inline void dissector_init_entry(int type) {}
112 static inline void dissector_init_exit(int type) {}
113 static void dissector_init_layer_2(int type) {}
114 static void dissector_init_layer_3(int type) {}
115 #endif /* __WITH_PROTOS */
117 static void dissector_init_ports_udp(void)
119 FILE *fp;
120 char buff[512], *ptr;
121 struct port_udp *pudp;
122 void **pos;
123 fp = fopen("/etc/netsniff-ng/udp.conf", "r");
124 if (!fp)
125 panic("No /etc/netsniff-ng/udp.conf found!\n");
126 memset(buff, 0, sizeof(buff));
127 while (fgets(buff, sizeof(buff), fp) != NULL) {
128 buff[sizeof(buff) - 1] = 0;
129 pudp = xmalloc(sizeof(*pudp));
130 ptr = buff;
131 ptr = skips(ptr);
132 ptr = getuint(ptr, &pudp->id);
133 ptr = skips(ptr);
134 ptr = skipchar(ptr, ',');
135 ptr = skips(ptr);
136 ptr = strtrim_right(ptr, '\n');
137 ptr = strtrim_right(ptr, ' ');
138 pudp->port = xstrdup(ptr);
139 pudp->next = NULL;
140 pos = insert_hash(pudp->id, pudp, &eth_ports_udp);
141 if (pos) {
142 pudp->next = *pos;
143 *pos = pudp;
145 memset(buff, 0, sizeof(buff));
147 fclose(fp);
150 static int dissector_cleanup_ports_udp(void *ptr)
152 struct port_udp *tmp, *p = ptr;
153 if (!ptr)
154 return 0;
155 while ((tmp = p->next)) {
156 xfree(p->port);
157 xfree(p);
158 p = tmp;
160 xfree(p->port);
161 xfree(p);
162 return 0;
165 static void dissector_init_ports_tcp(void)
167 FILE *fp;
168 char buff[512], *ptr;
169 struct port_tcp *ptcp;
170 void **pos;
171 fp = fopen("/etc/netsniff-ng/tcp.conf", "r");
172 if (!fp)
173 panic("No /etc/netsniff-ng/tcp.conf found!\n");
174 memset(buff, 0, sizeof(buff));
175 while (fgets(buff, sizeof(buff), fp) != NULL) {
176 buff[sizeof(buff) - 1] = 0;
177 ptcp = xmalloc(sizeof(*ptcp));
178 ptr = buff;
179 ptr = skips(ptr);
180 ptr = getuint(ptr, &ptcp->id);
181 ptr = skips(ptr);
182 ptr = skipchar(ptr, ',');
183 ptr = skips(ptr);
184 ptr = strtrim_right(ptr, '\n');
185 ptr = strtrim_right(ptr, ' ');
186 ptcp->port = xstrdup(ptr);
187 ptcp->next = NULL;
188 pos = insert_hash(ptcp->id, ptcp, &eth_ports_tcp);
189 if (pos) {
190 ptcp->next = *pos;
191 *pos = ptcp;
193 memset(buff, 0, sizeof(buff));
195 fclose(fp);
198 static int dissector_cleanup_ports_tcp(void *ptr)
200 struct port_tcp *tmp, *p = ptr;
201 if (!ptr)
202 return 0;
203 while ((tmp = p->next)) {
204 xfree(p->port);
205 xfree(p);
206 p = tmp;
208 xfree(p->port);
209 xfree(p);
210 return 0;
213 static void dissector_init_ether_types(void)
215 FILE *fp;
216 char buff[512], *ptr;
217 struct ether_type *et;
218 void **pos;
219 fp = fopen("/etc/netsniff-ng/ether.conf", "r");
220 if (!fp)
221 panic("No /etc/netsniff-ng/ether.conf found!\n");
222 memset(buff, 0, sizeof(buff));
223 while (fgets(buff, sizeof(buff), fp) != NULL) {
224 buff[sizeof(buff) - 1] = 0;
225 et = xmalloc(sizeof(*et));
226 ptr = buff;
227 ptr = skips(ptr);
228 ptr = getuint(ptr, &et->id);
229 ptr = skips(ptr);
230 ptr = skipchar(ptr, ',');
231 ptr = skips(ptr);
232 ptr = strtrim_right(ptr, '\n');
233 ptr = strtrim_right(ptr, ' ');
234 et->type = xstrdup(ptr);
235 et->next = NULL;
236 pos = insert_hash(et->id, et, &eth_ether_types);
237 if (pos) {
238 et->next = *pos;
239 *pos = et;
241 memset(buff, 0, sizeof(buff));
243 fclose(fp);
246 static int dissector_cleanup_ether_types(void *ptr)
248 struct ether_type *tmp, *p = ptr;
249 if (!ptr)
250 return 0;
251 while ((tmp = p->next)) {
252 xfree(p->type);
253 xfree(p);
254 p = tmp;
256 xfree(p->type);
257 xfree(p);
258 return 0;
261 void dissector_init_ethernet(int fnttype)
263 dissector_init_entry(fnttype);
264 dissector_init_layer_2(fnttype);
265 dissector_init_layer_3(fnttype);
266 dissector_init_exit(fnttype);
267 #ifdef __WITH_PROTOS
268 dissector_init_oui();
269 #endif
270 dissector_init_ports_udp();
271 dissector_init_ports_tcp();
272 dissector_init_ether_types();
275 void dissector_cleanup_ethernet(void)
277 free_hash(&eth_lay2);
278 free_hash(&eth_lay3);
279 for_each_hash(&eth_ether_types, dissector_cleanup_ether_types);
280 free_hash(&eth_ether_types);
281 for_each_hash(&eth_ports_udp, dissector_cleanup_ports_udp);
282 free_hash(&eth_ports_udp);
283 for_each_hash(&eth_ports_tcp, dissector_cleanup_ports_tcp);
284 free_hash(&eth_ports_tcp);
285 #ifdef __WITH_PROTOS
286 dissector_cleanup_oui();
287 #endif