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
95 static struct xtables_target tee_tg_reg[] = {
96 {
97 .name = "TEE",
98 .version = XTABLES_VERSION,
99 .revision = 1,
100 .family = NFPROTO_IPV4,
101 .size = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
102 .userspacesize = offsetof(struct xt_tee_tginfo, priv),
103 .help = tee_tg_help,
104 .print = tee_tg_print,
105 .save = tee_tg_save,
106 .x6_parse = xtables_option_parse,
107 .x6_options = tee_tg_opts,
108 },
109 {
110 .name = "TEE",
111 .version = XTABLES_VERSION,
112 .revision = 1,
113 .family = NFPROTO_IPV6,
114 .size = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
115 .userspacesize = offsetof(struct xt_tee_tginfo, priv),
116 .help = tee_tg_help,
117 .print = tee_tg6_print,
118 .save = tee_tg6_save,
119 .x6_parse = xtables_option_parse,
120 .x6_options = tee_tg_opts,
121 },
122 };
123
_init(void)124 void _init(void)
125 {
126 xtables_register_targets(tee_tg_reg, ARRAY_SIZE(tee_tg_reg));
127 }
128