(root)/
strace-6.5/
src/
netlink_sock_diag.c
       1  /*
       2   * Copyright (c) 2016 Fabien Siron <fabien.siron@epita.fr>
       3   * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
       4   * Copyright (c) 2017-2021 The strace developers.
       5   * All rights reserved.
       6   *
       7   * SPDX-License-Identifier: LGPL-2.1-or-later
       8   */
       9  
      10  #include "defs.h"
      11  #include "netlink.h"
      12  #include "netlink_sock_diag.h"
      13  
      14  #define XLAT_MACROS_ONLY
      15  #include "xlat/addrfams.h"
      16  #undef XLAT_MACROS_ONLY
      17  
      18  static void
      19  decode_family(struct tcb *const tcp, const uint8_t family,
      20  	      const kernel_ulong_t addr, const unsigned int len)
      21  {
      22  	tprint_struct_begin();
      23  	tprints_field_name("family");
      24  	printxval(addrfams, family, "AF_???");
      25  	if (len > sizeof(family)) {
      26  		tprint_struct_next();
      27  		tprints_field_name("data");
      28  		printstr_ex(tcp, addr + sizeof(family),
      29  			    len - sizeof(family), QUOTE_FORCE_HEX);
      30  	}
      31  	tprint_struct_end();
      32  }
      33  
      34  typedef DECL_NETLINK_DIAG_DECODER((*netlink_diag_decoder_t));
      35  
      36  static const struct {
      37  	const netlink_diag_decoder_t request, response;
      38  } diag_decoders[] = {
      39  	[AF_UNIX] = { decode_unix_diag_req, decode_unix_diag_msg },
      40  	[AF_INET] = { decode_inet_diag_req, decode_inet_diag_msg },
      41  	[AF_INET6] = { decode_inet_diag_req, decode_inet_diag_msg },
      42  	[AF_NETLINK] = { decode_netlink_diag_req, decode_netlink_diag_msg },
      43  	[AF_PACKET] = { decode_packet_diag_req, decode_packet_diag_msg },
      44  	[AF_SMC] = { decode_smc_diag_req, decode_smc_diag_msg },
      45  };
      46  
      47  bool
      48  decode_netlink_sock_diag(struct tcb *const tcp,
      49  			 const struct nlmsghdr *const nlmsghdr,
      50  			 const kernel_ulong_t addr,
      51  			 const unsigned int len)
      52  {
      53  	uint8_t family;
      54  
      55  	if (nlmsghdr->nlmsg_type == NLMSG_DONE)
      56  		return false;
      57  
      58  	if (!umove_or_printaddr(tcp, addr, &family)) {
      59  		if (family < ARRAY_SIZE(diag_decoders)
      60  		    && len > sizeof(family)) {
      61  			const netlink_diag_decoder_t decoder =
      62  				(nlmsghdr->nlmsg_flags & NLM_F_REQUEST)
      63  				? diag_decoders[family].request
      64  				: diag_decoders[family].response;
      65  
      66  			if (decoder) {
      67  				decoder(tcp, nlmsghdr, family, addr, len);
      68  				return true;
      69  			}
      70  		}
      71  
      72  		decode_family(tcp, family, addr, len);
      73  	}
      74  
      75  	return true;
      76  }