Coverage Report

Created: 2026-07-12 07:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-netanalyzer.c
Line
Count
Source
1
/* packet-netanalyzer.c
2
 * Dissector for Hilscher netANALYZER frames.
3
 * Copyright 2008-2016, Hilscher GmbH, Holger Pfrommer hpfrommer[AT]hilscher.com
4
 *
5
 * Packet structure:
6
 * +---------------------------+
7
 * |           Header          |
8
 * |         (4 Octets)        |
9
 * +---------------------------+
10
 * |           Payload         |
11
 * .                           .
12
 * .                           .
13
 * .                           .
14
 *
15
 * Description:
16
 * The header field contains a 32-bit value in little-endian byte order.
17
 * The low-order 8 bits are a set of error flags for the packet:
18
 *     0x00000001 - MII RX_ER
19
 *     0x00000002 - alignment error
20
 *     0x00000004 - FCS error
21
 *     0x00000008 - frame too long
22
 *     0x00000010 - SFD error
23
 *     0x00000020 - frame shorter than 64 bytes
24
 *     0x00000040 - preamble shorter than 7 bytes
25
 *     0x00000080 - preamble longer than 7 bytes/li>
26
 * The next bit, 0x00000100, is set if the packet arrived on the GPIO port rather tha the Ethernet port.
27
 * The next bit, 0x00000200, is set if the packet was received in transparent capture mode.
28
 *   That should never be set for LINKTYPE_NETANALYZER and should always be set for LINKTYPE_NETANALYZER_TRANSPARENT.
29
 * The next 4 bits, 0x00003C00, are a bitfield giving the version of the header field; version can be 1 or 2.
30
 * The next 2 bits, 0x0000C000, are the capture port/GPIO number, from 0 to 3.
31
 * The next 12 bits, 0x0FFF0000, are the frame length, in bytes.
32
 * The topmost 4 bits, 0xF0000000, for version 2 header, these bits are the type of the following packet
33
 *                                   (0: Ethernet, 1: PROFIBUS, 2: buffer state entry, 3: timetick, 4..15: reserved).
34
 * The payload is an Ethernet frame, beginning with the MAC header and ending with the FCS, for LINKTYPE_NETANALYZER,
35
 *   and an Ethernet frame, beginning with the preamble and ending with the FCS, for LINKTYPE_NETANALYZER_TRANSPARENT.
36
 *
37
 *
38
 * Wireshark - Network traffic analyzer
39
 * By Gerald Combs <gerald[AT]wireshark.org>
40
 * Copyright 1999 Gerald Combs
41
 *
42
 * SPDX-License-Identifier: GPL-2.0-or-later
43
 */
