blob: a11faf40b7c80d39e5efacc4e51bc66ab95d2732 [file] [log] [blame]
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +00001#include <stdio.h>
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +00002#include <xtables.h>
3#include <linux/netfilter/xt_physdev.h>
Jan Engelhardt2291d882011-03-02 19:09:38 +01004
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};
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000012
Jan Engelhardt181dead2007-10-04 16:27:07 +000013static void physdev_help(void)
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000014{
15 printf(
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020016"physdev match options:\n"
Jan Engelhardt96727922008-08-13 14:42:41 +020017" [!] --physdev-in inputname[+] bridge port name ([+] for wildcard)\n"
18" [!] --physdev-out outputname[+] bridge port name ([+] for wildcard)\n"
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000019" [!] --physdev-is-in arrived on a bridge device\n"
20" [!] --physdev-is-out will leave on a bridge device\n"
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020021" [!] --physdev-is-bridged it's a bridged packet\n");
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000022}
23
Jan Engelhardt2291d882011-03-02 19:09:38 +010024#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)},
Jan Engelhardtc2a47ea2011-08-21 12:27:06 +020030 {.name = "physdev-is-in", .id = O_PHYSDEV_IS_IN, .type = XTTYPE_NONE,
31 .flags = XTOPT_INVERT},
Jan Engelhardt2291d882011-03-02 19:09:38 +010032 {.name = "physdev-is-out", .id = O_PHYSDEV_IS_OUT,
Jan Engelhardtc2a47ea2011-08-21 12:27:06 +020033 .type = XTTYPE_NONE, .flags = XTOPT_INVERT},
Jan Engelhardt2291d882011-03-02 19:09:38 +010034 {.name = "physdev-is-bridged", .id = O_PHYSDEV_IS_BRIDGED,
Jan Engelhardtc2a47ea2011-08-21 12:27:06 +020035 .type = XTTYPE_NONE, .flags = XTOPT_INVERT},
Jan Engelhardt2291d882011-03-02 19:09:38 +010036 XTOPT_TABLEEND,
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000037};
Jan Engelhardt2291d882011-03-02 19:09:38 +010038#undef s
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000039
Jan Engelhardt2291d882011-03-02 19:09:38 +010040static void physdev_parse(struct xt_option_call *cb)
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000041{
Jan Engelhardt2291d882011-03-02 19:09:38 +010042 struct xt_physdev_info *info = cb->data;
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000043
Jan Engelhardt2291d882011-03-02 19:09:38 +010044 xtables_option_parse(cb);
45 switch (cb->entry->id) {
46 case O_PHYSDEV_IN:
47 xtables_parse_interface(cb->arg, info->physindev,
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000048 (unsigned char *)info->in_mask);
Jan Engelhardt2291d882011-03-02 19:09:38 +010049 if (cb->invert)
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000050 info->invert |= XT_PHYSDEV_OP_IN;
51 info->bitmask |= XT_PHYSDEV_OP_IN;
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000052 break;
Jan Engelhardt2291d882011-03-02 19:09:38 +010053 case O_PHYSDEV_OUT:
54 xtables_parse_interface(cb->arg, info->physoutdev,
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000055 (unsigned char *)info->out_mask);
Jan Engelhardt2291d882011-03-02 19:09:38 +010056 if (cb->invert)
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000057 info->invert |= XT_PHYSDEV_OP_OUT;
58 info->bitmask |= XT_PHYSDEV_OP_OUT;
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000059 break;
Jan Engelhardt2291d882011-03-02 19:09:38 +010060 case O_PHYSDEV_IS_IN:
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000061 info->bitmask |= XT_PHYSDEV_OP_ISIN;
Jan Engelhardt2291d882011-03-02 19:09:38 +010062 if (cb->invert)
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000063 info->invert |= XT_PHYSDEV_OP_ISIN;
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000064 break;
Jan Engelhardt2291d882011-03-02 19:09:38 +010065 case O_PHYSDEV_IS_OUT:
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000066 info->bitmask |= XT_PHYSDEV_OP_ISOUT;
Jan Engelhardt2291d882011-03-02 19:09:38 +010067 if (cb->invert)
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000068 info->invert |= XT_PHYSDEV_OP_ISOUT;
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000069 break;
Jan Engelhardt2291d882011-03-02 19:09:38 +010070 case O_PHYSDEV_IS_BRIDGED:
71 if (cb->invert)
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000072 info->invert |= XT_PHYSDEV_OP_BRIDGED;
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000073 info->bitmask |= XT_PHYSDEV_OP_BRIDGED;
74 break;
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000075 }
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000076}
77
Jan Engelhardt2291d882011-03-02 19:09:38 +010078static void physdev_check(struct xt_fcheck_call *cb)
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000079{
Jan Engelhardt2291d882011-03-02 19:09:38 +010080 if (cb->xflags == 0)
Jan Engelhardt1829ed42009-02-21 03:29:44 +010081 xtables_error(PARAMETER_PROBLEM, "PHYSDEV: no physdev option specified");
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000082}
83
84static void
Jan Engelhardt181dead2007-10-04 16:27:07 +000085physdev_print(const void *ip, const struct xt_entry_match *match, int numeric)
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000086{
Jan Engelhardt69f564e2009-05-26 13:14:06 +020087 const struct xt_physdev_info *info = (const void *)match->data;
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000088
Jan Engelhardt73866352010-12-18 02:04:59 +010089 printf(" PHYSDEV match");
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000090 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 KOZAKAIfec77fe2007-07-24 07:06:57 +0000106}
107
Jan Engelhardt181dead2007-10-04 16:27:07 +0000108static void physdev_save(const void *ip, const struct xt_entry_match *match)
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +0000109{
Jan Engelhardt69f564e2009-05-26 13:14:06 +0200110 const struct xt_physdev_info *info = (const void *)match->data;
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +0000111
112 if (info->bitmask & XT_PHYSDEV_OP_ISIN)
Jan Engelhardt73866352010-12-18 02:04:59 +0100113 printf("%s --physdev-is-in",
114 (info->invert & XT_PHYSDEV_OP_ISIN) ? " !" : "");
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +0000115 if (info->bitmask & XT_PHYSDEV_OP_IN)
Jan Engelhardt73866352010-12-18 02:04:59 +0100116 printf("%s --physdev-in %s",
117 (info->invert & XT_PHYSDEV_OP_IN) ? " !" : "",
Jan Engelhardtd38eaf42008-08-13 14:40:18 +0200118 info->physindev);
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +0000119
120 if (info->bitmask & XT_PHYSDEV_OP_ISOUT)
Jan Engelhardt73866352010-12-18 02:04:59 +0100121 printf("%s --physdev-is-out",
122 (info->invert & XT_PHYSDEV_OP_ISOUT) ? " !" : "");
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +0000123 if (info->bitmask & XT_PHYSDEV_OP_OUT)
Jan Engelhardt73866352010-12-18 02:04:59 +0100124 printf("%s --physdev-out %s",
125 (info->invert & XT_PHYSDEV_OP_OUT) ? " !" : "",
Jan Engelhardtd38eaf42008-08-13 14:40:18 +0200126 info->physoutdev);
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +0000127 if (info->bitmask & XT_PHYSDEV_OP_BRIDGED)
Jan Engelhardt73866352010-12-18 02:04:59 +0100128 printf("%s --physdev-is-bridged",
129 (info->invert & XT_PHYSDEV_OP_BRIDGED) ? " !" : "");
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +0000130}
131
Jan Engelhardt181dead2007-10-04 16:27:07 +0000132static struct xtables_match physdev_match = {
Jan Engelhardtc5e85732009-06-12 20:55:44 +0200133 .family = NFPROTO_UNSPEC,
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +0000134 .name = "physdev",
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200135 .version = XTABLES_VERSION,
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +0000136 .size = XT_ALIGN(sizeof(struct xt_physdev_info)),
137 .userspacesize = XT_ALIGN(sizeof(struct xt_physdev_info)),
Jan Engelhardt181dead2007-10-04 16:27:07 +0000138 .help = physdev_help,
Jan Engelhardt181dead2007-10-04 16:27:07 +0000139 .print = physdev_print,
140 .save = physdev_save,
Jan Engelhardt2291d882011-03-02 19:09:38 +0100141 .x6_parse = physdev_parse,
142 .x6_fcheck = physdev_check,
143 .x6_options = physdev_opts,
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +0000144};
145
146void _init(void)
147{
Jan Engelhardt181dead2007-10-04 16:27:07 +0000148 xtables_register_match(&physdev_match);
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +0000149}