libxt_MARK.c revision 60756e7f8be9242b606f1b5fbcb38f45e4de29c5
1#include <stdbool.h> 2#include <stdio.h> 3#include <xtables.h> 4#include <linux/netfilter/xt_MARK.h> 5 6/* Version 0 */ 7struct xt_mark_target_info { 8 unsigned long mark; 9}; 10 11/* Version 1 */ 12enum { 13 XT_MARK_SET=0, 14 XT_MARK_AND, 15 XT_MARK_OR, 16}; 17 18struct xt_mark_target_info_v1 { 19 unsigned long mark; 20 uint8_t mode; 21}; 22 23enum { 24 O_SET_MARK = 0, 25 O_AND_MARK, 26 O_OR_MARK, 27 O_XOR_MARK, 28 O_SET_XMARK, 29 F_SET_MARK = 1 << O_SET_MARK, 30 F_AND_MARK = 1 << O_AND_MARK, 31 F_OR_MARK = 1 << O_OR_MARK, 32 F_XOR_MARK = 1 << O_XOR_MARK, 33 F_SET_XMARK = 1 << O_SET_XMARK, 34 F_ANY = F_SET_MARK | F_AND_MARK | F_OR_MARK | 35 F_XOR_MARK | F_SET_XMARK, 36}; 37 38static void MARK_help(void) 39{ 40 printf( 41"MARK target options:\n" 42" --set-mark value Set nfmark value\n" 43" --and-mark value Binary AND the nfmark with value\n" 44" --or-mark value Binary OR the nfmark with value\n"); 45} 46 47static const struct xt_option_entry MARK_opts[] = { 48 {.name = "set-mark", .id = O_SET_MARK, .type = XTTYPE_UINT32, 49 .excl = F_ANY}, 50 {.name = "and-mark", .id = O_AND_MARK, .type = XTTYPE_UINT32, 51 .excl = F_ANY}, 52 {.name = "or-mark", .id = O_OR_MARK, .type = XTTYPE_UINT32, 53 .excl = F_ANY}, 54 XTOPT_TABLEEND, 55}; 56 57static const struct xt_option_entry mark_tg_opts[] = { 58 {.name = "set-xmark", .id = O_SET_XMARK, .type = XTTYPE_MARKMASK32, 59 .excl = F_ANY}, 60 {.name = "set-mark", .id = O_SET_MARK, .type = XTTYPE_MARKMASK32, 61 .excl = F_ANY}, 62 {.name = "and-mark", .id = O_AND_MARK, .type = XTTYPE_UINT32, 63 .excl = F_ANY}, 64 {.name = "or-mark", .id = O_OR_MARK, .type = XTTYPE_UINT32, 65 .excl = F_ANY}, 66 {.name = "xor-mark", .id = O_XOR_MARK, .type = XTTYPE_UINT32, 67 .excl = F_ANY}, 68 XTOPT_TABLEEND, 69}; 70 71static void mark_tg_help(void) 72{ 73 printf( 74"MARK target options:\n" 75" --set-xmark value[/mask] Clear bits in mask and XOR value into nfmark\n" 76" --set-mark value[/mask] Clear bits in mask and OR value into nfmark\n" 77" --and-mark bits Binary AND the nfmark with bits\n" 78" --or-mark bits Binary OR the nfmark with bits\n" 79" --xor-mask bits Binary XOR the nfmark with bits\n" 80"\n"); 81} 82 83static void MARK_parse_v0(struct xt_option_call *cb) 84{ 85 struct xt_mark_target_info *markinfo = cb->data; 86 87 xtables_option_parse(cb); 88 switch (cb->entry->id) { 89 case O_SET_MARK: 90 markinfo->mark = cb->val.mark; 91 break; 92 default: 93 xtables_error(PARAMETER_PROBLEM, 94 "MARK target: kernel too old for --%s", 95 cb->entry->name); 96 } 97} 98 99static void MARK_check(struct xt_fcheck_call *cb) 100{ 101 if (cb->xflags == 0) 102 xtables_error(PARAMETER_PROBLEM, 103 "MARK target: Parameter --set/and/or-mark" 104 " is required"); 105} 106 107static void MARK_parse_v1(struct xt_option_call *cb) 108{ 109 struct xt_mark_target_info_v1 *markinfo = cb->data; 110 111 xtables_option_parse(cb); 112 switch (cb->entry->id) { 113 case O_SET_MARK: 114 markinfo->mode = XT_MARK_SET; 115 break; 116 case O_AND_MARK: 117 markinfo->mode = XT_MARK_AND; 118 break; 119 case O_OR_MARK: 120 markinfo->mode = XT_MARK_OR; 121 break; 122 } 123 markinfo->mark = cb->val.u32; 124} 125 126static void mark_tg_parse(struct xt_option_call *cb) 127{ 128 struct xt_mark_tginfo2 *info = cb->data; 129 130 xtables_option_parse(cb); 131 switch (cb->entry->id) { 132 case O_SET_XMARK: 133 info->mark = cb->val.mark; 134 info->mask = cb->val.mask; 135 break; 136 case O_SET_MARK: 137 info->mark = cb->val.mark; 138 info->mask = cb->val.mark | cb->val.mask; 139 break; 140 case O_AND_MARK: 141 info->mark = 0; 142 info->mask = ~cb->val.u32; 143 break; 144 case O_OR_MARK: 145 info->mark = info->mask = cb->val.u32; 146 break; 147 case O_XOR_MARK: 148 info->mark = cb->val.u32; 149 info->mask = 0; 150 break; 151 } 152} 153 154static void mark_tg_check(struct xt_fcheck_call *cb) 155{ 156 if (cb->xflags == 0) 157 xtables_error(PARAMETER_PROBLEM, "MARK: One of the --set-xmark, " 158 "--{and,or,xor,set}-mark options is required"); 159} 160 161static void 162print_mark(unsigned long mark) 163{ 164 printf(" 0x%lx", mark); 165} 166 167static void MARK_print_v0(const void *ip, 168 const struct xt_entry_target *target, int numeric) 169{ 170 const struct xt_mark_target_info *markinfo = 171 (const struct xt_mark_target_info *)target->data; 172 printf(" MARK set"); 173 print_mark(markinfo->mark); 174} 175 176static void MARK_save_v0(const void *ip, const struct xt_entry_target *target) 177{ 178 const struct xt_mark_target_info *markinfo = 179 (const struct xt_mark_target_info *)target->data; 180 181 printf(" --set-mark"); 182 print_mark(markinfo->mark); 183} 184 185static void MARK_print_v1(const void *ip, const struct xt_entry_target *target, 186 int numeric) 187{ 188 const struct xt_mark_target_info_v1 *markinfo = 189 (const struct xt_mark_target_info_v1 *)target->data; 190 191 switch (markinfo->mode) { 192 case XT_MARK_SET: 193 printf(" MARK set"); 194 break; 195 case XT_MARK_AND: 196 printf(" MARK and"); 197 break; 198 case XT_MARK_OR: 199 printf(" MARK or"); 200 break; 201 } 202 print_mark(markinfo->mark); 203} 204 205static void mark_tg_print(const void *ip, const struct xt_entry_target *target, 206 int numeric) 207{ 208 const struct xt_mark_tginfo2 *info = (const void *)target->data; 209 210 if (info->mark == 0) 211 printf(" MARK and 0x%x", (unsigned int)(uint32_t)~info->mask); 212 else if (info->mark == info->mask) 213 printf(" MARK or 0x%x", info->mark); 214 else if (info->mask == 0) 215 printf(" MARK xor 0x%x", info->mark); 216 else if (info->mask == 0xffffffffU) 217 printf(" MARK set 0x%x", info->mark); 218 else 219 printf(" MARK xset 0x%x/0x%x", info->mark, info->mask); 220} 221 222static void MARK_save_v1(const void *ip, const struct xt_entry_target *target) 223{ 224 const struct xt_mark_target_info_v1 *markinfo = 225 (const struct xt_mark_target_info_v1 *)target->data; 226 227 switch (markinfo->mode) { 228 case XT_MARK_SET: 229 printf(" --set-mark"); 230 break; 231 case XT_MARK_AND: 232 printf(" --and-mark"); 233 break; 234 case XT_MARK_OR: 235 printf(" --or-mark"); 236 break; 237 } 238 print_mark(markinfo->mark); 239} 240 241static void mark_tg_save(const void *ip, const struct xt_entry_target *target) 242{ 243 const struct xt_mark_tginfo2 *info = (const void *)target->data; 244 245 printf(" --set-xmark 0x%x/0x%x", info->mark, info->mask); 246} 247 248static struct xtables_target mark_tg_reg[] = { 249 { 250 .family = NFPROTO_UNSPEC, 251 .name = "MARK", 252 .version = XTABLES_VERSION, 253 .revision = 0, 254 .size = XT_ALIGN(sizeof(struct xt_mark_target_info)), 255 .userspacesize = XT_ALIGN(sizeof(struct xt_mark_target_info)), 256 .help = MARK_help, 257 .print = MARK_print_v0, 258 .save = MARK_save_v0, 259 .x6_parse = MARK_parse_v0, 260 .x6_fcheck = MARK_check, 261 .x6_options = MARK_opts, 262 }, 263 { 264 .family = NFPROTO_IPV4, 265 .name = "MARK", 266 .version = XTABLES_VERSION, 267 .revision = 1, 268 .size = XT_ALIGN(sizeof(struct xt_mark_target_info_v1)), 269 .userspacesize = XT_ALIGN(sizeof(struct xt_mark_target_info_v1)), 270 .help = MARK_help, 271 .print = MARK_print_v1, 272 .save = MARK_save_v1, 273 .x6_parse = MARK_parse_v1, 274 .x6_fcheck = MARK_check, 275 .x6_options = MARK_opts, 276 }, 277 { 278 .version = XTABLES_VERSION, 279 .name = "MARK", 280 .revision = 2, 281 .family = NFPROTO_UNSPEC, 282 .size = XT_ALIGN(sizeof(struct xt_mark_tginfo2)), 283 .userspacesize = XT_ALIGN(sizeof(struct xt_mark_tginfo2)), 284 .help = mark_tg_help, 285 .print = mark_tg_print, 286 .save = mark_tg_save, 287 .x6_parse = mark_tg_parse, 288 .x6_fcheck = mark_tg_check, 289 .x6_options = mark_tg_opts, 290 }, 291}; 292 293void _init(void) 294{ 295 xtables_register_targets(mark_tg_reg, ARRAY_SIZE(mark_tg_reg)); 296} 297