Busybox: Upgrade to 1.21.1 (stable). lsof active.
[tomato.git] / release / src / router / iptables / extensions / libipt_MARK.c
blob457f6ad393886bc5aed7f1afc4957ec95b88a863
1 /* Shared library add-on to iptables to add MARK target support. */
2 #include <stdio.h>
3 #include <string.h>
4 #include <stdlib.h>
5 #include <getopt.h>
7 #include <iptables.h>
8 #include <linux/netfilter_ipv4/ip_tables.h>
9 /* For 64bit kernel / 32bit userspace */
10 #include "../include/linux/netfilter_ipv4/ipt_MARK.h"
12 /* Function which prints out usage message. */
13 static void
14 help(void)
16 printf(
17 "MARK target v%s options:\n"
18 " --set-mark value Set nfmark value\n"
19 " --and-mark value Binary AND the nfmark with value\n"
20 " --or-mark value Binary OR the nfmark with value\n"
21 "\n",
22 IPTABLES_VERSION);
25 static struct option opts[] = {
26 { "set-mark", 1, 0, '1' },
27 { "and-mark", 1, 0, '2' },
28 { "or-mark", 1, 0, '3' },
29 { 0 }
32 /* Initialize the target. */
33 static void
34 init(struct ipt_entry_target *t, unsigned int *nfcache)
38 /* Function which parses command options; returns true if it
39 ate an option */
40 static int
41 parse_v0(int c, char **argv, int invert, unsigned int *flags,
42 const struct ipt_entry *entry,
43 struct ipt_entry_target **target)
45 struct ipt_mark_target_info *markinfo
46 = (struct ipt_mark_target_info *)(*target)->data;
48 switch (c) {
49 case '1':
50 #ifdef KERNEL_64_USERSPACE_32
51 if (string_to_number_ll(optarg, 0, 0,
52 &markinfo->mark))
53 #else
54 if (string_to_number_l(optarg, 0, 0,
55 &markinfo->mark))
56 #endif
57 exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg);
58 if (*flags)
59 exit_error(PARAMETER_PROBLEM,
60 "MARK target: Can't specify --set-mark twice");
61 *flags = 1;
62 break;
63 case '2':
64 exit_error(PARAMETER_PROBLEM,
65 "MARK target: kernel too old for --and-mark");
66 case '3':
67 exit_error(PARAMETER_PROBLEM,
68 "MARK target: kernel too old for --or-mark");
69 default:
70 return 0;
73 return 1;
76 static void
77 final_check(unsigned int flags)
79 if (!flags)
80 exit_error(PARAMETER_PROBLEM,
81 "MARK target: Parameter --set/and/or-mark"
82 " is required");
85 /* Function which parses command options; returns true if it
86 ate an option */
87 static int
88 parse_v1(int c, char **argv, int invert, unsigned int *flags,
89 const struct ipt_entry *entry,
90 struct ipt_entry_target **target)
92 struct ipt_mark_target_info_v1 *markinfo
93 = (struct ipt_mark_target_info_v1 *)(*target)->data;
95 switch (c) {
96 case '1':
97 markinfo->mode = IPT_MARK_SET;
98 break;
99 case '2':
100 markinfo->mode = IPT_MARK_AND;
101 break;
102 case '3':
103 markinfo->mode = IPT_MARK_OR;
104 break;
105 default:
106 return 0;
109 #ifdef KERNEL_64_USERSPACE_32
110 if (string_to_number_ll(optarg, 0, 0, &markinfo->mark))
111 #else
112 if (string_to_number_l(optarg, 0, 0, &markinfo->mark))
113 #endif
114 exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg);
116 if (*flags)
117 exit_error(PARAMETER_PROBLEM,
118 "MARK target: Can't specify --set-mark twice");
120 *flags = 1;
121 return 1;
124 #ifdef KERNEL_64_USERSPACE_32
125 static void
126 print_mark(unsigned long long mark)
128 printf("0x%llx ", mark);
130 #else
131 static void
132 print_mark(unsigned long mark)
134 printf("0x%lx ", mark);
136 #endif
138 /* Prints out the targinfo. */
139 static void
140 print_v0(const struct ipt_ip *ip,
141 const struct ipt_entry_target *target,
142 int numeric)
144 const struct ipt_mark_target_info *markinfo =
145 (const struct ipt_mark_target_info *)target->data;
146 printf("MARK set ");
147 print_mark(markinfo->mark);
150 /* Saves the union ipt_targinfo in parsable form to stdout. */
151 static void
152 save_v0(const struct ipt_ip *ip, const struct ipt_entry_target *target)
154 const struct ipt_mark_target_info *markinfo =
155 (const struct ipt_mark_target_info *)target->data;
157 printf("--set-mark ");
158 print_mark(markinfo->mark);
161 /* Prints out the targinfo. */
162 static void
163 print_v1(const struct ipt_ip *ip,
164 const struct ipt_entry_target *target,
165 int numeric)
167 const struct ipt_mark_target_info_v1 *markinfo =
168 (const struct ipt_mark_target_info_v1 *)target->data;
170 switch (markinfo->mode) {
171 case IPT_MARK_SET:
172 printf("MARK set ");
173 break;
174 case IPT_MARK_AND:
175 printf("MARK and ");
176 break;
177 case IPT_MARK_OR:
178 printf("MARK or ");
179 break;
181 print_mark(markinfo->mark);
184 /* Saves the union ipt_targinfo in parsable form to stdout. */
185 static void
186 save_v1(const struct ipt_ip *ip, const struct ipt_entry_target *target)
188 const struct ipt_mark_target_info_v1 *markinfo =
189 (const struct ipt_mark_target_info_v1 *)target->data;
191 switch (markinfo->mode) {
192 case IPT_MARK_SET:
193 printf("--set-mark ");
194 break;
195 case IPT_MARK_AND:
196 printf("--and-mark ");
197 break;
198 case IPT_MARK_OR:
199 printf("--or-mark ");
200 break;
202 print_mark(markinfo->mark);
205 static
206 struct iptables_target mark_v0 = {
207 .next = NULL,
208 .name = "MARK",
209 .version = IPTABLES_VERSION,
210 .revision = 0,
211 .size = IPT_ALIGN(sizeof(struct ipt_mark_target_info)),
212 .userspacesize = IPT_ALIGN(sizeof(struct ipt_mark_target_info)),
213 .help = &help,
214 .init = &init,
215 .parse = &parse_v0,
216 .final_check = &final_check,
217 .print = &print_v0,
218 .save = &save_v0,
219 .extra_opts = opts
222 static
223 struct iptables_target mark_v1 = {
224 .next = NULL,
225 .name = "MARK",
226 .version = IPTABLES_VERSION,
227 .revision = 1,
228 .size = IPT_ALIGN(sizeof(struct ipt_mark_target_info_v1)),
229 .userspacesize = IPT_ALIGN(sizeof(struct ipt_mark_target_info_v1)),
230 .help = &help,
231 .init = &init,
232 .parse = &parse_v1,
233 .final_check = &final_check,
234 .print = &print_v1,
235 .save = &save_v1,
236 .extra_opts = opts
239 void _init(void)
241 register_target(&mark_v0);
242 register_target(&mark_v1);