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"
25 static struct option opts
[] = {
26 { "set-mark", 1, 0, '1' },
27 { "and-mark", 1, 0, '2' },
28 { "or-mark", 1, 0, '3' },
32 /* Initialize the target. */
34 init(struct ipt_entry_target
*t
, unsigned int *nfcache
)
38 /* Function which parses command options; returns true if it
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
;
50 #ifdef KERNEL_64_USERSPACE_32
51 if (string_to_number_ll(optarg
, 0, 0,
54 if (string_to_number_l(optarg
, 0, 0,
57 exit_error(PARAMETER_PROBLEM
, "Bad MARK value `%s'", optarg
);
59 exit_error(PARAMETER_PROBLEM
,
60 "MARK target: Can't specify --set-mark twice");
64 exit_error(PARAMETER_PROBLEM
,
65 "MARK target: kernel too old for --and-mark");
67 exit_error(PARAMETER_PROBLEM
,
68 "MARK target: kernel too old for --or-mark");
77 final_check(unsigned int flags
)
80 exit_error(PARAMETER_PROBLEM
,
81 "MARK target: Parameter --set/and/or-mark"
85 /* Function which parses command options; returns true if it
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
;
97 markinfo
->mode
= IPT_MARK_SET
;
100 markinfo
->mode
= IPT_MARK_AND
;
103 markinfo
->mode
= IPT_MARK_OR
;
109 #ifdef KERNEL_64_USERSPACE_32
110 if (string_to_number_ll(optarg
, 0, 0, &markinfo
->mark
))
112 if (string_to_number_l(optarg
, 0, 0, &markinfo
->mark
))
114 exit_error(PARAMETER_PROBLEM
, "Bad MARK value `%s'", optarg
);
117 exit_error(PARAMETER_PROBLEM
,
118 "MARK target: Can't specify --set-mark twice");
124 #ifdef KERNEL_64_USERSPACE_32
126 print_mark(unsigned long long mark
)
128 printf("0x%llx ", mark
);
132 print_mark(unsigned long mark
)
134 printf("0x%lx ", mark
);
138 /* Prints out the targinfo. */
140 print_v0(const struct ipt_ip
*ip
,
141 const struct ipt_entry_target
*target
,
144 const struct ipt_mark_target_info
*markinfo
=
145 (const struct ipt_mark_target_info
*)target
->data
;
147 print_mark(markinfo
->mark
);
150 /* Saves the union ipt_targinfo in parsable form to stdout. */
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. */
163 print_v1(const struct ipt_ip
*ip
,
164 const struct ipt_entry_target
*target
,
167 const struct ipt_mark_target_info_v1
*markinfo
=
168 (const struct ipt_mark_target_info_v1
*)target
->data
;
170 switch (markinfo
->mode
) {
181 print_mark(markinfo
->mark
);
184 /* Saves the union ipt_targinfo in parsable form to stdout. */
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
) {
193 printf("--set-mark ");
196 printf("--and-mark ");
199 printf("--or-mark ");
202 print_mark(markinfo
->mark
);
206 struct iptables_target mark_v0
= {
209 .version
= IPTABLES_VERSION
,
211 .size
= IPT_ALIGN(sizeof(struct ipt_mark_target_info
)),
212 .userspacesize
= IPT_ALIGN(sizeof(struct ipt_mark_target_info
)),
216 .final_check
= &final_check
,
223 struct iptables_target mark_v1
= {
226 .version
= IPTABLES_VERSION
,
228 .size
= IPT_ALIGN(sizeof(struct ipt_mark_target_info_v1
)),
229 .userspacesize
= IPT_ALIGN(sizeof(struct ipt_mark_target_info_v1
)),
233 .final_check
= &final_check
,
241 register_target(&mark_v0
);
242 register_target(&mark_v1
);