]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Add printing support for vsockmon devices.
authorGerard Garcia <[email protected]>
Tue, 14 Jun 2016 14:45:44 +0000 (16:45 +0200)
committerStefan Hajnoczi <[email protected]>
Tue, 16 Apr 2019 14:12:13 +0000 (15:12 +0100)
Print Linux 4.12 vsockmon captures:

  # modprobe vsockmon
  # ip link add type vsockmon
  # ip link set vsockmon0 up
  # tcpdump -i vsockmon0
  16:25:24.987917 VIRTIO 3.1025 > 2.1234 CONNECT, length 76
  16:25:24.987963 VIRTIO 2.1234 > 3.1025 CONNECT, length 76
  16:25:26.568271 VIRTIO 3.1025 > 2.1234 PAYLOAD, length 82
  16:25:26.568512 VIRTIO 2.1234 > 3.1025 CONTROL, length 76
  16:25:28.411335 VIRTIO 3.1025 > 2.1234 DISCONNECT, length 76
  16:25:28.411628 VIRTIO 2.1234 > 3.1025 DISCONNECT, length 76

For more information about vsock see:
http://wiki.qemu.org/Features/VirtioVsock

CMakeLists.txt
Makefile.in
netdissect.h
print-vsock.c [new file with mode: 0644]
print.c
win32/prj/GNUmakefile
win32/prj/WinDump.dsp
win32/prj/WinDump.vcproj

