1 /* Shared library add-on to iptables to add ACCOUNT(ing) support.
2 Author: Intra2net AG <opensource@intra2net.com>
13 #include <linux/netfilter_ipv4/ip_tables.h>
14 #include <linux/netfilter_ipv4/ipt_ACCOUNT.h>
16 static struct option opts[] = {
17 { .name = "addr", .has_arg = 1, .flag = 0, .val = 'a' },
18 { .name = "tname", .has_arg = 1, .flag = 0, .val = 't' },
22 /* Compat glue for iptables 1.4.0 */
23 #ifndef XTABLES_VERSION
24 #define XTABLES_VERSION IPTABLES_VERSION
27 /* Function which prints out usage message. */
28 static void help(void)
31 "ACCOUNT v%s options:\n"
32 " --%s ip/netmask\t\tBase network IP and netmask used for this table\n"
33 " --%s name\t\t\tTable name for the userspace library\n",
34 XTABLES_VERSION, opts[0].name, opts[1].name);
37 /* Initialize the target. */
39 init(struct xt_entry_target *t)
41 struct ipt_acc_info *accountinfo = (struct ipt_acc_info *)t->data;
43 accountinfo->table_nr = -1;
46 #define IPT_ACCOUNT_OPT_ADDR 0x01
47 #define IPT_ACCOUNT_OPT_TABLE 0x02
49 /* Function which parses command options; returns true if it
52 static int parse(int c, char **argv, int invert, unsigned int *flags,
53 const void *entry, struct xt_entry_target **target)
55 struct ipt_acc_info *accountinfo = (struct ipt_acc_info *)(*target)->data;
56 struct in_addr *addrs = NULL, mask;
57 unsigned int naddrs = 0;
61 if (*flags & IPT_ACCOUNT_OPT_ADDR)
62 exit_error(PARAMETER_PROBLEM, "Can't specify --%s twice",
65 if (check_inverse(optarg, &invert, NULL, 0))
66 exit_error(PARAMETER_PROBLEM, "Unexpected `!' after --%s",
69 #ifdef XTABLES_VERSION_CODE
70 ipparse_hostnetworkmask(optarg, &addrs, &mask, &naddrs);
72 parse_hostnetworkmask(optarg, &addrs, &mask, &naddrs);
76 exit_error(PARAMETER_PROBLEM, "multiple IP addresses not allowed");
78 accountinfo->net_ip = addrs[0].s_addr;
79 accountinfo->net_mask = mask.s_addr;
81 *flags |= IPT_ACCOUNT_OPT_ADDR;
85 if (*flags & IPT_ACCOUNT_OPT_TABLE)
86 exit_error(PARAMETER_PROBLEM,
87 "Can't specify --%s twice", opts[1].name);
89 if (check_inverse(optarg, &invert, NULL, 0))
90 exit_error(PARAMETER_PROBLEM,
91 "Unexpected `!' after --%s", opts[1].name);
93 if (strlen(optarg) > ACCOUNT_TABLE_NAME_LEN - 1)
94 exit_error(PARAMETER_PROBLEM,
95 "Maximum table name length %u for --%s",
96 ACCOUNT_TABLE_NAME_LEN - 1, opts[1].name);
98 strcpy(accountinfo->table_name, optarg);
99 *flags |= IPT_ACCOUNT_OPT_TABLE;
108 /* Final check; nothing. */
109 static void final_check(unsigned int flags)
111 if (!(flags&IPT_ACCOUNT_OPT_ADDR) || !(flags&IPT_ACCOUNT_OPT_TABLE))
112 exit_error(PARAMETER_PROBLEM, "ACCOUNT: needs --%s and --%s",
113 opts[0].name, opts[1].name);
116 static const char *print_helper_ip(struct in_addr a)
118 #ifdef XTABLES_VERSION_CODE
119 return ipaddr_to_numeric(&a);
121 return addr_to_dotted(&a);
125 static const char *print_helper_mask(struct in_addr a)
127 #ifdef XTABLES_VERSION_CODE
128 return ipmask_to_numeric(&a);
130 return mask_to_dotted(&a);
134 static void print_it(const void *ip,
135 const struct xt_entry_target *target, char do_prefix)
137 const struct ipt_acc_info *accountinfo
138 = (const struct ipt_acc_info *)target->data;
144 // Network information
147 printf("%s ", opts[0].name);
149 a.s_addr = accountinfo->net_ip;
150 printf("%s", print_helper_ip(a));
151 a.s_addr = accountinfo->net_mask;
152 printf("%s", print_helper_mask(a));
158 printf("%s %s", opts[1].name, accountinfo->table_name);
163 print(const void *ip,
164 const struct xt_entry_target *target,
167 print_it (ip, target, 0);
170 /* Saves the union ipt_targinfo in parsable form to stdout. */
172 save(const void *ip, const struct xt_entry_target *target)
174 print_it(ip, target, 1);
178 struct xtables_target account
183 .version = XTABLES_VERSION,
184 .size = IPT_ALIGN(sizeof(struct ipt_acc_info)),
185 .userspacesize = offsetof(struct ipt_acc_info, table_nr),
189 .final_check = &final_check,
197 xtables_register_target(&account);