(root)/
strace-6.5/
src/
netlink_netfilter.c
       1  /*
       2   * Copyright (c) 2018 Chen Jingpiao <chenjingpiao@gmail.com>
       3   * Copyright (c) 2018-2021 The strace developers.
       4   * All rights reserved.
       5   *
       6   * SPDX-License-Identifier: LGPL-2.1-or-later
       7   */
       8  
       9  #include "defs.h"
      10  #include "nlattr.h"
      11  
      12  #include <netinet/in.h>
      13  #include <arpa/inet.h>
      14  #include "netlink.h"
      15  #include <linux/netfilter/nfnetlink.h>
      16  
      17  #include "xlat/netfilter_versions.h"
      18  #include "xlat/nl_netfilter_msg_types.h"
      19  #include "xlat/nl_netfilter_subsys_ids.h"
      20  
      21  bool
      22  decode_netlink_netfilter(struct tcb *const tcp,
      23  			 const struct nlmsghdr *const nlmsghdr,
      24  			 const kernel_ulong_t addr,
      25  			 const unsigned int len)
      26  {
      27  	if (nlmsghdr->nlmsg_type == NLMSG_DONE)
      28  		return false;
      29  
      30  	struct nfgenmsg nfmsg;
      31  
      32  	if (len < sizeof(nfmsg))
      33  		printstr_ex(tcp, addr, len, QUOTE_FORCE_HEX);
      34  	else if (!umove_or_printaddr(tcp, addr, &nfmsg)) {
      35  		const uint8_t subsys_id = (uint8_t) (nlmsghdr->nlmsg_type >> 8);
      36  		uint16_t res_id = ntohs(nfmsg.res_id);
      37  
      38  		tprint_struct_begin();
      39  		PRINT_FIELD_XVAL(nfmsg, nfgen_family, addrfams, "AF_???");
      40  		tprint_struct_next();
      41  		PRINT_FIELD_XVAL(nfmsg, version, netfilter_versions,
      42  				 "NFNETLINK_???");
      43  
      44  		/*
      45  		 * Work around wrong endianness in res_id field,
      46  		 * see linux commit v4.3-rc1~28^2~47^2~1
      47  		 */
      48  		tprint_struct_next();
      49  		tprints_field_name("res_id");
      50  		if (subsys_id == NFNL_SUBSYS_NFTABLES
      51  		    && res_id == NFNL_SUBSYS_NFTABLES) {
      52  			print_xlat_ex(nfmsg.res_id,
      53  				      "htons(NFNL_SUBSYS_NFTABLES)",
      54  				      XLAT_STYLE_DEFAULT);
      55  		} else if (subsys_id == NFNL_SUBSYS_NFTABLES
      56  			   && nfmsg.res_id == NFNL_SUBSYS_NFTABLES) {
      57  			print_xlat_ex(nfmsg.res_id, "NFNL_SUBSYS_NFTABLES",
      58  				      XLAT_STYLE_DEFAULT);
      59  		} else {
      60  			tprints_arg_begin("htons");
      61  			PRINT_VAL_U(res_id);
      62  			tprint_arg_end();
      63  		}
      64  		tprint_struct_end();
      65  
      66  		const size_t offset = NLMSG_ALIGN(sizeof(nfmsg));
      67  		if (len > offset) {
      68  			tprint_array_next();
      69  			if ((nlmsghdr->nlmsg_type >= NFNL_MSG_BATCH_BEGIN
      70  			     && nlmsghdr->nlmsg_type <= NFNL_MSG_BATCH_END)
      71  			    || nlmsghdr->nlmsg_type < NLMSG_MIN_TYPE)
      72  				printstr_ex(tcp, addr + offset,
      73  					    len - offset, QUOTE_FORCE_HEX);
      74  			else
      75  				decode_nlattr(tcp, addr + offset, len - offset,
      76  					      NULL, NULL, NULL, 0, NULL);
      77  		}
      78  	}
      79  
      80  	return true;
      81  }