Coverage Report

Created: 2026-05-14 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-raw.c
Line
Count
Source
1
/* packet-raw.c
2
 * Routines for raw packet disassembly
3
 *
4
 * Wireshark - Network traffic analyzer
5
 * By Gerald Combs <gerald@wireshark.org>
6
 *
7
 * This file created and by Mike Hall <mlh@io.com>
8
 * Copyright 1998
9
 *
10
 * SPDX-License-Identifier: GPL-2.0-or-later
11
 */
12
13
#include "config.h"
14
15
#include <epan/packet.h>
16
#include <epan/capture_dissectors.h>
17
#include "packet-ip.h"
18
#include "packet-ppp.h"
19
20
void proto_register_raw(void);
21
void proto_reg_handoff_raw(void);
22
23
static int proto_raw;
24
static int ett_raw;
25
26
static const unsigned char zeroes[10] = {0,0,0,0,0,0,0,0,0,0};
27
28
static dissector_handle_t raw_handle;
29
static dissector_handle_t ip_handle;
30
static dissector_handle_t ipv4_handle;
31
static dissector_handle_t ipv6_handle;
32
static dissector_handle_t ppp_hdlc_handle;
33
34
static capture_dissector_handle_t ip_cap_handle;
35
static capture_dissector_handle_t ipv6_cap_handle;
36
static capture_dissector_handle_t ppp_hdlc_cap_handle;
37
38
static bool
39
capture_raw(const unsigned char *pd, int offset _U_, int len, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header _U_)
40
0
{
41
  /* So far, the only time we get raw connection types are with Linux and
42
   * Irix PPP connections.  We can't tell what type of data is coming down
43
   * the line, so our safest bet is IP. - GCC
44
   */
45
46
  /* Currently, the Linux 2.1.xxx PPP driver passes back some of the header
47
   * sometimes.  This check should be removed when 2.2 is out.
48
   */
49
0
  if (BYTES_ARE_IN_FRAME(0,len,2) && pd[0] == 0xff && pd[1] == 0x03) {
50
0
    return call_capture_dissector(ppp_hdlc_cap_handle, pd, 0, len, cpinfo, pseudo_header);
51
0
  }
52
  /* The Linux ISDN driver sends a fake MAC address before the PPP header
53
   * on its ippp interfaces... */
54
0
  else if (BYTES_ARE_IN_FRAME(0,len,8) && pd[6] == 0xff && pd[7] == 0x03) {
55
0
    return call_capture_dissector(ppp_hdlc_cap_handle, pd, 6, len, cpinfo, pseudo_header);
56
0
  }
57
  /* ...except when it just puts out one byte before the PPP header... */
58
0
  else if (BYTES_ARE_IN_FRAME(0,len,3) && pd[1] == 0xff && pd[2] == 0x03) {
59
0
    return call_capture_dissector(ppp_hdlc_cap_handle, pd, 1, len, cpinfo, pseudo_header);
60
0
  }
61
  /* ...and if the connection is currently down, it sends 10 bytes of zeroes
62
   * instead of a fake MAC address and PPP header. */
63
0
  else if (BYTES_ARE_IN_FRAME(0,len,10) && memcmp(pd, zeroes, 10) == 0) {
64
0
    return call_capture_dissector(ip_cap_handle, pd, 10, len, cpinfo, pseudo_header);
65
0
  }
66
0
  else {
67
    /*
68
     * OK, is this IPv4 or IPv6?
69
     */
70
0
    if (BYTES_ARE_IN_FRAME(0,len,1)) {
71
0
      switch (pd[0] & 0xF0) {
72
73
0
      case 0x40:
74
        /* IPv4 */
75
0
        return call_capture_dissector(ip_cap_handle, pd, 0, len, cpinfo, pseudo_header);
76
77
#if 0
78
      case 0x60:
79
        /* IPv6 */
80
        return call_capture_dissector(ipv6_cap_handle, pd, 0, len, cpinfo, pseudo_header);
81
#endif
82
0
      }
83
0
    }
84
0
  }
85
86
0
  return false;
87
0
}
88
89
static int
90
dissect_raw(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
91
2
{
92
2
  tvbuff_t      *next_tvb;
93
94
  /* load the top pane info. This should be overwritten by
95
     the next protocol in the stack */
96
2
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "N/A");
97
2
  col_set_str(pinfo->cinfo, COL_INFO, "Raw packet data");
98
99
  /* populate a tree in the second pane with the status of the link
100
     layer (ie none) */
101
2
  proto_tree_add_item(tree, proto_raw, tvb, 0, tvb_captured_length(tvb), ENC_NA);
102
103
  /* So far, the only time we get raw connection types are with Linux and
104
   * Irix PPP connections.  We can't tell what type of data is coming down
105
   * the line, so our safest bet is IP. - GCC
106
   */
107
108
  /* Currently, the Linux 2.1.xxx PPP driver passes back some of the header
109
   * sometimes.  This check should be removed when 2.2 is out.
110
   */
111
2
  if (tvb_get_ntohs(tvb, 0) == 0xff03) {
112
0
    call_dissector(ppp_hdlc_handle, tvb, pinfo, tree);
113
0
  }
114
  /* The Linux ISDN driver sends a fake MAC address before the PPP header
115
   * on its ippp interfaces... */
116
2
  else if (tvb_get_ntohs(tvb, 6) == 0xff03) {
117
0
    next_tvb = tvb_new_subset_remaining(tvb, 6);
118
0
    call_dissector(ppp_hdlc_handle, next_tvb, pinfo, tree);
119
0
  }
120
  /* ...except when it just puts out one byte before the PPP header... */
121
2
  else if (tvb_get_ntohs(tvb, 1) == 0xff03) {
122
0
    next_tvb = tvb_new_subset_remaining(tvb, 1);
123
0
    call_dissector(ppp_hdlc_handle, next_tvb, pinfo, tree);
124
0
  }
125
  /* ...and if the connection is currently down, it sends 10 bytes of zeroes
126
   * instead of a fake MAC address and PPP header.
127
   *
128
   * XXX - in at least one capture, I've seen 10 bytes of non-zero
129
   * values before the initial 0x45 of an IP packet without options.
130
   * However, just skipping the first 10 bytes if there's a 0x4x
131
   * byte after it breaks the parsing of some other captures. */
132
2
  else if (tvb_memeql(tvb, 0, zeroes,10) == 0) {
133
0
    next_tvb = tvb_new_subset_remaining(tvb, 10);
134
0
    call_dissector(ip_handle, next_tvb, pinfo, tree);
135
0
  }
136
2
  else {
137
    /*
138
     * OK, is this IPv4 or IPv6?
139
     */
140
2
    switch (tvb_get_uint8(tvb, 0) & 0xF0) {
141
142
1
    case 0x40:
143
      /*
144
       * IPv4.
145
       *
146
       * Create a new tvbuff, so that if the dissector sets the length
147
       * (e.g., because the packet has extra stuff after the datagram),
148
       * the top-level tvbuff isn't modified and shows all the data.
149
       */
150
1
      next_tvb = tvb_new_subset_remaining(tvb, 0);
151
1
      call_dissector(ipv4_handle, next_tvb, pinfo, tree);
152
1
      break;
153
154
0
    case 0x60:
155
      /*
156
       * IPv6.
157
       *
158
       * Create a new tvbuff, so that if the dissector sets the length
159
       * (e.g., because the packet has extra stuff after the datagram),
160
       * the top-level tvbuff isn't modified and shows all the data.
161
       */
162
0
      next_tvb = tvb_new_subset_remaining(tvb, 0);
163
0
      call_dissector(ipv6_handle, next_tvb, pinfo, tree);
164
0
      break;
165
166
1
    default:
167
      /* None of the above. */
168
1
      call_data_dissector(tvb, pinfo, tree);
169
1
      break;
170
2
    }
171
2
  }
172
2
  return tvb_captured_length(tvb);
173
2
}
174
175
static int
176
dissect_raw_ip4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
177
0
{
178
0
  tvbuff_t      *next_tvb;
179
180
  /* load the top pane info. This should be overwritten by
181
     the next protocol in the stack */
182
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "N/A");
183
0
  col_set_str(pinfo->cinfo, COL_INFO, "Raw packet data");
184
185
  /* populate a tree in the second pane with the status of the link
186
     layer (ie none) */
187
0
  proto_tree_add_item(tree, proto_raw, tvb, 0, tvb_captured_length(tvb), ENC_NA);
188
  /*
189
   * OK, hand this to the IPv4 dissector.
190
   *
191
   * Create a new tvbuff, so that if the dissector sets the length
192
   * (e.g., because the packet has extra stuff after the datagram),
193
   * the top-level tvbuff isn't modified and shows all the data.
194
   */
195
0
  next_tvb = tvb_new_subset_remaining(tvb, 0);
196
0
  call_dissector(ipv4_handle, next_tvb, pinfo, tree);
197
0
  return tvb_captured_length(tvb);
198
0
}
199
200
static int
201
dissect_raw_ip6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
202
0
{
203
0
  tvbuff_t      *next_tvb;
204
205
  /* load the top pane info. This should be overwritten by
206
     the next protocol in the stack */
207
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "N/A");
208
0
  col_set_str(pinfo->cinfo, COL_INFO, "Raw packet data");
209
210
  /* populate a tree in the second pane with the status of the link
211
     layer (ie none) */
212
0
  proto_tree_add_item(tree, proto_raw, tvb, 0, tvb_captured_length(tvb), ENC_NA);
