(root)/
strace-6.5/
tests/
netlink_netfilter.c
       1  /*
       2   * Copyright (c) 2017, 2018 Chen Jingpiao <chenjingpiao@gmail.com>
       3   * Copyright (c) 2017-2021 The strace developers.
       4   * All rights reserved.
       5   *
       6   * SPDX-License-Identifier: GPL-2.0-or-later
       7   */
       8  
       9  #include "tests.h"
      10  #include <stdio.h>
      11  #include <string.h>
      12  #include <unistd.h>
      13  #include <netinet/in.h>
      14  #include <arpa/inet.h>
      15  #include <sys/socket.h>
      16  #include "test_netlink.h"
      17  #include <linux/netfilter/nfnetlink.h>
      18  #include <linux/netfilter/nf_tables.h>
      19  
      20  static void
      21  test_nlmsg_type(const int fd)
      22  {
      23  	long rc;
      24  	struct nlmsghdr nlh = {
      25  		.nlmsg_len = sizeof(nlh),
      26  		.nlmsg_flags = NLM_F_REQUEST,
      27  	};
      28  
      29  	nlh.nlmsg_type = NFNL_MSG_BATCH_BEGIN;
      30  	rc = sendto(fd, &nlh, sizeof(nlh), MSG_DONTWAIT, NULL, 0);
      31  	printf("sendto(%d, {nlmsg_len=%u, nlmsg_type=NFNL_MSG_BATCH_BEGIN"
      32  	       ", nlmsg_flags=NLM_F_REQUEST, nlmsg_seq=0, nlmsg_pid=0}"
      33  	       ", %u, MSG_DONTWAIT, NULL, 0) = %s\n",
      34  	       fd, nlh.nlmsg_len, (unsigned) sizeof(nlh), sprintrc(rc));
      35  
      36  	nlh.nlmsg_type = NFNL_SUBSYS_CTNETLINK << 8 | 0xff;
      37  	rc = sendto(fd, &nlh, sizeof(nlh), MSG_DONTWAIT, NULL, 0);
      38  	printf("sendto(%d, {nlmsg_len=%u"
      39  	       ", nlmsg_type=NFNL_SUBSYS_CTNETLINK<<8|0xff"
      40  	       " /* IPCTNL_MSG_CT_??? */, nlmsg_flags=NLM_F_REQUEST"
      41  	       ", nlmsg_seq=0, nlmsg_pid=0}, %u, MSG_DONTWAIT, NULL, 0) = %s\n",
      42  	       fd, nlh.nlmsg_len, (unsigned) sizeof(nlh), sprintrc(rc));
      43  
      44  	nlh.nlmsg_type = 0xffff;
      45  	rc = sendto(fd, &nlh, sizeof(nlh), MSG_DONTWAIT, NULL, 0);
      46  	printf("sendto(%d, {nlmsg_len=%u, nlmsg_type=0xff"
      47  	       " /* NFNL_SUBSYS_??? */<<8|0xff, nlmsg_flags=NLM_F_REQUEST"
      48  	       ", nlmsg_seq=0, nlmsg_pid=0}, %u, MSG_DONTWAIT, NULL, 0) = %s\n",
      49  	       fd, nlh.nlmsg_len, (unsigned) sizeof(nlh), sprintrc(rc));
      50  }
      51  
      52  static void
      53  test_nlmsg_done(const int fd)
      54  {
      55  	const int num = 0xabcdefad;
      56  	void *const nlh0 = midtail_alloc(NLMSG_HDRLEN, sizeof(num));
      57  
      58  	TEST_NETLINK(fd, nlh0, NLMSG_DONE, NLM_F_REQUEST,
      59  		     sizeof(num), &num, sizeof(num),
      60  		     printf("%d", num));
      61  }
      62  
      63  static void
      64  test_nfgenmsg(const int fd)
      65  {
      66  	static const struct nlattr nla = {
      67  		.nla_len = sizeof(nla),
      68  		.nla_type = 0x0bcd
      69  	};
      70  
      71  	struct nfgenmsg msg = {
      72  		.nfgen_family = AF_UNIX,
      73  		.version = NFNETLINK_V0,
      74  		.res_id = NFNL_SUBSYS_NFTABLES
      75  	};
      76  	char str_buf[NLMSG_ALIGN(sizeof(msg)) + 4];
      77  	char nla_buf[NLMSG_ALIGN(sizeof(msg)) + sizeof(nla)];
      78  
      79  	void *const nlh0 = midtail_alloc(NLMSG_HDRLEN,
      80  					 MAX(sizeof(str_buf), sizeof(nla_buf)));
      81  
      82  	TEST_NETLINK_OBJECT_EX_(fd, nlh0,
      83  				NFNL_SUBSYS_NFTABLES << 8 | NFT_MSG_NEWTABLE,
      84  				"NFNL_SUBSYS_NFTABLES<<8|NFT_MSG_NEWTABLE",
      85  				NLM_F_REQUEST, "NLM_F_REQUEST",
      86  				msg, print_quoted_hex,
      87  				printf("{nfgen_family=AF_UNIX");
      88  				printf(", version=NFNETLINK_V0");
      89  				printf(", res_id=");
      90  				if (htons(NFNL_SUBSYS_NFTABLES) == NFNL_SUBSYS_NFTABLES)
      91  					printf("htons(NFNL_SUBSYS_NFTABLES)");
      92  				else
      93  					printf("NFNL_SUBSYS_NFTABLES");
      94  				printf("}");
      95  				);
      96  
      97  	msg.res_id = htons(NFNL_SUBSYS_NFTABLES);
      98  	TEST_NETLINK_(fd, nlh0,
      99  		      NFNL_SUBSYS_NFTABLES << 8 | NFT_MSG_NEWTABLE,
     100  		      "NFNL_SUBSYS_NFTABLES<<8|NFT_MSG_NEWTABLE",
     101  		      NLM_F_REQUEST, "NLM_F_REQUEST",
     102  		      sizeof(msg), &msg, sizeof(msg),
     103  		      printf("{nfgen_family=AF_UNIX");
     104  		      printf(", version=NFNETLINK_V0");
     105  		      printf(", res_id=htons(NFNL_SUBSYS_NFTABLES)}"));
     106  
     107  	msg.res_id = htons(0xabcd);
     108  	TEST_NETLINK_(fd, nlh0,
     109  		      NFNL_SUBSYS_NFTABLES << 8 | NFT_MSG_NEWTABLE,
     110  		      "NFNL_SUBSYS_NFTABLES<<8|NFT_MSG_NEWTABLE",
     111  		      NLM_F_REQUEST, "NLM_F_REQUEST",
     112  		      sizeof(msg), &msg, sizeof(msg),
     113  		      printf("{nfgen_family=AF_UNIX");
     114  		      printf(", version=NFNETLINK_V0");
     115  		      printf(", res_id=htons(%d)}", 0xabcd));
     116  
     117  	msg.res_id = htons(NFNL_SUBSYS_NFTABLES);
     118  	TEST_NETLINK(fd, nlh0,
     119  		     NFNL_MSG_BATCH_BEGIN, NLM_F_REQUEST,
     120  		     sizeof(msg), &msg, sizeof(msg),
     121  		     printf("{nfgen_family=AF_UNIX");
     122  		     printf(", version=NFNETLINK_V0");
     123  		     printf(", res_id=htons(%d)}", NFNL_SUBSYS_NFTABLES));
     124  
     125  	msg.res_id = htons(0xabcd);
     126  	memcpy(str_buf, &msg, sizeof(msg));
     127  	memcpy(str_buf + NLMSG_ALIGN(sizeof(msg)), "1234", 4);
     128  
     129  	TEST_NETLINK(fd, nlh0,
     130  		     NFNL_MSG_BATCH_BEGIN, NLM_F_REQUEST,
     131  		     sizeof(str_buf), str_buf, sizeof(str_buf),
     132  		     printf("{nfgen_family=AF_UNIX");
     133  		     printf(", version=NFNETLINK_V0");
     134  		     printf(", res_id=htons(%d)}"
     135  			    ", \"\\x31\\x32\\x33\\x34\"", 0xabcd));
     136  
     137  	msg.res_id = htons(NFNL_SUBSYS_NFTABLES);
     138  	memcpy(nla_buf, &msg, sizeof(msg));
     139  	memcpy(nla_buf + NLMSG_ALIGN(sizeof(msg)), &nla, sizeof(nla));
     140  
     141  	TEST_NETLINK_(fd, nlh0,
     142  		      NFNL_SUBSYS_NFTABLES << 8 | 0xff,
     143  		      "NFNL_SUBSYS_NFTABLES<<8|0xff /* NFT_MSG_??? */",
     144  		      NLM_F_REQUEST, "NLM_F_REQUEST",
     145  		      sizeof(nla_buf), nla_buf, sizeof(nla_buf),
     146  		      printf("{nfgen_family=AF_UNIX");
     147  		      printf(", version=NFNETLINK_V0");
     148  		      printf(", res_id=htons(NFNL_SUBSYS_NFTABLES)}"
     149  			     ", {nla_len=%d, nla_type=%#x}",
     150  			     nla.nla_len, nla.nla_type));
     151  }
     152  
     153  int main(void)
     154  {
     155  	skip_if_unavailable("/proc/self/fd/");
     156  
     157  	int fd = create_nl_socket(NETLINK_NETFILTER);
     158  
     159  	test_nlmsg_type(fd);
     160  	test_nlmsg_done(fd);
     161  	test_nfgenmsg(fd);
     162  
     163  	printf("+++ exited with 0 +++\n");
     164  
     165  	return 0;
     166  }