1#include <stdio.h> 2#include <xtables.h> 3#include <linux/netfilter/xt_physdev.h> 4 5enum { 6 O_PHYSDEV_IN = 0, 7 O_PHYSDEV_OUT, 8 O_PHYSDEV_IS_IN, 9 O_PHYSDEV_IS_OUT, 10 O_PHYSDEV_IS_BRIDGED, 11}; 12 13static void physdev_help(void) 14{ 15 printf( 16"physdev match options:\n" 17" [!] --physdev-in inputname[+] bridge port name ([+] for wildcard)\n" 18" [!] --physdev-out outputname[+] bridge port name ([+] for wildcard)\n" 19" [!] --physdev-is-in arrived on a bridge device\n" 20" [!] --physdev-is-out will leave on a bridge device\n" 21" [!] --physdev-is-bridged it's a bridged packet\n"); 22} 23 24#define s struct xt_physdev_info 25static const struct xt_option_entry physdev_opts[] = { 26 {.name = "physdev-in", .id = O_PHYSDEV_IN, .type = XTTYPE_STRING, 27 .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, physindev)}, 28 {.name = "physdev-out", .id = O_PHYSDEV_OUT, .type = XTTYPE_STRING, 29 .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, physoutdev)}, 30 {.name = "physdev-is-in", .id = O_PHYSDEV_IS_IN, .type = XTTYPE_NONE}, 31 {.name = "physdev-is-out", .id = O_PHYSDEV_IS_OUT, 32 .type = XTTYPE_NONE}, 33 {.name = "physdev-is-bridged", .id = O_PHYSDEV_IS_BRIDGED, 34 .type = XTTYPE_NONE}, 35 XTOPT_TABLEEND, 36}; 37#undef s 38 39static void physdev_parse(struct xt_option_call *cb) 40{ 41 struct xt_physdev_info *info = cb->data; 42 43 xtables_option_parse(cb); 44 switch (cb->entry->id) { 45 case O_PHYSDEV_IN: 46 xtables_parse_interface(cb->arg, info->physindev, 47 (unsigned char *)info->in_mask); 48 if (cb->invert) 49 info->invert |= XT_PHYSDEV_OP_IN; 50 info->bitmask |= XT_PHYSDEV_OP_IN; 51 break; 52 case O_PHYSDEV_OUT: 53 xtables_parse_interface(cb->arg, info->physoutdev, 54 (unsigned char *)info->out_mask); 55 if (cb->invert) 56 info->invert |= XT_PHYSDEV_OP_OUT; 57 info->bitmask |= XT_PHYSDEV_OP_OUT; 58 break; 59 case O_PHYSDEV_IS_IN: 60 info->bitmask |= XT_PHYSDEV_OP_ISIN; 61 if (cb->invert) 62 info->invert |= XT_PHYSDEV_OP_ISIN; 63 break; 64 case O_PHYSDEV_IS_OUT: 65 info->bitmask |= XT_PHYSDEV_OP_ISOUT; 66 if (cb->invert) 67 info->invert |= XT_PHYSDEV_OP_ISOUT; 68 break; 69 case O_PHYSDEV_IS_BRIDGED: 70 if (cb->invert) 71 info->invert |= XT_PHYSDEV_OP_BRIDGED; 72 info->bitmask |= XT_PHYSDEV_OP_BRIDGED; 73 break; 74 } 75} 76 77static void physdev_check(struct xt_fcheck_call *cb) 78{ 79 if (cb->xflags == 0) 80 xtables_error(PARAMETER_PROBLEM, "PHYSDEV: no physdev option specified"); 81} 82 83static void 84physdev_print(const void *ip, const struct xt_entry_match *match, int numeric) 85{ 86 const struct xt_physdev_info *info = (const void *)match->data; 87 88 printf(" PHYSDEV match"); 89 if (info->bitmask & XT_PHYSDEV_OP_ISIN) 90 printf("%s --physdev-is-in", 91 info->invert & XT_PHYSDEV_OP_ISIN ? " !":""); 92 if (info->bitmask & XT_PHYSDEV_OP_IN) 93 printf("%s --physdev-in %s", 94 (info->invert & XT_PHYSDEV_OP_IN) ? " !":"", info->physindev); 95 96 if (info->bitmask & XT_PHYSDEV_OP_ISOUT) 97 printf("%s --physdev-is-out", 98 info->invert & XT_PHYSDEV_OP_ISOUT ? " !":""); 99 if (info->bitmask & XT_PHYSDEV_OP_OUT) 100 printf("%s --physdev-out %s", 101 (info->invert & XT_PHYSDEV_OP_OUT) ? " !":"", info->physoutdev); 102 if (info->bitmask & XT_PHYSDEV_OP_BRIDGED) 103 printf("%s --physdev-is-bridged", 104 info->invert & XT_PHYSDEV_OP_BRIDGED ? " !":""); 105} 106 107static void physdev_save(const void *ip, const struct xt_entry_match *match) 108{ 109 const struct xt_physdev_info *info = (const void *)match->data; 110 111 if (info->bitmask & XT_PHYSDEV_OP_ISIN) 112 printf("%s --physdev-is-in", 113 (info->invert & XT_PHYSDEV_OP_ISIN) ? " !" : ""); 114 if (info->bitmask & XT_PHYSDEV_OP_IN) 115 printf("%s --physdev-in %s", 116 (info->invert & XT_PHYSDEV_OP_IN) ? " !" : "", 117 info->physindev); 118 119 if (info->bitmask & XT_PHYSDEV_OP_ISOUT) 120 printf("%s --physdev-is-out", 121 (info->invert & XT_PHYSDEV_OP_ISOUT) ? " !" : ""); 122 if (info->bitmask & XT_PHYSDEV_OP_OUT) 123 printf("%s --physdev-out %s", 124 (info->invert & XT_PHYSDEV_OP_OUT) ? " !" : "", 125 info->physoutdev); 126 if (info->bitmask & XT_PHYSDEV_OP_BRIDGED) 127 printf("%s --physdev-is-bridged", 128 (info->invert & XT_PHYSDEV_OP_BRIDGED) ? " !" : ""); 129} 130 131static struct xtables_match physdev_match = { 132 .family = NFPROTO_UNSPEC, 133 .name = "physdev", 134 .version = XTABLES_VERSION, 135 .size = XT_ALIGN(sizeof(struct xt_physdev_info)), 136 .userspacesize = XT_ALIGN(sizeof(struct xt_physdev_info)), 137 .help = physdev_help, 138 .print = physdev_print, 139 .save = physdev_save, 140 .x6_parse = physdev_parse, 141 .x6_fcheck = physdev_check, 142 .x6_options = physdev_opts, 143}; 144 145void _init(void) 146{ 147 xtables_register_match(&physdev_match); 148} 149