• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *	"TEE" target extension for iptables
3  *	Copyright © Sebastian Claßen <sebastian.classen [at] freenet.ag>, 2007
4  *	Jan Engelhardt <jengelh [at] medozas de>, 2007 - 2010
5  *
6  *	This program is free software; you can redistribute it and/or
7  *	modify it under the terms of the GNU General Public License; either
8  *	version 2 of the License, or any later version, as published by the
9  *	Free Software Foundation.
10  */
11 #include <sys/socket.h>
12 #include <getopt.h>
13 #include <stdbool.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 
18 #include <arpa/inet.h>
19 #include <net/if.h>
20 #include <netinet/in.h>
21 
22 #include <xtables.h>
23 #include <linux/netfilter.h>
24 #include <linux/netfilter/x_tables.h>
25 #include <linux/netfilter/xt_TEE.h>
26 
27 enum {
28 	O_GATEWAY = 0,
29 	O_OIF,
30 };
31 
32 #define s struct xt_tee_tginfo
33 static const struct xt_option_entry tee_tg_opts[] = {
34 	{.name = "gateway", .id = O_GATEWAY, .type = XTTYPE_HOST,
35 	 .flags = XTOPT_MAND | XTOPT_PUT, XTOPT_POINTER(s, gw)},
36 	{.name = "oif", .id = O_OIF, .type = XTTYPE_STRING,
37 	 .flags = XTOPT_PUT, XTOPT_POINTER(s, oif)},
38 	XTOPT_TABLEEND,
39 };
40 #undef s
41 
tee_tg_help(void)42 static void tee_tg_help(void)
43 {
44 	printf(
45 "TEE target options:\n"
46 "  --gateway IPADDR    Route packet via the gateway given by address\n"
47 "  --oif NAME          Include oif in route calculation\n"
48 "\n");
49 }
50 
tee_tg_print(const void * ip,const struct xt_entry_target * target,int numeric)51 static void tee_tg_print(const void *ip, const struct xt_entry_target *target,
52                          int numeric)
53 {
54 	const struct xt_tee_tginfo *info = (const void *)target->data;
55 
56 	if (numeric)
57 		printf(" TEE gw:%s", xtables_ipaddr_to_numeric(&info->gw.in));
58 	else
59 		printf(" TEE gw:%s", xtables_ipaddr_to_anyname(&info->gw.in));
60 	if (*info->oif != '\0')
61 		printf(" oif=%s", info->oif);
62 }
63 
tee_tg6_print(const void * ip,const struct xt_entry_target * target,int numeric)64 static void tee_tg6_print(const void *ip, const struct xt_entry_target *target,
65                           int numeric)
66 {
67 	const struct xt_tee_tginfo *info = (const void *)target->data;
68 
69 	if (numeric)
70 		printf(" TEE gw:%s", xtables_ip6addr_to_numeric(&info->gw.in6));
71 	else
72 		printf(" TEE gw:%s", xtables_ip6addr_to_anyname(&info->gw.in6));
73 	if (*info->oif != '\0')
74 		printf(" oif=%s", info->oif);
75 }
76 
tee_tg_save(const void * ip,const struct xt_entry_target * target)77 static void tee_tg_save(const void *ip, const struct xt_entry_target *target)
78 {
79 	const struct xt_tee_tginfo *info = (const void *)target->data;
80 
81 	printf(" --gateway %s", xtables_ipaddr_to_numeric(&info->gw.in));
82 	if (*info->oif != '\0')
83 		printf(" --oif %s", info->oif);
84 }
85 
tee_tg6_save(const void * ip,const struct xt_entry_target * target)86 static void tee_tg6_save(const void *ip, const struct xt_entry_target *target)
87 {
88 	const struct xt_tee_tginfo *info = (const void *)target->data;
89 
90 	printf(" --gateway %s", xtables_ip6addr_to_numeric(&info->gw.in6));
91 	if (*info->oif != '\0')
92 		printf(" --oif %s", info->oif);
93 }
94 
tee_tg_xlate(struct xt_xlate * xl,const struct xt_xlate_tg_params * params)95 static int tee_tg_xlate(struct xt_xlate *xl,
96 			const struct xt_xlate_tg_params *params)
97 {
98 	const struct xt_tee_tginfo *info = (const void *)params->target->data;
99 
100 	if (params->numeric)
101 		xt_xlate_add(xl, "dup to %s",
102 			     xtables_ipaddr_to_numeric(&info->gw.in));
103 	else
104 		xt_xlate_add(xl, "dup to %s",
105 			     xtables_ipaddr_to_anyname(&info->gw.in));
106 	if (*info->oif != '\0')
107 		xt_xlate_add(xl, " device %s", info->oif);
108 
109 	return 1;
110 }
111 
tee_tg6_xlate(struct xt_xlate * xl,const struct xt_xlate_tg_params * params)112 static int tee_tg6_xlate(struct xt_xlate *xl,
113 			 const struct xt_xlate_tg_params *params)
114 {
115 	const struct xt_tee_tginfo *info = (const void *)params->target->data;
116 
117 	if (params->numeric)
118 		xt_xlate_add(xl, "dup to %s",
119 			     xtables_ip6addr_to_numeric(&info->gw.in6));
120 	else
121 		xt_xlate_add(xl, "dup to %s",
122 			     xtables_ip6addr_to_anyname(&info->gw.in6));
123 	if (*info->oif != '\0')
124 		xt_xlate_add(xl, " device %s", info->oif);
125 
126 	return 1;
127 }
128 
129 static struct xtables_target tee_tg_reg[] = {
130 	{
131 		.name          = "TEE",
132 		.version       = XTABLES_VERSION,
133 		.revision      = 1,
134 		.family        = NFPROTO_IPV4,
135 		.size          = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
136 		.userspacesize = offsetof(struct xt_tee_tginfo, priv),
137 		.help          = tee_tg_help,
138 		.print         = tee_tg_print,
139 		.save          = tee_tg_save,
140 		.x6_parse      = xtables_option_parse,
141 		.x6_options    = tee_tg_opts,
142 		.xlate         = tee_tg_xlate,
143 	},
144 	{
145 		.name          = "TEE",
146 		.version       = XTABLES_VERSION,
147 		.revision      = 1,
148 		.family        = NFPROTO_IPV6,
149 		.size          = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
150 		.userspacesize = offsetof(struct xt_tee_tginfo, priv),
151 		.help          = tee_tg_help,
152 		.print         = tee_tg6_print,
153 		.save          = tee_tg6_save,
154 		.x6_parse      = xtables_option_parse,
155 		.x6_options    = tee_tg_opts,
156 		.xlate         = tee_tg6_xlate,
157 	},
158 };
159 
_init(void)160 void _init(void)
161 {
162 	xtables_register_targets(tee_tg_reg, ARRAY_SIZE(tee_tg_reg));
163 }
164