Coverage Report

Created: 2025-02-15 06:25

/src/wireshark/epan/dissectors/packet-ieee8023.c
Line
Count
Source
1
/* packet-ieee8023.c
2
 * Routine for dissecting Ethernet packets with a length field (as opposed
3
 * to a type field).
4
 *
5
 * The name "ieee8023" is historical, dating back to when IEEE Std 802.3
6
 * had only a length field and expected all packets to have an 802.2
7
 * header following the MAC header.  Since IEEE 802.3y-1997, 802.3
8
 * supports either a type field or a length field, so it's no longer
9
 * correct to refer to "802.3" vs. "D/I/X" or vs. "Ethernet II" frames.
10
 *
11
 * Wireshark - Network traffic analyzer
12
 * By Gerald Combs <gerald@wireshark.org>
13
 * Copyright 1998 Gerald Combs
14
 *
15
 * SPDX-License-Identifier: GPL-2.0-or-later
16
 */
17
18
#include "config.h"
19
20
#include <epan/packet.h>
21
#include <epan/exceptions.h>
22
#include <epan/expert.h>
23
#include <epan/show_exception.h>
24
#include "packet-ieee8023.h"
25
#include "packet-eth.h"
26
27
void proto_reg_handoff_ieee802_3(void);
28
29
static dissector_handle_t ipx_handle;
30
static dissector_handle_t llc_handle;
31
static dissector_handle_t ccsds_handle;
32
33
void
34
dissect_802_3(volatile int length, bool is_802_2, tvbuff_t *tvb,
35
              int offset_after_length, packet_info *pinfo, proto_tree *tree,
36
              proto_tree *fh_tree, int length_id, int trailer_id, expert_field* ei_len,
37
              int fcs_len)
38
3.33k
{
39
3.33k
  proto_item *length_it;
40
3.33k
  tvbuff_t   *volatile next_tvb = NULL;
41
3.33k
  tvbuff_t   *trailer_tvb = NULL;
42
3.33k
  const char *saved_proto;
43
3.33k
  int         captured_length, reported_length;
44
45
3.33k
  length_it = proto_tree_add_uint(fh_tree, length_id, tvb,
46
3.33k
                                  offset_after_length - 2, 2, length);
47
48
  /* Get the length of the payload.
49
     If the FCS length is positive, remove the FCS.
50
     (If it's zero, there's no FCS; if it's negative, we don't know whether
51
     there's an FCS, so we'll guess based on the length of the trailer.) */
52
3.33k
  reported_length = tvb_reported_length_remaining(tvb, offset_after_length);
53
3.33k
  if (fcs_len > 0) {
54
41
    if (reported_length >= fcs_len)
55
40
      reported_length -= fcs_len;
56
41
  }
57
58
  /* Make sure the length in the 802.3 header doesn't go past the end of
59
     the payload. */
60
3.33k
  if (length > reported_length) {
61
2.92k
    length = reported_length;
62
2.92k
    expert_add_info(pinfo, length_it, ei_len);
63
2.92k
  }
64
65
  /* Give the next dissector only 'length' number of bytes. */
66
3.33k
  captured_length = tvb_captured_length_remaining(tvb, offset_after_length);
67
3.33k
  if (captured_length > length)
68
432
    captured_length = length;
69
3.33k
  next_tvb = tvb_new_subset_length_caplen(tvb, offset_after_length, captured_length, length);
70
71
  /* Dissect the payload either as IPX or as an LLC frame.
72
     Catch non-fatal exceptions, so that if the reported length
73
     of "next_tvb" was reduced by some dissector before an
74
     exception was thrown, we can still put in an item for
75
     the trailer. */
76
3.33k
  saved_proto = pinfo->current_proto;
77
3.33k
  TRY {
78
3.33k
    if (is_802_2)
79
3.14k
      call_dissector(llc_handle, next_tvb, pinfo, tree);
80
187
    else {
81
      /* Check if first three bits of payload are 0x7.
82
         If so, then payload is IPX.  If not, then it's CCSDS.
83
         Refer to packet-eth.c for setting of is_802_2 variable. */
84
187
      if (tvb_get_bits8(next_tvb, 0, 3) == 7)
85
186
        call_dissector(ipx_handle, next_tvb, pinfo, tree);
86
1
      else
87
1
        call_dissector(ccsds_handle, next_tvb, pinfo, tree);
88
187
    }
89
3.33k
  }
90
3.33k
  CATCH_NONFATAL_ERRORS {
91
    /* Somebody threw an exception that means that there was a problem
92
       dissecting the payload; that means that a dissector was found,
93
       so we don't need to dissect the payload as data or update the
94
       protocol or info columns.
95
96
       Just show the exception and then drive on to show the trailer,
97
       after noting that a dissector was found and restoring the
98
       protocol value that was in effect before we called the subdissector. */
99
1.52k
    show_exception(next_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
100
1.52k
  }
101
3.33k
  ENDTRY;
102
103
  /* Restore the protocol value, so that any exception thrown by
104
     tvb_new_subset_remaining() refers to the protocol for which
105
     this is a trailer. */
106
3.33k
  pinfo->current_proto = saved_proto;
107
108
  /* Construct a tvbuff for the trailer; if the trailer is past the
109
     end of the captured data, this will throw a BoundsError, which
110
     is what we want, as it'll report that the packet was cut short. */
111
3.33k
  trailer_tvb = tvb_new_subset_remaining(tvb, offset_after_length + length);
112
113
3.33k
  add_ethernet_trailer(pinfo, tree, fh_tree, trailer_id, tvb, trailer_tvb, fcs_len, offset_after_length);
114
3.33k
}
115
116
void
117
proto_reg_handoff_ieee802_3(void)
118
14
{
119
  /*
120
   * Get handles for the subdissectors.
121
   */
122
14
  ipx_handle = find_dissector("ipx");
123
14
  llc_handle = find_dissector("llc");
124
14
  ccsds_handle = find_dissector("ccsds");
125
14
}
126
127
/*
128
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
129
 *
130
 * Local Variables:
131
 * c-basic-offset: 2
132
 * tab-width: 8
133
 * indent-tabs-mode: nil
134
 * End:
135
 *
136
 * ex: set shiftwidth=2 tabstop=8 expandtab:
137
 * :indentSize=2:tabSize=8:noTabs=true:
138
 */