Home | History | Annotate | Download | only in extensions
      1 /*
      2  * Shared library add-on to iptables to add quota support
      3  *
      4  * Sam Johnston <samj (at) samj.net>
      5  */
      6 #include <stddef.h>
      7 #include <stdio.h>
      8 #include <stdlib.h>
      9 #include <getopt.h>
     10 #include <iptables.h>
     11 
     12 #include <linux/netfilter/xt_quota.h>
     13 #include <linux/netfilter_ipv4/ip_tables.h>
     14 
     15 static struct option opts[] = {
     16         {"quota", 1, 0, '1'},
     17         {0}
     18 };
     19 
     20 /* print usage */
     21 static void
     22 help(void)
     23 {
     24         printf("quota options:\n"
     25                " --quota quota			quota (bytes)\n" "\n");
     26 }
     27 
     28 /* print matchinfo */
     29 static void
     30 print(const struct ipt_ip *ip, const struct ipt_entry_match *match, int numeric)
     31 {
     32         struct xt_quota_info *q = (struct xt_quota_info *) match->data;
     33         printf("quota: %llu bytes", (unsigned long long) q->quota);
     34 }
     35 
     36 /* save matchinfo */
     37 static void
     38 save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
     39 {
     40         struct xt_quota_info *q = (struct xt_quota_info *) match->data;
     41         printf("--quota %llu ", (unsigned long long) q->quota);
     42 }
     43 
     44 /* parse quota option */
     45 static int
     46 parse_quota(const char *s, u_int64_t * quota)
     47 {
     48         *quota = strtoull(s, (char **) NULL, 10);
     49 
     50 #ifdef DEBUG_IPT_QUOTA
     51         printf("Quota: %llu\n", *quota);
     52 #endif
     53 
     54         if (*quota == -1)
     55                 exit_error(PARAMETER_PROBLEM, "quota invalid: '%s'\n", s);
     56         else
     57                 return 1;
     58 }
     59 
     60 /* parse all options, returning true if we found any for us */
     61 static int
     62 parse(int c, char **argv, int invert, unsigned int *flags,
     63       const struct ipt_entry *entry,
     64       unsigned int *nfcache, struct ipt_entry_match **match)
     65 {
     66         struct xt_quota_info *info = (struct xt_quota_info *) (*match)->data;
     67 
     68         switch (c) {
     69         case '1':
     70                 if (check_inverse(optarg, &invert, NULL, 0))
     71                         exit_error(PARAMETER_PROBLEM, "quota: unexpected '!'");
     72                 if (!parse_quota(optarg, &info->quota))
     73                         exit_error(PARAMETER_PROBLEM,
     74                                    "bad quota: '%s'", optarg);
     75                 break;
     76 
     77         default:
     78                 return 0;
     79         }
     80         return 1;
     81 }
     82 
     83 /* no final check */
     84 static void
     85 final_check(unsigned int flags)
     86 {
     87 }
     88 
     89 struct iptables_match quota = {
     90 	.next		= NULL,
     91 	.name		= "quota",
     92 	.version	= IPTABLES_VERSION,
     93 	.size		= IPT_ALIGN(sizeof (struct xt_quota_info)),
     94 	.userspacesize	= offsetof(struct xt_quota_info, quota),
     95 	.help		= &help,
     96 	.parse		= &parse,
     97 	.final_check	= &final_check,
     98 	.print		= &print,
     99 	.save		= &save,
    100 	.extra_opts	= opts
    101 };
    102 
    103 void
    104 ipt_quota_init(void)
    105 {
    106         register_match(&quota);
    107 }
    108