Use libiptc to clear current ruleset
[project/firewall3.git] / iptables.c
1 /*
2  * firewall3 - 3rd OpenWrt UCI firewall implementation
3  *
4  *   Copyright (C) 2013 Jo-Philipp Wich <jow@openwrt.org>
5  *
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18
19 #include "iptables.h"
20
21
22 struct fw3_ipt_handle *
23 fw3_ipt_open(enum fw3_family family, enum fw3_table table)
24 {
25         struct fw3_ipt_handle *h;
26
27         h = malloc(sizeof(*h));
28
29         if (!h)
30                 return NULL;
31
32         if (family == FW3_FAMILY_V6)
33         {
34                 h->family = FW3_FAMILY_V6;
35                 h->table  = table;
36                 h->handle = ip6tc_init(fw3_flag_names[table]);
37         }
38         else
39         {
40                 h->family = FW3_FAMILY_V4;
41                 h->table  = table;
42                 h->handle = iptc_init(fw3_flag_names[table]);
43         }
44
45         if (!h->handle)
46         {
47                 free(h);
48                 return NULL;
49         }
50
51         return h;
52 }
53
54 void fw3_ipt_set_policy(struct fw3_ipt_handle *h, enum fw3_flag policy)
55 {
56         if (h->table != FW3_TABLE_FILTER)
57                 return;
58
59         if (h->family == FW3_FAMILY_V6)
60         {
61                 ip6tc_set_policy("INPUT", fw3_flag_names[policy], NULL, h->handle);
62                 ip6tc_set_policy("OUTPUT", fw3_flag_names[policy], NULL, h->handle);
63                 ip6tc_set_policy("FORWARD", fw3_flag_names[policy], NULL, h->handle);
64         }
65         else
66         {
67                 iptc_set_policy("INPUT", fw3_flag_names[policy], NULL, h->handle);
68                 iptc_set_policy("OUTPUT", fw3_flag_names[policy], NULL, h->handle);
69                 iptc_set_policy("FORWARD", fw3_flag_names[policy], NULL, h->handle);
70         }
71 }
72
73 void fw3_ipt_delete_chain(struct fw3_ipt_handle *h, const char *chain)
74 {
75         if (h->family == FW3_FAMILY_V6)
76         {
77                 if (ip6tc_flush_entries(chain, h->handle))
78                         ip6tc_delete_chain(chain, h->handle);
79         }
80         else
81         {
82                 if (iptc_flush_entries(chain, h->handle))
83                         iptc_delete_chain(chain, h->handle);
84         }
85 }
86
87 void fw3_ipt_delete_rules(struct fw3_ipt_handle *h, const char *target)
88 {
89         unsigned int num;
90         const struct ipt_entry *e;
91         const struct ip6t_entry *e6;
92         const char *chain;
93         const char *t;
94         bool found;
95
96         if (h->family == FW3_FAMILY_V6)
97         {
98                 for (chain = ip6tc_first_chain(h->handle);
99                      chain != NULL;
100                      chain = ip6tc_next_chain(h->handle))
101                 {
102                         do {
103                                 found = false;
104
105                                 for (num = 0, e6 = ip6tc_first_rule(chain, h->handle);
106                                          e6 != NULL;
107                                          num++, e6 = ip6tc_next_rule(e6, h->handle))
108                                 {
109                                         t = ip6tc_get_target(e6, h->handle);
110
111                                         if (*t && !strcmp(t, target))
112                                         {
113                                                 ip6tc_delete_num_entry(chain, num, h->handle);
114                                                 found = true;
115                                                 break;
116                                         }
117                                 }
118                         } while (found);
119                 }
120         }
121         else
122         {
123                 for (chain = iptc_first_chain(h->handle);
124                      chain != NULL;
125                      chain = iptc_next_chain(h->handle))
126                 {
127                         do {
128                                 found = false;
129
130                                 for (num = 0, e = iptc_first_rule(chain, h->handle);
131                                      e != NULL;
132                                          num++, e = iptc_next_rule(e, h->handle))
133                                 {
134                                         t = iptc_get_target(e, h->handle);
135
136                                         if (*t && !strcmp(t, target))
137                                         {
138                                                 iptc_delete_num_entry(chain, num, h->handle);
139                                                 found = true;
140                                                 break;
141                                         }
142                                 }
143                         } while (found);
144                 }
145         }
146 }
147
148 void fw3_ipt_flush(struct fw3_ipt_handle *h)
149 {
150         const char *chain;
151
152         if (h->family == FW3_FAMILY_V6)
153         {
154                 for (chain = ip6tc_first_chain(h->handle);
155                      chain != NULL;
156                      chain = ip6tc_next_chain(h->handle))
157                 {
158                         ip6tc_flush_entries(chain, h->handle);
159                 }
160
161                 for (chain = ip6tc_first_chain(h->handle);
162                      chain != NULL;
163                      chain = ip6tc_next_chain(h->handle))
164                 {
165                         ip6tc_delete_chain(chain, h->handle);
166                 }
167         }
168         else
169         {
170                 for (chain = iptc_first_chain(h->handle);
171                      chain != NULL;
172                      chain = iptc_next_chain(h->handle))
173                 {
174                         iptc_flush_entries(chain, h->handle);
175                 }
176
177                 for (chain = iptc_first_chain(h->handle);
178                      chain != NULL;
179                      chain = iptc_next_chain(h->handle))
180                 {
181                         iptc_delete_chain(chain, h->handle);
182                 }
183         }
184 }
185
186 void fw3_ipt_commit(struct fw3_ipt_handle *h)
187 {
188         if (h->family == FW3_FAMILY_V6)
189                 ip6tc_commit(h->handle);
190         else
191                 iptc_commit(h->handle);
192
193         free(h);
194 }