2 Shared library add-on to iptables to add match support for every Nth packet
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-07-17 Fabrice MARIE <fabrice@netfilter.org> : initial development.
9 2001-09-20 Richard Wagner (rwagner@cloudnet.com)
10 * added support for multiple counters
11 * added support for matching on individual packets
21 #include <ip6tables.h>
22 #include <linux/netfilter_ipv6/ip6_tables.h>
23 #include <linux/netfilter_ipv6/ip6t_nth.h>
26 /* Function which prints out usage message. */
32 " --every Nth Match every Nth packet\n"
33 " [--counter] num Use counter 0-%u (default:0)\n"
34 " [--start] num Initialize the counter at the number 'num'\n"
35 " instead of 0. Must be between 0 and Nth-1\n"
36 " [--packet] num Match on 'num' packet. Must be between 0\n"
38 " If --packet is used for a counter than\n"
39 " there must be Nth number of --packet\n"
40 " rules, covering all values between 0 and\n"
41 " Nth-1 inclusively.\n",
42 IPTABLES_VERSION, IP6T_NTH_NUM_COUNTERS-1);
45 static struct option opts[] = {
46 { "every", 1, 0, '1' },
47 { "start", 1, 0, '2' },
48 { "counter", 1, 0, '3' },
49 { "packet", 1, 0, '4' },
53 /* Initialize the target. */
55 init(struct ip6t_entry_match *m, unsigned int *nfcache)
57 *nfcache |= NFC_UNKNOWN;
60 #define IP6T_NTH_OPT_EVERY 0x01
61 #define IP6T_NTH_OPT_NOT_EVERY 0x02
62 #define IP6T_NTH_OPT_START 0x04
63 #define IP6T_NTH_OPT_COUNTER 0x08
64 #define IP6T_NTH_OPT_PACKET 0x10
66 /* Function which parses command options; returns true if it
69 parse(int c, char **argv, int invert, unsigned int *flags,
70 const struct ip6t_entry *entry,
71 unsigned int *nfcache,
72 struct ip6t_entry_match **match)
74 struct ip6t_nth_info *nthinfo = (struct ip6t_nth_info *)(*match)->data;
79 /* check for common mistakes... */
80 if ((!invert) && (*flags & IP6T_NTH_OPT_EVERY))
81 exit_error(PARAMETER_PROBLEM,
82 "Can't specify --every twice");
83 if (invert && (*flags & IP6T_NTH_OPT_NOT_EVERY))
84 exit_error(PARAMETER_PROBLEM,
85 "Can't specify ! --every twice");
86 if ((!invert) && (*flags & IP6T_NTH_OPT_NOT_EVERY))
87 exit_error(PARAMETER_PROBLEM,
88 "Can't specify --every with ! --every");
89 if (invert && (*flags & IP6T_NTH_OPT_EVERY))
90 exit_error(PARAMETER_PROBLEM,
91 "Can't specify ! --every with --every");
93 /* Remember, this function will interpret a leading 0 to be
94 Octal, a leading 0x to be hexdecimal... */
95 if (string_to_number(optarg, 2, 100, &num) == -1 || num < 2)
96 exit_error(PARAMETER_PROBLEM,
97 "bad --every `%s', must be between 2 and 100", optarg);
99 /* assign the values */
100 nthinfo->every = num-1;
101 nthinfo->startat = 0;
102 nthinfo->packet = 0xFF;
103 if(!(*flags & IP6T_NTH_OPT_EVERY))
105 nthinfo->counter = 0;
109 *flags |= IP6T_NTH_OPT_NOT_EVERY;
114 *flags |= IP6T_NTH_OPT_EVERY;
119 /* check for common mistakes... */
120 if (!((*flags & IP6T_NTH_OPT_EVERY) ||
121 (*flags & IP6T_NTH_OPT_NOT_EVERY)))
122 exit_error(PARAMETER_PROBLEM,
123 "Can't specify --start before --every");
125 exit_error(PARAMETER_PROBLEM,
126 "Can't specify with ! --start");
127 if (*flags & IP6T_NTH_OPT_START)
128 exit_error(PARAMETER_PROBLEM,
129 "Can't specify --start twice");
130 if (string_to_number(optarg, 0, nthinfo->every, &num) == -1)
131 exit_error(PARAMETER_PROBLEM,
132 "bad --start `%s', must between 0 and %u", optarg, nthinfo->every);
133 *flags |= IP6T_NTH_OPT_START;
134 nthinfo->startat = num;
137 /* check for common mistakes... */
139 exit_error(PARAMETER_PROBLEM,
140 "Can't specify with ! --counter");
141 if (*flags & IP6T_NTH_OPT_COUNTER)
142 exit_error(PARAMETER_PROBLEM,
143 "Can't specify --counter twice");
144 if (string_to_number(optarg, 0, IP6T_NTH_NUM_COUNTERS-1, &num) == -1)
145 exit_error(PARAMETER_PROBLEM,
146 "bad --counter `%s', must between 0 and %u", optarg, IP6T_NTH_NUM_COUNTERS-1);
147 /* assign the values */
148 *flags |= IP6T_NTH_OPT_COUNTER;
149 nthinfo->counter = num;
152 /* check for common mistakes... */
153 if (!((*flags & IP6T_NTH_OPT_EVERY) ||
154 (*flags & IP6T_NTH_OPT_NOT_EVERY)))
155 exit_error(PARAMETER_PROBLEM,
156 "Can't specify --packet before --every");
157 if ((*flags & IP6T_NTH_OPT_NOT_EVERY))
158 exit_error(PARAMETER_PROBLEM,
159 "Can't specify --packet with ! --every");
161 exit_error(PARAMETER_PROBLEM,
162 "Can't specify with ! --packet");
163 if (*flags & IP6T_NTH_OPT_PACKET)
164 exit_error(PARAMETER_PROBLEM,
165 "Can't specify --packet twice");
166 if (string_to_number(optarg, 0, nthinfo->every, &num) == -1)
167 exit_error(PARAMETER_PROBLEM,
168 "bad --packet `%s', must between 0 and %u", optarg, nthinfo->every);
169 *flags |= IP6T_NTH_OPT_PACKET;
170 nthinfo->packet = num;
178 /* Final check; nothing. */
179 static void final_check(unsigned int flags)
183 /* Prints out the targinfo. */
185 print(const struct ip6t_ip6 *ip,
186 const struct ip6t_entry_match *match,
189 const struct ip6t_nth_info *nthinfo
190 = (const struct ip6t_nth_info *)match->data;
192 if (nthinfo->not == 1)
194 printf("every %uth ", (nthinfo->every +1));
195 if (nthinfo->counter != 0)
196 printf("counter #%u ", (nthinfo->counter));
197 if (nthinfo->packet != 0xFF)
198 printf("packet #%u ", nthinfo->packet);
199 if (nthinfo->startat != 0)
200 printf("start at %u ", nthinfo->startat);
203 /* Saves the union ip6t_targinfo in parsable form to stdout. */
205 save(const struct ip6t_ip6 *ip, const struct ip6t_entry_match *match)
207 const struct ip6t_nth_info *nthinfo
208 = (const struct ip6t_nth_info *)match->data;
210 if (nthinfo->not == 1)
212 printf("--every %u ", (nthinfo->every +1));
213 printf("--counter %u ", (nthinfo->counter));
214 if (nthinfo->startat != 0)
215 printf("--start %u ", nthinfo->startat );
216 if (nthinfo->packet != 0xFF)
217 printf("--packet %u ", nthinfo->packet );
220 struct ip6tables_match nth
224 IP6T_ALIGN(sizeof(struct ip6t_nth_info)),
225 IP6T_ALIGN(sizeof(struct ip6t_nth_info)),
237 register_match6(&nth);