tizen 2.3.1 release
[external/iptables.git] / extensions / libxt_limit.c
index c836303..f75ef2f 100644 (file)
@@ -3,20 +3,24 @@
  * Jérôme de Vivie   <devivie@info.enserb.u-bordeaux.fr>
  * Hervé Eychenne    <rv@wallfire.org>
  */
-
+#define _BSD_SOURCE 1
+#define _ISOC99_SOURCE 1
+#include <math.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
-#include <getopt.h>
 #include <xtables.h>
-#include <stddef.h>
 #include <linux/netfilter/x_tables.h>
-/* For 64bit kernel / 32bit userspace */
 #include <linux/netfilter/xt_limit.h>
 
 #define XT_LIMIT_AVG   "3/hour"
 #define XT_LIMIT_BURST 5
 
+enum {
+       O_LIMIT = 0,
+       O_BURST,
+};
+
 static void limit_help(void)
 {
        printf(
@@ -28,18 +32,20 @@ static void limit_help(void)
 XT_LIMIT_BURST);
 }
 
-static const struct option limit_opts[] = {
-       { "limit", 1, NULL, '%' },
-       { "limit-burst", 1, NULL, '$' },
-       { .name = NULL }
+static const struct xt_option_entry limit_opts[] = {
+       {.name = "limit", .id = O_LIMIT, .type = XTTYPE_STRING},
+       {.name = "limit-burst", .id = O_BURST, .type = XTTYPE_UINT32,
+        .flags = XTOPT_PUT, XTOPT_POINTER(struct xt_rateinfo, burst),
+        .min = 0, .max = 10000},
+       XTOPT_TABLEEND,
 };
 
 static
-int parse_rate(const char *rate, u_int32_t *val)
+int parse_rate(const char *rate, uint32_t *val)
 {
        const char *delim;
-       u_int32_t r;
-       u_int32_t mult = 1;  /* Seconds by default. */
+       uint32_t r;
+       uint32_t mult = 1;  /* Seconds by default. */
 
        delim = strchr(rate, '/');
        if (delim) {
@@ -61,12 +67,13 @@ int parse_rate(const char *rate, u_int32_t *val)
        if (!r)
                return 0;
 
-       /* This would get mapped to infinite (1/day is minimum they
-           can specify, so we're ok at that end). */
-       if (r / mult > XT_LIMIT_SCALE)
-               xtables_error(PARAMETER_PROBLEM, "Rate too fast \"%s\"\n", rate);
-
        *val = XT_LIMIT_SCALE * mult / r;
+       if (*val == 0)
+               /*
+                * The rate maps to infinity. (1/day is the minimum they can
+                * specify, so we are ok at that end).
+                */
+               xtables_error(PARAMETER_PROBLEM, "Rate too fast \"%s\"\n", rate);
        return 1;
 }
 
@@ -85,76 +92,64 @@ static void limit_init(struct xt_entry_match *m)
                           "Sorry: burst too large for that avg rate.\n");
 */
 
-static int
-limit_parse(int c, char **argv, int invert, unsigned int *flags,
-            const void *entry, struct xt_entry_match **match)
+static void limit_parse(struct xt_option_call *cb)
 {
-       struct xt_rateinfo *r = (struct xt_rateinfo *)(*match)->data;
-       unsigned int num;
-
-       switch(c) {
-       case '%':
-               if (xtables_check_inverse(optarg, &invert, &optind, 0, argv)) break;
-               if (!parse_rate(optarg, &r->avg))
-                       xtables_error(PARAMETER_PROBLEM,
-                                  "bad rate `%s'", optarg);
-               break;
+       struct xt_rateinfo *r = cb->data;
 
-       case '$':
-               if (xtables_check_inverse(optarg, &invert, &optind, 0, argv)) break;
-               if (!xtables_strtoui(optarg, NULL, &num, 0, 10000))
+       xtables_option_parse(cb);
+       switch (cb->entry->id) {
+       case O_LIMIT:
+               if (!parse_rate(cb->arg, &r->avg))
                        xtables_error(PARAMETER_PROBLEM,
-                                  "bad --limit-burst `%s'", optarg);
-               r->burst = num;
+                                  "bad rate \"%s\"'", cb->arg);
                break;
-
-       default:
-               return 0;
        }
-
-       if (invert)
+       if (cb->invert)
                xtables_error(PARAMETER_PROBLEM,
                           "limit does not support invert");
-
-       return 1;
 }
 
 static const struct rates
 {
        const char *name;
-       u_int32_t mult;
+       uint32_t mult;
 } rates[] = { { "day", XT_LIMIT_SCALE*24*60*60 },
              { "hour", XT_LIMIT_SCALE*60*60 },
              { "min", XT_LIMIT_SCALE*60 },
              { "sec", XT_LIMIT_SCALE } };
 
-static void print_rate(u_int32_t period)
+static void print_rate(uint32_t period)
 {
        unsigned int i;
 
+       if (period == 0) {
+               printf(" %f", INFINITY);
+               return;
+       }
+
        for (i = 1; i < ARRAY_SIZE(rates); ++i)
                if (period > rates[i].mult
             || rates[i].mult/period < rates[i].mult%period)
                        break;
 
-       printf("%u/%s ", rates[i-1].mult / period, rates[i-1].name);
+       printf(" %u/%s", rates[i-1].mult / period, rates[i-1].name);
 }
 
 static void
 limit_print(const void *ip, const struct xt_entry_match *match, int numeric)
 {
        const struct xt_rateinfo *r = (const void *)match->data;
-       printf("limit: avg "); print_rate(r->avg);
-       printf("burst %u ", r->burst);
+       printf(" limit: avg"); print_rate(r->avg);
+       printf(" burst %u", r->burst);
 }
 
 static void limit_save(const void *ip, const struct xt_entry_match *match)
 {
        const struct xt_rateinfo *r = (const void *)match->data;
 
-       printf("--limit "); print_rate(r->avg);
+       printf(" --limit"); print_rate(r->avg);
        if (r->burst != XT_LIMIT_BURST)
-               printf("--limit-burst %u ", r->burst);
+               printf(" --limit-burst %u", r->burst);
 }
 
 static struct xtables_match limit_match = {
@@ -165,10 +160,10 @@ static struct xtables_match limit_match = {
        .userspacesize  = offsetof(struct xt_rateinfo, prev),
        .help           = limit_help,
        .init           = limit_init,
-       .parse          = limit_parse,
+       .x6_parse       = limit_parse,
        .print          = limit_print,
        .save           = limit_save,
-       .extra_opts     = limit_opts,
+       .x6_options     = limit_opts,
 };
 
 void _init(void)