diff options
-rw-r--r-- | contrib/ipfilter/ip_fil.c | 15 | ||||
-rw-r--r-- | contrib/ipfilter/ipsend/iptests.c | 1 | ||||
-rw-r--r-- | contrib/ipfilter/ipsend/sock.c | 1 | ||||
-rw-r--r-- | contrib/ipfilter/lib/printnat.c | 2 | ||||
-rw-r--r-- | contrib/ipfilter/test/regress/n12 | 2 | ||||
-rw-r--r-- | contrib/ipfilter/test/regress/n2 | 8 | ||||
-rw-r--r-- | contrib/ipfilter/test/regress/n5 | 6 | ||||
-rw-r--r-- | contrib/ipfilter/test/regress/ni1.nat | 4 | ||||
-rw-r--r-- | contrib/ipfilter/test/regress/ni2.nat | 2 | ||||
-rw-r--r-- | contrib/ipfilter/test/regress/ni4.nat | 2 | ||||
-rw-r--r-- | contrib/ipfilter/tools/ipnat_y.y | 12 | ||||
-rw-r--r-- | sys/contrib/ipfilter/netinet/ip_compat.h | 14 | ||||
-rw-r--r-- | sys/contrib/ipfilter/netinet/ip_fil.h | 6 | ||||
-rw-r--r-- | sys/contrib/ipfilter/netinet/ip_nat.c | 15 | ||||
-rw-r--r-- | sys/contrib/ipfilter/netinet/ip_nat.h | 4 | ||||
-rw-r--r-- | sys/contrib/ipfilter/netinet/ip_state.c | 18 |
16 files changed, 91 insertions, 21 deletions
diff --git a/contrib/ipfilter/ip_fil.c b/contrib/ipfilter/ip_fil.c index a3efa87..0694a75 100644 --- a/contrib/ipfilter/ip_fil.c +++ b/contrib/ipfilter/ip_fil.c @@ -801,3 +801,18 @@ int ipfsync() { return 0; } + + +u_32_t ipf_random() +{ + static int seeded = 0; + + /* + * Choose a non-random seed so that "randomness" can be "tested." + */ + if (seeded == 0) { + srand(0); + seeded = 1; + } + return rand(); +} diff --git a/contrib/ipfilter/ipsend/iptests.c b/contrib/ipfilter/ipsend/iptests.c index 0dd96b8..22ef71f 100644 --- a/contrib/ipfilter/ipsend/iptests.c +++ b/contrib/ipfilter/ipsend/iptests.c @@ -24,6 +24,7 @@ typedef int boolean_t; #if !defined(__osf__) # ifdef __NetBSD__ # include <machine/lock.h> +# include <machine/mutex.h> # endif # define _KERNEL # define KERNEL diff --git a/contrib/ipfilter/ipsend/sock.c b/contrib/ipfilter/ipsend/sock.c index 7d0157c..dcff6eb 100644 --- a/contrib/ipfilter/ipsend/sock.c +++ b/contrib/ipfilter/ipsend/sock.c @@ -32,6 +32,7 @@ typedef int boolean_t; #if !defined(__osf__) # ifdef __NetBSD__ # include <machine/lock.h> +# include <machine/mutex.h> # endif # ifdef __FreeBSD__ # define _WANT_FILE diff --git a/contrib/ipfilter/lib/printnat.c b/contrib/ipfilter/lib/printnat.c index 62942ce..39c43ca 100644 --- a/contrib/ipfilter/lib/printnat.c +++ b/contrib/ipfilter/lib/printnat.c @@ -217,6 +217,8 @@ int opts; putchar(' '); printproto(pr, np->in_p, np); } + if (np->in_flags & IPN_SEQUENTIAL) + printf(" sequential"); printf("\n"); if (opts & OPT_DEBUG) { struct in_addr nip; diff --git a/contrib/ipfilter/test/regress/n12 b/contrib/ipfilter/test/regress/n12 index 225675b..933856b 100644 --- a/contrib/ipfilter/test/regress/n12 +++ b/contrib/ipfilter/test/regress/n12 @@ -1 +1 @@ -map le0 192.168.126.0/24 -> 0/32 portmap tcp/udp 10000:20000 +map le0 192.168.126.0/24 -> 0/32 portmap tcp/udp 10000:20000 sequential diff --git a/contrib/ipfilter/test/regress/n2 b/contrib/ipfilter/test/regress/n2 index dbce5aa..39a4d72 100644 --- a/contrib/ipfilter/test/regress/n2 +++ b/contrib/ipfilter/test/regress/n2 @@ -1,4 +1,4 @@ -map zx0 10.1.1.1/32 -> 10.2.2.2/32 portmap tcp 10000:20000 -map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap udp 10000:20000 -map zx0 10.1.0.0/16 -> 10.3.4.0/24 portmap tcp/udp 10000:20000 -map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap tcp/udp 40000:40001 +map zx0 10.1.1.1/32 -> 10.2.2.2/32 portmap tcp 10000:20000 sequential +map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap udp 10000:20000 sequential +map zx0 10.1.0.0/16 -> 10.3.4.0/24 portmap tcp/udp 10000:20000 sequential +map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap tcp/udp 40000:40001 sequential diff --git a/contrib/ipfilter/test/regress/n5 b/contrib/ipfilter/test/regress/n5 index e55cea0..d9f1a88 100644 --- a/contrib/ipfilter/test/regress/n5 +++ b/contrib/ipfilter/test/regress/n5 @@ -1,6 +1,6 @@ map zx0 10.1.1.1/32 -> 10.2.2.2/32 map zx0 from 10.1.1.0/24 to 10.1.0.0/16 -> 10.3.4.5/32 map zx0 from 10.1.1.0/24 ! to 10.1.0.0/16 -> 10.3.4.0/24 -map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap udp 10000:20000 -map zx0 10.1.0.0/16 -> 10.3.4.0/24 portmap tcp/udp 10000:20000 -map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap tcp/udp 40000:40001 +map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap udp 10000:20000 sequential +map zx0 10.1.0.0/16 -> 10.3.4.0/24 portmap tcp/udp 10000:20000 sequential +map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap tcp/udp 40000:40001 sequential diff --git a/contrib/ipfilter/test/regress/ni1.nat b/contrib/ipfilter/test/regress/ni1.nat index f38e435..077aab1 100644 --- a/contrib/ipfilter/test/regress/ni1.nat +++ b/contrib/ipfilter/test/regress/ni1.nat @@ -1,3 +1,3 @@ -map df0 from 2.2.2.2/32 port 20000 >< 25000 to any -> 6.6.6.8/32 portmap udp 2000:2500 -map df0 from 2.2.2.2/32 port 2000 >< 2500 to any -> 6.6.6.7/32 portmap udp 20000:25000 +map df0 from 2.2.2.2/32 port 20000 >< 25000 to any -> 6.6.6.8/32 portmap udp 2000:2500 sequential +map df0 from 2.2.2.2/32 port 2000 >< 2500 to any -> 6.6.6.7/32 portmap udp 20000:25000 sequential map df0 from 2.2.2.2/32 to any -> 6.6.6.6/32 diff --git a/contrib/ipfilter/test/regress/ni2.nat b/contrib/ipfilter/test/regress/ni2.nat index 4ad73c2..43d2c83 100644 --- a/contrib/ipfilter/test/regress/ni2.nat +++ b/contrib/ipfilter/test/regress/ni2.nat @@ -1 +1 @@ -map xl0 10.0.0.0/8 -> 1.1.1.1/32 portmap tcp/udp 40000:60000 +map xl0 10.0.0.0/8 -> 1.1.1.1/32 portmap tcp/udp 40000:60000 sequential diff --git a/contrib/ipfilter/test/regress/ni4.nat b/contrib/ipfilter/test/regress/ni4.nat index 6eefdc2..e9d5cc1 100644 --- a/contrib/ipfilter/test/regress/ni4.nat +++ b/contrib/ipfilter/test/regress/ni4.nat @@ -1 +1 @@ -map df0 2.2.2.2/32 -> 6.6.6.6/32 portmap tcp/udp 40000:60000 +map df0 2.2.2.2/32 -> 6.6.6.6/32 portmap tcp/udp 40000:60000 sequential diff --git a/contrib/ipfilter/tools/ipnat_y.y b/contrib/ipfilter/tools/ipnat_y.y index cce717d..7109f60 100644 --- a/contrib/ipfilter/tools/ipnat_y.y +++ b/contrib/ipfilter/tools/ipnat_y.y @@ -95,7 +95,7 @@ static void setnatproto __P((int)); %token IPNY_MAP IPNY_BIMAP IPNY_FROM IPNY_TO IPNY_MASK IPNY_PORTMAP IPNY_ANY %token IPNY_ROUNDROBIN IPNY_FRAG IPNY_AGE IPNY_ICMPIDMAP IPNY_PROXY %token IPNY_TCP IPNY_UDP IPNY_TCPUDP IPNY_STICKY IPNY_MSSCLAMP IPNY_TAG -%token IPNY_TLATE +%token IPNY_TLATE IPNY_SEQUENTIAL %type <port> portspec %type <num> hexnumber compare range proto %type <ipa> hostname ipv4 @@ -422,11 +422,11 @@ otherifname: ; mapport: - IPNY_PORTMAP tcpudp portspec ':' portspec + IPNY_PORTMAP tcpudp portspec ':' portspec randport { nat->in_pmin = htons($3); nat->in_pmax = htons($5); } - | IPNY_PORTMAP tcpudp IPNY_AUTO + | IPNY_PORTMAP tcpudp IPNY_AUTO randport { nat->in_flags |= IPN_AUTOPORTMAP; nat->in_pmin = htons(1024); nat->in_pmax = htons(65535); @@ -446,6 +446,10 @@ mapport: } ; +randport: + | IPNY_SEQUENTIAL { nat->in_flags |= IPN_SEQUENTIAL; } + ; + sobject: saddr | saddr port portstuff { nat->in_sport = $3.p1; @@ -519,6 +523,7 @@ rdroptions: nattag: | IPNY_TAG YY_STR { strncpy(nat->in_tag.ipt_tag, $2, sizeof(nat->in_tag.ipt_tag)); } + rr: | IPNY_ROUNDROBIN { nat->in_flags |= IPN_ROUNDR; } ; @@ -647,6 +652,7 @@ static wordtab_t yywords[] = { { "range", IPNY_RANGE }, { "rdr", IPNY_RDR }, { "round-robin",IPNY_ROUNDROBIN }, + { "sequential", IPNY_SEQUENTIAL }, { "sticky", IPNY_STICKY }, { "tag", IPNY_TAG }, { "tcp", IPNY_TCP }, diff --git a/sys/contrib/ipfilter/netinet/ip_compat.h b/sys/contrib/ipfilter/netinet/ip_compat.h index 97c9d7e..daf824c 100644 --- a/sys/contrib/ipfilter/netinet/ip_compat.h +++ b/sys/contrib/ipfilter/netinet/ip_compat.h @@ -204,6 +204,8 @@ typedef unsigned int u_32_t; # define U_32_T 1 # ifdef _KERNEL +# define NEED_LOCAL_RAND 1 +# define ipf_random arc4random # define KRWLOCK_T krwlock_t # define KMUTEX_T kmutex_t @@ -334,6 +336,7 @@ typedef mblk_t mb_t; typedef struct uio uio_t; # endif typedef int ioctlcmd_t; +typedef uint8_t u_int8_t; # define OS_RECOGNISED 1 @@ -564,6 +567,8 @@ typedef struct { # endif # ifdef _KERNEL +# define NEED_LOCAL_RAND 1 +# define ipf_random arc4random # define ATOMIC_INC(x) { MUTEX_ENTER(&ipf_rw); \ (x)++; MUTEX_EXIT(&ipf_rw); } # define ATOMIC_DEC(x) { MUTEX_ENTER(&ipf_rw); \ @@ -660,6 +665,8 @@ typedef struct mbuf mb_t; # include <sys/sysmacros.h> # ifdef _KERNEL +# define NEED_LOCAL_RAND 1 +# define ipf_random arc4random # define KMUTEX_T simple_lock_data_t # define KRWLOCK_T lock_data_t # include <net/net_globals.h> @@ -781,6 +788,8 @@ typedef unsigned int u_32_t; typedef char * caddr_t; # endif +# define ipf_random arc4random + # ifdef _KERNEL # if (__NetBSD_Version__ >= 399001400) # define KMALLOCS(a, b, c) (a) = (b)malloc((c), _M_IPF, M_NOWAIT) @@ -820,6 +829,11 @@ typedef u_int32_t u_32_t; /* F R E E B S D */ /* ----------------------------------------------------------------------- */ #ifdef __FreeBSD__ +# if (__FreeBSD_version < 400000) +# define NEED_LOCAL_RAND 1 +# else +# define ipf_random arc4random +# endif # if defined(_KERNEL) # if (__FreeBSD_version >= 500000) # include "opt_bpf.h" diff --git a/sys/contrib/ipfilter/netinet/ip_fil.h b/sys/contrib/ipfilter/netinet/ip_fil.h index 353328c..0cd84b9 100644 --- a/sys/contrib/ipfilter/netinet/ip_fil.h +++ b/sys/contrib/ipfilter/netinet/ip_fil.h @@ -1523,6 +1523,12 @@ extern void ipf_freetoken __P((ipftoken_t *)); extern int ipf_deltoken __P((int,int, void *)); extern int ipfsync __P((void)); extern int ipf_genericiter __P((void *, int, void *)); +#ifndef ipf_random +extern u_32_t ipf_random __P((void)); +#endif +#ifdef NEED_LOCAL_RAND +extern void ipf_rand_push __P((void *, int)); +#endif extern int fr_running; extern u_long fr_frouteok[2]; diff --git a/sys/contrib/ipfilter/netinet/ip_nat.c b/sys/contrib/ipfilter/netinet/ip_nat.c index a696321..8b227e0 100644 --- a/sys/contrib/ipfilter/netinet/ip_nat.c +++ b/sys/contrib/ipfilter/netinet/ip_nat.c @@ -1678,6 +1678,9 @@ int logtype; if (logtype != 0 && nat_logging != 0) nat_log(nat, logtype); +#if defined(NEED_LOCAL_RAND) && defined(_KERNEL) + ipf_rand_push(nat, sizeof(*nat)); +#endif /* * Take it as a general indication that all the pointers are set if @@ -2029,7 +2032,13 @@ natinfo_t *ni; /* * Standard port translation. Select next port. */ - port = htons(np->in_pnext++); + if (np->in_flags & IPN_SEQUENTIAL) { + port = htons(np->in_pnext); + } else { + port = ipf_random() % (ntohs(np->in_pmax) - + ntohs(np->in_pmin)); + } + np->in_pnext++; if (np->in_pnext > ntohs(np->in_pmax)) { np->in_pnext = ntohs(np->in_pmin); @@ -3793,7 +3802,7 @@ u_32_t *passp; READ_ENTER(&ipf_nat); - if ((fin->fin_p == IPPROTO_ICMP) && !(nflags & IPN_ICMPQUERY) && + if (((fin->fin_flx & FI_ICMPERR) != 0) && (nat = nat_icmperror(fin, &nflags, NAT_OUTBOUND))) /*EMPTY*/; else if ((fin->fin_flx & FI_FRAG) && (nat = fr_nat_knownfrag(fin))) @@ -4088,7 +4097,7 @@ u_32_t *passp; READ_ENTER(&ipf_nat); - if ((fin->fin_p == IPPROTO_ICMP) && !(nflags & IPN_ICMPQUERY) && + if (((fin->fin_flx & FI_ICMPERR) != 0) && (nat = nat_icmperror(fin, &nflags, NAT_INBOUND))) /*EMPTY*/; else if ((fin->fin_flx & FI_FRAG) && (nat = fr_nat_knownfrag(fin))) diff --git a/sys/contrib/ipfilter/netinet/ip_nat.h b/sys/contrib/ipfilter/netinet/ip_nat.h index 3020eb6..c8581ef 100644 --- a/sys/contrib/ipfilter/netinet/ip_nat.h +++ b/sys/contrib/ipfilter/netinet/ip_nat.h @@ -256,9 +256,11 @@ typedef struct ipnat { #define IPN_FIXEDDPORT 0x200000 #define IPN_FINDFORWARD 0x400000 #define IPN_IN 0x800000 +#define IPN_SEQUENTIAL 0x1000000 #define IPN_USERFLAGS (IPN_TCPUDP|IPN_AUTOPORTMAP|IPN_IPRANGE|IPN_SPLIT|\ IPN_ROUNDR|IPN_FILTER|IPN_NOTSRC|IPN_NOTDST|\ - IPN_FRAG|IPN_STICKY|IPN_FIXEDDPORT|IPN_ICMPQUERY) + IPN_FRAG|IPN_STICKY|IPN_FIXEDDPORT|IPN_ICMPQUERY|\ + IPN_SEQUENTIAL) /* * Values for in_redir diff --git a/sys/contrib/ipfilter/netinet/ip_state.c b/sys/contrib/ipfilter/netinet/ip_state.c index aa9192a..6c8b158 100644 --- a/sys/contrib/ipfilter/netinet/ip_state.c +++ b/sys/contrib/ipfilter/netinet/ip_state.c @@ -195,6 +195,9 @@ ipstate_t *ips_list = NULL; /* ------------------------------------------------------------------------ */ int fr_stateinit() { +#if defined(NEED_LOCAL_RAND) || !defined(_KERNEL) + struct timeval tv; +#endif int i; KMALLOCS(ips_table, ipstate_t **, fr_statesize * sizeof(ipstate_t *)); @@ -205,20 +208,27 @@ int fr_stateinit() KMALLOCS(ips_seed, u_long *, fr_statesize * sizeof(*ips_seed)); if (ips_seed == NULL) return -2; +#if defined(NEED_LOCAL_RAND) || !defined(_KERNEL) + tv.tv_sec = 0; + GETKTIME(&tv); +#endif for (i = 0; i < fr_statesize; i++) { /* * XXX - ips_seed[X] should be a random number of sorts. */ -#if (__FreeBSD_version >= 400000) +#if !defined(NEED_LOCAL_RAND) && defined(_KERNEL) ips_seed[i] = arc4random(); #else ips_seed[i] = ((u_long)ips_seed + i) * fr_statesize; - ips_seed[i] ^= 0xa5a55a5a; + ips_seed[i] += tv.tv_sec; ips_seed[i] *= (u_long)ips_seed; ips_seed[i] ^= 0x5a5aa5a5; ips_seed[i] *= fr_statemax; #endif } +#if defined(NEED_LOCAL_RAND) && defined(_KERNEL) + ipf_rand_push(ips_seed, fr_statesize * sizeof(*ips_seed)); +#endif /* fill icmp reply type table */ for (i = 0; i <= ICMP_MAXTYPE; i++) @@ -3028,6 +3038,10 @@ int why; (void) fr_derefrule(&is->is_rule); } +#if defined(NEED_LOCAL_RAND) && defined(_KERNEL) + ipf_rand_push(is, sizeof(*is)); +#endif + MUTEX_DESTROY(&is->is_lock); KFREE(is); ips_num--; |