44
45
46
#include "config.h"
47
48
#include <epan/packet.h>
49
#include <epan/expert.h>
50
#include <wiretap/wtap.h>
51
52
void proto_register_netanalyzer(void);
53
void proto_reg_handoff_netanalyzer(void);
54
55
static dissector_handle_t netana_handle;
56
static dissector_handle_t netana_handle_transparent;
57
58
5
#define HEADER_SIZE  4
59
0
#define INFO_TYPE_OFFSET    18
60
61
15
#define MSK_RX_ERR             0x01
62
15
#define MSK_ALIGN_ERR          0x02
63
15
#define MSK_FCS_ERROR          0x04
64
15
#define MSK_TOO_LONG           0x08
65
15
#define MSK_SFD_ERROR          0x10
66
15
#define MSK_SHORT_FRAME        0x20
67
15
#define MSK_SHORT_PREAMBLE     0x40
68
15
#define MSK_LONG_PREAMBLE      0x80
69
70
static const char *msk_strings[] = {
71
  "MII RX_ER error",                /* 0x01 */
72
  "Alignment error",                /* 0x02 */
73
  "FCS error",                      /* 0x04 */
74
  "Frame too long",                 /* 0x08 */
75
  "No valid SFD found",             /* 0x10 */
76
  "Frame smaller 64 bytes",         /* 0x20 */
77
  "Preamble shorter than 7 bytes",  /* 0x40 */
78
  "Preamble longer than 7 bytes"    /* 0x80 */
79
};
80
81
3
#define SRT_TYPE              28
82
1
#define SRT_PORT_NUM           6
83
3
#define SRT_VERSION            2
84
5
#define SRT_GPIO_FLAG          0
85
15
#define MSK_PACKET_STATUS      0xff
86
1
#define MSK_LENGTH             0x0fff
87
1
#define MSK_TRANSPARENT_MODE   0x02
88
89
0
#define MSK_BUF_STATE         0x1
90
0
#define SRT_BUF_ID            4
91
0
#define MSK_BUF_ID            0xf0
92
93
1
#define VAL_TYPE_ETH            0
94
1
#define VAL_TYPE_PB             1
95
1
#define VAL_TYPE_BUF            2
96
1
#define VAL_TYPE_TICK           3
97
98
99
static const value_string gpio_number[] = {
100
  { 0x0, "GPIO 0" },
101
  { 0x1, "GPIO 1" },
102
  { 0x2, "GPIO 2" },
103
  { 0x3, "GPIO 3" },
104
  { 0,   NULL }
105
};
106
107
static const value_string gpio_edge_vals[] = {
108
  { 0x0, "Rising edge" },
109
  { 0x1, "Falling edge" },
110
  { 0,   NULL }
111
};
112
113
static const value_string buf_state_vals[] = {
114
  { 0x0, "Buffer overflow, frames will be dropped until next buffer recovery" },
115
  { 0x1, "Buffer recovery, frame reception has recovered" },
116
  { 0,   NULL }
117
};
118
119
static const value_string buf_source_vals[] = {
120
  { 0x0, "Backend RX FIFO" },
121
  { 0x1, "netX URX FIFO" },
122
  { 0x2, "netX INTRAM buffer" },
123
  { 0x3, "Host buffer" },
124
  { 0x4, "Capture driver (WinPcap)" },
125
  { 0,   NULL }
126
};
127
128
129
static dissector_handle_t  eth_dissector_handle;
130
131
static int   proto_netanalyzer;
132
133
static int   hf_netanalyzer_gpio;
134
static int   hf_netanalyzer_gpio_number;
135
static int   hf_netanalyzer_gpio_edge;
136
static int   hf_netanalyzer_eth;
137
static int   hf_netanalyzer_port;
138
static int   hf_netanalyzer_length;
139
static int   hf_netanalyzer_status;
140
static int   hf_netanalyzer_status_rx_err;
141
static int   hf_netanalyzer_status_align_err;
142
static int   hf_netanalyzer_status_fcs;
143
static int   hf_netanalyzer_status_too_long;
144
static int   hf_netanalyzer_status_sfd_error;
145
static int   hf_netanalyzer_status_short_frame;
146
static int   hf_netanalyzer_status_short_preamble;
147
static int   hf_netanalyzer_status_long_preamble;
148
static int   hf_netanalyzer_buf;
149
static int   hf_netanalyzer_buf_state;
150
static int   hf_netanalyzer_buf_source;
151
static int   hf_netanalyzer_timetick;
152
153
static int * const hfx_netanalyzer_status[] = {
154
  &hf_netanalyzer_status_rx_err,
155
  &hf_netanalyzer_status_align_err,
156
  &hf_netanalyzer_status_fcs,
157
  &hf_netanalyzer_status_too_long,
158
  &hf_netanalyzer_status_sfd_error,
159
  &hf_netanalyzer_status_short_frame,
160
  &hf_netanalyzer_status_short_preamble,
161
  &hf_netanalyzer_status_long_preamble,
162
  NULL
163
};
164
165
static int   ett_netanalyzer;
166
static int   ett_netanalyzer_gpio;
167
static int   ett_netanalyzer_status;
168
static int   ett_netanalyzer_transparent;
169
static int   ett_netanalyzer_buf;
170
171
static expert_field ei_netanalyzer_header_wrong;
172
static expert_field ei_netanalyzer_gpio_def_none;
173
static expert_field ei_netanalyzer_header_none;
174
static expert_field ei_netanalyzer_transparent_frame;
175
static expert_field ei_netanalyzer_alignment_error;
176
static expert_field ei_netanalyzer_not_implemented;
177
178
/* common routine for Ethernet and transparent mode */
179
static int
180
dissect_netanalyzer_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
181
5
{
182
5
  proto_item              *ti = NULL;
183
5
  proto_tree              *netanalyzer_header_tree = NULL;
184
5
  uint32_t                packet_status;
185
5
  uint32_t                port_num;
186
5
  uint32_t                frame_length;
187
5
  unsigned                is_gpio;
188
5
  uint32_t                offset;
189
5
  unsigned                gpio_num;
190
5
  unsigned                gpio_edge;
191
5
  unsigned                version;
192
5
  unsigned                type;
193
5
  unsigned                idx;
194
5
  unsigned                buf_state;
195
5
  unsigned                buf_source;
196
197
5
  if (tree)
198
5
  {
199
    /* generate netANALYZER tree */
200
5
    ti = proto_tree_add_item(tree, proto_netanalyzer, tvb, 0, HEADER_SIZE, ENC_NA);
201
5
    netanalyzer_header_tree = proto_item_add_subtree(ti, ett_netanalyzer);
202
203
5
    is_gpio = (tvb_get_uint8(tvb, 1) >> SRT_GPIO_FLAG) & 0x1;
204
205
5
    if (!is_gpio)
206
3
    {
207
      /* normal packet, no GPIO */
208
209
      /* decode version */
210
3
      version = (tvb_get_uint8(tvb, 1) >> SRT_VERSION) & 0xf;
211
3
      type    = (tvb_get_uint32(tvb, 0, ENC_LITTLE_ENDIAN) >> SRT_TYPE) & 0xf;
212
213
3
      if ((version == 1) || ((version == 2) && (type == VAL_TYPE_ETH)))
214
1
      {
215
1
        proto_tree_add_none_format(netanalyzer_header_tree, hf_netanalyzer_eth, tvb, 0, 0, "Ethernet frame");
216
217
        /* decode port */
218
1
        port_num = (tvb_get_uint8(tvb, 1) >> SRT_PORT_NUM) & 0x3;
219
1
        proto_tree_add_uint(netanalyzer_header_tree, hf_netanalyzer_port, tvb, 0, 4, port_num);
220
1
        proto_item_append_text(ti, " (Port: %u, ", port_num);
221
222
        /* decode length */
223
1
        frame_length = tvb_get_letohs(tvb, 2) & MSK_LENGTH;
224
1
        proto_tree_add_uint(netanalyzer_header_tree, hf_netanalyzer_length, tvb, 0, 4, frame_length);
225
1
        proto_item_append_text(ti, "Length: %u byte%s, ", frame_length, (frame_length == 1) ? "" : "s");
226
227
        /* decode status */
228
1
        proto_item_append_text(ti, "Status: ");
229
1
        packet_status = tvb_get_uint8(tvb, 0);
230
1
        if (packet_status == 0)
231
1
        {
232
1
          proto_tree_add_uint_format_value(netanalyzer_header_tree, hf_netanalyzer_status, tvb, 0, 1,
233
1
            packet_status, "No Error");
234
1
          proto_item_append_text(ti, "No Error)");
235
1
        }
236
0
        else
237
0
        {
238
0
          wmem_strbuf_t      *strbuf;
239
0
          bool                first = true;
240
241
0
          proto_tree_add_bitmask(netanalyzer_header_tree, tvb, 0, hf_netanalyzer_status, ett_netanalyzer_status, hfx_netanalyzer_status, ENC_LITTLE_ENDIAN);
242
243
0
          strbuf = wmem_strbuf_create(pinfo->pool);
244
0
          for (idx = 0; idx < 8; idx++)
245
0
          {
246
0
            if (packet_status & (1 << idx))
247
0
            {
248
0
              if (first)
249
0
              {
250
0
                first = false;
251
0
              }
252
0
              else
253
0
              {
254
0
                wmem_strbuf_append(strbuf, ", ");
255
0
              }
256
0
              wmem_strbuf_append(strbuf, msk_strings[idx]);
257
0
            }
258
0
          }
259
0
          proto_item_append_text(ti, "%s)", wmem_strbuf_get_str(strbuf));
260
0
        }
261
262
        /* decode transparent mode */
263
1
        if (tvb_get_uint8(tvb, 1) & MSK_TRANSPARENT_MODE)
264
0
        {
265
0
          proto_tree_add_expert(netanalyzer_header_tree, pinfo, &ei_netanalyzer_transparent_frame, tvb, 0, 4);
266
0
          proto_item_append_text(ti, ", Transparent Mode");
267
268
0
          if (packet_status & MSK_ALIGN_ERR)
269
0
          {
270
0
            proto_tree_add_expert(netanalyzer_header_tree, pinfo, &ei_netanalyzer_alignment_error, tvb, tvb_captured_length(tvb) - 1, 1);
271
0
          }
272
0
        }
273
1
      }
274
2
      else if ((version == 2) && (type == VAL_TYPE_PB))
275
0
      {
276
        /* currently not implemented */
277
0
        expert_add_info(pinfo, ti, &ei_netanalyzer_not_implemented);
278
0
        return false;
279
0
      }
280
2
      else if ((version == 2) && (type == VAL_TYPE_BUF))
281
0
      {
282
0
        proto_tree_add_none_format(netanalyzer_header_tree, hf_netanalyzer_buf, tvb, 0, 0, "Buffer state entry");
283
0
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "netANALYZER");
284
285
0
        buf_state = tvb_get_uint8(tvb, 0) & MSK_BUF_STATE;
286
0
        if (buf_state == 0)
287
0
        {
288
0
          col_set_str(pinfo->cinfo, COL_INFO, "Buffer overflow");
289
0
        }
290
0
        else
291
0
        {
292
0
          col_set_str(pinfo->cinfo, COL_INFO, "Buffer recovery");
293
0
        }
294
0
        proto_item_append_text(ti, " (%s)", buf_state_vals[buf_state].strptr);
295
296
        /* decode buffer state */
297
0
        proto_tree_add_uint(ti, hf_netanalyzer_buf_state, tvb, 0, 1, buf_state);
298
0
        port_num = (tvb_get_uint8(tvb, 1) >> SRT_PORT_NUM) & 0x3;
299
0
        proto_tree_add_uint(ti, hf_netanalyzer_port, tvb, 0, 4, port_num);
300
0
        buf_source = (tvb_get_uint8(tvb, 0) & MSK_BUF_ID) >> SRT_BUF_ID;
301
0
        proto_tree_add_uint(ti, hf_netanalyzer_buf_source, tvb, 0, 1, buf_source);
302
303
0
        return false;
304
0
      }
305
2
      else if ((version == 2) && (type == VAL_TYPE_TICK))
306
0
      {
307
0
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "netANALYZER");
308
0
        col_set_str(pinfo->cinfo, COL_INFO, "Time tick");
309
0
        proto_item_append_text(ti, " (Time tick)");
310
0
        proto_tree_add_none_format(netanalyzer_header_tree, hf_netanalyzer_timetick, tvb, 0, 0, "Time tick");
311
0
        return false;
312
0
      }
313
2
      else
314
2
      {
315
        /* something is wrong */
316
2
        expert_add_info(pinfo, ti, &ei_netanalyzer_header_wrong);
317
2
        return false;
318
2
      }
319
3
    }
