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