2 * Copyright (c) 2016 Fabien Siron <fabien.siron@epita.fr>
3 * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
4 * Copyright (c) 2016-2018 The strace developers.
7 * SPDX-License-Identifier: LGPL-2.1-or-later
14 #include <netinet/in.h>
15 #include <arpa/inet.h>
16 #include <linux/sock_diag.h>
17 #include "static_assert.h"
19 #include "xlat/netlink_sk_meminfo_indices.h"
22 fetch_nlattr(struct tcb *const tcp, struct nlattr *const nlattr,
23 const kernel_ulong_t addr, const unsigned int len,
26 if (len < sizeof(struct nlattr)) {
27 printstr_ex(tcp, addr, len, QUOTE_FORCE_HEX);
31 if (tfetch_obj(tcp, addr, nlattr))
36 printaddr_comment(addr);
45 print_nlattr(const struct nlattr *const nla,
46 const struct xlat *const table,
47 const char *const dflt)
49 static_assert(NLA_TYPE_MASK == ~(NLA_F_NESTED | NLA_F_NET_BYTEORDER),
50 "wrong NLA_TYPE_MASK");
52 tprintf("{nla_len=%u, nla_type=", nla->nla_len);
53 if (nla->nla_type & NLA_F_NESTED) {
54 print_xlat(NLA_F_NESTED);
57 if (nla->nla_type & NLA_F_NET_BYTEORDER) {
58 print_xlat(NLA_F_NET_BYTEORDER);
61 printxval(table, nla->nla_type & NLA_TYPE_MASK, dflt);
66 decode_nlattr_with_data(struct tcb *const tcp,
67 const struct nlattr *const nla,
68 const kernel_ulong_t addr,
69 const unsigned int len,
70 const struct xlat *const table,
71 const char *const dflt,
72 const nla_decoder_t *const decoders,
73 const unsigned int size,
74 const void *const opaque_data)
76 const unsigned int nla_len = MIN(nla->nla_len, len);
78 if (nla_len > NLA_HDRLEN)
81 print_nlattr(nla, table, dflt);
83 if (nla_len > NLA_HDRLEN) {
84 const unsigned int idx =
85 size ? nla->nla_type & NLA_TYPE_MASK : 0;
89 || (size && idx >= size)
92 tcp, addr + NLA_HDRLEN,
95 : (const void *) (uintptr_t) nla->nla_type)
97 printstr_ex(tcp, addr + NLA_HDRLEN,
98 nla_len - NLA_HDRLEN, QUOTE_FORCE_HEX);
104 decode_nlattr(struct tcb *const tcp,
107 const struct xlat *const table,
108 const char *const dflt,
109 const nla_decoder_t *const decoders,
110 const unsigned int size,
111 const void *const opaque_data)
114 bool is_array = false;
117 if (decoders && !size && opaque_data)
118 error_func_msg("[xlat %p, dflt \"%s\", decoders %p] "
119 "size is zero (going to pass nla_type as "
120 "decoder argument), but opaque data (%p) is not "
122 table, dflt, decoders, opaque_data);
124 for (elt = 0; fetch_nlattr(tcp, &nla, addr, len, is_array); elt++) {
125 if (abbrev(tcp) && elt == max_strlen) {
130 const unsigned int nla_len = NLA_ALIGN(nla.nla_len);
131 kernel_ulong_t next_addr = 0;
132 unsigned int next_len = 0;
134 if (nla.nla_len >= NLA_HDRLEN) {
135 next_len = (len >= nla_len) ? len - nla_len : 0;
137 if (next_len && addr + nla_len > addr)
138 next_addr = addr + nla_len;
141 if (!is_array && next_addr) {
146 decode_nlattr_with_data(tcp, &nla, addr, len, table, dflt,
147 decoders, size, opaque_data);
163 decode_nla_str(struct tcb *const tcp,
164 const kernel_ulong_t addr,
165 const unsigned int len,
166 const void *const opaque_data)
168 printstr_ex(tcp, addr, len, QUOTE_0_TERMINATED);
174 decode_nla_strn(struct tcb *const tcp,
175 const kernel_ulong_t addr,
176 const unsigned int len,
177 const void *const opaque_data)
179 printstrn(tcp, addr, len);
185 decode_nla_meminfo(struct tcb *const tcp,
186 const kernel_ulong_t addr,
187 const unsigned int len,
188 const void *const opaque_data)
191 const size_t nmemb = len / sizeof(mem);
196 unsigned int count = 0;
197 print_array_ex(tcp, addr, nmemb, &mem, sizeof(mem),
198 tfetch_mem, print_uint32_array_member, &count,
199 PAF_PRINT_INDICES | XLAT_STYLE_FMT_U,
200 netlink_sk_meminfo_indices, "SK_MEMINFO_???");
206 decode_nla_fd(struct tcb *const tcp,
207 const kernel_ulong_t addr,
208 const unsigned int len,
209 const void *const opaque_data)
213 if (len < sizeof(fd))
215 else if (!umove_or_printaddr(tcp, addr, &fd))
222 decode_nla_uid(struct tcb *const tcp,
223 const kernel_ulong_t addr,
224 const unsigned int len,
225 const void *const opaque_data)
229 if (len < sizeof(uid))
231 else if (!umove_or_printaddr(tcp, addr, &uid))
238 decode_nla_gid(struct tcb *const tcp,
239 const kernel_ulong_t addr,
240 const unsigned int len,
241 const void *const opaque_data)
243 return decode_nla_uid(tcp, addr, len, opaque_data);
247 decode_nla_ifindex(struct tcb *const tcp,
248 const kernel_ulong_t addr,
249 const unsigned int len,
250 const void *const opaque_data)
254 if (len < sizeof(ifindex))
256 else if (!umove_or_printaddr(tcp, addr, &ifindex))
257 print_ifindex(ifindex);
263 decode_nla_xval(struct tcb *const tcp,
264 const kernel_ulong_t addr,
266 const void *const opaque_data)
268 const struct decode_nla_xlat_opts * const opts = opaque_data;
271 uint8_t bytes[sizeof(uint64_t)];
272 } data = { .val = 0 };
274 if (len > sizeof(data) || len < opts->size)
278 len = MIN(len, opts->size);
280 const size_t bytes_offs = is_bigendian ? sizeof(data) - len : 0;
282 if (!umoven_or_printaddr(tcp, addr, len, data.bytes + bytes_offs)) {
283 if (opts->process_fn)
284 data.val = opts->process_fn(data.val);
286 tprints(opts->prefix);
287 printxval_ex(opts->xlat, data.val, opts->dflt, opts->style);
289 tprints(opts->suffix);
296 process_host_order(uint64_t val)
302 decode_nla_ether_proto(struct tcb *const tcp,
303 const kernel_ulong_t addr,
304 const unsigned int len,
305 const void *const opaque_data)
307 static const struct decode_nla_xlat_opts opts = {
308 .xlat = ethernet_protocols,
309 .dflt = "ETHER_P_???",
313 .process_fn = process_host_order,
316 return decode_nla_xval(tcp, addr, len, &opts);
320 decode_nla_ip_proto(struct tcb *const tcp,
321 const kernel_ulong_t addr,
322 const unsigned int len,
323 const void *const opaque_data)
325 static const struct decode_nla_xlat_opts opts = {
326 .xlat = inet_protocols,
327 .dflt = "IPPROTO_???",
331 return decode_nla_xval(tcp, addr, len, &opts);
335 decode_nla_in_addr(struct tcb *const tcp,
336 const kernel_ulong_t addr,
337 const unsigned int len,
338 const void *const opaque_data)
342 if (len < sizeof(in))
344 else if (!umove_or_printaddr(tcp, addr, &in))
345 print_inet_addr(AF_INET, &in, sizeof(in), NULL);
351 decode_nla_in6_addr(struct tcb *const tcp,
352 const kernel_ulong_t addr,
353 const unsigned int len,
354 const void *const opaque_data)
358 if (len < sizeof(in6))
360 else if (!umove_or_printaddr(tcp, addr, &in6))
361 print_inet_addr(AF_INET6, &in6, sizeof(in6), NULL);
367 decode_nla_flags(struct tcb *const tcp,
368 const kernel_ulong_t addr,
370 const void *const opaque_data)
372 const struct decode_nla_xlat_opts * const opts = opaque_data;
375 uint8_t bytes[sizeof(uint64_t)];
376 } data = { .flags = 0 };
378 if (len > sizeof(data) || len < opts->size)
382 len = MIN(len, opts->size);
384 const size_t bytes_offs = is_bigendian ? sizeof(data) - len : 0;
386 if (!umoven_or_printaddr(tcp, addr, len, data.bytes + bytes_offs)) {
387 if (opts->process_fn)
388 data.flags = opts->process_fn(data.flags);
390 tprints(opts->prefix);
391 printflags_ex(data.flags, opts->dflt, opts->style, opts->xlat,
394 tprints(opts->suffix);
401 decode_nla_be16(struct tcb *const tcp,
402 const kernel_ulong_t addr,
403 const unsigned int len,
404 const void *const opaque_data)
408 if (len < sizeof(num))
410 else if (!umove_or_printaddr(tcp, addr, &num))
411 tprintf("htons(%u)", ntohs(num));
417 decode_nla_be64(struct tcb *const tcp,
418 const kernel_ulong_t addr,
419 const unsigned int len,
420 const void *const opaque_data)
422 #if defined HAVE_BE64TOH || defined be64toh
425 if (len < sizeof(num))
427 else if (!umove_or_printaddr(tcp, addr, &num))
428 tprintf("htobe64(%" PRIu64 ")", be64toh(num));
436 #define DECODE_NLA_INTEGER(name, type, fmt) \
438 decode_nla_ ## name(struct tcb *const tcp, \
439 const kernel_ulong_t addr, \
440 const unsigned int len, \
441 const void *const opaque_data) \
445 if (len < sizeof(num)) \
447 if (!umove_or_printaddr(tcp, addr, &num)) \
452 DECODE_NLA_INTEGER(x8, uint8_t, "%#" PRIx8)
453 DECODE_NLA_INTEGER(x16, uint16_t, "%#" PRIx16)
454 DECODE_NLA_INTEGER(x32, uint32_t, "%#" PRIx32)
455 DECODE_NLA_INTEGER(x64, uint64_t, "%#" PRIx64)
456 DECODE_NLA_INTEGER(u8, uint8_t, "%" PRIu8)
457 DECODE_NLA_INTEGER(u16, uint16_t, "%" PRIu16)
458 DECODE_NLA_INTEGER(u32, uint32_t, "%" PRIu32)
459 DECODE_NLA_INTEGER(u64, uint64_t, "%" PRIu64)
460 DECODE_NLA_INTEGER(s8, int8_t, "%" PRId8)
461 DECODE_NLA_INTEGER(s16, int16_t, "%" PRId16)
462 DECODE_NLA_INTEGER(s32, int32_t, "%" PRId32)
463 DECODE_NLA_INTEGER(s64, int64_t, "%" PRId64)