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

which included commits to RCS files with non-trunk default branches.
This commit is contained in:
Guido van Rooij 2000-01-13 18:30:37 +00:00
commit c41766e97e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=55925
22 changed files with 714 additions and 245 deletions

View File

@ -20,6 +20,74 @@
# and especially those who have found the time to port IP Filter to new
# platforms.
#
3.3.6 28/12/1999 - Released
add in missing rwlock release in fr_checkicmpmatchingstate() and fix check
for ICMP_ECHO to only be for packet, not state entry which we don't have yet.
handle SIOCIPFFB in nat_ioctl() and fr_state_ioctl()
fix size of friostat for SunOS4
fix bug in running off the end of a buffer in real audio proxy
3.3.5 11/12/1999 - Released
fix parsing of "log level" and printing it back out too
<net/if_types.h> is only present on Solaris2.6/7/8
use send_icmp_err rather than icmp_error to send back a frag-needed error
when doing PMTU
do not use -b with add_drv on Solaris unless $BASEDIR is set.
fix problem where source address in icmp replies is reversed
fix yet another problem with real audio.
3.3.4 4/12/1999 - Released
patches from Guido: fix panic in ip_state:fr_checkicmpmatchingstate(), fix
byte order problem in ip_id (host order when called from ip_input(), vs
network byte order when called from ip_output()) and fix a problem where the
fragment cache was never timedout early.
fix up the real audio proxy to properly setup state information and NAT
entries, thanks to Laine Stump for testing/advice/fixes.
fix ipfr_fastroute to set dst->sin_addr (Sean Farley - appears to prevent
FreeBSD 3.3 from panic'ing) as this had been removed in prior hacks to this
routine.
fix kinstall for BSDI
support ICMP errors being allowed through for ICMP packets going out with
keep state enabled
support hardware checksumming (gigabit ethernet cards) on Solaris thanks to
Tel.Net Media for providing hardware for testing.
patched from Frank Volf for ipmon (ICMP & fragmented packets) and allowing
ICMP responses to ICMP packets in the keep state table.
add in patches for hardware checksumming under solaris
Solaris install scripts now use $BASEDIR as appropriate.
add Solaris8 support
fix "ipf -y" on solaris so that it rescans rules also for changes in
interface pointers
let ipmon become a daemon with -D if it is using syslog
fix parsing of return-icmp-as-dest(foo)
add reference to ipfstat -g to ipfstat.8
ipf_mutex needs to be declared for irix in ip_fil.c
3.3.3 22/10/1999 - Released
add -g command line option to ipfstat to show groups still define.

View File

@ -7,7 +7,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-1996 Darren Reed";
static const char rcsid[] = "@(#)$Id: fil.c,v 2.3.2.7 1999/10/21 14:21:40 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: fil.c,v 2.3.2.14 1999/12/07 12:53:40 darrenr Exp $";
#endif
#include <sys/errno.h>
@ -146,6 +146,9 @@ fr_info_t frcache[2];
static int fr_tcpudpchk __P((frentry_t *, fr_info_t *));
static int frflushlist __P((int, minor_t, int *, frentry_t **));
#ifdef _KERNEL
static void frsynclist __P((frentry_t *));
#endif
/*
@ -670,6 +673,13 @@ int out;
fin->fin_qif = qif;
# endif
#endif /* _KERNEL */
/*
* Be careful here: ip_id is in network byte order when called
* from ip_output()
*/
if (out)
ip->ip_id = ntohs(ip->ip_id);
fr_makefrip(hlen, ip, fin);
fin->fin_ifp = ifp;
fin->fin_out = out;
@ -823,6 +833,10 @@ int out;
}
}
#endif /* IPFILTER_LOG */
if (out)
ip->ip_id = htons(ip->ip_id);
#ifdef _KERNEL
/*
* Only allow FR_DUP to work if a rule matched - it makes no sense to
@ -1164,7 +1178,7 @@ tcphdr_t *tcp;
* SUCH DAMAGE.
*
* @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
* $Id: fil.c,v 2.3.2.7 1999/10/21 14:21:40 darrenr Exp $
* $Id: fil.c,v 2.3.2.14 1999/12/07 12:53:40 darrenr Exp $
*/
/*
* Copy data from an mbuf chain starting "off" bytes from the beginning,
@ -1357,14 +1371,16 @@ frentry_t **listp;
}
ATOMIC_DEC(fp->fr_ref);
if (fp->fr_grhead) {
fr_delgroup((u_int)fp->fr_grhead, fp->fr_flags,
unit, set);
fp->fr_grhead = NULL;
}
if (fp->fr_ref == 0) {
if (fp->fr_grhead)
fr_delgroup((u_int)fp->fr_grhead, fp->fr_flags,
unit, set);
KFREE(fp);
freed++;
} else
fp->fr_next = NULL;
freed++;
}
*nfreedp += freed;
return freed;
@ -1528,10 +1544,52 @@ struct in_addr *inp;
in = sin->sin_addr;
# endif /* linux */
# endif /* SOLARIS */
in.s_addr = ntohl(in.s_addr);
*inp = in;
return 0;
}
static void frsynclist(fr)
register frentry_t *fr;
{
for (; fr; fr = fr->fr_next) {
if (fr->fr_ifa != NULL) {
fr->fr_ifa = GETUNIT(fr->fr_ifname);
if (fr->fr_ifa == NULL)
fr->fr_ifa = (void *)-1;
}
if (fr->fr_grp)
frsynclist(fr->fr_grp);
}
}
void frsync()
{
register struct ifnet *ifp;
# if !SOLARIS
# if defined(__OpenBSD__) || ((NetBSD >= 199511) && (NetBSD < 1991011)) || \
(defined(__FreeBSD_version) && (__FreeBSD_version >= 300000))
# if (NetBSD >= 199905) || defined(__OpenBSD__)
for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next)
# else
for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next)
# endif
# else
for (ifp = ifnet; ifp; ifp = ifp->if_next)
# endif
ip_natsync(ifp);
# endif
WRITE_ENTER(&ipf_mutex);
frsynclist(ipacct[0][fr_active]);
frsynclist(ipacct[1][fr_active]);
frsynclist(ipfilter[0][fr_active]);
frsynclist(ipfilter[1][fr_active]);
RWLOCK_EXIT(&ipf_mutex);
}
#else

View File

