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/filter.h>
17 #include <linux/sock_diag.h>
18 #include <linux/packet_diag.h>
20 #include "xlat/af_packet_versions.h"
21 #include "xlat/packet_diag_attrs.h"
22 #include "xlat/packet_diag_info_flags.h"
23 #include "xlat/packet_diag_show.h"
25 DECL_NETLINK_DIAG_DECODER(decode_packet_diag_req)
27 struct packet_diag_req req = { .sdiag_family = family };
28 const size_t offset = sizeof(req.sdiag_family);
30 PRINT_FIELD_XVAL("{", req, sdiag_family, addrfams, "AF_???");
32 if (len >= sizeof(req)) {
33 if (!umoven_or_printaddr(tcp, addr + offset,
35 (char *) &req + offset)) {
37 * AF_PACKET currently doesn't support protocol values
40 PRINT_FIELD_X("", req, sdiag_protocol);
41 PRINT_FIELD_U(", ", req, pdiag_ino);
42 PRINT_FIELD_FLAGS(", ", req, pdiag_show,
43 packet_diag_show, "PACKET_SHOW_???");
44 PRINT_FIELD_COOKIE(", ", req, pdiag_cookie);
52 decode_packet_diag_info(struct tcb *const tcp,
53 const kernel_ulong_t addr,
54 const unsigned int len,
55 const void *const opaque_data)
57 struct packet_diag_info pinfo;
59 if (len < sizeof(pinfo))
61 if (umove_or_printaddr(tcp, addr, &pinfo))
64 PRINT_FIELD_IFINDEX("{", pinfo, pdi_index);
65 PRINT_FIELD_XVAL(", ", pinfo, pdi_version, af_packet_versions,
67 PRINT_FIELD_U(", ", pinfo, pdi_reserve);
68 PRINT_FIELD_U(", ", pinfo, pdi_copy_thresh);
69 PRINT_FIELD_U(", ", pinfo, pdi_tstamp);
70 PRINT_FIELD_FLAGS(", ", pinfo, pdi_flags,
71 packet_diag_info_flags, "PDI_???");
78 print_packet_diag_mclist(struct tcb *const tcp, void *const elem_buf,
79 const size_t elem_size, void *const opaque_data)
81 struct packet_diag_mclist *dml = elem_buf;
82 uint16_t alen = MIN(dml->pdmc_alen, sizeof(dml->pdmc_addr));
84 PRINT_FIELD_IFINDEX("{", *dml, pdmc_index);
85 PRINT_FIELD_U(", ", *dml, pdmc_count);
86 PRINT_FIELD_U(", ", *dml, pdmc_type);
87 PRINT_FIELD_U(", ", *dml, pdmc_alen);
88 PRINT_FIELD_STRING(", ", *dml, pdmc_addr, alen, QUOTE_FORCE_HEX);
95 decode_packet_diag_mclist(struct tcb *const tcp,
96 const kernel_ulong_t addr,
97 const unsigned int len,
98 const void *const opaque_data)
100 struct packet_diag_mclist dml;
101 const size_t nmemb = len / sizeof(dml);
106 print_array(tcp, addr, nmemb, &dml, sizeof(dml),
107 tfetch_mem, print_packet_diag_mclist, 0);
113 decode_packet_diag_ring(struct tcb *const tcp,
114 const kernel_ulong_t addr,
115 const unsigned int len,
116 const void *const opaque_data)
118 struct packet_diag_ring pdr;
120 if (len < sizeof(pdr))
122 if (umove_or_printaddr(tcp, addr, &pdr))
125 PRINT_FIELD_U("{", pdr, pdr_block_size);
126 PRINT_FIELD_U(", ", pdr, pdr_block_nr);
127 PRINT_FIELD_U(", ", pdr, pdr_frame_size);
128 PRINT_FIELD_U(", ", pdr, pdr_frame_nr);
129 PRINT_FIELD_U(", ", pdr, pdr_retire_tmo);
130 PRINT_FIELD_U(", ", pdr, pdr_sizeof_priv);
131 PRINT_FIELD_U(", ", pdr, pdr_features);
138 decode_packet_diag_filter(struct tcb *const tcp,
139 const kernel_ulong_t addr,
140 const unsigned int len,
141 const void *const opaque_data)
143 const unsigned int nmemb = len / sizeof(struct sock_filter);
144 if (!nmemb || (unsigned short) nmemb != nmemb)
147 print_sock_fprog(tcp, addr, nmemb);
152 static const nla_decoder_t packet_diag_msg_nla_decoders[] = {
153 [PACKET_DIAG_INFO] = decode_packet_diag_info,
154 [PACKET_DIAG_MCLIST] = decode_packet_diag_mclist,
155 [PACKET_DIAG_RX_RING] = decode_packet_diag_ring,
156 [PACKET_DIAG_TX_RING] = decode_packet_diag_ring,
157 [PACKET_DIAG_FANOUT] = decode_nla_u32,
158 [PACKET_DIAG_UID] = decode_nla_uid,
159 [PACKET_DIAG_MEMINFO] = decode_nla_meminfo,
160 [PACKET_DIAG_FILTER] = decode_packet_diag_filter
163 DECL_NETLINK_DIAG_DECODER(decode_packet_diag_msg)
165 struct packet_diag_msg msg = { .pdiag_family = family };
166 size_t offset = sizeof(msg.pdiag_family);
167 bool decode_nla = false;
169 PRINT_FIELD_XVAL("{", msg, pdiag_family, addrfams, "AF_???");
171 if (len >= sizeof(msg)) {
172 if (!umoven_or_printaddr(tcp, addr + offset,
173 sizeof(msg) - offset,
174 (char *) &msg + offset)) {
175 PRINT_FIELD_XVAL("", msg, pdiag_type,
176 socktypes, "SOCK_???");
177 PRINT_FIELD_XVAL(", ", msg, pdiag_num,
178 ethernet_protocols, "ETH_P_???");
179 PRINT_FIELD_U(", ", msg, pdiag_ino);
180 PRINT_FIELD_COOKIE(", ", msg, pdiag_cookie);
187 offset = NLMSG_ALIGN(sizeof(msg));
188 if (decode_nla && len > offset) {
190 decode_nlattr(tcp, addr + offset, len - offset,
191 packet_diag_attrs, "PACKET_DIAG_???",
192 packet_diag_msg_nla_decoders,
193 ARRAY_SIZE(packet_diag_msg_nla_decoders), NULL);