1 /* Shared library add-on to iptables to add MARK target support. */
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. */
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 " --copy-xid Set nfmark to be the connection xid (PlanetLab specific)\n"
26 static struct option opts[] = {
27 { "set-mark", 1, 0, '1' },
28 { "and-mark", 1, 0, '2' },
29 { "or-mark", 1, 0, '3' },
30 { "copy-xid", 1, 0, '4' },
34 /* Initialize the target. */
36 init(struct ipt_entry_target *t, unsigned int *nfcache)
40 /* Function which parses command options; returns true if it
43 parse_v0(int c, char **argv, int invert, unsigned int *flags,
44 const struct ipt_entry *entry,
45 struct ipt_entry_target **target)
47 struct ipt_mark_target_info *markinfo
48 = (struct ipt_mark_target_info *)(*target)->data;
52 #ifdef KERNEL_64_USERSPACE_32
53 if (string_to_number_ll(optarg, 0, 0,
56 if (string_to_number_l(optarg, 0, 0,
59 exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg);
61 exit_error(PARAMETER_PROBLEM,
62 "MARK target: Can't specify --set-mark twice");
66 exit_error(PARAMETER_PROBLEM,
67 "MARK target: kernel too old for --and-mark");
69 exit_error(PARAMETER_PROBLEM,
70 "MARK target: kernel too old for --or-mark");
79 final_check(unsigned int flags)
82 exit_error(PARAMETER_PROBLEM,
83 "MARK target: Parameter --set/and/or-mark"
87 /* Function which parses command options; returns true if it
90 parse_v1(int c, char **argv, int invert, unsigned int *flags,
91 const struct ipt_entry *entry,
92 struct ipt_entry_target **target)
94 struct ipt_mark_target_info_v1 *markinfo
95 = (struct ipt_mark_target_info_v1 *)(*target)->data;
99 markinfo->mode = IPT_MARK_SET;
102 markinfo->mode = IPT_MARK_AND;
105 markinfo->mode = IPT_MARK_OR;
108 markinfo->mode = IPT_MARK_COPYXID;
114 #ifdef KERNEL_64_USERSPACE_32
115 if (string_to_number_ll(optarg, 0, 0, &markinfo->mark))
117 if (string_to_number_l(optarg, 0, 0, &markinfo->mark))
119 exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg);
122 exit_error(PARAMETER_PROBLEM,
123 "MARK target: Can't specify --set-mark twice");
129 #ifdef KERNEL_64_USERSPACE_32
131 print_mark(unsigned long long mark)
133 printf("0x%llx ", mark);
137 print_mark(unsigned long mark)
139 printf("0x%lx ", mark);
143 /* Prints out the targinfo. */
145 print_v0(const struct ipt_ip *ip,
146 const struct ipt_entry_target *target,
149 const struct ipt_mark_target_info *markinfo =
150 (const struct ipt_mark_target_info *)target->data;
152 print_mark(markinfo->mark);
155 /* Saves the union ipt_targinfo in parsable form to stdout. */
157 save_v0(const struct ipt_ip *ip, const struct ipt_entry_target *target)
159 const struct ipt_mark_target_info *markinfo =
160 (const struct ipt_mark_target_info *)target->data;
162 printf("--set-mark ");
163 print_mark(markinfo->mark);
166 /* Prints out the targinfo. */
168 print_v1(const struct ipt_ip *ip,
169 const struct ipt_entry_target *target,
172 const struct ipt_mark_target_info_v1 *markinfo =
173 (const struct ipt_mark_target_info_v1 *)target->data;
175 switch (markinfo->mode) {
185 case IPT_MARK_COPYXID:
186 printf("MARK copyxid ");
189 print_mark(markinfo->mark);
192 /* Saves the union ipt_targinfo in parsable form to stdout. */
194 save_v1(const struct ipt_ip *ip, const struct ipt_entry_target *target)
196 const struct ipt_mark_target_info_v1 *markinfo =
197 (const struct ipt_mark_target_info_v1 *)target->data;
199 switch (markinfo->mode) {
201 printf("--set-mark ");
204 printf("--and-mark ");
207 printf("--or-mark ");
209 case IPT_MARK_COPYXID:
210 printf("--copy-xid ");
213 print_mark(markinfo->mark);
217 struct iptables_target mark_v0 = {
220 .version = IPTABLES_VERSION,
222 .size = IPT_ALIGN(sizeof(struct ipt_mark_target_info)),
223 .userspacesize = IPT_ALIGN(sizeof(struct ipt_mark_target_info)),
227 .final_check = &final_check,
234 struct iptables_target mark_v1 = {
237 .version = IPTABLES_VERSION,
239 .size = IPT_ALIGN(sizeof(struct ipt_mark_target_info_v1)),
240 .userspacesize = IPT_ALIGN(sizeof(struct ipt_mark_target_info_v1)),
244 .final_check = &final_check,
252 register_target(&mark_v0);
253 register_target(&mark_v1);