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)}, |
Jan Engelhardt | c2a47ea | 2011-08-21 12:27:06 +0200 | [diff] [blame] | 30 | {.name = "physdev-is-in", .id = O_PHYSDEV_IS_IN, .type = XTTYPE_NONE, |
| 31 | .flags = XTOPT_INVERT}, |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 32 | {.name = "physdev-is-out", .id = O_PHYSDEV_IS_OUT, |
Jan Engelhardt | c2a47ea | 2011-08-21 12:27:06 +0200 | [diff] [blame] | 33 | .type = XTTYPE_NONE, .flags = XTOPT_INVERT}, |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 34 | {.name = "physdev-is-bridged", .id = O_PHYSDEV_IS_BRIDGED, |
Jan Engelhardt | c2a47ea | 2011-08-21 12:27:06 +0200 | [diff] [blame] | 35 | .type = XTTYPE_NONE, .flags = XTOPT_INVERT}, |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 36 | XTOPT_TABLEEND, |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 37 | }; |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 38 | #undef s |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 39 | |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 40 | static void physdev_parse(struct xt_option_call *cb) |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 41 | { |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 42 | struct xt_physdev_info *info = cb->data; |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 43 | |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 44 | xtables_option_parse(cb); |
| 45 | switch (cb->entry->id) { |
| 46 | case O_PHYSDEV_IN: |
| 47 | xtables_parse_interface(cb->arg, info->physindev, |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 48 | (unsigned char *)info->in_mask); |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 49 | if (cb->invert) |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 50 | info->invert |= XT_PHYSDEV_OP_IN; |
| 51 | info->bitmask |= XT_PHYSDEV_OP_IN; |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 52 | break; |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 53 | case O_PHYSDEV_OUT: |
| 54 | xtables_parse_interface(cb->arg, info->physoutdev, |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 55 | (unsigned char *)info->out_mask); |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 56 | if (cb->invert) |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 57 | info->invert |= XT_PHYSDEV_OP_OUT; |
| 58 | info->bitmask |= XT_PHYSDEV_OP_OUT; |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 59 | break; |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 60 | case O_PHYSDEV_IS_IN: |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 61 | info->bitmask |= XT_PHYSDEV_OP_ISIN; |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 62 | if (cb->invert) |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 63 | info->invert |= XT_PHYSDEV_OP_ISIN; |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 64 | break; |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 65 | case O_PHYSDEV_IS_OUT: |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 66 | info->bitmask |= XT_PHYSDEV_OP_ISOUT; |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 67 | if (cb->invert) |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 68 | info->invert |= XT_PHYSDEV_OP_ISOUT; |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 69 | break; |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 70 | case O_PHYSDEV_IS_BRIDGED: |
| 71 | if (cb->invert) |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 72 | info->invert |= XT_PHYSDEV_OP_BRIDGED; |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 73 | info->bitmask |= XT_PHYSDEV_OP_BRIDGED; |
| 74 | break; |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 75 | } |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 76 | } |
| 77 | |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 78 | static void physdev_check(struct xt_fcheck_call *cb) |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 79 | { |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 80 | if (cb->xflags == 0) |
Jan Engelhardt | 1829ed4 | 2009-02-21 03:29:44 +0100 | [diff] [blame] | 81 | xtables_error(PARAMETER_PROBLEM, "PHYSDEV: no physdev option specified"); |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 82 | } |
| 83 | |
| 84 | static void |
Jan Engelhardt | 181dead | 2007-10-04 16:27:07 +0000 | [diff] [blame] | 85 | 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] | 86 | { |
Jan Engelhardt | 69f564e | 2009-05-26 13:14:06 +0200 | [diff] [blame] | 87 | const struct xt_physdev_info *info = (const void *)match->data; |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 88 | |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 89 | printf(" PHYSDEV match"); |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 90 | if (info->bitmask & XT_PHYSDEV_OP_ISIN) |
| 91 | printf("%s --physdev-is-in", |
| 92 | info->invert & XT_PHYSDEV_OP_ISIN ? " !":""); |
| 93 | if (info->bitmask & XT_PHYSDEV_OP_IN) |
| 94 | printf("%s --physdev-in %s", |
| 95 | (info->invert & XT_PHYSDEV_OP_IN) ? " !":"", info->physindev); |
| 96 | |
| 97 | if (info->bitmask & XT_PHYSDEV_OP_ISOUT) |
| 98 | printf("%s --physdev-is-out", |
| 99 | info->invert & XT_PHYSDEV_OP_ISOUT ? " !":""); |
| 100 | if (info->bitmask & XT_PHYSDEV_OP_OUT) |
| 101 | printf("%s --physdev-out %s", |
| 102 | (info->invert & XT_PHYSDEV_OP_OUT) ? " !":"", info->physoutdev); |
| 103 | if (info->bitmask & XT_PHYSDEV_OP_BRIDGED) |
| 104 | printf("%s --physdev-is-bridged", |
| 105 | info->invert & XT_PHYSDEV_OP_BRIDGED ? " !":""); |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 106 | } |
| 107 | |
Jan Engelhardt | 181dead | 2007-10-04 16:27:07 +0000 | [diff] [blame] | 108 | 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] | 109 | { |
Jan Engelhardt | 69f564e | 2009-05-26 13:14:06 +0200 | [diff] [blame] | 110 | const struct xt_physdev_info *info = (const void *)match->data; |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 111 | |
| 112 | if (info->bitmask & XT_PHYSDEV_OP_ISIN) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 113 | printf("%s --physdev-is-in", |
| 114 | (info->invert & XT_PHYSDEV_OP_ISIN) ? " !" : ""); |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 115 | if (info->bitmask & XT_PHYSDEV_OP_IN) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 116 | printf("%s --physdev-in %s", |
| 117 | (info->invert & XT_PHYSDEV_OP_IN) ? " !" : "", |
Jan Engelhardt | d38eaf4 | 2008-08-13 14:40:18 +0200 | [diff] [blame] | 118 | info->physindev); |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 119 | |
| 120 | if (info->bitmask & XT_PHYSDEV_OP_ISOUT) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 121 | printf("%s --physdev-is-out", |
| 122 | (info->invert & XT_PHYSDEV_OP_ISOUT) ? " !" : ""); |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 123 | if (info->bitmask & XT_PHYSDEV_OP_OUT) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 124 | printf("%s --physdev-out %s", |
| 125 | (info->invert & XT_PHYSDEV_OP_OUT) ? " !" : "", |
Jan Engelhardt | d38eaf4 | 2008-08-13 14:40:18 +0200 | [diff] [blame] | 126 | info->physoutdev); |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 127 | if (info->bitmask & XT_PHYSDEV_OP_BRIDGED) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 128 | printf("%s --physdev-is-bridged", |
| 129 | (info->invert & XT_PHYSDEV_OP_BRIDGED) ? " !" : ""); |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 130 | } |
| 131 | |
Jan Engelhardt | 181dead | 2007-10-04 16:27:07 +0000 | [diff] [blame] | 132 | static struct xtables_match physdev_match = { |
Jan Engelhardt | c5e8573 | 2009-06-12 20:55:44 +0200 | [diff] [blame] | 133 | .family = NFPROTO_UNSPEC, |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 134 | .name = "physdev", |
Jan Engelhardt | 8b7c64d | 2008-04-15 11:48:25 +0200 | [diff] [blame] | 135 | .version = XTABLES_VERSION, |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 136 | .size = XT_ALIGN(sizeof(struct xt_physdev_info)), |
| 137 | .userspacesize = XT_ALIGN(sizeof(struct xt_physdev_info)), |
Jan Engelhardt | 181dead | 2007-10-04 16:27:07 +0000 | [diff] [blame] | 138 | .help = physdev_help, |
Jan Engelhardt | 181dead | 2007-10-04 16:27:07 +0000 | [diff] [blame] | 139 | .print = physdev_print, |
| 140 | .save = physdev_save, |
Jan Engelhardt | 2291d88 | 2011-03-02 19:09:38 +0100 | [diff] [blame] | 141 | .x6_parse = physdev_parse, |
| 142 | .x6_fcheck = physdev_check, |
| 143 | .x6_options = physdev_opts, |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 144 | }; |
| 145 | |
| 146 | void _init(void) |
| 147 | { |
Jan Engelhardt | 181dead | 2007-10-04 16:27:07 +0000 | [diff] [blame] | 148 | xtables_register_match(&physdev_match); |
Yasuyuki KOZAKAI | fec77fe | 2007-07-24 07:06:57 +0000 | [diff] [blame] | 149 | } |