blob: 5f42a13717c761723dd5224c7b15c104de1fcea8 [file] [log] [blame]
Jan Engelhardt32b8e612010-07-23 21:16:14 +02001#include <stdbool.h>
Patrick McHardy6afc5b72008-01-15 17:27:04 +00002#include <stdio.h>
3#include <string.h>
4#include <stdlib.h>
5#include <stddef.h>
6#include <getopt.h>
7
8#include <xtables.h>
9#include <linux/netfilter/xt_rateest.h>
10
Patrick McHardy6afc5b72008-01-15 17:27:04 +000011static void rateest_help(void)
12{
13 printf(
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020014"rateest match options:\n"
Patrick McHardy6afc5b72008-01-15 17:27:04 +000015" --rateest1 name Rate estimator name\n"
16" --rateest2 name Rate estimator name\n"
17" --rateest-delta Compare difference(s) to given rate(s)\n"
18" --rateest-bps1 [bps] Compare bps\n"
19" --rateest-pps1 [pps] Compare pps\n"
20" --rateest-bps2 [bps] Compare bps\n"
21" --rateest-pps2 [pps] Compare pps\n"
22" [!] --rateest-lt Match if rate is less than given rate/estimator\n"
23" [!] --rateest-gt Match if rate is greater than given rate/estimator\n"
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020024" [!] --rateest-eq Match if rate is equal to given rate/estimator\n");
Patrick McHardy6afc5b72008-01-15 17:27:04 +000025}
26
27enum rateest_options {
28 OPT_RATEEST1,
29 OPT_RATEEST2,
30 OPT_RATEEST_BPS1,
31 OPT_RATEEST_PPS1,
32 OPT_RATEEST_BPS2,
33 OPT_RATEEST_PPS2,
34 OPT_RATEEST_DELTA,
35 OPT_RATEEST_LT,
36 OPT_RATEEST_GT,
37 OPT_RATEEST_EQ,
38};
39
40static const struct option rateest_opts[] = {
Jan Engelhardt32b8e612010-07-23 21:16:14 +020041 {.name = "rateest1", .has_arg = true, .val = OPT_RATEEST1},
42 {.name = "rateest", .has_arg = true, .val = OPT_RATEEST1}, /* alias for absolute mode */
43 {.name = "rateest2", .has_arg = true, .val = OPT_RATEEST2},
44 {.name = "rateest-bps1", .has_arg = false, .val = OPT_RATEEST_BPS1},
45 {.name = "rateest-pps1", .has_arg = false, .val = OPT_RATEEST_PPS1},
46 {.name = "rateest-bps2", .has_arg = false, .val = OPT_RATEEST_BPS2},
47 {.name = "rateest-pps2", .has_arg = false, .val = OPT_RATEEST_PPS2},
48 {.name = "rateest-bps", .has_arg = false, .val = OPT_RATEEST_BPS2}, /* alias for absolute mode */
49 {.name = "rateest-pps", .has_arg = false, .val = OPT_RATEEST_PPS2}, /* alias for absolute mode */
50 {.name = "rateest-delta", .has_arg = false, .val = OPT_RATEEST_DELTA},
51 {.name = "rateest-lt", .has_arg = false, .val = OPT_RATEEST_LT},
52 {.name = "rateest-gt", .has_arg = false, .val = OPT_RATEEST_GT},
53 {.name = "rateest-eq", .has_arg = false, .val = OPT_RATEEST_EQ},
54 XT_GETOPT_TABLEEND,
Patrick McHardy6afc5b72008-01-15 17:27:04 +000055};
56
57/* Copied from iproute. See http://physics.nist.gov/cuu/Units/binary.html */
58static const struct rate_suffix {
59 const char *name;
60 double scale;
61} suffixes[] = {
62 { "bit", 1. },
63 { "Kibit", 1024. },
64 { "kbit", 1000. },
Jan Engelhardt463628b2011-05-12 17:36:25 +020065 { "Mibit", 1024.*1024. },
Patrick McHardy6afc5b72008-01-15 17:27:04 +000066 { "mbit", 1000000. },
Jan Engelhardt463628b2011-05-12 17:36:25 +020067 { "Gibit", 1024.*1024.*1024. },
Patrick McHardy6afc5b72008-01-15 17:27:04 +000068 { "gbit", 1000000000. },
Jan Engelhardt463628b2011-05-12 17:36:25 +020069 { "Tibit", 1024.*1024.*1024.*1024. },
Patrick McHardy6afc5b72008-01-15 17:27:04 +000070 { "tbit", 1000000000000. },
71 { "Bps", 8. },
72 { "KiBps", 8.*1024. },
73 { "KBps", 8000. },
74 { "MiBps", 8.*1024*1024. },
75 { "MBps", 8000000. },
76 { "GiBps", 8.*1024.*1024.*1024. },
77 { "GBps", 8000000000. },
78 { "TiBps", 8.*1024.*1024.*1024.*1024. },
79 { "TBps", 8000000000000. },
Jan Engelhardt104fb312011-05-07 04:01:25 +020080 {NULL},
Patrick McHardy6afc5b72008-01-15 17:27:04 +000081};
82
83static int
Jan Engelhardt7ac40522011-01-07 12:34:04 +010084rateest_get_rate(uint32_t *rate, const char *str)
Patrick McHardy6afc5b72008-01-15 17:27:04 +000085{
86 char *p;
87 double bps = strtod(str, &p);
88 const struct rate_suffix *s;
89
90 if (p == str)
91 return -1;
92
93 if (*p == '\0') {
94 *rate = bps / 8.; /* assume bytes/sec */
95 return 0;
96 }
97
98 for (s = suffixes; s->name; ++s) {
99 if (strcasecmp(s->name, p) == 0) {
100 *rate = (bps * s->scale) / 8.;
101 return 0;
102 }
103 }
104
105 return -1;
106}
107
108static int
109rateest_parse(int c, char **argv, int invert, unsigned int *flags,
110 const void *entry, struct xt_entry_match **match)
111{
112 struct xt_rateest_match_info *info = (void *)(*match)->data;
Jan Engelhardt5f2922c2009-01-27 18:43:01 +0100113 unsigned int val;
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000114
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000115 switch (c) {
116 case OPT_RATEEST1:
Jan Engelhardtbf971282009-11-03 19:55:11 +0100117 xtables_check_inverse(optarg, &invert, &optind, 0, argv);
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000118 if (invert)
Jan Engelhardt1829ed42009-02-21 03:29:44 +0100119 xtables_error(PARAMETER_PROBLEM,
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000120 "rateest: rateest can't be inverted");
121
122 if (*flags & (1 << c))
Jan Engelhardt1829ed42009-02-21 03:29:44 +0100123 xtables_error(PARAMETER_PROBLEM,
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000124 "rateest: can't specify --rateest1 twice");
125 *flags |= 1 << c;
126
127 strncpy(info->name1, optarg, sizeof(info->name1) - 1);
128 break;
129
130 case OPT_RATEEST2:
Jan Engelhardtbf971282009-11-03 19:55:11 +0100131 xtables_check_inverse(optarg, &invert, &optind, 0, argv);
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000132 if (invert)
Jan Engelhardt1829ed42009-02-21 03:29:44 +0100133 xtables_error(PARAMETER_PROBLEM,
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000134 "rateest: rateest can't be inverted");
135
136 if (*flags & (1 << c))
Jan Engelhardt1829ed42009-02-21 03:29:44 +0100137 xtables_error(PARAMETER_PROBLEM,
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000138 "rateest: can't specify --rateest2 twice");
139 *flags |= 1 << c;
140
141 strncpy(info->name2, optarg, sizeof(info->name2) - 1);
142 info->flags |= XT_RATEEST_MATCH_REL;
143 break;
144
145 case OPT_RATEEST_BPS1:
Jan Engelhardtbf971282009-11-03 19:55:11 +0100146 xtables_check_inverse(optarg, &invert, &optind, 0, argv);
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000147 if (invert)
Jan Engelhardt1829ed42009-02-21 03:29:44 +0100148 xtables_error(PARAMETER_PROBLEM,
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000149 "rateest: rateest-bps can't be inverted");
150
151 if (*flags & (1 << c))
Jan Engelhardt1829ed42009-02-21 03:29:44 +0100152 xtables_error(PARAMETER_PROBLEM,
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000153 "rateest: can't specify --rateest-bps1 twice");
154 *flags |= 1 << c;
155
156 info->flags |= XT_RATEEST_MATCH_BPS;
157
158 /* The rate is optional and only required in absolute mode */
159 if (!argv[optind] || *argv[optind] == '-' || *argv[optind] == '!')
160 break;
161
162 if (rateest_get_rate(&info->bps1, argv[optind]) < 0)
Jan Engelhardt1829ed42009-02-21 03:29:44 +0100163 xtables_error(PARAMETER_PROBLEM,
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000164 "rateest: could not parse rate `%s'",
165 argv[optind]);
166 optind++;
167 break;
168
169 case OPT_RATEEST_PPS1:
Jan Engelhardtbf971282009-11-03 19:55:11 +0100170 xtables_check_inverse(optarg, &invert, &optind, 0, argv);
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000171 if (invert)
Jan Engelhardt1829ed42009-02-21 03:29:44 +0100172 xtables_error(PARAMETER_PROBLEM,
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000173 "rateest: rateest-pps can't be inverted");
174
175 if (*flags & (1 << c))
Jan Engelhardt1829ed42009-02-21 03:29:44 +0100176 xtables_error(PARAMETER_PROBLEM,
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000177 "rateest: can't specify --rateest-pps1 twice");
178 *flags |= 1 << c;
179
180 info->flags |= XT_RATEEST_MATCH_PPS;
181
182 /* The rate is optional and only required in absolute mode */
183 if (!argv[optind] || *argv[optind] == '-' || *argv[optind] == '!')
184 break;
185
Jan Engelhardt5f2922c2009-01-27 18:43:01 +0100186 if (!xtables_strtoui(argv[optind], NULL, &val, 0, UINT32_MAX))
Jan Engelhardt1829ed42009-02-21 03:29:44 +0100187 xtables_error(PARAMETER_PROBLEM,
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000188 "rateest: could not parse pps `%s'",
189 argv[optind]);
Jan Engelhardt5f2922c2009-01-27 18:43:01 +0100190 info->pps1 = val;
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000191 optind++;
192 break;
193
194 case OPT_RATEEST_BPS2:
Jan Engelhardtbf971282009-11-03 19:55:11 +0100195 xtables_check_inverse(optarg, &invert, &optind, 0, argv);
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000196 if (invert)
Jan Engelhardt1829ed42009-02-21 03:29:44 +0100197 xtables_error(PARAMETER_PROBLEM,
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000198 "rateest: rateest-bps can't be inverted");
199
200 if (*flags & (1 << c))
Jan Engelhardt1829ed42009-02-21 03:29:44 +0100201 xtables_error(PARAMETER_PROBLEM,
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000202 "rateest: can't specify --rateest-bps2 twice");
203 *flags |= 1 << c;
204
205 info->flags |= XT_RATEEST_MATCH_BPS;
206
207 /* The rate is optional and only required in absolute mode */
208 if (!argv[optind] || *argv[optind] == '-' || *argv[optind] == '!')
209 break;
210
211 if (rateest_get_rate(&info->bps2, argv[optind]) < 0)
Jan Engelhardt1829ed42009-02-21 03:29:44 +0100212 xtables_error(PARAMETER_PROBLEM,
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000213 "rateest: could not parse rate `%s'",
214 argv[optind]);
215 optind++;
216 break;
217
218 case OPT_RATEEST_PPS2:
Jan Engelhardtbf971282009-11-03 19:55:11 +0100219 xtables_check_inverse(optarg, &invert, &optind, 0, argv);
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000220 if (invert)
Jan Engelhardt1829ed42009-02-21 03:29:44 +0100221 xtables_error(PARAMETER_PROBLEM,
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000222 "rateest: rateest-pps can't be inverted");
223
224 if (*flags & (1 << c))
Jan Engelhardt1829ed42009-02-21 03:29:44 +0100225 xtables_error(PARAMETER_PROBLEM,
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000226 "rateest: can't specify --rateest-pps2 twice");
227 *flags |= 1 << c;
228
229 info->flags |= XT_RATEEST_MATCH_PPS;
230
231 /* The rate is optional and only required in absolute mode */
232 if (!argv[optind] || *argv[optind] == '-' || *argv[optind] == '!')
233 break;
234
Jan Engelhardt5f2922c2009-01-27 18:43:01 +0100235 if (!xtables_strtoui(argv[optind], NULL, &val, 0, UINT32_MAX))
Jan Engelhardt1829ed42009-02-21 03:29:44 +0100236 xtables_error(PARAMETER_PROBLEM,
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000237 "rateest: could not parse pps `%s'",
238 argv[optind]);
Jan Engelhardt5f2922c2009-01-27 18:43:01 +0100239 info->pps2 = val;
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000240 optind++;
241 break;
242
243 case OPT_RATEEST_DELTA:
Jan Engelhardtbf971282009-11-03 19:55:11 +0100244 xtables_check_inverse(optarg, &invert, &optind, 0, argv);
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000245 if (invert)
Jan Engelhardt1829ed42009-02-21 03:29:44 +0100246 xtables_error(PARAMETER_PROBLEM,
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000247 "rateest: rateest-delta can't be inverted");
248
249 if (*flags & (1 << c))
Jan Engelhardt1829ed42009-02-21 03:29:44 +0100250 xtables_error(PARAMETER_PROBLEM,
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000251 "rateest: can't specify --rateest-delta twice");
252 *flags |= 1 << c;
253
254 info->flags |= XT_RATEEST_MATCH_DELTA;
255 break;
256
257 case OPT_RATEEST_EQ:
Jan Engelhardtbbe83862009-10-24 00:45:33 +0200258 xtables_check_inverse(optarg, &invert, &optind, 0, argv);
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000259
260 if (*flags & (1 << c))
Jan Engelhardt1829ed42009-02-21 03:29:44 +0100261 xtables_error(PARAMETER_PROBLEM,
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000262 "rateest: can't specify lt/gt/eq twice");
263 *flags |= 1 << c;
264
265 info->mode = XT_RATEEST_MATCH_EQ;
266 if (invert)
267 info->flags |= XT_RATEEST_MATCH_INVERT;
268 break;
269
270 case OPT_RATEEST_LT:
Jan Engelhardtbbe83862009-10-24 00:45:33 +0200271 xtables_check_inverse(optarg, &invert, &optind, 0, argv);
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000272
273 if (*flags & (1 << c))
Jan Engelhardt1829ed42009-02-21 03:29:44 +0100274 xtables_error(PARAMETER_PROBLEM,
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000275 "rateest: can't specify lt/gt/eq twice");
276 *flags |= 1 << c;
277
278 info->mode = XT_RATEEST_MATCH_LT;
279 if (invert)
280 info->flags |= XT_RATEEST_MATCH_INVERT;
281 break;
282
283 case OPT_RATEEST_GT:
Jan Engelhardtbbe83862009-10-24 00:45:33 +0200284 xtables_check_inverse(optarg, &invert, &optind, 0, argv);
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000285
286 if (*flags & (1 << c))
Jan Engelhardt1829ed42009-02-21 03:29:44 +0100287 xtables_error(PARAMETER_PROBLEM,
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000288 "rateest: can't specify lt/gt/eq twice");
289 *flags |= 1 << c;
290
291 info->mode = XT_RATEEST_MATCH_GT;
292 if (invert)
293 info->flags |= XT_RATEEST_MATCH_INVERT;
294 break;
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000295 }
296
297 return 1;
298}
299
Jan Engelhardt4a96d2e2011-06-21 09:54:31 +0200300static void rateest_final_check(struct xt_fcheck_call *cb)
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000301{
Jan Engelhardt4a96d2e2011-06-21 09:54:31 +0200302 struct xt_rateest_match_info *info = cb->data;
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000303
Jan Engelhardtc3d0a7b2008-12-30 12:03:39 +0100304 if (info == NULL)
Jan Engelhardt1829ed42009-02-21 03:29:44 +0100305 xtables_error(PARAMETER_PROBLEM, "rateest match: "
Jan Engelhardtc3d0a7b2008-12-30 12:03:39 +0100306 "you need to specify some flags");
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000307 if (!(info->flags & XT_RATEEST_MATCH_REL))
308 info->flags |= XT_RATEEST_MATCH_ABS;
309}
310
311static void
Jan Engelhardt7ac40522011-01-07 12:34:04 +0100312rateest_print_rate(uint32_t rate, int numeric)
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000313{
314 double tmp = (double)rate*8;
315
316 if (numeric)
Jan Engelhardt73866352010-12-18 02:04:59 +0100317 printf(" %u", rate);
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000318 else if (tmp >= 1000.0*1000000.0)
Jan Engelhardt73866352010-12-18 02:04:59 +0100319 printf(" %.0fMbit", tmp/1000000.0);
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000320 else if (tmp >= 1000.0 * 1000.0)
Jan Engelhardt73866352010-12-18 02:04:59 +0100321 printf(" %.0fKbit", tmp/1000.0);
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000322 else
Jan Engelhardt73866352010-12-18 02:04:59 +0100323 printf(" %.0fbit", tmp);
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000324}
325
326static void
Jan Engelhardt69f564e2009-05-26 13:14:06 +0200327rateest_print_mode(const struct xt_rateest_match_info *info,
328 const char *prefix)
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000329{
330 if (info->flags & XT_RATEEST_MATCH_INVERT)
Jan Engelhardt73866352010-12-18 02:04:59 +0100331 printf(" !");
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000332
333 switch (info->mode) {
334 case XT_RATEEST_MATCH_EQ:
Jan Engelhardt73866352010-12-18 02:04:59 +0100335 printf(" %seq", prefix);
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000336 break;
337 case XT_RATEEST_MATCH_LT:
Jan Engelhardt73866352010-12-18 02:04:59 +0100338 printf(" %slt", prefix);
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000339 break;
340 case XT_RATEEST_MATCH_GT:
Jan Engelhardt73866352010-12-18 02:04:59 +0100341 printf(" %sgt", prefix);
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000342 break;
343 default:
344 exit(1);
345 }
346}
347
348static void
349rateest_print(const void *ip, const struct xt_entry_match *match, int numeric)
350{
Jan Engelhardt69f564e2009-05-26 13:14:06 +0200351 const struct xt_rateest_match_info *info = (const void *)match->data;
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000352
Jan Engelhardt73866352010-12-18 02:04:59 +0100353 printf(" rateest match ");
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000354
Jan Engelhardt73866352010-12-18 02:04:59 +0100355 printf("%s", info->name1);
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000356 if (info->flags & XT_RATEEST_MATCH_DELTA)
Jan Engelhardt73866352010-12-18 02:04:59 +0100357 printf(" delta");
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000358
359 if (info->flags & XT_RATEEST_MATCH_BPS) {
Jan Engelhardt73866352010-12-18 02:04:59 +0100360 printf(" bps");
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000361 if (info->flags & XT_RATEEST_MATCH_DELTA)
362 rateest_print_rate(info->bps1, numeric);
363 if (info->flags & XT_RATEEST_MATCH_ABS) {
364 rateest_print_mode(info, "");
365 rateest_print_rate(info->bps2, numeric);
366 }
367 }
368 if (info->flags & XT_RATEEST_MATCH_PPS) {
Jan Engelhardt73866352010-12-18 02:04:59 +0100369 printf(" pps");
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000370 if (info->flags & XT_RATEEST_MATCH_DELTA)
Jan Engelhardt73866352010-12-18 02:04:59 +0100371 printf(" %u", info->pps1);
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000372 if (info->flags & XT_RATEEST_MATCH_ABS) {
373 rateest_print_mode(info, "");
Jan Engelhardt73866352010-12-18 02:04:59 +0100374 printf(" %u", info->pps2);
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000375 }
376 }
377
378 if (info->flags & XT_RATEEST_MATCH_REL) {
379 rateest_print_mode(info, "");
380
Jan Engelhardt73866352010-12-18 02:04:59 +0100381 printf(" %s", info->name2);
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000382 if (info->flags & XT_RATEEST_MATCH_DELTA)
Jan Engelhardt73866352010-12-18 02:04:59 +0100383 printf(" delta");
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000384
385 if (info->flags & XT_RATEEST_MATCH_BPS) {
Jan Engelhardt73866352010-12-18 02:04:59 +0100386 printf(" bps");
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000387 if (info->flags & XT_RATEEST_MATCH_DELTA)
388 rateest_print_rate(info->bps2, numeric);
389 }
390 if (info->flags & XT_RATEEST_MATCH_PPS) {
Jan Engelhardt73866352010-12-18 02:04:59 +0100391 printf(" pps");
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000392 if (info->flags & XT_RATEEST_MATCH_DELTA)
Jan Engelhardt73866352010-12-18 02:04:59 +0100393 printf(" %u", info->pps2);
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000394 }
395 }
396}
397
398static void
399rateest_save(const void *ip, const struct xt_entry_match *match)
400{
Jan Engelhardt69f564e2009-05-26 13:14:06 +0200401 const struct xt_rateest_match_info *info = (const void *)match->data;
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000402
403 if (info->flags & XT_RATEEST_MATCH_REL) {
Jan Engelhardt73866352010-12-18 02:04:59 +0100404 printf(" --rateest1 %s", info->name1);
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000405 if (info->flags & XT_RATEEST_MATCH_BPS)
Jan Engelhardt73866352010-12-18 02:04:59 +0100406 printf(" --rateest-bps");
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000407 if (info->flags & XT_RATEEST_MATCH_PPS)
Jan Engelhardt73866352010-12-18 02:04:59 +0100408 printf(" --rateest-pps");
409 rateest_print_mode(info, " --rateest-");
410 printf(" --rateest2 %s", info->name2);
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000411 } else {
Jan Engelhardt73866352010-12-18 02:04:59 +0100412 printf(" --rateest %s", info->name1);
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000413 if (info->flags & XT_RATEEST_MATCH_BPS) {
Jan Engelhardt73866352010-12-18 02:04:59 +0100414 printf(" --rateest-bps1");
Luciano Coelhob4fa7222010-07-15 18:09:54 +0200415 rateest_print_rate(info->bps1, 0);
Jan Engelhardt73866352010-12-18 02:04:59 +0100416 printf(" --rateest-bps2");
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000417 rateest_print_rate(info->bps2, 0);
Luciano Coelhob4fa7222010-07-15 18:09:54 +0200418 rateest_print_mode(info, "--rateest-");
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000419 }
420 if (info->flags & XT_RATEEST_MATCH_PPS) {
Jan Engelhardt73866352010-12-18 02:04:59 +0100421 printf(" --rateest-pps");
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000422 rateest_print_mode(info, "--rateest-");
Jan Engelhardt73866352010-12-18 02:04:59 +0100423 printf(" %u", info->pps2);
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000424 }
425 }
426}
427
Jan Engelhardt23545c22008-02-14 04:23:04 +0100428static struct xtables_match rateest_mt_reg = {
Jan Engelhardt42979362009-06-01 11:56:23 +0200429 .family = NFPROTO_UNSPEC,
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000430 .name = "rateest",
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200431 .version = XTABLES_VERSION,
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000432 .size = XT_ALIGN(sizeof(struct xt_rateest_match_info)),
433 .userspacesize = XT_ALIGN(offsetof(struct xt_rateest_match_info, est1)),
434 .help = rateest_help,
435 .parse = rateest_parse,
Jan Engelhardt4a96d2e2011-06-21 09:54:31 +0200436 .x6_fcheck = rateest_final_check,
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000437 .print = rateest_print,
438 .save = rateest_save,
439 .extra_opts = rateest_opts,
440};
441
442void _init(void)
443{
Jan Engelhardt23545c22008-02-14 04:23:04 +0100444 xtables_register_match(&rateest_mt_reg);
Patrick McHardy6afc5b72008-01-15 17:27:04 +0000445}