Subject: Re: IPNAT trouble - system crashes (fwd)
To: Roger Fischer <roger@badger1.net>
From: Scott Reynolds <scottr@og.org>
List: port-mac68k
Date: 05/23/1998 09:08:48
hi folks.
there's a pretty serious problem in the NAT code when translating to a
single IP address, as in the case of NATing through a PPP link. this
problem has been fixed for almost 2 months in NetBSD-current, but hasn't
been pulled down to the release branch due to an oversight on my part.
here's the change, which should apply directly to a 1.3 or 1.3.1 source
tree.
--scott
Index: sys/netinet/ip_nat.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_nat.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -c -r1.16 -r1.17
*** ip_nat.c 1997/11/25 03:14:11 1.16
--- ip_nat.c 1998/03/29 22:56:00 1.17
***************
*** 11,17 ****
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed";
! static const char rcsid[] = "@(#)Id: ip_nat.c,v 2.0.2.44.2.6 1997/11/24 11:35:13 darrenr Exp ";
#endif
#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL)
--- 11,17 ----
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed";
! static const char rcsid[] = "@(#)Id: ip_nat.c,v 2.0.2.44.2.7 1997/12/02 13:54:27 darrenr Exp ";
#endif
#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL)
***************
*** 523,529 ****
u_short flags;
int direction;
{
! register u_long sum1, sum2, sumd;
u_short port = 0, sport = 0, dport = 0, nport = 0;
struct in_addr in;
tcphdr_t *tcp = NULL;
--- 523,529 ----
u_short flags;
int direction;
{
! register u_long sum1, sum2, sumd, l;
u_short port = 0, sport = 0, dport = 0, nport = 0;
struct in_addr in;
tcphdr_t *tcp = NULL;
***************
*** 553,565 ****
* If it's an outbound packet which doesn't match any existing
* record, then create a new port
*/
do {
port = 0;
in.s_addr = np->in_nip;
if (!in.s_addr && (np->in_outmsk == 0xffffffff)) {
! if (nat_ifpaddr(nat, fin->fin_ifp, &in) == -1)
return NULL;
} else if (!in.s_addr && !np->in_outmsk) {
in.s_addr = ntohl(ip->ip_src.s_addr);
if (nflags & IPN_TCPUDP)
port = sport;
--- 553,574 ----
* If it's an outbound packet which doesn't match any existing
* record, then create a new port
*/
+ l = 0;
do {
+ l++;
port = 0;
in.s_addr = np->in_nip;
if (!in.s_addr && (np->in_outmsk == 0xffffffff)) {
! if ((l > 1) ||
! nat_ifpaddr(nat, fin->fin_ifp, &in) == -1) {
! KFREE(nat);
return NULL;
+ }
} else if (!in.s_addr && !np->in_outmsk) {
+ if (l > 1) {
+ KFREE(nat);
+ return NULL;
+ }
in.s_addr = ntohl(ip->ip_src.s_addr);
if (nflags & IPN_TCPUDP)
port = sport;