2 * Copyright (c) 2016 Fabien Siron <fabien.siron@epita.fr>
3 * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
4 * Copyright (c) 2017-2018 The strace developers.
7 * SPDX-License-Identifier: LGPL-2.1-or-later
12 #include "netlink_sock_diag.h"
14 #include "print_fields.h"
16 #include <linux/sock_diag.h>
17 #include <linux/netlink_diag.h>
19 #include "xlat/netlink_diag_attrs.h"
20 #include "xlat/netlink_diag_show.h"
21 #include "xlat/netlink_socket_flags.h"
22 #include "xlat/netlink_states.h"
24 DECL_NETLINK_DIAG_DECODER(decode_netlink_diag_req)
26 struct netlink_diag_req req = { .sdiag_family = family };
27 const size_t offset = sizeof(req.sdiag_family);
29 PRINT_FIELD_XVAL("{", req, sdiag_family, addrfams, "AF_???");
31 if (len >= sizeof(req)) {
32 if (!umoven_or_printaddr(tcp, addr + offset,
34 (char *) &req + offset)) {
35 if (NDIAG_PROTO_ALL == req.sdiag_protocol)
37 "sdiag_protocol", "NDIAG_PROTO_ALL");
39 PRINT_FIELD_XVAL("", req, sdiag_protocol,
42 PRINT_FIELD_U(", ", req, ndiag_ino);
43 PRINT_FIELD_FLAGS(", ", req, ndiag_show,
44 netlink_diag_show, "NDIAG_SHOW_???");
45 PRINT_FIELD_COOKIE(", ", req, ndiag_cookie);
53 print_group(struct tcb *const tcp,
55 const size_t elem_size,
56 void *const opaque_data)
58 if (elem_size < sizeof(kernel_ulong_t))
59 tprintf("%#0*x", (int) elem_size * 2 + 2,
60 *(unsigned int *) elem_buf);
62 tprintf("%#0*" PRI_klx, (int) elem_size * 2 + 2,
63 *(kernel_ulong_t *) elem_buf);
69 decode_netlink_diag_groups(struct tcb *const tcp,
70 const kernel_ulong_t addr,
71 const unsigned int len,
72 const void *const opaque_data)
75 const size_t nmemb = len / current_wordsize;
80 print_array(tcp, addr, nmemb, &buf, current_wordsize,
81 tfetch_mem, print_group, 0);
87 decode_netlink_diag_ring(struct tcb *const tcp,
88 const kernel_ulong_t addr,
89 const unsigned int len,
90 const void *const opaque_data)
92 struct netlink_diag_ring ndr;
94 if (len < sizeof(ndr))
96 if (umove_or_printaddr(tcp, addr, &ndr))
99 PRINT_FIELD_U("{", ndr, ndr_block_size);
100 PRINT_FIELD_U(", ", ndr, ndr_block_nr);
101 PRINT_FIELD_U(", ", ndr, ndr_frame_size);
102 PRINT_FIELD_U(", ", ndr, ndr_frame_nr);
109 decode_netlink_diag_flags(struct tcb *const tcp,
110 const kernel_ulong_t addr,
111 const unsigned int len,
112 const void *const opaque_data)
116 if (len < sizeof(flags))
118 if (umove_or_printaddr(tcp, addr, &flags))
121 printflags(netlink_socket_flags, flags, "NDIAG_FLAG_???");
126 static const nla_decoder_t netlink_diag_msg_nla_decoders[] = {
127 [NETLINK_DIAG_MEMINFO] = decode_nla_meminfo,
128 [NETLINK_DIAG_GROUPS] = decode_netlink_diag_groups,
129 [NETLINK_DIAG_RX_RING] = decode_netlink_diag_ring,
130 [NETLINK_DIAG_TX_RING] = decode_netlink_diag_ring,
131 [NETLINK_DIAG_FLAGS] = decode_netlink_diag_flags
134 DECL_NETLINK_DIAG_DECODER(decode_netlink_diag_msg)
136 struct netlink_diag_msg msg = { .ndiag_family = family };
137 size_t offset = sizeof(msg.ndiag_family);
138 bool decode_nla = false;
140 PRINT_FIELD_XVAL("{", msg, ndiag_family, addrfams, "AF_???");
142 if (len >= sizeof(msg)) {
143 if (!umoven_or_printaddr(tcp, addr + offset,
144 sizeof(msg) - offset,
145 (char *) &msg + offset)) {
146 PRINT_FIELD_XVAL("", msg, ndiag_type,
147 socktypes, "SOCK_???");
148 PRINT_FIELD_XVAL(", ", msg, ndiag_protocol,
149 netlink_protocols, "NETLINK_???");
150 PRINT_FIELD_XVAL(", ", msg, ndiag_state,
151 netlink_states, "NETLINK_???");
152 PRINT_FIELD_U(", ", msg, ndiag_portid);
153 PRINT_FIELD_U(", ", msg, ndiag_dst_portid);
154 PRINT_FIELD_U(", ", msg, ndiag_dst_group);
155 PRINT_FIELD_U(", ", msg, ndiag_ino);
156 PRINT_FIELD_COOKIE(", ", msg, ndiag_cookie);
163 offset = NLMSG_ALIGN(sizeof(msg));
164 if (decode_nla && len > offset) {
166 decode_nlattr(tcp, addr + offset, len - offset,
167 netlink_diag_attrs, "NETLINK_DIAG_???",
168 netlink_diag_msg_nla_decoders,
169 ARRAY_SIZE(netlink_diag_msg_nla_decoders), NULL);