blob: 8f57fe9f235e588e7ef60edd419f20b7d6858af2 [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)},
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 KOZAKAIfec77fe2007-07-24 07:06:57 +000036};
Jan Engelhardt2291d882011-03-02 19:09:38 +010037#undef s
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000038
Jan Engelhardt2291d882011-03-02 19:09:38 +010039static void physdev_parse(struct xt_option_call *cb)
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000040{
Jan Engelhardt2291d882011-03-02 19:09:38 +010041 struct xt_physdev_info *info = cb->data;
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000042
Jan Engelhardt2291d882011-03-02 19:09:38 +010043 xtables_option_parse(cb);
44 switch (cb->entry->id) {
45 case O_PHYSDEV_IN:
46 xtables_parse_interface(cb->arg, info->physindev,
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000047 (unsigned char *)info->in_mask);
Jan Engelhardt2291d882011-03-02 19:09:38 +010048 if (cb->invert)
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000049 info->invert |= XT_PHYSDEV_OP_IN;
50 info->bitmask |= XT_PHYSDEV_OP_IN;
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000051 break;
Jan Engelhardt2291d882011-03-02 19:09:38 +010052 case O_PHYSDEV_OUT:
53 xtables_parse_interface(cb->arg, info->physoutdev,
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000054 (unsigned char *)info->out_mask);
Jan Engelhardt2291d882011-03-02 19:09:38 +010055 if (cb->invert)
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000056 info->invert |= XT_PHYSDEV_OP_OUT;
57 info->bitmask |= XT_PHYSDEV_OP_OUT;
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000058 break;
Jan Engelhardt2291d882011-03-02 19:09:38 +010059 case O_PHYSDEV_IS_IN:
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000060 info->bitmask |= XT_PHYSDEV_OP_ISIN;
Jan Engelhardt2291d882011-03-02 19:09:38 +010061 if (cb->invert)
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000062 info->invert |= XT_PHYSDEV_OP_ISIN;
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000063 break;
Jan Engelhardt2291d882011-03-02 19:09:38 +010064 case O_PHYSDEV_IS_OUT:
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000065 info->bitmask |= XT_PHYSDEV_OP_ISOUT;
Jan Engelhardt2291d882011-03-02 19:09:38 +010066 if (cb->invert)
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000067 info->invert |= XT_PHYSDEV_OP_ISOUT;
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000068 break;
Jan Engelhardt2291d882011-03-02 19:09:38 +010069 case O_PHYSDEV_IS_BRIDGED:
70 if (cb->invert)
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000071 info->invert |= XT_PHYSDEV_OP_BRIDGED;
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000072 info->bitmask |= XT_PHYSDEV_OP_BRIDGED;
73 break;
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000074 }
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000075}
76
Jan Engelhardt2291d882011-03-02 19:09:38 +010077static void physdev_check(struct xt_fcheck_call *cb)
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000078{
Jan Engelhardt2291d882011-03-02 19:09:38 +010079 if (cb->xflags == 0)
Jan Engelhardt1829ed42009-02-21 03:29:44 +010080 xtables_error(PARAMETER_PROBLEM, "PHYSDEV: no physdev option specified");
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000081}
82
83static void
Jan Engelhardt181dead2007-10-04 16:27:07 +000084physdev_print(const void *ip, const struct xt_entry_match *match, int numeric)
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000085{
Jan Engelhardt69f564e2009-05-26 13:14:06 +020086 const struct xt_physdev_info *info = (const void *)match->data;
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000087
Jan Engelhardt73866352010-12-18 02:04:59 +010088 printf(" PHYSDEV match");
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +000089 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 KOZAKAIfec77fe2007-07-24 07:06:57 +0000105}
106
Jan Engelhardt181dead2007-10-04 16:27:07 +0000107static void physdev_save(const void *ip, const struct xt_entry_match *match)
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +0000108{
Jan Engelhardt69f564e2009-05-26 13:14:06 +0200109 const struct xt_physdev_info *info = (const void *)match->data;
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +0000110
111 if (info->bitmask & XT_PHYSDEV_OP_ISIN)
Jan Engelhardt73866352010-12-18 02:04:59 +0100112 printf("%s --physdev-is-in",
113 (info->invert & XT_PHYSDEV_OP_ISIN) ? " !" : "");
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +0000114 if (info->bitmask & XT_PHYSDEV_OP_IN)
Jan Engelhardt73866352010-12-18 02:04:59 +0100115 printf("%s --physdev-in %s",
116 (info->invert & XT_PHYSDEV_OP_IN) ? " !" : "",
Jan Engelhardtd38eaf42008-08-13 14:40:18 +0200117 info->physindev);
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +0000118
119 if (info->bitmask & XT_PHYSDEV_OP_ISOUT)
Jan Engelhardt73866352010-12-18 02:04:59 +0100120 printf("%s --physdev-is-out",
121 (info->invert & XT_PHYSDEV_OP_ISOUT) ? " !" : "");
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +0000122 if (info->bitmask & XT_PHYSDEV_OP_OUT)
Jan Engelhardt73866352010-12-18 02:04:59 +0100123 printf("%s --physdev-out %s",
124 (info->invert & XT_PHYSDEV_OP_OUT) ? " !" : "",
Jan Engelhardtd38eaf42008-08-13 14:40:18 +0200125 info->physoutdev);
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +0000126 if (info->bitmask & XT_PHYSDEV_OP_BRIDGED)
Jan Engelhardt73866352010-12-18 02:04:59 +0100127 printf("%s --physdev-is-bridged",
128 (info->invert & XT_PHYSDEV_OP_BRIDGED) ? " !" : "");
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +0000129}
130
Jan Engelhardt181dead2007-10-04 16:27:07 +0000131static struct xtables_match physdev_match = {
Jan Engelhardtc5e85732009-06-12 20:55:44 +0200132 .family = NFPROTO_UNSPEC,
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +0000133 .name = "physdev",
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200134 .version = XTABLES_VERSION,
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +0000135 .size = XT_ALIGN(sizeof(struct xt_physdev_info)),
136 .userspacesize = XT_ALIGN(sizeof(struct xt_physdev_info)),
Jan Engelhardt181dead2007-10-04 16:27:07 +0000137 .help = physdev_help,
Jan Engelhardt181dead2007-10-04 16:27:07 +0000138 .print = physdev_print,
139 .save = physdev_save,
Jan Engelhardt2291d882011-03-02 19:09:38 +0100140 .x6_parse = physdev_parse,
141 .x6_fcheck = physdev_check,
142 .x6_options = physdev_opts,
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +0000143};
144
145void _init(void)
146{
Jan Engelhardt181dead2007-10-04 16:27:07 +0000147 xtables_register_match(&physdev_match);
Yasuyuki KOZAKAIfec77fe2007-07-24 07:06:57 +0000148}