This commit was generated by cvs2svn to compensate for changes in r67615,

which included commits to RCS files with non-trunk default branches.
This commit is contained in:
Darren Reed 2000-10-26 12:45:54 +00:00
commit c5de53b9a7
27 changed files with 1374 additions and 625 deletions

View File

@ -11,7 +11,7 @@ proto = "proto" protocol .
ip = srcdst [ flags ] [ with withopt ] [ icmp ] [ keep ] .
group = [ "head" decnumber ] [ "group" decnumber ] .
block = "block" [ icmp [return-code] | "return-rst" ] .
block = "block" [ reutrn-icmp[return-code] | "return-rst" ] .
auth = "auth" | "preauth" .
log = "log" [ "body" ] [ "first" ] [ "or-block" ] [ "level" loglevel ] .
call = "call" [ "now" ] function-name .
@ -22,7 +22,7 @@ protocol = "tcp/udp" | "udp" | "tcp" | "icmp" | decnumber .
srcdst = "all" | fromto .
fromto = "from" object "to" object .
icmp = "return-icmp" | "return-icmp-as-dest" .
reutrn-icmp = "return-icmp" | "return-icmp-as-dest" .
loglevel = facility"."priority | priority .
object = addr [ port-comp | port-range ] .
addr = "any" | nummask | host-name [ "mask" ipaddr | "mask" hexnumber ] .

View File

@ -0,0 +1,61 @@
*** ip6_input.c.orig Sun Feb 13 14:32:01 2000
--- ip6_input.c Wed Apr 26 22:31:34 2000
***************
*** 121,126 ****
--- 121,127 ----
extern struct domain inet6domain;
extern struct ip6protosw inet6sw[];
+ extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **));
u_char ip6_protox[IPPROTO_MAX];
static int ip6qmaxlen = IFQ_MAXLEN;
***************
*** 302,307 ****
--- 303,317 ----
ip6stat.ip6s_badvers++;
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);
goto bad;
+ }
+
+ if (fr_checkp) {
+ struct mbuf *m1 = m;
+
+ if ((*fr_checkp)(ip6, sizeof(*ip6), m->m_pkthdr.rcvif,
+ 0, &m1) || !m1)
+ return;
+ ip6 = mtod(m = m1, struct ip6_hdr *);
}
ip6stat.ip6s_nxthist[ip6->ip6_nxt]++;
*** ip6_output.c.orig Fri Mar 10 01:57:16 2000
--- ip6_output.c Wed Apr 26 22:34:34 2000
***************
*** 108,113 ****
--- 108,115 ----
#include <netinet6/ip6_fw.h>
#endif
+ extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **));
+
static MALLOC_DEFINE(M_IPMOPTS, "ip6_moptions", "internet multicast options");
struct ip6_exthdrs {
***************
*** 754,759 ****
--- 756,770 ----
ip6->ip6_src.s6_addr16[1] = 0;
if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst))
ip6->ip6_dst.s6_addr16[1] = 0;
+ }
+
+ if (fr_checkp) {
+ struct mbuf *m1 = m;
+
+ if ((error = (*fr_checkp)(ip6, sizeof(*ip6), ifp, 1, &m1)) ||
+ !m1)
+ goto done;
+ ip6 = mtod(m = m1, struct ip6_hdr *);
}
#ifdef IPV6FIREWALL

View File

@ -0,0 +1,63 @@
*** ip6_input.c.orig Sat Jul 15 07:14:34 2000
--- ip6_input.c Thu Oct 19 17:14:37 2000
***************
*** 120,125 ****
--- 120,127 ----
extern struct domain inet6domain;
extern struct ip6protosw inet6sw[];
+ extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int,
+ struct mbuf **));
u_char ip6_protox[IPPROTO_MAX];
static int ip6qmaxlen = IFQ_MAXLEN;
***************
*** 289,294 ****
--- 291,305 ----
ip6stat.ip6s_badvers++;
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);
goto bad;
+ }
+
+ if (fr_checkp) {
+ struct mbuf *m1 = m;
+
+ if ((*fr_checkp)(ip6, sizeof(*ip6), m->m_pkthdr.rcvif,
+ 0, &m1) || !m1)
+ return;
+ ip6 = mtod(m = m1, struct ip6_hdr *);
}
ip6stat.ip6s_nxthist[ip6->ip6_nxt]++;
*** ip6_output.c.orig Sat Jul 15 07:14:35 2000
--- ip6_output.c Thu Oct 19 17:13:53 2000
***************
*** 106,111 ****
--- 106,113 ----
#include <netinet6/ip6_fw.h>
#endif
+ extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **));
+
static MALLOC_DEFINE(M_IPMOPTS, "ip6_moptions", "internet multicast options");
struct ip6_exthdrs {
***************
*** 787,792 ****
--- 789,803 ----
ip6->ip6_src.s6_addr16[1] = 0;
if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst))
ip6->ip6_dst.s6_addr16[1] = 0;
+ }
+
+ if (fr_checkp) {
+ struct mbuf *m1 = m;
+
+ if ((error = (*fr_checkp)(ip6, sizeof(*ip6), ifp, 1, &m1)) ||
+ !m1)
+ goto done;
+ ip6 = mtod(m = m1, struct ip6_hdr *);
}
#ifdef IPV6FIREWALL

View File

@ -2,6 +2,7 @@
#
set dir=`pwd`
set karch=`uname -m`
set krev=`uname -r|sed -e 's/\([0-9\.]*\)-.*/\1/'`
if ( -d /sys/arch/$karch ) set archdir="/sys/arch/$karch"
if ( -d /sys/$karch ) set archdir="/sys/$karch"
set confdir="$archdir/conf"
@ -21,7 +22,7 @@ ln -s /usr/include/osreldate.h /sys/sys/osreldate.h
echo ""
echo "Patching ip6_input.c and ip6_output.c"
cat FreeBSD-4.0/ipv6-patch | (cd /sys/netinet6; patch)
cat FreeBSD-4.0/ipv6-patch-$krev | (cd /sys/netinet6; patch)
set config=`(cd $confdir; /bin/ls -1t [0-9A-Z_]*) | head -1`
echo -n "Kernel configuration to update [$config] "
@ -31,6 +32,11 @@ if ( "$newconfig" != "" ) then
else
set newconfig=$config
endif
grep -q IPFILTER $confdir/$newconfig
if ($status == 0) then
echo "IPFilter already configured in kernel config file"
exit 0
endif
echo "Rewriting $newconfig..."
if ( -f $confdir/$newconfig ) then
mv $confdir/$newconfig $confdir/$newconfig.bak

View File

@ -3,6 +3,7 @@
#
set dir=`pwd`
set karch=`uname -m`
set krev=`uname -r|sed -e 's/\([0-9\.]*\)-.*/\1/'`
if ( -d /sys/arch/$karch ) set archdir="/sys/arch/$karch"
if ( -d /sys/$karch ) set archdir="/sys/$karch"
set confdir="$archdir/conf"
@ -21,7 +22,7 @@ echo "Removing link from /usr/include/osreldate.h to /sys/sys/osreldate.h"
rm /sys/sys/osreldate.h
echo "Removing patch to ip6_input.c and ip6_output.c"
cat FreeBSD-4.0/ipv6-patch | (cd /sys/netinet6; patch -R)
cat FreeBSD-4.0/ipv6-patch-$krev | (cd /sys/netinet6; patch -R)
set config=`(cd $confdir; /bin/ls -1t [0-9A-Z_]*) | head -1`
echo -n "Kernel configuration to update [$config] "

View File

