11254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer#include <stdio.h> 2fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI#include <xtables.h> 3fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI#include <linux/netfilter/xt_physdev.h> 42291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt 52291d887cea2412af380f1ae995ddfee0362386bJan Engelhardtenum { 62291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt O_PHYSDEV_IN = 0, 72291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt O_PHYSDEV_OUT, 82291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt O_PHYSDEV_IS_IN, 92291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt O_PHYSDEV_IS_OUT, 102291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt O_PHYSDEV_IS_BRIDGED, 112291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt}; 121254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer 13181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic void physdev_help(void) 141254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer{ 151254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer printf( 168b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"physdev match options:\n" 17967279231a9ecfa99f26694a954afc535c63db1dJan Engelhardt" [!] --physdev-in inputname[+] bridge port name ([+] for wildcard)\n" 18967279231a9ecfa99f26694a954afc535c63db1dJan Engelhardt" [!] --physdev-out outputname[+] bridge port name ([+] for wildcard)\n" 1930596a5e7ae8c518a8a0bbf3aa891728e9f9ec1bBart De Schuymer" [!] --physdev-is-in arrived on a bridge device\n" 2030596a5e7ae8c518a8a0bbf3aa891728e9f9ec1bBart De Schuymer" [!] --physdev-is-out will leave on a bridge device\n" 218b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt" [!] --physdev-is-bridged it's a bridged packet\n"); 221254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer} 231254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer 242291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt#define s struct xt_physdev_info 252291d887cea2412af380f1ae995ddfee0362386bJan Engelhardtstatic const struct xt_option_entry physdev_opts[] = { 262291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt {.name = "physdev-in", .id = O_PHYSDEV_IN, .type = XTTYPE_STRING, 272291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, physindev)}, 282291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt {.name = "physdev-out", .id = O_PHYSDEV_OUT, .type = XTTYPE_STRING, 292291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, physoutdev)}, 30c2a47ead16fc488fbf7fd8aa12d306cedf4da441Jan Engelhardt {.name = "physdev-is-in", .id = O_PHYSDEV_IS_IN, .type = XTTYPE_NONE, 31c2a47ead16fc488fbf7fd8aa12d306cedf4da441Jan Engelhardt .flags = XTOPT_INVERT}, 322291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt {.name = "physdev-is-out", .id = O_PHYSDEV_IS_OUT, 33c2a47ead16fc488fbf7fd8aa12d306cedf4da441Jan Engelhardt .type = XTTYPE_NONE, .flags = XTOPT_INVERT}, 342291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt {.name = "physdev-is-bridged", .id = O_PHYSDEV_IS_BRIDGED, 35c2a47ead16fc488fbf7fd8aa12d306cedf4da441Jan Engelhardt .type = XTTYPE_NONE, .flags = XTOPT_INVERT}, 362291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt XTOPT_TABLEEND, 371254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer}; 382291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt#undef s 391254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer 402291d887cea2412af380f1ae995ddfee0362386bJan Engelhardtstatic void physdev_parse(struct xt_option_call *cb) 411254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer{ 422291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt struct xt_physdev_info *info = cb->data; 431254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer 442291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt xtables_option_parse(cb); 452291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt switch (cb->entry->id) { 462291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt case O_PHYSDEV_IN: 472291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt xtables_parse_interface(cb->arg, info->physindev, 48efa8fc2123a2a9fc229ab471edd2b2688ce1da3aHarald Welte (unsigned char *)info->in_mask); 492291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt if (cb->invert) 50fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI info->invert |= XT_PHYSDEV_OP_IN; 51fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI info->bitmask |= XT_PHYSDEV_OP_IN; 521254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer break; 532291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt case O_PHYSDEV_OUT: 542291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt xtables_parse_interface(cb->arg, info->physoutdev, 55efa8fc2123a2a9fc229ab471edd2b2688ce1da3aHarald Welte (unsigned char *)info->out_mask); 562291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt if (cb->invert) 57fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI info->invert |= XT_PHYSDEV_OP_OUT; 58fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI info->bitmask |= XT_PHYSDEV_OP_OUT; 5930596a5e7ae8c518a8a0bbf3aa891728e9f9ec1bBart De Schuymer break; 602291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt case O_PHYSDEV_IS_IN: 61fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI info->bitmask |= XT_PHYSDEV_OP_ISIN; 622291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt if (cb->invert) 63fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI info->invert |= XT_PHYSDEV_OP_ISIN; 6430596a5e7ae8c518a8a0bbf3aa891728e9f9ec1bBart De Schuymer break; 652291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt case O_PHYSDEV_IS_OUT: 66fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI info->bitmask |= XT_PHYSDEV_OP_ISOUT; 672291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt if (cb->invert) 68fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI info->invert |= XT_PHYSDEV_OP_ISOUT; 6930596a5e7ae8c518a8a0bbf3aa891728e9f9ec1bBart De Schuymer break; 702291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt case O_PHYSDEV_IS_BRIDGED: 712291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt if (cb->invert) 72fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI info->invert |= XT_PHYSDEV_OP_BRIDGED; 73fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI info->bitmask |= XT_PHYSDEV_OP_BRIDGED; 741254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer break; 751254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer } 761254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer} 771254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer 782291d887cea2412af380f1ae995ddfee0362386bJan Engelhardtstatic void physdev_check(struct xt_fcheck_call *cb) 791254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer{ 802291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt if (cb->xflags == 0) 811829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt xtables_error(PARAMETER_PROBLEM, "PHYSDEV: no physdev option specified"); 821254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer} 831254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer 841254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymerstatic void 85181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtphysdev_print(const void *ip, const struct xt_entry_match *match, int numeric) 861254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer{ 8769f564e3890976461de0016cd81171ff8bfa8353Jan Engelhardt const struct xt_physdev_info *info = (const void *)match->data; 881254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer 8973866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" PHYSDEV match"); 90fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI if (info->bitmask & XT_PHYSDEV_OP_ISIN) 9130596a5e7ae8c518a8a0bbf3aa891728e9f9ec1bBart De Schuymer printf("%s --physdev-is-in", 92fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI info->invert & XT_PHYSDEV_OP_ISIN ? " !":""); 93fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI if (info->bitmask & XT_PHYSDEV_OP_IN) 9430596a5e7ae8c518a8a0bbf3aa891728e9f9ec1bBart De Schuymer printf("%s --physdev-in %s", 95fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI (info->invert & XT_PHYSDEV_OP_IN) ? " !":"", info->physindev); 9630596a5e7ae8c518a8a0bbf3aa891728e9f9ec1bBart De Schuymer 97fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI if (info->bitmask & XT_PHYSDEV_OP_ISOUT) 9830596a5e7ae8c518a8a0bbf3aa891728e9f9ec1bBart De Schuymer printf("%s --physdev-is-out", 99fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI info->invert & XT_PHYSDEV_OP_ISOUT ? " !":""); 100fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI if (info->bitmask & XT_PHYSDEV_OP_OUT) 10130596a5e7ae8c518a8a0bbf3aa891728e9f9ec1bBart De Schuymer printf("%s --physdev-out %s", 102fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI (info->invert & XT_PHYSDEV_OP_OUT) ? " !":"", info->physoutdev); 103fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI if (info->bitmask & XT_PHYSDEV_OP_BRIDGED) 10430596a5e7ae8c518a8a0bbf3aa891728e9f9ec1bBart De Schuymer printf("%s --physdev-is-bridged", 105fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI info->invert & XT_PHYSDEV_OP_BRIDGED ? " !":""); 1061254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer} 1071254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer 108181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic void physdev_save(const void *ip, const struct xt_entry_match *match) 1091254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer{ 11069f564e3890976461de0016cd81171ff8bfa8353Jan Engelhardt const struct xt_physdev_info *info = (const void *)match->data; 1111254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer 112fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI if (info->bitmask & XT_PHYSDEV_OP_ISIN) 11373866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf("%s --physdev-is-in", 11473866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt (info->invert & XT_PHYSDEV_OP_ISIN) ? " !" : ""); 115fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI if (info->bitmask & XT_PHYSDEV_OP_IN) 11673866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf("%s --physdev-in %s", 11773866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt (info->invert & XT_PHYSDEV_OP_IN) ? " !" : "", 118d38eaf488dcd9c78d1ea7c1b9613d210688114afJan Engelhardt info->physindev); 11930596a5e7ae8c518a8a0bbf3aa891728e9f9ec1bBart De Schuymer 120fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI if (info->bitmask & XT_PHYSDEV_OP_ISOUT) 12173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf("%s --physdev-is-out", 12273866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt (info->invert & XT_PHYSDEV_OP_ISOUT) ? " !" : ""); 123fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI if (info->bitmask & XT_PHYSDEV_OP_OUT) 12473866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf("%s --physdev-out %s", 12573866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt (info->invert & XT_PHYSDEV_OP_OUT) ? " !" : "", 126d38eaf488dcd9c78d1ea7c1b9613d210688114afJan Engelhardt info->physoutdev); 127fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI if (info->bitmask & XT_PHYSDEV_OP_BRIDGED) 12873866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf("%s --physdev-is-bridged", 12973866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt (info->invert & XT_PHYSDEV_OP_BRIDGED) ? " !" : ""); 1301254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer} 1311254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer 132181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic struct xtables_match physdev_match = { 133c5e85736c207f211d82d2878a5781f512327dfceJan Engelhardt .family = NFPROTO_UNSPEC, 134fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI .name = "physdev", 1358b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt .version = XTABLES_VERSION, 136fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI .size = XT_ALIGN(sizeof(struct xt_physdev_info)), 137fec77fed67feb55aba4c33ae2367178c57ce83deYasuyuki KOZAKAI .userspacesize = XT_ALIGN(sizeof(struct xt_physdev_info)), 138181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .help = physdev_help, 139181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .print = physdev_print, 140181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .save = physdev_save, 1412291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt .x6_parse = physdev_parse, 1422291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt .x6_fcheck = physdev_check, 1432291d887cea2412af380f1ae995ddfee0362386bJan Engelhardt .x6_options = physdev_opts, 1441254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer}; 1451254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer 1461254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymervoid _init(void) 1471254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer{ 148181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt xtables_register_match(&physdev_match); 1491254871c88483cc1a0adc448a83cab6a9d4510a1Bart De Schuymer} 150