Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-vsock.c
bloba44e67b68c32d61b2f9ad745b185b025edb23462
1 /* packet-vsock.c
2 * Routines for AF_VSOCK dissection
3 * Copyright 2016, Gerard Garcia <ggarcia@deic.uab.cat>
5 * Header definition:
6 * https://github.com/GerardGarcia/linux/blob/vsockmon/include/uapi/linux/vsockmon.h
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * SPDX-License-Identifier: GPL-2.0-or-later
16 * The AF_VSOCK socket allows zero-configuration communication between guests
17 * and hypervisors using the standard socket API.
20 #include <config.h>
21 #include <epan/packet.h>
22 #include <wsutil/pint.h>
23 #include <epan/address_types.h>
24 #include <wiretap/wtap.h>
26 void proto_register_vsock(void);
27 void proto_reg_handoff_vsock(void);
29 static int proto_vsock;
30 static int vsock_address_type = -1;
31 static dissector_handle_t vsock_handle;
33 /* Generic header related fields */
34 static int hf_vsock_src_cid;
35 static int hf_vsock_src_port;
36 static int hf_vsock_dst_cid;
37 static int hf_vsock_dst_port;
38 static int hf_vsock_op;
39 static int hf_vsock_t;
40 static int hf_vsock_t_len;
41 static int hf_vsock_reserved;
42 static int hf_vsock_payload;
44 /* Virtio related fields */
45 static int hf_virtio_src_cid;
46 static int hf_virtio_dst_cid;
47 static int hf_virtio_src_port;
48 static int hf_virtio_dst_port;
49 static int hf_virtio_len;
50 static int hf_virtio_type;
51 static int hf_virtio_op;
52 static int hf_virtio_flags;
53 static int hf_virtio_buf_alloc;
54 static int hf_virtio_fwd_cnt;
56 static int ett_vsock;
57 static int ett_virtio;
59 static const value_string af_vsockmon_op_names[] = {
60 { 0, "Unknown" },
61 { 1, "Connect" },
62 { 2, "Disconnect" },
63 { 3, "Control" },
64 { 4, "Payload" },
65 { 0, NULL }
68 enum af_vsockmon_t {
69 AF_VSOCK_T_UNKNOWN = 0,
70 AF_VSOCK_T_NO_INFO = 1,
71 AF_VSOCK_T_VIRTIO = 2
74 static const value_string af_vsockmon_t_names[] = {
75 { 0, "Unknown" },
76 { 1, "No info" },
77 { 2, "Virtio" },
78 { 0 , NULL }
81 static const value_string virtio_vsock_type_names[] = {
82 { 1, "Stream"},
83 { 0, NULL }
86 static const value_string virtio_vsock_op_names[] = {
87 { 0, "Invalid" },
88 { 1, "Request" },
89 { 2, "Response" },
90 { 3, "Rst" },
91 { 4, "Shutdown" },
92 { 5, "RW" },
93 { 6, "Credit update" },
94 { 7, "Credit response" },
95 { 0 , NULL }
98 #define VSOCK_MIN_LENGTH 32
100 static int vsock_addr_to_str(const address* addr, char *buf, int buf_len)
102 const uint8_t *addrp = (const uint8_t *)addr->data;
104 if(pletoh64(&addrp[0])==2){
105 (void) g_strlcpy(buf, "host", buf_len);
106 } else {
107 snprintf(buf, buf_len, "%" PRIu64, pletoh64(&addrp[0]));
110 return (int)(strlen(buf)+1);
113 static int vsock_addr_str_len(const address* addr _U_)
115 /* 2^64 unsigned int len */
116 return 19;
119 static int
120 dissect_vsock(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
121 void *data _U_)
123 proto_item *ti, *virtio_ti;
124 proto_tree *vsock_tree, *virtio_tree;
126 uint32_t t_len, payload_len, virtio_buf_alloc, op, type,
127 virtio_fwd_cnt, virtio_op, virtio_type;
128 uint16_t payload_offset = 0, offset = 0;
130 if (tvb_reported_length(tvb) < VSOCK_MIN_LENGTH)
131 return 0;
133 /* Clear column information before start parsing */
134 col_clear(pinfo->cinfo, COL_INFO);
136 /* Create top tree */
137 ti = proto_tree_add_item(tree, proto_vsock, tvb, 0, -1, ENC_NA);
138 vsock_tree = proto_item_add_subtree(ti, ett_vsock);
140 /* Parse generic header part */
141 proto_tree_add_item(vsock_tree, hf_vsock_src_cid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
142 set_address_tvb(&pinfo->src, vsock_address_type, 8, tvb, offset);
143 offset += 8;
145 proto_tree_add_item(vsock_tree, hf_vsock_dst_cid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
146 set_address_tvb(&pinfo->dst, vsock_address_type, 8, tvb, offset);
147 offset += 8;
149 proto_tree_add_item_ret_uint(vsock_tree, hf_vsock_src_port, tvb, offset, 4, ENC_LITTLE_ENDIAN, &pinfo->srcport);
150 offset += 4;
152 proto_tree_add_item_ret_uint(vsock_tree, hf_vsock_dst_port, tvb, offset, 4, ENC_LITTLE_ENDIAN, &pinfo->destport);
153 offset += 4;
155 proto_tree_add_item_ret_uint(vsock_tree, hf_vsock_op, tvb, offset, 2, ENC_LITTLE_ENDIAN, &op);
156 offset += 2;
158 proto_tree_add_item_ret_uint(vsock_tree, hf_vsock_t, tvb, offset, 2, ENC_LITTLE_ENDIAN, &type);
159 offset += 2;
161 proto_tree_add_item_ret_uint(vsock_tree, hf_vsock_t_len, tvb, offset, 2, ENC_LITTLE_ENDIAN, &t_len);
162 offset += 2;
164 proto_tree_add_item(vsock_tree, hf_vsock_reserved, tvb, offset, 2, ENC_NA);
165 offset += 2;
167 payload_offset = offset + t_len;
169 /* Append summary information to top tree */
170 proto_item_append_text(ti, ", Op: %s, Transport: %s",
171 val_to_str(op, af_vsockmon_op_names, "Unknown (%d)"),
172 val_to_str(type, af_vsockmon_t_names, "Unknown (%d)"));
174 /* Fill columns */
175 col_add_fstr(pinfo->cinfo, COL_INFO, "[%s] %s",
176 val_to_str(op, af_vsockmon_op_names, "Unknown (%d)"),
177 val_to_str(type, af_vsockmon_t_names, "Unknown (%d)"));
178 col_set_str(pinfo->cinfo, COL_PROTOCOL, "vSocket");
180 /* Create subtree if there is transport information */
181 switch (type) {
182 case AF_VSOCK_T_UNKNOWN:
183 case AF_VSOCK_T_NO_INFO:
184 break;
185 case AF_VSOCK_T_VIRTIO:
186 virtio_tree = proto_tree_add_subtree(vsock_tree, tvb, offset, 44, ett_virtio, &virtio_ti, "Virtio transport header");
188 proto_tree_add_item(virtio_tree, hf_virtio_src_cid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
189 offset += 8;
190 proto_tree_add_item(virtio_tree, hf_virtio_dst_cid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
191 offset += 8;
192 proto_tree_add_item(virtio_tree, hf_virtio_src_port, tvb, offset, 4, ENC_LITTLE_ENDIAN);
193 offset += 4;
194 proto_tree_add_item(virtio_tree, hf_virtio_dst_port, tvb, offset, 4, ENC_LITTLE_ENDIAN);
195 offset += 4;
196 proto_tree_add_item(virtio_tree, hf_virtio_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
197 offset += 4;
199 proto_tree_add_item_ret_uint(virtio_tree, hf_virtio_type, tvb, offset, 2, ENC_LITTLE_ENDIAN, &virtio_type);
200 offset += 2;
202 proto_tree_add_item_ret_uint(virtio_tree, hf_virtio_op, tvb, offset, 2, ENC_LITTLE_ENDIAN, &virtio_op);
203 offset += 2;
205 proto_tree_add_item(virtio_tree, hf_virtio_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
206 offset += 4;
208 proto_tree_add_item_ret_uint(virtio_tree, hf_virtio_buf_alloc, tvb, offset, 4, ENC_LITTLE_ENDIAN, &virtio_buf_alloc);
209 offset += 4;
211 proto_tree_add_item_ret_uint(virtio_tree, hf_virtio_fwd_cnt, tvb, offset, 4, ENC_LITTLE_ENDIAN, &virtio_fwd_cnt);
212 /*offset += 4;*/
214 /* Append virtio information */
215 col_append_fstr(pinfo->cinfo, COL_INFO, ": %s, Op: %s, Buf alloc: %u, Fwd cnt: %u",
216 val_to_str(virtio_type, virtio_vsock_type_names, "Unknown (%d)"),
217 val_to_str(virtio_op, virtio_vsock_op_names, "Unknown (%d)"),
218 virtio_buf_alloc, virtio_fwd_cnt);
219 break;
223 /* Append payload */
224 payload_len = tvb_reported_length_remaining(tvb, payload_offset);
225 if (payload_len)
226 proto_tree_add_bytes_format(vsock_tree, hf_vsock_payload, tvb, payload_offset, payload_len,
227 NULL, "Payload (%uB)", payload_len);
229 return tvb_reported_length(tvb);
232 void
233 proto_register_vsock(void)
235 static hf_register_info hf[] = {
236 { &hf_vsock_src_cid,
237 {"Source cid", "vsock.src_cid", FT_UINT64, BASE_DEC, NULL,
238 0x0, NULL, HFILL }},
239 { &hf_vsock_dst_cid,
240 {"Destination cid", "vsock.dst_cid", FT_UINT64, BASE_DEC, NULL,
241 0x0, NULL, HFILL }},
242 { &hf_vsock_src_port,
243 {"Source port", "vsock.src_port", FT_UINT32, BASE_DEC, NULL,
244 0x0, NULL, HFILL }},
245 { &hf_vsock_dst_port,
246 {"Destination port", "vsock.dst_port", FT_UINT32, BASE_DEC, NULL,
247 0x0, NULL, HFILL }},
248 { &hf_vsock_op,
249 {"Operation", "vsock.op", FT_UINT16, BASE_DEC, VALS(af_vsockmon_op_names),
250 0x0, NULL, HFILL }},
251 { &hf_vsock_t,
252 {"Transport", "vsock.trans", FT_UINT16, BASE_DEC, VALS(af_vsockmon_t_names),
253 0x0, NULL, HFILL }},
254 { &hf_vsock_t_len,
255 {"Transport length", "vsock.trans_len", FT_UINT16, BASE_DEC, NULL,
256 0x0, NULL, HFILL }},
257 { &hf_vsock_reserved,
258 {"Reserved", "vsock.reserved", FT_BYTES, BASE_NONE, NULL,
259 0x0, NULL, HFILL }},
260 { &hf_vsock_payload,
261 { "Payload", "vsock.payload", FT_BYTES, BASE_NONE, NULL,
262 0x0, NULL, HFILL}},
263 { &hf_virtio_src_cid,
264 {"Source cid", "vsock.virtio.src_cid", FT_UINT64, BASE_DEC, NULL,
265 0x0, NULL, HFILL }},
266 { &hf_virtio_dst_cid,
267 {"Destination cid", "vsock.virtio.dst_cid", FT_UINT64, BASE_DEC, NULL,
268 0x0, NULL, HFILL }},
269 { &hf_virtio_src_port,
270 {"Source port", "vsock.virtio.src_prot", FT_UINT32, BASE_DEC, NULL,
271 0x0, NULL, HFILL }},
272 { &hf_virtio_dst_port,
273 {"Destination port", "vsock.virtio.dst_prot", FT_UINT32, BASE_DEC, NULL,
274 0x0, NULL, HFILL }},
275 { &hf_virtio_len,
276 {"Length", "vsock.virtio.len", FT_UINT32, BASE_DEC, NULL,
277 0x0, NULL, HFILL }},
278 { &hf_virtio_type,
279 {"Type", "vsock.virtio.type", FT_UINT16, BASE_DEC, VALS(virtio_vsock_type_names),
280 0x0, NULL, HFILL }},
281 { &hf_virtio_op,
282 {"Operation", "vsock.virtio.op", FT_UINT16, BASE_DEC, VALS(virtio_vsock_op_names),
283 0x0, NULL, HFILL }},
284 { &hf_virtio_flags,
285 {"Flags", "vsock.virtio.flags", FT_UINT32, BASE_HEX, NULL,
286 0x0, NULL, HFILL }},
287 { &hf_virtio_buf_alloc,
288 {"Buf alloc", "vsock.virtio.buf_alloc", FT_UINT32, BASE_DEC, NULL,
289 0x0, NULL, HFILL }},
290 { &hf_virtio_fwd_cnt,
291 {"Fwd cnt", "vsock.virtio.fwd_cnt", FT_UINT32, BASE_DEC, NULL,
292 0x0, NULL, HFILL }}
294 static int *ett[] = {
295 &ett_vsock,
296 &ett_virtio
299 vsock_address_type = address_type_dissector_register("AT_VSOCK", "vSocket Address",
300 vsock_addr_to_str, vsock_addr_str_len, NULL, NULL, NULL, NULL, NULL);
302 proto_vsock = proto_register_protocol("vSocket", "vsock", "vsock");
303 proto_register_field_array(proto_vsock, hf, array_length(hf));
304 proto_register_subtree_array(ett, array_length(ett));
306 vsock_handle = register_dissector("vsock", dissect_vsock, proto_vsock);
309 void
310 proto_reg_handoff_vsock(void)
312 dissector_add_uint("wtap_encap", WTAP_ENCAP_VSOCK, vsock_handle);
316 * Editor modelines - https://www.wireshark.org/tools/modelines.html
318 * Local variables:
319 * c-basic-offset: 4
320 * tab-width: 8
321 * indent-tabs-mode: nil
322 * End:
324 * vi: set shiftwidth=4 tabstop=8 expandtab:
325 * :indentSize=4:tabSize=8:noTabs=true: