1 /* Shared library add-on to iptables to add ACCOUNT(ing) support.
2 Author: Intra2net AG <opensource@intra2net.com>
12 #include <linux/netfilter_ipv4/ip_tables.h>
13 #include <linux/netfilter_ipv4/ipt_ACCOUNT.h>
15 static struct option opts[] = {
16 { .name = "addr", .has_arg = 1, .flag = 0, .val = 'a' },
17 { .name = "tname", .has_arg = 1, .flag = 0, .val = 't' },
21 /* Function which prints out usage message. */
22 static void help(void)
25 "ACCOUNT v%s options:\n"
26 " --%s ip/netmask\t\tBase network IP and netmask used for this table\n"
27 " --%s name\t\t\tTable name for the userspace library\n",
28 IPTABLES_VERSION, opts[0].name, opts[1].name);
31 /* Initialize the target. */
33 init(struct ipt_entry_target *t, unsigned int *nfcache)
35 struct ipt_acc_info *accountinfo = (struct ipt_acc_info *)t->data;
37 accountinfo->table_nr = -1;
39 /* Can't cache this */
40 *nfcache |= NFC_UNKNOWN;
43 #define IPT_ACCOUNT_OPT_ADDR 0x01
44 #define IPT_ACCOUNT_OPT_TABLE 0x02
46 /* Function which parses command options; returns true if it
49 parse(int c, char **argv, int invert, unsigned int *flags,
50 const struct ipt_entry *entry,
51 struct ipt_entry_target **target)
53 struct ipt_acc_info *accountinfo = (struct ipt_acc_info *)(*target)->data;
54 struct in_addr *addrs = NULL, mask;
55 unsigned int naddrs = 0;
59 if (*flags & IPT_ACCOUNT_OPT_ADDR)
60 exit_error(PARAMETER_PROBLEM, "Can't specify --%s twice",
63 if (check_inverse(optarg, &invert, NULL, 0))
64 exit_error(PARAMETER_PROBLEM, "Unexpected `!' after --%s",
67 //loginfo->level = parse_level(optarg);
68 parse_hostnetworkmask(optarg, &addrs, &mask, &naddrs);
71 exit_error(PARAMETER_PROBLEM, "multiple IP addresses not allowed");
73 accountinfo->net_ip = addrs[0].s_addr;
74 accountinfo->net_mask = mask.s_addr;
76 *flags |= IPT_ACCOUNT_OPT_ADDR;
80 if (*flags & IPT_ACCOUNT_OPT_TABLE)
81 exit_error(PARAMETER_PROBLEM,
82 "Can't specify --%s twice", opts[1].name);
84 if (check_inverse(optarg, &invert, NULL, 0))
85 exit_error(PARAMETER_PROBLEM,
86 "Unexpected `!' after --%s", opts[1].name);
88 if (strlen(optarg) > ACCOUNT_TABLE_NAME_LEN - 1)
89 exit_error(PARAMETER_PROBLEM,
90 "Maximum table name length %u for --%s",
91 ACCOUNT_TABLE_NAME_LEN - 1, opts[1].name);
93 strcpy(accountinfo->table_name, optarg);
94 *flags |= IPT_ACCOUNT_OPT_TABLE;
103 /* Final check; nothing. */
104 static void final_check(unsigned int flags)
106 if (!(flags&IPT_ACCOUNT_OPT_ADDR) || !(flags&IPT_ACCOUNT_OPT_TABLE))
107 exit_error(PARAMETER_PROBLEM, "ACCOUNT: needs --%s and --%s",
108 opts[0].name, opts[1].name);
111 static void print_it(const struct ipt_ip *ip,
112 const struct ipt_entry_target *target, char do_prefix)
114 const struct ipt_acc_info *accountinfo
115 = (const struct ipt_acc_info *)target->data;
121 // Network information
124 printf("%s ", opts[0].name);
126 a.s_addr = accountinfo->net_ip;
127 printf("%s", addr_to_dotted(&a));
128 a.s_addr = accountinfo->net_mask;
129 printf("%s", mask_to_dotted(&a));
135 printf("%s %s", opts[1].name, accountinfo->table_name);
138 /* Prints out the targinfo. */
140 print(const struct ipt_ip *ip,
141 const struct ipt_entry_target *target,
144 print_it (ip, target, 0);
147 /* Saves the union ipt_targinfo in parsable form to stdout. */
149 save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
151 print_it(ip, target, 1);
155 struct iptables_target account
159 .version = IPTABLES_VERSION,
160 .size = IPT_ALIGN(sizeof(struct ipt_acc_info)),
161 .userspacesize = IPT_ALIGN(sizeof(struct ipt_acc_info)),
165 .final_check = &final_check,
173 register_target(&account);