Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 9 Jan 2009 16:02:19 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r186955 - in head/sys: conf netinet
Message-ID:  <200901091602.n09G2Jj1061164@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Fri Jan  9 16:02:19 2009
New Revision: 186955
URL: http://svn.freebsd.org/changeset/base/186955

Log:
  Implement a new IP option (not compiled/enabled by default) to allow
  applications to specify a non-local IP address when bind()'ing a socket
  to a local endpoint.
  
  This allows applications to spoof the client IP address of connections
  if (obviously!) they somehow are able to receive the traffic normally
  destined to said clients.
  
  This patch doesn't include any changes to ipfw or the bridging code to
  redirect the client traffic through the PCB checks so TCP gets a shot
  at it. The normal behaviour is that packets with a non-local destination
  IP address are not handled locally. This can be dealth with some IPFW hackery;
  modifications to IPFW to make this less hacky will occur in subsequent
  commmits.
  
  Thanks to Julian Elischer and others at Ironport. This work was approved
  and donated before Cisco acquired them.
  
  Obtained from:	Julian Elischer and others
  MFC after:	2 weeks

Modified:
  head/sys/conf/NOTES
  head/sys/conf/options
  head/sys/netinet/in.h
  head/sys/netinet/in_pcb.c
  head/sys/netinet/in_pcb.h
  head/sys/netinet/ip_output.c

Modified: head/sys/conf/NOTES
==============================================================================
--- head/sys/conf/NOTES	Fri Jan  9 15:13:46 2009	(r186954)
+++ head/sys/conf/NOTES	Fri Jan  9 16:02:19 2009	(r186955)
@@ -633,6 +633,14 @@ options 	ALTQ_PRIQ	# Priority Queueing
 options 	ALTQ_NOPCC	# Required if the TSC is unusable
 options 	ALTQ_DEBUG
 
+# IP optional behaviour.
+# IP_NONLOCALBIND disables the check that bind() usually makes that the
+# Address is one that is assigned to an interface on this machine.
+# It allows transparent proxies to pretend to be other machines.
+# How the packet GET to that machine is a problem solved elsewhere,
+# smart routers, ipfw fwd, etc.
+options        IP_NONLOCALBIND		#Allow impersonation for proxies.
+
 # netgraph(4). Enable the base netgraph code with the NETGRAPH option.
 # Individual node types can be enabled with the corresponding option
 # listed below; however, this is not strictly necessary as netgraph

Modified: head/sys/conf/options
==============================================================================
--- head/sys/conf/options	Fri Jan  9 15:13:46 2009	(r186954)
+++ head/sys/conf/options	Fri Jan  9 16:02:19 2009	(r186955)
@@ -392,6 +392,7 @@ IPFIREWALL_VERBOSE	opt_ipfw.h
 IPFIREWALL_VERBOSE_LIMIT	opt_ipfw.h
 IPSEC			opt_ipsec.h
 IPSEC_DEBUG		opt_ipsec.h
+IP_NONLOCALBIND		opt_inet.h
 IPSEC_FILTERTUNNEL	opt_ipsec.h
 IPSTEALTH
 IPX

Modified: head/sys/netinet/in.h
==============================================================================
--- head/sys/netinet/in.h	Fri Jan  9 15:13:46 2009	(r186954)
+++ head/sys/netinet/in.h	Fri Jan  9 16:02:19 2009	(r186955)
@@ -441,6 +441,7 @@ __END_DECLS
 #define	IP_FAITH		22   /* bool; accept FAITH'ed connections */
 
 #define	IP_ONESBCAST		23   /* bool: send all-ones broadcast */
+#define	IP_NONLOCALOK		24   /* allow bind to spoof other machines */
 
 #define	IP_FW_TABLE_ADD		40   /* add entry */
 #define	IP_FW_TABLE_DEL		41   /* delete entry */

Modified: head/sys/netinet/in_pcb.c
==============================================================================
--- head/sys/netinet/in_pcb.c	Fri Jan  9 15:13:46 2009	(r186954)
+++ head/sys/netinet/in_pcb.c	Fri Jan  9 16:02:19 2009	(r186955)
@@ -35,6 +35,7 @@
 __FBSDID("$FreeBSD$");
 
 #include "opt_ddb.h"
