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>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * SPDX-License-Identifier: GPL-2.0-or-later
14 /* net_dm (network drop monitor) is a netlink-based protocol via which alerts
15 * about dropped packets are sent to user space
17 * Relevant Linux kernel header file:
18 * include/uapi/linux/net_dropmon.h
26 #include <epan/packet.h>
28 #include "packet-netlink.h"
29 #include "packet-sll.h"
31 void proto_register_netlink_net_dm(void);
32 void proto_reg_handoff_netlink_net_dm(void);
34 enum ws_net_dm_commands
{
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
,
47 enum ws_net_dm_attrs
{
48 WS_NET_DM_ATTR_UNSPEC
,
49 WS_NET_DM_ATTR_ALERT_MODE
,
51 WS_NET_DM_ATTR_SYMBOL
,
52 WS_NET_DM_ATTR_IN_PORT
,
53 WS_NET_DM_ATTR_TIMESTAMP
,
55 WS_NET_DM_ATTR_PAYLOAD
,
57 WS_NET_DM_ATTR_TRUNC_LEN
,
58 WS_NET_DM_ATTR_ORIG_LEN
,
59 WS_NET_DM_ATTR_QUEUE_LEN
,
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
,
74 enum ws_net_dm_attrs_port
{
75 WS_NET_DM_ATTR_PORT_NETDEV_IFINDEX
,
76 WS_NET_DM_ATTR_PORT_NETDEV_NAME
,
79 enum ws_net_dm_attrs_stats
{
80 WS_NET_DM_ATTR_STATS_DROPPED
,
83 enum ws_net_dm_alert_mode
{
84 WS_NET_DM_ALERT_MODE_SUMMARY
,
85 WS_NET_DM_ALERT_MODE_PACKET
,
88 enum ws_net_dm_origin
{
93 struct netlink_net_dm_info
{
95 uint16_t protocol
; /* protocol for packet payload */
98 static dissector_handle_t netlink_net_dm_handle
;
99 static dissector_table_t sll_ltype_table
;
100 static dissector_table_t ethertype_table
;
102 static int proto_netlink_net_dm
;
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
;
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
;
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" },
150 static value_string_ext ws_net_dm_commands_vals_ext
= VALUE_STRING_EXT_INIT(ws_net_dm_commands_vals
);
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" },
180 static value_string_ext ws_net_dm_attrs_vals_ext
= VALUE_STRING_EXT_INIT(ws_net_dm_attrs_vals
);
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" },
188 static const value_string ws_net_dm_attrs_stats_vals
[] = {
189 { WS_NET_DM_ATTR_STATS_DROPPED
, "Dropped" },
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" },
199 static const value_string ws_net_dm_origin_vals
[] = {
200 { WS_NET_DM_ORIGIN_SW
, "Software" },
201 { WS_NET_DM_ORIGIN_HW
, "Hardware" },
206 dissect_net_dm_attrs_port(tvbuff_t
*tvb
, void *data _U_
, struct packet_netlink_data
*nl_data
, proto_tree
*tree
, int nla_type
, int offset
, int len
)
208 enum ws_net_dm_attrs_port type
= (enum ws_net_dm_attrs_port
) nla_type
& NLA_TYPE_MASK
;
213 case WS_NET_DM_ATTR_PORT_NETDEV_IFINDEX
:
214 proto_tree_add_item_ret_uint(tree
, hf_net_dm_port_netdev_index
, tvb
, offset
, len
, nl_data
->encoding
, &value
);
215 proto_item_append_text(tree
, ": %u", value
);
217 case WS_NET_DM_ATTR_PORT_NETDEV_NAME
:
218 proto_tree_add_item_ret_string(tree
, hf_net_dm_port_netdev_name
, tvb
, offset
, len
, ENC_ASCII
| ENC_NA
, wmem_packet_scope(), &str
);
219 proto_item_append_text(tree
, ": %s", str
);
227 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 enum ws_net_dm_attrs_port type
= (enum ws_net_dm_attrs_port
) nla_type
& NLA_TYPE_MASK
;
232 case WS_NET_DM_ATTR_STATS_DROPPED
:
233 proto_tree_add_item(tree
, hf_net_dm_stats_dropped
, tvb
, offset
, len
, nl_data
->encoding
);
241 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 enum ws_net_dm_attrs type
= (enum ws_net_dm_attrs
) nla_type
& NLA_TYPE_MASK
;
244 struct netlink_net_dm_info
*info
= (struct netlink_net_dm_info
*) data
;
245 uint64_t pc
, timestamp
;
249 static dissector_table_t dissector_table
;
254 case WS_NET_DM_ATTR_ALERT_MODE
:
255 proto_tree_add_item(tree
, hf_net_dm_alert_mode
, tvb
, offset
, len
, nl_data
->encoding
);
257 case WS_NET_DM_ATTR_PC
:
258 proto_tree_add_item_ret_uint64(tree
, hf_net_dm_pc
, tvb
,
259 offset
, 8, nl_data
->encoding
, &pc
);
260 proto_item_append_text(tree
, ": 0x%" PRIx64
, pc
);
262 case WS_NET_DM_ATTR_SYMBOL
:
263 proto_tree_add_item_ret_string(tree
, hf_net_dm_symbol
, tvb
, offset
, len
, ENC_ASCII
| ENC_NA
, wmem_packet_scope(), &str
);
264 proto_item_append_text(tree
, ": %s", str
);
266 case WS_NET_DM_ATTR_IN_PORT
:
267 return dissect_netlink_attributes(tvb
, hf_net_dm_attrs_port
, ett_net_dm_attrs_in_port
, info
, nl_data
, tree
, offset
, len
,
268 dissect_net_dm_attrs_port
);
269 case WS_NET_DM_ATTR_TIMESTAMP
:
270 timestamp
= tvb_get_uint64(tvb
, offset
, nl_data
->encoding
);
271 ts_nstime
.secs
= timestamp
/ 1000000000;
272 ts_nstime
.nsecs
= timestamp
% 1000000000;
273 proto_tree_add_time(tree
, hf_net_dm_timestamp
, tvb
, offset
, 8, &ts_nstime
);
275 case WS_NET_DM_ATTR_PROTO
:
276 info
->protocol
= tvb_get_uint16(tvb
, offset
, nl_data
->encoding
);
278 proto_tree_add_item(tree
, hf_net_dm_proto
, tvb
, offset
, len
, nl_data
->encoding
);
280 case WS_NET_DM_ATTR_PAYLOAD
:
281 /* This whole payload protocol thing is messed up:
282 * We can't know from the kernel netlink message what we get exacly
284 protocol
= info
->protocol
;
285 dissector_table
= sll_ltype_table
;
286 /* This attribute encodes 'skb->protocol' and if it is greater
287 * than or equal to 1536 (0x0600), then it is an Ethertype and
288 * we need to treat the packet as Ethernet.
290 if (info
->protocol
>= 1536 || info
->protocol
== LINUX_SLL_P_802_2
) {
291 /* It might be ethernet, but we're not really sure what the packet actually is.
292 * We try a guess: if two bytes 12-14 match the Ethertype, then it's ethernet,
293 * otherwise we just assume that we have is a payload of the Ethertype itself.
294 * (this is not a perfect match, but in practice gives good enough results)
296 * If it's too short to be Ethernet, then for sure we don't have an Ethernet payload.
298 if (len
>= 14 && tvb_get_uint16(tvb
, offset
+ 12, ENC_BIG_ENDIAN
) == info
->protocol
) {
299 protocol
= LINUX_SLL_P_ETHERNET
;
301 dissector_table
= ethertype_table
;
306 next_tvb
= tvb_new_subset_length(tvb
, offset
, len
);
307 if (!dissector_try_uint(dissector_table
, protocol
, next_tvb
, info
->pinfo
, tree
))
308 call_data_dissector(next_tvb
, info
->pinfo
, tree
);
310 case WS_NET_DM_ATTR_TRUNC_LEN
:
311 proto_tree_add_item_ret_uint(tree
, hf_net_dm_trunc_len
, tvb
, offset
, len
, nl_data
->encoding
, &value
);
312 proto_item_append_text(tree
, ": %u", value
);
314 case WS_NET_DM_ATTR_ORIG_LEN
:
315 proto_tree_add_item_ret_uint(tree
, hf_net_dm_orig_len
, tvb
, offset
, len
, nl_data
->encoding
, &value
);
316 proto_item_append_text(tree
, ": %u", value
);
318 case WS_NET_DM_ATTR_QUEUE_LEN
:
319 proto_tree_add_item_ret_uint(tree
, hf_net_dm_queue_len
, tvb
, offset
, len
, nl_data
->encoding
, &value
);
320 proto_item_append_text(tree
, ": %u", value
);
322 case WS_NET_DM_ATTR_STATS
:
323 return dissect_netlink_attributes(tvb
, hf_net_dm_attrs_stats
, ett_net_dm_attrs_stats
, info
, nl_data
, tree
, offset
, len
,
324 dissect_net_dm_attrs_stats
);
325 case WS_NET_DM_ATTR_HW_STATS
:
326 return dissect_netlink_attributes(tvb
, hf_net_dm_attrs_stats
, ett_net_dm_attrs_hw_stats
, info
, nl_data
, tree
, offset
, len
,
327 dissect_net_dm_attrs_stats
);
328 case WS_NET_DM_ATTR_ORIGIN
:
329 proto_tree_add_item(tree
, hf_net_dm_origin
, tvb
, offset
, len
, nl_data
->encoding
);
331 case WS_NET_DM_ATTR_HW_TRAP_GROUP_NAME
:
332 proto_tree_add_item_ret_string(tree
, hf_net_dm_hw_trap_group_name
, tvb
, offset
, len
, ENC_ASCII
| ENC_NA
, wmem_packet_scope(), &str
);
333 proto_item_append_text(tree
, ": %s", str
);
335 case WS_NET_DM_ATTR_HW_TRAP_NAME
:
336 proto_tree_add_item_ret_string(tree
, hf_net_dm_hw_trap_name
, tvb
, offset
, len
, ENC_ASCII
| ENC_NA
, wmem_packet_scope(), &str
);
337 proto_item_append_text(tree
, ": %s", str
);
339 case WS_NET_DM_ATTR_HW_ENTRIES
:
340 return dissect_netlink_attributes(tvb
, hf_net_dm_attrs
, ett_net_dm_attrs_hw_entries
, info
, nl_data
, tree
, offset
, len
,
341 dissect_net_dm_attrs
);
342 case WS_NET_DM_ATTR_HW_ENTRY
:
343 return dissect_netlink_attributes(tvb
, hf_net_dm_attrs
, ett_net_dm_attrs_hw_entry
, info
, nl_data
, tree
, offset
, len
,
344 dissect_net_dm_attrs
);
345 case WS_NET_DM_ATTR_HW_TRAP_COUNT
:
346 proto_tree_add_item_ret_uint(tree
, hf_net_dm_hw_trap_count
, tvb
, offset
, len
, nl_data
->encoding
, &value
);
347 proto_item_append_text(tree
, ": %u", value
);
349 case WS_NET_DM_ATTR_SW_DROPS
:
350 proto_tree_add_item(tree
, hf_net_dm_sw
, tvb
, offset
, len
, nl_data
->encoding
);
352 case WS_NET_DM_ATTR_HW_DROPS
:
353 proto_tree_add_item(tree
, hf_net_dm_hw
, tvb
, offset
, len
, nl_data
->encoding
);
355 case WS_NET_DM_ATTR_FLOW_ACTION_COOKIE
:
356 proto_tree_add_item(tree
, hf_net_dm_flow_action_cookie
, tvb
, offset
, len
, ENC_NA
);
358 case WS_NET_DM_ATTR_REASON
:
359 proto_tree_add_item_ret_string(tree
, hf_net_dm_reason
, tvb
, offset
, len
, ENC_ASCII
| ENC_NA
, wmem_packet_scope(), &str
);
360 proto_item_append_text(tree
, ": %s", str
);
368 dissect_netlink_net_dm(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
370 genl_info_t
*genl_info
= (genl_info_t
*)data
;
371 struct netlink_net_dm_info info
;
372 proto_tree
*nlmsg_tree
;
376 DISSECTOR_ASSERT(genl_info
);
378 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "net_dm");
379 col_clear(pinfo
->cinfo
, COL_INFO
);
381 /* Generic netlink header */
382 offset
= dissect_genl_header(tvb
, genl_info
, genl_info
->nl_data
, hf_net_dm_commands
);
384 /* Not all commands have a payload */
385 if (!tvb_reported_length_remaining(tvb
, offset
))
386 /* XXX If you do not set the protocol item, you cannot filter on these messages */
389 pi
= proto_tree_add_item(tree
, proto_netlink_net_dm
, tvb
, offset
, -1, ENC_NA
);
390 nlmsg_tree
= proto_item_add_subtree(pi
, ett_net_dm
);
395 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
);
401 proto_register_netlink_net_dm(void)
403 static hf_register_info hf
[] = {
404 { &hf_net_dm_commands
,
405 { "Command", "net_dm.cmd",
406 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
, &ws_net_dm_commands_vals_ext
, 0x00,
410 { "Attribute type", "net_dm.attr_type",
411 FT_UINT16
, BASE_DEC
| BASE_EXT_STRING
, &ws_net_dm_attrs_vals_ext
, NLA_TYPE_MASK
,
414 { &hf_net_dm_alert_mode
,
415 { "Alert mode", "net_dm.alert_mode",
416 FT_UINT8
, BASE_DEC
, VALS(ws_net_dm_alert_mode_vals
), 0x00,
420 { "Program counter", "net_dm.pc",
421 FT_UINT64
, BASE_HEX
, NULL
, 0x00,
425 { "Symbol", "net_dm.symbol",
426 FT_STRINGZ
, BASE_NONE
, NULL
, 0x00,
429 { &hf_net_dm_attrs_port
,
430 { "Attribute type", "net_dm.port.attr_type",
431 FT_UINT16
, BASE_DEC
, VALS(ws_net_dm_attrs_port_vals
), NLA_TYPE_MASK
,
434 { &hf_net_dm_timestamp
,
435 { "Timestamp", "net_dm.timestamp",
436 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x00,
440 { "Protocol", "net_dm.proto",
441 FT_UINT16
, BASE_HEX
, NULL
, 0x00,
444 { &hf_net_dm_trunc_len
,
445 { "Truncation length", "net_dm.trunc_len",
446 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
449 { &hf_net_dm_orig_len
,
450 { "Original length", "net_dm.orig_len",
451 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
454 { &hf_net_dm_queue_len
,
455 { "Queue length", "net_dm.queue_len",
456 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
459 { &hf_net_dm_attrs_stats
,
460 { "Attribute type", "net_dm.stats.attr_type",
461 FT_UINT16
, BASE_DEC
, VALS(ws_net_dm_attrs_stats_vals
), NLA_TYPE_MASK
,
465 { "Packet origin", "net_dm.origin",
466 FT_UINT16
, BASE_DEC
, VALS(ws_net_dm_origin_vals
), 0x00,
469 { &hf_net_dm_hw_trap_group_name
,
470 { "Hardware trap group name", "net_dm.hw_trap_group_name",
471 FT_STRINGZ
, BASE_NONE
, NULL
, 0x00,
474 { &hf_net_dm_hw_trap_name
,
475 { "Hardware trap name", "net_dm.hw_trap_name",
476 FT_STRINGZ
, BASE_NONE
, NULL
, 0x00,
479 { &hf_net_dm_hw_trap_count
,
480 { "Hardware trap count", "net_dm.hw_trap_count",
481 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
485 { "Software", "net_dm.sw",
486 FT_NONE
, BASE_NONE
, NULL
, 0x00,
490 { "Hardware", "net_dm.hw",
491 FT_NONE
, BASE_NONE
, NULL
, 0x00,
494 { &hf_net_dm_port_netdev_index
,
495 { "Port net device index", "net_dm.port.netdev_index",
496 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
499 { &hf_net_dm_port_netdev_name
,
500 { "Port net device name", "net_dm.port.netdev_name",
501 FT_STRINGZ
, BASE_NONE
, NULL
, 0x00,
504 { &hf_net_dm_stats_dropped
,
505 { "Dropped", "net_dm.stats.dropped",
506 FT_UINT64
, BASE_DEC
, NULL
, 0x00,
509 { &hf_net_dm_flow_action_cookie
,
510 { "Flow action cookie", "net_dm.cookie",
511 FT_BYTES
, BASE_NONE
, NULL
, 0x00,
515 { "Reason", "net_dm.reason",
516 FT_STRINGZ
, BASE_NONE
, NULL
, 0x00,
521 static int *ett
[] = {
524 &ett_net_dm_attrs_in_port
,
525 &ett_net_dm_attrs_stats
,
526 &ett_net_dm_attrs_hw_stats
,
527 &ett_net_dm_attrs_hw_entries
,
528 &ett_net_dm_attrs_hw_entry
,
531 proto_netlink_net_dm
= proto_register_protocol("Linux net_dm (network drop monitor) protocol", "net_dm", "net_dm");
532 proto_register_field_array(proto_netlink_net_dm
, hf
, array_length(hf
));
533 proto_register_subtree_array(ett
, array_length(ett
));
535 netlink_net_dm_handle
= register_dissector("net_dm", dissect_netlink_net_dm
, proto_netlink_net_dm
);
539 proto_reg_handoff_netlink_net_dm(void)
541 dissector_add_string("genl.family", "NET_DM", netlink_net_dm_handle
);
542 sll_ltype_table
= find_dissector_table("sll.ltype");
543 ethertype_table
= find_dissector_table("ethertype");
547 * Editor modelines - https://www.wireshark.org/tools/modelines.html
552 * indent-tabs-mode: t
555 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
556 * :indentSize=8:tabSize=8:noTabs=false: