HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / epan / dissectors / packet-user_encap.c
blobc9a8bc0f906cb0abb9f7ed4d0c7022d47ae0f40c
1 /* packet-user_encap.c
2 * Allow users to specify the dissectors for DLTs
3 * Luis E. Garcia Ontanon <luis@ontanon.org>
5 * $Id$
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include "config.h"
28 #include <glib.h>
29 #include <epan/packet.h>
30 #include <epan/expert.h>
31 #include <epan/prefs.h>
32 #include <epan/uat.h>
33 #include <epan/wmem/wmem.h>
35 #ifdef _MSC_VER
36 /* disable: warning C4090: 'XY' : different 'const' qualifiers */
37 #pragma warning(disable:4090)
38 #endif
40 typedef struct _user_encap_t {
41 guint encap;
42 char* payload_proto_name;
43 dissector_handle_t payload_proto;
44 char* header_proto_name;
45 dissector_handle_t header_proto;
46 char* trailer_proto_name;
47 dissector_handle_t trailer_proto;
48 guint header_size;
49 guint trailer_size;
50 } user_encap_t;
52 #define ENCAP0_STR "User 0 (DLT=147)"
53 static const value_string user_dlts[] = {
54 { WTAP_ENCAP_USER0, ENCAP0_STR},
55 { WTAP_ENCAP_USER1, "User 1 (DLT=148)"},
56 { WTAP_ENCAP_USER2, "User 2 (DLT=149)"},
57 { WTAP_ENCAP_USER3, "User 3 (DLT=150)"},
58 { WTAP_ENCAP_USER4, "User 4 (DLT=151)"},
59 { WTAP_ENCAP_USER5, "User 5 (DLT=152)"},
60 { WTAP_ENCAP_USER6, "User 6 (DLT=153)"},
61 { WTAP_ENCAP_USER7, "User 7 (DLT=154)"},
62 { WTAP_ENCAP_USER8, "User 8 (DLT=155)"},
63 { WTAP_ENCAP_USER9, "User 9 (DLT=156)"},
64 { WTAP_ENCAP_USER10, "User 10 (DLT=157)"},
65 { WTAP_ENCAP_USER11, "User 11 (DLT=158)"},
66 { WTAP_ENCAP_USER12, "User 12 (DLT=159)"},
67 { WTAP_ENCAP_USER13, "User 13 (DLT=160)"},
68 { WTAP_ENCAP_USER14, "User 14 (DLT=161)"},
69 { WTAP_ENCAP_USER15, "User 15 (DLT=162)"},
70 { 0, NULL }
72 static int proto_user_encap = -1;
74 static expert_field ei_user_encap_not_handled = EI_INIT;
76 static user_encap_t* encaps = NULL;
77 static guint num_encaps = 0;
78 static uat_t* encaps_uat;
79 static dissector_handle_t data_handle;
81 static void dissect_user(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree) {
82 user_encap_t* encap = NULL;
83 tvbuff_t* payload_tvb;
84 proto_item* item;
85 gint len, reported_len;
86 guint i;
88 for (i = 0; i < num_encaps; i++) {
89 if (encaps[i].encap == pinfo->match_uint) {
90 encap = &(encaps[i]);
91 break;
95 item = proto_tree_add_item(tree,proto_user_encap,tvb,0,-1,ENC_NA);
96 if (!encap) {
97 char* msg = wmem_strdup_printf(wmem_packet_scope(),
98 "User encapsulation not handled: DLT=%d, "
99 "check your Preferences->Protocols->DLT_USER",
100 pinfo->match_uint + 147 - WTAP_ENCAP_USER0);
101 proto_item_set_text(item,"%s",msg);
102 expert_add_info_format(pinfo, item, &ei_user_encap_not_handled, "%s", msg);
104 call_dissector(data_handle, tvb, pinfo, tree);
105 return;
107 if (encap->payload_proto == NULL) {
108 char* msg = wmem_strdup_printf(wmem_packet_scope(),
109 "User encapsulation's protocol %s not found: "
110 "DLT=%d, check your Preferences->Protocols->DLT_USER",
111 encap->payload_proto_name,
112 pinfo->match_uint + 147 - WTAP_ENCAP_USER0);
113 proto_item_set_text(item,"%s",msg);
114 expert_add_info_format(pinfo, item, &ei_user_encap_not_handled, "%s", msg);
116 call_dissector(data_handle, tvb, pinfo, tree);
117 return;
120 proto_item_set_text(item,"DLT: %d",pinfo->match_uint + 147 - WTAP_ENCAP_USER0);
122 if (encap->header_size) {
123 tvbuff_t* hdr_tvb = tvb_new_subset(tvb, 0, encap->header_size, encap->header_size);
124 call_dissector(encap->header_proto, hdr_tvb, pinfo, tree);
125 if (encap->header_proto_name) {
126 const char *proto_name = dissector_handle_get_long_name(find_dissector(encap->header_proto_name));
127 if (proto_name) {
128 proto_item_append_text(item, ", Header: %s (%s)", encap->header_proto_name, proto_name);
133 len = tvb_length(tvb) - (encap->header_size + encap->trailer_size);
134 reported_len = tvb_reported_length(tvb) - (encap->header_size + encap->trailer_size);
136 payload_tvb = tvb_new_subset(tvb, encap->header_size, len, reported_len);
137 call_dissector(encap->payload_proto, payload_tvb, pinfo, tree);
138 if (encap->payload_proto_name) {
139 const char *proto_name = dissector_handle_get_long_name(find_dissector(encap->payload_proto_name));
140 if (proto_name) {
141 proto_item_append_text(item, ", Payload: %s (%s)", encap->payload_proto_name, proto_name);
145 if (encap->trailer_size) {
146 tvbuff_t* trailer_tvb = tvb_new_subset(tvb, encap->header_size + len, encap->trailer_size, encap->trailer_size);
147 call_dissector(encap->trailer_proto, trailer_tvb, pinfo, tree);
148 if (encap->trailer_proto_name) {
149 const char *proto_name = dissector_handle_get_long_name(find_dissector(encap->trailer_proto_name));
150 if (proto_name) {
151 proto_item_append_text(item, ", Trailer: %s (%s)", encap->trailer_proto_name, proto_name);
157 static void* user_copy_cb(void* dest, const void* orig, size_t len _U_)
159 const user_encap_t *o = (const user_encap_t *)orig;
160 user_encap_t *d = (user_encap_t *)dest;
162 d->payload_proto_name = g_strdup(o->payload_proto_name);
163 d->header_proto_name = g_strdup(o->header_proto_name);
164 d->trailer_proto_name = g_strdup(o->trailer_proto_name);
166 return d;
169 static void user_free_cb(void* record)
171 user_encap_t *u = (user_encap_t *)record;
173 g_free(u->payload_proto_name);
174 g_free(u->header_proto_name);
175 g_free(u->trailer_proto_name);
178 UAT_VS_DEF(user_encap, encap, user_encap_t, guint, WTAP_ENCAP_USER0, ENCAP0_STR)
179 UAT_PROTO_DEF(user_encap, payload_proto, payload_proto, payload_proto_name, user_encap_t)
180 UAT_DEC_CB_DEF(user_encap, header_size, user_encap_t)
181 UAT_DEC_CB_DEF(user_encap, trailer_size, user_encap_t)
182 UAT_PROTO_DEF(user_encap, header_proto, header_proto, header_proto_name, user_encap_t)
183 UAT_PROTO_DEF(user_encap, trailer_proto, trailer_proto, trailer_proto_name, user_encap_t)
185 void proto_reg_handoff_user_encap(void)
187 dissector_handle_t user_encap_handle;
188 guint i;
190 user_encap_handle = find_dissector("user_dlt");
191 data_handle = find_dissector("data");
193 for (i = WTAP_ENCAP_USER0 ; i <= WTAP_ENCAP_USER15; i++)
194 dissector_add_uint("wtap_encap", i, user_encap_handle);
199 void proto_register_user_encap(void)
201 module_t *module;
202 expert_module_t* expert_user_encap;
204 static uat_field_t user_flds[] = {
205 UAT_FLD_VS(user_encap,encap,"DLT",user_dlts,"The DLT"),
206 UAT_FLD_PROTO(user_encap,payload_proto,"Payload protocol",
207 "Protocol to be used for the payload of this DLT"),
208 UAT_FLD_DEC(user_encap,header_size,"Header size",
209 "Size of an eventual header that precedes the actual payload, 0 means none"),
210 UAT_FLD_PROTO(user_encap,header_proto,"Header protocol",
211 "Protocol to be used for the header (empty = data)"),
212 UAT_FLD_DEC(user_encap,trailer_size,"Trailer size",
213 "Size of an eventual trailer that follows the actual payload, 0 means none"),
214 UAT_FLD_PROTO(user_encap,trailer_proto,"Trailer protocol",
215 "Protocol to be used for the trailer (empty = data)"),
216 UAT_END_FIELDS
219 static ei_register_info ei[] = {
220 { &ei_user_encap_not_handled, { "user_dlt.not_handled", PI_UNDECODED, PI_WARN, "Formatted text", EXPFILL }},
223 proto_user_encap = proto_register_protocol("DLT User","DLT_USER","user_dlt");
224 expert_user_encap = expert_register_protocol(proto_user_encap);
225 expert_register_field_array(expert_user_encap, ei, array_length(ei));
227 module = prefs_register_protocol(proto_user_encap, NULL);
229 encaps_uat = uat_new("User DLTs Table",
230 sizeof(user_encap_t),
231 "user_dlts",
232 TRUE,
233 (void**) &encaps,
234 &num_encaps,
235 UAT_AFFECTS_DISSECTION, /* affects dissection of packets, but not set of named fields */
236 "ChUserDLTsSection",
237 user_copy_cb,
238 NULL,
239 user_free_cb,
240 NULL,
241 user_flds );
243 prefs_register_uat_preference(module,
244 "encaps_table",
245 "Encapsulations Table",
246 "A table that enumerates the various protocols to be used against a certain user DLT",
247 encaps_uat);
250 register_dissector("user_dlt",dissect_user,proto_user_encap);
253 prefs_register_protocol_obsolete(proto_register_protocol("DLT User A","DLT_USER_A","user_dlt_a"));
254 prefs_register_protocol_obsolete(proto_register_protocol("DLT User B","DLT_USER_B","user_dlt_b"));
255 prefs_register_protocol_obsolete(proto_register_protocol("DLT User C","DLT_USER_C","user_dlt_c"));
256 prefs_register_protocol_obsolete(proto_register_protocol("DLT User D","DLT_USER_D","user_dlt_d"));