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
958532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardystatic struct xtables_target tee_tg_reg = {
968532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	.name          = "TEE",
978532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	.version       = XTABLES_VERSION,
988532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	.revision      = 1,
998532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	.family        = NFPROTO_IPV4,
1008532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	.size          = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
1018532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	.userspacesize = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
1028532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	.help          = tee_tg_help,
1038532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	.print         = tee_tg_print,
1048532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	.save          = tee_tg_save,
105d44c31ac8e52f34e058f44aba14f679abcc7edf9Jan Engelhardt	.x6_parse      = xtables_option_parse,
106d44c31ac8e52f34e058f44aba14f679abcc7edf9Jan Engelhardt	.x6_options    = tee_tg_opts,
1078532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy};
1088532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy
1098532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardystatic struct xtables_target tee_tg6_reg = {
1108532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	.name          = "TEE",
1118532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	.version       = XTABLES_VERSION,
1128532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	.revision      = 1,
1138532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	.family        = NFPROTO_IPV6,
1148532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	.size          = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
1158532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	.userspacesize = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
1168532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	.help          = tee_tg_help,
1178532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	.print         = tee_tg6_print,
1188532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	.save          = tee_tg6_save,
119d44c31ac8e52f34e058f44aba14f679abcc7edf9Jan Engelhardt	.x6_parse      = xtables_option_parse,
120d44c31ac8e52f34e058f44aba14f679abcc7edf9Jan Engelhardt	.x6_options    = tee_tg_opts,
1218532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy};
1228532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy
1230428e5a6541c3f5eaaf683d8da9ea60c44eac4c7Jan Engelhardtvoid _init(void)
1248532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy{
1258532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	xtables_register_target(&tee_tg_reg);
1268532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy	xtables_register_target(&tee_tg6_reg);
1278532c70fd182057b440b41f013d8021a95bd72b2Patrick McHardy}
128