• 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 	 .flags = XTOPT_INVERT},
32 	{.name = "physdev-is-out", .id = O_PHYSDEV_IS_OUT,
33 	 .type = XTTYPE_NONE, .flags = XTOPT_INVERT},
34 	{.name = "physdev-is-bridged", .id = O_PHYSDEV_IS_BRIDGED,
35 	 .type = XTTYPE_NONE, .flags = XTOPT_INVERT},
36 	XTOPT_TABLEEND,
37 };
38 #undef s
39 
physdev_parse(struct xt_option_call * cb)40 static void physdev_parse(struct xt_option_call *cb)
41 {
42 	struct xt_physdev_info *info = cb->data;
43 
44 	xtables_option_parse(cb);
45 	switch (cb->entry->id) {
46 	case O_PHYSDEV_IN:
47 		xtables_parse_interface(cb->arg, info->physindev,
48 				(unsigned char *)info->in_mask);
49 		if (cb->invert)
50 			info->invert |= XT_PHYSDEV_OP_IN;
51 		info->bitmask |= XT_PHYSDEV_OP_IN;
52 		break;
53 	case O_PHYSDEV_OUT:
54 		xtables_parse_interface(cb->arg, info->physoutdev,
55 				(unsigned char *)info->out_mask);
56 		if (cb->invert)
57 			info->invert |= XT_PHYSDEV_OP_OUT;
58 		info->bitmask |= XT_PHYSDEV_OP_OUT;
59 		break;
60 	case O_PHYSDEV_IS_IN:
61 		info->bitmask |= XT_PHYSDEV_OP_ISIN;
62 		if (cb->invert)
63 			info->invert |= XT_PHYSDEV_OP_ISIN;
64 		break;
65 	case O_PHYSDEV_IS_OUT:
66 		info->bitmask |= XT_PHYSDEV_OP_ISOUT;
67 		if (cb->invert)
68 			info->invert |= XT_PHYSDEV_OP_ISOUT;
69 		break;
70 	case O_PHYSDEV_IS_BRIDGED:
71 		if (cb->invert)
72 			info->invert |= XT_PHYSDEV_OP_BRIDGED;
73 		info->bitmask |= XT_PHYSDEV_OP_BRIDGED;
74 		break;
75 	}
76 }
77 
physdev_check(struct xt_fcheck_call * cb)78 static void physdev_check(struct xt_fcheck_call *cb)
79 {
80 	if (cb->xflags == 0)
81 		xtables_error(PARAMETER_PROBLEM, "PHYSDEV: no physdev option specified");
82 }
83 
84 static void
physdev_print(const void * ip,const struct xt_entry_match * match,int numeric)85 physdev_print(const void *ip, const struct xt_entry_match *match, int numeric)
86 {
87 	const struct xt_physdev_info *info = (const void *)match->data;
88 
89 	printf(" PHYSDEV match");
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 ? " !":"");
106 }
107 
physdev_save(const void * ip,const struct xt_entry_match * match)108 static void physdev_save(const void *ip, const struct xt_entry_match *match)
109 {
110 	const struct xt_physdev_info *info = (const void *)match->data;
111 
112 	if (info->bitmask & XT_PHYSDEV_OP_ISIN)
113 		printf("%s --physdev-is-in",
114 		       (info->invert & XT_PHYSDEV_OP_ISIN) ? " !" : "");
115 	if (info->bitmask & XT_PHYSDEV_OP_IN)
116 		printf("%s --physdev-in %s",
117 		       (info->invert & XT_PHYSDEV_OP_IN) ? " !" : "",
118 		       info->physindev);
119 
120 	if (info->bitmask & XT_PHYSDEV_OP_ISOUT)
121 		printf("%s --physdev-is-out",
122 		       (info->invert & XT_PHYSDEV_OP_ISOUT) ? " !" : "");
123 	if (info->bitmask & XT_PHYSDEV_OP_OUT)
124 		printf("%s --physdev-out %s",
125 		       (info->invert & XT_PHYSDEV_OP_OUT) ? " !" : "",
126 		       info->physoutdev);
127 	if (info->bitmask & XT_PHYSDEV_OP_BRIDGED)
128 		printf("%s --physdev-is-bridged",
129 		       (info->invert & XT_PHYSDEV_OP_BRIDGED) ? " !" : "");
130 }
131 
132 static struct xtables_match physdev_match = {
133 	.family		= NFPROTO_UNSPEC,
134 	.name		= "physdev",
135 	.version	= XTABLES_VERSION,
136 	.size		= XT_ALIGN(sizeof(struct xt_physdev_info)),
137 	.userspacesize	= XT_ALIGN(sizeof(struct xt_physdev_info)),
138 	.help		= physdev_help,
139 	.print		= physdev_print,
140 	.save		= physdev_save,
141 	.x6_parse	= physdev_parse,
142 	.x6_fcheck	= physdev_check,
143 	.x6_options	= physdev_opts,
144 };
145 
_init(void)146 void _init(void)
147 {
148 	xtables_register_match(&physdev_match);
149 }
150