Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 1 | #include <stdio.h> |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 2 | #include <xtables.h> |
| 3 | #include <linux/netfilter/xt_physdev.h> |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 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 | }; |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 12 | |
Jan Engelhardt | 181dead | 2007-10-04 16:27:07 +0000 | [diff] [blame] | 13 | static void physdev_help(void) |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 14 | { |
| 15 | printf( |
Jan Engelhardt | 8b7c64d | 2008-04-15 11:48:25 +0200 | [diff] [blame] | 16 | "physdev match options:\n" |
Jan Engelhardt | 9672792 | 2008-08-13 14:42:41 +0200 | [diff] [blame] | 17 | " [!] --physdev-in inputname[+] bridge port name ([+] for wildcard)\n" |
| 18 | " [!] --physdev-out outputname[+] bridge port name ([+] for wildcard)\n" |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 19 | " [!] --physdev-is-in arrived on a bridge device\n" |
| 20 | " [!] --physdev-is-out will leave on a bridge device\n" |
Jan Engelhardt | 8b7c64d | 2008-04-15 11:48:25 +0200 | [diff] [blame] | 21 | " [!] --physdev-is-bridged it's a bridged packet\n"); |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 22 | } |
| 23 | |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 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, |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 36 | }; |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 37 | #undef s |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 38 | |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 39 | static void physdev_parse(struct xt_option_call *cb) |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 40 | { |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 41 | struct xt_physdev_info *info = cb->data; |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 42 | |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 43 | xtables_option_parse(cb); |
| 44 | switch (cb->entry->id) { |
| 45 | case O_PHYSDEV_IN: |
| 46 | xtables_parse_interface(cb->arg, info->physindev, |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 47 | (unsigned char *)info->in_mask); |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 48 | if (cb->invert) |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 49 | info->invert |= XT_PHYSDEV_OP_IN; |
| 50 | info->bitmask |= XT_PHYSDEV_OP_IN; |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 51 | break; |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 52 | case O_PHYSDEV_OUT: |
| 53 | xtables_parse_interface(cb->arg, info->physoutdev, |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 54 | (unsigned char *)info->out_mask); |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 55 | if (cb->invert) |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 56 | info->invert |= XT_PHYSDEV_OP_OUT; |
| 57 | info->bitmask |= XT_PHYSDEV_OP_OUT; |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 58 | break; |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 59 | case O_PHYSDEV_IS_IN: |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 60 | info->bitmask |= XT_PHYSDEV_OP_ISIN; |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 61 | if (cb->invert) |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 62 | info->invert |= XT_PHYSDEV_OP_ISIN; |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 63 | break; |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 64 | case O_PHYSDEV_IS_OUT: |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 65 | info->bitmask |= XT_PHYSDEV_OP_ISOUT; |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 66 | if (cb->invert) |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 67 | info->invert |= XT_PHYSDEV_OP_ISOUT; |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 68 | break; |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 69 | case O_PHYSDEV_IS_BRIDGED: |
| 70 | if (cb->invert) |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 71 | info->invert |= XT_PHYSDEV_OP_BRIDGED; |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 72 | info->bitmask |= XT_PHYSDEV_OP_BRIDGED; |
| 73 | break; |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 74 | } |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 75 | } |
| 76 | |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 77 | static void physdev_check(struct xt_fcheck_call *cb) |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 78 | { |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 79 | if (cb->xflags == 0) |
Jan Engelhardt | 1829ed4 | 2009-02-21 03:29:44 +0100 | [diff] [blame] | 80 | xtables_error(PARAMETER_PROBLEM, "PHYSDEV: no physdev option specified"); |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 81 | } |
| 82 | |
| 83 | static void |
Jan Engelhardt | 181dead | 2007-10-04 16:27:07 +0000 | [diff] [blame] | 84 | physdev_print(const void *ip, const struct xt_entry_match *match, int numeric) |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 85 | { |
Jan Engelhardt | 69f564e | 2009-05-26 13:14:06 +0200 | [diff] [blame] | 86 | const struct xt_physdev_info *info = (const void *)match->data; |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 87 | |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 88 | printf(" PHYSDEV match"); |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 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 ? " !":""); |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 105 | } |
| 106 | |
Jan Engelhardt | 181dead | 2007-10-04 16:27:07 +0000 | [diff] [blame] | 107 | static void physdev_save(const void *ip, const struct xt_entry_match *match) |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 108 | { |
Jan Engelhardt | 69f564e | 2009-05-26 13:14:06 +0200 | [diff] [blame] | 109 | const struct xt_physdev_info *info = (const void *)match->data; |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 110 | |
| 111 | if (info->bitmask & XT_PHYSDEV_OP_ISIN) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 112 | printf("%s --physdev-is-in", |
| 113 | (info->invert & XT_PHYSDEV_OP_ISIN) ? " !" : ""); |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 114 | if (info->bitmask & XT_PHYSDEV_OP_IN) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 115 | printf("%s --physdev-in %s", |
| 116 | (info->invert & XT_PHYSDEV_OP_IN) ? " !" : "", |
Jan Engelhardt | d38eaf4 | 2008-08-13 14:40:18 +0200 | [diff] [blame] | 117 | info->physindev); |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 118 | |
| 119 | if (info->bitmask & XT_PHYSDEV_OP_ISOUT) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 120 | printf("%s --physdev-is-out", |
| 121 | (info->invert & XT_PHYSDEV_OP_ISOUT) ? " !" : ""); |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 122 | if (info->bitmask & XT_PHYSDEV_OP_OUT) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 123 | printf("%s --physdev-out %s", |
| 124 | (info->invert & XT_PHYSDEV_OP_OUT) ? " !" : "", |
Jan Engelhardt | d38eaf4 | 2008-08-13 14:40:18 +0200 | [diff] [blame] | 125 | info->physoutdev); |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 126 | if (info->bitmask & XT_PHYSDEV_OP_BRIDGED) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 127 | printf("%s --physdev-is-bridged", |
| 128 | (info->invert & XT_PHYSDEV_OP_BRIDGED) ? " !" : ""); |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 129 | } |
| 130 | |
Jan Engelhardt | 181dead | 2007-10-04 16:27:07 +0000 | [diff] [blame] | 131 | static struct xtables_match physdev_match = { |
Jan Engelhardt | c5e8573 | 2009-06-12 20:55:44 +0200 | [diff] [blame] | 132 | .family = NFPROTO_UNSPEC, |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 133 | .name = "physdev", |
Jan Engelhardt | 8b7c64d | 2008-04-15 11:48:25 +0200 | [diff] [blame] | 134 | .version = XTABLES_VERSION, |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 135 | .size = XT_ALIGN(sizeof(struct xt_physdev_info)), |
| 136 | .userspacesize = XT_ALIGN(sizeof(struct xt_physdev_info)), |
Jan Engelhardt | 181dead | 2007-10-04 16:27:07 +0000 | [diff] [blame] | 137 | .help = physdev_help, |
Jan Engelhardt | 181dead | 2007-10-04 16:27:07 +0000 | [diff] [blame] | 138 | .print = physdev_print, |
| 139 | .save = physdev_save, |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 140 | .x6_parse = physdev_parse, |
| 141 | .x6_fcheck = physdev_check, |
| 142 | .x6_options = physdev_opts, |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 143 | }; |
| 144 | |
| 145 | void _init(void) |
| 146 | { |
Jan Engelhardt | 181dead | 2007-10-04 16:27:07 +0000 | [diff] [blame] | 147 | xtables_register_match(&physdev_match); |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 148 | } |