summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--contrib/ipfilter/ip_fil.c15
-rw-r--r--contrib/ipfilter/ipsend/iptests.c1
-rw-r--r--contrib/ipfilter/ipsend/sock.c1
-rw-r--r--contrib/ipfilter/lib/printnat.c2
-rw-r--r--contrib/ipfilter/test/regress/n122
-rw-r--r--contrib/ipfilter/test/regress/n28
-rw-r--r--contrib/ipfilter/test/regress/n56
-rw-r--r--contrib/ipfilter/test/regress/ni1.nat4
-rw-r--r--contrib/ipfilter/test/regress/ni2.nat2
-rw-r--r--contrib/ipfilter/test/regress/ni4.nat2
-rw-r--r--contrib/ipfilter/tools/ipnat_y.y12
-rw-r--r--sys/contrib/ipfilter/netinet/ip_compat.h14
-rw-r--r--sys/contrib/ipfilter/netinet/ip_fil.h6
-rw-r--r--sys/contrib/ipfilter/netinet/ip_nat.c15
-rw-r--r--sys/contrib/ipfilter/netinet/ip_nat.h4
-rw-r--r--sys/contrib/ipfilter/netinet/ip_state.c18
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--;
OpenPOWER on IntegriCloud