320
2
    else
321
2
    {
322
      /* check consistency */
323
2
      if ( (tvb_get_uint8(tvb, 10) == 0x00) &&
324
1
           (tvb_get_uint8(tvb, 11) == 0x02) &&
325
0
           (tvb_get_uint8(tvb, 12) == 0xa2) &&
326
0
           (tvb_get_uint8(tvb, 13) == 0xff) &&
327
0
           (tvb_get_uint8(tvb, 14) == 0xff) &&
328
0
           (tvb_get_uint8(tvb, 15) == 0xff) &&
329
0
           (tvb_get_uint8(tvb, 16) == 0x88) &&
330
0
           (tvb_get_uint8(tvb, 17) == 0xff) &&
331
0
           (tvb_get_uint8(tvb, INFO_TYPE_OFFSET) == 0x00) )
332
0
      {
333
0
        char *szTemp;
334
335
        /* everything ok */
336
0
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "netANALYZER");
337
0
        offset = INFO_TYPE_OFFSET;
338
0
        proto_tree_add_none_format(netanalyzer_header_tree, hf_netanalyzer_gpio, tvb, 0, 0, "GPIO event");
339
0
        proto_item_append_text(ti, " (GPIO event)");
340
341
        /* GPIO number */
342
0
        offset++;
343
0
        proto_tree_add_item (netanalyzer_header_tree, hf_netanalyzer_gpio_number, tvb, offset, 1, ENC_LITTLE_ENDIAN);
344
0
        gpio_num = (tvb_get_uint8(tvb, offset) & 0x03);
345
346
        /* GPIO edge */
347
0
        offset++;
348
0
        ti = proto_tree_add_item (netanalyzer_header_tree, hf_netanalyzer_gpio_edge, tvb, offset, 1, ENC_LITTLE_ENDIAN);
349
0
        gpio_edge = (tvb_get_uint8(tvb, offset) & 0x01);
350
351
0
        szTemp = wmem_strdup_printf(pinfo->pool, "GPIO event on GPIO %d (%sing edge)", gpio_num, (gpio_edge == 0x00) ? "ris" : "fall");
352
353
0
        col_add_str(pinfo->cinfo, COL_INFO, szTemp);
354
0
        proto_item_append_text(ti, " %s", szTemp);
355
0
      }
