2 Shared library add-on to iptables to add match support for random match.
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
8 2001-10-14 Fabrice MARIE <fabrice@netfilter.org> : initial development.
18 #include <linux/netfilter_ipv4/ip_tables.h>
19 #include <linux/netfilter_ipv4/ipt_random.h>
22 * The kernel random routing returns numbers between 0 and 255.
23 * To ease the task of the user in choosing the probability
24 * of matching, we want him to be able to use percentages.
25 * Therefore we have to accept numbers in percentage here,
26 * turn them into number between 0 and 255 for the kernel module,
27 * and turn them back to percentages when we print/save
32 /* Function which prints out usage message. */
37 "random v%s options:\n"
38 " [--average percent ] The probability in percentage of the match\n"
39 " If ommited, a probability of 50%% percent is set.\n"
40 " Percentage must be within : 1 <= percent <= 99.\n\n",
44 static struct option opts
[] = {
45 { "average", 1, 0, '1' },
49 /* Initialize the target. */
51 init(struct ipt_entry_match
*m
, unsigned int *nfcache
)
53 struct ipt_rand_info
*randinfo
= (struct ipt_rand_info
*)(m
)->data
;
55 /* We assign the average to be 50 which is our default value */
57 randinfo
->average
= 128;
60 #define IPT_RAND_OPT_AVERAGE 0x01
62 /* Function which parses command options; returns true if it
65 parse(int c
, char **argv
, int invert
, unsigned int *flags
,
66 const struct ipt_entry
*entry
,
67 unsigned int *nfcache
,
68 struct ipt_entry_match
**match
)
70 struct ipt_rand_info
*randinfo
= (struct ipt_rand_info
*)(*match
)->data
;
75 /* check for common mistakes... */
77 exit_error(PARAMETER_PROBLEM
,
78 "Can't specify ! --average");
79 if (*flags
& IPT_RAND_OPT_AVERAGE
)
80 exit_error(PARAMETER_PROBLEM
,
81 "Can't specify --average twice");
83 /* Remember, this function will interpret a leading 0 to be
84 Octal, a leading 0x to be hexdecimal... */
85 if (string_to_number(optarg
, 1, 99, &num
) == -1 || num
< 1)
86 exit_error(PARAMETER_PROBLEM
,
87 "bad --average `%s', must be between 1 and 99", optarg
);
89 /* assign the values */
90 randinfo
->average
= (int)(num
* 2.55);
91 *flags
|= IPT_RAND_OPT_AVERAGE
;
99 /* Final check; nothing. */
100 static void final_check(unsigned int flags
)
104 /* Prints out the targinfo. */
106 print(const struct ipt_ip
*ip
,
107 const struct ipt_entry_match
*match
,
110 const struct ipt_rand_info
*randinfo
111 = (const struct ipt_rand_info
*)match
->data
;
112 div_t result
= div((randinfo
->average
*100), 255);
113 if (result
.rem
> 127) /* round up... */
116 printf(" random %u%% ", result
.quot
);
119 /* Saves the union ipt_targinfo in parsable form to stdout. */
121 save(const struct ipt_ip
*ip
, const struct ipt_entry_match
*match
)
123 const struct ipt_rand_info
*randinfo
124 = (const struct ipt_rand_info
*)match
->data
;
125 div_t result
= div((randinfo
->average
*100), 255);
126 if (result
.rem
> 127) /* round up... */
129 printf("--average %u ", result
.quot
);
132 struct iptables_match rand_match
= {
135 .version
= IPTABLES_VERSION
,
136 .size
= IPT_ALIGN(sizeof(struct ipt_rand_info
)),
137 .userspacesize
= IPT_ALIGN(sizeof(struct ipt_rand_info
)),
141 .final_check
= &final_check
,
149 register_match(&rand_match
);