Coverage Report

Created: 2025-02-15 06:25

/src/wireshark/epan/dissectors/packet-null.c
Line
Count
Source (jump to first uncovered line)
1
/* packet-null.c
2
 * Routines for null packet disassembly
3
 *
4
 * Wireshark - Network traffic analyzer
5
 * By Gerald Combs <gerald@wireshark.org>
6
 *
7
 * This file created 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 <wsutil/pint.h>
16
17
#include <epan/packet.h>
18
#include <epan/capture_dissectors.h>
19
#include "packet-ip.h"
20
#include "packet-ppp.h"
21
#include <epan/etypes.h>
22
#include <epan/aftypes.h>
23
24
void proto_register_null(void);
25
void proto_reg_handoff_null(void);
26
27
static dissector_table_t null_dissector_table;
28
static dissector_table_t ethertype_dissector_table;
29
30
/* protocols and header fields */
31
static int proto_null;
32
static int hf_null_etype;
33
static int hf_null_family;
34
35
static int ett_null;
36
37
/* Null/loopback structs and definitions */
38
39
/* Family values. */
40
static const value_string family_vals[] = {
41
  {BSD_AF_INET,          "IP"             },
42
  {BSD_AF_ISO,           "OSI"            },
43
  {BSD_AF_APPLETALK,     "Appletalk"      },
44
  {BSD_AF_IPX,           "Netware IPX/SPX"},
45
  {BSD_AF_INET6_BSD,     "IPv6"           },
46
  {BSD_AF_INET6_FREEBSD, "IPv6"           },
47
  {BSD_AF_INET6_DARWIN,  "IPv6"           },
48
  {0,                    NULL             }
49
};
50
51
static dissector_handle_t null_handle, loop_handle;
52
static capture_dissector_handle_t null_cap_handle;
53
54
static dissector_handle_t ppp_hdlc_handle;
55
static capture_dissector_handle_t ppp_hdlc_cap_handle;
56
57
static bool
58
capture_null( const unsigned char *pd, int offset _U_, int len, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header _U_ )
59
0
{
60
0
  uint32_t null_header;
61
62
  /*
63
   * BSD drivers that use DLT_NULL - including the FreeBSD 3.2 ISDN-for-BSD
64
   * drivers, as well as the 4.4-Lite and FreeBSD loopback drivers -
65
   * stuff the AF_ value for the protocol, in *host* byte order, in the
66
   * first four bytes.
67
   *
68
   * However, the IRIX and UNICOS/mp snoop socket mechanism supplies,
69
   * on loopback devices, a 4-byte header that has a 2 byte (big-endian)
70
   * AF_ value and 2 bytes of 0, so it's
71
   *
72
   *    0000AAAA
73
   *
74
   * when read on a little-endian machine and
75
   *
76
   *    AAAA0000
77
   *
78
   * when read on a big-endian machine.  The current CVS version of libpcap
79
   * compensates for this by converting it to standard 4-byte format before
80
   * processing the packet, but snoop captures from IRIX or UNICOS/mp
81
   * have the 2-byte+2-byte header, as might tcpdump or libpcap captures
82
   * with older versions of libpcap.
83
   *
84
   * AF_ values are small integers, and probably fit in 8 bits (current
85
   * values on the BSDs do), and have their upper 24 bits zero.
86
   * This means that, in practice, if you look at the header as a 32-bit
87
   * integer in host byte order:
88
   *
89
   *    on a little-endian machine:
90
   *
91
   *            a little-endian DLT_NULL header looks like
92
   *
93
   *                    000000AA
94
   *
95
   *            a big-endian DLT_NULL header, or a DLT_LOOP header, looks
96
   *            like
97
   *
98
   *                    AA000000
99
   *
100
   *            an IRIX or UNICOS/mp DLT_NULL header looks like
101
   *
102
   *                    0000AA00
103
   *
104
   *    on a big-endian machine:
105
   *
106
   *            a big-endian DLT_NULL header, or a DLT_LOOP header, looks
107
   *            like
108
   *
109
   *                    000000AA
110
   *
111
   *            a little-endian DLT_NULL header looks like
112
   *
113
   *                    AA000000
114
   *
115
   *            an IRIX or UNICOS/mp DLT_NULL header looks like
116
   *
117
   *                    00AA0000
118
   *
119
   * However, according to Gerald Combs, a FreeBSD ISDN PPP dump that
120
   * Andreas Klemm sent to wireshark-dev has a packet type of DLT_NULL,
121
   * and the family bits look like PPP's protocol field.  (Was this an
122
   * older, or different, ISDN driver?)  Looking at what appears to be
123
   * that capture file, it appears that it's using PPP in HDLC framing,
124
   * RFC 1549, wherein the first two octets of the frame are 0xFF
125
   * (address) and 0x03 (control), so the header bytes are, in order:
126
   *
127
   *    0xFF
128
   *    0x03
129
   *    high-order byte of a PPP protocol field
130
   *    low-order byte of a PPP protocol field
131
   *
132
   * If we treat that as a 32-bit host-byte-order value, it looks like
133
   *
134
   *    PPPP03FF
135
   *
136
   * where PPPP is a byte-swapped PPP protocol type if we read it on
137
   * a little-endian machine and
138
   *
139
   *    FF03PPPP
140
   *
141
   * where PPPP is a PPP protocol type if we read it on a big-endian
142
   * machine.  0x0000 does not appear to be a valid PPP protocol type
143
   * value, so at least one of those hex digits is guaranteed not to
144
   * be 0.
145
   *
146
   * Old versions of libpcap for Linux used DLT_NULL for loopback devices,
147
   * but not any other devices.  (Current versions use DLT_EN10MB for it.)
148
   * The Linux loopback driver puts an *Ethernet* header at the beginning
149
   * of loopback packets, with fake source and destination addresses and
150
   * the appropriate Ethernet type value; however, those older versions of
151
   * libpcap for Linux compensated for this by skipping the source and
152
   * destination MAC addresses, replacing them with 2 bytes of 0.
153
   * This means that if we're reading the capture on a little-endian
154
   * machine, the header, treated as a 32-bit integer, looks like
155
   *
156
   *    EEEE0000
157
   *
158
   * where EEEE is a byte-swapped Ethernet type, and if we're reading it
159
   * on a big-endian machine, it looks like
160
   *
161
   *    0000EEEE
162
   *
163
   * where EEEE is an Ethernet type.
164
   *
165
   * If the first 2 bytes of the header are FF 03:
166
   *
167
   *    it can't be a big-endian BSD DLT_NULL header, or a DLT_LOOP
168
   *    header, as AF_ values are small so the first 2 bytes of the
169
   *    header would be 0;
170
   *
171
   *    it can't be a little-endian BSD DLT_NULL header, as the
172
   *    resulting AF_ value would be >= 0x03FF, which is too big
173
   *    for an AF_ value;
174
   *
175
   *    it can't be an IRIX or UNICOS/mp DLT_NULL header, as the
176
   *    resulting AF_ value with be 0x03FF.
177
   *
178
   * So the first thing we do is check the first two bytes of the
179
   * header; if it's FF 03, we treat the packet as a PPP frame.
180
   *
181
   * Otherwise, if the upper 16 bits are non-zero, either:
182
   *
183
   *    it's a BSD DLT_NULL header whose AF_ value is not in our
184
   *    byte order;
185
   *
186
   *    it's an IRIX or UNICOS/mp DLT_NULL header being read on
187
   *    a big-endian machine;
188
   *
189
   *    it's a Linux DLT_NULL header being read on a little-endian
190
   *    machine.
191
   *
192
   * In all those cases except for the IRIX or UNICOS/mp DLT_NULL header,
193
   * we should byte-swap it (if it's a Linux DLT_NULL header, that'll
194
   * put the Ethernet type in the right byte order).  In the case
195
   * of the IRIX or UNICOS/mp DLT_NULL header, we should just get
196
   * the upper 16 bits as an AF_ value.
197
   *
198
   * If it's a BSD DLT_NULL header whose AF_ value is not in our byte
199
   * order, then the upper 2 hex digits would be non-zero and the next
200
   * 2 hex digits down would be zero, as AF_ values fit in 8 bits, and
201
   * the upper 2 hex digits are the *lower* 8 bits of the value.
202
   *
203
   * If it's an IRIX or UNICOS/mp DLT_NULL header, the upper 2 hex digits
204
   * would be zero and the next 2 hex digits down would be non-zero, as
205
   * the upper 16 bits are a big-endian AF_ value.  Furthermore, the
206
   * next 2 hex digits down are likely to be < 0x60, as 0x60 is 96,
207
   * and, so far, we're far from requiring AF_ values that high.
208
   *
209
   * If it's a Linux DLT_NULL header, the third hex digit from the top
210
   * will be >= 6, as Ethernet types are >= 1536, or 0x0600, and
211
   * it's byte-swapped, so the second 2 hex digits from the top are
212
   * >= 0x60.
213
   *
214
   * So, if the upper 16 bits are non-zero:
215
   *
216
   *    if the upper 2 hex digits are 0 and the next 2 hex digits are
217
   *    in the range 0x00-0x5F, we treat it as a big-endian IRIX or
218
   *    UNICOS/mp DLT_NULL header;
219
   *
220
   *    otherwise, we byte-swap it and do the next stage.
221
   *
222
   * If the upper 16 bits are zero, either:
223
   *
224
   *    it's a BSD DLT_NULL header whose AF_ value is in our byte
225
   *    order;
226
   *
227
   *    it's an IRIX or UNICOS/mp DLT_NULL header being read on
228
   *    a little-endian machine;
229
   *
230
   *    it's a Linux DLT_NULL header being read on a big-endian
231
   *    machine.
232
   *
233
   * In all of those cases except for the IRIX or UNICOS/mp DLT_NULL header,
234
   * we should *not* byte-swap it.  In the case of the IRIX or UNICOS/mp
235
   * DLT_NULL header, we should extract the AF_ value and byte-swap it.
236
   *
237
   * If it's a BSD DLT_NULL header whose AF_ value is in our byte order,
238
   * the upper 6 hex digits would all be zero.
239
   *
240
   * If it's an IRIX or UNICOS/mp DLT_NULL header, the upper 4 hex
241
   * digits would be zero and the next 2 hex digits would not be zero.
242
   * Furthermore, the third hex digit from the bottom would be <
243
   */
244
0
  if (!BYTES_ARE_IN_FRAME(0, len, 2))
245
0
    return false;
246
247
0
  if (pd[0] == 0xFF && pd[1] == 0x03) {
248
    /*
249
     * Hand it to PPP.
250
     */
251
0
    return call_capture_dissector(ppp_hdlc_cap_handle, pd, 0, len, cpinfo, pseudo_header);
252
0
  } else {
253
    /*
254
     * Treat it as a normal DLT_NULL header.
255
     */
256
0
    if (!BYTES_ARE_IN_FRAME(0, len, (int)sizeof(null_header)))
257
0
      return false;
258
259
0
    memcpy((char *)&null_header, (const char *)&pd[0], sizeof(null_header));
260
261
0
    if ((null_header & 0xFFFF0000) != 0) {
262
      /*
263
       * It is possible that the AF_ type was only a 16 bit value.
264
       * IRIX and UNICOS/mp loopback snoop use a 4 byte header with
265
       * AF_ type in the first 2 bytes!
266
       * BSD AF_ types will always have the upper 8 bits as 0.
267
       */
268
0
      if ((null_header & 0xFF000000) == 0 &&
269
0
          (null_header & 0x00FF0000) < 0x00060000) {
270
        /*
271
         * Looks like a IRIX or UNICOS/mp loopback header, in the
272
         * correct byte order.  Set the null header value to the
273
         * AF_ type, which is in the upper 16 bits of "null_header".
274
         */
275
0
        null_header >>= 16;
276
0
      } else {
277
        /* Byte-swap it. */
278
0
        null_header = GUINT32_SWAP_LE_BE(null_header);
279
0
      }
280
0
    } else {
281
      /*
282
       * Check for an IRIX or UNICOS/mp snoop header.
283
       */
284
0
      if ((null_header & 0x000000FF) == 0 &&
285
0
          (null_header & 0x0000FF00) < 0x00000600) {
286
        /*
287
         * Looks like a IRIX or UNICOS/mp loopback header, in the
288
         * wrong byte order.  Set the null header value to the AF_
289
         * type; that's in the lower 16 bits of "null_header", but
290
         * is byte-swapped.
291
         */
292
0
        null_header = GUINT16_SWAP_LE_BE(null_header & 0xFFFF);
293
0
      }
294
0
    }
295
296
    /*
297
     * The null header value must be greater than the IEEE 802.3 maximum
298
     * frame length to be a valid Ethernet type; if it is, hand it
299
     * to "capture_ethertype()", otherwise treat it as a BSD AF_type (we
300
     * wire in the values of the BSD AF_ types, because the values
301
     * in the file will be BSD values, and the OS on which
302
     * we're building this might not have the same values or
303
     * might not have them defined at all; XXX - what if different
304
     * BSD derivatives have different values?).
305
     */
306
0
    if (null_header > IEEE_802_3_MAX_LEN)
307
0
      return try_capture_dissector("ethertype", null_header, pd, 4, len, cpinfo, pseudo_header);
308
0
    else
309
0
      return try_capture_dissector("null.bsd", null_header, pd, 4, len, cpinfo, pseudo_header);
310
0
  }
311
312
0
  return false;
313
0
}
314
315
static int
316
dissect_null(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
317
9
{
318
9
  uint32_t      null_header;
319
9
  proto_tree    *fh_tree;
320
9
  proto_item    *ti;
321
9
  tvbuff_t      *next_tvb;
322
323
  /*
324
   * See comment in "capture_null()" for an explanation of what we're
325
   * doing.
326
   */
327
9
  if (tvb_get_ntohs(tvb, 0) == 0xFF03) {
328
    /*
329
     * Hand it to PPP.
330
     */
331
0
    call_dissector(ppp_hdlc_handle, tvb, pinfo, tree);
332
9
  } else {
333
334
    /* load the top pane info. This should be overwritten by
335
       the next protocol in the stack */
336
9
    col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "N/A");
337
9
    col_set_str(pinfo->cinfo, COL_RES_DL_DST, "N/A");
338
9
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "N/A");
339
9
    col_set_str(pinfo->cinfo, COL_INFO, "Null/Loopback");
340
341
    /*
342
     * Treat it as a normal DLT_NULL header.  Fetch it in host
343
     * byte order.
344
     */
345
9
    null_header = tvb_get_h_uint32(tvb, 0);
346
347
9
    if ((null_header & 0xFFFF0000) != 0) {
348
      /*
349
       * It is possible that the AF_ type was only a 16 bit value.
350
       * IRIX and UNICOS/mp loopback snoop use a 4 byte header with
351
       * AF_ type in the first 2 bytes!
352
       * BSD AF_ types will always have the upper 8 bits as 0.
353
       */
354
5
      if ((null_header & 0xFF000000) == 0 &&
355
5
          (null_header & 0x00FF0000) < 0x00060000) {
356
        /*
357
         * Looks like a IRIX or UNICOS/mp loopback header, in the
358
         * correct byte order.  Set the null header value to the
359
         * AF_ type, which is in the upper 16 bits of "null_header".
360
         */
361
0
        null_header >>= 16;
362
5
      } else {
363
        /* Byte-swap it. */
364
5
        null_header = GUINT32_SWAP_LE_BE(null_header);
365
5
      }
366
5
    } else {
367
      /*
368
       * Check for an IRIX or UNICOS/mp snoop header.
369
       */
370
4
      if ((null_header & 0x000000FF) == 0 &&
371
4
          (null_header & 0x0000FF00) < 0x00000600) {
372
        /*
373
         * Looks like a IRIX or UNICOS/mp loopback header, in the
374
         * wrong byte order.  Set the null header value to the AF_
375
         * type; that's in the lower 16 bits of "null_header", but
376
         * is byte-swapped.
377
         */
378
0
        null_header = GUINT16_SWAP_LE_BE(null_header & 0xFFFF);
379
0
      }
380
4
    }
381
382
    /*
383
     * The null header value must be greater than the IEEE 802.3 maximum
384
     * frame length to be a valid Ethernet type; if it is, dissect it
385
     * as one, otherwise treat it as a BSD AF_type (we wire in the values
386
     * of the BSD AF_ types, because the values in the file will be BSD
387
     * values, and the OS on which we're building this might not have the
388
     * same values or might not have them defined at all; XXX - what if
389
     * different BSD derivatives have different values?).
390
     */
391
9
    if (null_header > IEEE_802_3_MAX_LEN) {
392
6
      if (tree) {
393
6
        ti = proto_tree_add_item(tree, proto_null, tvb, 0, 4, ENC_NA);
394
6
        fh_tree = proto_item_add_subtree(ti, ett_null);
395
6
        proto_tree_add_uint(fh_tree, hf_null_etype, tvb, 0, 4,
396
6
          (uint16_t) null_header);
397
6
      }
398
399
6
      next_tvb = tvb_new_subset_remaining(tvb, 4);
400
6
      if (!dissector_try_uint(ethertype_dissector_table,
401
6
            (uint16_t) null_header, next_tvb, pinfo, tree))
402
5
        call_data_dissector(next_tvb, pinfo, tree);
403
6
    } else {
404
      /* populate a tree in the second pane with the status of the link
405
         layer (ie none) */
406
3
      if (tree) {
407
3
        ti = proto_tree_add_item(tree, proto_null, tvb, 0, 4, ENC_NA);
408
3
        fh_tree = proto_item_add_subtree(ti, ett_null);
409
3
        proto_tree_add_uint(fh_tree, hf_null_family, tvb, 0, 4, null_header);
410
3
      }
411
412
3
      next_tvb = tvb_new_subset_remaining(tvb, 4);
413
3
      if (!dissector_try_uint(null_dissector_table, null_header,
414
3
            next_tvb, pinfo, tree)) {
415
        /* No sub-dissector found.  Label rest of packet as "Data" */
416
1
        call_data_dissector(next_tvb, pinfo, tree);
417
1
      }
418
3
    }
419
9
  }
420
9
  return tvb_captured_length(tvb);
421
9
}
422
423
/*
424
 * OpenBSD DLT_LOOP; like DLT_NULL, but with the first 4 byte *always*
425
 * being a *big-endian* type.
426
 */
427
static int
428
dissect_loop(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
429
0
{
430
0
  uint32_t      loop_family;
431
0
  proto_tree    *fh_tree;
432
0
  proto_item    *ti;
433
0
  tvbuff_t      *next_tvb;
434
435
  /* load the top pane info. This should be overwritten by
436
     the next protocol in the stack */
437
0
  col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "N/A");
438
0
  col_set_str(pinfo->cinfo, COL_RES_DL_DST, "N/A");
439
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "N/A");
440
0
  col_set_str(pinfo->cinfo, COL_INFO, "Null/Loopback");
441
442
  /* populate a tree in the second pane with the status of the link
443
     layer (ie none) */
444
0
  loop_family = tvb_get_ntohl(tvb, 0);
445
0
  if (tree) {
446
0
    ti = proto_tree_add_item(tree, proto_null, tvb, 0, 4, ENC_NA);
447
0
    fh_tree = proto_item_add_subtree(ti, ett_null);
448
0
    proto_tree_add_uint(fh_tree, hf_null_family, tvb, 0, 4, loop_family);
449
0
  }
