Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / file-file.c
bloba38f2f4d62f2eb667620428581b15743adbda3d9
1 /* file-file.c
3 * Top-most file dissector. Decides dissector based on Filetap Encapsulation Type.
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 2000 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 #include "config.h"
14 #ifdef _MSC_VER
15 #include <windows.h>
16 #endif
18 #include <epan/packet.h>
19 #include <epan/exceptions.h>
20 #include <epan/show_exception.h>
21 #include <epan/tap.h>
22 #include <epan/proto_data.h>
23 #include <epan/color_filters.h>
24 #include <wiretap/wtap.h>
25 #include <wsutil/str_util.h>
26 #include <wsutil/array.h>
28 #include "file-file.h"
30 void proto_register_file(void);
32 static int proto_file;
33 static int hf_file_record_number;
34 static int hf_file_record_len;
35 static int hf_file_ftap_encap;
36 static int hf_file_marked;
37 static int hf_file_ignored;
38 static int hf_file_protocols;
39 static int hf_file_num_p_prot_data;
40 static int hf_file_proto_name_and_key;
41 static int hf_file_color_filter_name;
42 static int hf_file_color_filter_text;
44 static int ett_file;
46 static int file_tap;
48 dissector_table_t file_encap_dissector_table;
51 * Routine used to register record end routine. The routine should only
52 * be registered when the dissector is used in the record, not in the
53 * proto_register_XXX function.
55 void
56 register_file_record_end_routine(packet_info *pinfo, void (*func)(void))
58 pinfo->frame_end_routines = g_slist_append(pinfo->frame_end_routines, (void *)func);
61 typedef void (*void_func_t)(void);
63 static void
64 call_file_record_end_routine(void *routine, void *dummy _U_)
66 void_func_t func = (void_func_t)routine;
67 (*func)();
70 /* XXX - "packet comment" is passed into dissector as data, but currently doesn't have a use */
71 static int
72 dissect_file_record(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data)
74 proto_item *volatile ti = NULL;
75 proto_tree *volatile fh_tree = NULL;
76 proto_tree *volatile tree;
77 proto_item *item;
78 const char *cap_plurality, *frame_plurality;
79 const color_filter_t *color_filter;
80 file_data_t *file_data = (file_data_t*)data;
82 tree=parent_tree;
84 pinfo->current_proto = "File";
86 /* if FILE is not referenced from any filters we don't need to worry about
87 generating any tree items. */
88 if(!proto_field_is_referenced(tree, proto_file)) {
89 tree=NULL;
90 } else {
91 unsigned cap_len, frame_len;
93 /* Put in frame header information. */
94 cap_len = tvb_captured_length(tvb);
95 frame_len = tvb_reported_length(tvb);
97 cap_plurality = plurality(cap_len, "", "s");
98 frame_plurality = plurality(frame_len, "", "s");
100 ti = proto_tree_add_protocol_format(tree, proto_file, tvb, 0, -1,
101 "File record %u: %u byte%s",
102 pinfo->num, frame_len, frame_plurality);
103 proto_item_append_text(ti, ", %u byte%s",
104 cap_len, cap_plurality);
106 fh_tree = proto_item_add_subtree(ti, ett_file);
108 if (pinfo->rec->rec_type == REC_TYPE_PACKET)
109 proto_tree_add_int(fh_tree, hf_file_ftap_encap, tvb, 0, 0, pinfo->rec->rec_header.packet_header.pkt_encap);
111 proto_tree_add_uint(fh_tree, hf_file_record_number, tvb, 0, 0, pinfo->num);
113 proto_tree_add_uint_format(fh_tree, hf_file_record_len, tvb,
114 0, 0, frame_len, "Record Length: %u byte%s (%u bits)",
115 frame_len, frame_plurality, frame_len * 8);
117 ti = proto_tree_add_boolean(fh_tree, hf_file_marked, tvb, 0, 0,pinfo->fd->marked);
118 proto_item_set_generated(ti);
120 ti = proto_tree_add_boolean(fh_tree, hf_file_ignored, tvb, 0, 0,pinfo->fd->ignored);
121 proto_item_set_generated(ti);
123 if(pinfo->fd->pfd != 0){
124 proto_item *ppd_item;
125 unsigned num_entries = g_slist_length(pinfo->fd->pfd);
126 unsigned i;
127 ppd_item = proto_tree_add_uint(fh_tree, hf_file_num_p_prot_data, tvb, 0, 0, num_entries);
128 proto_item_set_generated(ppd_item);
129 for(i=0; i<num_entries; i++){
130 char* str = p_get_proto_name_and_key(wmem_file_scope(), pinfo, i);
131 proto_tree_add_string_format(fh_tree, hf_file_proto_name_and_key, tvb, 0, 0, str, "%s", str);
135 #if 0
136 if (show_file_off) {
137 proto_tree_add_int64_format_value(fh_tree, hf_frame_file_off, tvb,
138 0, 0, pinfo->fd->file_off,
139 "%" PRId64 " (0x%" PRIx64 ")",
140 pinfo->fd->file_off, pinfo->fd->file_off);
142 #endif
145 if (pinfo->fd->ignored) {
146 /* Ignored package, stop handling here */
147 col_set_str(pinfo->cinfo, COL_INFO, "<Ignored>");
148 proto_tree_add_boolean_format(tree, hf_file_ignored, tvb, 0, -1, true, "This record is marked as ignored");
149 return tvb_captured_length(tvb);
152 /* Portable Exception Handling to trap Wireshark specific exceptions like BoundsError exceptions */
153 TRY {
154 #ifdef _MSC_VER
155 /* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions
156 like memory access violations.
157 (a running debugger will be called before the except part below) */
158 /* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling)
159 stack in an inconsistent state thus causing a crash at some point in the
160 handling of the exception.
161 See: https://lists.wireshark.org/archives/wireshark-dev/200704/msg00243.html
163 __try {
164 #endif
165 if (pinfo->rec->rec_type != REC_TYPE_PACKET ||
166 !dissector_try_uint(file_encap_dissector_table, pinfo->rec->rec_header.packet_header.pkt_encap,
167 tvb, pinfo, parent_tree)) {
169 col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN");
170 col_add_fstr(pinfo->cinfo, COL_INFO, "FTAP_ENCAP = %d",
171 pinfo->rec->rec_header.packet_header.pkt_encap);
172 call_data_dissector(tvb, pinfo, parent_tree);
174 #ifdef _MSC_VER
175 } __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) {
176 switch(GetExceptionCode()) {
177 case(STATUS_ACCESS_VIOLATION):
178 show_exception(tvb, pinfo, parent_tree, DissectorError,
179 "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
180 break;
181 case(STATUS_INTEGER_DIVIDE_BY_ZERO):
182 show_exception(tvb, pinfo, parent_tree, DissectorError,
183 "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
184 break;
185 case(STATUS_STACK_OVERFLOW):
186 show_exception(tvb, pinfo, parent_tree, DissectorError,
187 "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)");
188 /* XXX - this will have probably corrupted the stack,
189 which makes problems later in the exception code */
190 break;
191 /* XXX - add other hardware exception codes as required */
192 default:
193 show_exception(tvb, pinfo, parent_tree, DissectorError,
194 ws_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode()));
197 #endif
199 CATCH_BOUNDS_AND_DISSECTOR_ERRORS {
200 show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
202 ENDTRY;
204 if(proto_field_is_referenced(tree, hf_file_protocols)) {
205 wmem_strbuf_t *val = wmem_strbuf_new(pinfo->pool, "");
206 wmem_list_frame_t *frame;
207 /* skip the first entry, it's always the "frame" protocol */
208 frame = wmem_list_frame_next(wmem_list_head(pinfo->layers));
209 if (frame) {
210 wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame))));
211 frame = wmem_list_frame_next(frame);
213 while (frame) {
214 wmem_strbuf_append_c(val, ':');
215 wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame))));
216 frame = wmem_list_frame_next(frame);
218 ti = proto_tree_add_string(fh_tree, hf_file_protocols, tvb, 0, 0, wmem_strbuf_get_str(val));
219 proto_item_set_generated(ti);
222 /* Call postdissectors if we have any (while trying to avoid another
223 * TRY/CATCH)
225 if (have_postdissector()) {
226 TRY {
227 #ifdef _MSC_VER
228 /* Win32: Visual-C Structured Exception Handling (SEH)
229 to trap hardware exceptions like memory access violations */
230 /* (a running debugger will be called before the except part below) */
231 /* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling)
232 stack in an inconsistent state thus causing a crash at some point in the
233 handling of the exception.
234 See: https://lists.wireshark.org/archives/wireshark-dev/200704/msg00243.html
236 __try {
237 #endif
238 call_all_postdissectors(tvb, pinfo, parent_tree);
239 #ifdef _MSC_VER
240 } __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) {
241 switch(GetExceptionCode()) {
242 case(STATUS_ACCESS_VIOLATION):
243 show_exception(tvb, pinfo, parent_tree, DissectorError,
244 "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
245 break;
246 case(STATUS_INTEGER_DIVIDE_BY_ZERO):
247 show_exception(tvb, pinfo, parent_tree, DissectorError,
248 "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
249 break;
250 case(STATUS_STACK_OVERFLOW):
251 show_exception(tvb, pinfo, parent_tree, DissectorError,
252 "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)");
253 /* XXX - this will have probably corrupted the stack,
254 which makes problems later in the exception code */
255 break;
256 /* XXX - add other hardware exception codes as required */
257 default:
258 show_exception(tvb, pinfo, parent_tree, DissectorError,
259 ws_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode()));
262 #endif
264 CATCH_BOUNDS_AND_DISSECTOR_ERRORS {
265 show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
267 ENDTRY;
270 /* Attempt to (re-)calculate color filters (if any). */
271 if (pinfo->fd->need_colorize) {
272 color_filter = color_filters_colorize_packet(file_data->color_edt);
273 pinfo->fd->color_filter = color_filter;
274 pinfo->fd->need_colorize = 0;
275 } else {
276 color_filter = pinfo->fd->color_filter;
278 if (color_filter) {
279 pinfo->fd->color_filter = color_filter;
280 item = proto_tree_add_string(fh_tree, hf_file_color_filter_name, tvb,
281 0, 0, color_filter->filter_name);
282 proto_item_set_generated(item);
283 item = proto_tree_add_string(fh_tree, hf_file_color_filter_text, tvb,
284 0, 0, color_filter->filter_text);
285 proto_item_set_generated(item);
288 tap_queue_packet(file_tap, pinfo, NULL);
291 if (pinfo->frame_end_routines) {
292 g_slist_foreach(pinfo->frame_end_routines, &call_file_record_end_routine, NULL);
293 g_slist_free(pinfo->frame_end_routines);
294 pinfo->frame_end_routines = NULL;
297 return tvb_captured_length(tvb);
300 void
301 proto_register_file(void)
303 static hf_register_info hf[] = {
304 { &hf_file_record_number,
305 { "Record Number", "file.record_number",
306 FT_UINT32, BASE_DEC, NULL, 0x0,
307 NULL, HFILL }},
309 { &hf_file_record_len,
310 { "Record length", "file.record_len",
311 FT_UINT32, BASE_DEC, NULL, 0x0,
312 NULL, HFILL }},
313 #if 0
314 { &hf_frame_file_off,
315 { "File Offset", "file.offset",
316 FT_INT64, BASE_DEC, NULL, 0x0,
317 NULL, HFILL }},
318 #endif
319 { &hf_file_marked,
320 { "File record is marked", "file.marked",
321 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
322 "File record is marked in the GUI", HFILL }},
324 { &hf_file_ignored,
325 { "File record is ignored", "file.ignored",
326 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
327 "File record is ignored by the dissectors", HFILL }},
329 { &hf_file_protocols,
330 { "File record types in frame", "file.record_types",
331 FT_STRING, BASE_NONE, NULL, 0x0,
332 "File record types carried by this frame", HFILL }},
334 { &hf_file_color_filter_name,
335 { "Coloring Rule Name", "file.coloring_rule.name",
336 FT_STRING, BASE_NONE, NULL, 0x0,
337 "The file record matched the coloring rule with this name", HFILL }},
339 { &hf_file_color_filter_text,
340 { "Coloring Rule String", "file.coloring_rule.string",
341 FT_STRING, BASE_NONE, NULL, 0x0,
342 "The file record matched this coloring rule string", HFILL }},
344 { &hf_file_num_p_prot_data,
345 { "Number of per-record-data", "file.p_record_data",
346 FT_UINT32, BASE_DEC, NULL, 0x0,
347 NULL, HFILL }},
349 { &hf_file_proto_name_and_key,
350 { "Protocol Name and Key", "file.proto_name_and_key",
351 FT_STRING, BASE_NONE, NULL, 0x0,
352 NULL, HFILL }},
354 { &hf_file_ftap_encap,
355 { "Encapsulation type", "file.encap_type",
356 FT_INT16, BASE_DEC, NULL, 0x0,
357 NULL, HFILL }},
360 static int *ett[] = {
361 &ett_file
364 #if 0
365 module_t *file_module;
366 #endif
368 proto_file = proto_register_protocol("File", "File", "file");
369 proto_register_field_array(proto_file, hf, array_length(hf));
370 proto_register_subtree_array(ett, array_length(ett));
371 register_dissector("file",dissect_file_record,proto_file);
373 file_encap_dissector_table = register_dissector_table("ftap_encap",
374 "Filetap encapsulation type", proto_file, FT_UINT32, BASE_DEC);
376 /* You can't disable dissection of "Frame", as that would be
377 tantamount to not doing any dissection whatsoever. */
378 proto_set_cant_toggle(proto_file);
380 /* Our preferences */
381 #if 0
382 frame_module = prefs_register_protocol(proto_frame, NULL);
383 prefs_register_bool_preference(frame_module, "show_file_off",
384 "Show File Offset", "Show offset of frame in capture file", &show_file_off);
385 #endif
387 file_tap=register_tap("file");
391 * Editor modelines - https://www.wireshark.org/tools/modelines.html
393 * Local variables:
394 * c-basic-offset: 8
395 * tab-width: 8
396 * indent-tabs-mode: t
397 * End:
399 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
400 * :indentSize=8:tabSize=8:noTabs=false: