iptables-1.2.9-2.3.1.src.rpm
[iptables.git] / extensions / libip6t_fuzzy.c
1 /*
2    Shared library add-on to iptables to add match support for the fuzzy match.
3
4    This file is distributed under the terms of the GNU General Public
5    License (GPL). Copies of the GPL can be obtained from:
6    ftp://prep.ai.mit.edu/pub/gnu/GPL
7
8 2002-08-07 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version.
9 2003-04-08 Maciej Soltysiak <solt@dns.toxicfilms.tv> : IPv6 Port
10 2003-06-09 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Bug corrections in
11 the save function , thanks to information given by Jean-Francois Patenaude.
12
13 */
14
15 #include <stdio.h>
16 #include <netdb.h>
17 #include <string.h>
18 #include <stdlib.h>
19 #include <syslog.h>
20 #include <getopt.h>
21 #include <ip6tables.h>
22 #include <linux/netfilter_ipv6/ip6_tables.h>
23 #include <linux/netfilter_ipv6/ip6t_fuzzy.h>
24
25
26 static void
27 help(void)
28 {
29         printf(
30 "fuzzy v%s options:\n"
31 "                      --lower-limit number (in packets per second)\n"
32 "                      --upper-limit number\n"
33 ,IPTABLES_VERSION);
34 };
35
36 static struct option opts[] = {
37         { .name = "lower-limit", .has_arg = 1, .flag = 0, .val = '1' },
38         { .name = "upper-limit", .has_arg = 1, .flag = 0, .val = '2' },
39         { .name = 0 }
40 };
41
42 /* Initialize data structures */
43 static void
44 init(struct ip6t_entry_match *m, unsigned int *nfcache)
45 {
46         struct ip6t_fuzzy_info *presentinfo = (struct ip6t_fuzzy_info *)(m)->data;
47         *nfcache |= NFC_UNKNOWN;
48
49         /*
50          * Default rates ( I'll improve this very soon with something based
51          * on real statistics of the running machine ) .
52         */
53
54         presentinfo->minimum_rate = 1000;
55         presentinfo->maximum_rate = 2000;
56 }
57
58 #define IP6T_FUZZY_OPT_MINIMUM  0x01
59 #define IP6T_FUZZY_OPT_MAXIMUM  0x02
60
61 static int
62 parse(int c, char **argv, int invert, unsigned int *flags,
63       const struct ip6t_entry *entry,
64       unsigned int *nfcache,
65       struct ip6t_entry_match **match)
66 {
67         struct ip6t_fuzzy_info *fuzzyinfo =
68                 (struct ip6t_fuzzy_info *)(*match)->data;
69
70         u_int32_t num;
71
72         switch (c) {
73
74         case '1':
75
76         if (invert)
77                 exit_error(PARAMETER_PROBLEM,"Can't specify ! --lower-limit");
78
79         if (*flags & IP6T_FUZZY_OPT_MINIMUM)
80               exit_error(PARAMETER_PROBLEM,"Can't specify --lower-limit twice");
81
82         if (string_to_number(optarg,1,MAXFUZZYRATE,&num) == -1 || num < 1)
83                         exit_error(PARAMETER_PROBLEM,"BAD --lower-limit");
84
85                 fuzzyinfo->minimum_rate = num ;
86
87                 *flags |= IP6T_FUZZY_OPT_MINIMUM;
88
89                 break;
90
91         case '2':
92
93         if (invert)
94                 exit_error(PARAMETER_PROBLEM,"Can't specify ! --upper-limit");
95
96         if (*flags & IP6T_FUZZY_OPT_MAXIMUM)
97            exit_error(PARAMETER_PROBLEM,"Can't specify --upper-limit twice");
98
99         if (string_to_number(optarg,1,MAXFUZZYRATE,&num) == -1 || num < 1)
100                 exit_error(PARAMETER_PROBLEM,"BAD --upper-limit");
101
102                 fuzzyinfo->maximum_rate = num;
103
104                 *flags |= IP6T_FUZZY_OPT_MAXIMUM;
105
106                 break ;
107
108         default:
109                 return 0;
110         }
111         return 1;
112 }
113
114 static void final_check(unsigned int flags)
115 {
116 }
117
118 static void
119 print(const struct ip6t_ip6 *ipv6,
120       const struct ip6t_entry_match *match,
121       int numeric)
122 {
123         const struct ip6t_fuzzy_info *fuzzyinfo
124                 = (const struct ip6t_fuzzy_info *)match->data;
125
126         printf(" fuzzy: lower limit = %u pps - upper limit = %u pps ",
127                 fuzzyinfo->minimum_rate, fuzzyinfo->maximum_rate);
128 }
129
130 /* Saves the union ip6t_targinfo in parsable form to stdout. */
131 static void
132 save(const struct ip6t_ip6 *ipv6, const struct ip6t_entry_match *match)
133 {
134         const struct ip6t_fuzzy_info *fuzzyinfo
135                 = (const struct ip6t_fuzzy_info *)match->data;
136
137         printf("--lower-limit %u --upper-limit %u ",
138                 fuzzyinfo->minimum_rate, fuzzyinfo->maximum_rate);
139 }
140
141 struct ip6tables_match fuzzy_match = {
142         .name          = "fuzzy",
143         .version       = IPTABLES_VERSION,
144         .size          = IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info)),
145         .userspacesize = IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info)),
146         .help          = &help,
147         .init          = &init,
148         .parse         = &parse,
149         .final_check   = &final_check,
150         .print         = &print,
151         .save          = &save,
152         .extra_opts    = opts
153 };
154
155 void _init(void)
156 {
157         register_match6(&fuzzy_match);
158 }