450
451
0
  next_tvb = tvb_new_subset_remaining(tvb, 4);
452
0
  if (!dissector_try_uint(null_dissector_table, loop_family,
453
0
        next_tvb, pinfo, tree)) {
454
    /* No sub-dissector found.  Label rest of packet as "Data" */
455
0
    call_data_dissector(next_tvb, pinfo, tree);
456
0
  }
457
0
  return tvb_captured_length(tvb);
458
0
}
459
460
void
461
proto_register_null(void)
462
14
{
463
14
  static hf_register_info hf[] = {
464
465
    /* registered here but handled in ethertype.c */
466
14
    { &hf_null_etype,
467
14
      { "Type",         "null.type", FT_UINT16, BASE_HEX, VALS(etype_vals), 0x0,
468
14
        NULL, HFILL }},
469
470
14
    { &hf_null_family,
471
14
      { "Family",       "null.family", FT_UINT32, BASE_DEC, VALS(family_vals), 0x0,
472
14
        NULL, HFILL }}
473
14
  };
474
14
  static int *ett[] = {
475
14
    &ett_null,
476
14
  };
477
478
14
  proto_null = proto_register_protocol("Null/Loopback", "Null", "null");
479
14
  proto_register_field_array(proto_null, hf, array_length(hf));
480
14
  proto_register_subtree_array(ett, array_length(ett));
481
482
  /* subdissector code */
483
14
  null_dissector_table = register_dissector_table("null.type",
484
14
                                                  "Null type", proto_null, FT_UINT32, BASE_DEC);
485
486
14
  register_capture_dissector_table("null.bsd", "Null/Loopback BSD AF");
487
488
14
  null_handle = register_dissector("null", dissect_null, proto_null);
489
14
  loop_handle = register_dissector("null.loop", dissect_loop, proto_null);
490
14
  null_cap_handle = register_capture_dissector("null", capture_null, proto_null);
491
14
}
492
493
void
494
proto_reg_handoff_null(void)
495
14
{
496
  /*
497
   * Get a handle for the PPP-in-HDLC-like-framing dissector and
498
   * the "I don't know what this is" dissector.
499
   */
500
14
  ppp_hdlc_handle = find_dissector_add_dependency("ppp_hdlc", proto_null);
501
502
14
  ethertype_dissector_table = find_dissector_table("ethertype");
503
504
14
  dissector_add_uint("wtap_encap", WTAP_ENCAP_NULL, null_handle);
505
506
14
  dissector_add_uint("wtap_encap", WTAP_ENCAP_LOOP, loop_handle);
507
508
14
  capture_dissector_add_uint("wtap_encap", WTAP_ENCAP_NULL, null_cap_handle);
509
14
  capture_dissector_add_uint("wtap_encap", WTAP_ENCAP_LOOP, null_cap_handle);
510
511
14
  ppp_hdlc_cap_handle = find_capture_dissector("ppp_hdlc");
512
14
}
513
514
/*
515
 * Editor modelines
516
 *
517
 * Local Variables:
518
 * c-basic-offset: 2
519
 * tab-width: 8
520
 * indent-tabs-mode: nil
521
 * End:
522
 *
523
 * ex: set shiftwidth=2 tabstop=8 expandtab:
524
 * :indentSize=2:tabSize=8:noTabs=true:
525
 */