18532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy/*
28532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy *	"TEE" target extension for iptables
38532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy *	Copyright © Sebastian Claßen <sebastian.classen [at] freenet.ag>, 2007
48532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy *	Jan Engelhardt <jengelh [at] medozas de>, 2007 - 2010
58532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy *
68532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy *	This program is free software; you can redistribute it and/or
78532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy *	modify it under the terms of the GNU General Public License; either
88532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy *	version 2 of the License, or any later version, as published by the
98532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy *	Free Software Foundation.
108532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy */
118532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy#include <sys/socket.h>
128532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy#include <getopt.h>
138532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy#include <stdbool.h>
148532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy#include <stdio.h>
158532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy#include <stdlib.h>
168532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy#include <string.h>
178532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy
188532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy#include <arpa/inet.h>
198532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy#include <net/if.h>
208532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy#include <netinet/in.h>
218532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy
228532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy#include <xtables.h>
238532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy#include <linux/netfilter.h>
248532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy#include <linux/netfilter/x_tables.h>
258532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy#include <linux/netfilter/xt_TEE.h>
268532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy
278532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardyenum {
28d44c31ac8e52f34e058f44aba14f679abcc7edf9Jan Engelhardt	O_GATEWAY = 0,
29d44c31ac8e52f34e058f44aba14f679abcc7edf9Jan Engelhardt	O_OIF,
308532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy};
318532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy
32d44c31ac8e52f34e058f44aba14f679abcc7edf9Jan Engelhardt#define s struct xt_tee_tginfo
33d44c31ac8e52f34e058f44aba14f679abcc7edf9Jan Engelhardtstatic const struct xt_option_entry tee_tg_opts[] = {
34d7282413763b0ba85d512c1cd49174b762ff449cJan Engelhardt	{.name = "gateway", .id = O_GATEWAY, .type = XTTYPE_HOST,
35d44c31ac8e52f34e058f44aba14f679abcc7edf9Jan Engelhardt	 .flags = XTOPT_MAND | XTOPT_PUT, XTOPT_POINTER(s, gw)},
36d44c31ac8e52f34e058f44aba14f679abcc7edf9Jan Engelhardt	{.name = "oif", .id = O_OIF, .type = XTTYPE_STRING,
37d44c31ac8e52f34e058f44aba14f679abcc7edf9Jan Engelhardt	 .flags = XTOPT_PUT, XTOPT_POINTER(s, oif)},
38d44c31ac8e52f34e058f44aba14f679abcc7edf9Jan Engelhardt	XTOPT_TABLEEND,
398532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy};
40d44c31ac8e52f34e058f44aba14f679abcc7edf9Jan Engelhardt#undef s
418532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy
428532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardystatic void tee_tg_help(void)
438532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy{
448532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	printf(
458532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy"TEE target options:\n"
468532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy"  --gateway IPADDR    Route packet via the gateway given by address\n"
478532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy"  --oif NAME          Include oif in route calculation\n"
488532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy"\n");
498532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy}
508532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy
518532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardystatic void tee_tg_print(const void *ip, const struct xt_entry_target *target,
528532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy                         int numeric)
538532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy{
548532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	const struct xt_tee_tginfo *info = (const void *)target->data;
558532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy
568532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	if (numeric)
5773866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" TEE gw:%s", xtables_ipaddr_to_numeric(&info->gw.in));
588532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	else
5973866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" TEE gw:%s", xtables_ipaddr_to_anyname(&info->gw.in));
608532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	if (*info->oif != '\0')
6173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" oif=%s", info->oif);
628532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy}
638532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy
648532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardystatic void tee_tg6_print(const void *ip, const struct xt_entry_target *target,
658532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy                          int numeric)
668532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy{
678532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	const struct xt_tee_tginfo *info = (const void *)target->data;
688532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy
698532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	if (numeric)
7073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" TEE gw:%s", xtables_ip6addr_to_numeric(&info->gw.in6));
718532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	else
7273866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" TEE gw:%s", xtables_ip6addr_to_anyname(&info->gw.in6));
738532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	if (*info->oif != '\0')
7473866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" oif=%s", info->oif);
758532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy}
768532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy
778532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardystatic void tee_tg_save(const void *ip, const struct xt_entry_target *target)
788532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy{
798532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	const struct xt_tee_tginfo *info = (const void *)target->data;
808532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy
8173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf(" --gateway %s", xtables_ipaddr_to_numeric(&info->gw.in));
828532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	if (*info->oif != '\0')
8373866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" --oif %s", info->oif);
848532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy}
858532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy
868532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardystatic void tee_tg6_save(const void *ip, const struct xt_entry_target *target)
878532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy{
888532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	const struct xt_tee_tginfo *info = (const void *)target->data;
898532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy
9073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf(" --gateway %s", xtables_ip6addr_to_numeric(&info->gw.in6));
918532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	if (*info->oif != '\0')
9273866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" --oif %s", info->oif);
938532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy}
948532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy
951757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardtstatic struct xtables_target tee_tg_reg[] = {
961757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardt	{
971757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardt		.name          = "TEE",
981757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardt		.version       = XTABLES_VERSION,
991757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardt		.revision      = 1,
1001757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardt		.family        = NFPROTO_IPV4,
1011757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardt		.size          = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
1021757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardt		.userspacesize = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
1031757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardt		.help          = tee_tg_help,
1041757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardt		.print         = tee_tg_print,
1051757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardt		.save          = tee_tg_save,
1061757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardt		.x6_parse      = xtables_option_parse,
1071757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardt		.x6_options    = tee_tg_opts,
1081757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardt	},
1091757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardt	{
1101757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardt		.name          = "TEE",
1111757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardt		.version       = XTABLES_VERSION,
1121757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardt		.revision      = 1,
1131757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardt		.family        = NFPROTO_IPV6,
1141757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardt		.size          = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
1151757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardt		.userspacesize = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
1161757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardt		.help          = tee_tg_help,
1171757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardt		.print         = tee_tg6_print,
1181757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardt		.save          = tee_tg6_save,
1191757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardt		.x6_parse      = xtables_option_parse,
1201757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardt		.x6_options    = tee_tg_opts,
1211757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardt	},
1228532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy};
1238532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy
1240428e5a6541c3f5eaaf683d8da9ea60c44eac4c7Jan Engelhardtvoid _init(void)
1258532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy{
1261757ec846419c76da4e104f9675b40e05ac3eee6Jan Engelhardt	xtables_register_targets(tee_tg_reg, ARRAY_SIZE(tee_tg_reg));
1278532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy}
128