1 #include <stdio.h> 2 #include <xtables.h> 3 #include <linux/netfilter/xt_physdev.h> 4 5 enum { 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 13 static 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 25 static 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 39 static 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 77 static 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 83 static void 84 physdev_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 107 static 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 131 static 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 145 void _init(void) 146 { 147 xtables_register_match(&physdev_match); 148 } 149