iptables test program
[framework/connectivity/connman.git] / tools / iptables-test.c
1 /*
2  *  Connection Manager
3  *
4  *  Copyright (C) 2007-2010  Intel Corporation. All rights reserved.
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License version 2 as
8  *  published by the Free Software Foundation.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18  *
19  */
20
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <sys/errno.h>
26 #include <libiptc/libiptc.h>
27 #include <libiptc/libip6tc.h>
28 #include <xtables.h>
29
30 #include <linux/netfilter/x_tables.h>
31 #include <linux/netfilter/xt_quota.h>
32
33 static void print_match(const struct ipt_entry *e)
34 {
35         struct xt_entry_match *match;
36         struct xtables_match *xt_match;
37
38         match = (struct xt_entry_match *)e->elems;
39         if (match == NULL)
40                 return;
41
42         xt_match = xtables_find_match(match->u.user.name, XTF_TRY_LOAD, NULL);
43         if (xt_match == NULL)
44                 return;
45
46         printf("\tMATCH:%s\n", xt_match->m->u.user.name);
47 }
48
49 static void print_target(const struct ipt_entry *e)
50 {
51         struct xt_entry_target *target;
52         struct xtables_target *xt_target;
53
54         target = (void *)e + e->target_offset;
55         if (target == NULL)
56                 return;
57
58         xt_target = xtables_find_target(target->u.user.name, XTF_TRY_LOAD);
59         if (xt_target == NULL)
60                 return;
61
62         printf("\tTARGET: %s\n", xt_target->t->u.user.name);
63 }
64
65
66 static void print_rule(const struct ipt_entry *e, const char *chain)
67 {
68         /* print chain name */
69         printf("CHAIN %s:\n", chain);
70
71         print_match(e);
72         print_target(e);
73 }
74
75 static void print_tables(struct iptc_handle *h)
76 {
77         const char *chain;
78         const struct ipt_entry *rule;
79
80         chain = iptc_first_chain(h);
81
82         while(chain) {
83                 rule = iptc_first_rule(chain, h);
84                 while (rule) {
85                         print_rule(rule, chain);
86
87                         rule = iptc_next_rule(rule, h);
88                 }
89
90                 chain = iptc_next_chain(h);
91         }
92 }
93
94 static struct ipt_entry *build_quota_drop_entry(void)
95 {
96         struct ipt_entry *e;
97         size_t match_size, target_size;
98         struct xtables_target *t;
99         struct xtables_match *m;
100         struct xtables_rule_match *matches = NULL;
101
102         m = xtables_find_match("quota", XTF_LOAD_MUST_SUCCEED, &matches);
103         if (m == NULL)
104                 return NULL;
105
106         match_size = IPT_ALIGN(sizeof(struct ipt_entry_match)) + m->size;
107
108         m->m = xtables_calloc(1, match_size);
109         if (m->m == NULL)
110                 return NULL;
111         m->m->u.match_size = match_size;
112         strcpy(m->m->u.user.name, m->name);
113         xtables_set_revision(m->m->u.user.name, m->revision);
114         if (m->init != NULL)
115                 m->init(m->m);
116
117         t = xtables_find_target("DROP", XTF_TRY_LOAD);
118         if (t == NULL) {
119                 free(m->m);
120                 return NULL;
121         }
122
123         target_size = IPT_ALIGN(sizeof(struct ipt_entry_target)) + t->size;
124
125         t->t = xtables_calloc(1, target_size);
126         t->t->u.target_size = target_size;
127         strcpy(t->t->u.user.name, "DROP");
128         xtables_set_revision(t->t->u.user.name, t->revision);
129         if (t->init != NULL)
130                 t->init(t->t);
131
132         e = calloc(1, sizeof(struct ipt_entry) + match_size + target_size);
133         if (e == NULL) {
134                 free(m->m);
135                 free(t->t);
136         }
137
138         e->target_offset = sizeof(struct ipt_entry) + match_size;
139         e->next_offset = sizeof(struct ipt_entry) + match_size + target_size;
140
141         memcpy(e->elems, m->m, match_size);
142         memcpy(e->elems + match_size, t->t, target_size);
143
144         return e;
145 }
146
147 static int add_rule(const ipt_chainlabel chain, struct ipt_entry *e,
148                         struct iptc_handle *h)
149 {
150         if (!iptc_create_chain(chain, h)) {
151                 printf("Chain creation error (%s)\n", iptc_strerror(errno));
152                 return -1;
153         }
154
155         if (!iptc_insert_entry(chain, e, 0, h)) {
156                 printf("Entry insertion error (%s)\n", iptc_strerror(errno));
157                 return -1;
158         }
159
160         if (!iptc_commit(h)) {
161                 printf("Commit error (%s)\n", iptc_strerror(errno));
162                 return -1;
163         }
164
165         return 0;
166 }
167
168 static void remove_rule(const ipt_chainlabel chain, struct iptc_handle *h)
169 {
170         iptc_flush_entries(chain, h);
171         iptc_delete_chain(chain, h);
172         iptc_commit(h);
173 }
174
175
176 int main(int argc, char *argv[])
177 {
178         struct iptc_handle *h;
179         struct ipt_entry *e;
180
181         if (argc < 2) {
182                 printf("Usage: iptables-test [chain-name]\n");
183                 return -1;
184         }
185
186         h = iptc_init("filter");
187         if (!h) {
188                 printf("libiptc initialization error (%s)\n",
189                         iptc_strerror(errno));
190                 exit(errno);
191         }
192
193         xtables_init();
194         xtables_set_nfproto(NFPROTO_IPV4);
195
196         e = build_quota_drop_entry();
197         if (e == NULL)
198                 return -1;
199
200         add_rule(argv[1], e, h);
201
202         print_tables(h);
203
204         remove_rule(argv[1], h);
205
206         return 0;
207 }