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-netlink-net_dm.c
Line
Count
Source
1
/* packet-netlink-net_dm.c
2
 * Routines for netlink-net_dm dissection
3
 * Based on netlink-route and netlink-generic dissectors
4
 * Copyright 2019, Mellanox Technologies Ltd.
5
 * Code by Ido Schimmel <idosch@mellanox.com>
6
 *
7
 * Wireshark - Network traffic analyzer
8
 * By Gerald Combs <gerald@wireshark.org>
9
 * Copyright 1998 Gerald Combs
10
 *
11
 * SPDX-License-Identifier: GPL-2.0-or-later
12
 */
13
14
/* net_dm (network drop monitor) is a netlink-based protocol via which alerts
15
 * about dropped packets are sent to user space
16
 *
17
 * Relevant Linux kernel header file:
18
 * include/uapi/linux/net_dropmon.h
19
 *
20
 * Man page:
21
 * man 1 dropwatch
22
 */
23
24
#include "config.h"
25
26
#include <epan/packet.h>
27
28
#include "packet-netlink.h"
29
#include "packet-sll.h"
30
31
void proto_register_netlink_net_dm(void);
32
void proto_reg_handoff_netlink_net_dm(void);
33
34
enum ws_net_dm_commands {
35
  WS_NET_DM_CMD_UNSPEC,
36
  WS_NET_DM_CMD_ALERT,
37
  WS_NET_DM_CMD_CONFIG,
38
  WS_NET_DM_CMD_START,
39
  WS_NET_DM_CMD_STOP,
40
  WS_NET_DM_CMD_PACKET_ALERT,
41
  WS_NET_DM_CMD_CONFIG_GET,
42
  WS_NET_DM_CMD_CONFIG_NEW,
43
  WS_NET_DM_CMD_STATS_GET,
44
  WS_NET_DM_CMD_STATS_NEW,
45
};
46
47
enum ws_net_dm_attrs {
48
  WS_NET_DM_ATTR_UNSPEC,
49
  WS_NET_DM_ATTR_ALERT_MODE,
50
  WS_NET_DM_ATTR_PC,
51
  WS_NET_DM_ATTR_SYMBOL,
52
  WS_NET_DM_ATTR_IN_PORT,
53
  WS_NET_DM_ATTR_TIMESTAMP,
54
  WS_NET_DM_ATTR_PROTO,
55
  WS_NET_DM_ATTR_PAYLOAD,
56
  WS_NET_DM_ATTR_PAD,
57
  WS_NET_DM_ATTR_TRUNC_LEN,
58
  WS_NET_DM_ATTR_ORIG_LEN,
59
  WS_NET_DM_ATTR_QUEUE_LEN,
60
  WS_NET_DM_ATTR_STATS,
61
  WS_NET_DM_ATTR_HW_STATS,
62
  WS_NET_DM_ATTR_ORIGIN,
63
  WS_NET_DM_ATTR_HW_TRAP_GROUP_NAME,
64
  WS_NET_DM_ATTR_HW_TRAP_NAME,
65
  WS_NET_DM_ATTR_HW_ENTRIES,
66
  WS_NET_DM_ATTR_HW_ENTRY,
67
  WS_NET_DM_ATTR_HW_TRAP_COUNT,
68
  WS_NET_DM_ATTR_SW_DROPS,
69
  WS_NET_DM_ATTR_HW_DROPS,
70
  WS_NET_DM_ATTR_FLOW_ACTION_COOKIE,
71
  WS_NET_DM_ATTR_REASON,
72
};
73
74
enum ws_net_dm_attrs_port {
75
  WS_NET_DM_ATTR_PORT_NETDEV_IFINDEX,
76
  WS_NET_DM_ATTR_PORT_NETDEV_NAME,
77
};
78
79
enum ws_net_dm_attrs_stats {
80
  WS_NET_DM_ATTR_STATS_DROPPED,
81
};
82
83
enum ws_net_dm_alert_mode {
84
  WS_NET_DM_ALERT_MODE_SUMMARY,
85
  WS_NET_DM_ALERT_MODE_PACKET,
86
};
87
88
enum ws_net_dm_origin {
89
  WS_NET_DM_ORIGIN_SW,
90
  WS_NET_DM_ORIGIN_HW,
91
};
92
93
struct netlink_net_dm_info {
94
  packet_info *pinfo;
95
  uint16_t protocol; /* protocol for packet payload */
96
};
97
98
static dissector_handle_t netlink_net_dm_handle;
99
static dissector_table_t sll_ltype_table;
100
static dissector_table_t ethertype_table;
101
102
static int proto_netlink_net_dm;
103
104
static int hf_net_dm_alert_mode;
105
static int hf_net_dm_attrs;
106
static int hf_net_dm_attrs_port;
107
static int hf_net_dm_attrs_stats;
108
static int hf_net_dm_commands;
109
static int hf_net_dm_flow_action_cookie;
110
static int hf_net_dm_hw;
111
static int hf_net_dm_hw_trap_count;
112
static int hf_net_dm_hw_trap_group_name;
113
static int hf_net_dm_hw_trap_name;
114
static int hf_net_dm_orig_len;
115
static int hf_net_dm_origin;
116
static int hf_net_dm_pc;
117
static int hf_net_dm_port_netdev_index;
118
static int hf_net_dm_port_netdev_name;
119
static int hf_net_dm_proto;
120
static int hf_net_dm_queue_len;
121
static int hf_net_dm_stats_dropped;
122
static int hf_net_dm_sw;
123
static int hf_net_dm_symbol;
124
static int hf_net_dm_timestamp;
125
static int hf_net_dm_trunc_len;
126
static int hf_net_dm_reason;
127
128
static int ett_net_dm;
129
static int ett_net_dm_attrs;
130
static int ett_net_dm_attrs_in_port;
131
static int ett_net_dm_attrs_stats;
132
static int ett_net_dm_attrs_hw_stats;
133
static int ett_net_dm_attrs_hw_entries;
134
static int ett_net_dm_attrs_hw_entry;
135
136
static const value_string ws_net_dm_commands_vals[] = {
137
  { WS_NET_DM_CMD_UNSPEC,     "Unspecified command" },
138
  { WS_NET_DM_CMD_ALERT,      "Drop alert (summary)" },
139
  { WS_NET_DM_CMD_CONFIG,     "Configure drop monitor" },
140
  { WS_NET_DM_CMD_START,      "Start monitoring" },
141
  { WS_NET_DM_CMD_STOP,     "Stop monitoring" },
142
  { WS_NET_DM_CMD_PACKET_ALERT,   "Drop alert (packet)" },
143
  { WS_NET_DM_CMD_CONFIG_GET,   "Get drop monitor configuration" },
144
  { WS_NET_DM_CMD_CONFIG_NEW,   "New drop monitor configuration" },
145
  { WS_NET_DM_CMD_STATS_GET,    "Get drop monitor statistics" },
146
  { WS_NET_DM_CMD_STATS_NEW,    "New drop monitor statistics" },
147
  { 0, NULL },
148
};
149
150
static value_string_ext ws_net_dm_commands_vals_ext = VALUE_STRING_EXT_INIT(ws_net_dm_commands_vals);
151
152
static const value_string ws_net_dm_attrs_vals[] = {
153
  { WS_NET_DM_ATTR_UNSPEC,      "Unspecified" },
154
  { WS_NET_DM_ATTR_ALERT_MODE,      "Alert mode" },
155
  { WS_NET_DM_ATTR_PC,        "Drop location (PC)" },
156
  { WS_NET_DM_ATTR_SYMBOL,      "Drop location (symbol)" },
157
  { WS_NET_DM_ATTR_IN_PORT,     "Input port" },
158
  { WS_NET_DM_ATTR_TIMESTAMP,     "Timestamp" },
159
  { WS_NET_DM_ATTR_PROTO,       "Protocol" },
160
  { WS_NET_DM_ATTR_PAYLOAD,     "Payload" },
161
  { WS_NET_DM_ATTR_PAD,       "Pad" },
162
  { WS_NET_DM_ATTR_TRUNC_LEN,     "Truncation length" },
163
  { WS_NET_DM_ATTR_ORIG_LEN,      "Original length" },
164
  { WS_NET_DM_ATTR_QUEUE_LEN,     "Queue length" },
165
  { WS_NET_DM_ATTR_STATS,       "Software statistics" },
166
  { WS_NET_DM_ATTR_HW_STATS,      "Hardware statistics" },
167
  { WS_NET_DM_ATTR_ORIGIN,      "Packet origin" },
168
  { WS_NET_DM_ATTR_HW_TRAP_GROUP_NAME,    "Hardware trap group name" },
169
  { WS_NET_DM_ATTR_HW_TRAP_NAME,      "Hardware trap name" },
170
  { WS_NET_DM_ATTR_HW_ENTRIES,      "Hardware trap entries" },
171
  { WS_NET_DM_ATTR_HW_ENTRY,      "Hardware trap entry" },
172
  { WS_NET_DM_ATTR_HW_TRAP_COUNT,     "Hardware trap count" },
173
  { WS_NET_DM_ATTR_SW_DROPS,      "Software drops" },
174
  { WS_NET_DM_ATTR_HW_DROPS,      "Hardware drops" },
175
  { WS_NET_DM_ATTR_FLOW_ACTION_COOKIE,    "Flow action cookie" },
176
  { WS_NET_DM_ATTR_REASON,      "Reason" },
177
  { 0, NULL },
178
};
179
180
static value_string_ext ws_net_dm_attrs_vals_ext = VALUE_STRING_EXT_INIT(ws_net_dm_attrs_vals);
181
182
static const value_string ws_net_dm_attrs_port_vals[] = {
183
  { WS_NET_DM_ATTR_PORT_NETDEV_IFINDEX,   "Net device index" },
184
  { WS_NET_DM_ATTR_PORT_NETDEV_NAME,    "Net device name" },
185
  { 0, NULL },
186
};
187
188
static const value_string ws_net_dm_attrs_stats_vals[] = {
189
  { WS_NET_DM_ATTR_STATS_DROPPED,     "Dropped" },
190
  { 0, NULL },
191
};
192
193
static const value_string ws_net_dm_alert_mode_vals[] = {
194
  { WS_NET_DM_ALERT_MODE_SUMMARY,   "Summary" },
195
  { WS_NET_DM_ALERT_MODE_PACKET,    "Packet" },
196
  { 0, NULL },
197
};
198
199
static const value_string ws_net_dm_origin_vals[] = {
200
  { WS_NET_DM_ORIGIN_SW,    "Software" },
201
  { WS_NET_DM_ORIGIN_HW,    "Hardware" },
202
  { 0, NULL },
203
};
204
205
static int
206
dissect_net_dm_attrs_port(tvbuff_t *tvb, void *data, struct packet_netlink_data *nl_data, proto_tree *tree, int nla_type, int offset, int len)
207
0
{
208
0
  struct netlink_net_dm_info* info = (struct netlink_net_dm_info*)data;
209
0
  enum ws_net_dm_attrs_port type = (enum ws_net_dm_attrs_port) nla_type & NLA_TYPE_MASK;
210
0
  const uint8_t *str;
211
0
  uint32_t value;
212
213
0
  switch (type) {
214
0
  case WS_NET_DM_ATTR_PORT_NETDEV_IFINDEX:
215
0
    proto_tree_add_item_ret_uint(tree, hf_net_dm_port_netdev_index, tvb, offset, len, nl_data->encoding, &value);
216
0
    proto_item_append_text(tree, ": %u", value);
217
0
    return 1;
218
0
  case WS_NET_DM_ATTR_PORT_NETDEV_NAME:
219
0
    proto_tree_add_item_ret_string(tree, hf_net_dm_port_netdev_name, tvb, offset, len, ENC_ASCII | ENC_NA, info->pinfo->pool, &str);
220
0
    proto_item_append_text(tree, ": %s", str);
221
0
    return 1;
222
0
  default:
223
0
    return 0;
224
0
  }
225
0
}
226
227
static int
228
dissect_net_dm_attrs_stats(tvbuff_t *tvb, void *data _U_, struct packet_netlink_data *nl_data, proto_tree *tree, int nla_type, int offset, int len)
229
0
{
230
0
  enum ws_net_dm_attrs_stats type = (enum ws_net_dm_attrs_port) nla_type & NLA_TYPE_MASK;
231
232
0
  switch (type) {
233
0
  case WS_NET_DM_ATTR_STATS_DROPPED:
234
0
    proto_tree_add_item(tree, hf_net_dm_stats_dropped, tvb, offset, len, nl_data->encoding);
235
0
    return 1;
236
0
  default:
237
0
    return 0;
238
0
  }
239
0
}
240
241
static int
242
dissect_net_dm_attrs(tvbuff_t *tvb, void *data, struct packet_netlink_data *nl_data, proto_tree *tree, int nla_type, int offset, int len)
243
0
{
244
0
  enum ws_net_dm_attrs type = (enum ws_net_dm_attrs) nla_type & NLA_TYPE_MASK;
245
0
  struct netlink_net_dm_info *info = (struct netlink_net_dm_info *) data;
246
0
  uint64_t pc, timestamp;
247
0
  nstime_t ts_nstime;
248
0
  uint32_t value;
249
0
  uint16_t protocol;
250
0
  static dissector_table_t dissector_table;
251
0
  tvbuff_t *next_tvb;
252
0
  const uint8_t *str;
253
254
0
  switch (type) {
255
0
  case WS_NET_DM_ATTR_ALERT_MODE:
256
0
    proto_tree_add_item(tree, hf_net_dm_alert_mode, tvb, offset, len, nl_data->encoding);
257
0
    return 1;
258
0
  case WS_NET_DM_ATTR_PC:
259
0
    proto_tree_add_item_ret_uint64(tree, hf_net_dm_pc, tvb,
260
0
                 offset, 8, nl_data->encoding, &pc);
261
0
    proto_item_append_text(tree, ": 0x%" PRIx64, pc);
262
0
    return 1;
263
0
  case WS_NET_DM_ATTR_SYMBOL:
264
0
    proto_tree_add_item_ret_string(tree, hf_net_dm_symbol, tvb, offset, len, ENC_ASCII | ENC_NA, info->pinfo->pool, &str);
265
0
    proto_item_append_text(tree, ": %s", str);
266
0
    return 1;
267
0
  case WS_NET_DM_ATTR_IN_PORT:
268
0
    return dissect_netlink_attributes(tvb, hf_net_dm_attrs_port, ett_net_dm_attrs_in_port, info, nl_data, tree, offset, len,
269
0
              dissect_net_dm_attrs_port);
270
0
  case WS_NET_DM_ATTR_TIMESTAMP:
271
0
    timestamp = tvb_get_uint64(tvb, offset, nl_data->encoding);
272
0
    ts_nstime.secs = timestamp / 1000000000;
273
0
    ts_nstime.nsecs = timestamp % 1000000000;
274
0
    proto_tree_add_time(tree, hf_net_dm_timestamp, tvb, offset, 8, &ts_nstime);
275
0
    return 1;
276
0
  case WS_NET_DM_ATTR_PROTO:
277
0
    info->protocol = tvb_get_uint16(tvb, offset, nl_data->encoding);
278
279
0
    proto_tree_add_item(tree, hf_net_dm_proto, tvb, offset, len, nl_data->encoding);
280
0
    return 1;
281
0
  case WS_NET_DM_ATTR_PAYLOAD:
282
    /* This whole payload protocol thing is messed up:
283
    * We can't know from the kernel netlink message what we get exacly
284
    */
285
0
    protocol = info->protocol;
286
0
    dissector_table = sll_ltype_table;
287
    /* This attribute encodes 'skb->protocol' and if it is greater
288
     * than or equal to 1536 (0x0600), then it is an Ethertype and
289
     * we need to treat the packet as Ethernet.
290
     */
291
0
    if (info->protocol >= 1536 || info->protocol == LINUX_SLL_P_802_2) {
292
      /* It might be ethernet, but we're not really sure what the packet actually is.
293
      * We try a guess: if two bytes 12-14 match the Ethertype, then it's ethernet,
294
      * otherwise we just assume that we have is a payload of the Ethertype itself.
295
      * (this is not a perfect match, but in practice gives good enough results)
296
      *
297
      * If it's too short to be Ethernet, then for sure we don't have an Ethernet payload.
298
      */
299
0
      if (len >= 14 && tvb_get_uint16(tvb, offset + 12, ENC_BIG_ENDIAN) == info->protocol) {
300
0
        protocol = LINUX_SLL_P_ETHERNET;
301
0
      } else {
302
0
        dissector_table = ethertype_table;
303
0
      }
304
0
    }
305
306
307
0
    next_tvb = tvb_new_subset_length(tvb, offset, len);
308
0
    if (!dissector_try_uint(dissector_table, protocol, next_tvb, info->pinfo, tree))
309
0
      call_data_dissector(next_tvb, info->pinfo, tree);
310
0
    return 1;
311
0
  case WS_NET_DM_ATTR_TRUNC_LEN:
312
0
    proto_tree_add_item_ret_uint(tree, hf_net_dm_trunc_len, tvb, offset, len, nl_data->encoding, &value);
313
0
    proto_item_append_text(tree, ": %u", value);
314
0
    return 1;
315
0
  case WS_NET_DM_ATTR_ORIG_LEN:
316
0
    proto_tree_add_item_ret_uint(tree, hf_net_dm_orig_len, tvb, offset, len, nl_data->encoding, &value);
317
0
    proto_item_append_text(tree, ": %u", value);
318
0
    return 1;
319
0
  case WS_NET_DM_ATTR_QUEUE_LEN:
320
0
    proto_tree_add_item_ret_uint(tree, hf_net_dm_queue_len, tvb, offset, len, nl_data->encoding, &value);
321
0
    proto_item_append_text(tree, ": %u", value);
322
0
    return 1;
323
0
  case WS_NET_DM_ATTR_STATS:
324
0
    return dissect_netlink_attributes(tvb, hf_net_dm_attrs_stats, ett_net_dm_attrs_stats, info, nl_data, tree, offset, len,
325
0
              dissect_net_dm_attrs_stats);
326
0
  case WS_NET_DM_ATTR_HW_STATS:
327
0
    return dissect_netlink_attributes(tvb, hf_net_dm_attrs_stats, ett_net_dm_attrs_hw_stats, info, nl_data, tree, offset, len,
328
0
              dissect_net_dm_attrs_stats);
329
0
  case WS_NET_DM_ATTR_ORIGIN:
330
0
    proto_tree_add_item(tree, hf_net_dm_origin, tvb, offset, len, nl_data->encoding);
331
0
    return 1;
332
0
  case WS_NET_DM_ATTR_HW_TRAP_GROUP_NAME:
333
0
    proto_tree_add_item_ret_string(tree, hf_net_dm_hw_trap_group_name, tvb, offset, len, ENC_ASCII | ENC_NA, info->pinfo->pool, &str);
334
0
    proto_item_append_text(tree, ": %s", str);
335
0
    return 1;
336
0
  case WS_NET_DM_ATTR_HW_TRAP_NAME:
337
0
    proto_tree_add_item_ret_string(tree, hf_net_dm_hw_trap_name, tvb, offset, len, ENC_ASCII | ENC_NA, info->pinfo->pool, &str);
338
0
    proto_item_append_text(tree, ": %s", str);
339
0
    return 1;
340
0
  case WS_NET_DM_ATTR_HW_ENTRIES:
341
0
    return dissect_netlink_attributes(tvb, hf_net_dm_attrs, ett_net_dm_attrs_hw_entries, info, nl_data, tree, offset, len,
342
0
              dissect_net_dm_attrs);
343
0
  case WS_NET_DM_ATTR_HW_ENTRY:
344
0
    return dissect_netlink_attributes(tvb, hf_net_dm_attrs, ett_net_dm_attrs_hw_entry, info, nl_data, tree, offset, len,
345
0
              dissect_net_dm_attrs);
346
0
  case WS_NET_DM_ATTR_HW_TRAP_COUNT:
347
0
    proto_tree_add_item_ret_uint(tree, hf_net_dm_hw_trap_count, tvb, offset, len, nl_data->encoding, &value);
348
0
    proto_item_append_text(tree, ": %u", value);
349
0
    return 1;
350
0
  case WS_NET_DM_ATTR_SW_DROPS:
351
0
    proto_tree_add_item(tree, hf_net_dm_sw, tvb, offset, len, nl_data->encoding);
352
0
    return 1;
353
0
  case WS_NET_DM_ATTR_HW_DROPS:
354
0
    proto_tree_add_item(tree, hf_net_dm_hw, tvb, offset, len, nl_data->encoding);
355
0
    return 1;
356
0
  case WS_NET_DM_ATTR_FLOW_ACTION_COOKIE:
357
0
    proto_tree_add_item(tree, hf_net_dm_flow_action_cookie, tvb, offset, len, ENC_NA);
358
0
    return 1;
359
0
  case WS_NET_DM_ATTR_REASON:
360
0
    proto_tree_add_item_ret_string(tree, hf_net_dm_reason, tvb, offset, len, ENC_ASCII | ENC_NA, info->pinfo->pool, &str);
361
0
    proto_item_append_text(tree, ": %s", str);
362
0
    return 1;
363
0
  default:
364
0
    return 0;
365
0
  }
366
0
}
367
368
static int
369
dissect_netlink_net_dm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
370
0
{
371
0
  genl_info_t *genl_info = (genl_info_t *)data;
372
0
  struct netlink_net_dm_info info;
373
0
  proto_tree *nlmsg_tree;
374
0
  proto_item *pi;
375
0
  int offset;
376
377
0
  DISSECTOR_ASSERT(genl_info);
378
379
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "net_dm");
380
0
  col_clear(pinfo->cinfo, COL_INFO);
