1 #include <stdio.h> 2 #include <xtables.h> 3 #include <linux/netfilter/xt_rpfilter.h> 4 5 enum { 6 O_RPF_LOOSE = 0, 7 O_RPF_VMARK = 1, 8 O_RPF_ACCEPT_LOCAL = 2, 9 O_RPF_INVERT = 3, 10 }; 11 12 static void rpfilter_help(void) 13 { 14 printf( 15 "rpfilter match options:\n" 16 " --loose permit reverse path via any interface\n" 17 " --validmark use skb nfmark when performing route lookup\n" 18 " --accept-local do not reject packets with a local source address\n" 19 " --invert match packets that failed the reverse path test\n" 20 ); 21 } 22 23 static const struct xt_option_entry rpfilter_opts[] = { 24 {.name = "loose", .id = O_RPF_LOOSE, .type = XTTYPE_NONE, }, 25 {.name = "validmark", .id = O_RPF_VMARK, .type = XTTYPE_NONE, }, 26 {.name = "accept-local", .id = O_RPF_ACCEPT_LOCAL, .type = XTTYPE_NONE, }, 27 {.name = "invert", .id = O_RPF_INVERT, .type = XTTYPE_NONE, }, 28 XTOPT_TABLEEND, 29 }; 30 31 static void rpfilter_parse(struct xt_option_call *cb) 32 { 33 struct xt_rpfilter_info *rpfinfo = cb->data; 34 35 xtables_option_parse(cb); 36 switch (cb->entry->id) { 37 case O_RPF_LOOSE: 38 rpfinfo->flags |= XT_RPFILTER_LOOSE; 39 break; 40 case O_RPF_VMARK: 41 rpfinfo->flags |= XT_RPFILTER_VALID_MARK; 42 break; 43 case O_RPF_ACCEPT_LOCAL: 44 rpfinfo->flags |= XT_RPFILTER_ACCEPT_LOCAL; 45 break; 46 case O_RPF_INVERT: 47 rpfinfo->flags |= XT_RPFILTER_INVERT; 48 break; 49 } 50 } 51 52 static void 53 rpfilter_print_prefix(const void *ip, const void *matchinfo, 54 const char *prefix) 55 { 56 const struct xt_rpfilter_info *info = matchinfo; 57 if (info->flags & XT_RPFILTER_LOOSE) 58 printf(" %s%s", prefix, rpfilter_opts[O_RPF_LOOSE].name); 59 if (info->flags & XT_RPFILTER_VALID_MARK) 60 printf(" %s%s", prefix, rpfilter_opts[O_RPF_VMARK].name); 61 if (info->flags & XT_RPFILTER_ACCEPT_LOCAL) 62 printf(" %s%s", prefix, rpfilter_opts[O_RPF_ACCEPT_LOCAL].name); 63 if (info->flags & XT_RPFILTER_INVERT) 64 printf(" %s%s", prefix, rpfilter_opts[O_RPF_INVERT].name); 65 } 66 67 68 static void 69 rpfilter_print(const void *ip, const struct xt_entry_match *match, int numeric) 70 { 71 printf(" rpfilter"); 72 return rpfilter_print_prefix(ip, match->data, ""); 73 } 74 75 static void rpfilter_save(const void *ip, const struct xt_entry_match *match) 76 { 77 return rpfilter_print_prefix(ip, match->data, "--"); 78 } 79 80 static struct xtables_match rpfilter_match = { 81 .family = NFPROTO_UNSPEC, 82 .name = "rpfilter", 83 .version = XTABLES_VERSION, 84 .size = XT_ALIGN(sizeof(struct xt_rpfilter_info)), 85 .userspacesize = XT_ALIGN(sizeof(struct xt_rpfilter_info)), 86 .help = rpfilter_help, 87 .print = rpfilter_print, 88 .save = rpfilter_save, 89 .x6_parse = rpfilter_parse, 90 .x6_options = rpfilter_opts, 91 }; 92 93 void _init(void) 94 { 95 xtables_register_match(&rpfilter_match); 96 } 97