@ -51,7 +51,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)fils.c 1.21 4/20/96 (C) 1993-1996 Darren Reed";
static const char rcsid[] = "@(#)$Id: fils.c,v 2.2.2.3 1999/10/05 12:57:37 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: fils.c,v 2.2.2.4 1999/12/04 02:06:24 darrenr Exp $";
#endif
extern char *optarg;
@ -474,7 +474,8 @@ ips_stat_t *ipsp;
PRINTF(" keep state");
PRINTF("\n");
PRINTF("\tpkt_flags & %x = %x,\t", ips.is_flags & 0xf,
PRINTF("\tpkt_flags & %x(%x) = %x,\t",
ips.is_flags & 0xf, ips.is_flags,
ips.is_flags >> 4);
PRINTF("\tpkt_options & %x = %x\n", ips.is_optmsk,
ips.is_opt);

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.1.2.1 1999/09/18 15:03:51 darrenr Exp $
* $Id: ip_compat.h,v 2.1.2.3 1999/11/18 13:55:26 darrenr Exp $
*/
#ifndef __IP_COMPAT_H__
@ -99,6 +99,11 @@ struct ether_addr {
# include <inet/ip.h>
# include <inet/ip_ire.h>
# endif /* _KERNEL */
# if SOLARIS2 >= 8
# include <netinet/ip6.h>
# include <inet/ip6.h>
# define ipif_local_addr ipif_lcl_addr
# endif
#else
# if !defined(__sgi)
typedef int minor_t;
@ -650,8 +655,8 @@ typedef struct {
__u8 ip_hl:4;
__u8 ip_v:4;
# else
__u8 ip_hl:4;
__u8 ip_v:4;
__u8 ip_hl:4;
# endif
__u8 ip_tos;
__u16 ip_len;

View File

@ -7,7 +7,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.4.2.7 1999/10/15 13:49:43 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.4.2.14 1999/12/11 05:31:08 darrenr Exp $";
#endif
#ifndef SOLARIS
@ -141,6 +141,7 @@ static int (*fr_savep) __P((ip_t *, int, void *, int, struct mbuf **));
static int send_ip __P((struct mbuf *, ip_t *));
# ifdef __sgi
extern kmutex_t ipf_rw;
extern KRWLOCK_T ipf_mutex;
# endif
#else
int ipllog __P((void));
@ -574,42 +575,6 @@ int mode;
}
void frsync()
{
#ifdef _KERNEL
register frentry_t *f;
register struct ifnet *ifp;
# if defined(__OpenBSD__) || ((NetBSD >= 199511) && (NetBSD < 1991011)) || \
(defined(__FreeBSD_version) && (__FreeBSD_version >= 300000))
# if (NetBSD >= 199905) || defined(__OpenBSD__)
for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next)
# else
for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next)
# endif
# else
for (ifp = ifnet; ifp; ifp = ifp->if_next)
# endif
ip_natsync(ifp);
WRITE_ENTER(&ipf_mutex);
for (f = ipacct[0][fr_active]; (f != NULL); f = f->fr_next)
if (f->fr_ifa == (void *)-1)
f->fr_ifa = GETUNIT(f->fr_ifname);
for (f = ipacct[1][fr_active]; (f != NULL); f = f->fr_next)
if (f->fr_ifa == (void *)-1)
f->fr_ifa = GETUNIT(f->fr_ifname);
for (f = ipfilter[0][fr_active]; (f != NULL); f = f->fr_next)
if (f->fr_ifa == (void *)-1)
f->fr_ifa = GETUNIT(f->fr_ifname);
for (f = ipfilter[1][fr_active]; (f != NULL); f = f->fr_next)
if (f->fr_ifa == (void *)-1)
f->fr_ifa = GETUNIT(f->fr_ifname);
RWLOCK_EXIT(&ipf_mutex);
#endif
}
void fr_forgetifp(ifp)
void *ifp;
{
@ -737,14 +702,15 @@ caddr_t data;
}
if (!f) {
ftail = fprev;
if (req != SIOCINAFR && req != SIOCINIFR)
if (req != SIOCINAFR || req != SIOCINIFR)
while ((f = *ftail))
ftail = &f->fr_next;
else if (fp->fr_hits)
while (--fp->fr_hits && (f = *ftail))
ftail = &f->fr_next;
f = NULL;
else {
if (fp->fr_hits)
while (--fp->fr_hits && (f = *ftail))
ftail = &f->fr_next;
f = NULL;
}
}
if (req == SIOCDELFR || req == SIOCRMIFR) {
@ -769,7 +735,7 @@ caddr_t data;
error = EEXIST;
else {
if (unit == IPL_LOGAUTH)
return fr_auth_ioctl(data, req, f, ftail);
return fr_auth_ioctl(data, req, fp, ftail);
KMALLOC(f, frentry_t *);
if (f != NULL) {
if (fg && fg->fg_head)
@ -958,6 +924,9 @@ ip_t *ip;
ip->ip_ttl = ip_defttl;
# endif
# ifdef IPSEC
m->m_pkthdr.rcvif = NULL;
# endif
# if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)
{
int err;
@ -985,7 +954,7 @@ int send_icmp_err(oip, type, code, ifp, dst)
ip_t *oip;
int type, code;
void *ifp;
struct in_addr dst;
struct in_addr dst;
{
struct icmp *icmp;
struct mbuf *m;
@ -1020,7 +989,6 @@ struct in_addr dst;
if (dst.s_addr == 0) {
if (fr_ifpaddr(ifp, &dst) == -1)
return -1;
dst.s_addr = htonl(dst.s_addr);
}
nip->ip_src = dst;
nip->ip_dst = oip->ip_src;
@ -1107,9 +1075,12 @@ frdest_t *fdp;
* In case we're here due to "to <if>" being used with "keep state",
* check that we're going in the correct direction.
*/
if ((fr != NULL) && (ifp != NULL) && (fin->fin_rev != 0) &&
(fdp == &fr->fr_tif))
return -1;
if ((fr != NULL) && (fin->fin_rev != 0)) {
if ((ifp != NULL) && (fdp == &fr->fr_tif))
return -1;
dst->sin_addr = ip->ip_dst;
} else
dst->sin_addr = fdp->fd_ip.s_addr ? fdp->fd_ip : ip->ip_dst;
# ifdef __bsdi__
dst->sin_len = sizeof(*dst);
# endif
@ -1236,6 +1207,10 @@ frdest_t *fdp;
error = ENOBUFS; /* ??? */
goto sendorfree;
}
# if BSD >= 199306
m->m_pkthdr.len = mhlen + len;
m->m_pkthdr.rcvif = NULL;
# endif
# ifndef sparc
mhip->ip_off = htons((u_short)mhip->ip_off);
# endif
@ -1279,6 +1254,9 @@ frdest_t *fdp;
RTFREE(ro->ro_rt);
return 0;
bad:
if (error == EMSGSIZE)
(void) send_icmp_err(ip, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG,
ifp, ip->ip_dst);
m_freem(m);
goto done;
}
@ -1466,4 +1444,10 @@ struct ifnet *ifp;
verbose("- TCP RST sent\n");
return 0;
}
void frsync()
{
return;
}
#endif /* _KERNEL */

View File

@ -6,7 +6,7 @@
* to the original author and the contributors.
*
* @(#)ip_fil.h 1.35 6/5/96
* $Id: ip_fil.h,v 2.3.2.4 1999/10/15 13:42:37 darrenr Exp $
* $Id: ip_fil.h,v 2.3.2.6 1999/12/17 12:58:16 darrenr Exp $
*/
#ifndef __IP_FIL_H__
@ -106,6 +106,7 @@ typedef struct fr_ip {
*/
#define FI_W_SPORT 0x00000100
#define FI_W_DPORT 0x00000200
#define FI_WILD (FI_W_SPORT|FI_W_DPORT)
typedef struct fr_info {
void *fin_ifp; /* interface packet is `on' */
@ -306,11 +307,15 @@ typedef struct friostat {
struct frentry *f_auth;
struct frgroup *f_groups[3][2];
u_long f_froute[2];
int f_active; /* 1 or 0 - active rule set */
int f_defpass; /* default pass - from fr_pass */
int f_running; /* 1 if running, else 0 */
int f_logging; /* 1 if enabled, else 0 */
char f_active; /* 1 or 0 - active rule set */
char f_running; /* 1 if running, else 0 */
char f_logging; /* 1 if enabled, else 0 */
#if !SOLARIS && defined(sun)
char f_version[25]; /* version string */
#else
char f_version[32]; /* version string */
#endif
} friostat_t;
typedef struct optlist {

View File

@ -7,7 +7,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.4.2.3 1999/09/18 15:03:54 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.4.2.4 1999/11/28 04:52:10 darrenr Exp $";
#endif
#if defined(KERNEL) && !defined(_KERNEL)
@ -279,14 +279,14 @@ ipfr_t *table[];
f->ipfr_prev = NULL;
table[idx] = f;
}
off = ip->ip_off;
off = ip->ip_off & IP_OFFMASK;
atoff = off + (fin->fin_dlen >> 3);
/*
* If we've follwed the fragments, and this is the
* last (in order), shrink expiration time.
*/
if ((off & IP_OFFMASK) == f->ipfr_off) {
if (!(off & IP_MF))
if (off == f->ipfr_off) {
if (!(ip->ip_off & IP_MF))
f->ipfr_ttl = 1;
else
f->ipfr_off = atoff;

View File

@ -212,7 +212,7 @@ nat_t *nat;
sum2 -= sum1;
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
fix_outcksum(&ip->ip_sum, sum2);
fix_outcksum(&ip->ip_sum, sum2, 0);
#endif
ip->ip_len += inc;
}
@ -407,7 +407,7 @@ nat_t *nat;
sum2 -= sum1;
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
fix_outcksum(&ip->ip_sum, sum2);
fix_outcksum(&ip->ip_sum, sum2, 0);
#endif
ip->ip_len += inc;
}

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.2.2.5 1999/10/05 12:58:33 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.2.2.11 1999/12/17 13:05:40 darrenr Exp $";
#endif
#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL)
@ -198,15 +198,22 @@ ipnat_t *n;
}
void fix_outcksum(sp, n)
void fix_outcksum(sp, n , len)
u_short *sp;
u_32_t n;
int len;
{
register u_short sumshort;
register u_32_t sum1;
if (!n)
return;
#if SOLARIS2 >= 6
else if (n & NAT_HW_CKSUM) {
*sp = n & 0xffff;
return;
}
#endif
sum1 = (~ntohs(*sp)) & 0xffff;
sum1 += (n);
sum1 = (sum1 >> 16) + (sum1 & 0xffff);
@ -217,15 +224,22 @@ u_32_t n;
}
void fix_incksum(sp, n)
void fix_incksum(sp, n , len)
u_short *sp;
u_32_t n;
int len;
{
register u_short sumshort;
register u_32_t sum1;
if (!n)
return;
#if SOLARIS2 >= 6
else if (n & NAT_HW_CKSUM) {
*sp = n & 0xffff;
return;
}
#endif
#ifdef sparc
sum1 = (~(*sp)) & 0xffff;
#else
@ -312,6 +326,14 @@ int mode;
switch (cmd)
{
#ifdef IPFILTER_LOG
case SIOCIPFFB :
if (!(mode & FWRITE))
error = EPERM;
else
*(int *)data = ipflog_clear(IPL_LOGNAT);
break;
#endif
case SIOCADNAT :
if (!(mode & FWRITE)) {
error = EPERM;
@ -664,6 +686,9 @@ int direction;
tcphdr_t *tcp = NULL;
u_short nflags;
u_int hv;
#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6)
qif_t *qf = fin->fin_qif;
#endif
nflags = flags & np->in_flags;
if (flags & IPN_TCPUDP) {
@ -756,6 +781,7 @@ int direction;
KFREE(nat);
return NULL;
}
in.s_addr = ntohl(in.s_addr);
} else if (!in.s_addr && !np->in_outmsk) {
/*
* 0/0 - use the original source address/port.
@ -827,7 +853,7 @@ int direction;
* this is appropriate.
*/
inb.s_addr = htonl(in.s_addr);
natl = nat_inlookup(fin->fin_ifp, flags,
natl = nat_inlookup(fin->fin_ifp, flags & ~FI_WILD,
(u_int)ip->ip_p, ip->ip_dst, inb,
(port << 16) | dport);
@ -896,7 +922,21 @@ int direction;
}
CALC_SUMD(sum1, sum2, sumd);
nat->nat_sumd = (sumd & 0xffff) + (sumd >> 16);
nat->nat_sumd[0] = (sumd & 0xffff) + (sumd >> 16);
#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6)
if ((flags == IPN_TCP) && dohwcksum &&
(qf->qf_ill->ill_ick.ick_magic == ICK_M_CTL_MAGIC)) {
if (direction == NAT_OUTBOUND)
sum1 = LONG_SUM(ntohl(in.s_addr));
else
sum1 = LONG_SUM(ntohl(ip->ip_src.s_addr));
sum1 += LONG_SUM(ntohl(ip->ip_dst.s_addr));
sum1 += 30;
sum1 = (sum1 & 0xffff) + (sum1 >> 16);
nat->nat_sumd[1] = NAT_HW_CKSUM|(sum1 & 0xffff);
} else
#endif
nat->nat_sumd[1] = nat->nat_sumd[0];
if ((flags & IPN_TCPUDP) && ((sport != port) || (dport != nport))) {
if (direction == NAT_OUTBOUND)
@ -909,7 +949,7 @@ int direction;
CALC_SUMD(sum1, sum2, sumd);
nat->nat_ipsumd = (sumd & 0xffff) + (sumd >> 16);
} else
nat->nat_ipsumd = nat->nat_sumd;
nat->nat_ipsumd = nat->nat_sumd[0];
in.s_addr = htonl(in.s_addr);
nat->nat_next = nat_instances;
@ -1042,19 +1082,19 @@ u_int *nflags;
CALC_SUMD(sum1, sum2, sumd);
if (nat->nat_dir == NAT_OUTBOUND) {
fix_incksum(&oip->ip_sum, sumd);
fix_incksum(&oip->ip_sum, sumd, 0);
sumd += (sumd & 0xffff);
while (sumd > 0xffff)
sumd = (sumd & 0xffff) + (sumd >> 16);
fix_outcksum(&icmp->icmp_cksum, sumd);
fix_outcksum(&icmp->icmp_cksum, sumd, 0);
} else {
fix_outcksum(&oip->ip_sum, sumd);
fix_outcksum(&oip->ip_sum, sumd, 0);
sumd += (sumd & 0xffff);
while (sumd > 0xffff)
sumd = (sumd & 0xffff) + (sumd >> 16);
fix_incksum(&icmp->icmp_cksum, sumd);
fix_incksum(&icmp->icmp_cksum, sumd, 0);
}
@ -1070,7 +1110,7 @@ u_int *nflags;
sum2 = ntohs(nat->nat_inport);
CALC_SUMD(sum1, sum2, sumd);
tcp->th_sport = nat->nat_inport;
fix_outcksum(&icmp->icmp_cksum, sumd);
fix_outcksum(&icmp->icmp_cksum, sumd, 0);
}
} else {
if (tcp->th_dport != nat->nat_outport) {
@ -1078,7 +1118,7 @@ u_int *nflags;
sum2 = ntohs(nat->nat_outport);
CALC_SUMD(sum1, sum2, sumd);
tcp->th_dport = nat->nat_outport;
fix_incksum(&icmp->icmp_cksum, sumd);
fix_incksum(&icmp->icmp_cksum, sumd, 0);
}
}
}
@ -1351,9 +1391,9 @@ fr_info_t *fin;
*/
#if SOLARIS || defined(__sgi)
if (nat->nat_dir == NAT_OUTBOUND)
fix_outcksum(&ip->ip_sum, nat->nat_ipsumd);
fix_outcksum(&ip->ip_sum, nat->nat_ipsumd, 0);
else
fix_incksum(&ip->ip_sum, nat->nat_ipsumd);
fix_incksum(&ip->ip_sum, nat->nat_ipsumd, 0);
#endif
if (!(ip->ip_off & IP_OFFMASK) &&
@ -1392,9 +1432,11 @@ fr_info_t *fin;
}
if (csump) {
if (nat->nat_dir == NAT_OUTBOUND)
fix_outcksum(csump, nat->nat_sumd);
fix_outcksum(csump, nat->nat_sumd[1],
ip->ip_len);
else
fix_incksum(csump, nat->nat_sumd);
fix_incksum(csump, nat->nat_sumd[1],
ip->ip_len);
}
}
if ((np->in_apr != NULL) && (np->in_dport == 0 ||
@ -1484,7 +1526,8 @@ fr_info_t *fin;
((in.s_addr & np->in_outmsk) == np->in_outip) &&
((src.s_addr & np->in_srcmsk) == np->in_srcip) &&
(np->in_redir & NAT_REDIRECT) &&
(!np->in_pmin || np->in_pmin == dport)) {
(!np->in_pmin || np->in_pmin == dport) &&
(!np->in_p || np->in_p == ip->ip_p)) {
if ((nat = nat_new(np, ip, fin, nflags,
NAT_INBOUND))) {
np->in_hits++;
@ -1529,9 +1572,9 @@ fr_info_t *fin;
*/
#if SOLARIS || defined(__sgi)
if (nat->nat_dir == NAT_OUTBOUND)
fix_incksum(&ip->ip_sum, nat->nat_ipsumd);
fix_incksum(&ip->ip_sum, nat->nat_ipsumd, 0);
else
fix_outcksum(&ip->ip_sum, nat->nat_ipsumd);
fix_outcksum(&ip->ip_sum, nat->nat_ipsumd, 0);
#endif
if (!(ip->ip_off & IP_OFFMASK) &&
!(fin->fin_fi.fi_fl & FI_SHORT)) {
@ -1569,9 +1612,9 @@ fr_info_t *fin;
}
if (csump) {
if (nat->nat_dir == NAT_OUTBOUND)
fix_incksum(csump, nat->nat_sumd);
fix_incksum(csump, nat->nat_sumd[0], 0);
else
fix_outcksum(csump, nat->nat_sumd);
fix_outcksum(csump, nat->nat_sumd[0], 0);
}
}
ATOMIC_INC(nat_stats.ns_mapped[0]);
@ -1675,7 +1718,7 @@ void *ifp;
*/
sum1 = nat->nat_outip.s_addr;
if (fr_ifpaddr(ifp2, &in) != -1)
nat->nat_outip.s_addr = htonl(in.s_addr);
nat->nat_outip = in;
sum2 = nat->nat_outip.s_addr;
if (sum1 == sum2)
@ -1685,13 +1728,20 @@ void *ifp;
* account the new IP#.
*/
CALC_SUMD(sum1, sum2, sumd);
sumd += nat->nat_sumd;
nat->nat_sumd = (sumd & 0xffff) + (sumd >> 16);
/* XXX - dont change for TCP when solaris does
* hardware checksumming.
*/
sumd += nat->nat_sumd[0];
nat->nat_sumd[0] = (sumd & 0xffff) + (sumd >> 16);
nat->nat_sumd[1] = nat->nat_sumd[0];
}
for (n = nat_list; (n != NULL); n = n->in_next)
if (n->in_ifp == ifp)
if (n->in_ifp == ifp) {
n->in_ifp = (void *)GETUNIT(n->in_ifname);
if (!n->in_ifp)
n->in_ifp = (void *)-1;
}
RWLOCK_EXIT(&ipf_nat);
SPL_X(s);
}

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.1.2.1 1999/08/14 04:47:54 darrenr Exp $
* $Id: ip_nat.h,v 2.1.2.2 1999/11/28 11:01:51 darrenr Exp $
*/
#ifndef __IP_NAT_H__
@ -57,13 +57,14 @@
#ifndef APR_LABELLEN
#define APR_LABELLEN 16
#endif
#define NAT_HW_CKSUM 0x80000000
#define DEF_NAT_AGE 1200 /* 10 minutes (600 seconds) */
typedef struct nat {
u_long nat_age;
int nat_flags;
u_32_t nat_sumd;
u_32_t nat_sumd[2];
u_32_t nat_ipsumd;
void *nat_data;
void *nat_aps; /* proxy session */
@ -240,7 +241,7 @@ 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));
extern void fix_outcksum __P((u_short *, u_32_t));
extern void fix_incksum __P((u_short *, u_32_t, int));
extern void fix_outcksum __P((u_short *, u_32_t, int));
#endif /* __IP_NAT_H__ */

View File

@ -55,15 +55,12 @@ ip_t *ip;
ap_session_t *aps;
nat_t *nat;
{
char membuf[512 + 1], *s;
int off, dlen, inc = 0;
tcphdr_t *tcp, tcph, *tcp2 = &tcph;
raudio_t *rap = aps->aps_data;
u_short sp, dp, id = 0;
struct in_addr swip;
fr_info_t fi;
unsigned char membuf[512 + 1], *s;
u_short id = 0;
tcphdr_t *tcp;
int off, dlen;
int len = 0;
nat_t *ipn;
mb_t *m;
#if SOLARIS
mb_t *m1;
@ -85,14 +82,14 @@ nat_t *nat;
dlen = msgdsize(m) - off;
if (dlen <= 0)
return 0;
copyout_mblk(m, off, MIN(sizeof(membuf), dlen), membuf);
copyout_mblk(m, off, MIN(sizeof(membuf), dlen), (char *)membuf);
#else
m = *(mb_t **)fin->fin_mp;
dlen = mbufchainlen(m) - off;
if (dlen <= 0)
return 0;
m_copydata(m, off, MIN(sizeof(membuf), dlen), membuf);
m_copydata(m, off, MIN(sizeof(membuf), dlen), (char *)membuf);
#endif
/*
* In all the startup parsing, ensure that we don't go outside
@ -102,7 +99,7 @@ nat_t *nat;
* Look for the start of connection "PNA" string if not seen yet.
*/
if (rap->rap_seenpna == 0) {
s = memstr("PNA", membuf, 3, dlen);
s = (u_char *)memstr("PNA", (char *)membuf, 3, dlen);
if (s == NULL)
return 0;
s += 3;
@ -156,38 +153,7 @@ nat_t *nat;
rap->rap_gotid = 0;
}
}
/*
* Wait until we've seen the end of the start messages and even then
* only proceed further if we're using UDP.
*/
if ((rap->rap_eos == 0) || ((rap->rap_mode & RAP_M_UDP) != RAP_M_UDP))
return 0;
sp = rap->rap_plport;
dp = 0;
bcopy((char *)fin, (char *)&fi, sizeof(fi));
bzero((char *)tcp2, sizeof(*tcp2));
tcp2->th_sport = htons(sp);
tcp2->th_dport = 0; /* XXX - don't specify remote port */
tcp2->th_win = htons(8192);
fi.fin_dp = (char *)tcp2;
fi.fin_data[0] = sp;
fi.fin_data[1] = 0;
fi.fin_fr = &raudiofr;
swip = ip->ip_src;
ip->ip_src = nat->nat_inip;
ipn = nat_new(nat->nat_ptr, ip, &fi, IPN_TCP|FI_W_DPORT, NAT_OUTBOUND);
if (ipn != NULL) {
ipn->nat_age = fr_defnatage;
(void) fr_addstate(ip, &fi, FI_W_DPORT);
}
ip->ip_src = swip;
if ((rap->rap_mode & RAP_M_UDP_ROBUST) == RAP_M_UDP_ROBUST) {
sp = rap->rap_prport;
}
return inc;
return 0;
}
@ -197,19 +163,28 @@ ip_t *ip;
ap_session_t *aps;
nat_t *nat;
{
char membuf[IPF_MAXPORTLEN + 1], *s;
int off, dlen;
unsigned char membuf[IPF_MAXPORTLEN + 1], *s;
tcphdr_t *tcp, tcph, *tcp2 = &tcph;
raudio_t *rap = aps->aps_data;
struct in_addr swa, swb;
u_int a1, a2, a3, a4;
tcphdr_t *tcp;
u_short sp, dp;
int off, dlen;
fr_info_t fi;
tcp_seq seq;
nat_t *ipn;
u_char swp;
mb_t *m;
#if SOLARIS
mb_t *m1;
#endif
if ((rap->rap_sdone != 0) ||
((rap->rap_mode & RAP_M_UDP_ROBUST) != RAP_M_UDP_ROBUST))
/*
* Wait until we've seen the end of the start messages and even then
* only proceed further if we're using UDP. If they want to use TCP
* then data is sent back on the same channel that is already open.
*/
if (rap->rap_sdone != 0)
return 0;
tcp = (tcphdr_t *)fin->fin_dp;
@ -223,13 +198,13 @@ nat_t *nat;
if (dlen <= 0)
return 0;
bzero(membuf, sizeof(membuf));
copyout_mblk(m, off, MIN(sizeof(membuf), dlen), membuf);
copyout_mblk(m, off, MIN(sizeof(membuf), dlen), (char *)membuf);
#else
dlen = mbufchainlen(m) - off;
if (dlen <= 0)
return 0;
bzero(membuf, sizeof(membuf));
m_copydata(m, off, MIN(sizeof(membuf), dlen), membuf);
m_copydata(m, off, MIN(sizeof(membuf), dlen), (char *)membuf);
#endif
seq = ntohl(tcp->th_seq);
@ -238,7 +213,7 @@ nat_t *nat;
* We only care for the first 19 bytes coming back from the server.
*/
if (rap->rap_sseq == 0) {
s = memstr("PNA", membuf, 3, dlen);
s = (u_char *)memstr("PNA", (char *)membuf, 3, dlen);
if (s == NULL)
return 0;
a1 = s - membuf;
@ -258,13 +233,68 @@ nat_t *nat;
} else
return 0;
for (a3 = a1, a4 = a2; a4 > 0; a4--, a3++) {
for (a3 = a1, a4 = a2; (a4 > 0) && (a3 < 19) && (a3 >= 0); a4--,a3++) {
rap->rap_sbf |= (1 << a3);
rap->rap_svr[a3] = *s++;
}
if (rap->rap_sbf == 0x7ffff) { /* 19 bits */
s = rap->rap_svr + 13;
if ((rap->rap_sbf != 0x7ffff) || (!rap->rap_eos)) /* 19 bits */
return 0;
rap->rap_sdone = 1;
s = (u_char *)rap->rap_svr + 11;
if (((*s << 8) | *(s + 1)) == RA_ID_ROBUST) {
s += 2;
rap->rap_srport = (*s << 8) | *(s + 1);
}
swp = ip->ip_p;
swa = ip->ip_src;
swb = ip->ip_dst;
ip->ip_p = IPPROTO_UDP;
ip->ip_src = nat->nat_inip;
ip->ip_dst = nat->nat_oip;
bcopy((char *)fin, (char *)&fi, sizeof(fi));
bzero((char *)tcp2, sizeof(*tcp2));
fi.fin_dp = (char *)tcp2;
fi.fin_fr = &raudiofr;
tcp2->th_win = htons(8192);
if (((rap->rap_mode & RAP_M_UDP_ROBUST) == RAP_M_UDP_ROBUST) &&
(rap->rap_srport != 0)) {
dp = rap->rap_srport;
sp = rap->rap_prport;
tcp2->th_sport = htons(sp);
tcp2->th_dport = htons(dp);
fi.fin_data[0] = dp;
fi.fin_data[1] = sp;
ipn = nat_new(nat->nat_ptr, ip, &fi,
IPN_UDP | (sp ? 0 : FI_W_SPORT),
NAT_OUTBOUND);
if (ipn != NULL) {
ipn->nat_age = fr_defnatage;
(void) fr_addstate(ip, &fi, sp ? 0 : FI_W_SPORT);
}
}
if ((rap->rap_mode & RAP_M_UDP) == RAP_M_UDP) {
sp = rap->rap_plport;
tcp2->th_sport = htons(sp);
tcp2->th_dport = 0; /* XXX - don't specify remote port */
fi.fin_data[0] = sp;
fi.fin_data[1] = 0;
ipn = nat_new(nat->nat_ptr, ip, &fi, IPN_UDP|FI_W_DPORT,
NAT_OUTBOUND);
if (ipn != NULL) {
ipn->nat_age = fr_defnatage;
(void) fr_addstate(ip, &fi, FI_W_DPORT);
}
}
ip->ip_p = swp;
ip->ip_src = swa;
ip->ip_dst = swb;
return 0;
}

View File

@ -9,7 +9,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "%W% %G% (C) 1993-1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.1.2.2 1999/10/05 12:59:08 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.1.2.5 1999/12/11 05:31:10 darrenr Exp $";
#endif
#include <sys/types.h>
@ -498,14 +498,15 @@ caddr_t data;
}
if (!f) {
ftail = fprev;
if (req != SIOCINAFR && req != SIOCINIFR)
if (req != SIOCINAFR || req != SIOCINIFR)
while ((f = *ftail))
ftail = &f->fr_next;
else if (fp->fr_hits)
while (--fp->fr_hits && (f = *ftail))
ftail = &f->fr_next;
f = NULL;
else {
if (fp->fr_hits)
while (--fp->fr_hits && (f = *ftail))
ftail = &f->fr_next;
f = NULL;
}
}
if (req == SIOCDELFR || req == SIOCRMIFR) {
@ -534,7 +535,7 @@ caddr_t data;
error = EEXIST;
} else {
if (unit == IPL_LOGAUTH) {
error = fr_auth_ioctl(data, req, f, ftail);
error = fr_auth_ioctl(data, req, fp, ftail);
goto out;
}
KMALLOC(f, frentry_t *);

View File

@ -7,7 +7,7 @@
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.3.2.9 1999/10/21 14:31:09 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.3.2.16 1999/12/28 05:24:58 darrenr Exp $";
#endif
#include <sys/errno.h>
@ -200,10 +200,6 @@ int which;
} else
isp = &is->is_next;
}
if (fr_state_doflush) {
(void) fr_state_flush(1);
fr_state_doflush = 0;
}
RWLOCK_EXIT(&ipf_state);
SPL_X(s);
return removed;
@ -231,6 +227,14 @@ int mode;
} else
error = EINVAL;
break;
#ifdef IPFILTER_LOG
case SIOCIPFFB :
if (!(mode & FWRITE))
error = EPERM;
else
*(int *)data = ipflog_clear(IPL_LOGSTATE);
break;
#endif
case SIOCGIPST :
IWCOPY((caddr_t)fr_statetstats(), data, sizeof(ips_stat_t));
break;
@ -346,9 +350,11 @@ u_int flags;
{
register tcphdr_t *tcp = (tcphdr_t *)fin->fin_dp;
is->is_dport = tcp->th_dport;
is->is_sport = tcp->th_sport;
if ((flags & (FI_W_DPORT|FI_W_SPORT)) == 0) {
hv += (is->is_dport = tcp->th_dport);
hv += (is->is_sport = tcp->th_sport);
hv += tcp->th_dport;
hv += tcp->th_sport;
}
ATOMIC_INC(ips_stats.iss_udp);
is->is_age = fr_udptimeout;
@ -656,12 +662,14 @@ fr_info_t *fin;
register u_short sport, dport;
register u_char pr;
struct icmp *ic;
u_short savelen;
fr_info_t ofin;
u_int hv, dest;
tcphdr_t *tcp;
icmphdr_t *icmp;
frentry_t *fr;
ip_t *oip;
int type;
u_int hv;
/*
* Does it at least have the return (basic) IP header ?
@ -683,6 +691,70 @@ fr_info_t *fin;
oip = (ip_t *)((char *)fin->fin_dp + ICMPERR_ICMPHLEN);
if (ip->ip_len < ICMPERR_MAXPKTLEN + ((oip->ip_hl - 5) << 2))
return NULL;
if (oip->ip_p == IPPROTO_ICMP) {
icmp = (icmphdr_t *)((char *)oip + (oip->ip_hl << 2));
/*
* a ICMP error can only be generated as a result of an
* ICMP query, not as the response on an ICMP error
*
* XXX theoretically ICMP_ECHOREP and the other reply's are
* ICMP query's as well, but adding them here seems strange XXX
*/
if ((icmp->icmp_type != ICMP_ECHO) &&
(icmp->icmp_type != ICMP_TSTAMP) &&
(icmp->icmp_type != ICMP_IREQ) &&
(icmp->icmp_type != ICMP_MASKREQ))
return NULL;
/*
* perform a lookup of the ICMP packet in the state table
*/
hv = (pr = oip->ip_p);
hv += (src.s_addr = oip->ip_src.s_addr);
hv += (dst.s_addr = oip->ip_dst.s_addr);
if (icmp->icmp_type == ICMP_ECHO) {
hv += icmp->icmp_id;
hv += icmp->icmp_seq;
}
hv %= fr_statesize;
oip->ip_len = ntohs(oip->ip_len);
fr_makefrip(oip->ip_hl << 2, oip, &ofin);
oip->ip_len = htons(oip->ip_len);
ofin.fin_ifp = fin->fin_ifp;
ofin.fin_out = !fin->fin_out;
ofin.fin_mp = NULL; /* if dereferenced, panic XXX */
READ_ENTER(&ipf_state);
for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_next)
if ((is->is_p == pr) &&
fr_matchsrcdst(is, src, dst, &ofin, NULL)) {
/*
* in the state table ICMP query's are stored
* with the type of the corresponding ICMP
* response. Correct here
*/
if (((is->is_type == ICMP_ECHOREPLY) &&
(icmp->icmp_id == is->is_icmp.ics_id) &&
(icmp->icmp_seq == is->is_icmp.ics_seq) &&
(icmp->icmp_type == ICMP_ECHO)) ||
(is->is_type - 1 == ic->icmp_type)) {
ips_stats.iss_hits++;
is->is_pkts++;
is->is_bytes += ip->ip_len;
fr = is->is_rule;
RWLOCK_EXIT(&ipf_state);
return fr;
}
}
RWLOCK_EXIT(&ipf_state);
return NULL;
};
if ((oip->ip_p != IPPROTO_TCP) && (oip->ip_p != IPPROTO_UDP))
return NULL;
@ -706,9 +778,10 @@ fr_info_t *fin;
* watch out here, as ip is in host order and oip in network
* order. Any change we make must be undone afterwards.
*/
oip->ip_len = ntohs(oip->ip_len);
savelen = oip->ip_len;
oip->ip_len = ip->ip_len - (ip->ip_hl << 2) - ICMPERR_ICMPHLEN;
fr_makefrip(oip->ip_hl << 2, oip, &ofin);
oip->ip_len = htons(oip->ip_len);
oip->ip_len = savelen;
ofin.fin_ifp = fin->fin_ifp;
ofin.fin_out = !fin->fin_out;
ofin.fin_mp = NULL; /* if dereferenced, panic XXX */
@ -729,7 +802,6 @@ fr_info_t *fin;
* we must swap src and dst here because the icmp
* comes the other way around
*/
dest = (is->is_dst.s_addr != src.s_addr);
is->is_pkts++;
is->is_bytes += ip->ip_len;
/*
@ -777,17 +849,20 @@ fr_info_t *fin;
switch (ip->ip_p)
{
case IPPROTO_ICMP :
hv += ic->icmp_id;
hv += ic->icmp_seq;
if ((ic->icmp_type == ICMP_ECHO) ||
(ic->icmp_type == ICMP_ECHOREPLY)) {
hv += ic->icmp_id;
hv += ic->icmp_seq;
}
hv %= fr_statesize;
READ_ENTER(&ipf_state);
for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_next)
if ((is->is_p == pr) &&
(ic->icmp_id == is->is_icmp.ics_id) &&
(ic->icmp_seq == is->is_icmp.ics_seq) &&
fr_matchsrcdst(is, src, dst, fin, NULL)) {
if ((is->is_type == ICMP_ECHOREPLY) &&
(ic->icmp_type == ICMP_ECHO))
(ic->icmp_type == ICMP_ECHO) &&
(ic->icmp_id == is->is_icmp.ics_id) &&
(ic->icmp_seq == is->is_icmp.ics_seq))
;
else if (is->is_type != ic->icmp_type)
continue;
@ -818,7 +893,6 @@ fr_info_t *fin;
if ((is->is_p == pr) &&
fr_matchsrcdst(is, src, dst, fin, tcp)) {
if (fr_tcpstate(is, fin, ip, tcp)) {
break;
#ifndef _KERNEL
if (tcp->th_flags & TCP_CLOSE) {
*isp = is->is_next;
@ -964,6 +1038,10 @@ void fr_timeoutstate()
ips_num--;
} else
isp = &is->is_next;
if (fr_state_doflush) {
(void) fr_state_flush(1);
fr_state_doflush = 0;
}
RWLOCK_EXIT(&ipf_state);
SPL_X(s);
}

View File

@ -11,6 +11,6 @@
#ifndef __IPL_H__
#define __IPL_H__
#define IPL_VERSION "IP Filter: v3.3.3"
#define IPL_VERSION "IP Filter: v3.3.6"
#endif

View File

@ -6,7 +6,7 @@
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* $Id: iplang_y.y,v 2.1 1999/08/04 17:30:53 darrenr Exp $
* $Id: iplang_y.y,v 2.1.2.1 1999/11/21 11:05:09 darrenr Exp $
*/
#include <stdio.h>
@ -164,6 +164,7 @@ void end_tcp __P((void));
void end_data __P((void));
void yyerror __P((char *));
void iplang __P((FILE *));
int arp_getipv4 __P((char *, char *));
int yyparse __P((void));
%}
%union {

View File

@ -56,7 +56,7 @@ extern char *sys_errlist[];
#if !defined(lint)
static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed";
static const char rcsid[] = "@(#)$Id: ipnat.c,v 2.1 1999/08/04 17:30:07 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ipnat.c,v 2.1.2.2 1999/12/04 02:09:30 darrenr Exp $";
#endif
@ -77,6 +77,7 @@ int countbits __P((u_32_t));
char *getnattype __P((ipnat_t *));
int main __P((int, char*[]));
void printaps __P((ap_session_t *, int));
char *getsumd __P((u_32_t));
#define OPT_REM 1
#define OPT_NODO 2
@ -96,6 +97,19 @@ char *name;
}
char *getsumd(sum)
u_32_t sum;
{
static char sumdbuf[17];
if (sum & NAT_HW_CKSUM)
sprintf(sumdbuf, "hw(%#0x)", sum & 0xffff);
else
sprintf(sumdbuf, "%#0x", sum);
return sumdbuf;
}
int main(argc, argv)
int argc;
char *argv[];
@ -332,10 +346,12 @@ int fd, opts;
printf(" [%s %hu]", inet_ntoa(nat.nat_oip),
ntohs(nat.nat_oport));
if (opts & OPT_VERBOSE) {
printf("\n\tage %lu use %hu sumd %x pr %u",
nat.nat_age, nat.nat_use, nat.nat_sumd,
nat.nat_p);
printf(" bkt %d flags %x ", i, nat.nat_flags);
printf("\n\tage %lu use %hu sumd %s/",
nat.nat_age, nat.nat_use,
getsumd(nat.nat_sumd[0]));
printf("%s pr %u bkt %d flags %x ",
getsumd(nat.nat_sumd[1]), nat.nat_p,
i, nat.nat_flags);
#ifdef USE_QUAD_T
printf("bytes %qu pkts %qu",
nat.nat_bytes, nat.nat_pkts);

View File

@ -12,13 +12,14 @@
*/
#if !defined(lint)
static const char sccsid[] = "%W% %G% (C)1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: iptest.c,v 2.1 1999/08/04 17:31:08 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: iptest.c,v 2.1.2.2 1999/11/28 03:43:45 darrenr Exp $";
#endif
#include <stdio.h>
#include <netdb.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
@ -97,7 +98,8 @@ char **argv;
struct tcpiphdr *ti;
struct in_addr gwip;
ip_t *ip;
char *name = argv[0], host[64], *gateway = NULL, *dev = NULL;
char *name = argv[0], host[MAXHOSTNAMELEN + 1];
char *gateway = NULL, *dev = NULL;
char *src = NULL, *dst;
int mtu = 1500, tests = 0, pointtest = 0, c;
@ -153,6 +155,7 @@ char **argv;
if (!src)
{
gethostname(host, sizeof(host));
host[sizeof(host) - 1] = '\0';
src = host;
}

View File

@ -53,7 +53,7 @@ extern char *sys_errlist[];
#if !defined(lint)
static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed";
static const char rcsid[] = "@(#)$Id: natparse.c,v 1.2 1999/08/01 11:17:18 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: natparse.c,v 1.2.2.1 1999/11/20 22:50:30 darrenr Exp $";
#endif
@ -547,13 +547,14 @@ int linenum;
ipn.in_flags = IPN_TCPUDP;
else if (!strcasecmp(s, "tcpudp"))
ipn.in_flags = IPN_TCPUDP;
else if (!strcasecmp(s, "ip"))
else if (!strcasecmp(s, "ip"))
ipn.in_flags = IPN_ANY;
else {
fprintf(stderr,
"%d: expected protocol - got \"%s\"\n",
linenum, s);
return NULL;
ipn.in_flags = IPN_ANY;
if ((pr = getprotobyname(s)))
ipn.in_p = pr->p_proto;
else
ipn.in_p = atoi(s);
}
proto = s;
if ((s = strtok(NULL, " \t"))) {

View File

@ -41,7 +41,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)parse.c 1.44 6/5/96 (C) 1993-1996 Darren Reed";
static const char rcsid[] = "@(#)$Id: parse.c,v 2.1.2.1 1999/09/11 05:32:10 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: parse.c,v 2.1.2.5 1999/12/28 06:06:58 darrenr Exp $";
#endif
extern struct ipopt_names ionames[], secclass[];
@ -94,7 +94,7 @@ int linenum;
struct protoent *p = NULL;
char *cps[31], **cpp, *endptr;
u_char ch;
int i, cnt = 1;
int i, cnt = 1, j;
while (*line && isspace(*line))
line++;
@ -133,15 +133,19 @@ int linenum;
fil.fr_flags |= FR_RETICMP;
if (fil.fr_flags & FR_RETICMP) {
cpp++;
if (*(*cpp + 11) == '(') {
i = icmpcode(*cpp + 12);
if (i == -1) {
i = 11;
if ((strlen(*cpp) > i) && (*(*cpp + i) != '('))
i = 19;
if (*(*cpp + i) == '(') {
i++;
j = icmpcode(*cpp + i);
if (j == -1) {
fprintf(stderr,
"%d: unrecognised icmp code %s\n",
linenum, *cpp + 12);
linenum, *cpp + 20);
return NULL;
}
fil.fr_icode = i;
fil.fr_icode = j;
}
} else if (!strncasecmp(*(cpp+1), "return-rst", 10)) {
fil.fr_flags |= FR_RETRST;
@ -239,7 +243,11 @@ int linenum;
return NULL;
if (!strcasecmp("log", *cpp)) {
cpp++;
if (!*++cpp) {
fprintf(stderr, "%d: missing source specification\n",
linenum);
return NULL;
}
if (fil.fr_flags & FR_PASS)
fil.fr_flags |= FR_LOGP;
else if (fil.fr_flags & FR_BLOCK)
@ -262,6 +270,39 @@ int linenum;
fil.fr_flags |= FR_LOGORBLOCK;
cpp++;
}
if (!strcasecmp(*cpp, "level")) {
int fac, pri;
char *s;
fac = 0;
pri = 0;
cpp++;
s = index(*cpp, '.');
if (s) {
*s++ = '\0';
fac = fac_findname(*cpp);
if (fac == -1) {
fprintf(stderr, "%d: %s %s\n", linenum,
"Unknown facility", *cpp);
return NULL;
}
pri = pri_findname(s);
if (pri == -1) {
fprintf(stderr, "%d: %s %s\n", linenum,
"Unknown priority", s);
return NULL;
}
} else {
pri = pri_findname(*cpp);
if (pri == -1) {
fprintf(stderr, "%d: %s %s\n", linenum,
"Unknown priority", *cpp);
return NULL;
}
}
fil.fr_loglevel = fac|pri;
cpp++;
}
}
if (!strcasecmp("quick", *cpp)) {
@ -535,8 +576,8 @@ int linenum;
else {
fprintf(stderr, "%d: invalid group (%s)\n",
linenum, *cpp);
return NULL;
}
return NULL;
}
cpp++;
}
@ -1376,9 +1417,9 @@ struct frentry *fp;
if (u == NULL)
u = "!!!";
if (*s)
printf("%s.%s ", s, u);
printf("level %s.%s ", s, u);
else
printf("%s ", u);
printf("level %s ", u);
}
}

View File

@ -2,7 +2,9 @@ How to setup FTP proxying using the built in proxy code.
========================================================
NOTE: Currently, the built-in FTP proxy is only available for use with NAT
(i.e. only if you're already using "map" rules with ipnat).
(i.e. only if you're already using "map" rules with ipnat). It does
support null-NAT mappings, that is, using the proxy without changing
the addresses.
Lets assume your network diagram looks something like this:
@ -38,3 +40,6 @@ ipaddr-a = 10.1.1.1
int-c = vx0
ipaddr-c-net = 203.45.67.91
The "map" rule for this proxy should precede any other NAT rules you are
using.

View File

@ -6,7 +6,7 @@
* to the original author and the contributors.
*/
/* #pragma ident "@(#)solaris.c 1.12 6/5/96 (C) 1995 Darren Reed"*/
#pragma ident "@(#)$Id: solaris.c,v 2.1.2.5 1999/10/15 13:49:44 darrenr Exp $";
#pragma ident "@(#)$Id: solaris.c,v 2.1.2.11 1999/12/04 03:33:59 darrenr Exp $"
#include <sys/systm.h>
#include <sys/types.h>
@ -31,6 +31,9 @@
#include <sys/stropts.h>
#include <sys/sockio.h>
#include <net/if.h>
#if SOLARIS2 >= 6
# include <net/if_types.h>
#endif
#include <net/af.h>
#include <net/route.h>
#include <netinet/in.h>
@ -139,6 +142,65 @@ static struct modldrv iplmod = {
&mod_driverops, IPL_VERSION, &ipf_ops };
static struct modlinkage modlink1 = { MODREV_1, &iplmod, NULL };
#if SOLARIS2 >= 6
static size_t hdrsizes[57][2] = {
{ 0, 0 },
{ IFT_OTHER, 0 },
{ IFT_1822, 0 },
{ IFT_HDH1822, 0 },
{ IFT_X25DDN, 0 },
{ IFT_X25, 0 },
{ IFT_ETHER, 14 },
{ IFT_ISO88023, 0 },
{ IFT_ISO88024, 0 },
{ IFT_ISO88025, 0 },
{ IFT_ISO88026, 0 },
{ IFT_STARLAN, 0 },
{ IFT_P10, 0 },
{ IFT_P80, 0 },
{ IFT_HY, 0 },
{ IFT_FDDI, 24 },
{ IFT_LAPB, 0 },
{ IFT_SDLC, 0 },
{ IFT_T1, 0 },
{ IFT_CEPT, 0 },
{ IFT_ISDNBASIC, 0 },
{ IFT_ISDNPRIMARY, 0 },
{ IFT_PTPSERIAL, 0 },
{ IFT_PPP, 0 },
{ IFT_LOOP, 0 },
{ IFT_EON, 0 },
{ IFT_XETHER, 0 },
{ IFT_NSIP, 0 },
{ IFT_SLIP, 0 },
{ IFT_ULTRA, 0 },
{ IFT_DS3, 0 },
{ IFT_SIP, 0 },
{ IFT_FRELAY, 0 },
{ IFT_RS232, 0 },
{ IFT_PARA, 0 },
{ IFT_ARCNET, 0 },
{ IFT_ARCNETPLUS, 0 },
{ IFT_ATM, 0 },
{ IFT_MIOX25, 0 },
{ IFT_SONET, 0 },
{ IFT_X25PLE, 0 },
{ IFT_ISO88022LLC, 0 },
{ IFT_LOCALTALK, 0 },
{ IFT_SMDSDXI, 0 },
{ IFT_FRELAYDCE, 0 },
{ IFT_V35, 0 },
{ IFT_HSSI, 0 },
{ IFT_HIPPI, 0 },
{ IFT_MODEM, 0 },
{ IFT_AAL5, 0 },
{ IFT_SONETPATH, 0 },
{ IFT_SONETVT, 0 },
{ IFT_SMDSICIP, 0 },
{ IFT_PROPVIRTUAL, 0 },
{ IFT_PROPMUX, 0 },
};
#endif /* SOLARIS2 >= 6 */
static dev_info_t *ipf_dev_info = NULL;
@ -415,12 +477,12 @@ size_t off;
if (!ip && (m == mt) && m->b_cont && (MTYPE(m) != M_DATA))
m = m->b_cont;
printf("!IP %s:%d %d %p %p %p %d %p/%d %p/%d %p %d %d %p\n",
cmn_err(CE_CONT, " !IP %s:%d %d %p %p %p %d %p/%d %p/%d %p %d %d %p\n",
qif ? qif->qf_name : "?", out, qif->qf_hl, q,
q ? q->q_ptr : NULL, q ? q->q_qinfo : NULL,
mt->b_wptr - mt->b_rptr, m, MTYPE(m), mt, MTYPE(mt), m->b_rptr,
m->b_wptr - m->b_rptr, off, ip);
printf("%02x%02x%02x%02x\n", *s, *(s+1), *(s+2), *(s+3));
cmn_err(CE_CONT, "%02x%02x%02x%02x\n", *s, *(s+1), *(s+2), *(s+3));
while (m != mt) {
i = 0;
t = outb;
@ -434,7 +496,7 @@ size_t off;
}
*t++ = '\n';
*t = '\0';
printf("%s", outb);
cmn_err(CE_CONT, "%s", outb);
mt = mt->b_cont;
}
i = 0;
@ -448,7 +510,7 @@ size_t off;
}
*t++ = '\n';
*t = '\0';
printf("%s", outb);
cmn_err(CE_CONT, "%s", outb);
}
@ -540,7 +602,7 @@ int out;
len = m->b_wptr - m->b_rptr;
if (m->b_wptr < m->b_rptr) {
cmn_err(CE_NOTE, "IP Filter: Bad packet: wptr %p < rptr %p",
cmn_err(CE_NOTE, "!IP Filter: Bad packet: wptr %p < rptr %p",
m->b_wptr, m->b_rptr);
frstats[out].fr_bad++;
return -1;
@ -558,12 +620,7 @@ int out;
* can, now ?
*/
fixalign:
if (off == (u_char *)ip - m->b_rptr) {
m->b_rptr += off;
off = 0;
}
if (!pullupmsg(m, sizeof(ip_t) + off)) {
cmn_err(CE_NOTE, "pullupmsg failed\n");
if (!pullupmsg(m, sizeof(ip_t))) {
frstats[out].fr_pull[1]++;
return -1;
}
@ -582,7 +639,6 @@ int out;
READ_ENTER(&ipfs_mutex);
goto tryagain;
}
fr_donotip(out, qif, q, m, mt, ip, off);
frstats[out].fr_notip++;
return (fr_flags & FF_BLOCKNONIP) ? -1 : 0;
}
@ -602,9 +658,6 @@ int out;
/*
* Bad IP packet or not enough data/data length mismatches
*/
cmn_err(CE_NOTE,
"IP Filter: Bad packet: iphlen %u ip_len %u mlen %u",
iphlen, ip->ip_len, mlen);
#ifndef sparc
__iplen = (u_short)ip->ip_len,
__ipoff = (u_short)ip->ip_off;
@ -679,7 +732,7 @@ int out;
#endif
} else
cmn_err(CE_NOTE,
"IP Filter: *mp %p mt %p %s\n", *mp, mt,
"!IP Filter: *mp %p mt %p %s\n", *mp, mt,
"mblk changed, cannot revert ip_len, ip_off");
}
return err;
@ -731,13 +784,13 @@ mblk_t *mb;
goto again;
}
cmn_err(CE_WARN,
"IP Filter: dropped: fr_qin(%x,%x): type %x qif %x",
"!IP Filter: dropped: fr_qin(%x,%x): type %x qif %x",
q, mb, MTYPE(mb), qif);
cmn_err(CE_CONT,
"IP Filter: info %x next %x ptr %x fsrv %x bsrv %x\n",
"!IP Filter: info %x next %x ptr %x fsrv %x bsrv %x\n",
q->q_qinfo, q->q_next, q->q_ptr, q->q_nfsrv,
q->q_nbsrv);
cmn_err(CE_CONT, "IP Filter: info: putp %x srvp %x info %x\n",
cmn_err(CE_CONT, "!IP Filter: info: putp %x srvp %x info %x\n",
q->q_qinfo->qi_putp, q->q_qinfo->qi_srvp,
#if SOLARIS > 3
q->q_qinfo->qi_infop
@ -767,7 +820,7 @@ mblk_t *mb;
if (pnext)
return (*pnext)(q, mb);
cmn_err(CE_WARN, "IP Filter: inp NULL: qif %x q %x info %x",
cmn_err(CE_WARN, "!IP Filter: inp NULL: qif %x q %x info %x",
qif, q, q->q_qinfo);
}
if (mb) {
@ -823,13 +876,13 @@ mblk_t *mb;
goto again;
}
cmn_err(CE_WARN,
"IP Filter: dropped: fr_qout(%x,%x): type %x: qif %x",
"!IP Filter: dropped: fr_qout(%x,%x): type %x: qif %x",
q, mb, MTYPE(mb), qif);
cmn_err(CE_CONT,
"IP Filter: info %x next %x ptr %x fsrv %x bsrv %x\n",
"!IP Filter: info %x next %x ptr %x fsrv %x bsrv %x\n",
q->q_qinfo, q->q_next, q->q_ptr, q->q_nfsrv,
q->q_nbsrv);
cmn_err(CE_CONT, "IP Filter: info: putp %x srvp %x info %x\n",
cmn_err(CE_CONT, "!IP Filter: info: putp %x srvp %x info %x\n",
q->q_qinfo->qi_putp, q->q_qinfo->qi_srvp,
#if SOLARIS > 3
q->q_qinfo->qi_infop
@ -839,12 +892,12 @@ mblk_t *mb;
);
if (q->q_nfsrv)
cmn_err(CE_CONT,
"IP Filter: nfsrv: info %x next %x ptr %x\n",
"!IP Filter: nfsrv: info %x next %x ptr %x\n",
q->q_nfsrv->q_qinfo, q->q_nfsrv->q_next,
q->q_nfsrv->q_ptr);
if (q->q_nbsrv)
cmn_err(CE_CONT,
"IP Filter: nbsrv: info %x next %x ptr %x\n",
"!IP Filter: nbsrv: info %x next %x ptr %x\n",
q->q_nbsrv->q_qinfo, q->q_nbsrv->q_next,
q->q_nbsrv->q_ptr);
frstats[1].fr_drop++;
@ -869,7 +922,8 @@ mblk_t *mb;
if (pnext)
return (*pnext)(q, mb);
cmn_err(CE_WARN, "IP Filter: outp NULL: qif %x %s q %x info %x",
cmn_err(CE_WARN,
"!IP Filter: outp NULL: qif %x %s q %x info %x",
qif, qif->qf_name, q, q->q_qinfo);
}
if (mb) {
@ -924,8 +978,6 @@ mblk_t *mb;
#ifdef IPFDEBUG
cmn_err(CE_NOTE, "IP Filter: ipf_ip_qin() M_IOCTL type=0x%x\n", ioc->ioc_cmd);
#endif
ret = (*ipf_ip_inp)(q, mb);
WRITE_ENTER(&ipfs_mutex);
if (synctimeoutid == 0) {
synctimeoutid = timeout(ipf_synctimeout,
@ -933,14 +985,13 @@ mblk_t *mb;
drv_usectohz(1000000) /*1 sec*/
);
}
RWLOCK_EXIT(&ipfs_mutex);
break;
default:
ret = (*ipf_ip_inp)(q, mb);
break;
}
RWLOCK_EXIT(&ipf_solaris);
return ret;
return (*ipf_ip_inp)(q, mb);
}
static int ipdrvattcnt = 0;
@ -1003,6 +1054,10 @@ void solattach()
if (!in || !il->ill_wq)
continue;
#if SOLARIS2 >= 8
if (il->ill_isv6)
continue;
#endif
out = il->ill_wq->q_next;
WRITE_ENTER(&ipfs_mutex);
@ -1025,7 +1080,7 @@ void solattach()
#endif
KMALLOC(qif, qif_t *);
if (!qif) {
cmn_err(CE_NOTE,
cmn_err(CE_WARN,
"IP Filter: malloc(%d) for qif_t failed\n",
sizeof(qif_t));
RWLOCK_EXIT(&ipfs_mutex);
@ -1077,7 +1132,36 @@ void solattach()
qif->qf_out = out;
qif->qf_iptr = in->q_ptr;
qif->qf_optr = out->q_ptr;
#if SOLARIS2 < 8
qif->qf_hl = il->ill_hdr_length;
#else
{
ire_t *ire;
mblk_t *m;
qif->qf_hl = 0;
# if 0
/*
* Can't seem to lookup a route for the IP address on the
* interface itself.
*/
ire = ire_route_lookup(il->ill_ipif->ipif_lcl_addr, 0xffffffff,
0, 0, NULL, NULL, NULL,
MATCH_IRE_DSTONLY|MATCH_IRE_RECURSIVE);
if ((ire != NULL) && (m = ire->ire_fp_mp))
qif->qf_hl = m->b_wptr - m->b_rptr;
# endif
if ((qif->qf_hl == 0) && (il->ill_type > 0) &&
(il->ill_type < 0x37) &&
(hdrsizes[il->ill_type][0] == il->ill_type))
qif->qf_hl = hdrsizes[il->ill_type][1];
if (qif->qf_hl == 0)
cmn_err(CE_WARN,
"Unknown layer 2 header size for %s type %d\n",
qif->qf_name, il->ill_type);
}
#endif
strncpy(qif->qf_name, il->ill_name, sizeof(qif->qf_name));
qif->qf_name[sizeof(qif->qf_name) - 1] = '\0';
@ -1168,12 +1252,14 @@ int ipfsync()
for (il = ill_g_head; il; il = il->ill_next)
if ((qif->qf_ill == il) &&
!strcmp(qif->qf_name, il->ill_name)) {
#if SOLARIS2 < 8
mblk_t *m = il->ill_hdr_mp;
qif->qf_hl = il->ill_hdr_length;
if (m && qif->qf_hl != (m->b_wptr - m->b_rptr))
cmn_err(CE_NOTE,
"IP Filter: ILL Header Length Mismatch\n");
#endif
break;
}
if (il) {
@ -1237,6 +1323,7 @@ int ipfsync()
RWLOCK_EXIT(&ipfs_mutex);
solattach();
frsync();
/*
* Resync. any NAT `connections' using this interface and its IP #.
*/
@ -1337,7 +1424,7 @@ frdest_t *fdp;
mblk_t *mp = NULL;
size_t hlen = 0;
frentry_t *fr;
void *ifp;
ill_t *ifp;
u_char *s;
#ifndef sparc
@ -1367,7 +1454,7 @@ frdest_t *fdp;
else
dst = fin->fin_fi.fi_dst;
#if SOLARIS2 > 5
#if SOLARIS2 >= 6
gw = NULL;
dir = ire_route_lookup(dst.s_addr, 0xffffffff, 0, 0, NULL, &gw, NULL,
MATCH_IRE_DSTONLY|MATCH_IRE_DEFAULT|
@ -1375,15 +1462,23 @@ frdest_t *fdp;
#else
dir = ire_lookup(dst.s_addr);
#endif
#if SOLARIS2 < 8
if (dir)
if (!dir->ire_ll_hdr_mp || !dir->ire_ll_hdr_length)
dir = NULL;
#else
if (dir)
if (!dir->ire_fp_mp || !dir->ire_dlureq_mp)
dir = NULL;
#endif
if (!ir)
ir = dir;
if (ir && dir) {
ifp = ire_to_ill(ir);
if (ifp == NULL)
goto bad_fastroute;
fr = fin->fin_fr;
/*
* In case we're here due to "to <if>" being used with
@ -1394,7 +1489,7 @@ frdest_t *fdp;
(fin->fin_rev != 0) && (fdp == &fr->fr_tif))
return -1;
fin->fin_ifp == ifp;
fin->fin_ifp = ifp;
if (fin->fin_out == 0) {
fin->fin_fr = ipacct[1][fr_active];
if ((fin->fin_fr != NULL) &&
@ -1413,11 +1508,22 @@ frdest_t *fdp;
ip->ip_off = htons(__ipoff);
#endif
if ((mp = dir->ire_ll_hdr_mp)) {
hlen = dir->ire_ll_hdr_length;
#if SOLARIS2 < 8
mp = dir->ire_ll_hdr_mp;
hlen = dir->ire_ll_hdr_length;
#else
mp = dir->ire_fp_mp;
hlen = mp ? mp->b_wptr - mp->b_rptr : 0;
mp = dir->ire_dlureq_mp;
#endif
if (mp != NULL) {
s = mb->b_rptr;
if (hlen && (s - mb->b_datap->db_base) >= hlen) {
if (
#if SOLARIS2 >= 6
(dohwcksum &&
ifp->ill_ick.ick_magic == ICK_M_CTL_MAGIC) ||
#endif
(hlen && (s - mb->b_datap->db_base) >= hlen)) {
s -= hlen;
mb->b_rptr = (u_char *)s;
bcopy((char *)mp->b_rptr, (char *)s, hlen);
@ -1440,6 +1546,20 @@ frdest_t *fdp;
mb->b_prev = NULL;
RWLOCK_EXIT(&ipfs_mutex);
RWLOCK_EXIT(&ipf_solaris);
#if SOLARIS2 >= 6
if ((ip->ip_p == IPPROTO_TCP) && dohwcksum &&
(ifp->ill_ick.ick_magic == ICK_M_CTL_MAGIC)) {
tcphdr_t *tcp;
u_32_t t;
tcp = (tcphdr_t *)((char *)ip + fin->fin_hlen);
t = ip->ip_src.s_addr;
t += ip->ip_dst.s_addr;
t += 30;
t = (t & 0xffff) + (t >> 16);
tcp->th_sum = t & 0xffff;
}
#endif
putnext(q, mb);
READ_ENTER(&ipf_solaris);
READ_ENTER(&ipfs_mutex);

View File

@ -39,3 +39,4 @@ return-rst done, to/dup-to/fastroute remain - ip_forward() problems :-(
* add more docs
in progress
* fix up where manual pages go for Solaris2