libnftnl 1.2.9
nft-ct-expectation-get.c
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*
3 * (C) 2019 by Stéphane Veyret <sveyret@gmail.com>
4 */
5
6#include <stdlib.h>
7#include <time.h>
8#include <string.h>
9#include <netinet/in.h>
10
11#include <linux/netfilter.h>
12#include <linux/netfilter/nf_tables.h>
13
14#include <libmnl/libmnl.h>
15#include <libnftnl/object.h>
16
17static uint16_t parse_family(char *str, const char *option)
18{
19 if (strcmp(str, "ip") == 0)
20 return NFPROTO_IPV4;
21 else if (strcmp(str, "ip6") == 0)
22 return NFPROTO_IPV6;
23 else if (strcmp(str, "inet") == 0)
24 return NFPROTO_INET;
25 else if (strcmp(str, "arp") == 0)
26 return NFPROTO_INET;
27 fprintf(stderr, "Unknown %s: ip, ip6, inet, arp\n", option);
28 exit(EXIT_FAILURE);
29}
30
31static struct nftnl_obj *obj_parse(int argc, char *argv[])
32{
33 struct nftnl_obj *t;
34 uint16_t family;
35
36 t = nftnl_obj_alloc();
37 if (t == NULL) {
38 perror("OOM");
39 return NULL;
40 }
41
42 family = parse_family(argv[1], "family");
43 nftnl_obj_set_u32(t, NFTNL_OBJ_FAMILY, family);
44 nftnl_obj_set_u32(t, NFTNL_OBJ_TYPE, NFT_OBJECT_CT_EXPECT);
45 nftnl_obj_set_str(t, NFTNL_OBJ_TABLE, argv[2]);
46
47 if (argc > 3)
48 nftnl_obj_set_str(t, NFTNL_OBJ_NAME, argv[3]);
49
50 return t;
51}
52
53static int obj_cb(const struct nlmsghdr *nlh, void *data)
54{
55 uint32_t *type = data;
56 struct nftnl_obj *t;
57 char buf[4096];
58
59 t = nftnl_obj_alloc();
60 if (t == NULL) {
61 perror("OOM");
62 goto err;
63 }
64
65 if (nftnl_obj_nlmsg_parse(nlh, t) < 0) {
66 perror("nftnl_obj_nlmsg_parse");
67 goto err_free;
68 }
69
70 nftnl_obj_snprintf(buf, sizeof(buf), t, *type, 0);
71 printf("%s\n", buf);
72
73err_free:
74 nftnl_obj_free(t);
75err:
76 return MNL_CB_OK;
77}
78
79int main(int argc, char *argv[])
80{
81 struct mnl_socket *nl;
82 char buf[MNL_SOCKET_BUFFER_SIZE];
83 struct nlmsghdr *nlh;
84 uint32_t portid, seq, family;
85 struct nftnl_obj *t;
86 int ret;
87 uint32_t type = NFTNL_OUTPUT_DEFAULT;
88 uint16_t flags = NLM_F_ACK;
89
90 if (argc < 3 || argc > 4) {
91 fprintf(stderr, "%s <family> <table> [<name>]\n", argv[0]);
92 return EXIT_FAILURE;
93 }
94
95 t = obj_parse(argc, argv);
96 if (t == NULL)
97 exit(EXIT_FAILURE);
98 family = nftnl_obj_get_u32(t, NFTNL_OBJ_FAMILY);
99
100 seq = time(NULL);
101 if (argc < 4)
102 flags = NLM_F_DUMP;
103 nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETOBJ, family, flags, seq);
104 nftnl_obj_nlmsg_build_payload(nlh, t);
105 nftnl_obj_free(t);
106
107 nl = mnl_socket_open(NETLINK_NETFILTER);
108 if (nl == NULL) {
109 perror("mnl_socket_open");
110 exit(EXIT_FAILURE);
111 }
112
113 if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
114 perror("mnl_socket_bind");
115 exit(EXIT_FAILURE);
116 }
117 portid = mnl_socket_get_portid(nl);
118
119 if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
120 perror("mnl_socket_send");
121 exit(EXIT_FAILURE);
122 }
123
124 ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
125 while (ret > 0) {
126 ret = mnl_cb_run(buf, ret, seq, portid, obj_cb, &type);
127 if (ret <= 0)
128 break;
129 ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
130 }
131 if (ret == -1) {
132 perror("error");
133 exit(EXIT_FAILURE);
134 }
135 mnl_socket_close(nl);
136
137 return EXIT_SUCCESS;
138}