2 * Copyright (c) 2016 Fabien Siron <fabien.siron@epita.fr>
3 * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
4 * Copyright (c) 2017 The strace developers.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include "print_fields.h"
35 #include <arpa/inet.h>
36 #include <linux/filter.h>
38 #include <linux/inet_diag.h>
39 #include <linux/netlink_diag.h>
40 #include <linux/packet_diag.h>
42 # include <linux/smc_diag.h>
44 #include <linux/sock_diag.h>
45 #include <linux/unix_diag.h>
47 #include "xlat/inet_diag_attrs.h"
48 #include "xlat/inet_diag_extended_flags.h"
49 #include "xlat/inet_diag_req_attrs.h"
51 #include "xlat/tcp_states.h"
52 #include "xlat/tcp_state_flags.h"
54 #include "xlat/netlink_diag_attrs.h"
55 #include "xlat/netlink_diag_show.h"
56 #include "xlat/netlink_socket_flags.h"
57 #include "xlat/netlink_states.h"
59 #include "xlat/packet_diag_attrs.h"
60 #include "xlat/packet_diag_info_flags.h"
61 #include "xlat/packet_diag_show.h"
64 # include "xlat/smc_diag_attrs.h"
65 # include "xlat/smc_diag_extended_flags.h"
66 # include "xlat/smc_link_group_roles.h"
67 # include "xlat/smc_states.h"
70 #include "xlat/unix_diag_attrs.h"
71 #include "xlat/unix_diag_show.h"
74 decode_family(struct tcb *const tcp, const uint8_t family,
75 const kernel_ulong_t addr, const kernel_ulong_t len)
78 printxval(addrfams, family, "AF_???");
79 if (len > sizeof(family)) {
81 printstr_ex(tcp, addr + sizeof(family),
82 len - sizeof(family), QUOTE_FORCE_HEX);
88 decode_unix_diag_req(struct tcb *const tcp,
89 const struct nlmsghdr *const nlmsghdr,
91 const kernel_ulong_t addr,
92 const kernel_ulong_t len)
94 struct unix_diag_req req = { .sdiag_family = family };
95 const size_t offset = sizeof(req.sdiag_family);
97 PRINT_FIELD_XVAL("{", req, sdiag_family, addrfams, "AF_???");
99 if (len >= sizeof(req)) {
100 if (!umoven_or_printaddr(tcp, addr + offset,
101 sizeof(req) - offset,
102 (void *) &req + offset)) {
103 PRINT_FIELD_U("", req, sdiag_protocol);
104 PRINT_FIELD_FLAGS(", ", req, udiag_states,
105 tcp_state_flags, "1<<TCP_???");
106 PRINT_FIELD_U(", ", req, udiag_ino);
107 PRINT_FIELD_FLAGS(", ", req, udiag_show,
108 unix_diag_show, "UDIAG_SHOW_???");
109 PRINT_FIELD_COOKIE(", ", req, udiag_cookie);
117 print_meminfo(struct tcb *const tcp,
118 void *const elem_buf,
119 const size_t elem_size,
120 void *const opaque_data)
122 tprintf("%" PRIu32, *(uint32_t *) elem_buf);
128 decode_meminfo(struct tcb *const tcp,
129 const kernel_ulong_t addr,
130 const kernel_ulong_t len,
131 const void *const opaque_data)
134 size_t nmemb = len / sizeof(mem);
139 if (nmemb > SK_MEMINFO_VARS)
140 nmemb = SK_MEMINFO_VARS;
142 print_array(tcp, addr, nmemb, &mem, sizeof(mem),
143 umoven_or_printaddr, print_meminfo, 0);
149 decode_unix_diag_vfs(struct tcb *const tcp,
150 const kernel_ulong_t addr,
151 const kernel_ulong_t len,
152 const void *const opaque_data)
154 struct unix_diag_vfs uv;
156 if (len < sizeof(uv))
158 if (umove_or_printaddr(tcp, addr, &uv))
161 PRINT_FIELD_DEV("{", uv, udiag_vfs_dev);
162 PRINT_FIELD_U(", ", uv, udiag_vfs_ino);
169 print_inode(struct tcb *const tcp,
170 void *const elem_buf,
171 const size_t elem_size,
172 void *const opaque_data)
174 tprintf("%" PRIu32, *(uint32_t *) elem_buf);
180 decode_unix_diag_inode(struct tcb *const tcp,
181 const kernel_ulong_t addr,
182 const kernel_ulong_t len,
183 const void *const opaque_data)
186 const size_t nmemb = len / sizeof(inode);
191 print_array(tcp, addr, nmemb, &inode, sizeof(inode),
192 umoven_or_printaddr, print_inode, 0);
198 decode_unix_diag_rqlen(struct tcb *const tcp,
199 const kernel_ulong_t addr,
200 const kernel_ulong_t len,
201 const void *const opaque_data)
203 struct unix_diag_rqlen rql;
205 if (len < sizeof(rql))
207 if (umove_or_printaddr(tcp, addr, &rql))
210 PRINT_FIELD_U("{", rql, udiag_rqueue);
211 PRINT_FIELD_U(", ", rql, udiag_wqueue);
217 static const nla_decoder_t unix_diag_msg_nla_decoders[] = {
218 [UNIX_DIAG_NAME] = decode_nla_str,
219 [UNIX_DIAG_VFS] = decode_unix_diag_vfs,
220 [UNIX_DIAG_PEER] = decode_nla_u32,
221 [UNIX_DIAG_ICONS] = decode_unix_diag_inode,
222 [UNIX_DIAG_RQLEN] = decode_unix_diag_rqlen,
223 [UNIX_DIAG_MEMINFO] = decode_meminfo,
224 [UNIX_DIAG_SHUTDOWN] = decode_nla_u8
228 decode_unix_diag_msg(struct tcb *const tcp,
229 const struct nlmsghdr *const nlmsghdr,
230 const uint8_t family,
231 const kernel_ulong_t addr,
232 const kernel_ulong_t len)
234 struct unix_diag_msg msg = { .udiag_family = family };
235 size_t offset = sizeof(msg.udiag_family);
236 bool decode_nla = false;
238 PRINT_FIELD_XVAL("{", msg, udiag_family, addrfams, "AF_???");
240 if (len >= sizeof(msg)) {
241 if (!umoven_or_printaddr(tcp, addr + offset,
242 sizeof(msg) - offset,
243 (void *) &msg + offset)) {
244 PRINT_FIELD_XVAL("", msg, udiag_type,
245 socktypes, "SOCK_???");
246 PRINT_FIELD_XVAL(", ", msg, udiag_state,
247 tcp_states, "TCP_???");
248 PRINT_FIELD_U(", ", msg, udiag_ino);
249 PRINT_FIELD_COOKIE(", ", msg, udiag_cookie);
256 offset = NLMSG_ALIGN(sizeof(msg));
257 if (decode_nla && len > offset) {
259 decode_nlattr(tcp, addr + offset, len - offset,
260 unix_diag_attrs, "UNIX_DIAG_???",
261 unix_diag_msg_nla_decoders,
262 ARRAY_SIZE(unix_diag_msg_nla_decoders), NULL);
267 decode_netlink_diag_req(struct tcb *const tcp,
268 const struct nlmsghdr *const nlmsghdr,
269 const uint8_t family,
270 const kernel_ulong_t addr,
271 const kernel_ulong_t len)
273 struct netlink_diag_req req = { .sdiag_family = family };
274 const size_t offset = sizeof(req.sdiag_family);
276 PRINT_FIELD_XVAL("{", req, sdiag_family, addrfams, "AF_???");
278 if (len >= sizeof(req)) {
279 if (!umoven_or_printaddr(tcp, addr + offset,
280 sizeof(req) - offset,
281 (void *) &req + offset)) {
282 if (NDIAG_PROTO_ALL == req.sdiag_protocol)
284 "sdiag_protocol", "NDIAG_PROTO_ALL");
286 PRINT_FIELD_XVAL("", req, sdiag_protocol,
289 PRINT_FIELD_U(", ", req, ndiag_ino);
290 PRINT_FIELD_FLAGS(", ", req, ndiag_show,
291 netlink_diag_show, "NDIAG_SHOW_???");
292 PRINT_FIELD_COOKIE(", ", req, ndiag_cookie);
300 print_group(struct tcb *const tcp,
301 void *const elem_buf,
302 const size_t elem_size,
303 void *const opaque_data)
305 if (elem_size < sizeof(kernel_ulong_t))
306 tprintf("%#0*x", (int) elem_size * 2 + 2,
307 *(unsigned int *) elem_buf);
309 tprintf("%#0*" PRI_klx, (int) elem_size * 2 + 2,
310 *(kernel_ulong_t *) elem_buf);
316 decode_netlink_diag_groups(struct tcb *const tcp,
317 const kernel_ulong_t addr,
318 const kernel_ulong_t len,
319 const void *const opaque_data)
322 const size_t nmemb = len / current_wordsize;
327 print_array(tcp, addr, nmemb, &buf, current_wordsize,
328 umoven_or_printaddr, print_group, 0);
334 decode_netlink_diag_ring(struct tcb *const tcp,
335 const kernel_ulong_t addr,
336 const kernel_ulong_t len,
337 const void *const opaque_data)
339 struct netlink_diag_ring ndr;
341 if (len < sizeof(ndr))
343 if (umove_or_printaddr(tcp, addr, &ndr))
346 PRINT_FIELD_U("{", ndr, ndr_block_size);
347 PRINT_FIELD_U(", ", ndr, ndr_block_nr);
348 PRINT_FIELD_U(", ", ndr, ndr_frame_size);
349 PRINT_FIELD_U(", ", ndr, ndr_frame_nr);
356 decode_netlink_diag_flags(struct tcb *const tcp,
357 const kernel_ulong_t addr,
358 const kernel_ulong_t len,
359 const void *const opaque_data)
363 if (len < sizeof(flags))
365 if (umove_or_printaddr(tcp, addr, &flags))
368 printflags(netlink_socket_flags, flags, "NDIAG_FLAG_???");
373 static const nla_decoder_t netlink_diag_msg_nla_decoders[] = {
374 [NETLINK_DIAG_MEMINFO] = decode_meminfo,
375 [NETLINK_DIAG_GROUPS] = decode_netlink_diag_groups,
376 [NETLINK_DIAG_RX_RING] = decode_netlink_diag_ring,
377 [NETLINK_DIAG_TX_RING] = decode_netlink_diag_ring,
378 [NETLINK_DIAG_FLAGS] = decode_netlink_diag_flags
382 decode_netlink_diag_msg(struct tcb *const tcp,
383 const struct nlmsghdr *const nlmsghdr,
384 const uint8_t family,
385 const kernel_ulong_t addr,
386 const kernel_ulong_t len)
388 struct netlink_diag_msg msg = { .ndiag_family = family };
389 size_t offset = sizeof(msg.ndiag_family);
390 bool decode_nla = false;
392 PRINT_FIELD_XVAL("{", msg, ndiag_family, addrfams, "AF_???");
394 if (len >= sizeof(msg)) {
395 if (!umoven_or_printaddr(tcp, addr + offset,
396 sizeof(msg) - offset,
397 (void *) &msg + offset)) {
398 PRINT_FIELD_XVAL("", msg, ndiag_type,
399 socktypes, "SOCK_???");
400 PRINT_FIELD_XVAL(", ", msg, ndiag_protocol,
401 netlink_protocols, "NETLINK_???");
402 PRINT_FIELD_XVAL(", ", msg, ndiag_state,
403 netlink_states, "NETLINK_???");
404 PRINT_FIELD_U(", ", msg, ndiag_portid);
405 PRINT_FIELD_U(", ", msg, ndiag_dst_portid);
406 PRINT_FIELD_U(", ", msg, ndiag_dst_group);
407 PRINT_FIELD_U(", ", msg, ndiag_ino);
408 PRINT_FIELD_COOKIE(", ", msg, ndiag_cookie);
415 offset = NLA_ALIGN(sizeof(msg));
416 if (decode_nla && len > offset) {
418 decode_nlattr(tcp, addr + offset, len - offset,
419 netlink_diag_attrs, "NETLINK_DIAG_???",
420 netlink_diag_msg_nla_decoders,
421 ARRAY_SIZE(netlink_diag_msg_nla_decoders), NULL);
426 decode_packet_diag_req(struct tcb *const tcp,
427 const struct nlmsghdr *const nlmsghdr,
428 const uint8_t family,
429 const kernel_ulong_t addr,
430 const kernel_ulong_t len)
432 struct packet_diag_req req = { .sdiag_family = family };
433 const size_t offset = sizeof(req.sdiag_family);
435 PRINT_FIELD_XVAL("{", req, sdiag_family, addrfams, "AF_???");
437 if (len >= sizeof(req)) {
438 if (!umoven_or_printaddr(tcp, addr + offset,
439 sizeof(req) - offset,
440 (void *) &req + offset)) {
441 PRINT_FIELD_XVAL("", req, sdiag_protocol,
442 ethernet_protocols, "ETH_P_???");
443 PRINT_FIELD_U(", ", req, pdiag_ino);
444 PRINT_FIELD_FLAGS(", ", req, pdiag_show,
445 packet_diag_show, "PACKET_SHOW_???");
446 PRINT_FIELD_COOKIE(", ", req, pdiag_cookie);
454 decode_packet_diag_info(struct tcb *const tcp,
455 const kernel_ulong_t addr,
456 const kernel_ulong_t len,
457 const void *const opaque_data)
459 struct packet_diag_info pinfo;
461 if (len < sizeof(pinfo))
463 if (umove_or_printaddr(tcp, addr, &pinfo))
466 PRINT_FIELD_U("{", pinfo, pdi_index);
467 PRINT_FIELD_U(", ", pinfo, pdi_version);
468 PRINT_FIELD_U(", ", pinfo, pdi_reserve);
469 PRINT_FIELD_U(", ", pinfo, pdi_copy_thresh);
470 PRINT_FIELD_U(", ", pinfo, pdi_tstamp);
471 PRINT_FIELD_FLAGS(", ", pinfo, pdi_flags,
472 packet_diag_info_flags, "PDI_???");
479 print_packet_diag_mclist(struct tcb *const tcp, void *const elem_buf,
480 const size_t elem_size, void *const opaque_data)
482 struct packet_diag_mclist *dml = elem_buf;
483 uint16_t alen = dml->pdmc_alen > sizeof(dml->pdmc_addr) ?
484 sizeof(dml->pdmc_addr) : dml->pdmc_alen;
486 PRINT_FIELD_IFINDEX("{", *dml, pdmc_index);
487 PRINT_FIELD_U(", ", *dml, pdmc_count);
488 PRINT_FIELD_U(", ", *dml, pdmc_type);
489 PRINT_FIELD_U(", ", *dml, pdmc_alen);
490 PRINT_FIELD_STRING(", ", *dml, pdmc_addr, alen, QUOTE_FORCE_HEX);
497 decode_packet_diag_mclist(struct tcb *const tcp,
498 const kernel_ulong_t addr,
499 const kernel_ulong_t len,
500 const void *const opaque_data)
502 struct packet_diag_mclist dml;
503 const size_t nmemb = len / sizeof(dml);
508 print_array(tcp, addr, nmemb, &dml, sizeof(dml),
509 umoven_or_printaddr, print_packet_diag_mclist, 0);
515 decode_packet_diag_ring(struct tcb *const tcp,
516 const kernel_ulong_t addr,
517 const kernel_ulong_t len,
518 const void *const opaque_data)
520 struct packet_diag_ring pdr;
522 if (len < sizeof(pdr))
524 if (umove_or_printaddr(tcp, addr, &pdr))
527 PRINT_FIELD_U("{", pdr, pdr_block_size);
528 PRINT_FIELD_U(", ", pdr, pdr_block_nr);
529 PRINT_FIELD_U(", ", pdr, pdr_frame_size);
530 PRINT_FIELD_U(", ", pdr, pdr_frame_nr);
531 PRINT_FIELD_U(", ", pdr, pdr_retire_tmo);
532 PRINT_FIELD_U(", ", pdr, pdr_sizeof_priv);
533 PRINT_FIELD_U(", ", pdr, pdr_features);
540 decode_packet_diag_filter(struct tcb *const tcp,
541 const kernel_ulong_t addr,
542 const kernel_ulong_t len,
543 const void *const opaque_data)
545 const kernel_ulong_t nmemb = len / sizeof(struct sock_filter);
546 if (!nmemb || (unsigned short) nmemb != nmemb)
549 print_sock_fprog(tcp, addr, nmemb);
554 static const nla_decoder_t packet_diag_msg_nla_decoders[] = {
555 [PACKET_DIAG_INFO] = decode_packet_diag_info,
556 [PACKET_DIAG_MCLIST] = decode_packet_diag_mclist,
557 [PACKET_DIAG_RX_RING] = decode_packet_diag_ring,
558 [PACKET_DIAG_TX_RING] = decode_packet_diag_ring,
559 [PACKET_DIAG_FANOUT] = decode_nla_u32,
560 [PACKET_DIAG_UID] = decode_nla_u32,
561 [PACKET_DIAG_MEMINFO] = decode_meminfo,
562 [PACKET_DIAG_FILTER] = decode_packet_diag_filter
566 decode_packet_diag_msg(struct tcb *const tcp,
567 const struct nlmsghdr *const nlmsghdr,
568 const uint8_t family,
569 const kernel_ulong_t addr,
570 const kernel_ulong_t len)
572 struct packet_diag_msg msg = { .pdiag_family = family };
573 size_t offset = sizeof(msg.pdiag_family);
574 bool decode_nla = false;
576 PRINT_FIELD_XVAL("{", msg, pdiag_family, addrfams, "AF_???");
578 if (len >= sizeof(msg)) {
579 if (!umoven_or_printaddr(tcp, addr + offset,
580 sizeof(msg) - offset,
581 (void *) &msg + offset)) {
582 PRINT_FIELD_XVAL("", msg, pdiag_type,
583 socktypes, "SOCK_???");
584 PRINT_FIELD_U(", ", msg, pdiag_num);
585 PRINT_FIELD_U(", ", msg, pdiag_ino);
586 PRINT_FIELD_COOKIE(", ", msg, pdiag_cookie);
593 offset = NLA_ALIGN(sizeof(msg));
594 if (decode_nla && len > offset) {
596 decode_nlattr(tcp, addr + offset, len - offset,
597 packet_diag_attrs, "PACKET_DIAG_???",
598 packet_diag_msg_nla_decoders,
599 ARRAY_SIZE(packet_diag_msg_nla_decoders), NULL);
604 print_inet_diag_sockid(const struct inet_diag_sockid *id, const uint8_t family)
606 PRINT_FIELD_NET_PORT("{", *id, idiag_sport);
607 PRINT_FIELD_NET_PORT(", ", *id, idiag_dport);
608 PRINT_FIELD_INET_ADDR(", ", *id, idiag_src, family);
609 PRINT_FIELD_INET_ADDR(", ", *id, idiag_dst, family);
610 PRINT_FIELD_IFINDEX(", ", *id, idiag_if);
611 PRINT_FIELD_COOKIE(", ", *id, idiag_cookie);
615 #define PRINT_FIELD_INET_DIAG_SOCKID(prefix_, where_, field_, af_) \
617 STRACE_PRINTF("%s%s=", (prefix_), #field_); \
618 print_inet_diag_sockid(&(where_).field_, (af_)); \
622 decode_inet_diag_req_compat(struct tcb *const tcp,
623 const struct nlmsghdr *const nlmsghdr,
624 const uint8_t family,
625 const kernel_ulong_t addr,
626 const kernel_ulong_t len)
628 struct inet_diag_req req = { .idiag_family = family };
629 size_t offset = sizeof(req.idiag_family);
630 bool decode_nla = false;
632 PRINT_FIELD_XVAL("{", req, idiag_family, addrfams, "AF_???");
634 if (len >= sizeof(req)) {
635 if (!umoven_or_printaddr(tcp, addr + offset,
636 sizeof(req) - offset,
637 (void *) &req + offset)) {
638 PRINT_FIELD_U("", req, idiag_src_len);
639 PRINT_FIELD_U(", ", req, idiag_dst_len);
640 PRINT_FIELD_FLAGS(", ", req, idiag_ext,
641 inet_diag_extended_flags,
642 "1<<INET_DIAG_\?\?\?-1");
643 PRINT_FIELD_INET_DIAG_SOCKID(", ", req, id,
645 PRINT_FIELD_FLAGS(", ", req, idiag_states,
646 tcp_state_flags, "1<<TCP_???");
647 PRINT_FIELD_U(", ", req, idiag_dbs);
654 offset = NLA_ALIGN(sizeof(req));
655 if (decode_nla && len > offset) {
657 decode_nlattr(tcp, addr + offset, len - offset,
658 inet_diag_req_attrs, "INET_DIAG_REQ_???",
664 decode_inet_diag_req_v2(struct tcb *const tcp,
665 const struct nlmsghdr *const nlmsghdr,
666 const uint8_t family,
667 const kernel_ulong_t addr,
668 const kernel_ulong_t len)
670 struct inet_diag_req_v2 req = { .sdiag_family = family };
671 size_t offset = sizeof(req.sdiag_family);
672 bool decode_nla = false;
674 PRINT_FIELD_XVAL("{", req, sdiag_family, addrfams, "AF_???");
676 if (len >= sizeof(req)) {
677 if (!umoven_or_printaddr(tcp, addr + offset,
678 sizeof(req) - offset,
679 (void *) &req + offset)) {
680 PRINT_FIELD_XVAL("", req, sdiag_protocol,
681 inet_protocols, "IPPROTO_???");
682 PRINT_FIELD_FLAGS(", ", req, idiag_ext,
683 inet_diag_extended_flags,
684 "1<<INET_DIAG_\?\?\?-1");
685 PRINT_FIELD_FLAGS(", ", req, idiag_states,
686 tcp_state_flags, "1<<TCP_???");
687 PRINT_FIELD_INET_DIAG_SOCKID(", ", req, id,
695 offset = NLA_ALIGN(sizeof(req));
696 if (decode_nla && len > offset) {
698 decode_nlattr(tcp, addr + offset, len - offset,
699 inet_diag_req_attrs, "INET_DIAG_REQ_???",
705 decode_inet_diag_req(struct tcb *const tcp,
706 const struct nlmsghdr *const nlmsghdr,
707 const uint8_t family,
708 const kernel_ulong_t addr,
709 const kernel_ulong_t len)
711 if (nlmsghdr->nlmsg_type == TCPDIAG_GETSOCK
712 || nlmsghdr->nlmsg_type == DCCPDIAG_GETSOCK)
713 return decode_inet_diag_req_compat(tcp, nlmsghdr,
716 return decode_inet_diag_req_v2(tcp, nlmsghdr,
721 decode_inet_diag_meminfo(struct tcb *const tcp,
722 const kernel_ulong_t addr,
723 const kernel_ulong_t len,
724 const void *const opaque_data)
726 struct inet_diag_meminfo minfo;
728 if (len < sizeof(minfo))
730 if (umove_or_printaddr(tcp, addr, &minfo))
733 PRINT_FIELD_U("{", minfo, idiag_rmem);
734 PRINT_FIELD_U(", ", minfo, idiag_wmem);
735 PRINT_FIELD_U(", ", minfo, idiag_fmem);
736 PRINT_FIELD_U(", ", minfo, idiag_tmem);
743 decode_tcpvegas_info(struct tcb *const tcp,
744 const kernel_ulong_t addr,
745 const kernel_ulong_t len,
746 const void *const opaque_data)
748 struct tcpvegas_info vegas;
750 if (len < sizeof(vegas))
752 if (umove_or_printaddr(tcp, addr, &vegas))
755 PRINT_FIELD_U("{", vegas, tcpv_enabled);
756 PRINT_FIELD_U(", ", vegas, tcpv_rttcnt);
757 PRINT_FIELD_U(", ", vegas, tcpv_rtt);
758 PRINT_FIELD_U(", ", vegas, tcpv_minrtt);
765 decode_tcp_dctcp_info(struct tcb *const tcp,
766 const kernel_ulong_t addr,
767 const kernel_ulong_t len,
768 const void *const opaque_data)
770 struct tcp_dctcp_info dctcp;
772 if (len < sizeof(dctcp))
774 if (umove_or_printaddr(tcp, addr, &dctcp))
777 PRINT_FIELD_U("{", dctcp, dctcp_enabled);
778 PRINT_FIELD_U(", ", dctcp, dctcp_ce_state);
779 PRINT_FIELD_U(", ", dctcp, dctcp_alpha);
780 PRINT_FIELD_U(", ", dctcp, dctcp_ab_ecn);
781 PRINT_FIELD_U(", ", dctcp, dctcp_ab_tot);
788 decode_tcp_bbr_info(struct tcb *const tcp,
789 const kernel_ulong_t addr,
790 const kernel_ulong_t len,
791 const void *const opaque_data)
793 struct tcp_bbr_info bbr;
795 if (len < sizeof(bbr))
797 if (umove_or_printaddr(tcp, addr, &bbr))
800 PRINT_FIELD_X("{", bbr, bbr_bw_lo);
801 PRINT_FIELD_X(", ", bbr, bbr_bw_hi);
802 PRINT_FIELD_U(", ", bbr, bbr_min_rtt);
803 PRINT_FIELD_U(", ", bbr, bbr_pacing_gain);
804 PRINT_FIELD_U(", ", bbr, bbr_cwnd_gain);
810 static const nla_decoder_t inet_diag_msg_nla_decoders[] = {
811 [INET_DIAG_MEMINFO] = decode_inet_diag_meminfo,
812 [INET_DIAG_INFO] = NULL, /* unimplemented */
813 [INET_DIAG_VEGASINFO] = decode_tcpvegas_info,
814 [INET_DIAG_CONG] = decode_nla_str,
815 [INET_DIAG_TOS] = decode_nla_u8,
816 [INET_DIAG_TCLASS] = decode_nla_u8,
817 [INET_DIAG_SKMEMINFO] = decode_meminfo,
818 [INET_DIAG_SHUTDOWN] = decode_nla_u8,
819 [INET_DIAG_DCTCPINFO] = decode_tcp_dctcp_info,
820 [INET_DIAG_PROTOCOL] = decode_nla_u8,
821 [INET_DIAG_SKV6ONLY] = decode_nla_u8,
822 [INET_DIAG_LOCALS] = NULL, /* unimplemented */
823 [INET_DIAG_PEERS] = NULL, /* unimplemented */
824 [INET_DIAG_PAD] = NULL,
825 [INET_DIAG_MARK] = decode_nla_u32,
826 [INET_DIAG_BBRINFO] = decode_tcp_bbr_info
830 decode_inet_diag_msg(struct tcb *const tcp,
831 const struct nlmsghdr *const nlmsghdr,
832 const uint8_t family,
833 const kernel_ulong_t addr,
834 const kernel_ulong_t len)
836 struct inet_diag_msg msg = { .idiag_family = family };
837 size_t offset = sizeof(msg.idiag_family);
838 bool decode_nla = false;
840 PRINT_FIELD_XVAL("{", msg, idiag_family, addrfams, "AF_???");
842 if (len >= sizeof(msg)) {
843 if (!umoven_or_printaddr(tcp, addr + offset,
844 sizeof(msg) - offset,
845 (void *) &msg + offset)) {
846 PRINT_FIELD_XVAL("", msg, idiag_state,
847 tcp_states, "TCP_???");
848 PRINT_FIELD_U(", ", msg, idiag_timer);
849 PRINT_FIELD_U(", ", msg, idiag_retrans);
850 PRINT_FIELD_INET_DIAG_SOCKID(", ", msg, id,
852 PRINT_FIELD_U(", ", msg, idiag_expires);
853 PRINT_FIELD_U(", ", msg, idiag_rqueue);
854 PRINT_FIELD_U(", ", msg, idiag_wqueue);
855 PRINT_FIELD_U(", ", msg, idiag_uid);
856 PRINT_FIELD_U(", ", msg, idiag_inode);
863 offset = NLA_ALIGN(sizeof(msg));
864 if (decode_nla && len > offset) {
866 decode_nlattr(tcp, addr + offset, len - offset,
867 inet_diag_attrs, "INET_DIAG_???",
868 inet_diag_msg_nla_decoders,
869 ARRAY_SIZE(inet_diag_msg_nla_decoders), NULL);
875 decode_smc_diag_req(struct tcb *const tcp,
876 const struct nlmsghdr *const nlmsghdr,
877 const uint8_t family,
878 const kernel_ulong_t addr,
879 const kernel_ulong_t len)
881 struct smc_diag_req req = { .diag_family = family };
882 const size_t offset = sizeof(req.diag_family);
884 PRINT_FIELD_XVAL("{", req, diag_family, addrfams, "AF_???");
886 if (len >= sizeof(req)) {
887 if (!umoven_or_printaddr(tcp, addr + offset,
888 sizeof(req) - offset,
889 (void *) &req + offset)) {
890 PRINT_FIELD_FLAGS("", req, diag_ext,
891 smc_diag_extended_flags,
892 "1<<SMC_DIAG_\?\?\?-1");
894 * AF_SMC protocol family socket handler
895 * keeping the AF_INET sock address.
897 PRINT_FIELD_INET_DIAG_SOCKID(", ", req, id, AF_INET);
905 print_smc_diag_cursor(const struct smc_diag_cursor *const cursor)
907 PRINT_FIELD_U("{", *cursor, reserved);
908 PRINT_FIELD_U(", ", *cursor, wrap);
909 PRINT_FIELD_U(", ", *cursor, count);
913 #define PRINT_FIELD_SMC_DIAG_CURSOR(prefix_, where_, field_) \
915 tprintf("%s%s=", (prefix_), #field_); \
916 print_smc_diag_cursor(&(where_).field_); \
920 decode_smc_diag_conninfo(struct tcb *const tcp,
921 const kernel_ulong_t addr,
922 const kernel_ulong_t len,
923 const void *const opaque_data)
925 struct smc_diag_conninfo cinfo;
927 if (len < sizeof(cinfo))
929 if (umove_or_printaddr(tcp, addr, &cinfo))
932 PRINT_FIELD_U("{", cinfo, token);
933 PRINT_FIELD_U(", ", cinfo, sndbuf_size);
934 PRINT_FIELD_U(", ", cinfo, rmbe_size);
935 PRINT_FIELD_U(", ", cinfo, peer_rmbe_size);
936 PRINT_FIELD_SMC_DIAG_CURSOR(", ", cinfo, rx_prod);
937 PRINT_FIELD_SMC_DIAG_CURSOR(", ", cinfo, rx_cons);
938 PRINT_FIELD_SMC_DIAG_CURSOR(", ", cinfo, tx_prod);
939 PRINT_FIELD_SMC_DIAG_CURSOR(", ", cinfo, tx_cons);
940 PRINT_FIELD_0X(", ", cinfo, rx_prod_flags);
941 PRINT_FIELD_0X(", ", cinfo, rx_conn_state_flags);
942 PRINT_FIELD_0X(", ", cinfo, tx_prod_flags);
943 PRINT_FIELD_0X(", ", cinfo, tx_conn_state_flags);
944 PRINT_FIELD_SMC_DIAG_CURSOR(", ", cinfo, tx_prep);
945 PRINT_FIELD_SMC_DIAG_CURSOR(", ", cinfo, tx_sent);
946 PRINT_FIELD_SMC_DIAG_CURSOR(", ", cinfo, tx_fin);
953 decode_smc_diag_lgrinfo(struct tcb *const tcp,
954 const kernel_ulong_t addr,
955 const kernel_ulong_t len,
956 const void *const opaque_data)
958 struct smc_diag_lgrinfo linfo;
960 if (len < sizeof(linfo))
962 if (umove_or_printaddr(tcp, addr, &linfo))
965 tprints("{lnk[0]={");
966 PRINT_FIELD_U("", linfo.lnk[0], link_id);
967 PRINT_FIELD_STRING(", ", linfo.lnk[0], ibname,
968 sizeof(linfo.lnk[0].ibname),
970 PRINT_FIELD_U(", ", linfo.lnk[0], ibport);
971 PRINT_FIELD_STRING(", ", linfo.lnk[0], gid,
972 sizeof(linfo.lnk[0].gid),
974 PRINT_FIELD_STRING(", ", linfo.lnk[0], peer_gid,
975 sizeof(linfo.lnk[0].peer_gid),
977 PRINT_FIELD_XVAL("}, ", linfo, role, smc_link_group_roles, "SMC_???");
983 static const nla_decoder_t smc_diag_msg_nla_decoders[] = {
984 [SMC_DIAG_CONNINFO] = decode_smc_diag_conninfo,
985 [SMC_DIAG_LGRINFO] = decode_smc_diag_lgrinfo,
986 [SMC_DIAG_SHUTDOWN] = decode_nla_u8
990 decode_smc_diag_msg(struct tcb *const tcp,
991 const struct nlmsghdr *const nlmsghdr,
992 const uint8_t family,
993 const kernel_ulong_t addr,
994 const kernel_ulong_t len)
996 struct smc_diag_msg msg = { .diag_family = family };
997 size_t offset = sizeof(msg.diag_family);
998 bool decode_nla = false;
1000 PRINT_FIELD_XVAL("{", msg, diag_family, addrfams, "AF_???");
1002 if (len >= sizeof(msg)) {
1003 if (!umoven_or_printaddr(tcp, addr + offset,
1004 sizeof(msg) - offset,
1005 (void *) &msg + offset)) {
1006 PRINT_FIELD_XVAL("", msg, diag_state,
1007 smc_states, "SMC_???");
1008 PRINT_FIELD_U(", ", msg, diag_fallback);
1009 PRINT_FIELD_U(", ", msg, diag_shutdown);
1011 * AF_SMC protocol family socket handler
1012 * keeping the AF_INET sock address.
1014 PRINT_FIELD_INET_DIAG_SOCKID(", ", msg, id, AF_INET);
1015 PRINT_FIELD_U(", ", msg, diag_uid);
1016 PRINT_FIELD_U(", ", msg, diag_inode);
1023 offset = NLA_ALIGN(sizeof(msg));
1024 if (decode_nla && len > offset) {
1026 decode_nlattr(tcp, addr + offset, len - offset,
1027 smc_diag_attrs, "SMC_DIAG_???",
1028 smc_diag_msg_nla_decoders,
1029 ARRAY_SIZE(smc_diag_msg_nla_decoders), NULL);
1034 typedef void (*netlink_diag_decoder_t)(struct tcb *,
1035 const struct nlmsghdr *,
1037 kernel_ulong_t addr,
1038 kernel_ulong_t len);
1040 static const struct {
1041 const netlink_diag_decoder_t request, response;
1042 } diag_decoders[] = {
1043 [AF_INET] = { decode_inet_diag_req, decode_inet_diag_msg },
1044 [AF_INET6] = { decode_inet_diag_req, decode_inet_diag_msg },
1045 [AF_NETLINK] = { decode_netlink_diag_req, decode_netlink_diag_msg },
1046 [AF_PACKET] = { decode_packet_diag_req, decode_packet_diag_msg },
1048 [AF_SMC] = { decode_smc_diag_req, decode_smc_diag_msg },
1050 [AF_UNIX] = { decode_unix_diag_req, decode_unix_diag_msg }
1054 decode_netlink_sock_diag(struct tcb *const tcp,
1055 const struct nlmsghdr *const nlmsghdr,
1056 const kernel_ulong_t addr,
1057 const kernel_ulong_t len)
1061 if (nlmsghdr->nlmsg_type == NLMSG_DONE)
1064 if (!umove_or_printaddr(tcp, addr, &family)) {
1065 if (family < ARRAY_SIZE(diag_decoders)
1066 && len > sizeof(family)) {
1067 const netlink_diag_decoder_t decoder =
1068 (nlmsghdr->nlmsg_flags & NLM_F_REQUEST)
1069 ? diag_decoders[family].request
1070 : diag_decoders[family].response;
1073 decoder(tcp, nlmsghdr, family, addr, len);
1078 decode_family(tcp, family, addr, len);