index 095d1f9f1e9b8a90ea99bb3c2244d91bafc4ab87..905bc787372f6cae35f66dd83427aee864875a9c 100644 (file)
@@ -1066,6 +1066,7 @@ set(NETDISSECT_SOURCE_LIST_C
     print-vjc.c
     print-vqp.c
     print-vrrp.c
+    print-vsock.c
     print-vtp.c
     print-vxlan.c
     print-vxlan-gpe.c
index 9176afcfdaf966d47c798ef70510af33c3101cd9..2096afba4afd128036c79e48b42bab9d1e844bf1 100644 (file)
@@ -229,6 +229,7 @@ LIBNETDISSECT_SRC=\
        print-vjc.c \
        print-vqp.c \
        print-vrrp.c \
+       print-vsock.c \
        print-vtp.c \
        print-vxlan.c \
        print-vxlan-gpe.c \
index debd38268234d2ea2fbfd95aed42daae04ae2a25..8cf1c08fed3d111d06bd5797c810cac075158c0a 100644 (file)
@@ -520,6 +520,7 @@ extern u_int symantec_if_print IF_PRINTER_ARGS;
 extern u_int token_if_print IF_PRINTER_ARGS;
 extern u_int usb_linux_48_byte_if_print IF_PRINTER_ARGS;
 extern u_int usb_linux_64_byte_if_print IF_PRINTER_ARGS;
+extern u_int vsock_if_print IF_PRINTER_ARGS;
 
 /*
  * Structure passed to some printers to allow them to print
diff --git a/print-vsock.c b/print-vsock.c
new file mode 100644 (file)
index 0000000..6d8a44e
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2016 Gerard Garcia <[email protected]>
+ * Copyright (c) 2017 Red Hat, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *   3. The names of the authors may not be used to endorse or promote
+ *      products derived from this software without specific prior
+ *      written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* \summary: Linux vsock printer */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "netdissect-stdinc.h"
+#include <stddef.h>
+
+#include "netdissect.h"
+#include "extract.h"
+
+enum af_vsockmon_transport {
+       AF_VSOCK_TRANSPORT_UNKNOWN = 0,
+       AF_VSOCK_TRANSPORT_NO_INFO = 1,         /* No transport information */
+       AF_VSOCK_TRANSPORT_VIRTIO = 2,          /* Virtio transport header */
+};
+
+static const struct tok vsock_transport[] = {
+       {AF_VSOCK_TRANSPORT_UNKNOWN, "UNKNOWN"},
+       {AF_VSOCK_TRANSPORT_NO_INFO, "NO_INFO"},
+       {AF_VSOCK_TRANSPORT_VIRTIO, "VIRTIO"},
+       { 0, NULL }
+};
+
+enum af_vsockmon_op {
+       AF_VSOCK_OP_UNKNOWN = 0,
+       AF_VSOCK_OP_CONNECT = 1,
+       AF_VSOCK_OP_DISCONNECT = 2,
+       AF_VSOCK_OP_CONTROL = 3,
+       AF_VSOCK_OP_PAYLOAD = 4,
+};
+
+static const struct tok vsock_op[] = {
+       {AF_VSOCK_OP_UNKNOWN, "UNKNOWN"},
+       {AF_VSOCK_OP_CONNECT, "CONNECT"},
+       {AF_VSOCK_OP_DISCONNECT, "DISCONNECT"},
+       {AF_VSOCK_OP_CONTROL, "CONTROL"},
+       {AF_VSOCK_OP_PAYLOAD, "PAYLOAD"},
+       { 0, NULL }
+};
+
+enum virtio_vsock_type {
+       VIRTIO_VSOCK_TYPE_STREAM = 1,
+};
+
+static const struct tok virtio_type[] = {
+       {VIRTIO_VSOCK_TYPE_STREAM, "STREAM"},
+       { 0, NULL }
+};
+
+enum virtio_vsock_op {
+       VIRTIO_VSOCK_OP_INVALID = 0,
+       VIRTIO_VSOCK_OP_REQUEST = 1,
+       VIRTIO_VSOCK_OP_RESPONSE = 2,
+       VIRTIO_VSOCK_OP_RST = 3,
+       VIRTIO_VSOCK_OP_SHUTDOWN = 4,
+       VIRTIO_VSOCK_OP_RW = 5,
+       VIRTIO_VSOCK_OP_CREDIT_UPDATE = 6,
+       VIRTIO_VSOCK_OP_CREDIT_REQUEST = 7,
+};
+
+static const struct tok virtio_op[] = {
+       {VIRTIO_VSOCK_OP_INVALID, "INVALID"},
+       {VIRTIO_VSOCK_OP_REQUEST, "REQUEST"},
+       {VIRTIO_VSOCK_OP_RESPONSE, "RESPONSE"},
+       {VIRTIO_VSOCK_OP_RST, "RST"},
+       {VIRTIO_VSOCK_OP_SHUTDOWN, "SHUTDOWN"},
+       {VIRTIO_VSOCK_OP_RW, "RW"},
+       {VIRTIO_VSOCK_OP_CREDIT_UPDATE, "CREDIT UPDATE"},
+       {VIRTIO_VSOCK_OP_CREDIT_REQUEST, "CREDIT REQUEST"},
+       { 0, NULL }
+};
+
+/* All fields are little-endian */
+
+struct virtio_vsock_hdr {
+       nd_uint64_t     src_cid;
+       nd_uint64_t     dst_cid;
+       nd_uint32_t     src_port;
+       nd_uint32_t     dst_port;
+       nd_uint32_t     len;
+       nd_uint16_t     type;           /* enum virtio_vsock_type */
+       nd_uint16_t     op;             /* enum virtio_vsock_op */
+       nd_uint32_t     flags;
+       nd_uint32_t     buf_alloc;
+       nd_uint32_t     fwd_cnt;
+};
+
+struct af_vsockmon_hdr {
+       nd_uint64_t     src_cid;
+       nd_uint64_t     dst_cid;
+       nd_uint32_t     src_port;
+       nd_uint32_t     dst_port;
+       nd_uint16_t     op;             /* enum af_vsockmon_op */
+       nd_uint16_t     transport;      /* enum af_vosckmon_transport */
+       nd_uint16_t     len;            /* size of transport header */
+       nd_uint8_t      reserved[2];
+};
+
+static void
+vsock_virtio_hdr_print(netdissect_options *ndo, const struct virtio_vsock_hdr *hdr)
+{
+       uint16_t u16_v;
+       uint32_t u32_v;
+
+       u32_v = GET_LE_U_4(&hdr->len);
+       ND_PRINT("len %u", u32_v);
+
+       u16_v = GET_LE_U_2(&hdr->type);
+       ND_PRINT(", type %s",
+                tok2str(virtio_type, "Invalid type (%hu)", u16_v));
+
+       u16_v = GET_LE_U_2(&hdr->op);
+       ND_PRINT(", op %s",
+                tok2str(virtio_op, "Invalid op (%hu)", u16_v));
+
+       u32_v = GET_LE_U_4(&hdr->flags);
+       ND_PRINT(", flags %x", u32_v);
+
+       u32_v = GET_LE_U_4(&hdr->buf_alloc);
+       ND_PRINT(", buf_alloc %u", u32_v);
+
+       u32_v = GET_LE_U_4(&hdr->fwd_cnt);
+       ND_PRINT(", fwd_cnt %u", u32_v);
+}
+
+static size_t
+vsock_transport_hdr_size(uint16_t transport)
+{
+       switch (transport) {
+               case AF_VSOCK_TRANSPORT_VIRTIO:
+                       return sizeof(struct virtio_vsock_hdr);
+               default:
+                       return 0;
+       }
+}
+
+/* Returns 0 on success, -1 on truncation */
+static int
+vsock_transport_hdr_print(netdissect_options *ndo, uint16_t transport,
+                          const u_char *p, const u_int len)
+{
+       size_t transport_size = vsock_transport_hdr_size(transport);
+       const void *hdr;
+
+       if (len < sizeof(struct af_vsockmon_hdr) + transport_size) {
+               return -1;
+       }
+
+       hdr = p + sizeof(struct af_vsockmon_hdr);
+       switch (transport) {
+               case AF_VSOCK_TRANSPORT_VIRTIO:
+                       ND_PRINT(" (");
+                       vsock_virtio_hdr_print(ndo, hdr);
+                       ND_PRINT(")");
+                       break;
+               default:
+                       break;
+       }
+       return 0;
+}
+
+static void
+vsock_hdr_print(netdissect_options *ndo, const u_char *p, const u_int len)
+{
+       const struct af_vsockmon_hdr *hdr = (const struct af_vsockmon_hdr *)p;
+       uint16_t hdr_transport, hdr_op;
+       uint32_t hdr_src_port, hdr_dst_port;
+       uint64_t hdr_src_cid, hdr_dst_cid;
+       size_t total_hdr_size;
+       int ret = 0;
+
+       hdr_transport = GET_LE_U_2(&hdr->transport);
+       ND_PRINT("%s",
+                tok2str(vsock_transport, "Invalid transport (%u)",
+                         hdr_transport));
+
+       /* If verbose level is more than 0 print transport details */
+       if (ndo->ndo_vflag) {
+               ret = vsock_transport_hdr_print(ndo, hdr_transport, p, len);
+               if (ret == 0)
+                       ND_PRINT("\n\t");
+       } else
+               ND_PRINT(" ");
+
+       hdr_src_cid = GET_LE_U_8(&hdr->src_cid);
+       hdr_dst_cid = GET_LE_U_8(&hdr->dst_cid);
+       hdr_src_port = GET_LE_U_4(&hdr->src_port);
+       hdr_dst_port = GET_LE_U_4(&hdr->dst_port);
+       hdr_op = GET_LE_U_2(&hdr->op);
+       ND_PRINT("%" PRIu64 ".%u > %" PRIu64 ".%u %s, length %u",
+                hdr_src_cid, hdr_src_port,
+                hdr_dst_cid, hdr_dst_port,
+                tok2str(vsock_op, " invalid op (%u)", hdr_op),
+                len);
+
+       if (ret < 0)
+               goto trunc;
+
+       /* If debug level is more than 1 print payload contents */
+       total_hdr_size = sizeof(struct af_vsockmon_hdr) +
+                        vsock_transport_hdr_size(hdr_transport);
+       if (ndo->ndo_vflag > 1 && hdr_op == AF_VSOCK_OP_PAYLOAD) {
+               if (len > total_hdr_size) {
+                       const u_char *payload = p + total_hdr_size;
+
+                       ND_PRINT("\n");
+                       print_unknown_data(ndo, payload, "\t",
+                                          len - total_hdr_size);
+               } else
+                       goto trunc;
+       }
+       return;
+
+trunc:
+       nd_print_trunc(ndo);
+}
+
+u_int
+vsock_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h,
+              const u_char *cp)
+{
+       u_int len = h->caplen;
+
+       ndo->ndo_protocol = "vsock";
+
+       if (len < sizeof(struct af_vsockmon_hdr))
+               nd_print_trunc(ndo);
+       else
+               vsock_hdr_print(ndo, cp, len);
+
+       return len;
+}
diff --git a/print.c b/print.c
index 21182ba26d2604ae51c54587d8a5bb7216933757..44040ecd8550a645cbd784cfe27a405c014fee68 100644 (file)
--- a/print.c
+++ b/print.c
@@ -233,6 +233,9 @@ static const struct printer printers[] = {
 #endif
 #ifdef DLT_DSA_TAG_BRCM_PREPEND
        { brcm_tag_prepend_if_print, DLT_DSA_TAG_BRCM_PREPEND },
+#endif
+#ifdef DLT_VSOCK
+       { vsock_if_print,       DLT_VSOCK },
 #endif
        { NULL,                 0 },
 };
