ifpps: Also display min hitter for IRQs
[netsniff-ng.git] / dissector_eth.c
blobb8166e471c8ef640eaa27c57985e2cac774d2aec
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2009, 2010 Daniel Borkmann.
4 * Subject to the GPL, version 2.
5 */
7 #include <stdint.h>
9 #include "hash.h"
10 #include "oui.h"
11 #include "str.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 {
26 unsigned int id;
27 char *port;
28 struct port *next;
31 #define __do_lookup_inline(id, struct_name, hash_ptr, struct_member) \
32 ({ \
33 struct struct_name *entry = lookup_hash(id, hash_ptr); \
35 while (entry && id != entry->id) \
36 entry = entry->next; \
38 (entry && id == entry->id ? entry->struct_member : 0); \
41 char *lookup_port_udp(unsigned int id)
43 return __do_lookup_inline(id, port, &eth_ports_udp, port);
46 char *lookup_port_tcp(unsigned int id)
48 return __do_lookup_inline(id, port, &eth_ports_tcp, port);
51 char *lookup_ether_type(unsigned int id)
53 return __do_lookup_inline(id, port, &eth_ether_types, port);
56 #ifdef __WITH_PROTOS
57 static inline void dissector_init_entry(int type)
59 dissector_set_print_type(&ethernet_ops, type);
62 static inline void dissector_init_exit(int type)
64 dissector_set_print_type(&none_ops, type);
67 static void dissector_init_layer_2(int type)
69 init_hash(&eth_lay2);
70 INSERT_HASH_PROTOS(arp_ops, eth_lay2);
71 INSERT_HASH_PROTOS(lldp_ops, eth_lay2);
72 INSERT_HASH_PROTOS(vlan_ops, eth_lay2);
73 INSERT_HASH_PROTOS(ipv4_ops, eth_lay2);
74 INSERT_HASH_PROTOS(ipv6_ops, eth_lay2);
75 INSERT_HASH_PROTOS(QinQ_ops, eth_lay2);
76 INSERT_HASH_PROTOS(mpls_uc_ops, eth_lay2);
77 for_each_hash_int(&eth_lay2, dissector_set_print_type, type);
80 static void dissector_init_layer_3(int type)
82 init_hash(&eth_lay3);
83 INSERT_HASH_PROTOS(icmpv4_ops, eth_lay3);
84 INSERT_HASH_PROTOS(icmpv6_ops, eth_lay3);
85 INSERT_HASH_PROTOS(igmp_ops, eth_lay3);
86 INSERT_HASH_PROTOS(ip_auth_ops, eth_lay3);
87 INSERT_HASH_PROTOS(ip_esp_ops, eth_lay3);
88 INSERT_HASH_PROTOS(ipv6_dest_opts_ops, eth_lay3);
89 INSERT_HASH_PROTOS(ipv6_fragm_ops, eth_lay3);
90 INSERT_HASH_PROTOS(ipv6_hop_by_hop_ops, eth_lay3);
91 INSERT_HASH_PROTOS(ipv6_in_ipv4_ops, eth_lay3);
92 INSERT_HASH_PROTOS(ipv6_mobility_ops, eth_lay3);
93 INSERT_HASH_PROTOS(ipv6_no_next_header_ops, eth_lay3);
94 INSERT_HASH_PROTOS(ipv6_routing_ops, eth_lay3);
95 INSERT_HASH_PROTOS(tcp_ops, eth_lay3);
96 INSERT_HASH_PROTOS(udp_ops, eth_lay3);
97 for_each_hash_int(&eth_lay3, dissector_set_print_type, type);
99 #else
100 static inline void dissector_init_entry(int type) {}
101 static inline void dissector_init_exit(int type) {}
102 static void dissector_init_layer_2(int type) {}
103 static void dissector_init_layer_3(int type) {}
104 #endif /* __WITH_PROTOS */
106 enum ports {
107 PORTS_UDP,
108 PORTS_TCP,
109 PORTS_ETHER,
112 static void dissector_init_ports(enum ports which)
114 FILE *fp;
115 char buff[128], *ptr, *file;
116 struct hash_table *table;
117 struct port *p;
118 void **pos;
120 switch (which) {
121 case PORTS_UDP:
122 file = PREFIX_STRING "/etc/netsniff-ng/udp.conf";
123 table = &eth_ports_udp;
124 break;
125 case PORTS_TCP:
126 file = PREFIX_STRING "/etc/netsniff-ng/tcp.conf";
127 table = &eth_ports_tcp;
128 break;
129 case PORTS_ETHER:
130 file = PREFIX_STRING "/etc/netsniff-ng/ether.conf";
131 table = &eth_ether_types;
132 break;
133 default:
134 bug();
137 fp = fopen(file, "r");
138 if (!fp)
139 panic("No %s found!\n", file);
141 memset(buff, 0, sizeof(buff));
143 while (fgets(buff, sizeof(buff), fp) != NULL) {
144 buff[sizeof(buff) - 1] = 0;
145 ptr = buff;
147 p = xmalloc(sizeof(*p));
148 p->id = strtol(ptr, &ptr, 0);
150 if ((ptr = strstr(buff, ", ")))
151 ptr += strlen(", ");
152 ptr = strtrim_right(ptr, '\n');
153 ptr = strtrim_right(ptr, ' ');
155 p->port = xstrdup(ptr);
156 p->next = NULL;
158 pos = insert_hash(p->id, p, table);
159 if (pos) {
160 p->next = *pos;
161 *pos = p;
164 memset(buff, 0, sizeof(buff));
167 fclose(fp);
170 static int dissector_cleanup_ports(void *ptr)
172 struct port *tmp, *p = ptr;
174 if (!ptr)
175 return 0;
177 while ((tmp = p->next)) {
178 xfree(p->port);
179 xfree(p);
180 p = tmp;
183 xfree(p->port);
184 xfree(p);
186 return 0;
189 void dissector_init_ethernet(int fnttype)
191 dissector_init_entry(fnttype);
192 dissector_init_layer_2(fnttype);
193 dissector_init_layer_3(fnttype);
194 dissector_init_exit(fnttype);
196 #ifdef __WITH_PROTOS
197 dissector_init_oui();
198 #endif
199 dissector_init_ports(PORTS_UDP);
200 dissector_init_ports(PORTS_TCP);
201 dissector_init_ports(PORTS_ETHER);
204 void dissector_cleanup_ethernet(void)
206 free_hash(&eth_lay2);
207 free_hash(&eth_lay3);
209 for_each_hash(&eth_ether_types, dissector_cleanup_ports);
210 for_each_hash(&eth_ports_udp, dissector_cleanup_ports);
211 for_each_hash(&eth_ports_tcp, dissector_cleanup_ports);
213 free_hash(&eth_ether_types);
214 free_hash(&eth_ports_udp);
215 free_hash(&eth_ports_tcp);
217 #ifdef __WITH_PROTOS
218 dissector_cleanup_oui();
219 #endif