libnftnl 1.2.9
nft-events.c
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*
3 * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
4 *
5 * This software has been sponsored by Sophos Astaro <http://www.sophos.com>
6 */
7
8#include <stdlib.h>
9#include <time.h>
10#include <string.h>
11#include <netinet/in.h>
12
13#include <linux/netfilter/nfnetlink.h>
14#include <linux/netfilter/nf_tables.h>
15
16#include <libmnl/libmnl.h>
17#include <libnftnl/table.h>
18#include <libnftnl/chain.h>
19#include <libnftnl/rule.h>
20#include <libnftnl/set.h>
21#include <libnftnl/gen.h>
22#include <libnftnl/common.h>
23
24static uint32_t event2flag(uint32_t event)
25{
26 switch (event) {
27 case NFT_MSG_NEWTABLE:
28 case NFT_MSG_NEWCHAIN:
29 case NFT_MSG_NEWRULE:
30 case NFT_MSG_NEWSET:
31 case NFT_MSG_NEWSETELEM:
32 case NFT_MSG_NEWGEN:
33 return NFTNL_OF_EVENT_NEW;
34 case NFT_MSG_DELTABLE:
35 case NFT_MSG_DELCHAIN:
36 case NFT_MSG_DELRULE:
37 case NFT_MSG_DELSET:
38 case NFT_MSG_DELSETELEM:
39 return NFTNL_OF_EVENT_DEL;
40 }
41
42 return 0;
43}
44
45static int table_cb(const struct nlmsghdr *nlh, int event, int type)
46{
47 struct nftnl_table *t;
48
49 t = nftnl_table_alloc();
50 if (t == NULL) {
51 perror("OOM");
52 goto err;
53 }
54
55 if (nftnl_table_nlmsg_parse(nlh, t) < 0) {
56 perror("nftnl_table_nlmsg_parse");
57 goto err_free;
58 }
59
60 nftnl_table_fprintf(stdout, t, type, event2flag(event));
61 fprintf(stdout, "\n");
62
63err_free:
64 nftnl_table_free(t);
65err:
66 return MNL_CB_OK;
67}
68
69static int rule_cb(const struct nlmsghdr *nlh, int event, int type)
70{
71 struct nftnl_rule *t;
72
73 t = nftnl_rule_alloc();
74 if (t == NULL) {
75 perror("OOM");
76 goto err;
77 }
78
79 if (nftnl_rule_nlmsg_parse(nlh, t) < 0) {
80 perror("nftnl_rule_nlmsg_parse");
81 goto err_free;
82 }
83
84 nftnl_rule_fprintf(stdout, t, type, event2flag(event));
85 fprintf(stdout, "\n");
86
87err_free:
88 nftnl_rule_free(t);
89err:
90 return MNL_CB_OK;
91}
92
93static int chain_cb(const struct nlmsghdr *nlh, int event, int type)
94{
95 struct nftnl_chain *t;
96
97 t = nftnl_chain_alloc();
98 if (t == NULL) {
99 perror("OOM");
100 goto err;
101 }
102
103 if (nftnl_chain_nlmsg_parse(nlh, t) < 0) {
104 perror("nftnl_chain_nlmsg_parse");
105 goto err_free;
106 }
107
108 nftnl_chain_fprintf(stdout, t, type, event2flag(event));
109 fprintf(stdout, "\n");
110
111err_free:
112 nftnl_chain_free(t);
113err:
114 return MNL_CB_OK;
115}
116
117static int set_cb(const struct nlmsghdr *nlh, int event, int type)
118{
119 struct nftnl_set *t;
120
121 t = nftnl_set_alloc();
122 if (t == NULL) {
123 perror("OOM");
124 goto err;
125 }
126
127 if (nftnl_set_nlmsg_parse(nlh, t) < 0) {
128 perror("nftnl_set_nlmsg_parse");
129 goto err_free;
130 }
131
132 nftnl_set_fprintf(stdout, t, type, event2flag(event));
133 fprintf(stdout, "\n");
134
135err_free:
136 nftnl_set_free(t);
137err:
138 return MNL_CB_OK;
139}
140
141static int setelem_cb(const struct nlmsghdr *nlh, int event, int type)
142{
143
144 struct nftnl_set *s;
145
146 s = nftnl_set_alloc();
147 if (s == NULL) {
148 perror("OOM");
149 goto err;
150 }
151
152 if (nftnl_set_elems_nlmsg_parse(nlh, s) < 0) {
153 perror("nftnl_set_nlmsg_parse");
154 goto err_free;
155 }
156
157 nftnl_set_fprintf(stdout, s, type, event2flag(event));
158 fprintf(stdout, "\n");
159
160err_free:
161 nftnl_set_free(s);
162err:
163 return MNL_CB_OK;
164}
165
166static int gen_cb(const struct nlmsghdr *nlh, int event, int type)
167{
168 struct nftnl_gen *gen;
169
170 gen = nftnl_gen_alloc();
171 if (gen == NULL) {
172 perror("OOM");
173 goto err;
174 }
175
176 if (nftnl_gen_nlmsg_parse(nlh, gen) < 0) {
177 perror("nftnl_gen_parse");
178 goto err_free;
179 }
180
181 nftnl_gen_fprintf(stdout, gen, type, event2flag(event));
182 fprintf(stdout, "\n");
183err_free:
184 nftnl_gen_free(gen);
185err:
186 return MNL_CB_OK;
187}
188
189static int events_cb(const struct nlmsghdr *nlh, void *data)
190{
191 int ret = MNL_CB_OK;
192 int event = NFNL_MSG_TYPE(nlh->nlmsg_type);
193 int type = *((int *)data);
194
195 switch(event) {
196 case NFT_MSG_NEWTABLE:
197 case NFT_MSG_DELTABLE:
198 ret = table_cb(nlh, event, type);
199 break;
200 case NFT_MSG_NEWCHAIN:
201 case NFT_MSG_DELCHAIN:
202 ret = chain_cb(nlh, event, type);
203 break;
204 case NFT_MSG_NEWRULE:
205 case NFT_MSG_DELRULE:
206 ret = rule_cb(nlh, event, type);
207 break;
208 case NFT_MSG_NEWSET:
209 case NFT_MSG_DELSET:
210 ret = set_cb(nlh, event, type);
211 break;
212 case NFT_MSG_NEWSETELEM:
213 case NFT_MSG_DELSETELEM:
214 ret = setelem_cb(nlh, event, type);
215 break;
216 case NFT_MSG_NEWGEN:
217 ret = gen_cb(nlh, event, type);
218 break;
219 }
220
221 return ret;
222}
223
224int main(int argc, char *argv[])
225{
226 struct mnl_socket *nl;
227 char buf[MNL_SOCKET_BUFFER_SIZE];
228 int ret, type;
229
230 switch (argc) {
231 case 1:
232 type = NFTNL_OUTPUT_DEFAULT;
233 break;
234 default:
235 fprintf(stderr, "%s\n", argv[0]);
236 return EXIT_FAILURE;
237 }
238
239 nl = mnl_socket_open(NETLINK_NETFILTER);
240 if (nl == NULL) {
241 perror("mnl_socket_open");
242 exit(EXIT_FAILURE);
243 }
244
245 if (mnl_socket_bind(nl, (1 << (NFNLGRP_NFTABLES-1)), MNL_SOCKET_AUTOPID) < 0) {
246 perror("mnl_socket_bind");
247 exit(EXIT_FAILURE);
248 }
249
250 ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
251 while (ret > 0) {
252 ret = mnl_cb_run(buf, ret, 0, 0, events_cb, &type);
253 if (ret <= 0)
254 break;
255 ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
256 }
257 if (ret == -1) {
258 perror("error");
259 exit(EXIT_FAILURE);
260 }
261 mnl_socket_close(nl);
262
263 return EXIT_SUCCESS;
264}