[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: ip nat limitation



> From the ipnat man page:
> 
>   BUGS
>      bimap should really only be used with single IP addresses (x.x.x.x/32).
>      Bimapping other CIDR ranges will result in unexpected, and possibly ran-
>      dom mappings into the destination address block.
> 
> How hard would it be to overcome this limitation?  Ideally anytime
> an address mapping like   1.1.0.0/16 -> 2.2.0.0/16 
> was in place (ie. the address block size was the same), the
> mapping would be one to one, leaving the low bits in tact
> (ie. 1.1.0.1 -> 2.2.0.1, 1.1.3.3 -> 2.2.3.3).
> 
> I sent mail to Darren Reed (listed as ipnat author), but have
> not heard back from him yet.
> 
>                                             Tim N.

I implemented the changes required to overcome this.  The
code explicitely only supports mapping from one fixed sized
network block to another.  If the block sizes are mismatched,
the mapping will happen in the same ad hoc fashion previously
supported.  The changes are small and isolated to sys/netinet/ip_nat.c
Diffs below are against -r HEAD in the tree.  Would openbsd
be interested in merging these in, and if so, is there anything
more needed from me other than these patches? 


Index: ip_nat.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_nat.c,v
retrieving revision 1.35
diff -u -3 -r1.35 ip_nat.c
--- ip_nat.c	2000/08/10 15:43:20	1.35
+++ ip_nat.c	2000/12/12 02:04:11
@@ -778,7 +778,13 @@
 				}
 			}
 
-			if (np->in_redir & NAT_MAPBLK) {
+			if(np->in_redir == NAT_BIMAP && 
+					np->in_inmsk == np->in_outmsk) {
+				/* map the address block in a 1:1 fashion */
+				in.s_addr = np->in_outip;
+				in.s_addr |= ip->ip_src.s_addr & ~np->in_inmsk;
+				in.s_addr = ntohl(in.s_addr);
+			} else if (np->in_redir & NAT_MAPBLK) {
 				if ((l >= np->in_ppip) || ((l > 0) &&
 				     !(flags & IPN_TCPUDP))) {
 					KFREE(nat);
@@ -939,6 +945,12 @@
 		if ((in.s_addr == 0) && (nport == dport)) {
 			KFREE(nat);
 			return NULL;
+		}
+
+		if(np->in_redir == NAT_BIMAP && 
+				np->in_inmsk == np->in_outmsk) {
+			/* map the address block in a 1:1 fashion */
+			in.s_addr |= ntohl(ip->ip_dst.s_addr & ~np->in_inmsk);
 		}
 
 		nat->nat_inip.s_addr = htonl(in.s_addr);





Visit your host, monkey.org