@ -6,9 +6,11 @@
# in providing a very available location for the IP Filter home page and
# distribution center.
#
# Thanks to Tel.Net Media for allowing me to maintain and further develop
# IP Filter as part of my job and supplying Sun equipment for testing the
# move to 64bits and Gigabit Ethernet.
# Thanks to Hewlett Packard for making it possible to port IP Filter to
# HP-UX 11.00.
#
# Thanks to Tel.Net Media for supplying me with equipment to ensure that
# IP Filter continues to work on Solaris/sparc64.
#
# Thanks to BSDI for providing object files for BSD/OS 3.1 and the means
# to further support development of IP Filter under BSDI.
@ -20,6 +22,50 @@
# and especially those who have found the time to port IP Filter to new
# platforms.
#
3.4.12 26/10/2000 - Released
fix installing into FreeBSD-4.1
fix FTP proxy bug where it'd hang and make NAT slightly more efficient
fix general compiling errors/warnings on various platforms
don't access ICMP data fields that aren't there
3.4.11 09/10/2000 - Released
return NULL for IPv6 access control lists if it is disabled rather than
random garbage.
fix for getting protocol & packet length for IPv6 packets for pullup.
update plog script from version 0.8 to version 0.10
patch from Frank Volf adding fix_datacksum() to NAT code, enhancing the
capabilities for "fixing" checksums.
3.4.10 03/09/2000 - Released
merge patch from Frank Volf for ICMP nat handling of TCP/UDP data `errors'
getline() adjusts linenum now
add tcphalfclosed timeout
fill in icmp_nextmtu field if it is defined on the platform
RST generation fix from guido
force 32bit compile for gcc on solaris if it can't generate 64bit code
encase logging when fr_chksrc == 2 in #ifdef IPFILTER_LOG
fix up line wrap problems in plog script
fix ICMP packet handling to not drop valid ICMP errors
freebsd 5.0 compat changes
3.4.9 08/08/2000 - Released
implement new aging mechanism in fr_tcp_age()

View File

@ -5,7 +5,7 @@
# provided that this notice is preserved and due credit is given
# to the original author and the contributors.
#
# $Id: Makefile,v 2.11.2.3 2000/08/05 14:50:00 darrenr Exp $
# $Id: Makefile,v 2.11.2.4 2000/10/19 15:42:56 darrenr Exp $
#
BINDEST=/usr/local/bin
SBINDEST=/sbin
@ -16,7 +16,7 @@ CC=gcc -Wstrict-prototypes -Wmissing-prototypes
#CC=cc -Dconst=
DEBUG=-g
TOP=../..
CFLAGS=-I$$(TOP) -g
CFLAGS=-I$$(TOP)
CPU=`uname -m`
CPUDIR=`uname -s|sed -e 's@/@@g'`-`uname -r`-`uname -m`
#
@ -169,8 +169,8 @@ bsdi bsdos: include
irix IRIX: include
make setup "TARGOS=IRIX" "CPUDIR=$(CPUDIR)"
(cd IRIX/$(CPUDIR); smake build TOP=../.. $(DEST) $(MFLAGS); cd ..)
(cd IRIX/$(CPUDIR); make -f Makefile.ipsend TOP=../.. $(DEST) $(MFLAGS); cd ..)
-(SMAKE=`which smake >/dev/null 2>&1; if [ $$? -ne 0 ] ; then echo make -f Makefile.std; else echo smake; fi`; cd IRIX/$(CPUDIR); $${SMAKE} build TOP=../.. $(DEST) $(MFLAGS); cd ..)
-(SMAKE=`which smake >/dev/null 2>&1; if [ $$? -ne 0 ] ; then echo make -f Makefile.ipsend.std; else echo smake -f Makefile.ipsend; fi`; cd IRIX/$(CPUDIR); $${SMAKE} TOP=../.. $(DEST) $(MFLAGS); cd ..)
linux: include
make setup "TARGOS=Linux" "CPUDIR=$(CPUDIR)"
@ -184,6 +184,14 @@ setup:
-if [ ! -d $(TARGOS)/$(CPUDIR) ] ; then mkdir $(TARGOS)/$(CPUDIR); fi
-rm -f $(TARGOS)/$(CPUDIR)/Makefile $(TARGOS)/$(CPUDIR)/Makefile.ipsend
-ln -s ../Makefile $(TARGOS)/$(CPUDIR)/Makefile
-if [ ! -f $(TARGOS)/$(CPUDIR)/Makefile.std -a \
-f $(TARGOS)/Makefile.std ] ; then \
ln -s ../Makefile.std $(TARGOS)/$(CPUDIR)/Makefile.std; \
fi
-if [ ! -f $(TARGOS)/$(CPUDIR)/Makefile.ipsend.std -a \
-f $(TARGOS)/Makefile.ipsend.std ] ; then \
ln -s ../Makefile.ipsend.std $(TARGOS)/$(CPUDIR)/Makefile.ipsend.std; \
fi
-ln -s ../Makefile.ipsend $(TARGOS)/$(CPUDIR)/Makefile.ipsend
clean: clean-include

View File

@ -274,7 +274,7 @@ int linenum;
return 0;
if (!strcasecmp(**seg, "port") && *(*seg + 1) && *(*seg + 2)) {
(*seg)++;
if (isdigit(***seg) && *(*seg + 2)) {
if (isalnum(***seg) && *(*seg + 2)) {
if (portnum(**seg, pp, linenum) == 0)
return -1;
(*seg)++;

View File

@ -5,7 +5,7 @@
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* $Id: ip_auth.h,v 2.3.2.1 2000/05/22 10:26:11 darrenr Exp $
* $Id: ip_auth.h,v 2.3.2.2 2000/10/19 15:38:44 darrenr Exp $
*
*/
#ifndef __IP_AUTH_H__
@ -46,8 +46,6 @@ typedef struct fr_authstat {
extern frentry_t *ipauth;
extern struct fr_authstat fr_authstats;
extern int fr_defaultauthage;
extern int fr_authstart;
extern int fr_authend;
extern int fr_authsize;
extern int fr_authused;
extern int fr_auth_lock;

View File

@ -6,7 +6,7 @@
* to the original author and the contributors.
*
* @(#)ip_compat.h 1.8 1/14/96
* $Id: ip_compat.h,v 2.26.2.4 2000/08/13 03:51:03 darrenr Exp $
* $Id: ip_compat.h,v 2.26.2.6 2000/10/19 15:39:05 darrenr Exp $
*/
#ifndef __IP_COMPAT_H__
@ -263,6 +263,12 @@ union i6addr {
#if defined(__FreeBSD__) && (defined(KERNEL) || defined(_KERNEL))
# ifdef IPFILTER_LKM
# include <osreldate.h>
# define ACTUALLY_LKM_NOT_KERNEL
# else
# include <sys/osreldate.h>
# endif
# if __FreeBSD__ < 3
# include <machine/spl.h>
# else
@ -288,6 +294,19 @@ union i6addr {
# define ATOMIC_DEC32 ATOMIC_DEC
# define ATOMIC_DEC16 ATOMIC_DEC
#endif
#ifdef __sgi
# define hz HZ
# include <sys/ksynch.h>
# define IPF_LOCK_PL plhi
# include <sys/sema.h>
#undef kmutex_t
typedef struct {
lock_t *l;
int pl;
} kmutex_t;
# undef MUTEX_INIT
# undef MUTEX_DESTROY
#endif
#ifdef KERNEL
# if SOLARIS
# if SOLARIS2 >= 6
@ -337,8 +356,8 @@ union i6addr {
# define MUTEX_DESTROY(x) mutex_destroy(x)
# define MUTEX_EXIT(x) mutex_exit(x)
# define MTOD(m,t) (t)((m)->b_rptr)
# define IRCOPY(a,b,c) copyin((a), (b), (c))
# define IWCOPY(a,b,c) copyout((a), (b), (c))
# define IRCOPY(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c))
# define IWCOPY(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c))
# define IRCOPYPTR ircopyptr
# define IWCOPYPTR iwcopyptr
# define FREE_MB_T(m) freemsg(m)
@ -383,15 +402,6 @@ extern ill_t *get_unit __P((char *, int));
# define IFNAME(x) ((ill_t *)x)->ill_name
# else /* SOLARIS */
# if defined(__sgi)
# define hz HZ
# include <sys/ksynch.h>
# define IPF_LOCK_PL plhi
# include <sys/sema.h>
#undef kmutex_t
typedef struct {
lock_t *l;
int pl;
} kmutex_t;
# define ATOMIC_INC(x) { MUTEX_ENTER(&ipf_rw); \
(x)++; MUTEX_EXIT(&ipf_rw); }
# define ATOMIC_DEC(x) { MUTEX_ENTER(&ipf_rw); \
@ -404,8 +414,8 @@ typedef struct {
# define MUTEX_DOWNGRADE(x) ;
# define RWLOCK_EXIT(x) MUTEX_EXIT(x)
# define MUTEX_EXIT(x) UNLOCK((x)->l, (x)->pl);
# define MUTEX_INIT(x,y,z) (x).l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP)
# define MUTEX_DESTROY(x) LOCK_DEALLOC((x).l)
# define MUTEX_INIT(x,y,z) (x)->l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP)
# define MUTEX_DESTROY(x) LOCK_DEALLOC((x)->l)
# else /* __sgi */
# define ATOMIC_INC(x) (x)++
# define ATOMIC_DEC(x) (x)--

View File

@ -7,7 +7,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.42.2.15 2000/08/05 14:49:08 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.42.2.17 2000/10/19 15:39:42 darrenr Exp $";
#endif
#ifndef SOLARIS
@ -171,6 +171,9 @@ struct callout_handle ipfr_slowtimer_ch;
# include <sys/callout.h>
struct callout ipfr_slowtimer_ch;
#endif
#if defined(__sgi) && defined(_KERNEL)
toid_t ipfr_slowtimer_ch;
#endif
#if (_BSDI_VERSION >= 199510) && defined(_KERNEL)
# include <sys/device.h>
@ -318,7 +321,7 @@ int iplattach()
callout_init(&ipfr_slowtimer_ch);
callout_reset(&ipfr_slowtimer_ch, hz / 2, ipfr_slowtimer, NULL);
# else
# if (__FreeBSD_version >= 300000) && defined(_KERNEL)
# if (__FreeBSD_version >= 300000) || defined(__sgi)
ipfr_slowtimer_ch = timeout(ipfr_slowtimer, NULL, hz/2);
# else
timeout(ipfr_slowtimer, NULL, hz/2);
@ -348,7 +351,7 @@ int ipldetach()
untimeout(ipfr_slowtimer, NULL, ipfr_slowtimer_ch);
# else
# ifdef __sgi
untimeout(ipfr_slowtimer);
untimeout(ipfr_slowtimer_ch);
# else
untimeout(ipfr_slowtimer, NULL);
# endif
@ -975,8 +978,10 @@ fr_info_t *fin;
if (m == NULL)
return -1;
if (tcp->th_flags & TH_SYN)
tlen = 1;
tlen = oip->ip_len - fin->fin_hlen - (tcp->th_off << 2) +
((tcp->th_flags & TH_SYN) ? 1 : 0) +
((tcp->th_flags & TH_FIN) ? 1 : 0);
#ifdef USE_INET6
hlen = (fin->fin_v == 6) ? sizeof(ip6_t) : sizeof(ip_t);
#else
@ -997,11 +1002,16 @@ fr_info_t *fin;
tcp2->th_sport = tcp->th_dport;
tcp2->th_dport = tcp->th_sport;
tcp2->th_ack = ntohl(tcp->th_seq);
tcp2->th_ack += tlen;
tcp2->th_ack = htonl(tcp2->th_ack);
if (tcp->th_flags & TH_ACK) {
tcp2->th_seq = tcp->th_ack;
tcp2->th_flags = TH_RST;
} else {
tcp2->th_ack = ntohl(tcp->th_seq);
tcp2->th_ack += tlen;
tcp2->th_ack = htonl(tcp2->th_ack);
tcp2->th_flags = TH_RST|TH_ACK;
}
tcp2->th_off = sizeof(*tcp2) >> 2;
tcp2->th_flags = TH_RST|TH_ACK;
# ifdef USE_INET6
if (fin->fin_v == 6) {
ip6->ip6_plen = htons(sizeof(struct tcphdr));
@ -1143,7 +1153,12 @@ int dst;
m_freem(m);
return ENOBUFS;
}
# ifdef M_TRAILINGSPACE
m->m_len = 0;
avail = M_TRAILINGSPACE(m);
# else
avail = (m->m_flags & M_EXT) ? MCLBYTES : MHLEN;
# endif
xtra = MIN(ntohs(oip6->ip6_plen) + sizeof(ip6_t),
avail - hlen - sizeof(*icmp) - max_linkhdr);
if (dst == 0) {
@ -1177,6 +1192,12 @@ int dst;
icmp->icmp_type = type;
icmp->icmp_code = fin->fin_icode;
icmp->icmp_cksum = 0;
#ifdef icmp_nextmtu
if (type == ICMP_UNREACH &&
fin->fin_icode == ICMP_UNREACH_NEEDFRAG && ifp)
icmp->icmp_nextmtu = htons(((struct ifnet *) ifp)->if_mtu);
#endif
if (avail) {
bcopy((char *)oip, (char *)&icmp->icmp_ip, MIN(ohlen, avail));
avail -= MIN(ohlen, avail);

View File

@ -7,7 +7,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.10.2.4 2000/06/06 15:49:15 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.10.2.5 2000/10/19 15:39:58 darrenr Exp $";
#endif
#if defined(KERNEL) && !defined(_KERNEL)
@ -214,7 +214,7 @@ u_int pass;
ipfr_t *ipf;
if ((ip->ip_v != 4) || (fr_frag_lock))
return NULL;
return -1;
WRITE_ENTER(&ipf_frag);
ipf = ipfr_new(ip, fin, pass, ipfr_heads);
RWLOCK_EXIT(&ipf_frag);
@ -231,7 +231,7 @@ nat_t *nat;
ipfr_t *ipf;
if ((ip->ip_v != 4) || (fr_frag_lock))
return NULL;
return -1;
WRITE_ENTER(&ipf_natfrag);
ipf = ipfr_new(ip, fin, pass, ipfr_nattab);
if (ipf != NULL) {
@ -328,13 +328,16 @@ fr_info_t *fin;
ipf = ipfr_lookup(ip, fin, ipfr_nattab);
if (ipf != NULL) {
nat = ipf->ipfr_data;
/*
* This is the last fragment for this packet.
*/
if ((ipf->ipfr_ttl == 1) && (nat != NULL)) {
nat->nat_data = NULL;
ipf->ipfr_data = NULL;
}
if (nat->nat_ifp == fin->fin_ifp) {
/*
* This is the last fragment for this packet.
*/
if ((ipf->ipfr_ttl == 1) && (nat != NULL)) {
nat->nat_data = NULL;
ipf->ipfr_data = NULL;
}
} else
nat = NULL;
} else
nat = NULL;
RWLOCK_EXIT(&ipf_natfrag);

View File

@ -6,7 +6,7 @@
* to the original author and the contributors.
*
* @(#)ip_frag.h 1.5 3/24/96
* $Id: ip_frag.h,v 2.4 2000/03/13 22:10:21 darrenr Exp $
* $Id: ip_frag.h,v 2.4.2.1 2000/10/19 15:40:13 darrenr Exp $
*/
#ifndef __IP_FRAG_H__
@ -60,6 +60,6 @@ extern void ipfr_slowtimer __P((void *));
# endif
#else
extern int ipfr_slowtimer __P((void));
#endif
#endif /* (BSD >= 199306) || SOLARIS */
#endif /* __IP_FIL_H__ */

View File

@ -2,7 +2,7 @@
* Simple FTP transparent proxy for in-kernel use. For use with the NAT
* code.
*
* $Id: ip_ftp_pxy.c,v 2.7.2.13 2000/08/07 12:35:27 darrenr Exp $
* $Id: ip_ftp_pxy.c,v 2.7.2.17 2000/10/19 15:40:40 darrenr Exp $
*/
#if SOLARIS && defined(_KERNEL)
extern kmutex_t ipf_rw;
@ -146,6 +146,7 @@ int dlen;
} else
return 0;
a5 >>= 8;
a5 &= 0xff;
/*
* Calculate new address parts for PORT command
*/
@ -214,7 +215,7 @@ int dlen;
sum2 -= sum1;
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
fix_outcksum(&ip->ip_sum, sum2, 0);
fix_outcksum(&ip->ip_sum, sum2);
#endif
ip->ip_len += inc;
}
@ -441,7 +442,7 @@ int dlen;
sum2 -= sum1;
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
fix_outcksum(&ip->ip_sum, sum2, 0);
fix_outcksum(&ip->ip_sum, sum2);
#endif /* SOLARIS || defined(__sgi) */
ip->ip_len += inc;
}
@ -670,15 +671,18 @@ int rv;
while ((rptr < wptr) && (*rptr != '\r'))
rptr++;
if ((*rptr == '\r') && (rptr + 1 < wptr)) {
if (*(rptr + 1) == '\n') {
rptr += 2;
f->ftps_junk = 0;
if (*rptr == '\r') {
if (rptr + 1 < wptr) {
if (*(rptr + 1) == '\n') {
rptr += 2;
f->ftps_junk = 0;
} else
rptr++;
} else
rptr++;
break;
}
f->ftps_rptr = rptr;
}
f->ftps_rptr = rptr;
if (rptr == wptr) {
rptr = wptr = f->ftps_buf;
@ -762,5 +766,7 @@ char **ptr;
j += c - '0';
}
*ptr = s;
i &= 0xff;
j &= 0xff;
return (i << 8) | j;
}

View File

@ -9,7 +9,7 @@
*/
#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.37.2.21 2000/08/12 07:32:40 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.37.2.25 2000/10/25 10:38:47 darrenr Exp $";
#endif
#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL)
@ -118,6 +118,7 @@ u_int ipf_nattable_sz = NAT_TABLE_SZ;
u_int ipf_natrules_sz = NAT_SIZE;
u_int ipf_rdrrules_sz = RDR_SIZE;
u_int ipf_hostmap_sz = HOSTMAP_SIZE;
int nat_wilds = 0;
u_32_t nat_masks = 0;
u_32_t rdr_masks = 0;
ipnat_t **nat_rules = NULL;
@ -143,6 +144,7 @@ static void nat_delnat __P((struct ipnat *));
static int fr_natgetent __P((caddr_t));
static int fr_natgetsz __P((caddr_t));
static int fr_natputent __P((caddr_t));
static void nat_tabmove __P((nat_t *, u_int));
static int nat_match __P((fr_info_t *, ipnat_t *, ip_t *));
static hostmap_t *nat_hostmap __P((ipnat_t *, struct in_addr,
struct in_addr));
@ -300,10 +302,9 @@ struct hostmap *hm;
}
void fix_outcksum(sp, n , len)
void fix_outcksum(sp, n)
u_short *sp;
u_32_t n;
int len;
{
register u_short sumshort;
register u_32_t sum1;
@ -326,10 +327,9 @@ int len;
}
void fix_incksum(sp, n , len)
void fix_incksum(sp, n)
u_short *sp;
u_32_t n;
int len;
{
register u_short sumshort;
register u_32_t sum1;
@ -356,6 +356,38 @@ int len;
}
/*
* fix_datacksum is used *only* for the adjustments of checksums in the data
* section of an IP packet.
*
* The only situation in which you need to do this is when NAT'ing an
* ICMP error message. Such a message, contains in its body the IP header
* of the original IP packet, that causes the error.
*
* You can't use fix_incksum or fix_outcksum in that case, because for the
* kernel the data section of the ICMP error is just data, and no special
* processing like hardware cksum or ntohs processing have been done by the
* kernel on the data section.
*/
void fix_datacksum(sp, n)
u_short *sp;
u_32_t n;
{
register u_short sumshort;
register u_32_t sum1;
if (!n)
return;
sum1 = (~ntohs(*sp)) & 0xffff;
sum1 += (n);
sum1 = (sum1 >> 16) + (sum1 & 0xffff);
/* Again */
sum1 = (sum1 >> 16) + (sum1 & 0xffff);
sumshort = ~(u_short)sum1;
*(sp) = htons(sumshort);
}
/*
* How the NAT is organised and works.
*
@ -856,8 +888,8 @@ caddr_t data;
/*
* Initialize all these so that nat_delete() doesn't cause a crash.
*/
nat->nat_hstart[0] = NULL;
nat->nat_hstart[1] = NULL;
nat->nat_phnext[0] = NULL;
nat->nat_phnext[1] = NULL;
fr = nat->nat_fr;
nat->nat_fr = NULL;
aps = nat->nat_aps;
@ -969,22 +1001,16 @@ caddr_t data;
static void nat_delete(natd)
struct nat *natd;
{
register struct nat **natp, *nat;
struct ipnat *ipn;
for (natp = natd->nat_hstart[0]; natp && (nat = *natp);
natp = &nat->nat_hnext[0])
if (nat == natd) {
*natp = nat->nat_hnext[0];
break;
}
for (natp = natd->nat_hstart[1]; natp && (nat = *natp);
natp = &nat->nat_hnext[1])
if (nat == natd) {
*natp = nat->nat_hnext[1];
break;
}
if (natd->nat_flags & FI_WILDP)
nat_wilds--;
if (natd->nat_hnext[0])
natd->nat_hnext[0]->nat_phnext[0] = natd->nat_phnext[0];
*natd->nat_phnext[0] = natd->nat_hnext[0];
if (natd->nat_hnext[1])
natd->nat_hnext[1]->nat_phnext[1] = natd->nat_phnext[1];
*natd->nat_phnext[1] = natd->nat_hnext[1];
if (natd->nat_fr != NULL) {
ATOMIC_DEC32(natd->nat_fr->fr_ref);
@ -1029,7 +1055,7 @@ static int nat_flushtable()
{
register nat_t *nat, **natp;
register int j = 0;
/*
* ALL NAT mappings deleted, so lets just make the deletions
* quicker.
@ -1121,6 +1147,8 @@ int direction;
bzero((char *)nat, sizeof(*nat));
nat->nat_flags = flags;
if (flags & FI_WILDP)
nat_wilds++;
/*
* Search the current table for a match.
*/
@ -1443,16 +1471,22 @@ nat_t *nat;
nat->nat_next = nat_instances;
nat_instances = nat;
hv = NAT_HASH_FN(nat->nat_inip.s_addr, nat->nat_inport,
ipf_nattable_sz);
natp = &nat_table[0][hv];
nat->nat_hstart[0] = natp;
if (*natp)
(*natp)->nat_phnext[0] = &nat->nat_hnext[0];
nat->nat_phnext[0] = natp;
nat->nat_hnext[0] = *natp;
*natp = nat;
hv = NAT_HASH_FN(nat->nat_outip.s_addr, nat->nat_outport,
ipf_nattable_sz);
natp = &nat_table[1][hv];
nat->nat_hstart[1] = natp;
if (*natp)
(*natp)->nat_phnext[1] = &nat->nat_hnext[1];
nat->nat_phnext[1] = natp;
nat->nat_hnext[1] = *natp;
*natp = nat;
@ -1560,12 +1594,16 @@ int dir;
u_32_t sum1, sum2, sumd;
struct in_addr in;
icmphdr_t *icmp;
udphdr_t *udp;
nat_t *nat;
ip_t *oip;
int flags = 0;
if ((fin->fin_fi.fi_fl & FI_SHORT) || (ip->ip_off & IP_OFFMASK))
return NULL;
/*
* nat_icmplookup() will return NULL for `defective' packets.
*/
if ((ip->ip_v != 4) || !(nat = nat_icmplookup(ip, fin, dir)))
return NULL;
*nflags = IPN_ICMPERR;
@ -1575,16 +1613,33 @@ int dir;
flags = IPN_TCP;
else if (oip->ip_p == IPPROTO_UDP)
flags = IPN_UDP;
udp = (udphdr_t *)((((char *)oip) + (oip->ip_hl << 2)));
/*
* Need to adjust ICMP header to include the real IP#'s and
* port #'s. Only apply a checksum change relative to the
* IP address change is it will be modified again in ip_natout
* IP address change as it will be modified again in ip_natout
* for both address and port. Two checksum changes are
* necessary for the two header address changes. Be careful
* to only modify the checksum once for the port # and twice
* for the IP#.
*/
/*
* Step 1
* Fix the IP addresses in the offending IP packet. You also need
* to adjust the IP header checksum of that offending IP packet
* and the ICMP checksum of the ICMP error message itself.
*
* Unfortunately, for UDP and TCP, the IP addresses are also contained
* in the pseudo header that is used to compute the UDP resp. TCP
* checksum. So, we must compensate that as well. Even worse, the
* change in the UDP and TCP checksums require yet another
* adjustment of the ICMP checksum of the ICMP error message.
*
* For the moment we forget about TCP, because that checksum is not
* in the first 8 bytes, so it will not be available in most cases.
*/
if (nat->nat_dir == NAT_OUTBOUND) {
sum1 = LONG_SUM(ntohl(oip->ip_src.s_addr));
in = nat->nat_inip;
@ -1600,19 +1655,117 @@ int dir;
CALC_SUMD(sum1, sum2, sumd);
if (nat->nat_dir == NAT_OUTBOUND) {
fix_incksum(&oip->ip_sum, sumd, 0);
/*
* Fix IP checksum of the offending IP packet to adjust for
* the change in the IP address.
*
* Normally, you would expect that the ICMP checksum of the
* ICMP error message needs to be adjusted as well for the
* IP address change in oip.
* However, this is a NOP, because the ICMP checksum is
* calculated over the complete ICMP packet, which includes the
* changed oip IP addresses and oip->ip_sum. However, these
* two changes cancel each other out (if the delta for
* the IP address is x, then the delta for ip_sum is minus x),
* so no change in the icmp_cksum is necessary.
*
* Be careful that nat_dir refers to the direction of the
* offending IP packet (oip), not to its ICMP response (icmp)
*/
fix_datacksum(&oip->ip_sum, sumd);
sumd += (sumd & 0xffff);
while (sumd > 0xffff)
sumd = (sumd & 0xffff) + (sumd >> 16);
fix_outcksum(&icmp->icmp_cksum, sumd, 0);
/*
* Fix UDP pseudo header checksum to compensate for the
* IP address change.
*/
if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
/*
* The UDP checksum is optional, only adjust it
* if it has been set.
*/
sum1 = ntohs(udp->uh_sum);
fix_datacksum(&udp->uh_sum, sumd);
sum2 = ntohs(udp->uh_sum);
/*
* Fix ICMP checksum to compensate the UDP
* checksum adjustment.
*/
CALC_SUMD(sum1, sum2, sumd);
fix_outcksum(&icmp->icmp_cksum, sumd);
}
#if 0
/*
* Fix TCP pseudo header checksum to compensate for the
* IP address change. Before we can do the change, we
* must make sure that oip is sufficient large to hold
* the TCP checksum (normally it does not!).
*/
if (oip->ip_p == IPPROTO_TCP) {
}
#endif
} else {
fix_outcksum(&oip->ip_sum, sumd, 0);
/*
* Fix IP checksum of the offending IP packet to adjust for
* the change in the IP address.
*
* Normally, you would expect that the ICMP checksum of the
* ICMP error message needs to be adjusted as well for the
* IP address change in oip.
* However, this is a NOP, because the ICMP checksum is
* calculated over the complete ICMP packet, which includes the
* changed oip IP addresses and oip->ip_sum. However, these
* two changes cancel each other out (if the delta for
* the IP address is x, then the delta for ip_sum is minus x),
* so no change in the icmp_cksum is necessary.
*
* Be careful that nat_dir refers to the direction of the
* offending IP packet (oip), not to its ICMP response (icmp)
*/
fix_datacksum(&oip->ip_sum, sumd);
/* XXX FV : without having looked at Solaris source code, it seems unlikely
* that SOLARIS would compensate this in the kernel (a body of an IP packet
* in the data section of an ICMP packet). I have the feeling that this should
* be unconditional, but I'm not in a position to check.
*/
#if !SOLARIS && !defined(__sgi)
sumd += (sumd & 0xffff);
while (sumd > 0xffff)
sumd = (sumd & 0xffff) + (sumd >> 16);
fix_incksum(&icmp->icmp_cksum, sumd, 0);
/*
* Fix UDP pseudo header checksum to compensate for the
* IP address change.
*/
if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
/*
* The UDP checksum is optional, only adjust it
* if it has been set
*/
sum1 = ntohs(udp->uh_sum);
fix_datacksum(&udp->uh_sum, sumd);
sum2 = ntohs(udp->uh_sum);
/*
* Fix ICMP checksum to compensate the UDP
* checksum adjustment.
*/
CALC_SUMD(sum1, sum2, sumd);
fix_incksum(&icmp->icmp_cksum, sumd);
}
#if 0
/*
* Fix TCP pseudo header checksum to compensate for the
* IP address change. Before we can do the change, we
* must make sure that oip is sufficient large to hold
* the TCP checksum (normally it does not!).
*/
if (oip->ip_p == IPPROTO_TCP) {
};
#endif
#endif
}
@ -1623,23 +1776,98 @@ int dir;
* XXX - what if this is bogus hl and we go off the end ?
* In this case, nat_icmpinlookup() will have returned NULL.
*/
tcp = (tcphdr_t *)((((char *)oip) + (oip->ip_hl << 2)));
tcp = (tcphdr_t *)udp;
/*
* Step 2 :
* For offending TCP/UDP IP packets, translate the ports as
* well, based on the NAT specification. Of course such
* a change must be reflected in the ICMP checksum as well.
*
* Advance notice : Now it becomes complicated :-)
*
* Since the port fields are part of the TCP/UDP checksum
* of the offending IP packet, you need to adjust that checksum
* as well... but, if you change, you must change the icmp
* checksum *again*, to reflect that change.
*
* To further complicate: the TCP checksum is not in the first
* 8 bytes of the offending ip packet, so it most likely is not
* available (we might have to fix that if the encounter a
* device that returns more than 8 data bytes on icmp error)
*/
if (nat->nat_dir == NAT_OUTBOUND) {
if (tcp->th_sport != nat->nat_inport) {
/*
* Fix ICMP checksum to compensate port
* adjustment.
*/
sum1 = ntohs(tcp->th_sport);
sum2 = ntohs(nat->nat_inport);
CALC_SUMD(sum1, sum2, sumd);
tcp->th_sport = nat->nat_inport;
fix_outcksum(&icmp->icmp_cksum, sumd, 0);
fix_outcksum(&icmp->icmp_cksum, sumd);
/*
* Fix udp checksum to compensate port
* adjustment. NOTE : the offending IP packet
* flows the other direction compared to the
* ICMP message.
*
* The UDP checksum is optional, only adjust
* it if it has been set.
*/
if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
sum1 = ntohs(udp->uh_sum);
fix_datacksum(&udp->uh_sum, sumd);
sum2 = ntohs(udp->uh_sum);
/*
* Fix ICMP checksum to
* compensate UDP checksum
* adjustment.
*/
CALC_SUMD(sum1, sum2, sumd);
fix_outcksum(&icmp->icmp_cksum, sumd);
}
}
} else {
if (tcp->th_dport != nat->nat_outport) {
/*
* Fix ICMP checksum to compensate port
* adjustment.
*/
sum1 = ntohs(tcp->th_dport);
sum2 = ntohs(nat->nat_outport);
CALC_SUMD(sum1, sum2, sumd);
tcp->th_dport = nat->nat_outport;
fix_incksum(&icmp->icmp_cksum, sumd, 0);
fix_incksum(&icmp->icmp_cksum, sumd);
/*
* Fix udp checksum to compensate port
* adjustment. NOTE : the offending IP
* packet flows the other direction compared
* to the ICMP message.
*
* The UDP checksum is optional, only adjust
* it if it has been set.
*/
if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
sum1 = ntohs(udp->uh_sum);
fix_datacksum(&udp->uh_sum, sumd);
sum2 = ntohs(udp->uh_sum);
/*
* Fix ICMP checksum to compensate
* UDP checksum adjustment.
*/
CALC_SUMD(sum1, sum2, sumd);
fix_incksum(&icmp->icmp_cksum, sumd);
}
}
}
}
@ -1664,30 +1892,92 @@ register u_int flags, p;
struct in_addr src , mapdst;
u_32_t ports;
{
register u_short sport, mapdport;
register u_short sport, dport;
register nat_t *nat;
register int nflags;
register u_32_t dst;
u_int hv;
mapdport = ports >> 16;
dst = mapdst.s_addr;
dport = ports >> 16;
sport = ports & 0xffff;
flags &= IPN_TCPUDP;
hv = NAT_HASH_FN(mapdst.s_addr, mapdport, ipf_nattable_sz);
hv = NAT_HASH_FN(dst, dport, ipf_nattable_sz);
nat = nat_table[1][hv];
for (; nat; nat = nat->nat_hnext[1]) {
nflags = nat->nat_flags;
if ((!ifp || ifp == nat->nat_ifp) &&
nat->nat_oip.s_addr == src.s_addr &&
nat->nat_outip.s_addr == mapdst.s_addr &&
nat->nat_outip.s_addr == dst &&
(((p == 0) && (flags == (nat->nat_flags & IPN_TCPUDP)))
|| (p == nat->nat_p)) && (!flags ||
(((nat->nat_oport == sport) || (nflags & FI_W_DPORT)) &&
((nat->nat_outport == mapdport) ||
(nflags & FI_W_SPORT)))))
((nat->nat_outport == dport) || (nflags & FI_W_SPORT)))))
return nat;
}
return NULL;
if (!nat_wilds || !(flags & IPN_TCPUDP))
return NULL;
RWLOCK_EXIT(&ipf_nat);
hv = NAT_HASH_FN(dst, 0, ipf_nattable_sz);
WRITE_ENTER(&ipf_nat);
nat = nat_table[1][hv];
for (; nat; nat = nat->nat_hnext[1]) {
nflags = nat->nat_flags;
if (ifp && ifp != nat->nat_ifp)
continue;
if (!(nflags & IPN_TCPUDP))
continue;
if (!(nflags & FI_WILDP))
continue;
if (nat->nat_oip.s_addr != src.s_addr ||
nat->nat_outip.s_addr != dst)
continue;
if (((nat->nat_oport == sport) || (nflags & FI_W_DPORT)) &&
((nat->nat_outport == dport) || (nflags & FI_W_SPORT))) {
hv = NAT_HASH_FN(dst, dport, ipf_nattable_sz);
nat_tabmove(nat, hv);
break;
}
}
MUTEX_DOWNGRADE(&ipf_nat);
return nat;
}
static void nat_tabmove(nat, hv)
nat_t *nat;
u_int hv;
{
nat_t **natp;
/*
* Remove the NAT entry from the old location
*/
if (nat->nat_hnext[0])
nat->nat_hnext[0]->nat_phnext[0] = nat->nat_phnext[0];
*nat->nat_phnext[0] = nat->nat_hnext[0];
if (nat->nat_hnext[1])
nat->nat_hnext[0]->nat_phnext[1] = nat->nat_phnext[1];
*nat->nat_phnext[1] = nat->nat_hnext[1];
natp = &nat_table[0][hv];
if (*natp)
(*natp)->nat_phnext[0] = &nat->nat_hnext[0];
nat->nat_phnext[0] = natp;
nat->nat_hnext[0] = *natp;
*natp = nat;
/*
* Add into the NAT table in the new position
*/
natp = &nat_table[1][hv];
if (*natp)
(*natp)->nat_phnext[1] = &nat->nat_hnext[1];
nat->nat_phnext[1] = natp;
nat->nat_hnext[1] = *natp;
*natp = nat;
}
@ -1706,19 +1996,21 @@ u_32_t ports;
register u_short sport, dport;
register nat_t *nat;
register int nflags;
u_32_t srcip;
u_int hv;
sport = ports & 0xffff;
dport = ports >> 16;
flags &= IPN_TCPUDP;
srcip = src.s_addr;
hv = NAT_HASH_FN(src.s_addr, sport, ipf_nattable_sz);
hv = NAT_HASH_FN(srcip, sport, ipf_nattable_sz);
nat = nat_table[0][hv];
for (; nat; nat = nat->nat_hnext[0]) {
nflags = nat->nat_flags;
if ((!ifp || ifp == nat->nat_ifp) &&
nat->nat_inip.s_addr == src.s_addr &&
nat->nat_inip.s_addr == srcip &&
nat->nat_oip.s_addr == dst.s_addr &&
(((p == 0) && (flags == (nat->nat_flags & IPN_TCPUDP)))
|| (p == nat->nat_p)) && (!flags ||
@ -1726,7 +2018,32 @@ u_32_t ports;
(nat->nat_oport == dport || nflags & FI_W_DPORT))))
return nat;
}
return NULL;
if (!nat_wilds || !(flags & IPN_TCPUDP))
return NULL;
RWLOCK_EXIT(&ipf_nat);
hv = NAT_HASH_FN(srcip, 0, ipf_nattable_sz);
WRITE_ENTER(&ipf_nat);
nat = nat_table[0][hv];
for (; nat; nat = nat->nat_hnext[0]) {
nflags = nat->nat_flags;
if (ifp && ifp != nat->nat_ifp)
continue;
if (!(nflags & IPN_TCPUDP))
continue;
if (!(nflags & FI_WILDP))
continue;
if ((nat->nat_inip.s_addr != srcip) ||
(nat->nat_oip.s_addr != dst.s_addr))
continue;
if (((nat->nat_inport == sport) || (nflags & FI_W_DPORT)) &&
((nat->nat_oport == dport) || (nflags & FI_W_SPORT))) {
hv = NAT_HASH_FN(srcip, sport, ipf_nattable_sz);
nat_tabmove(nat, hv);
break;
}
}
MUTEX_DOWNGRADE(&ipf_nat);
return nat;
}
@ -1862,6 +2179,7 @@ fr_info_t *fin;
nat->nat_outport = sport;
nat->nat_flags &= ~(FI_W_DPORT|FI_W_SPORT);
nflags = nat->nat_flags;
nat_wilds--;
}
} else {
RWLOCK_EXIT(&ipf_nat);
@ -1942,16 +2260,16 @@ fr_info_t *fin;
CALC_SUMD(s1, s2, sumd);
if (nat->nat_dir == NAT_OUTBOUND)
fix_incksum(&ip->ip_sum, sumd, 0);
fix_incksum(&ip->ip_sum, sumd);
else
fix_outcksum(&ip->ip_sum, sumd, 0);
fix_outcksum(&ip->ip_sum, sumd);
}
#if SOLARIS || defined(__sgi)
else {
if (nat->nat_dir == NAT_OUTBOUND)
fix_outcksum(&ip->ip_sum, nat->nat_ipsumd, 0);
fix_outcksum(&ip->ip_sum, nat->nat_ipsumd);
else
fix_incksum(&ip->ip_sum, nat->nat_ipsumd, 0);
fix_incksum(&ip->ip_sum, nat->nat_ipsumd);
}
#endif
ip->ip_src = nat->nat_outip;
@ -1995,11 +2313,9 @@ fr_info_t *fin;
if (csump) {
if (nat->nat_dir == NAT_OUTBOUND)
fix_outcksum(csump, nat->nat_sumd[1],
ip->ip_len);
fix_outcksum(csump, nat->nat_sumd[1]);
else
fix_incksum(csump, nat->nat_sumd[1],
ip->ip_len);
fix_incksum(csump, nat->nat_sumd[1]);
}
}
@ -2076,6 +2392,7 @@ fr_info_t *fin;
nat->nat_outport = dport;
nat->nat_flags &= ~(FI_W_SPORT|FI_W_DPORT);
nflags = nat->nat_flags;
nat_wilds--;
}
} else {
RWLOCK_EXIT(&ipf_nat);
@ -2153,9 +2470,9 @@ fr_info_t *fin;
*/
#if SOLARIS || defined(__sgi)
if (nat->nat_dir == NAT_OUTBOUND)
fix_incksum(&ip->ip_sum, nat->nat_ipsumd, 0);
fix_incksum(&ip->ip_sum, nat->nat_ipsumd);
else
fix_outcksum(&ip->ip_sum, nat->nat_ipsumd, 0);
fix_outcksum(&ip->ip_sum, nat->nat_ipsumd);
#endif
if (!(ip->ip_off & IP_OFFMASK) &&
!(fin->fin_fi.fi_fl & FI_SHORT)) {
@ -2196,11 +2513,9 @@ fr_info_t *fin;
if (csump) {
if (nat->nat_dir == NAT_OUTBOUND)
fix_incksum(csump, nat->nat_sumd[0],
0);
fix_incksum(csump, nat->nat_sumd[0]);
else
fix_outcksum(csump, nat->nat_sumd[0],
0);
fix_outcksum(csump, nat->nat_sumd[0]);
}
}
ATOMIC_INCL(nat_stats.ns_mapped[0]);

View File

@ -6,7 +6,7 @@
* to the original author and the contributors.
*
* @(#)ip_nat.h 1.5 2/4/96
* $Id: ip_nat.h,v 2.17.2.6 2000/07/15 14:50:06 darrenr Exp $
* $Id: ip_nat.h,v 2.17.2.9 2000/10/19 15:44:04 darrenr Exp $
*/
#ifndef __IP_NAT_H__
@ -81,7 +81,7 @@ typedef struct nat {
struct hostmap *nat_hm;
struct nat *nat_next;
struct nat *nat_hnext[2];
struct nat **nat_hstart[2];
struct nat **nat_phnext[2];
void *nat_ifp;
int nat_dir;
char nat_ifname[IFNAMSIZ];
@ -141,6 +141,11 @@ typedef struct ipnat {
#define NAT_REDIRECT 0x02
#define NAT_BIMAP (NAT_MAP|NAT_REDIRECT)
#define NAT_MAPBLK 0x04
/* 0x100 reserved for FI_W_SPORT */
/* 0x200 reserved for FI_W_DPORT */
/* 0x400 reserved for FI_W_SADDR */
/* 0x800 reserved for FI_W_DADDR */
/* 0x1000 reserved for FI_W_NEWFR */
#define MAPBLK_MINPORT 1024 /* don't use reserved ports for src port */
#define USABLE_PORTS (65536 - MAPBLK_MINPORT)
@ -293,7 +298,8 @@ extern int ip_natout __P((ip_t *, fr_info_t *));
extern int ip_natin __P((ip_t *, fr_info_t *));
extern void ip_natunload __P((void)), ip_natexpire __P((void));
extern void nat_log __P((struct nat *, u_int));
extern void fix_incksum __P((u_short *, u_32_t, int));
extern void fix_outcksum __P((u_short *, u_32_t, int));
extern void fix_incksum __P((u_short *, u_32_t));
extern void fix_outcksum __P((u_short *, u_32_t));
extern void fix_datacksum __P((u_short *, u_32_t));
#endif /* __IP_NAT_H__ */

View File

@ -1,5 +1,5 @@
/*
* $Id: ip_raudio_pxy.c,v 1.7.2.1 2000/05/06 11:19:33 darrenr Exp $
* $Id: ip_raudio_pxy.c,v 1.7.2.2 2000/09/03 00:23:12 darrenr Exp $
*/
#if SOLARIS && defined(_KERNEL)
extern kmutex_t ipf_rw;
@ -171,8 +171,8 @@ nat_t *nat;
tcphdr_t *tcp, tcph, *tcp2 = &tcph;
raudio_t *rap = aps->aps_data;
struct in_addr swa, swb;
u_int a1, a2, a3, a4;
int off, dlen, slen;
int a1, a2, a3, a4;
u_short sp, dp;
fr_info_t fi;
tcp_seq seq;

View File

@ -9,7 +9,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "%W% %G% (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.23.2.6 2000/08/07 12:36:19 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.23.2.8 2000/10/19 15:42:10 darrenr Exp $";
#endif
#include <sys/types.h>
@ -441,7 +441,7 @@ caddr_t data;
}
group = fp->fr_group;
if (group != NULL) {
if (group != 0) {
fg = fr_findgroup(group, fp->fr_flags, unit, set, NULL);
if (fg == NULL) {
error = ESRCH;
@ -613,7 +613,7 @@ caddr_t data;
fixskip(fprev, f, 1);
f->fr_grp = NULL;
group = f->fr_grhead;
if (group != NULL)
if (group != 0)
fg = fr_addgroup(group, f, unit, set);
} else
error = ENOMEM;
@ -688,7 +688,7 @@ ip_t *oip;
fr_info_t *fin;
{
tcphdr_t *tcp, *tcp2;
int tlen = 0, hlen;
int tlen, hlen;
mblk_t *m;
#ifdef USE_INET6
ip6_t *ip6, *oip6 = (ip6_t *)oip;
@ -698,8 +698,7 @@ fr_info_t *fin;
tcp = (struct tcphdr *)fin->fin_dp;
if (tcp->th_flags & TH_RST)
return -1;
if (tcp->th_flags & TH_SYN)
tlen = 1;
tlen = (tcp->th_flags & (TH_SYN|TH_FIN)) ? 1 : 0;
#ifdef USE_INET6
if (fin->fin_v == 6)
hlen = sizeof(ip6_t);
@ -717,8 +716,15 @@ fr_info_t *fin;
tcp2 = (struct tcphdr *)(m->b_rptr + hlen - sizeof(*tcp2));
tcp2->th_dport = tcp->th_sport;
tcp2->th_sport = tcp->th_dport;
tcp2->th_ack = htonl(ntohl(tcp->th_seq) + tlen);
tcp2->th_seq = tcp->th_ack;
if (tcp->th_flags & TH_ACK) {
tcp2->th_seq = tcp->th_ack;
tcp2->th_flags = TH_RST|TH_ACK;
} else {
tcp2->th_ack = ntohl(tcp->th_seq);
tcp2->th_ack += tlen;
tcp2->th_ack = htonl(tcp2->th_ack);
tcp2->th_flags = TH_RST;
}
tcp2->th_off = sizeof(struct tcphdr) >> 2;
tcp2->th_flags = TH_RST|TH_ACK;
@ -791,8 +797,9 @@ int dst;
struct icmp *icmp;
mblk_t *m, *mb;
int hlen, code;
qif_t *qif;
qif_t *qif;
u_short sz;
ill_t *il;
#ifdef USE_INET6
ip6_t *ip6, *oip6;
#endif
@ -851,6 +858,11 @@ int dst;
icmp->icmp_type = type;
icmp->icmp_code = code;
icmp->icmp_cksum = 0;
#ifdef icmp_nextmtu
if (type == ICMP_UNREACH && (il = qif->qf_ill) &&
fin->fin_icode == ICMP_UNREACH_NEEDFRAG)
icmp->icmp_nextmtu = htons(il->ill_max_frag);
#endif
#ifdef USE_INET6
if (oip->ip_v == 6) {

View File

@ -7,7 +7,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.30.2.17 2000/08/08 16:01:03 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.30.2.22 2000/10/26 10:41:29 darrenr Exp $";
#endif
#include <sys/errno.h>
@ -106,6 +106,7 @@ static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.30.2.17 2000/08/08 16:01:03
static ipstate_t **ips_table = NULL;
static ipstate_t *ips_list = NULL;
static int ips_num = 0;
static int ips_wild = 0;
static ips_stat_t ips_stats;
#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
extern KRWLOCK_T ipf_state, ipf_mutex;
@ -123,6 +124,7 @@ static int fr_state_flush __P((int));
static ips_stat_t *fr_statetstats __P((void));
static void fr_delstate __P((ipstate_t *));
static int fr_state_remove __P((caddr_t));
static void fr_ipsmove __P((ipstate_t **, ipstate_t *, u_int));
int fr_stputent __P((caddr_t));
int fr_stgetent __P((caddr_t));
void fr_stinsert __P((ipstate_t *));
@ -135,7 +137,8 @@ u_long fr_tcpidletimeout = FIVE_DAYS,
fr_tcpclosewait = 2 * TCP_MSL,
fr_tcplastack = 2 * TCP_MSL,
fr_tcptimeout = 2 * TCP_MSL,
fr_tcpclosed = 1,
fr_tcpclosed = 120,
fr_tcphalfclosed = 2 * 2 * 3600, /* 2 hours */
fr_udptimeout = 240,
fr_icmptimeout = 120;
int fr_statemax = IPSTATE_MAX,
@ -240,9 +243,12 @@ caddr_t data;
for (sp = ips_list; sp; sp = sp->is_next)
if ((sp->is_p == st.is_p) && (sp->is_v == st.is_v) &&
!bcmp(&sp->is_src, &st.is_src, sizeof(st.is_src)) &&
!bcmp(&sp->is_dst, &st.is_src, sizeof(st.is_dst)) &&
!bcmp(&sp->is_ps, &st.is_ps, sizeof(st.is_ps))) {
!bcmp((char *)&sp->is_src, (char *)&st.is_src,
sizeof(st.is_src)) &&
!bcmp((char *)&sp->is_dst, (char *)&st.is_src,
sizeof(st.is_dst)) &&
!bcmp((char *)&sp->is_ps, (char *)&st.is_ps,
sizeof(st.is_ps))) {
WRITE_ENTER(&ipf_state);
#ifdef IPFILTER_LOG
ipstate_log(sp, ISL_REMOVE);
@ -590,8 +596,8 @@ u_int flags;
hv += tcp->th_dport;
hv += tcp->th_sport;
}
is->is_send = ntohl(tcp->th_seq) + ip->ip_len -
fin->fin_hlen - (tcp->th_off << 2) +
is->is_send = ntohl(tcp->th_seq) + fin->fin_dlen -
(tcp->th_off << 2) +
((tcp->th_flags & TH_SYN) ? 1 : 0) +
((tcp->th_flags & TH_FIN) ? 1 : 0);
is->is_maxsend = is->is_send;
@ -660,6 +666,8 @@ u_int flags;
is->is_flags = fin->fin_fi.fi_fl & FI_CMP;
is->is_flags |= FI_CMP << 4;
is->is_flags |= flags & (FI_WILDP|FI_WILDA);
if (flags & (FI_WILDP|FI_WILDA))
ips_wild++;
is->is_ifp[1 - out] = NULL;
is->is_ifp[out] = fin->fin_ifp;
#ifdef _KERNEL
@ -718,6 +726,7 @@ tcphdr_t *tcp;
((tcp->th_flags & TH_SYN) ? 1 : 0) +
((tcp->th_flags & TH_FIN) ? 1 : 0);
MUTEX_ENTER(&is->is_lock);
if (fdata->td_end == 0) {
/*
* Must be a (outgoing) SYN-ACK in reply to a SYN.
@ -783,12 +792,11 @@ tcphdr_t *tcp;
/*
* Nearing end of connection, start timeout.
*/
MUTEX_ENTER(&is->is_lock);
/* source ? 0 : 1 -> !source */
fr_tcp_age(&is->is_age, is->is_state, fin, !source);
MUTEX_EXIT(&is->is_lock);
ret = 1;
}
MUTEX_EXIT(&is->is_lock);
return ret;
}
@ -892,6 +900,7 @@ tcphdr_t *tcp;
is->is_maxdend = is->is_dend + 1;
}
is->is_flags &= ~(FI_W_SPORT|FI_W_DPORT);
ips_wild--;
}
ret = -1;
@ -983,7 +992,7 @@ fr_info_t *fin;
* Only a basic IP header (no options) should be with
* an ICMP error header.
*/
if (((ip->ip_v != 4) && (ip->ip_hl != 5)) ||
if (((ip->ip_v != 4) || (ip->ip_hl != 5)) ||
(fin->fin_plen < ICMPERR_MINPKTLEN))
return NULL;
ic = (struct icmp *)fin->fin_dp;
@ -1037,8 +1046,8 @@ fr_info_t *fin;
* the IP6EQ and IP6NEQ macros produce the wrong results because
* of the 'junk' in the unused part of the union
*/
bzero(&src, sizeof(src));
bzero(&dst, sizeof(dst));
bzero((char *)&src, sizeof(src));
bzero((char *)&dst, sizeof(dst));
if (oip->ip_p == IPPROTO_ICMP) {
icmp = (icmphdr_t *)((char *)oip + (oip->ip_hl << 2));
@ -1158,6 +1167,38 @@ fr_info_t *fin;
return NULL;
}
static void fr_ipsmove(isp, is, hv)
ipstate_t **isp, *is;
u_int hv;
{
u_int hvm;
hvm = is->is_hv;
/*
* Remove the hash from the old location...
*/
if (is->is_hnext)
is->is_hnext->is_phnext = isp;
*isp = is->is_hnext;
if (ips_table[hvm] == NULL)
ips_stats.iss_inuse--;
/*
* ...and put the hash in the new one.
*/
hvm = hv % fr_statesize;
isp = &ips_table[hvm];
if (*isp)
(*isp)->is_phnext = &is->is_hnext;
else
ips_stats.iss_inuse++;
is->is_phnext = isp;
is->is_hnext = *isp;
*isp = is;
}
/*
* Check if a packet has a registered state.
*/
@ -1240,7 +1281,7 @@ fr_info_t *fin;
break;
case IPPROTO_TCP :
{
register u_short dport = tcp->th_dport, sport = tcp->th_sport;
register u_short dport, sport;
register int i;
i = tcp->th_flags;
@ -1250,57 +1291,42 @@ fr_info_t *fin;
if ((i & TH_RST) &&
((i & (TH_FIN|TH_SYN|TH_RST)) != TH_RST))
break;
tryagain = 0;
retry_tcp:
hvm = hv % fr_statesize;
WRITE_ENTER(&ipf_state);
for (isp = &ips_table[hvm]; (is = *isp);
isp = &is->is_hnext)
if ((is->is_p == pr) && (is->is_v == v) &&
fr_matchsrcdst(is, src, dst, fin, tcp)) {
if (fr_tcpstate(is, fin, ip, tcp))
break;
is = NULL;
break;
}
if (is != NULL)
break;
RWLOCK_EXIT(&ipf_state);
hv += dport;
hv += sport;
if (tryagain == 0) {
tryagain = 1;
goto retry_tcp;
}
break;
}
case IPPROTO_UDP :
{
register u_short dport = tcp->th_dport, sport = tcp->th_sport;
dport = tcp->th_dport;
sport = tcp->th_sport;
tryagain = 0;
retry_udp:
hvm = hv % fr_statesize;
/*
* Nothing else to match on but ports. and IP#'s
*/
READ_ENTER(&ipf_state);
for (is = ips_table[hvm]; is; is = is->is_hnext)
if ((is->is_p == pr) && (is->is_v == v) &&
fr_matchsrcdst(is, src, dst, fin, tcp)) {
is->is_age = fr_udptimeout;
break;
}
if (is != NULL)
break;
RWLOCK_EXIT(&ipf_state);
hv += dport;
hv += sport;
if (tryagain == 0) {
READ_ENTER(&ipf_state);
retry_tcpudp:
hvm = hv % fr_statesize;
for (isp = &ips_table[hvm]; (is = *isp); isp = &is->is_hnext)
if ((is->is_p == pr) && (is->is_v == v) &&
fr_matchsrcdst(is, src, dst, fin, tcp)) {
if ((pr == IPPROTO_TCP)) {
if (!fr_tcpstate(is, fin, ip, tcp)) {
continue;
}
}
break;
}
if (is != NULL) {
if (tryagain &&
!(is->is_flags & (FI_WILDP|FI_WILDA))) {
hv += dport;
hv += sport;
fr_ipsmove(isp, is, hv);
MUTEX_DOWNGRADE(&ipf_state);
}
break;
}
RWLOCK_EXIT(&ipf_state);
if (!tryagain && ips_wild) {
hv -= dport;
hv -= sport;
tryagain = 1;
goto retry_udp;
WRITE_ENTER(&ipf_state);
goto retry_tcpudp;
}
break;
}
@ -1357,6 +1383,8 @@ ipstate_t *is;
{
frentry_t *fr;
if (is->is_flags & (FI_WILDP|FI_WILDA))
ips_wild--;
if (is->is_next)
is->is_next->is_pnext = is->is_pnext;
*is->is_pnext = is->is_next;
@ -1566,7 +1594,7 @@ int dir;
* SYN_RECEIVED -> FIN_WAIT_1
*/
state[dir] = TCPS_FIN_WAIT_1;
*age = fr_tcpidletimeout; /* or fr_tcptimeout? */
*age = fr_tcpidletimeout;
}
break;
@ -1578,7 +1606,7 @@ int dir;
* ESTABLISHED -> FIN_WAIT_1
*/
state[dir] = TCPS_FIN_WAIT_1;
*age = fr_tcpidletimeout;
*age = fr_tcphalfclosed;
} else if (flags & TH_ACK) {
/* an ACK, should we exclude other flags here? */
if (ostate == TCPS_FIN_WAIT_1) {
@ -1590,7 +1618,7 @@ int dir;
* a half-closed connection
*/
state[dir] = TCPS_CLOSE_WAIT;
*age = fr_tcpidletimeout;
*age = fr_tcphalfclosed;
} else if (ostate < TCPS_CLOSE_WAIT)
/*
* Still a fully established connection,
@ -1614,7 +1642,7 @@ int dir;
* closed already and we did not close our side yet;
* reset timeout
*/
*age = fr_tcpidletimeout;
*age = fr_tcphalfclosed;
}
break;
@ -1638,7 +1666,7 @@ int dir;
* other side is still active (ESTABLISHED/CLOSE_WAIT);
* continue with this half-closed connection
*/
*age = fr_tcpidletimeout;
*age = fr_tcphalfclosed;
break;
case TCPS_CLOSING: /* 7 */

View File

@ -6,7 +6,7 @@
* to the original author and the contributors.
*
* @(#)ip_state.h 1.3 1/12/96 (C) 1995 Darren Reed
* $Id: ip_state.h,v 2.13.2.1 2000/07/08 02:15:35 darrenr Exp $
* $Id: ip_state.h,v 2.13.2.2 2000/08/23 11:01:31 darrenr Exp $
*/
#ifndef __IP_STATE_H__
#define __IP_STATE_H__
@ -173,6 +173,7 @@ extern u_long fr_tcpclosewait;
extern u_long fr_tcplastack;
extern u_long fr_tcptimeout;
extern u_long fr_tcpclosed;
extern u_long fr_tcphalfclosed;
extern u_long fr_udptimeout;
extern u_long fr_icmptimeout;
extern int fr_state_lock;

View File

@ -43,7 +43,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)ipf.c 1.23 6/5/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$Id: ipf.c,v 2.10.2.3 2000/08/07 14:54:05 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipf.c,v 2.10.2.5 2000/10/25 10:37:11 darrenr Exp $";
#endif
#if SOLARIS
@ -71,7 +71,7 @@ static void set_state __P((u_int)), showstats __P((friostat_t *));
static void packetlogon __P((char *)), swapactive __P((void));
static int opendevice __P((char *));
static void closedevice __P((void));
static char *getline __P((char *, size_t, FILE *));
static char *getline __P((char *, size_t, FILE *, int *));
static char *ipfname = IPL_NAME;
static void usage __P((void));
static void showversion __P((void));
@ -252,8 +252,7 @@ char *name, *file;
exit(1);
}
while (getline(line, sizeof(line), fp)) {
linenum++;
while (getline(line, sizeof(line), fp, &linenum)) {
/*
* treat CR as EOL. LF is converted to NUL by getline().
*/
@ -335,10 +334,11 @@ char *name, *file;
* Similar to fgets(3) but can handle '\\' and NL is converted to NUL.
* Returns NULL if error occured, EOF encounterd or input line is too long.
*/
static char *getline(str, size, file)
static char *getline(str, size, file, linenum)
register char *str;
size_t size;
FILE *file;
int *linenum;
{
char *p;
int s, len;
@ -356,6 +356,7 @@ FILE *file;
p[len] = '\0';
break;
}
(*linenum)++;
p[len - 1] = '\0';
if (len < 2 || p[len - 2] != '\\')
break;
@ -568,7 +569,7 @@ static void showversion()
}
if (ioctl(vfd, SIOCGETFS, &fiop)) {
perror("ioctl(SIOCGETFS");
perror("ioctl(SIOCGETFS)");
close(vfd);
return;
}

View File

@ -6,12 +6,12 @@
* to the original author and the contributors.
*
* @(#)ipl.h 1.21 6/5/96
* $Id: ipl.h,v 2.15.2.10 2000/08/07 15:10:09 darrenr Exp $
* $Id: ipl.h,v 2.15.2.13 2000/10/25 11:08:41 darrenr Exp $
*/
#ifndef __IPL_H__
#define __IPL_H__
#define IPL_VERSION "IP Filter: v3.4.9"
#define IPL_VERSION "IP Filter: v3.4.12"
#endif

View File

@ -67,7 +67,7 @@ char *addr, *eaddr;
struct sockaddr_dl *sdl;
#ifdef IPSEND
if (arp_getipv4(ip, ether) == 0)
if (arp_getipv4(addr, ether) == 0)
return 0;
#endif

View File

@ -95,6 +95,8 @@ SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &fr_active, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &fr_chksrc, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RW,
&fr_tcpidletimeout, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RW,
&fr_tcphalfclosed, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RW,
&fr_tcpclosewait, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcplastack, CTLFLAG_RW,

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: mlfk_ipl.c,v 2.1.2.3 2000/08/13 03:42:42 darrenr Exp $
* $Id: mlfk_ipl.c,v 2.1.2.4 2000/08/23 11:02:33 darrenr Exp $
*/
@ -65,6 +65,8 @@ SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RW,
&fr_tcptimeout, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RW,
&fr_tcpclosed, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RW,
&fr_tcphalfclosed, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RW,
&fr_udptimeout, 0, "");
SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RW,

File diff suppressed because it is too large Load Diff

View File

@ -8,6 +8,12 @@
#
# If we have only 1 valid IP address from our ISP, then we do this:
#
# To make ftp work, using the internal ftp proxy, use:
#
map ppp0 w.x.y.z/24 -> a.b.c.d/32 proxy port ftp ftp/tcp
#
# For normal TCP/UDP and other IP protocols
#
map ppp0 w.x.y.z/24 -> a.b.c.d/32 portmap tcp/udp 40000:60000
map ppp0 w.x.y.z/24 -> a.b.c.d/32
#
@ -38,8 +44,3 @@ map ppp0 w.x.y.z/24 -> a.b.c.d/32
#map ppp0 w.x.y.q/32 -> a.b.c.J/32
#map ppp0 w.x.y.p/32 -> a.b.c.K/32 portmap tcp/udp 40000:60000
#map ppp0 w.x.y.p/32 -> a.b.c.K/32
#
# To make ftp work, using the internal ftp proxy, use:
#
map ppp0 w.x.y.z/24 -> a.b.c.d/32 proxy port ftp ftp/tcp
#