diff options
-rw-r--r-- | sys/conf/NOTES | 8 | ||||
-rw-r--r-- | sys/conf/options | 1 | ||||
-rw-r--r-- | sys/netinet/in.h | 1 | ||||
-rw-r--r-- | sys/netinet/in_pcb.c | 7 | ||||
-rw-r--r-- | sys/netinet/in_pcb.h | 2 | ||||
-rw-r--r-- | sys/netinet/ip_output.c | 19 |
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 |