+#include "opt_inet.h"
 #include "opt_ipsec.h"
 #include "opt_inet6.h"
 #include "opt_mac.h"
@@ -346,7 +347,11 @@ in_pcbbind_setup(struct inpcb *inp, stru
 		} else if (sin->sin_addr.s_addr != INADDR_ANY) {
 			sin->sin_port = 0;		/* yech... */
 			bzero(&sin->sin_zero, sizeof(sin->sin_zero));
-			if (ifa_ifwithaddr((struct sockaddr *)sin) == 0)
+			if (
+#if defined(IP_NONLOCALBIND)
+			    ((inp->inp_flags & INP_NONLOCALOK) == 0) &&
+#endif
+			    (ifa_ifwithaddr((struct sockaddr *)sin) == 0))
 				return (EADDRNOTAVAIL);
 		}
 		laddr = sin->sin_addr;

Modified: head/sys/netinet/in_pcb.h
==============================================================================
--- head/sys/netinet/in_pcb.h	Fri Jan  9 15:13:46 2009	(r186954)
+++ head/sys/netinet/in_pcb.h	Fri Jan  9 16:02:19 2009	(r186955)
@@ -411,6 +411,8 @@ void 	inp_4tuple_get(struct inpcb *inp, 
 #define	INP_FAITH		0x200	/* accept FAITH'ed connections */
 #define	INP_RECVTTL		0x400	/* receive incoming IP TTL */
 #define	INP_DONTFRAG		0x800	/* don't fragment packet */
+#define	INP_NONLOCALOK		0x1000	/* Allow bind to spoof any address */
+					/* - requires options IP_NONLOCALBIND */
 
 #define IN6P_IPV6_V6ONLY	0x008000 /* restrict AF_INET6 socket for v6 */
 

Modified: head/sys/netinet/ip_output.c
==============================================================================
--- head/sys/netinet/ip_output.c	Fri Jan  9 15:13:46 2009	(r186954)
+++ head/sys/netinet/ip_output.c	Fri Jan  9 16:02:19 2009	(r186955)
@@ -33,6 +33,7 @@
 __FBSDID("$FreeBSD$");
 
 #include "opt_ipfw.h"
+#include "opt_inet.h"
 #include "opt_ipsec.h"
 #include "opt_mac.h"
 #include "opt_mbuf_stress_test.h"
@@ -95,6 +96,12 @@ SYSCTL_INT(_net_inet_ip, OID_AUTO, mbuf_
 	&mbuf_frag_size, 0, "Fragment outgoing mbufs to this size");
 #endif
 
+#if defined(IP_NONLOCALBIND)
+static int ip_nonlocalok = 0;
+SYSCTL_INT(_net_inet_ip, OID_AUTO, nonlocalok,
+	CTLFLAG_RW|CTLFLAG_SECURE, &ip_nonlocalok, 0, "");
+#endif
+
 static void	ip_mloopback
 	(struct ifnet *, struct mbuf *, struct sockaddr_in *, int);
 
@@ -866,6 +873,13 @@ ip_ctloutput(struct socket *so, struct s
 			return (error);
 		}
 
+#if defined(IP_NONLOCALBIND)
+		case IP_NONLOCALOK:
+			if (! ip_nonlocalok) {
+			error = ENOPROTOOPT;
+			break;
+		}
+#endif
 		case IP_TOS:
 		case IP_TTL:
 		case IP_MINTTL:
@@ -937,6 +951,11 @@ ip_ctloutput(struct socket *so, struct s
 			case IP_DONTFRAG:
 				OPTSET(INP_DONTFRAG);
 				break;
+#if defined(IP_NONLOCALBIND)
+			case IP_NONLOCALOK:
+				OPTSET(INP_NONLOCALOK);
+				break;
+#endif
 			}
 			break;
 #undef OPTSET



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200901091602.n09G2Jj1061164>