381
382
  /* Generic netlink header */
383
0
  offset = dissect_genl_header(tvb, genl_info, genl_info->nl_data, hf_net_dm_commands);
384
385
  /* Not all commands have a payload */
386
0
  if (!tvb_reported_length_remaining(tvb, offset))
387
    /* XXX If you do not set the protocol item, you cannot filter on these messages */
388
0
    return offset;
389
390
0
  pi = proto_tree_add_item(tree, proto_netlink_net_dm, tvb, offset, -1, ENC_NA);
391
0
  nlmsg_tree = proto_item_add_subtree(pi, ett_net_dm);
392
393
0
  info.pinfo = pinfo;
394
0
  info.protocol = 0;
395
396
0
  offset = dissect_netlink_attributes_to_end(tvb, hf_net_dm_attrs, ett_net_dm_attrs, &info, genl_info->nl_data, nlmsg_tree, offset, dissect_net_dm_attrs);
397
398
0
  return offset;
399
0
}
400
401
void
402
proto_register_netlink_net_dm(void)
403
15
{
404
15
  static hf_register_info hf[] = {
405
15
    { &hf_net_dm_commands,
406
15
      { "Command", "net_dm.cmd",
407
15
        FT_UINT8, BASE_DEC | BASE_EXT_STRING, &ws_net_dm_commands_vals_ext, 0x00,
408
15
        NULL, HFILL }
409
15
    },
410
15
    { &hf_net_dm_attrs,
411
15
      { "Attribute type", "net_dm.attr_type",
412
15
        FT_UINT16, BASE_DEC | BASE_EXT_STRING, &ws_net_dm_attrs_vals_ext, NLA_TYPE_MASK,
413
15
        NULL, HFILL }
414
15
    },
415
15
    { &hf_net_dm_alert_mode,
416
15
      { "Alert mode", "net_dm.alert_mode",
417
15
        FT_UINT8, BASE_DEC, VALS(ws_net_dm_alert_mode_vals), 0x00,
418
15
        NULL, HFILL }
419
15
    },
420
15
    { &hf_net_dm_pc,
421
15
      { "Program counter", "net_dm.pc",
422
15
        FT_UINT64, BASE_HEX, NULL, 0x00,
423
15
        NULL, HFILL }
424
15
    },
425
15
    { &hf_net_dm_symbol,
426
15
      { "Symbol", "net_dm.symbol",
427
15
        FT_STRINGZ, BASE_NONE, NULL, 0x00,
428
15
        NULL, HFILL }
429
15
    },
430
15
    { &hf_net_dm_attrs_port,
431
15
      { "Attribute type", "net_dm.port.attr_type",
432
15
        FT_UINT16, BASE_DEC, VALS(ws_net_dm_attrs_port_vals), NLA_TYPE_MASK,
433
15
        NULL, HFILL }
434
15
    },
435
15
    { &hf_net_dm_timestamp,
436
15
      { "Timestamp", "net_dm.timestamp",
437
15
        FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x00,
438
15
        NULL, HFILL }
439
15
    },
440
15
    { &hf_net_dm_proto,
441
15
      { "Protocol", "net_dm.proto",
442
15
        FT_UINT16, BASE_HEX, NULL, 0x00,
443
15
        NULL, HFILL }
444
15
    },
445
15
    { &hf_net_dm_trunc_len,
446
15
      { "Truncation length", "net_dm.trunc_len",
447
15
        FT_UINT32, BASE_DEC, NULL, 0x00,
448
15
        NULL, HFILL }
449
15
    },
450
15
    { &hf_net_dm_orig_len,
451
15
      { "Original length", "net_dm.orig_len",
452
15
        FT_UINT32, BASE_DEC, NULL, 0x00,
453
15
        NULL, HFILL }
454
15
    },
455
15
    { &hf_net_dm_queue_len,
456
15
      { "Queue length", "net_dm.queue_len",
457
15
        FT_UINT32, BASE_DEC, NULL, 0x00,
458
15
        NULL, HFILL }
459
15
    },
460
15
    { &hf_net_dm_attrs_stats,
461
15
      { "Attribute type", "net_dm.stats.attr_type",
462
15
        FT_UINT16, BASE_DEC, VALS(ws_net_dm_attrs_stats_vals), NLA_TYPE_MASK,
463
15
        NULL, HFILL }
464
15
    },
465
15
    { &hf_net_dm_origin,
466
15
      { "Packet origin", "net_dm.origin",
467
15
        FT_UINT16, BASE_DEC, VALS(ws_net_dm_origin_vals), 0x00,
468
15
        NULL, HFILL }
469
15
    },
470
15
    { &hf_net_dm_hw_trap_group_name,
471
15
      { "Hardware trap group name", "net_dm.hw_trap_group_name",
472
15
        FT_STRINGZ, BASE_NONE, NULL, 0x00,
473
15
        NULL, HFILL }
474
15
    },
475
15
    { &hf_net_dm_hw_trap_name,
476
15
      { "Hardware trap name", "net_dm.hw_trap_name",
477
15
        FT_STRINGZ, BASE_NONE, NULL, 0x00,
478
15
        NULL, HFILL }
479
15
    },
480
15
    { &hf_net_dm_hw_trap_count,
481
15
      { "Hardware trap count", "net_dm.hw_trap_count",
482
15
        FT_UINT32, BASE_DEC, NULL, 0x00,
483
15
        NULL, HFILL }
484
15
    },
485
15
    { &hf_net_dm_sw,
486
15
      { "Software", "net_dm.sw",
487
15
        FT_NONE, BASE_NONE, NULL, 0x00,
488
15
        NULL, HFILL }
489
15
    },
490
15
    { &hf_net_dm_hw,
491
15
      { "Hardware", "net_dm.hw",
492
15
        FT_NONE, BASE_NONE, NULL, 0x00,
493
15
        NULL, HFILL }
494
15
    },
495
15
    { &hf_net_dm_port_netdev_index,
496
15
      { "Port net device index", "net_dm.port.netdev_index",
497
15
        FT_UINT32, BASE_DEC, NULL, 0x00,
498
15
        NULL, HFILL }
499
15
    },
500
15
    { &hf_net_dm_port_netdev_name,
501
15
      { "Port net device name", "net_dm.port.netdev_name",
502
15
        FT_STRINGZ, BASE_NONE, NULL, 0x00,
503
15
        NULL, HFILL }
504
15
    },
505
15
    { &hf_net_dm_stats_dropped,
506
15
      { "Dropped", "net_dm.stats.dropped",
507
15
        FT_UINT64, BASE_DEC, NULL, 0x00,
508
15
        NULL, HFILL }
509
15
    },
510
15
    { &hf_net_dm_flow_action_cookie,
511
15
      { "Flow action cookie", "net_dm.cookie",
512
15
        FT_BYTES, BASE_NONE, NULL, 0x00,
513
15
        NULL, HFILL }
514
15
    },
515
15
    { &hf_net_dm_reason,
516
15
      { "Reason", "net_dm.reason",
517
15
        FT_STRINGZ, BASE_NONE, NULL, 0x00,
518
15
        NULL, HFILL }
519
15
    },
520
15
  };
521
522
15
  static int *ett[] = {
523
15
    &ett_net_dm,
524
15
    &ett_net_dm_attrs,
525
15
    &ett_net_dm_attrs_in_port,
526
15
    &ett_net_dm_attrs_stats,
527
15
    &ett_net_dm_attrs_hw_stats,
528
15
    &ett_net_dm_attrs_hw_entries,
529
15
    &ett_net_dm_attrs_hw_entry,
530
15
  };
531
532
15
  proto_netlink_net_dm = proto_register_protocol("Linux net_dm (network drop monitor) protocol", "net_dm", "net_dm");
533
15
  proto_register_field_array(proto_netlink_net_dm, hf, array_length(hf));
534
15
  proto_register_subtree_array(ett, array_length(ett));
535
536
15
  netlink_net_dm_handle = register_dissector("net_dm", dissect_netlink_net_dm, proto_netlink_net_dm);
537
15
}
538
539
void
540
proto_reg_handoff_netlink_net_dm(void)
541
15
{
542
15
  dissector_add_string("genl.family", "NET_DM", netlink_net_dm_handle);
543
15
  sll_ltype_table = find_dissector_table("sll.ltype");
544
15
  ethertype_table = find_dissector_table("ethertype");
545
15
}
546
547
/*
548
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
549
 *
550
 * Local variables:
551
 * c-basic-offset: 8
552
 * tab-width: 8
553
 * indent-tabs-mode: t
554
 * End:
555
 *
556
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
557
 * :indentSize=8:tabSize=8:noTabs=false:
558
 */