356
2
      else
357
2
      {
358
        /* something is wrong */
359
2
        expert_add_info(pinfo, ti, &ei_netanalyzer_gpio_def_none);
360
2
      }
361
2
      return false;
362
2
    }
363
5
  }
364
1
  return true;
365
5
}
366
367
368
/* Ethernet capture mode */
369
static int
370
dissect_netanalyzer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
371
1
{
372
1
  tvbuff_t                *next_tvb;
373
374
1
  if (tvb_reported_length(tvb) >= 4)
375
1
  {
376
    /* generate tvb subset for Ethernet frame */
377
1
    if (dissect_netanalyzer_common(tvb, pinfo, tree))
378
0
    {
379
      /* hand off to eth dissector with the new tvb subset */
380
0
      next_tvb = tvb_new_subset_remaining(tvb, 4);
381
0
      call_dissector(eth_dissector_handle, next_tvb, pinfo, tree);
382
0
    }
383
1
  }
384
0
  else
385
0
  {
386
    /* something is wrong */
387
0
    proto_tree_add_expert_format_remaining(tree, pinfo, &ei_netanalyzer_header_none, tvb, 4,
388
0
        "netANALYZER - No netANALYZER header found");
389
0
  }
390
1
  return tvb_captured_length(tvb);
391
1
}
392
393
394
/* Transparent capture mode */
395
static int
396
dissect_netanalyzer_transparent(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
397
4
{
398
4
  proto_tree              *transparent_payload_tree = NULL;
399
4
  tvbuff_t                *next_tvb;
400
401
4
  if (tvb_reported_length(tvb) >= 4)
402
4
  {
403
    /* generate tvb subset for Ethernet frame */
404
4
    if (dissect_netanalyzer_common(tvb, pinfo, tree))
405
1
    {
406
      /* do not hand off transparent packet for further Ethernet dissectors
407
       * as normally the transparent mode is used for low level analysis
408
       * where dissecting the frame's content wouldn't make much sense
409
       * use data dissector instead */
410
1
      transparent_payload_tree = proto_tree_add_subtree(tree, tvb, 4, tvb_captured_length(tvb)-4,
411
1
                                    ett_netanalyzer_transparent, NULL, "Raw packet data");
412
1
      next_tvb = tvb_new_subset_remaining(tvb, 4);
413
1
      call_data_dissector(next_tvb, pinfo, transparent_payload_tree);
414
415
1
      col_set_str(pinfo->cinfo, COL_PROTOCOL, "netANALYZER");
416
1
      col_set_str(pinfo->cinfo, COL_INFO, "Frame captured in transparent mode");
417
1
    }
418
4
  }
419
0
  else
420
0
  {
421
    /* something is wrong */
422
0
    proto_tree_add_expert_format_remaining(tree, pinfo, &ei_netanalyzer_header_none, tvb, 4,
423
0
        "netANALYZER transparent mode - No netANALYZER header found");
424
0
  }
425
4
  return tvb_captured_length(tvb);
426
4
}
427
428
429
void proto_register_netanalyzer(void)
430
15
{
431
15
  static hf_register_info hf[] = {
432
15
    { &hf_netanalyzer_gpio,
433
15
      { "GPIO event", "netanalyzer.gpio_event",
434
15
        FT_NONE, BASE_NONE, NULL, 0x0,
435
15
        "Shows the occurrence of an digital switching event", HFILL }
436
15
    },
437
15
    { &hf_netanalyzer_gpio_number,
438
15
      { "GPIO event on", "netanalyzer.gpio_event.gpio_number",
439
15
        FT_UINT8, BASE_HEX, VALS(gpio_number), 0x0,
440
15
        "GPIO event on GPIO number", HFILL }
441
15
    },
442
15
    { &hf_netanalyzer_gpio_edge,
443
15
      { "GPIO event type", "netanalyzer.gpio_event.gpio_edge",
444
15
        FT_UINT8, BASE_HEX, VALS(gpio_edge_vals), 0x0,
445
15
        "GPIO edge of GPIO event", HFILL }
446
15
    },
447
15
    { &hf_netanalyzer_eth,
448
15
      { "Ethernet frame", "netanalyzer.eth",
449
15
        FT_NONE, BASE_NONE, NULL, 0x0,
450
15
        "This is an Ethernet frame", HFILL }
451
15
    },
452
15
    { &hf_netanalyzer_port,
453
15
      { "Reception Port", "netanalyzer.port",
454
15
        FT_UINT8, BASE_DEC, NULL, 0x0,
455
15
        "netANALYZER reception port", HFILL }
456
15
    },
457
15
    { &hf_netanalyzer_length,
458
15
      { "Ethernet frame length", "netanalyzer.framelen",
459
15
        FT_UINT16, BASE_DEC, NULL, 0x0,
460
15
        "Actual Ethernet frame length", HFILL }
461
15
    },
462
15
    { &hf_netanalyzer_status,
463
15
      { "Status", "netanalyzer.packetstatus",
464
15
        FT_UINT8, BASE_HEX, NULL, MSK_PACKET_STATUS,
465
15
        "Status of Ethernet frame", HFILL }
466
15
    },
467
15
    { &hf_netanalyzer_status_rx_err,
468
15
      { "MII RX_ER error", "netanalyzer.packetstatus.rx_er",
469
15
        FT_BOOLEAN, 8, NULL, MSK_RX_ERR,
470
15
        "RX_ER detected in frame", HFILL }
471
15
    },
472
15
    { &hf_netanalyzer_status_align_err,
473
15
      { "Alignment error", "netanalyzer.packetstatus.alignment_error",
474
15
        FT_BOOLEAN, 8, NULL, MSK_ALIGN_ERR,
475
15
        NULL, HFILL }
476
15
    },
477
15
    { &hf_netanalyzer_status_fcs,
478
15
      { "FCS error", "netanalyzer.packetstatus.fcs_error",
479
15
        FT_BOOLEAN, 8, NULL, MSK_FCS_ERROR,
480
15
        NULL, HFILL }
481
15
    },
482
15
    { &hf_netanalyzer_status_too_long,
483
15
      { "Frame too long", "netanalyzer.packetstatus.too_long",
484
15
        FT_BOOLEAN, 8, NULL, MSK_TOO_LONG,
485
15
        "Frame too long (capture truncated)", HFILL }
486
15
    },
487
15
    { &hf_netanalyzer_status_sfd_error,
488
15
      { "No valid SFD found", "netanalyzer.packetstatus.sfd_error",
489
15
        FT_BOOLEAN, 8, NULL, MSK_SFD_ERROR,
490
15
        "SDF error detected in frame", HFILL }
491
15
    },
492
15
    { &hf_netanalyzer_status_short_frame,
493
15
      { "Frame smaller 64 bytes", "netanalyzer.packetstatus.short_frame",
494
15
        FT_BOOLEAN, 8, NULL, MSK_SHORT_FRAME,
495
15
        NULL, HFILL }
496
15
    },
497
15
    { &hf_netanalyzer_status_short_preamble,
498
15
      { "Preamble shorter than 7 bytes", "netanalyzer.packetstatus.short_preamble",
499
15
        FT_BOOLEAN, 8, NULL, MSK_SHORT_PREAMBLE,
500
15
        NULL, HFILL }
501
15
    },
502
15
    { &hf_netanalyzer_status_long_preamble,
503
15
      { "Preamble longer than 7 bytes", "netanalyzer.packetstatus.long_preamble",
504
15
        FT_BOOLEAN, 8, NULL, MSK_LONG_PREAMBLE,
505
15
        NULL, HFILL }
506
15
    },
507
15
    { &hf_netanalyzer_buf,
508
15
      { "Buffer state entry", "netanalyzer.buffer",
509
15
        FT_NONE, BASE_NONE, NULL, 0x0,
510
15
        "Info about reception buffer conditions", HFILL }
511
15
    },
512
15
    { &hf_netanalyzer_buf_state,
513
15
      { "Buffer state", "netanalyzer.buffer.state",
514
15
        FT_UINT8, BASE_DEC, VALS(buf_state_vals), 0x0,
515
15
        "State of receive buffers", HFILL }
516
15
    },
517
15
    { &hf_netanalyzer_buf_source,
518
15
      { "Buffer source", "netanalyzer.buffer.source",
519
15
        FT_UINT8, BASE_DEC, VALS(buf_source_vals), 0x0,
520
15
        "Source of buffer error", HFILL }
521
15
    },
522
15
    { &hf_netanalyzer_timetick,
523
15
      { "Time tick", "netanalyzer.timetick",
524
15
        FT_NONE, BASE_NONE, NULL, 0x0,
525
15
        "Cyclic time tick of netANALYZER device", HFILL }
526
15
    },
527
15
  };
528
529
15
  static int *ett[] = {
530
15
    &ett_netanalyzer,
531
15
    &ett_netanalyzer_gpio,
532
15
    &ett_netanalyzer_status,
533
15
    &ett_netanalyzer_transparent,
534
15
    &ett_netanalyzer_buf,
535
15
  };
536
537
15
  static ei_register_info ei[] = {
538
15
    { &ei_netanalyzer_header_wrong, { "netanalyzer.header.wrong", PI_PROTOCOL, PI_ERROR, "Wrong netANALYZER header", EXPFILL }},
539
15
    { &ei_netanalyzer_gpio_def_none, { "netanalyzer.gpio_def_none", PI_MALFORMED, PI_ERROR, "No valid netANALYZER GPIO definition found", EXPFILL }},
540
15
    { &ei_netanalyzer_header_none, { "netanalyzer.header.none", PI_MALFORMED, PI_ERROR, "No netANALYZER header found", EXPFILL }},
541
15
    { &ei_netanalyzer_transparent_frame, { "netanalyzer.transparent_frame", PI_PROTOCOL, PI_NOTE, "This frame was captured in transparent mode", EXPFILL }},
542
15
    { &ei_netanalyzer_alignment_error, { "netanalyzer.alignment_error", PI_PROTOCOL, PI_WARN, "Displayed frame data contains additional nibble due to alignment error (upper nibble is not valid)", EXPFILL }},
543
15
    { &ei_netanalyzer_not_implemented,{ "netanalyzer.not_implemented", PI_PROTOCOL, PI_ERROR, "This feature is currently not implemented in Wireshark", EXPFILL } },
544
15
  };
545
546
15
  expert_module_t* expert_netanalyzer;
547
548
15
  proto_netanalyzer = proto_register_protocol ("netANALYZER", "netANALYZER", "netanalyzer");
549
550
15
  proto_register_field_array(proto_netanalyzer, hf, array_length(hf));
551
15
  proto_register_subtree_array(ett, array_length(ett));
552
15
  expert_netanalyzer = expert_register_protocol(proto_netanalyzer);
553
15
  expert_register_field_array(expert_netanalyzer, ei, array_length(ei));
554
555
15
  netana_handle             = register_dissector("netanalyzer",             dissect_netanalyzer,             proto_netanalyzer);
556
15
  netana_handle_transparent = register_dissector("netanalyzer_transparent", dissect_netanalyzer_transparent, proto_netanalyzer);
557
15
}
558
559
560
void proto_reg_handoff_netanalyzer(void)
561
15
{
562
15
  eth_dissector_handle  = find_dissector_add_dependency("eth_withfcs", proto_netanalyzer);
563
15
  dissector_add_uint("wtap_encap", WTAP_ENCAP_NETANALYZER,             netana_handle);
564
15
  dissector_add_uint("wtap_encap", WTAP_ENCAP_NETANALYZER_TRANSPARENT, netana_handle_transparent);
565
15
}
566
567
/*
568
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
569
 *
570
 * Local Variables:
571
 * c-basic-offset: 2
572
 * tab-width: 8
573
 * indent-tabs-mode: nil
574
 * End:
575
 *
576
 * ex: set shiftwidth=2 tabstop=8 expandtab:
577
 * :indentSize=2:tabSize=8:noTabs=true:
578
 */