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 
24 static 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 
45 static 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 
63 err_free:
64  nftnl_table_free(t);
65 err:
66  return MNL_CB_OK;
67 }
68 
69 static 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 
87 err_free:
88  nftnl_rule_free(t);
89 err:
90  return MNL_CB_OK;
91 }
92 
93 static 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 
111 err_free:
112  nftnl_chain_free(t);
113 err:
114  return MNL_CB_OK;
115 }
116 
117 static 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 
135 err_free:
136  nftnl_set_free(t);
137 err:
138  return MNL_CB_OK;
139 }
140 
141 static 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 
160 err_free:
161  nftnl_set_free(s);
162 err:
163  return MNL_CB_OK;
164 }
165 
166 static 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");
183 err_free:
184  nftnl_gen_free(gen);
185 err:
186  return MNL_CB_OK;
187 }
188 
189 static 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 
224 int 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 }
Definition: gen.c:22