Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-user_encap.c
blob3ab88c1f9e2fa36c6d07a97d9d12c93fca3a0767
1 /* packet-user_encap.c
2 * Allow users to specify the dissectors for DLTs
3 * Luis E. Garcia Ontanon <luis@ontanon.org>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 #include "config.h"
15 #include <epan/packet.h>
16 #include <epan/expert.h>
17 #include <epan/prefs.h>
18 #include <epan/uat.h>
19 #include <epan/exported_pdu.h>
20 #include <epan/tap.h>
21 #include <wiretap/wtap.h>
23 #ifdef _MSC_VER
24 /* disable: warning C4090: 'XY' : different 'const' qualifiers */
25 #pragma warning(disable:4090)
26 #endif
28 void proto_register_user_encap(void);
29 void proto_reg_handoff_user_encap(void);
31 typedef struct _user_encap_t {
32 unsigned encap;
33 char* payload_proto_name;
34 dissector_handle_t payload_proto;
35 char* header_proto_name;
36 dissector_handle_t header_proto;
37 char* trailer_proto_name;
38 dissector_handle_t trailer_proto;
39 unsigned header_size;
40 unsigned trailer_size;
41 } user_encap_t;
43 #define ENCAP0_STR "User 0 (DLT=147)"
44 static const value_string user_dlts[] = {
45 { WTAP_ENCAP_USER0, ENCAP0_STR},
46 { WTAP_ENCAP_USER1, "User 1 (DLT=148)"},
47 { WTAP_ENCAP_USER2, "User 2 (DLT=149)"},
48 { WTAP_ENCAP_USER3, "User 3 (DLT=150)"},
49 { WTAP_ENCAP_USER4, "User 4 (DLT=151)"},
50 { WTAP_ENCAP_USER5, "User 5 (DLT=152)"},
51 { WTAP_ENCAP_USER6, "User 6 (DLT=153)"},
52 { WTAP_ENCAP_USER7, "User 7 (DLT=154)"},
53 { WTAP_ENCAP_USER8, "User 8 (DLT=155)"},
54 { WTAP_ENCAP_USER9, "User 9 (DLT=156)"},
55 { WTAP_ENCAP_USER10, "User 10 (DLT=157)"},
56 { WTAP_ENCAP_USER11, "User 11 (DLT=158)"},
57 { WTAP_ENCAP_USER12, "User 12 (DLT=159)"},
58 { WTAP_ENCAP_USER13, "User 13 (DLT=160)"},
59 { WTAP_ENCAP_USER14, "User 14 (DLT=161)"},
60 { WTAP_ENCAP_USER15, "User 15 (DLT=162)"},
61 { 0, NULL }
63 static int proto_user_encap;
65 static expert_field ei_user_encap_not_handled;
67 static user_encap_t* encaps;
68 static unsigned num_encaps;
69 static uat_t* encaps_uat;
71 static int exported_pdu_tap = -1;
73 static dissector_handle_t user_encap_handle;
76 * Use this for DLT_USER2 if we don't have an encapsulation for it.
78 static user_encap_t user2_encap = {WTAP_ENCAP_USER2, "pktap", NULL, "", NULL, "", NULL, 0, 0};
80 static void export_pdu(tvbuff_t *tvb, packet_info* pinfo, char *proto_name)
82 if (have_tap_listener(exported_pdu_tap)) {
83 static const exp_pdu_data_item_t *user_encap_exp_pdu_items[] = {
84 &exp_pdu_data_orig_frame_num,
85 NULL
88 exp_pdu_data_t *exp_pdu_data = export_pdu_create_tags(pinfo, proto_name, EXP_PDU_TAG_DISSECTOR_NAME, user_encap_exp_pdu_items);
90 exp_pdu_data->tvb_captured_length = tvb_captured_length(tvb);
91 exp_pdu_data->tvb_reported_length = tvb_reported_length(tvb);
92 exp_pdu_data->pdu_tvb = tvb;
93 tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data);
97 static int dissect_user(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_) {
98 user_encap_t* encap = NULL;
99 tvbuff_t* payload_tvb;
100 proto_item* item;
101 int len, reported_len;
102 unsigned i;
104 for (i = 0; i < num_encaps; i++) {
105 if (encaps[i].encap == pinfo->match_uint) {
106 encap = &(encaps[i]);
107 break;
111 item = proto_tree_add_item(tree,proto_user_encap,tvb,0,-1,ENC_NA);
112 if (!encap && pinfo->match_uint == WTAP_ENCAP_USER2) {
114 * Special-case DLT_USER2 - Apple hijacked it for use as DLT_PKTAP.
115 * The user hasn't assigned anything to it, so default it to
116 * the PKTAP dissector.
118 encap = &user2_encap;
120 if (!encap) {
121 char* msg = wmem_strdup_printf(pinfo->pool,
122 "User encapsulation not handled: DLT=%d, "
123 "check your Preferences->Protocols->DLT_USER",
124 pinfo->match_uint + 147 - WTAP_ENCAP_USER0);
125 proto_item_set_text(item,"%s",msg);
126 expert_add_info_format(pinfo, item, &ei_user_encap_not_handled, "%s", msg);
128 call_data_dissector(tvb, pinfo, tree);
129 return tvb_captured_length(tvb);
131 if (encap->payload_proto == NULL) {
132 char* msg = wmem_strdup_printf(pinfo->pool,
133 "User encapsulation's protocol %s not found: "
134 "DLT=%d, check your Preferences->Protocols->DLT_USER",
135 encap->payload_proto_name,
136 pinfo->match_uint + 147 - WTAP_ENCAP_USER0);
137 proto_item_set_text(item,"%s",msg);
138 expert_add_info_format(pinfo, item, &ei_user_encap_not_handled, "%s", msg);
140 call_data_dissector(tvb, pinfo, tree);
141 return tvb_captured_length(tvb);
144 proto_item_set_text(item,"DLT: %d",pinfo->match_uint + 147 - WTAP_ENCAP_USER0);
146 if (encap->header_size) {
147 tvbuff_t* hdr_tvb = tvb_new_subset_length(tvb, 0, encap->header_size);
148 export_pdu(hdr_tvb, pinfo, encap->header_proto_name);
149 call_dissector(encap->header_proto, hdr_tvb, pinfo, tree);
150 if (encap->header_proto_name) {
151 const char *proto_name = dissector_handle_get_protocol_long_name(encap->header_proto);
152 if (proto_name) {
153 proto_item_append_text(item, ", Header: %s (%s)", encap->header_proto_name, proto_name);
158 len = tvb_captured_length(tvb) - (encap->header_size + encap->trailer_size);
159 reported_len = tvb_reported_length(tvb) - (encap->header_size + encap->trailer_size);
161 payload_tvb = tvb_new_subset_length_caplen(tvb, encap->header_size, len, reported_len);
162 export_pdu(payload_tvb, pinfo, encap->payload_proto_name);
163 call_dissector(encap->payload_proto, payload_tvb, pinfo, tree);
164 if (encap->payload_proto_name) {
165 const char *proto_name = dissector_handle_get_protocol_long_name(encap->payload_proto);
166 if (proto_name) {
167 proto_item_append_text(item, ", Payload: %s (%s)", encap->payload_proto_name, proto_name);
171 if (encap->trailer_size) {
172 tvbuff_t* trailer_tvb = tvb_new_subset_length(tvb, encap->header_size + len, encap->trailer_size);
173 export_pdu(trailer_tvb, pinfo, encap->trailer_proto_name);
174 call_dissector(encap->trailer_proto, trailer_tvb, pinfo, tree);
175 if (encap->trailer_proto_name) {
176 const char *proto_name = dissector_handle_get_protocol_long_name(encap->trailer_proto);
177 if (proto_name) {
178 proto_item_append_text(item, ", Trailer: %s (%s)", encap->trailer_proto_name, proto_name);
182 return tvb_captured_length(tvb);
185 static void* user_copy_cb(void* dest, const void* orig, size_t len _U_)
187 const user_encap_t *o = (const user_encap_t *)orig;
188 user_encap_t *d = (user_encap_t *)dest;
190 d->encap = o->encap;
191 d->payload_proto_name = g_strdup(o->payload_proto_name);
192 d->payload_proto = o->payload_proto;
193 d->header_proto_name = g_strdup(o->header_proto_name);
194 d->header_proto = o->header_proto;
195 d->trailer_proto_name = g_strdup(o->trailer_proto_name);
196 d->trailer_proto = o->trailer_proto;
197 d->header_size = o->header_size;
198 d->trailer_size = o->trailer_size;
200 return d;
203 static void user_free_cb(void* record)
205 user_encap_t *u = (user_encap_t *)record;
207 g_free(u->payload_proto_name);
208 g_free(u->header_proto_name);
209 g_free(u->trailer_proto_name);
212 UAT_VS_DEF(user_encap, encap, user_encap_t, unsigned, WTAP_ENCAP_USER0, ENCAP0_STR)
213 UAT_DISSECTOR_DEF(user_encap, payload_proto, payload_proto, payload_proto_name, user_encap_t)
214 UAT_DEC_CB_DEF(user_encap, header_size, user_encap_t)
215 UAT_DISSECTOR_DEF(user_encap, header_proto, header_proto, header_proto_name, user_encap_t)
216 UAT_DEC_CB_DEF(user_encap, trailer_size, user_encap_t)
217 UAT_DISSECTOR_DEF(user_encap, trailer_proto, trailer_proto, trailer_proto_name, user_encap_t)
219 void proto_reg_handoff_user_encap(void)
221 unsigned i;
223 user2_encap.payload_proto = find_dissector("pktap");
225 for (i = WTAP_ENCAP_USER0; i <= WTAP_ENCAP_USER15; i++)
226 dissector_add_uint("wtap_encap", i, user_encap_handle);
230 void proto_register_user_encap(void)
232 module_t *module;
233 expert_module_t* expert_user_encap;
235 static uat_field_t user_flds[] = {
236 UAT_FLD_VS(user_encap,encap,"DLT",user_dlts,"The DLT"),
237 UAT_FLD_DISSECTOR(user_encap,payload_proto,"Payload dissector",
238 "Dissector to be used for the payload of this DLT"),
239 UAT_FLD_DEC(user_encap,header_size,"Header size",
240 "Size of an eventual header that precedes the actual payload, 0 means none"),
241 UAT_FLD_DISSECTOR(user_encap,header_proto,"Header dissector",
242 "Dissector to be used for the header (empty = data)"),
243 UAT_FLD_DEC(user_encap,trailer_size,"Trailer size",
244 "Size of an eventual trailer that follows the actual payload, 0 means none"),
245 UAT_FLD_DISSECTOR(user_encap,trailer_proto,"Trailer dissector",
246 "Dissector to be used for the trailer (empty = data)"),
247 UAT_END_FIELDS
250 static ei_register_info ei[] = {
251 { &ei_user_encap_not_handled, { "user_dlt.not_handled", PI_UNDECODED, PI_WARN, "Formatted text", EXPFILL }},
254 proto_user_encap = proto_register_protocol("DLT User","DLT_USER","user_dlt");
255 expert_user_encap = expert_register_protocol(proto_user_encap);
256 expert_register_field_array(expert_user_encap, ei, array_length(ei));
258 module = prefs_register_protocol(proto_user_encap, NULL);
260 encaps_uat = uat_new("User DLTs Table",
261 sizeof(user_encap_t),
262 "user_dlts",
263 true,
264 &encaps,
265 &num_encaps,
266 UAT_AFFECTS_DISSECTION, /* affects dissection of packets, but not set of named fields */
267 "ChUserDLTsSection",
268 user_copy_cb,
269 NULL,
270 user_free_cb,
271 NULL,
272 NULL,
273 user_flds );
275 prefs_register_uat_preference(module,
276 "encaps_table",
277 "Encapsulations Table",
278 "A table that enumerates the various protocols to be used against a certain user DLT",
279 encaps_uat);
282 user_encap_handle = register_dissector("user_dlt",dissect_user,proto_user_encap);
285 prefs_register_protocol_obsolete(proto_register_protocol("DLT User A","DLT_USER_A","user_dlt_a"));
286 prefs_register_protocol_obsolete(proto_register_protocol("DLT User B","DLT_USER_B","user_dlt_b"));
287 prefs_register_protocol_obsolete(proto_register_protocol("DLT User C","DLT_USER_C","user_dlt_c"));
288 prefs_register_protocol_obsolete(proto_register_protocol("DLT User D","DLT_USER_D","user_dlt_d"));
291 exported_pdu_tap = register_export_pdu_tap("DLT User");
295 * Editor modelines - https://www.wireshark.org/tools/modelines.html
297 * Local variables:
298 * c-basic-offset: 4
299 * tab-width: 8
300 * indent-tabs-mode: nil
301 * End:
303 * vi: set shiftwidth=4 tabstop=8 expandtab:
304 * :indentSize=4:tabSize=8:noTabs=true: