blob: d13ec85f92d0a012d7fe194ff2d8bd4487f1cede [file] [log] [blame]
KOVACS Krisztian92b54aa2008-10-15 11:49:37 +02001/*
Jan Engelhardt64cb56e2011-02-09 02:15:22 +01002 * shared library add-on to iptables to add TPROXY target support.
KOVACS Krisztian92b54aa2008-10-15 11:49:37 +02003 *
4 * Copyright (C) 2002-2008 BalaBit IT Ltd.
5 */
KOVACS Krisztian92b54aa2008-10-15 11:49:37 +02006#include <stdio.h>
KOVACS Krisztian92b54aa2008-10-15 11:49:37 +02007#include <limits.h>
KOVACS Krisztian92b54aa2008-10-15 11:49:37 +02008#include <xtables.h>
KOVACS Krisztian92b54aa2008-10-15 11:49:37 +02009#include <linux/netfilter/xt_TPROXY.h>
Jan Engelhardt64cb56e2011-02-09 02:15:22 +010010#include <arpa/inet.h>
KOVACS Krisztian92b54aa2008-10-15 11:49:37 +020011
12enum {
Jan Engelhardt64cb56e2011-02-09 02:15:22 +010013 P_PORT = 0,
14 P_ADDR,
15 P_MARK,
16 F_PORT = 1 << P_PORT,
17 F_ADDR = 1 << P_ADDR,
18 F_MARK = 1 << P_MARK,
KOVACS Krisztian92b54aa2008-10-15 11:49:37 +020019};
20
Jan Engelhardt64cb56e2011-02-09 02:15:22 +010021#define s struct xt_tproxy_target_info
22static const struct xt_option_entry tproxy_tg0_opts[] = {
Jan Engelhardtc02c92d2011-05-18 22:48:51 +020023 {.name = "on-port", .id = P_PORT, .type = XTTYPE_PORT,
24 .flags = XTOPT_MAND | XTOPT_NBO | XTOPT_PUT, XTOPT_POINTER(s, lport)},
Jan Engelhardtd7282412011-05-04 16:41:13 +020025 {.name = "on-ip", .id = P_ADDR, .type = XTTYPE_HOST},
Jan Engelhardt64cb56e2011-02-09 02:15:22 +010026 {.name = "tproxy-mark", .id = P_MARK, .type = XTTYPE_MARKMASK32},
27 XTOPT_TABLEEND,
28};
29#undef s
30#define s struct xt_tproxy_target_info_v1
31static const struct xt_option_entry tproxy_tg1_opts[] = {
Jan Engelhardtc02c92d2011-05-18 22:48:51 +020032 {.name = "on-port", .id = P_PORT, .type = XTTYPE_PORT,
33 .flags = XTOPT_MAND | XTOPT_NBO | XTOPT_PUT, XTOPT_POINTER(s, lport)},
Jan Engelhardtd7282412011-05-04 16:41:13 +020034 {.name = "on-ip", .id = P_ADDR, .type = XTTYPE_HOST,
Jan Engelhardt64cb56e2011-02-09 02:15:22 +010035 .flags = XTOPT_PUT, XTOPT_POINTER(s, laddr)},
36 {.name = "tproxy-mark", .id = P_MARK, .type = XTTYPE_MARKMASK32},
37 XTOPT_TABLEEND,
38};
39#undef s
40
KOVACS Krisztian92b54aa2008-10-15 11:49:37 +020041static void tproxy_tg_help(void)
42{
43 printf(
44"TPROXY target options:\n"
45" --on-port port Redirect connection to port, or the original port if 0\n"
46" --on-ip ip Optionally redirect to the given IP\n"
47" --tproxy-mark value[/mask] Mark packets with the given value/mask\n\n");
48}
49
KOVACS Krisztian92b54aa2008-10-15 11:49:37 +020050static void tproxy_tg_print(const void *ip, const struct xt_entry_target *target,
51 int numeric)
52{
53 const struct xt_tproxy_target_info *info = (const void *)target->data;
Jan Engelhardt73866352010-12-18 02:04:59 +010054 printf(" TPROXY redirect %s:%u mark 0x%x/0x%x",
Jan Engelhardte44ea7f2009-01-30 03:55:09 +010055 xtables_ipaddr_to_numeric((const struct in_addr *)&info->laddr),
KOVACS Krisztian92b54aa2008-10-15 11:49:37 +020056 ntohs(info->lport), (unsigned int)info->mark_value,
57 (unsigned int)info->mark_mask);
58}
59
Jan Engelhardt9e152fa2010-12-03 22:08:32 +010060static void
61tproxy_tg_print4(const void *ip, const struct xt_entry_target *target,
62 int numeric)
63{
64 const struct xt_tproxy_target_info_v1 *info =
65 (const void *)target->data;
66
Jan Engelhardt73866352010-12-18 02:04:59 +010067 printf(" TPROXY redirect %s:%u mark 0x%x/0x%x",
Jan Engelhardt9e152fa2010-12-03 22:08:32 +010068 xtables_ipaddr_to_numeric(&info->laddr.in),
69 ntohs(info->lport), (unsigned int)info->mark_value,
70 (unsigned int)info->mark_mask);
71}
72
73static void
74tproxy_tg_print6(const void *ip, const struct xt_entry_target *target,
75 int numeric)
76{
77 const struct xt_tproxy_target_info_v1 *info =
78 (const void *)target->data;
79
Jan Engelhardt73866352010-12-18 02:04:59 +010080 printf(" TPROXY redirect %s:%u mark 0x%x/0x%x",
Jan Engelhardt9e152fa2010-12-03 22:08:32 +010081 xtables_ip6addr_to_numeric(&info->laddr.in6),
82 ntohs(info->lport), (unsigned int)info->mark_value,
83 (unsigned int)info->mark_mask);
84}
85
KOVACS Krisztian92b54aa2008-10-15 11:49:37 +020086static void tproxy_tg_save(const void *ip, const struct xt_entry_target *target)
87{
88 const struct xt_tproxy_target_info *info = (const void *)target->data;
89
Jan Engelhardt73866352010-12-18 02:04:59 +010090 printf(" --on-port %u", ntohs(info->lport));
91 printf(" --on-ip %s",
Jan Engelhardte44ea7f2009-01-30 03:55:09 +010092 xtables_ipaddr_to_numeric((const struct in_addr *)&info->laddr));
Jan Engelhardt73866352010-12-18 02:04:59 +010093 printf(" --tproxy-mark 0x%x/0x%x",
KOVACS Krisztian92b54aa2008-10-15 11:49:37 +020094 (unsigned int)info->mark_value, (unsigned int)info->mark_mask);
95}
96
Jan Engelhardt9e152fa2010-12-03 22:08:32 +010097static void
98tproxy_tg_save4(const void *ip, const struct xt_entry_target *target)
99{
100 const struct xt_tproxy_target_info_v1 *info;
101
102 info = (const void *)target->data;
Jan Engelhardt73866352010-12-18 02:04:59 +0100103 printf(" --on-port %u", ntohs(info->lport));
104 printf(" --on-ip %s", xtables_ipaddr_to_numeric(&info->laddr.in));
105 printf(" --tproxy-mark 0x%x/0x%x",
Jan Engelhardt9e152fa2010-12-03 22:08:32 +0100106 (unsigned int)info->mark_value, (unsigned int)info->mark_mask);
107}
108
109static void
110tproxy_tg_save6(const void *ip, const struct xt_entry_target *target)
111{
112 const struct xt_tproxy_target_info_v1 *info;
113
114 info = (const void *)target->data;
Jan Engelhardt73866352010-12-18 02:04:59 +0100115 printf(" --on-port %u", ntohs(info->lport));
116 printf(" --on-ip %s", xtables_ip6addr_to_numeric(&info->laddr.in6));
117 printf(" --tproxy-mark 0x%x/0x%x",
Jan Engelhardt9e152fa2010-12-03 22:08:32 +0100118 (unsigned int)info->mark_value, (unsigned int)info->mark_mask);
119}
120
Jan Engelhardt64cb56e2011-02-09 02:15:22 +0100121static void tproxy_tg0_parse(struct xt_option_call *cb)
122{
123 struct xt_tproxy_target_info *info = cb->data;
124
125 xtables_option_parse(cb);
126 switch (cb->entry->id) {
127 case P_MARK:
128 info->mark_value = cb->val.mark;
129 info->mark_mask = cb->val.mask;
130 break;
131 case P_ADDR:
Jan Engelhardtd7282412011-05-04 16:41:13 +0200132 info->laddr = cb->val.haddr.ip;
Jan Engelhardt64cb56e2011-02-09 02:15:22 +0100133 break;
134 }
135}
136
137static void tproxy_tg1_parse(struct xt_option_call *cb)
138{
139 struct xt_tproxy_target_info_v1 *info = cb->data;
140
141 xtables_option_parse(cb);
142 switch (cb->entry->id) {
143 case P_MARK:
144 info->mark_value = cb->val.mark;
145 info->mark_mask = cb->val.mask;
146 break;
147 }
148}
149
Jan Engelhardt9e152fa2010-12-03 22:08:32 +0100150static struct xtables_target tproxy_tg_reg[] = {
151 {
152 .name = "TPROXY",
153 .revision = 0,
154 .family = NFPROTO_IPV4,
155 .version = XTABLES_VERSION,
156 .size = XT_ALIGN(sizeof(struct xt_tproxy_target_info)),
157 .userspacesize = XT_ALIGN(sizeof(struct xt_tproxy_target_info)),
158 .help = tproxy_tg_help,
Jan Engelhardt9e152fa2010-12-03 22:08:32 +0100159 .print = tproxy_tg_print,
160 .save = tproxy_tg_save,
Jan Engelhardt64cb56e2011-02-09 02:15:22 +0100161 .x6_options = tproxy_tg0_opts,
162 .x6_parse = tproxy_tg0_parse,
Jan Engelhardt9e152fa2010-12-03 22:08:32 +0100163 },
164 {
165 .name = "TPROXY",
166 .revision = 1,
167 .family = NFPROTO_IPV4,
168 .version = XTABLES_VERSION,
169 .size = XT_ALIGN(sizeof(struct xt_tproxy_target_info_v1)),
170 .userspacesize = XT_ALIGN(sizeof(struct xt_tproxy_target_info_v1)),
171 .help = tproxy_tg_help,
Jan Engelhardt9e152fa2010-12-03 22:08:32 +0100172 .print = tproxy_tg_print4,
173 .save = tproxy_tg_save4,
Jan Engelhardt64cb56e2011-02-09 02:15:22 +0100174 .x6_options = tproxy_tg1_opts,
175 .x6_parse = tproxy_tg1_parse,
Jan Engelhardt9e152fa2010-12-03 22:08:32 +0100176 },
177 {
178 .name = "TPROXY",
179 .revision = 1,
180 .family = NFPROTO_IPV6,
181 .version = XTABLES_VERSION,
182 .size = XT_ALIGN(sizeof(struct xt_tproxy_target_info_v1)),
183 .userspacesize = XT_ALIGN(sizeof(struct xt_tproxy_target_info_v1)),
184 .help = tproxy_tg_help,
Jan Engelhardt9e152fa2010-12-03 22:08:32 +0100185 .print = tproxy_tg_print6,
186 .save = tproxy_tg_save6,
Jan Engelhardt64cb56e2011-02-09 02:15:22 +0100187 .x6_options = tproxy_tg1_opts,
188 .x6_parse = tproxy_tg1_parse,
Jan Engelhardt9e152fa2010-12-03 22:08:32 +0100189 },
KOVACS Krisztian92b54aa2008-10-15 11:49:37 +0200190};
191
192void _init(void)
193{
Jan Engelhardt9e152fa2010-12-03 22:08:32 +0100194 xtables_register_targets(tproxy_tg_reg, ARRAY_SIZE(tproxy_tg_reg));
KOVACS Krisztian92b54aa2008-10-15 11:49:37 +0200195}