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