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/inet_diag.h>
37 #include <linux/netlink_diag.h>
38 #include <linux/packet_diag.h>
40 # include <linux/smc_diag.h>
42 #include <linux/sock_diag.h>
43 #include <linux/unix_diag.h>
45 #include "xlat/inet_diag_attrs.h"
46 #include "xlat/inet_diag_extended_flags.h"
47 #include "xlat/inet_diag_req_attrs.h"
49 #include "xlat/tcp_states.h"
50 #include "xlat/tcp_state_flags.h"
52 #include "xlat/netlink_diag_attrs.h"
53 #include "xlat/netlink_diag_show.h"
54 #include "xlat/netlink_socket_flags.h"
55 #include "xlat/netlink_states.h"
57 #include "xlat/packet_diag_attrs.h"
58 #include "xlat/packet_diag_show.h"
61 # include "xlat/smc_diag_attrs.h"
62 # include "xlat/smc_diag_extended_flags.h"
63 # include "xlat/smc_states.h"
66 #include "xlat/unix_diag_attrs.h"
67 #include "xlat/unix_diag_show.h"
70 decode_family(struct tcb *const tcp, const uint8_t family,
71 const kernel_ulong_t addr, const kernel_ulong_t len)
74 printxval(addrfams, family, "AF_???");
75 if (len > sizeof(family)) {
77 printstr_ex(tcp, addr + sizeof(family),
78 len - sizeof(family), QUOTE_FORCE_HEX);
84 decode_unix_diag_req(struct tcb *const tcp,
85 const struct nlmsghdr *const nlmsghdr,
87 const kernel_ulong_t addr,
88 const kernel_ulong_t len)
90 struct unix_diag_req req = { .sdiag_family = family };
91 const size_t offset = sizeof(req.sdiag_family);
93 PRINT_FIELD_XVAL("{", req, sdiag_family, addrfams, "AF_???");
95 if (len >= sizeof(req)) {
96 if (!umoven_or_printaddr(tcp, addr + offset,
98 (void *) &req + offset)) {
99 PRINT_FIELD_U("", req, sdiag_protocol);
100 PRINT_FIELD_FLAGS(", ", req, udiag_states,
101 tcp_state_flags, "1<<TCP_???");
102 PRINT_FIELD_U(", ", req, udiag_ino);
103 PRINT_FIELD_FLAGS(", ", req, udiag_show,
104 unix_diag_show, "UDIAG_SHOW_???");
105 PRINT_FIELD_COOKIE(", ", req, udiag_cookie);
113 print_meminfo(struct tcb *const tcp,
114 void *const elem_buf,
115 const size_t elem_size,
116 void *const opaque_data)
118 tprintf("%" PRIu32, *(uint32_t *) elem_buf);
124 decode_meminfo(struct tcb *const tcp,
125 const kernel_ulong_t addr,
126 const kernel_ulong_t len,
127 const void *const opaque_data)
130 size_t nmemb = len / sizeof(mem);
135 if (nmemb > SK_MEMINFO_VARS)
136 nmemb = SK_MEMINFO_VARS;
138 print_array(tcp, addr, nmemb, &mem, sizeof(mem),
139 umoven_or_printaddr, print_meminfo, 0);
145 decode_unix_diag_vfs(struct tcb *const tcp,
146 const kernel_ulong_t addr,
147 const kernel_ulong_t len,
148 const void *const opaque_data)
150 struct unix_diag_vfs uv;
152 if (len < sizeof(uv))
154 if (umove_or_printaddr(tcp, addr, &uv))
157 tprints("{udiag_vfs_dev=");
158 print_dev_t(uv.udiag_vfs_dev);
159 PRINT_FIELD_U(", ", uv, udiag_vfs_ino);
166 print_inode(struct tcb *const tcp,
167 void *const elem_buf,
168 const size_t elem_size,
169 void *const opaque_data)
171 tprintf("%" PRIu32, *(uint32_t *) elem_buf);
177 decode_unix_diag_inode(struct tcb *const tcp,
178 const kernel_ulong_t addr,
179 const kernel_ulong_t len,
180 const void *const opaque_data)
183 const size_t nmemb = len / sizeof(inode);
188 print_array(tcp, addr, nmemb, &inode, sizeof(inode),
189 umoven_or_printaddr, print_inode, 0);
195 decode_unix_diag_rqlen(struct tcb *const tcp,
196 const kernel_ulong_t addr,
197 const kernel_ulong_t len,
198 const void *const opaque_data)
200 struct unix_diag_rqlen rql;
202 if (len < sizeof(rql))
204 if (umove_or_printaddr(tcp, addr, &rql))
207 PRINT_FIELD_U("{", rql, udiag_rqueue);
208 PRINT_FIELD_U(", ", rql, udiag_wqueue);
214 static const nla_decoder_t unix_diag_msg_nla_decoders[] = {
215 [UNIX_DIAG_NAME] = decode_nla_str,
216 [UNIX_DIAG_VFS] = decode_unix_diag_vfs,
217 [UNIX_DIAG_PEER] = decode_nla_u32,
218 [UNIX_DIAG_ICONS] = decode_unix_diag_inode,
219 [UNIX_DIAG_RQLEN] = decode_unix_diag_rqlen,
220 [UNIX_DIAG_MEMINFO] = decode_meminfo,
221 [UNIX_DIAG_SHUTDOWN] = decode_nla_u8
225 decode_unix_diag_msg(struct tcb *const tcp,
226 const struct nlmsghdr *const nlmsghdr,
227 const uint8_t family,
228 const kernel_ulong_t addr,
229 const kernel_ulong_t len)
231 struct unix_diag_msg msg = { .udiag_family = family };
232 size_t offset = sizeof(msg.udiag_family);
233 bool decode_nla = false;
235 PRINT_FIELD_XVAL("{", msg, udiag_family, addrfams, "AF_???");
237 if (len >= sizeof(msg)) {
238 if (!umoven_or_printaddr(tcp, addr + offset,
239 sizeof(msg) - offset,
240 (void *) &msg + offset)) {
241 PRINT_FIELD_XVAL("", msg, udiag_type,
242 socktypes, "SOCK_???");
243 PRINT_FIELD_XVAL(", ", msg, udiag_state,
244 tcp_states, "TCP_???");
245 PRINT_FIELD_U(", ", msg, udiag_ino);
246 PRINT_FIELD_COOKIE(", ", msg, udiag_cookie);
253 offset = NLMSG_ALIGN(sizeof(msg));
254 if (decode_nla && len > offset) {
256 decode_nlattr(tcp, addr + offset, len - offset,
257 unix_diag_attrs, "UNIX_DIAG_???",
258 unix_diag_msg_nla_decoders,
259 ARRAY_SIZE(unix_diag_msg_nla_decoders), NULL);
264 decode_netlink_diag_req(struct tcb *const tcp,
265 const struct nlmsghdr *const nlmsghdr,
266 const uint8_t family,
267 const kernel_ulong_t addr,
268 const kernel_ulong_t len)
270 struct netlink_diag_req req = { .sdiag_family = family };
271 const size_t offset = sizeof(req.sdiag_family);
273 PRINT_FIELD_XVAL("{", req, sdiag_family, addrfams, "AF_???");
275 if (len >= sizeof(req)) {
276 if (!umoven_or_printaddr(tcp, addr + offset,
277 sizeof(req) - offset,
278 (void *) &req + offset)) {
279 if (NDIAG_PROTO_ALL == req.sdiag_protocol)
281 "sdiag_protocol", "NDIAG_PROTO_ALL");
283 PRINT_FIELD_XVAL("", req, sdiag_protocol,
286 PRINT_FIELD_U(", ", req, ndiag_ino);
287 PRINT_FIELD_FLAGS(", ", req, ndiag_show,
288 netlink_diag_show, "NDIAG_SHOW_???");
289 PRINT_FIELD_COOKIE(", ", req, ndiag_cookie);
297 print_group(struct tcb *const tcp,
298 void *const elem_buf,
299 const size_t elem_size,
300 void *const opaque_data)
302 if (elem_size < sizeof(kernel_ulong_t))
303 tprintf("%#0*x", (int) elem_size * 2 + 2,
304 *(unsigned int *) elem_buf);
306 tprintf("%#0*" PRI_klx, (int) elem_size * 2 + 2,
307 *(kernel_ulong_t *) elem_buf);
313 decode_netlink_diag_groups(struct tcb *const tcp,
314 const kernel_ulong_t addr,
315 const kernel_ulong_t len,
316 const void *const opaque_data)
319 const size_t nmemb = len / current_wordsize;
324 print_array(tcp, addr, nmemb, &buf, current_wordsize,
325 umoven_or_printaddr, print_group, 0);
331 decode_netlink_diag_ring(struct tcb *const tcp,
332 const kernel_ulong_t addr,
333 const kernel_ulong_t len,
334 const void *const opaque_data)
336 struct netlink_diag_ring ndr;
338 if (len < sizeof(ndr))
340 if (umove_or_printaddr(tcp, addr, &ndr))
343 PRINT_FIELD_U("{", ndr, ndr_block_size);
344 PRINT_FIELD_U(", ", ndr, ndr_block_nr);
345 PRINT_FIELD_U(", ", ndr, ndr_frame_size);
346 PRINT_FIELD_U(", ", ndr, ndr_frame_nr);
353 decode_netlink_diag_flags(struct tcb *const tcp,
354 const kernel_ulong_t addr,
355 const kernel_ulong_t len,
356 const void *const opaque_data)
360 if (len < sizeof(flags))
362 if (umove_or_printaddr(tcp, addr, &flags))
365 printflags(netlink_socket_flags, flags, "NDIAG_FLAG_???");
370 static const nla_decoder_t netlink_diag_msg_nla_decoders[] = {
371 [NETLINK_DIAG_MEMINFO] = decode_meminfo,
372 [NETLINK_DIAG_GROUPS] = decode_netlink_diag_groups,
373 [NETLINK_DIAG_RX_RING] = decode_netlink_diag_ring,
374 [NETLINK_DIAG_TX_RING] = decode_netlink_diag_ring,
375 [NETLINK_DIAG_FLAGS] = decode_netlink_diag_flags
379 decode_netlink_diag_msg(struct tcb *const tcp,
380 const struct nlmsghdr *const nlmsghdr,
381 const uint8_t family,
382 const kernel_ulong_t addr,
383 const kernel_ulong_t len)
385 struct netlink_diag_msg msg = { .ndiag_family = family };
386 size_t offset = sizeof(msg.ndiag_family);
387 bool decode_nla = false;
389 PRINT_FIELD_XVAL("{", msg, ndiag_family, addrfams, "AF_???");
391 if (len >= sizeof(msg)) {
392 if (!umoven_or_printaddr(tcp, addr + offset,
393 sizeof(msg) - offset,
394 (void *) &msg + offset)) {
395 PRINT_FIELD_XVAL("", msg, ndiag_type,
396 socktypes, "SOCK_???");
397 PRINT_FIELD_XVAL(", ", msg, ndiag_protocol,
398 netlink_protocols, "NETLINK_???");
399 PRINT_FIELD_XVAL(", ", msg, ndiag_state,
400 netlink_states, "NETLINK_???");
401 PRINT_FIELD_U(", ", msg, ndiag_portid);
402 PRINT_FIELD_U(", ", msg, ndiag_dst_portid);
403 PRINT_FIELD_U(", ", msg, ndiag_dst_group);
404 PRINT_FIELD_U(", ", msg, ndiag_ino);
405 PRINT_FIELD_COOKIE(", ", msg, ndiag_cookie);
412 offset = NLA_ALIGN(sizeof(msg));
413 if (decode_nla && len > offset) {
415 decode_nlattr(tcp, addr + offset, len - offset,
416 netlink_diag_attrs, "NETLINK_DIAG_???",
417 netlink_diag_msg_nla_decoders,
418 ARRAY_SIZE(netlink_diag_msg_nla_decoders), NULL);
423 decode_packet_diag_req(struct tcb *const tcp,
424 const struct nlmsghdr *const nlmsghdr,
425 const uint8_t family,
426 const kernel_ulong_t addr,
427 const kernel_ulong_t len)
429 struct packet_diag_req req = { .sdiag_family = family };
430 const size_t offset = sizeof(req.sdiag_family);
432 PRINT_FIELD_XVAL("{", req, sdiag_family, addrfams, "AF_???");
434 if (len >= sizeof(req)) {
435 if (!umoven_or_printaddr(tcp, addr + offset,
436 sizeof(req) - offset,
437 (void *) &req + offset)) {
438 PRINT_FIELD_XVAL("", req, sdiag_protocol,
439 ethernet_protocols, "ETH_P_???");
440 PRINT_FIELD_U(", ", req, pdiag_ino);
441 PRINT_FIELD_FLAGS(", ", req, pdiag_show,
442 packet_diag_show, "PACKET_SHOW_???");
443 PRINT_FIELD_COOKIE(", ", req, pdiag_cookie);
451 decode_packet_diag_msg(struct tcb *const tcp,
452 const struct nlmsghdr *const nlmsghdr,
453 const uint8_t family,
454 const kernel_ulong_t addr,
455 const kernel_ulong_t len)
457 struct packet_diag_msg msg = { .pdiag_family = family };
458 size_t offset = sizeof(msg.pdiag_family);
459 bool decode_nla = false;
461 PRINT_FIELD_XVAL("{", msg, pdiag_family, addrfams, "AF_???");
463 if (len >= sizeof(msg)) {
464 if (!umoven_or_printaddr(tcp, addr + offset,
465 sizeof(msg) - offset,
466 (void *) &msg + offset)) {
467 PRINT_FIELD_XVAL("", msg, pdiag_type,
468 socktypes, "SOCK_???");
469 PRINT_FIELD_U(", ", msg, pdiag_num);
470 PRINT_FIELD_U(", ", msg, pdiag_ino);
471 PRINT_FIELD_COOKIE(", ", msg, pdiag_cookie);
478 offset = NLA_ALIGN(sizeof(msg));
479 if (decode_nla && len > offset) {
481 decode_nlattr(tcp, addr + offset, len - offset,
482 packet_diag_attrs, "PACKET_DIAG_???",
488 print_inet_diag_sockid(const struct inet_diag_sockid *id, const uint8_t family)
490 tprintf("{idiag_sport=htons(%u), idiag_dport=htons(%u)",
491 ntohs(id->idiag_sport), ntohs(id->idiag_dport));
494 print_inet_addr(family, id->idiag_src,
495 sizeof(id->idiag_src), "idiag_src");
497 print_inet_addr(family, id->idiag_dst,
498 sizeof(id->idiag_dst), "idiag_dst");
500 tprints(", idiag_if=");
501 print_ifindex(id->idiag_if);
503 PRINT_FIELD_COOKIE(", ", *id, idiag_cookie);
509 decode_inet_diag_req_compat(struct tcb *const tcp,
510 const struct nlmsghdr *const nlmsghdr,
511 const uint8_t family,
512 const kernel_ulong_t addr,
513 const kernel_ulong_t len)
515 struct inet_diag_req req = { .idiag_family = family };
516 size_t offset = sizeof(req.idiag_family);
517 bool decode_nla = false;
519 PRINT_FIELD_XVAL("{", req, idiag_family, addrfams, "AF_???");
521 if (len >= sizeof(req)) {
522 if (!umoven_or_printaddr(tcp, addr + offset,
523 sizeof(req) - offset,
524 (void *) &req + offset)) {
525 PRINT_FIELD_U("", req, idiag_src_len);
526 PRINT_FIELD_U(", ", req, idiag_dst_len);
527 PRINT_FIELD_FLAGS(", ", req, idiag_ext,
528 inet_diag_extended_flags,
529 "1<<INET_DIAG_\?\?\?-1");
531 print_inet_diag_sockid(&req.id, req.idiag_family);
532 PRINT_FIELD_FLAGS(", ", req, idiag_states,
533 tcp_state_flags, "1<<TCP_???");
534 PRINT_FIELD_U(", ", req, idiag_dbs);
541 offset = NLA_ALIGN(sizeof(req));
542 if (decode_nla && len > offset) {
544 decode_nlattr(tcp, addr + offset, len - offset,
545 inet_diag_req_attrs, "INET_DIAG_REQ_???",
551 decode_inet_diag_req_v2(struct tcb *const tcp,
552 const struct nlmsghdr *const nlmsghdr,
553 const uint8_t family,
554 const kernel_ulong_t addr,
555 const kernel_ulong_t len)
557 struct inet_diag_req_v2 req = { .sdiag_family = family };
558 size_t offset = sizeof(req.sdiag_family);
559 bool decode_nla = false;
561 PRINT_FIELD_XVAL("{", req, sdiag_family, addrfams, "AF_???");
563 if (len >= sizeof(req)) {
564 if (!umoven_or_printaddr(tcp, addr + offset,
565 sizeof(req) - offset,
566 (void *) &req + offset)) {
567 PRINT_FIELD_XVAL("", req, sdiag_protocol,
568 inet_protocols, "IPPROTO_???");
569 PRINT_FIELD_FLAGS(", ", req, idiag_ext,
570 inet_diag_extended_flags,
571 "1<<INET_DIAG_\?\?\?-1");
572 PRINT_FIELD_FLAGS(", ", req, idiag_states,
573 tcp_state_flags, "1<<TCP_???");
575 print_inet_diag_sockid(&req.id, req.sdiag_family);
582 offset = NLA_ALIGN(sizeof(req));
583 if (decode_nla && len > offset) {
585 decode_nlattr(tcp, addr + offset, len - offset,
586 inet_diag_req_attrs, "INET_DIAG_REQ_???",
592 decode_inet_diag_req(struct tcb *const tcp,
593 const struct nlmsghdr *const nlmsghdr,
594 const uint8_t family,
595 const kernel_ulong_t addr,
596 const kernel_ulong_t len)
598 if (nlmsghdr->nlmsg_type == TCPDIAG_GETSOCK
599 || nlmsghdr->nlmsg_type == DCCPDIAG_GETSOCK)
600 return decode_inet_diag_req_compat(tcp, nlmsghdr,
603 return decode_inet_diag_req_v2(tcp, nlmsghdr,
608 decode_inet_diag_meminfo(struct tcb *const tcp,
609 const kernel_ulong_t addr,
610 const kernel_ulong_t len,
611 const void *const opaque_data)
613 struct inet_diag_meminfo minfo;
615 if (len < sizeof(minfo))
617 if (umove_or_printaddr(tcp, addr, &minfo))
620 PRINT_FIELD_U("{", minfo, idiag_rmem);
621 PRINT_FIELD_U(", ", minfo, idiag_wmem);
622 PRINT_FIELD_U(", ", minfo, idiag_fmem);
623 PRINT_FIELD_U(", ", minfo, idiag_tmem);
630 decode_tcpvegas_info(struct tcb *const tcp,
631 const kernel_ulong_t addr,
632 const kernel_ulong_t len,
633 const void *const opaque_data)
635 struct tcpvegas_info vegas;
637 if (len < sizeof(vegas))
639 if (umove_or_printaddr(tcp, addr, &vegas))
642 PRINT_FIELD_U("{", vegas, tcpv_enabled);
643 PRINT_FIELD_U(", ", vegas, tcpv_rttcnt);
644 PRINT_FIELD_U(", ", vegas, tcpv_rtt);
645 PRINT_FIELD_U(", ", vegas, tcpv_minrtt);
652 decode_tcp_dctcp_info(struct tcb *const tcp,
653 const kernel_ulong_t addr,
654 const kernel_ulong_t len,
655 const void *const opaque_data)
657 struct tcp_dctcp_info dctcp;
659 if (len < sizeof(dctcp))
661 if (umove_or_printaddr(tcp, addr, &dctcp))
664 PRINT_FIELD_U("{", dctcp, dctcp_enabled);
665 PRINT_FIELD_U(", ", dctcp, dctcp_ce_state);
666 PRINT_FIELD_U(", ", dctcp, dctcp_alpha);
667 PRINT_FIELD_U(", ", dctcp, dctcp_ab_ecn);
668 PRINT_FIELD_U(", ", dctcp, dctcp_ab_tot);
675 decode_tcp_bbr_info(struct tcb *const tcp,
676 const kernel_ulong_t addr,
677 const kernel_ulong_t len,
678 const void *const opaque_data)
680 struct tcp_bbr_info bbr;
682 if (len < sizeof(bbr))
684 if (umove_or_printaddr(tcp, addr, &bbr))
687 PRINT_FIELD_X("{", bbr, bbr_bw_lo);
688 PRINT_FIELD_X(", ", bbr, bbr_bw_hi);
689 PRINT_FIELD_U(", ", bbr, bbr_min_rtt);
690 PRINT_FIELD_U(", ", bbr, bbr_pacing_gain);
691 PRINT_FIELD_U(", ", bbr, bbr_cwnd_gain);
697 static const nla_decoder_t inet_diag_msg_nla_decoders[] = {
698 [INET_DIAG_MEMINFO] = decode_inet_diag_meminfo,
699 [INET_DIAG_INFO] = NULL, /* unimplemented */
700 [INET_DIAG_VEGASINFO] = decode_tcpvegas_info,
701 [INET_DIAG_CONG] = decode_nla_str,
702 [INET_DIAG_TOS] = decode_nla_u8,
703 [INET_DIAG_TCLASS] = decode_nla_u8,
704 [INET_DIAG_SKMEMINFO] = decode_meminfo,
705 [INET_DIAG_SHUTDOWN] = decode_nla_u8,
706 [INET_DIAG_DCTCPINFO] = decode_tcp_dctcp_info,
707 [INET_DIAG_PROTOCOL] = decode_nla_u8,
708 [INET_DIAG_SKV6ONLY] = decode_nla_u8,
709 [INET_DIAG_LOCALS] = NULL, /* unimplemented */
710 [INET_DIAG_PEERS] = NULL, /* unimplemented */
711 [INET_DIAG_PAD] = NULL,
712 [INET_DIAG_MARK] = decode_nla_u32,
713 [INET_DIAG_BBRINFO] = decode_tcp_bbr_info
717 decode_inet_diag_msg(struct tcb *const tcp,
718 const struct nlmsghdr *const nlmsghdr,
719 const uint8_t family,
720 const kernel_ulong_t addr,
721 const kernel_ulong_t len)
723 struct inet_diag_msg msg = { .idiag_family = family };
724 size_t offset = sizeof(msg.idiag_family);
725 bool decode_nla = false;
727 PRINT_FIELD_XVAL("{", msg, idiag_family, addrfams, "AF_???");
729 if (len >= sizeof(msg)) {
730 if (!umoven_or_printaddr(tcp, addr + offset,
731 sizeof(msg) - offset,
732 (void *) &msg + offset)) {
733 PRINT_FIELD_XVAL("", msg, idiag_state,
734 tcp_states, "TCP_???");
735 PRINT_FIELD_U(", ", msg, idiag_timer);
736 PRINT_FIELD_U(", ", msg, idiag_retrans);
738 print_inet_diag_sockid(&msg.id, msg.idiag_family);
739 PRINT_FIELD_U(", ", msg, idiag_expires);
740 PRINT_FIELD_U(", ", msg, idiag_rqueue);
741 PRINT_FIELD_U(", ", msg, idiag_wqueue);
742 PRINT_FIELD_U(", ", msg, idiag_uid);
743 PRINT_FIELD_U(", ", msg, idiag_inode);
750 offset = NLA_ALIGN(sizeof(msg));
751 if (decode_nla && len > offset) {
753 decode_nlattr(tcp, addr + offset, len - offset,
754 inet_diag_attrs, "INET_DIAG_???",
755 inet_diag_msg_nla_decoders,
756 ARRAY_SIZE(inet_diag_msg_nla_decoders), NULL);
762 decode_smc_diag_req(struct tcb *const tcp,
763 const struct nlmsghdr *const nlmsghdr,
764 const uint8_t family,
765 const kernel_ulong_t addr,
766 const kernel_ulong_t len)
768 struct smc_diag_req req = { .diag_family = family };
769 const size_t offset = sizeof(req.diag_family);
771 PRINT_FIELD_XVAL("{", req, diag_family, addrfams, "AF_???");
773 if (len >= sizeof(req)) {
774 if (!umoven_or_printaddr(tcp, addr + offset,
775 sizeof(req) - offset,
776 (void *) &req + offset)) {
777 PRINT_FIELD_FLAGS("", req, diag_ext,
778 smc_diag_extended_flags,
779 "1<<SMC_DIAG_\?\?\?-1");
782 * AF_SMC protocol family socket handler
783 * keeping the AF_INET sock address.
785 print_inet_diag_sockid(&req.id, AF_INET);
793 decode_smc_diag_msg(struct tcb *const tcp,
794 const struct nlmsghdr *const nlmsghdr,
795 const uint8_t family,
796 const kernel_ulong_t addr,
797 const kernel_ulong_t len)
799 struct smc_diag_msg msg = { .diag_family = family };
800 size_t offset = sizeof(msg.diag_family);
801 bool decode_nla = false;
803 PRINT_FIELD_XVAL("{", msg, diag_family, addrfams, "AF_???");
805 if (len >= sizeof(msg)) {
806 if (!umoven_or_printaddr(tcp, addr + offset,
807 sizeof(msg) - offset,
808 (void *) &msg + offset)) {
809 PRINT_FIELD_XVAL("", msg, diag_state,
810 smc_states, "SMC_???");
811 PRINT_FIELD_U(", ", msg, diag_fallback);
812 PRINT_FIELD_U(", ", msg, diag_shutdown);
815 * AF_SMC protocol family socket handler
816 * keeping the AF_INET sock address.
818 print_inet_diag_sockid(&msg.id, AF_INET);
819 PRINT_FIELD_U(", ", msg, diag_uid);
820 PRINT_FIELD_U(", ", msg, diag_inode);
827 offset = NLA_ALIGN(sizeof(msg));
828 if (decode_nla && len > offset) {
830 decode_nlattr(tcp, addr + offset, len - offset,
831 smc_diag_attrs, "SMC_DIAG_???",
837 typedef void (*netlink_diag_decoder_t)(struct tcb *,
838 const struct nlmsghdr *,
843 static const struct {
844 const netlink_diag_decoder_t request, response;
845 } diag_decoders[] = {
846 [AF_INET] = { decode_inet_diag_req, decode_inet_diag_msg },
847 [AF_INET6] = { decode_inet_diag_req, decode_inet_diag_msg },
848 [AF_NETLINK] = { decode_netlink_diag_req, decode_netlink_diag_msg },
849 [AF_PACKET] = { decode_packet_diag_req, decode_packet_diag_msg },
851 [AF_SMC] = { decode_smc_diag_req, decode_smc_diag_msg },
853 [AF_UNIX] = { decode_unix_diag_req, decode_unix_diag_msg }
857 decode_netlink_sock_diag(struct tcb *const tcp,
858 const struct nlmsghdr *const nlmsghdr,
859 const kernel_ulong_t addr,
860 const kernel_ulong_t len)
864 if (nlmsghdr->nlmsg_type == NLMSG_DONE)
867 if (!umove_or_printaddr(tcp, addr, &family)) {
868 if (family < ARRAY_SIZE(diag_decoders)
869 && len > sizeof(family)) {
870 const netlink_diag_decoder_t decoder =
871 (nlmsghdr->nlmsg_flags & NLM_F_REQUEST)
872 ? diag_decoders[family].request
873 : diag_decoders[family].response;
876 decoder(tcp, nlmsghdr, family, addr, len);
881 decode_family(tcp, family, addr, len);