3 * Top-most dissector. Decides dissector based on Wiretap Encapsulation Type.
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 2000 Gerald Combs
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #include <epan/packet.h>
32 #include <epan/timestamp.h>
33 #include <epan/tvbuff.h>
34 #include "packet-frame.h"
35 #include <epan/prefs.h>
37 #include <epan/expert.h>
40 #include "color_filters.h"
43 int hf_frame_arrival_time = -1;
44 static int hf_frame_time_invalid = -1;
45 static int hf_frame_time_delta = -1;
46 static int hf_frame_time_relative = -1;
47 int hf_frame_number = -1;
48 int hf_frame_packet_len = -1;
49 int hf_frame_capture_len = -1;
50 static int hf_frame_p2p_dir = -1;
51 static int hf_frame_file_off = -1;
52 static int hf_frame_marked = -1;
53 static int hf_frame_ref_time = -1;
54 static int hf_link_number = -1;
55 static int hf_frame_protocols = -1;
56 static int hf_frame_color_filter_name = -1;
57 static int hf_frame_color_filter_text = -1;
59 static int proto_short = -1;
60 int proto_malformed = -1;
61 static int proto_unreassembled = -1;
63 static gint ett_frame = -1;
65 static int frame_tap = -1;
67 static dissector_handle_t data_handle;
68 static dissector_handle_t docsis_handle;
71 static gboolean show_file_off = FALSE;
72 static gboolean force_docsis_encap;
74 static const value_string p2p_dirs[] = {
75 { P2P_DIR_SENT, "Sent" },
76 { P2P_DIR_RECV, "Received" },
80 static dissector_table_t wtap_encap_dissector_table;
82 static GSList *frame_end_routines = NULL;
85 * Routine used to register frame end routine. The routine should only
86 * be registred when the dissector is used in the frame, not in the
87 * proto_register_XXX function.
90 register_frame_end_routine(void (*func)(void))
92 frame_end_routines = g_slist_append(frame_end_routines, (gpointer)func);
95 typedef void (*void_func_t)(void);
98 call_frame_end_routine(gpointer routine, gpointer dummy _U_)
100 void_func_t func = (void_func_t)routine;
105 dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
107 proto_tree *fh_tree=NULL;
108 proto_item *volatile ti = NULL;
110 int cap_len = 0, pkt_len = 0;
115 frame_number=pinfo->fd->num; /* dummy so that the buildbot crashdumps
116 will show the packetnumber where the
121 pinfo->current_proto = "Frame";
123 if (pinfo->pseudo_header != NULL) {
124 switch (pinfo->fd->lnk_t) {
126 case WTAP_ENCAP_WFLEET_HDLC:
127 case WTAP_ENCAP_CHDLC_WITH_PHDR:
128 case WTAP_ENCAP_PPP_WITH_PHDR:
129 case WTAP_ENCAP_SDLC:
130 case WTAP_ENCAP_BLUETOOTH_H4:
131 pinfo->p2p_dir = pinfo->pseudo_header->p2p.sent ?
132 P2P_DIR_SENT : P2P_DIR_RECV;
135 case WTAP_ENCAP_LAPB:
136 case WTAP_ENCAP_FRELAY_WITH_PHDR:
138 (pinfo->pseudo_header->x25.flags & FROM_DCE) ?
139 P2P_DIR_RECV : P2P_DIR_SENT;
142 case WTAP_ENCAP_ISDN:
143 pinfo->p2p_dir = pinfo->pseudo_header->isdn.uton ?
144 P2P_DIR_SENT : P2P_DIR_RECV;
147 case WTAP_ENCAP_LINUX_LAPD:
148 pinfo->p2p_dir = (pinfo->pseudo_header->lapd.pkttype == 3 ||
149 pinfo->pseudo_header->lapd.pkttype == 4) ?
150 P2P_DIR_SENT : P2P_DIR_RECV;
153 case WTAP_ENCAP_MTP2_WITH_PHDR:
154 pinfo->p2p_dir = pinfo->pseudo_header->mtp2.sent ?
155 P2P_DIR_SENT : P2P_DIR_RECV;
156 pinfo->link_number = pinfo->pseudo_header->mtp2.link_number;
157 pinfo->annex_a_used = pinfo->pseudo_header->mtp2.annex_a_used ?
158 MTP2_ANNEX_A_USED : MTP2_ANNEX_A_NOT_USED;
164 /* Put in frame header information. */
166 cap_len = tvb_length(tvb);
167 pkt_len = tvb_reported_length(tvb);
169 ti = proto_tree_add_protocol_format(tree, proto_frame, tvb, 0, -1,
170 "Frame %u (%u bytes on wire, %u bytes captured)", pinfo->fd->num, pkt_len, cap_len);
172 fh_tree = proto_item_add_subtree(ti, ett_frame);
175 /* if FRAME is not referenced from any filters we dont need to worry about
176 generating any tree items. We must do this after we created the actual
177 protocol above so that proto hier stat still works though.
179 if(!proto_field_is_referenced(tree, proto_frame)){
186 ts = pinfo->fd->abs_ts;
188 proto_tree_add_time(fh_tree, hf_frame_arrival_time, tvb,
190 if(ts.nsecs < 0 || ts.nsecs >= 1000000000) {
191 item = proto_tree_add_none_format(fh_tree, hf_frame_time_invalid, tvb,
192 0, 0, "Arrival Time: Fractional second %09ld is invalid, the valid range is 0-1000000000", (long) ts.nsecs);
193 PROTO_ITEM_SET_GENERATED(item);
194 expert_add_info_format(pinfo, item, PI_MALFORMED, PI_WARN, "Arrival Time: Fractional second out of range (0-1000000000)");
197 ts = pinfo->fd->del_ts;
199 item = proto_tree_add_time(fh_tree, hf_frame_time_delta, tvb,
201 PROTO_ITEM_SET_GENERATED(item);
203 ts = pinfo->fd->rel_ts;
205 item = proto_tree_add_time(fh_tree, hf_frame_time_relative, tvb,
207 PROTO_ITEM_SET_GENERATED(item);
209 proto_tree_add_uint(fh_tree, hf_frame_number, tvb,
210 0, 0, pinfo->fd->num);
212 proto_tree_add_uint_format(fh_tree, hf_frame_packet_len, tvb,
213 0, 0, pkt_len, "Packet Length: %d byte%s", pkt_len,
214 plurality(pkt_len, "", "s"));
216 proto_tree_add_uint_format(fh_tree, hf_frame_capture_len, tvb,
217 0, 0, cap_len, "Capture Length: %d byte%s", cap_len,
218 plurality(cap_len, "", "s"));
220 /* we are going to be using proto_item_append_string() on
221 * hf_frame_protocols, and we must therefore disable the
222 * TRY_TO_FAKE_THIS_ITEM() optimisation for the tree by
223 * setting it as visible.
225 * See proto.h for details.
227 PTREE_DATA(fh_tree)->visible=1;
229 if(pinfo->fd->flags.ref_time){
230 ti = proto_tree_add_item(fh_tree, hf_frame_ref_time, tvb, 0, 0, FALSE);
231 PROTO_ITEM_SET_GENERATED(ti);
234 ti = proto_tree_add_boolean(fh_tree, hf_frame_marked, tvb, 0, 0,pinfo->fd->flags.marked);
235 PROTO_ITEM_SET_GENERATED(ti);
237 ti = proto_tree_add_string(fh_tree, hf_frame_protocols, tvb,
239 PROTO_ITEM_SET_GENERATED(ti);
240 pinfo->layer_names = g_string_new("");
242 /* Check for existences of P2P pseudo header */
243 if (pinfo->p2p_dir != P2P_DIR_UNKNOWN) {
244 proto_tree_add_uint(fh_tree, hf_frame_p2p_dir, tvb,
245 0, 0, pinfo->p2p_dir);
248 /* Check for existences of MTP2 link number */
249 if ((pinfo->pseudo_header != NULL ) && (pinfo->fd->lnk_t == WTAP_ENCAP_MTP2_WITH_PHDR)) {
250 proto_tree_add_uint(fh_tree, hf_link_number, tvb,
251 0, 0, pinfo->link_number);
255 proto_tree_add_int_format(fh_tree, hf_frame_file_off, tvb,
256 0, 0, pinfo->fd->file_off,
257 "File Offset: %ld (0x%lx)",
258 pinfo->fd->file_off, pinfo->fd->file_off);
261 if(pinfo->fd->color_filter != NULL) {
262 color_filter_t *color_filter = pinfo->fd->color_filter;
263 item = proto_tree_add_string(fh_tree, hf_frame_color_filter_name, tvb,
264 0, 0, color_filter->filter_name);
265 PROTO_ITEM_SET_GENERATED(item);
266 item = proto_tree_add_string(fh_tree, hf_frame_color_filter_text, tvb,
267 0, 0, color_filter->filter_text);
268 PROTO_ITEM_SET_GENERATED(item);
271 if(pinfo->fd->abs_ts.nsecs < 0 || pinfo->fd->abs_ts.nsecs >= 1000000000) {
272 expert_add_info_format(pinfo, NULL, PI_MALFORMED, PI_WARN, "Arrival Time: Fractional second out of range (0-1000000000)");
276 /* Portable Exception Handling to trap Wireshark specific exceptions like BoundsError exceptions */
279 /* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions like memory access violations */
280 /* (a running debugger will be called before the except part below) */
283 if ((force_docsis_encap) && (docsis_handle)) {
284 call_dissector(docsis_handle, tvb, pinfo, parent_tree);
286 if (!dissector_try_port(wtap_encap_dissector_table, pinfo->fd->lnk_t,
287 tvb, pinfo, parent_tree)) {
289 if (check_col(pinfo->cinfo, COL_PROTOCOL))
290 col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN");
291 if (check_col(pinfo->cinfo, COL_INFO))
292 col_add_fstr(pinfo->cinfo, COL_INFO, "WTAP_ENCAP = %u",
294 call_dissector(data_handle,tvb, pinfo, parent_tree);
298 } __except(TRUE /* handle all exceptions */) {
299 switch(GetExceptionCode()) {
300 case(STATUS_ACCESS_VIOLATION):
301 show_exception(tvb, pinfo, parent_tree, DissectorError,
302 "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
304 case(STATUS_INTEGER_DIVIDE_BY_ZERO):
305 show_exception(tvb, pinfo, parent_tree, DissectorError,
306 "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
308 /* XXX - add other hardware exception codes as required */
310 show_exception(tvb, pinfo, parent_tree, DissectorError,
311 g_strdup_printf("dissector caused an unknown exception: %u", GetExceptionCode()));
317 show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
322 proto_item_append_string(ti, pinfo->layer_names->str);
323 g_string_free(pinfo->layer_names, TRUE);
324 pinfo->layer_names = NULL;
327 call_all_postdissectors(tvb,pinfo,parent_tree);
329 tap_queue_packet(frame_tap, pinfo, NULL);
332 if (frame_end_routines) {
333 g_slist_foreach(frame_end_routines, &call_frame_end_routine, NULL);
334 g_slist_free(frame_end_routines);
335 frame_end_routines = NULL;
340 show_exception(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
341 unsigned long exception, const char *exception_message)
343 static const char dissector_error_nomsg[] =
344 "Dissector writer didn't bother saying what the error was";
350 case ScsiBoundsError:
351 if (check_col(pinfo->cinfo, COL_INFO))
352 col_append_str(pinfo->cinfo, COL_INFO, "[SCSI transfer limited due to allocation_length too small]");
353 /*item =*/ proto_tree_add_protocol_format(tree, proto_short, tvb, 0, 0,
354 "SCSI transfer limited due to allocation_length too small: %s truncated]", pinfo->current_proto);
355 /* Don't record ScsiBoundsError exceptions as expert events - they merely
356 * reflect a normal SCSI condition.
357 * (any case where it's caused by something else is a bug). */
358 /* expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "Packet size limited");*/
362 if (check_col(pinfo->cinfo, COL_INFO))
363 col_append_str(pinfo->cinfo, COL_INFO, "[Packet size limited during capture]");
364 /*item =*/ proto_tree_add_protocol_format(tree, proto_short, tvb, 0, 0,
365 "[Packet size limited during capture: %s truncated]", pinfo->current_proto);
366 /* Don't record BoundsError exceptions as expert events - they merely
367 * reflect a capture done with a snapshot length too short to capture
369 * (any case where it's caused by something else is a bug). */
370 /* expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "Packet size limited");*/
373 case ReportedBoundsError:
374 show_reported_bounds_error(tvb, pinfo, tree);
378 if (check_col(pinfo->cinfo, COL_INFO))
379 col_append_fstr(pinfo->cinfo, COL_INFO,
380 "[Dissector bug, protocol %s: %s]",
381 pinfo->current_proto,
382 exception_message == NULL ?
383 dissector_error_nomsg : exception_message);
384 item = proto_tree_add_protocol_format(tree, proto_malformed, tvb, 0, 0,
385 "[Dissector bug, protocol %s: %s]",
386 pinfo->current_proto,
387 exception_message == NULL ?
388 dissector_error_nomsg : exception_message);
389 g_warning("Dissector bug, protocol %s, in packet %u: %s",
390 pinfo->current_proto, pinfo->fd->num,
391 exception_message == NULL ?
392 dissector_error_nomsg : exception_message);
393 expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR,
395 exception_message == NULL ?
396 dissector_error_nomsg : exception_message);
400 /* XXX - we want to know, if an unknown exception passed until here, don't we? */
401 g_assert_not_reached();
406 show_reported_bounds_error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
410 if (pinfo->fragmented) {
412 * We were dissecting an unreassembled fragmented
413 * packet when the exception was thrown, so the
414 * problem isn't that the dissector expected
415 * something but it wasn't in the packet, the
416 * problem is that the dissector expected something
417 * but it wasn't in the fragment we dissected.
419 if (check_col(pinfo->cinfo, COL_INFO))
420 col_append_fstr(pinfo->cinfo, COL_INFO,
421 "[Unreassembled Packet%s]",
422 pinfo->noreassembly_reason);
423 item = proto_tree_add_protocol_format(tree, proto_unreassembled,
424 tvb, 0, 0, "[Unreassembled Packet%s: %s]",
425 pinfo->noreassembly_reason, pinfo->current_proto);
426 expert_add_info_format(pinfo, item, PI_REASSEMBLE, PI_WARN, "Unreassembled Packet (Exception occured)");
428 if (check_col(pinfo->cinfo, COL_INFO))
429 col_append_str(pinfo->cinfo, COL_INFO,
430 "[Malformed Packet]");
431 item = proto_tree_add_protocol_format(tree, proto_malformed,
432 tvb, 0, 0, "[Malformed Packet: %s]", pinfo->current_proto);
433 expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "Malformed Packet (Exception occured)");
438 proto_register_frame(void)
440 static hf_register_info hf[] = {
441 { &hf_frame_arrival_time,
442 { "Arrival Time", "frame.time", FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x0,
443 "Absolute time when this frame was captured", HFILL }},
445 { &hf_frame_time_invalid,
446 { "Arrival Timestamp invalid", "frame.time_invalid", FT_NONE, BASE_NONE, NULL, 0x0,
447 "The timestamp from the capture is out of the valid range", HFILL }},
449 { &hf_frame_time_delta,
450 { "Time delta from previous packet", "frame.time_delta", FT_RELATIVE_TIME, BASE_NONE, NULL,
452 "Time delta since previous displayed frame", HFILL }},
454 { &hf_frame_time_relative,
455 { "Time since reference or first frame", "frame.time_relative", FT_RELATIVE_TIME, BASE_NONE, NULL,
457 "Time relative to time reference or first frame", HFILL }},
460 { "Frame Number", "frame.number", FT_UINT32, BASE_DEC, NULL, 0x0,
463 { &hf_frame_packet_len,
464 { "Frame length on the wire", "frame.pkt_len", FT_UINT32, BASE_DEC, NULL, 0x0,
467 { &hf_frame_capture_len,
468 { "Frame length stored into the capture file", "frame.cap_len", FT_UINT32, BASE_DEC, NULL, 0x0,
472 { "Point-to-Point Direction", "frame.p2p_dir", FT_UINT8, BASE_DEC, VALS(p2p_dirs), 0x0,
476 { "Link Number", "frame.link_nr", FT_UINT16, BASE_DEC, NULL, 0x0,
479 { &hf_frame_file_off,
480 { "File Offset", "frame.file_off", FT_INT32, BASE_DEC, NULL, 0x0,
484 { "Frame is marked", "frame.marked", FT_BOOLEAN, 8, NULL, 0x0,
485 "Frame is marked in the GUI", HFILL }},
487 { &hf_frame_ref_time,
488 { "This is a Time Reference frame", "frame.ref_time", FT_NONE, 0, NULL, 0x0,
489 "This frame is a Time Reference frame", HFILL }},
491 { &hf_frame_protocols,
492 { "Protocols in frame", "frame.protocols", FT_STRING, 0, NULL, 0x0,
493 "Protocols carried by this frame", HFILL }},
495 { &hf_frame_color_filter_name,
496 { "Coloring Rule Name", "frame.coloring_rule.name", FT_STRING, 0, NULL, 0x0,
497 "The frame matched the coloring rule with this name", HFILL }},
498 { &hf_frame_color_filter_text,
499 { "Coloring Rule String", "frame.coloring_rule.string", FT_STRING, 0, NULL, 0x0,
500 "The frame matched this coloring rule string", HFILL }},
502 static gint *ett[] = {
505 module_t *frame_module;
507 wtap_encap_dissector_table = register_dissector_table("wtap_encap",
508 "Wiretap encapsulation type", FT_UINT32, BASE_DEC);
510 proto_frame = proto_register_protocol("Frame", "Frame", "frame");
511 proto_register_field_array(proto_frame, hf, array_length(hf));
512 proto_register_subtree_array(ett, array_length(ett));
513 register_dissector("frame",dissect_frame,proto_frame);
515 /* You can't disable dissection of "Frame", as that would be
516 tantamount to not doing any dissection whatsoever. */
517 proto_set_cant_toggle(proto_frame);
519 proto_short = proto_register_protocol("Short Frame", "Short frame", "short");
520 proto_malformed = proto_register_protocol("Malformed Packet",
521 "Malformed packet", "malformed");
522 proto_unreassembled = proto_register_protocol(
523 "Unreassembled Fragmented Packet",
524 "Unreassembled fragmented packet", "unreassembled");
526 /* "Short Frame", "Malformed Packet", and "Unreassembled Fragmented
527 Packet" aren't really protocols, they're error indications;
528 disabling them makes no sense. */
529 proto_set_cant_toggle(proto_short);
530 proto_set_cant_toggle(proto_malformed);
531 proto_set_cant_toggle(proto_unreassembled);
533 /* Our preferences */
534 frame_module = prefs_register_protocol(proto_frame, NULL);
535 prefs_register_bool_preference(frame_module, "show_file_off",
536 "Show File Offset", "Show File Offset", &show_file_off);
537 prefs_register_bool_preference(frame_module, "force_docsis_encap",
538 "Treat all frames as DOCSIS frames", "Treat all frames as DOCSIS Frames", &force_docsis_encap);
540 frame_tap=register_tap("frame");
544 proto_reg_handoff_frame(void)
546 data_handle = find_dissector("data");
547 docsis_handle = find_dissector("docsis");