2 * Transparent proxy support for Linux/iptables
4 * Copyright (c) 2006-2007 BalaBit IT Ltd.
5 * Author: Balazs Scheidler, Krisztian Kovacs
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
13 #include <linux/module.h>
14 #include <linux/skbuff.h>
16 #include <net/checksum.h>
18 #include <net/inet_sock.h>
20 #include <linux/netfilter/x_tables.h>
21 #include <linux/netfilter_ipv4/ip_tables.h>
22 #include <linux/netfilter/xt_TPROXY.h>
24 #include <net/netfilter/ipv4/nf_defrag_ipv4.h>
25 #include <net/netfilter/nf_tproxy_core.h>
28 tproxy_tg(struct sk_buff
*skb
, const struct xt_target_param
*par
)
30 const struct iphdr
*iph
= ip_hdr(skb
);
31 const struct xt_tproxy_target_info
*tgi
= par
->targinfo
;
32 struct udphdr _hdr
, *hp
;
35 hp
= skb_header_pointer(skb
, ip_hdrlen(skb
), sizeof(_hdr
), &_hdr
);
39 sk
= nf_tproxy_get_sock_v4(dev_net(skb
->dev
), iph
->protocol
,
40 iph
->saddr
, tgi
->laddr
? tgi
->laddr
: iph
->daddr
,
41 hp
->source
, tgi
->lport
? tgi
->lport
: hp
->dest
,
44 /* NOTE: assign_sock consumes our sk reference */
45 if (sk
&& nf_tproxy_assign_sock(skb
, sk
)) {
46 /* This should be in a separate target, but we don't do multiple
47 targets on the same rule yet */
48 skb
->mark
= (skb
->mark
& ~tgi
->mark_mask
) ^ tgi
->mark_value
;
50 pr_debug("redirecting: proto %u %08x:%u -> %08x:%u, mark: %x\n",
51 iph
->protocol
, ntohl(iph
->daddr
), ntohs(hp
->dest
),
52 ntohl(tgi
->laddr
), ntohs(tgi
->lport
), skb
->mark
);
56 pr_debug("no socket, dropping: proto %u %08x:%u -> %08x:%u, mark: %x\n",
57 iph
->protocol
, ntohl(iph
->daddr
), ntohs(hp
->dest
),
58 ntohl(tgi
->laddr
), ntohs(tgi
->lport
), skb
->mark
);
62 static bool tproxy_tg_check(const struct xt_tgchk_param
*par
)
64 const struct ipt_ip
*i
= par
->entryinfo
;
66 if ((i
->proto
== IPPROTO_TCP
|| i
->proto
== IPPROTO_UDP
)
67 && !(i
->invflags
& IPT_INV_PROTO
))
70 pr_info("xt_TPROXY: Can be used only in combination with "
71 "either -p tcp or -p udp\n");
75 static struct xt_target tproxy_tg_reg __read_mostly
= {
80 .targetsize
= sizeof(struct xt_tproxy_target_info
),
81 .checkentry
= tproxy_tg_check
,
82 .hooks
= 1 << NF_INET_PRE_ROUTING
,
86 static int __init
tproxy_tg_init(void)
88 nf_defrag_ipv4_enable();
89 return xt_register_target(&tproxy_tg_reg
);
92 static void __exit
tproxy_tg_exit(void)
94 xt_unregister_target(&tproxy_tg_reg
);
97 module_init(tproxy_tg_init
);
98 module_exit(tproxy_tg_exit
);
99 MODULE_LICENSE("GPL");
100 MODULE_AUTHOR("Krisztian Kovacs");
101 MODULE_DESCRIPTION("Netfilter transparent proxy (TPROXY) target module.");
102 MODULE_ALIAS("ipt_TPROXY");