213
  /*
214
   * OK, hand this to the IPv6 dissector.
215
   *
216
   * Create a new tvbuff, so that if the dissector sets the length
217
   * (e.g., because the packet has extra stuff after the datagram),
218
   * the top-level tvbuff isn't modified and shows all the data.
219
   */
220
0
  next_tvb = tvb_new_subset_remaining(tvb, 0);
221
0
  call_dissector(ipv6_handle, next_tvb, pinfo, tree);
222
0
  return tvb_captured_length(tvb);
223
0
}
224
225
void
226
proto_register_raw(void)
227
15
{
228
15
  static int *ett[] = {
229
15
    &ett_raw,
230
15
  };
231
232
15
  proto_raw = proto_register_protocol("Raw packet data", "Raw", "raw");
233
15
  proto_register_subtree_array(ett, array_length(ett));
234
235
15
  raw_handle = register_dissector("raw_ip", dissect_raw, proto_raw);
236
15
}
237
238
void
239
proto_reg_handoff_raw(void)
240
15
{
241
15
  dissector_handle_t raw_ip4_handle;
242
15
  dissector_handle_t raw_ip6_handle;
243
15
  capture_dissector_handle_t raw_cap_handle;
244
245
  /*
246
   * Get handles for the IPv{4,6}, IPv4, IPv6, undissected-data, and
247
   * PPP-in-HDLC-like-framing dissectors.
248
   */
249
15
  ip_handle = find_dissector_add_dependency("ip", proto_raw);
250
15
  ipv4_handle = find_dissector_add_dependency("ipv4", proto_raw);
251
15
  ipv6_handle = find_dissector_add_dependency("ipv6", proto_raw);
252
15
  ppp_hdlc_handle = find_dissector_add_dependency("ppp_hdlc", proto_raw);
253
15
  dissector_add_uint("wtap_encap", WTAP_ENCAP_RAW_IP, raw_handle);
254
15
  raw_ip4_handle = create_dissector_handle(dissect_raw_ip4, proto_raw);
255
15
  dissector_add_uint("wtap_encap", WTAP_ENCAP_RAW_IP4, raw_ip4_handle);
256
15
  raw_ip6_handle = create_dissector_handle(dissect_raw_ip6, proto_raw);
257
15
  dissector_add_uint("wtap_encap", WTAP_ENCAP_RAW_IP6, raw_ip6_handle);
258
15
  raw_cap_handle = create_capture_dissector_handle(capture_raw, proto_raw);
259
15
  capture_dissector_add_uint("wtap_encap", WTAP_ENCAP_RAW_IP, raw_cap_handle);
260
261
15
  ip_cap_handle = find_capture_dissector("ip");
262
15
  ipv6_cap_handle = find_capture_dissector("ipv6");
263
15
  ppp_hdlc_cap_handle = find_capture_dissector("ppp_hdlc");
264
15
}
265
266
/*
267
 * Editor modelines
268
 *
269
 * Local Variables:
270
 * c-basic-offset: 2
271
 * tab-width: 8
272
 * indent-tabs-mode: nil
273
 * End:
274
 *
275
 * ex: set shiftwidth=2 tabstop=8 expandtab:
276
 * :indentSize=2:tabSize=8:noTabs=true:
277
 */