proto_ipv4: don't trim length of pkt_buff
[netsniff-ng.git] / src / dissector_eth.c
blob480e65131b939dab999ec76c3e7bf0e84a0246a8
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;
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;
27 struct port_tcp {
28 unsigned int id;
29 char *port;
30 struct port_tcp *next;
33 struct port_udp {
34 unsigned int id;
35 char *port;
36 struct port_udp *next;
39 struct ether_type {
40 unsigned int id;
41 char *type;
42 struct ether_type *next;
45 /* Note: this macro only applies to the lookup_* functions here in this file,
46 * mainly to remove redundand code. */
47 #define __do_lookup_inline(id, struct_name, hash_ptr, struct_member) \
48 ({ \
49 struct struct_name *entry = lookup_hash(id, hash_ptr); \
50 while (entry && id != entry->id) \
51 entry = entry->next; \
52 (entry && id == entry->id ? entry->struct_member : "Unknown");\
55 char *lookup_port_udp(unsigned int id)
57 return __do_lookup_inline(id, port_udp, &eth_ports_udp, port);
60 char *lookup_port_tcp(unsigned int id)
62 return __do_lookup_inline(id, port_tcp, &eth_ports_tcp, port);
65 char *lookup_ether_type(unsigned int id)
67 return __do_lookup_inline(id, ether_type, &eth_ether_types, type);
70 #ifdef __WITH_PROTOS
71 static inline void dissector_init_entry(int type)
73 dissector_set_print_type(&ethernet_ops, type);
76 static inline void dissector_init_exit(int type)
78 dissector_set_print_type(&none_ops, type);
81 static void dissector_init_layer_2(int type)
83 init_hash(&eth_lay2);
84 INSERT_HASH_PROTOS(arp_ops, eth_lay2);
85 INSERT_HASH_PROTOS(vlan_ops, eth_lay2);
86 INSERT_HASH_PROTOS(ipv4_ops, eth_lay2);
87 INSERT_HASH_PROTOS(ipv6_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);
111 static void dissector_init_layer_4(int type)
113 init_hash(&eth_lay4);
114 for_each_hash_int(&eth_lay4, dissector_set_print_type, type);
116 #else
117 static inline void dissector_init_entry(int type) {}
118 static inline void dissector_init_exit(int type) {}
119 static void dissector_init_layer_2(int type) {}
120 static void dissector_init_layer_3(int type) {}
121 static void dissector_init_layer_4(int type) {}
122 #endif /* __WITH_PROTOS */
124 static void dissector_init_ports_udp(void)
126 FILE *fp;
127 char buff[512], *ptr;
128 struct port_udp *pudp;
129 void **pos;
130 fp = fopen("/etc/netsniff-ng/udp.conf", "r");
131 if (!fp)
132 panic("No /etc/netsniff-ng/udp.conf found!\n");
133 memset(buff, 0, sizeof(buff));
134 while (fgets(buff, sizeof(buff), fp) != NULL) {
135 buff[sizeof(buff) - 1] = 0;
136 pudp = xmalloc(sizeof(*pudp));
137 ptr = buff;
138 ptr = skips(ptr);
139 ptr = getuint(ptr, &pudp->id);
140 ptr = skips(ptr);
141 ptr = skipchar(ptr, ',');
142 ptr = skips(ptr);
143 ptr = strtrim_right(ptr, '\n');
144 ptr = strtrim_right(ptr, ' ');
145 pudp->port = xstrdup(ptr);
146 pudp->next = NULL;
147 pos = insert_hash(pudp->id, pudp, &eth_ports_udp);
148 if (pos) {
149 pudp->next = *pos;
150 *pos = pudp;
152 memset(buff, 0, sizeof(buff));
154 fclose(fp);
157 static int dissector_cleanup_ports_udp(void *ptr)
159 struct port_udp *tmp, *p = ptr;
160 if (!ptr)
161 return 0;
162 while ((tmp = p->next)) {
163 xfree(p->port);
164 xfree(p);
165 p = tmp;
167 xfree(p->port);
168 xfree(p);
169 return 0;
172 static void dissector_init_ports_tcp(void)
174 FILE *fp;
175 char buff[512], *ptr;
176 struct port_tcp *ptcp;
177 void **pos;
178 fp = fopen("/etc/netsniff-ng/tcp.conf", "r");
179 if (!fp)
180 panic("No /etc/netsniff-ng/tcp.conf found!\n");
181 memset(buff, 0, sizeof(buff));
182 while (fgets(buff, sizeof(buff), fp) != NULL) {
183 buff[sizeof(buff) - 1] = 0;
184 ptcp = xmalloc(sizeof(*ptcp));
185 ptr = buff;
186 ptr = skips(ptr);
187 ptr = getuint(ptr, &ptcp->id);
188 ptr = skips(ptr);
189 ptr = skipchar(ptr, ',');
190 ptr = skips(ptr);
191 ptr = strtrim_right(ptr, '\n');
192 ptr = strtrim_right(ptr, ' ');
193 ptcp->port = xstrdup(ptr);
194 ptcp->next = NULL;
195 pos = insert_hash(ptcp->id, ptcp, &eth_ports_tcp);
196 if (pos) {
197 ptcp->next = *pos;
198 *pos = ptcp;
200 memset(buff, 0, sizeof(buff));
202 fclose(fp);
205 static int dissector_cleanup_ports_tcp(void *ptr)
207 struct port_tcp *tmp, *p = ptr;
208 if (!ptr)
209 return 0;
210 while ((tmp = p->next)) {
211 xfree(p->port);
212 xfree(p);
213 p = tmp;
215 xfree(p->port);
216 xfree(p);
217 return 0;
220 static void dissector_init_ether_types(void)
222 FILE *fp;
223 char buff[512], *ptr;
224 struct ether_type *et;
225 void **pos;
226 fp = fopen("/etc/netsniff-ng/ether.conf", "r");
227 if (!fp)
228 panic("No /etc/netsniff-ng/ether.conf found!\n");
229 memset(buff, 0, sizeof(buff));
230 while (fgets(buff, sizeof(buff), fp) != NULL) {
231 buff[sizeof(buff) - 1] = 0;
232 et = xmalloc(sizeof(*et));
233 ptr = buff;
234 ptr = skips(ptr);
235 ptr = getuint(ptr, &et->id);
236 ptr = skips(ptr);
237 ptr = skipchar(ptr, ',');
238 ptr = skips(ptr);
239 ptr = strtrim_right(ptr, '\n');
240 ptr = strtrim_right(ptr, ' ');
241 et->type = xstrdup(ptr);
242 et->next = NULL;
243 pos = insert_hash(et->id, et, &eth_ether_types);
244 if (pos) {
245 et->next = *pos;
246 *pos = et;
248 memset(buff, 0, sizeof(buff));
250 fclose(fp);
253 static int dissector_cleanup_ether_types(void *ptr)
255 struct ether_type *tmp, *p = ptr;
256 if (!ptr)
257 return 0;
258 while ((tmp = p->next)) {
259 xfree(p->type);
260 xfree(p);
261 p = tmp;
263 xfree(p->type);
264 xfree(p);
265 return 0;
268 void dissector_init_ethernet(int fnttype)
270 dissector_init_entry(fnttype);
271 dissector_init_layer_2(fnttype);
272 dissector_init_layer_3(fnttype);
273 dissector_init_layer_4(fnttype);
274 dissector_init_exit(fnttype);
275 #ifdef __WITH_PROTOS
276 dissector_init_oui();
277 #endif
278 dissector_init_ports_udp();
279 dissector_init_ports_tcp();
280 dissector_init_ether_types();
283 void dissector_cleanup_ethernet(void)
285 free_hash(&eth_lay2);
286 free_hash(&eth_lay3);
287 free_hash(&eth_lay4);
288 for_each_hash(&eth_ether_types, dissector_cleanup_ether_types);
289 free_hash(&eth_ether_types);
290 for_each_hash(&eth_ports_udp, dissector_cleanup_ports_udp);
291 free_hash(&eth_ports_udp);
292 for_each_hash(&eth_ports_tcp, dissector_cleanup_ports_tcp);
293 free_hash(&eth_ports_tcp);
294 #ifdef __WITH_PROTOS
295 dissector_cleanup_oui();
296 #endif