summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/conf/NOTES8
-rw-r--r--sys/conf/options1
-rw-r--r--sys/netinet/in.h1
-rw-r--r--sys/netinet/in_pcb.c7
-rw-r--r--sys/netinet/in_pcb.h2
-rw-r--r--sys/netinet/ip_output.c19
6 files changed, 37 insertions, 1 deletions
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index 8f176b7..3b6eb19 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -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
diff --git a/sys/conf/options b/sys/conf/options
index eae3ce3..34c1d63 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -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
diff --git a/sys/netinet/in.h b/sys/netinet/in.h
index b969bdf..53d84ef 100644
--- a/sys/netinet/in.h
+++ b/sys/netinet/in.h
@@ -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 */
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 6d1c2aa..d42d109 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -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, struct sockaddr *nam, in_addr_t *laddrp,
} 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;
diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h
index 01636fe..acc6404 100644
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -411,6 +411,8 @@ void inp_4tuple_get(struct inpcb *inp, uint32_t *laddr, uint16_t *lp,
#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 */
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 65372d9..5f19acc 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -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_frag_size, CTLFLAG_RW,
&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 sockopt *sopt)
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 sockopt *sopt)
case IP_DONTFRAG:
OPTSET(INP_DONTFRAG);
break;
+#if defined(IP_NONLOCALBIND)
+ case IP_NONLOCALOK:
+ OPTSET(INP_NONLOCALOK);
+ break;
+#endif
}
break;
#undef OPTSET
OpenPOWER on IntegriCloud