1#include <stdbool.h> 2#include <stdio.h> 3#include <xtables.h> 4#include <linux/netfilter/xt_mark.h> 5 6struct xt_mark_info { 7 unsigned long mark, mask; 8 uint8_t invert; 9}; 10 11enum { 12 O_MARK = 0, 13}; 14 15static void mark_mt_help(void) 16{ 17 printf( 18"mark match options:\n" 19"[!] --mark value[/mask] Match nfmark value with optional mask\n"); 20} 21 22static const struct xt_option_entry mark_mt_opts[] = { 23 {.name = "mark", .id = O_MARK, .type = XTTYPE_MARKMASK32, 24 .flags = XTOPT_MAND | XTOPT_INVERT}, 25 XTOPT_TABLEEND, 26}; 27 28static void mark_mt_parse(struct xt_option_call *cb) 29{ 30 struct xt_mark_mtinfo1 *info = cb->data; 31 32 xtables_option_parse(cb); 33 if (cb->invert) 34 info->invert = true; 35 info->mark = cb->val.mark; 36 info->mask = cb->val.mask; 37} 38 39static void mark_parse(struct xt_option_call *cb) 40{ 41 struct xt_mark_info *markinfo = cb->data; 42 43 xtables_option_parse(cb); 44 if (cb->invert) 45 markinfo->invert = 1; 46 markinfo->mark = cb->val.mark; 47 markinfo->mask = cb->val.mask; 48} 49 50static void print_mark(unsigned int mark, unsigned int mask) 51{ 52 if (mask != 0xffffffffU) 53 printf(" 0x%x/0x%x", mark, mask); 54 else 55 printf(" 0x%x", mark); 56} 57 58static void 59mark_mt_print(const void *ip, const struct xt_entry_match *match, int numeric) 60{ 61 const struct xt_mark_mtinfo1 *info = (const void *)match->data; 62 63 printf(" mark match"); 64 if (info->invert) 65 printf(" !"); 66 print_mark(info->mark, info->mask); 67} 68 69static void 70mark_print(const void *ip, const struct xt_entry_match *match, int numeric) 71{ 72 const struct xt_mark_info *info = (const void *)match->data; 73 74 printf(" MARK match"); 75 76 if (info->invert) 77 printf(" !"); 78 79 print_mark(info->mark, info->mask); 80} 81 82static void mark_mt_save(const void *ip, const struct xt_entry_match *match) 83{ 84 const struct xt_mark_mtinfo1 *info = (const void *)match->data; 85 86 if (info->invert) 87 printf(" !"); 88 89 printf(" --mark"); 90 print_mark(info->mark, info->mask); 91} 92 93static void 94mark_save(const void *ip, const struct xt_entry_match *match) 95{ 96 const struct xt_mark_info *info = (const void *)match->data; 97 98 if (info->invert) 99 printf(" !"); 100 101 printf(" --mark"); 102 print_mark(info->mark, info->mask); 103} 104 105static void 106print_mark_xlate(struct xt_xlate *xl, unsigned int mark, 107 unsigned int mask, uint32_t op) 108{ 109 if (mask != 0xffffffffU) 110 xt_xlate_add(xl, " and 0x%x %s 0x%x", mask, 111 op == XT_OP_EQ ? "==" : "!=", mark); 112 else 113 xt_xlate_add(xl, " %s0x%x", 114 op == XT_OP_EQ ? "" : "!= ", mark); 115} 116 117static int mark_mt_xlate(struct xt_xlate *xl, 118 const struct xt_xlate_mt_params *params) 119{ 120 const struct xt_mark_mtinfo1 *info = (const void *)params->match->data; 121 enum xt_op op = XT_OP_EQ; 122 123 if (info->invert) 124 op = XT_OP_NEQ; 125 126 xt_xlate_add(xl, "mark"); 127 print_mark_xlate(xl, info->mark, info->mask, op); 128 129 return 1; 130} 131 132static int mark_xlate(struct xt_xlate *xl, 133 const struct xt_xlate_mt_params *params) 134{ 135 const struct xt_mark_info *info = (const void *)params->match->data; 136 enum xt_op op = XT_OP_EQ; 137 138 if (info->invert) 139 op = XT_OP_NEQ; 140 141 xt_xlate_add(xl, "mark"); 142 print_mark_xlate(xl, info->mark, info->mask, op); 143 144 return 1; 145} 146 147static struct xtables_match mark_mt_reg[] = { 148 { 149 .family = NFPROTO_UNSPEC, 150 .name = "mark", 151 .revision = 0, 152 .version = XTABLES_VERSION, 153 .size = XT_ALIGN(sizeof(struct xt_mark_info)), 154 .userspacesize = XT_ALIGN(sizeof(struct xt_mark_info)), 155 .help = mark_mt_help, 156 .print = mark_print, 157 .save = mark_save, 158 .x6_parse = mark_parse, 159 .x6_options = mark_mt_opts, 160 .xlate = mark_xlate, 161 }, 162 { 163 .version = XTABLES_VERSION, 164 .name = "mark", 165 .revision = 1, 166 .family = NFPROTO_UNSPEC, 167 .size = XT_ALIGN(sizeof(struct xt_mark_mtinfo1)), 168 .userspacesize = XT_ALIGN(sizeof(struct xt_mark_mtinfo1)), 169 .help = mark_mt_help, 170 .print = mark_mt_print, 171 .save = mark_mt_save, 172 .x6_parse = mark_mt_parse, 173 .x6_options = mark_mt_opts, 174 .xlate = mark_mt_xlate, 175 }, 176}; 177 178void _init(void) 179{ 180 xtables_register_matches(mark_mt_reg, ARRAY_SIZE(mark_mt_reg)); 181} 182