libnftnl  1.0.2
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/common.h>
26 
27 static uint32_t event2flag(uint32_t event)
28 {
29  switch (event) {
30  case NFT_MSG_NEWTABLE:
31  case NFT_MSG_NEWCHAIN:
32  case NFT_MSG_NEWRULE:
33  case NFT_MSG_NEWSET:
34  case NFT_MSG_NEWSETELEM:
35  return NFT_OF_EVENT_NEW;
36  case NFT_MSG_DELTABLE:
37  case NFT_MSG_DELCHAIN:
38  case NFT_MSG_DELRULE:
39  case NFT_MSG_DELSET:
40  case NFT_MSG_DELSETELEM:
41  return NFT_OF_EVENT_DEL;
42  }
43 
44  return 0;
45 }
46 
47 static int table_cb(const struct nlmsghdr *nlh, int event, int type)
48 {
49  struct nft_table *t;
50 
51  t = nft_table_alloc();
52  if (t == NULL) {
53  perror("OOM");
54  goto err;
55  }
56 
57  if (nft_table_nlmsg_parse(nlh, t) < 0) {
58  perror("nft_table_nlmsg_parse");
59  goto err_free;
60  }
61 
62  nft_table_fprintf(stdout, t, type, event2flag(event));
63  fprintf(stdout, "\n");
64 
65 err_free:
66  nft_table_free(t);
67 err:
68  return MNL_CB_OK;
69 }
70 
71 static int rule_cb(const struct nlmsghdr *nlh, int event, int type)
72 {
73  struct nft_rule *t;
74 
75  t = nft_rule_alloc();
76  if (t == NULL) {
77  perror("OOM");
78  goto err;
79  }
80 
81  if (nft_rule_nlmsg_parse(nlh, t) < 0) {
82  perror("nft_rule_nlmsg_parse");
83  goto err_free;
84  }
85 
86  nft_rule_fprintf(stdout, t, type, event2flag(event));
87  fprintf(stdout, "\n");
88 
89 err_free:
90  nft_rule_free(t);
91 err:
92  return MNL_CB_OK;
93 }
94 
95 static int chain_cb(const struct nlmsghdr *nlh, int event, int type)
96 {
97  struct nft_chain *t;
98 
99  t = nft_chain_alloc();
100  if (t == NULL) {
101  perror("OOM");
102  goto err;
103  }
104 
105  if (nft_chain_nlmsg_parse(nlh, t) < 0) {
106  perror("nft_chain_nlmsg_parse");
107  goto err_free;
108  }
109 
110  nft_chain_fprintf(stdout, t, type, event2flag(event));
111  fprintf(stdout, "\n");
112 
113 err_free:
114  nft_chain_free(t);
115 err:
116  return MNL_CB_OK;
117 }
118 
119 static int set_cb(const struct nlmsghdr *nlh, int event, int type)
120 {
121  struct nft_set *t;
122 
123  t = nft_set_alloc();
124  if (t == NULL) {
125  perror("OOM");
126  goto err;
127  }
128 
129  if (nft_set_nlmsg_parse(nlh, t) < 0) {
130  perror("nft_set_nlmsg_parse");
131  goto err_free;
132  }
133 
134  nft_set_fprintf(stdout, t, type, event2flag(event));
135  fprintf(stdout, "\n");
136 
137 err_free:
138  nft_set_free(t);
139 err:
140  return MNL_CB_OK;
141 }
142 
143 static int setelem_cb(const struct nlmsghdr *nlh, int event, int type)
144 {
145 
146  struct nft_set *s;
147 
148  s = nft_set_alloc();
149  if (s == NULL) {
150  perror("OOM");
151  goto err;
152  }
153 
154  if (nft_set_elems_nlmsg_parse(nlh, s) < 0) {
155  perror("nft_set_nlmsg_parse");
156  goto err_free;
157  }
158 
159  nft_set_fprintf(stdout, s, type, event2flag(event));
160  fprintf(stdout, "\n");
161 
162 err_free:
163  nft_set_free(s);
164 err:
165  return MNL_CB_OK;
166 }
167 
168 static int events_cb(const struct nlmsghdr *nlh, void *data)
169 {
170  int ret = MNL_CB_OK;
171  int event = NFNL_MSG_TYPE(nlh->nlmsg_type);
172  int type = *((int *)data);
173 
174  switch(event) {
175  case NFT_MSG_NEWTABLE:
176  case NFT_MSG_DELTABLE:
177  ret = table_cb(nlh, event, type);
178  break;
179  case NFT_MSG_NEWCHAIN:
180  case NFT_MSG_DELCHAIN:
181  ret = chain_cb(nlh, event, type);
182  break;
183  case NFT_MSG_NEWRULE:
184  case NFT_MSG_DELRULE:
185  ret = rule_cb(nlh, event, type);
186  break;
187  case NFT_MSG_NEWSET:
188  case NFT_MSG_DELSET:
189  ret = set_cb(nlh, event, type);
190  break;
191  case NFT_MSG_NEWSETELEM:
192  case NFT_MSG_DELSETELEM:
193  ret = setelem_cb(nlh, event, type);
194  break;
195  }
196 
197  return ret;
198 }
199 
200 int main(int argc, char *argv[])
201 {
202  struct mnl_socket *nl;
203  char buf[MNL_SOCKET_BUFFER_SIZE];
204  int ret, type;
205 
206  switch (argc) {
207  case 1:
208  type = NFT_OUTPUT_DEFAULT;
209  break;
210  case 2:
211  if (strcmp(argv[1], "xml") == 0) {
212  type = NFT_OUTPUT_XML;
213  } else if (strcmp(argv[1], "json") == 0) {
214  type = NFT_OUTPUT_JSON;
215  } else if (strcmp(argv[1], "default") == 0) {
216  type = NFT_OUTPUT_DEFAULT;
217  } else {
218  fprintf(stderr, "unknown format type `%s'\n", argv[1]);
219  return EXIT_FAILURE;
220  }
221  break;
222  default:
223  fprintf(stderr, "%s [<default|xml|json>]\n", argv[0]);
224  return EXIT_FAILURE;
225  }
226 
227  nl = mnl_socket_open(NETLINK_NETFILTER);
228  if (nl == NULL) {
229  perror("mnl_socket_open");
230  exit(EXIT_FAILURE);
231  }
232 
233  if (mnl_socket_bind(nl, (1 << (NFNLGRP_NFTABLES-1)), MNL_SOCKET_AUTOPID) < 0) {
234  perror("mnl_socket_bind");
235  exit(EXIT_FAILURE);
236  }
237 
238  ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
239  while (ret > 0) {
240  ret = mnl_cb_run(buf, ret, 0, 0, events_cb, &type);
241  if (ret <= 0)
242  break;
243  ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
244  }
245  if (ret == -1) {
246  perror("error");
247  exit(EXIT_FAILURE);
248  }
249  mnl_socket_close(nl);
250 
251  return EXIT_SUCCESS;
252 }
Definition: rule.c:34