ipt_ACCOUNT, iptables: (tomj) fix delete handling (#1379)
[ipt_ACCOUNT] / iptables / extensions / libipt_ACCOUNT.c
CommitLineData
146aa677
TJ
1/* Shared library add-on to iptables to add ACCOUNT(ing) support.
2 Author: Intra2net AG <opensource@intra2net.com>
3*/
4
5#include <stdio.h>
6#include <netdb.h>
7#include <string.h>
8#include <stdlib.h>
9#include <syslog.h>
10#include <getopt.h>
e8bd93ad 11#include <stddef.h>
146aa677
TJ
12#include <iptables.h>
13#include <linux/netfilter_ipv4/ip_tables.h>
14#include <linux/netfilter_ipv4/ipt_ACCOUNT.h>
15
16static struct option opts[] = {
17 { .name = "addr", .has_arg = 1, .flag = 0, .val = 'a' },
18 { .name = "tname", .has_arg = 1, .flag = 0, .val = 't' },
19 { .name = 0 }
20};
21
22/* Function which prints out usage message. */
23static void help(void)
24{
25 printf(
26"ACCOUNT v%s options:\n"
27" --%s ip/netmask\t\tBase network IP and netmask used for this table\n"
28" --%s name\t\t\tTable name for the userspace library\n",
29IPTABLES_VERSION, opts[0].name, opts[1].name);
30}
31
32/* Initialize the target. */
33static void
f05fa82a 34init(struct xt_entry_target *t)
146aa677
TJ
35{
36 struct ipt_acc_info *accountinfo = (struct ipt_acc_info *)t->data;
37
38 accountinfo->table_nr = -1;
146aa677
TJ
39}
40
41#define IPT_ACCOUNT_OPT_ADDR 0x01
42#define IPT_ACCOUNT_OPT_TABLE 0x02
43
44/* Function which parses command options; returns true if it
45 ate an option */
f05fa82a
TJ
46
47static int parse(int c, char **argv, int invert, unsigned int *flags,
48 const void *entry, struct xt_entry_target **target)
146aa677
TJ
49{
50 struct ipt_acc_info *accountinfo = (struct ipt_acc_info *)(*target)->data;
51 struct in_addr *addrs = NULL, mask;
52 unsigned int naddrs = 0;
53
54 switch (c) {
55 case 'a':
56 if (*flags & IPT_ACCOUNT_OPT_ADDR)
57 exit_error(PARAMETER_PROBLEM, "Can't specify --%s twice",
58 opts[0].name);
59
60 if (check_inverse(optarg, &invert, NULL, 0))
61 exit_error(PARAMETER_PROBLEM, "Unexpected `!' after --%s",
62 opts[0].name);
63
64 //loginfo->level = parse_level(optarg);
65 parse_hostnetworkmask(optarg, &addrs, &mask, &naddrs);
f05fa82a 66
146aa677
TJ
67 if (naddrs > 1)
68 exit_error(PARAMETER_PROBLEM, "multiple IP addresses not allowed");
f05fa82a 69
146aa677
TJ
70 accountinfo->net_ip = addrs[0].s_addr;
71 accountinfo->net_mask = mask.s_addr;
f05fa82a 72
146aa677
TJ
73 *flags |= IPT_ACCOUNT_OPT_ADDR;
74 break;
75
76 case 't':
77 if (*flags & IPT_ACCOUNT_OPT_TABLE)
78 exit_error(PARAMETER_PROBLEM,
79 "Can't specify --%s twice", opts[1].name);
80
81 if (check_inverse(optarg, &invert, NULL, 0))
82 exit_error(PARAMETER_PROBLEM,
83 "Unexpected `!' after --%s", opts[1].name);
84
85 if (strlen(optarg) > ACCOUNT_TABLE_NAME_LEN - 1)
86 exit_error(PARAMETER_PROBLEM,
87 "Maximum table name length %u for --%s",
88 ACCOUNT_TABLE_NAME_LEN - 1, opts[1].name);
89
90 strcpy(accountinfo->table_name, optarg);
91 *flags |= IPT_ACCOUNT_OPT_TABLE;
92 break;
f05fa82a 93
146aa677
TJ
94 default:
95 return 0;
96 }
97 return 1;
98}
99
100/* Final check; nothing. */
101static void final_check(unsigned int flags)
102{
103 if (!(flags&IPT_ACCOUNT_OPT_ADDR) || !(flags&IPT_ACCOUNT_OPT_TABLE))
104 exit_error(PARAMETER_PROBLEM, "ACCOUNT: needs --%s and --%s",
105 opts[0].name, opts[1].name);
106}
107
f05fa82a
TJ
108static void print_it(const void *ip,
109 const struct xt_entry_target *target, char do_prefix)
146aa677
TJ
110{
111 const struct ipt_acc_info *accountinfo
112 = (const struct ipt_acc_info *)target->data;
113 struct in_addr a;
114
115 if (!do_prefix)
116 printf("ACCOUNT ");
f05fa82a 117
146aa677
TJ
118 // Network information
119 if (do_prefix)
f05fa82a 120 printf("--");
146aa677 121 printf("%s ", opts[0].name);
f05fa82a 122
146aa677
TJ
123 a.s_addr = accountinfo->net_ip;
124 printf("%s", addr_to_dotted(&a));
125 a.s_addr = accountinfo->net_mask;
126 printf("%s", mask_to_dotted(&a));
127
128 printf(" ");
129 if (do_prefix)
f05fa82a 130 printf("--");
146aa677
TJ
131
132 printf("%s %s", opts[1].name, accountinfo->table_name);
133}
134
f05fa82a 135
146aa677 136static void
f05fa82a
TJ
137print(const void *ip,
138 const struct xt_entry_target *target,
146aa677
TJ
139 int numeric)
140{
141 print_it (ip, target, 0);
142}
143
144/* Saves the union ipt_targinfo in parsable form to stdout. */
145static void
f05fa82a 146save(const void *ip, const struct xt_entry_target *target)
146aa677
TJ
147{
148 print_it(ip, target, 1);
149}
150
151static
152struct iptables_target account
153= {
154 .next = NULL,
155 .name = "ACCOUNT",
156 .version = IPTABLES_VERSION,
157 .size = IPT_ALIGN(sizeof(struct ipt_acc_info)),
e8bd93ad 158 .userspacesize = offsetof(struct ipt_acc_info, table_nr),
146aa677
TJ
159 .help = &help,
160 .init = &init,
161 .parse = &parse,
162 .final_check = &final_check,
163 .print = &print,
164 .save = &save,
165 .extra_opts = opts
166};
167
168void _init(void)
169{
170 register_target(&account);
171}