index b5599f4f85d331c4f3a7e43b97459d693153f47e..dd0917def024633aae2c31166fd1982c680ee468 100644 (file)
@@ -139,6 +139,7 @@ OBJS = \
        ../../print-vjc.o \
        ../../print-vqp.o \
        ../../print-vrrp.o \
+       ../../print-vsock.o \
        ../../print-vtp.o \
        ../../print-wb.o \
        ../../print-zephyr.o \
index 1808774eaaf0cc1ed0ed33482156a011bbb6b02f..59b073f17246c74bca4df1fdb2f51347c316ec91 100644 (file)
@@ -696,6 +696,10 @@ SOURCE="..\..\print-vqp.c"
 SOURCE="..\..\print-vrrp.c"
 # End Source File
 # Begin Source File
+#
+SOURCE="..\..\print-vsock.c"
+# End Source File
+# Begin Source File
 
 SOURCE="..\..\print-vtp.c"
 # End Source File
index 0fead8fad414a3e42b1ec58bb8277136fd4379fc..fff7b7272a3feab6f17818db3c594ebd76b1616c 100644 (file)
                                />
                        </FileConfiguration>
                </File>
+               <File
+                       RelativePath="..\..\print-vsock.c"
+                       >
+                       <FileConfiguration
+                               Name="Debug|Win32"
+                               >
+                               <Tool
+                                       Name="VCCLCompilerTool"
+                                       AdditionalIncludeDirectories=""
+                                       PreprocessorDefinitions=""
+                               />
+                       </FileConfiguration>
+                       <FileConfiguration
+                               Name="Release|Win32"
+                               >
+                               <Tool
+                                       Name="VCCLCompilerTool"
+                                       AdditionalIncludeDirectories=""
+                                       PreprocessorDefinitions=""
+                               />
+                       </FileConfiguration>
+               </File>
                <File
                        RelativePath="..\..\print-vtp.c"
                        >