iptables-1.3.2-20050720
[iptables.git] / extensions / libipt_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-06-09 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Bug corrections in
10 the save function , thanks to information given by Jean-Francois Patenaude .
11
12 */
13
14 #include <stdio.h>
15 #include <netdb.h>
16 #include <string.h>
17 #include <stdlib.h>
18 #include <syslog.h>
19 #include <getopt.h>
20 #include <iptables.h>
21 #include <linux/netfilter_ipv4/ip_tables.h>
22 #include <linux/netfilter_ipv4/ipt_fuzzy.h>
23
24
25 static void
26 help(void)
27 {
28         printf(
29 "fuzzy v%s options:\n"
30 "                      --lower-limit number (in packets per second)\n"
31 "                      --upper-limit number\n"
32 ,IPTABLES_VERSION);
33 };
34
35 static struct option opts[] = {
36         { "lower-limit", 1 , 0 , '1' } ,
37         { "upper-limit", 1 , 0 , '2' } ,
38         { 0 }
39 };
40
41 /* Initialize data structures */
42 static void
43 init(struct ipt_entry_match *m, unsigned int *nfcache)
44 {
45         struct ipt_fuzzy_info *presentinfo = (struct ipt_fuzzy_info *)(m)->data;
46
47         /*
48          * Default rates ( I'll improve this very soon with something based 
49          * on real statistics of the running machine ) .
50         */
51
52         presentinfo->minimum_rate = 1000;
53         presentinfo->maximum_rate = 2000;
54 }
55
56 #define IPT_FUZZY_OPT_MINIMUM   0x01
57 #define IPT_FUZZY_OPT_MAXIMUM   0x02
58
59 static int
60 parse(int c, char **argv, int invert, unsigned int *flags,
61       const struct ipt_entry *entry,
62       unsigned int *nfcache,
63       struct ipt_entry_match **match)
64 {
65
66 struct ipt_fuzzy_info *fuzzyinfo = (struct ipt_fuzzy_info *)(*match)->data;
67
68         u_int32_t num;
69
70         switch (c) {
71
72         case '1':
73                 
74         if (invert)
75                 exit_error(PARAMETER_PROBLEM,"Can't specify ! --lower-limit");
76
77         if (*flags & IPT_FUZZY_OPT_MINIMUM)
78               exit_error(PARAMETER_PROBLEM,"Can't specify --lower-limit twice");
79         
80         if (string_to_number(optarg,1,MAXFUZZYRATE,&num) == -1 || num < 1)
81                         exit_error(PARAMETER_PROBLEM,"BAD --lower-limit");
82
83                 fuzzyinfo->minimum_rate = num ;
84
85                 *flags |= IPT_FUZZY_OPT_MINIMUM;
86                 
87                 break;
88
89         case '2':
90
91         if (invert)
92                 exit_error(PARAMETER_PROBLEM,"Can't specify ! --upper-limit");
93
94         if (*flags & IPT_FUZZY_OPT_MAXIMUM)
95            exit_error(PARAMETER_PROBLEM,"Can't specify --upper-limit twice");
96
97         if (string_to_number(optarg,1,MAXFUZZYRATE,&num) == -1 || num < 1)
98                 exit_error(PARAMETER_PROBLEM,"BAD --upper-limit");
99
100                 fuzzyinfo->maximum_rate = num ;
101
102                 *flags |= IPT_FUZZY_OPT_MAXIMUM;
103
104                 break ;
105
106         default:
107                 return 0;
108         }
109         return 1;
110 }
111
112 static void final_check(unsigned int flags)
113 {
114 }
115
116 static void
117 print(const struct ipt_ip *ip,
118       const struct ipt_entry_match *match,
119       int numeric)
120 {
121         const struct ipt_fuzzy_info *fuzzyinfo
122                 = (const struct ipt_fuzzy_info *)match->data;
123
124         printf(" fuzzy: lower limit = %u pps - upper limit = %u pps ",fuzzyinfo->minimum_rate,fuzzyinfo->maximum_rate);
125
126 }
127
128 /* Saves the union ipt_targinfo in parsable form to stdout. */
129 static void
130 save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
131 {
132         const struct ipt_fuzzy_info *fuzzyinfo
133                 = (const struct ipt_fuzzy_info *)match->data;
134
135         printf("--lower-limit %u ",fuzzyinfo->minimum_rate);
136         printf("--upper-limit %u ",fuzzyinfo->maximum_rate);
137
138 }
139
140 static struct iptables_match fuzzy_match = { 
141         .next           = NULL,
142         .name           = "fuzzy",
143         .version        = IPTABLES_VERSION,
144         .size           = IPT_ALIGN(sizeof(struct ipt_fuzzy_info)),
145         .userspacesize  = IPT_ALIGN(sizeof(struct ipt_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_match(&fuzzy_match);
158 }