Index: conf/NOTES =================================================================== --- conf/NOTES (.../head/sys) (revision 185063) +++ conf/NOTES (.../user/adrian/spoof_bind/sys) (revision 186911) @@ -633,6 +633,14 @@ 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 Index: conf/options =================================================================== --- conf/options (.../head/sys) (revision 185063) +++ conf/options (.../user/adrian/spoof_bind/sys) (revision 186911) @@ -392,6 +392,7 @@ 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 Index: netinet/in.h =================================================================== --- netinet/in.h (.../head/sys) (revision 185063) +++ netinet/in.h (.../user/adrian/spoof_bind/sys) (revision 186911) @@ -441,6 +441,7 @@ #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 */ Index: netinet/in_pcb.c =================================================================== --- netinet/in_pcb.c (.../head/sys) (revision 185063) +++ netinet/in_pcb.c (.../user/adrian/spoof_bind/sys) (revision 186911) @@ -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" @@ -343,7 +344,11 @@ } 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; Index: netinet/in_pcb.h =================================================================== --- netinet/in_pcb.h (.../head/sys) (revision 185063) +++ netinet/in_pcb.h (.../user/adrian/spoof_bind/sys) (revision 186911) @@ -396,6 +396,8 @@ #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 */ Index: netinet/ip_output.c =================================================================== --- netinet/ip_output.c (.../head/sys) (revision 185063) +++ netinet/ip_output.c (.../user/adrian/spoof_bind/sys) (revision 186911) @@ -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" @@ -91,6 +92,12 @@ &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); @@ -856,6 +863,13 @@ 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: @@ -927,6 +941,11 @@ case IP_DONTFRAG: OPTSET(INP_DONTFRAG); break; +#if defined(IP_NONLOCALBIND) + case IP_NONLOCALOK: + OPTSET(INP_NONLOCALOK); + break; +#endif } break; #undef OPTSET