Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-netlink-psample.c
blob5054392ae3475feb6243b396549f84c505d84c50
1 /* packet-netlink-psample.c
2 * Routines for netlink-psample dissection
3 * Based on netlink-net_dm and netlink-generic dissectors
4 * Copyright 2021, Mellanox Technologies Ltd.
5 * Code by Amit Cohen <amcohen@nvidia.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 /* psample is a netlink-based protocol via which alerts
15 * about sampled packets are sent to user space
17 * Relevant Linux kernel header file:
18 * include/uapi/linux/psample.h
21 #include "config.h"
23 #include <epan/packet.h>
25 #include "packet-netlink.h"
26 #include "packet-sll.h"
28 void proto_register_netlink_psample(void);
29 void proto_reg_handoff_netlink_psample(void);
31 enum ws_psample_commands {
32 WS_PSAMPLE_CMD_SAMPLE,
33 WS_PSAMPLE_CMD_GET_GROUP,
34 WS_PSAMPLE_CMD_NEW_GROUP,
35 WS_PSAMPLE_CMD_DEL_GROUP,
38 enum ws_psample_attrs {
39 WS_PSAMPLE_ATTR_IIFINDEX,
40 WS_PSAMPLE_ATTR_OIFINDEX,
41 WS_PSAMPLE_ATTR_ORIGSIZE,
42 WS_PSAMPLE_ATTR_SAMPLE_GROUP,
43 WS_PSAMPLE_ATTR_GROUP_SEQ,
44 WS_PSAMPLE_ATTR_SAMPLE_RATE,
45 WS_PSAMPLE_ATTR_DATA,
46 WS_PSAMPLE_ATTR_GROUP_REFCOUNT,
47 WS_PSAMPLE_ATTR_TUNNEL,
48 WS_PSAMPLE_ATTR_PAD,
49 WS_PSAMPLE_ATTR_OUT_TC,
50 WS_PSAMPLE_ATTR_OUT_TC_OCC,
51 WS_PSAMPLE_ATTR_LATENCY,
52 WS_PSAMPLE_ATTR_TIMESTAMP,
53 WS_PSAMPLE_ATTR_PROTO,
56 struct netlink_psample_info {
57 packet_info *pinfo;
58 uint16_t protocol; /* protocol for packet payload */
61 static int proto_netlink_psample;
63 static dissector_handle_t netlink_psample_handle;
64 static dissector_table_t sll_ltype_table;
66 static int hf_psample_attrs;
67 static int hf_psample_commands;
68 static int hf_psample_group_refcount;
69 static int hf_psample_group_seq;
70 static int hf_psample_iifindex;
71 static int hf_psample_latency;
72 static int hf_psample_oifindex;
73 static int hf_psample_origsize;
74 static int hf_psample_out_tc;
75 static int hf_psample_out_tc_occ;
76 static int hf_psample_proto;
77 static int hf_psample_sample_group;
78 static int hf_psample_sample_rate;
79 static int hf_psample_timestamp;
80 static int hf_psample_tunnel;
82 static int ett_psample;
83 static int ett_psample_attrs;
85 static const value_string ws_psample_commands_vals[] = {
86 { WS_PSAMPLE_CMD_SAMPLE, "Sample" },
87 { WS_PSAMPLE_CMD_GET_GROUP, "Get group" },
88 { WS_PSAMPLE_CMD_NEW_GROUP, "New group" },
89 { WS_PSAMPLE_CMD_DEL_GROUP, "Delete group" },
90 { 0, NULL },
93 static value_string_ext ws_psample_commands_vals_ext = VALUE_STRING_EXT_INIT(ws_psample_commands_vals);
95 static const value_string ws_psample_attrs_vals[] = {
96 { WS_PSAMPLE_ATTR_IIFINDEX, "Input interface index" },
97 { WS_PSAMPLE_ATTR_OIFINDEX, "Output interface index" },
98 { WS_PSAMPLE_ATTR_ORIGSIZE, "Original size" },
99 { WS_PSAMPLE_ATTR_SAMPLE_GROUP, "Sample group" },
100 { WS_PSAMPLE_ATTR_GROUP_SEQ, "Group sequence number" },
101 { WS_PSAMPLE_ATTR_SAMPLE_RATE, "Sample rate" },
102 { WS_PSAMPLE_ATTR_DATA, "Data" },
103 { WS_PSAMPLE_ATTR_GROUP_REFCOUNT, "Group reference count" },
104 { WS_PSAMPLE_ATTR_TUNNEL, "Tunnel" },
105 { WS_PSAMPLE_ATTR_PAD, "Pad" },
106 { WS_PSAMPLE_ATTR_OUT_TC, "Output traffic class" },
107 { WS_PSAMPLE_ATTR_OUT_TC_OCC, "Output traffic class occupancy" },
108 { WS_PSAMPLE_ATTR_LATENCY, "Latency" },
109 { WS_PSAMPLE_ATTR_TIMESTAMP, "Timestamp" },
110 { WS_PSAMPLE_ATTR_PROTO, "Protocol" },
111 { 0, NULL },
114 static value_string_ext ws_psample_attrs_vals_ext = VALUE_STRING_EXT_INIT(ws_psample_attrs_vals);
116 static int
117 dissect_psample_attrs(tvbuff_t *tvb, void *data, struct packet_netlink_data *nl_data, proto_tree *tree, int nla_type, int offset, int len)
119 enum ws_psample_attrs type = (enum ws_psample_attrs) nla_type & NLA_TYPE_MASK;
120 struct netlink_psample_info *info = (struct netlink_psample_info *) data;
121 uint64_t value64, timestamp;
122 nstime_t ts_nstime;
123 tvbuff_t *next_tvb;
124 uint32_t value;
126 switch (type) {
127 case WS_PSAMPLE_ATTR_IIFINDEX:
128 proto_tree_add_item_ret_uint(tree, hf_psample_iifindex, tvb, offset, len, nl_data->encoding, &value);
129 proto_item_append_text(tree, ": %u", value);
130 return 1;
131 case WS_PSAMPLE_ATTR_OIFINDEX:
132 proto_tree_add_item_ret_uint(tree, hf_psample_oifindex, tvb, offset, len, nl_data->encoding, &value);
133 proto_item_append_text(tree, ": %u", value);
134 return 1;
135 case WS_PSAMPLE_ATTR_ORIGSIZE:
136 proto_tree_add_item_ret_uint(tree, hf_psample_origsize, tvb, offset, len, nl_data->encoding, &value);
137 proto_item_append_text(tree, ": %u", value);
138 return 1;
139 case WS_PSAMPLE_ATTR_SAMPLE_GROUP:
140 proto_tree_add_item_ret_uint(tree, hf_psample_sample_group, tvb, offset, len, nl_data->encoding, &value);
141 proto_item_append_text(tree, ": %u", value);
142 return 1;
143 case WS_PSAMPLE_ATTR_GROUP_SEQ:
144 proto_tree_add_item_ret_uint(tree, hf_psample_group_seq, tvb, offset, len, nl_data->encoding, &value);
145 proto_item_append_text(tree, ": %u", value);
146 return 1;
147 case WS_PSAMPLE_ATTR_SAMPLE_RATE:
148 proto_tree_add_item_ret_uint(tree, hf_psample_sample_rate, tvb, offset, len, nl_data->encoding, &value);
149 proto_item_append_text(tree, ": %u", value);
150 return 1;
151 case WS_PSAMPLE_ATTR_DATA:
152 next_tvb = tvb_new_subset_length(tvb, offset, len);
153 if (!dissector_try_uint(sll_ltype_table, info->protocol, next_tvb, info->pinfo, tree))
154 call_data_dissector(next_tvb, info->pinfo, tree);
155 return 1;
156 case WS_PSAMPLE_ATTR_GROUP_REFCOUNT:
157 proto_tree_add_item_ret_uint(tree, hf_psample_group_refcount, tvb, offset, len, nl_data->encoding, &value);
158 proto_item_append_text(tree, ": %u", value);
159 return 1;
160 case WS_PSAMPLE_ATTR_TUNNEL:
161 /* Currently there is no support for tunnel dissection. */
162 return 0;
163 case WS_PSAMPLE_ATTR_OUT_TC:
164 proto_tree_add_item_ret_uint(tree, hf_psample_out_tc, tvb, offset, len, nl_data->encoding, &value);
165 proto_item_append_text(tree, ": %u", value);
166 return 1;
167 case WS_PSAMPLE_ATTR_OUT_TC_OCC:
168 proto_tree_add_item_ret_uint64(tree, hf_psample_out_tc_occ, tvb, offset, len, nl_data->encoding, &value64);
169 proto_item_append_text(tree, ": %"PRIu64, value64);
170 return 1;
171 case WS_PSAMPLE_ATTR_LATENCY:
172 proto_tree_add_item_ret_uint64(tree, hf_psample_latency, tvb, offset, len, nl_data->encoding, &value64);
173 proto_item_append_text(tree, ": %"PRIu64, value64);
174 return 1;
175 case WS_PSAMPLE_ATTR_TIMESTAMP:
176 timestamp = tvb_get_uint64(tvb, offset, nl_data->encoding);
177 ts_nstime.secs = timestamp / 1000000000;
178 ts_nstime.nsecs = timestamp % 1000000000;
179 proto_tree_add_time(tree, hf_psample_timestamp, tvb, offset, 8, &ts_nstime);
180 return 1;
181 case WS_PSAMPLE_ATTR_PROTO:
182 info->protocol = tvb_get_uint16(tvb, offset, nl_data->encoding);
183 /* This attribute encodes 'skb->protocol' and if it is greater
184 * than or equal to 1536 (0x0600), then it is an Ethertype and
185 * we need to treat the packet as Ethernet.
187 if (info->protocol >= 1536 || info->protocol == LINUX_SLL_P_802_2)
188 info->protocol = LINUX_SLL_P_ETHERNET;
189 proto_tree_add_item(tree, hf_psample_proto, tvb, offset, len, nl_data->encoding);
190 return 1;
191 default:
192 return 0;
196 static int
197 dissect_netlink_psample(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
199 genl_info_t *genl_info = (genl_info_t *)data;
200 struct netlink_psample_info info;
201 proto_tree *nlmsg_tree;
202 proto_item *pi;
203 int offset;
205 DISSECTOR_ASSERT(genl_info);
207 col_set_str(pinfo->cinfo, COL_PROTOCOL, "psample");
208 col_clear(pinfo->cinfo, COL_INFO);
210 /* Generic netlink header */
211 offset = dissect_genl_header(tvb, genl_info, genl_info->nl_data, hf_psample_commands);
213 /* Not all commands have a payload */
214 if (!tvb_reported_length_remaining(tvb, offset))
215 /* XXX If you do not set the protocol item, you cannot filter on these messages */
216 return offset;
218 pi = proto_tree_add_item(tree, proto_netlink_psample, tvb, offset, -1, ENC_NA);
219 nlmsg_tree = proto_item_add_subtree(pi, ett_psample);
221 info.pinfo = pinfo;
222 info.protocol = 0;
224 offset = dissect_netlink_attributes_to_end(tvb, hf_psample_attrs, ett_psample_attrs, &info, genl_info->nl_data, nlmsg_tree, offset, dissect_psample_attrs);
226 return offset;
229 void
230 proto_register_netlink_psample(void)
232 static hf_register_info hf[] = {
233 { &hf_psample_commands,
234 { "Command", "psample.cmd",
235 FT_UINT8, BASE_DEC | BASE_EXT_STRING, &ws_psample_commands_vals_ext, 0x00,
236 NULL, HFILL }
238 { &hf_psample_attrs,
239 { "Attribute type", "psample.attr_type",
240 FT_UINT16, BASE_DEC | BASE_EXT_STRING, &ws_psample_attrs_vals_ext, NLA_TYPE_MASK,
241 NULL, HFILL }
243 { &hf_psample_iifindex,
244 { "Input interface index", "psample.iifindex",
245 FT_UINT16, BASE_HEX, NULL, 0x00,
246 NULL, HFILL }
248 { &hf_psample_oifindex,
249 { "Output interface index", "psample.oifindex",
250 FT_UINT16, BASE_HEX, NULL, 0x00,
251 NULL, HFILL }
253 { &hf_psample_origsize,
254 { "Original size", "psample.origsize",
255 FT_UINT32, BASE_HEX, NULL, 0x00,
256 NULL, HFILL }
258 { &hf_psample_sample_group,
259 { "Sample group", "psample.sample_group",
260 FT_UINT32, BASE_DEC, NULL, 0x00,
261 NULL, HFILL }
263 { &hf_psample_group_seq,
264 { "Group sequence number", "psample.group_seq_num",
265 FT_UINT32, BASE_DEC, NULL, 0x00,
266 NULL, HFILL }
268 { &hf_psample_sample_rate,
269 { "Sample rate", "psample.sample_rate",
270 FT_UINT32, BASE_DEC, NULL, 0x00,
271 NULL, HFILL }
273 { &hf_psample_tunnel,
274 { "Tunnel", "psample.tunnel",
275 FT_UINT32, BASE_HEX, NULL, 0x00,
276 NULL, HFILL }
278 { &hf_psample_group_refcount,
279 { "Group reference count", "psample.group_refcount",
280 FT_UINT32, BASE_HEX, NULL, 0x00,
281 NULL, HFILL }
283 { &hf_psample_out_tc,
284 { "Output traffic class", "psample.out_tc",
285 FT_UINT16, BASE_DEC, NULL, 0x00,
286 NULL, HFILL }
288 { &hf_psample_out_tc_occ,
289 { "Output traffic class occupancy", "psample.out_tc_occ",
290 FT_UINT64, BASE_DEC, NULL, 0x00,
291 NULL, HFILL }
293 { &hf_psample_latency,
294 { "Latency", "psample.latency",
295 FT_UINT64, BASE_DEC, NULL, 0x00,
296 NULL, HFILL }
298 { &hf_psample_timestamp,
299 { "Timestamp", "psample.timestamp",
300 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x00,
301 NULL, HFILL }
303 { &hf_psample_proto,
304 { "Protocol", "psample.proto",
305 FT_UINT16, BASE_HEX, NULL, 0x00,
306 NULL, HFILL }
310 static int *ett[] = {
311 &ett_psample,
312 &ett_psample_attrs,
315 proto_netlink_psample = proto_register_protocol("Linux psample protocol", "psample", "psample");
316 proto_register_field_array(proto_netlink_psample, hf, array_length(hf));
317 proto_register_subtree_array(ett, array_length(ett));
319 netlink_psample_handle = register_dissector("psample", dissect_netlink_psample, proto_netlink_psample);
322 void
323 proto_reg_handoff_netlink_psample(void)
325 dissector_add_string("genl.family", "psample", netlink_psample_handle);
326 sll_ltype_table = find_dissector_table("sll.ltype");
330 * Editor modelines - https://www.wireshark.org/tools/modelines.html
332 * Local variables:
333 * c-basic-offset: 8
334 * tab-width: 8
335 * indent-tabs-mode: t
336 * End:
338 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
339 * :indentSize=8:tabSize=8:noTabs=false: