[tproxy] [PATCH] [TPROXY] implemented IP_RECVORIGDSTADDR socket option

Andrey Luzgin andrey at icomsw.com
Thu Nov 13 16:26:22 CET 2008


Great. This is working in kernel: 2.6.25-gentoo-r7
Thanks!

On Thu, 2008-11-13 at 11:37 +0100, Balazs Scheidler wrote:

> In case UDP traffic is redirected to a local UDP socket,
> the originally addressed destination address/port
> cannot be recovered with the in-kernel tproxy.
> 
> This patch adds an IP_RECVORIGDSTADDR sockopt that enables
> a IP_ORIGDSTADDR ancillary message in recvmsg(). This
> ancillary message contains the original destination address/port
> of the packet being received.
> 
> Please apply.
> 
> Signed-off-by: Balazs Scheidler <bazsi at balabit.hu>
> ---
>  include/linux/in.h     |    4 ++++
>  net/ipv4/ip_sockglue.c |   40 +++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 43 insertions(+), 1 deletions(-)
> 
> diff --git a/include/linux/in.h b/include/linux/in.h
> index db458be..d60122a 100644
> --- a/include/linux/in.h
> +++ b/include/linux/in.h
> @@ -80,6 +80,10 @@ struct in_addr {
>  /* BSD compatibility */
>  #define IP_RECVRETOPTS	IP_RETOPTS
>  
> +/* TProxy original addresses */
> +#define IP_ORIGDSTADDR       20
> +#define IP_RECVORIGDSTADDR   IP_ORIGDSTADDR
> +
>  /* IP_MTU_DISCOVER values */
>  #define IP_PMTUDISC_DONT		0	/* Never send DF frames */
>  #define IP_PMTUDISC_WANT		1	/* Use per route hints	*/
> diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
> index 465abf0..1e70488 100644
> --- a/net/ipv4/ip_sockglue.c
> +++ b/net/ipv4/ip_sockglue.c
> @@ -48,6 +48,7 @@
>  #define IP_CMSG_RECVOPTS	8
>  #define IP_CMSG_RETOPTS		16
>  #define IP_CMSG_PASSSEC		32
> +#define IP_CMSG_ORIGDSTADDR     64
>  
>  /*
>   *	SOL_IP control messages.
> @@ -126,6 +127,27 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb)
>  	security_release_secctx(secdata, seclen);
>  }
>  
> +void ip_cmsg_recv_dstaddr(struct msghdr *msg, struct sk_buff *skb)
> +{
> +	struct sockaddr_in sin;
> +	struct iphdr *iph = ip_hdr(skb);
> +	u16 *ports = (u16 *) skb_transport_header(skb);
> +
> +	if (skb_transport_offset(skb) + 4 > skb->len)
> +		return;
> +
> +	/* All current transport protocols have the port numbers in the
> +	 * first four bytes of the transport header and this function is
> +	 * written with this assumption in mind.
> +	 */
> +
> +	sin.sin_family = AF_INET;
> +	sin.sin_addr.s_addr = iph->daddr;
> +	sin.sin_port = ports[1];
> +	memset(sin.sin_zero, 0, sizeof(sin.sin_zero));
> +
> +	put_cmsg(msg, SOL_IP, IP_ORIGDSTADDR, sizeof(sin), &sin);
> +}
>  
>  void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb)
>  {
> @@ -160,6 +182,12 @@ void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb)
>  
>  	if (flags & 1)
>  		ip_cmsg_recv_security(msg, skb);
> +
> +	if ((flags>>=1) == 0)
> +		return;
> +	if (flags & 1)
> +		ip_cmsg_recv_dstaddr(msg, skb);
> +
>  }
>  
>  int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc)
> @@ -421,7 +449,8 @@ static int do_ip_setsockopt(struct sock *sk, int level,
>  			     (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
>  			     (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT))) ||
>  	    optname == IP_MULTICAST_TTL ||
> -	    optname == IP_MULTICAST_LOOP) {
> +	    optname == IP_MULTICAST_LOOP ||
> +	    optname == IP_RECVORIGDSTADDR) {
>  		if (optlen >= sizeof(int)) {
>  			if (get_user(val, (int __user *) optval))
>  				return -EFAULT;
> @@ -509,6 +538,12 @@ static int do_ip_setsockopt(struct sock *sk, int level,
>  		else
>  			inet->cmsg_flags &= ~IP_CMSG_PASSSEC;
>  		break;
> +	case IP_RECVORIGDSTADDR:
> +		if (val)
> +			inet->cmsg_flags |= IP_CMSG_ORIGDSTADDR;
> +		else
> +			inet->cmsg_flags &= ~IP_CMSG_ORIGDSTADDR;
> +		break;
>  	case IP_TOS:	/* This sets both TOS and Precedence */
>  		if (sk->sk_type == SOCK_STREAM) {
>  			val &= ~3;
> @@ -1022,6 +1057,9 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
>  	case IP_PASSSEC:
>  		val = (inet->cmsg_flags & IP_CMSG_PASSSEC) != 0;
>  		break;
> +	case IP_RECVORIGDSTADDR:
> +		val = (inet->cmsg_flags & IP_CMSG_ORIGDSTADDR) != 0;
> +		break;
>  	case IP_TOS:
>  		val = inet->tos;
>  		break;
> -- 
> 1.5.4.3
> 
> 

-- 
Andrey Luzgin <andrey at icomsw.com>
I-com software
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.balabit.hu/pipermail/tproxy/attachments/20081113/df50207b/attachment.htm 


More information about the tproxy mailing list