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 /* Function which prints out usage message. */
23 static void help(void)
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",
29 IPTABLES_VERSION, opts[0].name, opts[1].name);
32 /* Initialize the target. */
34 init(struct xt_entry_target *t)
36 struct ipt_acc_info *accountinfo = (struct ipt_acc_info *)t->data;
38 accountinfo->table_nr = -1;
41 #define IPT_ACCOUNT_OPT_ADDR 0x01
42 #define IPT_ACCOUNT_OPT_TABLE 0x02
44 /* Function which parses command options; returns true if it
47 static int parse(int c, char **argv, int invert, unsigned int *flags,
48 const void *entry, struct xt_entry_target **target)
50 struct ipt_acc_info *accountinfo = (struct ipt_acc_info *)(*target)->data;
51 struct in_addr *addrs = NULL, mask;
52 unsigned int naddrs = 0;
56 if (*flags & IPT_ACCOUNT_OPT_ADDR)
57 exit_error(PARAMETER_PROBLEM, "Can't specify --%s twice",
60 if (check_inverse(optarg, &invert, NULL, 0))
61 exit_error(PARAMETER_PROBLEM, "Unexpected `!' after --%s",
64 //loginfo->level = parse_level(optarg);
65 parse_hostnetworkmask(optarg, &addrs, &mask, &naddrs);
68 exit_error(PARAMETER_PROBLEM, "multiple IP addresses not allowed");
70 accountinfo->net_ip = addrs[0].s_addr;
71 accountinfo->net_mask = mask.s_addr;
73 *flags |= IPT_ACCOUNT_OPT_ADDR;
77 if (*flags & IPT_ACCOUNT_OPT_TABLE)
78 exit_error(PARAMETER_PROBLEM,
79 "Can't specify --%s twice", opts[1].name);
81 if (check_inverse(optarg, &invert, NULL, 0))
82 exit_error(PARAMETER_PROBLEM,
83 "Unexpected `!' after --%s", opts[1].name);
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);
90 strcpy(accountinfo->table_name, optarg);
91 *flags |= IPT_ACCOUNT_OPT_TABLE;
100 /* Final check; nothing. */
101 static void final_check(unsigned int flags)
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);
108 static void print_it(const void *ip,
109 const struct xt_entry_target *target, char do_prefix)
111 const struct ipt_acc_info *accountinfo
112 = (const struct ipt_acc_info *)target->data;
118 // Network information
121 printf("%s ", opts[0].name);
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));
132 printf("%s %s", opts[1].name, accountinfo->table_name);
137 print(const void *ip,
138 const struct xt_entry_target *target,
141 print_it (ip, target, 0);
144 /* Saves the union ipt_targinfo in parsable form to stdout. */
146 save(const void *ip, const struct xt_entry_target *target)
148 print_it(ip, target, 1);
152 struct iptables_target account
156 .version = IPTABLES_VERSION,
157 .size = IPT_ALIGN(sizeof(struct ipt_acc_info)),
158 .userspacesize = offsetof(struct ipt_acc_info, table_nr),
162 .final_check = &final_check,
170 register_target(&account);