1 #include <stdbool.h> 2 #include <stdio.h> 3 #include <xtables.h> 4 #include <linux/netfilter/xt_mark.h> 5 6 struct xt_mark_info { 7 unsigned long mark, mask; 8 uint8_t invert; 9 }; 10 11 enum { 12 O_MARK = 0, 13 }; 14 15 static 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 22 static 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 28 static 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 39 static 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 50 static 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 58 static void 59 mark_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 69 static void 70 mark_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 82 static 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 93 static void 94 mark_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 105 static void 106 print_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 117 static 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 132 static 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 147 static 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 178 void _init(void) 179 { 180 xtables_register_matches(mark_mt_reg, ARRAY_SIZE(mark_mt_reg)); 181 } 182