Properly import usr.sbin/ipf updates

This commit is contained in:
darrenr 1997-03-29 02:49:40 +00:00
parent e15f7fac43
commit e8fb8bd3a9
90 changed files with 5971 additions and 100 deletions

View File

@ -1,9 +1,9 @@
# $NetBSD: Makefile,v 1.1.1.1 1997/01/05 13:09:04 mrg Exp $
# $NetBSD: Makefile,v 1.1.1.2 1997/03/29 02:49:43 darrenr Exp $
PROG= ipfstat
SRCS= kmem.c fils.c opt.c parse.c
MAN= ipfstat.8
CFLAGS+= -I${.CURDIR}/../../../sbin/ipf
CFLAGS+= -I${.CURDIR}/../../sbin/ipf
.PATH: ${.CURDIR}/../../../sbin/ipf
.PATH: ${.CURDIR}/../../sbin/ipf
.include <bsd.prog.mk>

View File

@ -1,3 +1,5 @@
/* $NetBSD: kmem.c,v 1.1.1.2 1997/03/29 02:49:40 darrenr Exp $ */
/*
* (C)opyright 1993,1994,1995 by Darren Reed.
*
@ -16,12 +18,11 @@
#include <unistd.h>
#include <fcntl.h>
#include <sys/file.h>
#define KMEM "/dev/kmem"
#include "kmem.h"
#if !defined(lint) && defined(LIBC_SCCS)
static char sccsid[] = "@(#)kmem.c 1.4 1/12/96 (C) 1992 Darren Reed";
static char rcsid[] = "$Id: kmem.c,v 1.1.1.1 1997/01/05 13:09:04 mrg Exp $";
static char rcsid[] = "$Id: kmem.c,v 1.1.1.2 1997/03/29 02:49:40 darrenr Exp $";
#endif
static int kmemfd = -1;

View File

@ -1,12 +1,23 @@
/* $NetBSD: kmem.h,v 1.1.1.2 1997/03/29 02:49:41 darrenr Exp $ */
/*
* (C)opyright 1993,1994,1995 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
* $Id: kmem.h,v 1.1.1.1 1997/01/05 13:09:04 mrg Exp $
* $Id: kmem.h,v 1.1.1.2 1997/03/29 02:49:41 darrenr Exp $
*/
extern int openkmem();
extern int kmemcpy();
#ifndef __P
# ifdef __STDC__
# define __P(x) x
# else
# define __P(x) ()
# endif
#endif
extern int openkmem __P((void));
extern int kmemcpy __P((char *, long, int));
#define KMEM "/dev/kmem"

View File

@ -1,9 +1,9 @@
# $NetBSD: Makefile,v 1.1.1.1 1997/01/05 13:09:04 mrg Exp $
# $NetBSD: Makefile,v 1.1.1.2 1997/03/29 02:49:55 darrenr Exp $
PROG= ipftest
SRCS= parse.c fil.c ipt.c ipft_sn.c ipft_ef.c ipft_td.c opt.c ipft_tx.c misc.c ip_frag.c ip_state.c ip_nat.c ipft_hx.c
SRCS= ipt.c ipft_sn.c ipft_ef.c ipft_td.c ipft_pc.c opt.c ipft_tx.c misc.c ip_frag.c ip_state.c ip_nat.c ipft_hx.c
NOMAN= yes
CFLAGS+= -I${.CURDIR}/../../../sbin/ipf
CFLAGS+= -I${.CURDIR}/../../sbin/ipf
.PATH: ${.CURDIR}/../../../sbin/ipf ${.CURDIR}/../../../sys/netinet
.PATH: ${.CURDIR}/../../sbin/ipf
.include <bsd.prog.mk>

View File

@ -0,0 +1,280 @@
/* $NetBSD: ip_frag.c,v 1.1.1.1 1997/03/29 02:49:52 darrenr Exp $ */
/*
* (C)opyright 1993,1994,1995 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
#if !defined(lint) && defined(LIBC_SCCS)
static char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-1995 Darren Reed";
static char rcsid[] = "$Id: ip_frag.c,v 1.1.1.1 1997/03/29 02:49:52 darrenr Exp $";
#endif
#if !defined(_KERNEL) && !defined(KERNEL)
# include <string.h>
# include <stdlib.h>
#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/uio.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#ifdef _KERNEL
# include <sys/systm.h>
#endif
#if !defined(__SVR4) && !defined(__svr4__)
# include <sys/mbuf.h>
#else
# include <sys/byteorder.h>
# include <sys/dditypes.h>
# include <sys/stream.h>
# include <sys/kmem.h>
#endif
#include <net/if.h>
#ifdef sun
#include <net/af.h>
#endif
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/tcpip.h>
#include <netinet/ip_icmp.h>
#include <netinet/ip_compat.h>
#include <netinet/ip_fil.h>
#include <netinet/ip_frag.h>
#include <netinet/ip_nat.h>
#include <netinet/ip_state.h>
ipfr_t *ipfr_heads[IPFT_SIZE];
ipfrstat_t ipfr_stats;
u_long ipfr_inuse = 0,
fr_ipfrttl = 120; /* 60 seconds */
#ifdef _KERNEL
extern int ipfr_timer_id;
#endif
#if SOLARIS
# ifdef _KERNEL
extern kmutex_t ipf_frag;
# else
#define bcmp(a,b,c) memcmp(a,b,c)
#define bcopy(a,b,c) memmove(b,a,c)
# endif
#endif
ipfrstat_t *ipfr_fragstats()
{
ipfr_stats.ifs_table = ipfr_heads;
ipfr_stats.ifs_inuse = ipfr_inuse;
return &ipfr_stats;
}
/*
* add a new entry to the fragment cache, registering it as having come
* through this box, with the result of the filter operation.
*/
int ipfr_newfrag(ip, fin, pass)
ip_t *ip;
fr_info_t *fin;
int pass;
{
ipfr_t **fp, *fr, frag;
u_int idx;
frag.ipfr_p = ip->ip_p;
idx = ip->ip_p;
frag.ipfr_id = ip->ip_id;
idx += ip->ip_id;
frag.ipfr_tos = ip->ip_tos;
frag.ipfr_src.s_addr = ip->ip_src.s_addr;
idx += ip->ip_src.s_addr;
frag.ipfr_dst.s_addr = ip->ip_dst.s_addr;
idx += ip->ip_dst.s_addr;
idx *= 127;
idx %= IPFT_SIZE;
/*
* first, make sure it isn't already there...
*/
MUTEX_ENTER(&ipf_frag);
for (fp = &ipfr_heads[idx]; (fr = *fp); fp = &fr->ipfr_next)
if (!bcmp((char *)&frag.ipfr_src, (char *)&fr->ipfr_src,
IPFR_CMPSZ)) {
ipfr_stats.ifs_exists++;
MUTEX_EXIT(&ipf_frag);
return -1;
}
KMALLOC(fr, ipfr_t *, sizeof(*fr));
if (fr == NULL) {
ipfr_stats.ifs_nomem++;
MUTEX_EXIT(&ipf_frag);
return -1;
}
if ((fr->ipfr_next = ipfr_heads[idx]))
ipfr_heads[idx]->ipfr_prev = fr;
fr->ipfr_prev = NULL;
ipfr_heads[idx] = fr;
bcopy((char *)&frag.ipfr_src, (char *)&fr->ipfr_src, IPFR_CMPSZ);
fr->ipfr_ttl = fr_ipfrttl;
fr->ipfr_pass = pass & ~(FR_LOGFIRST|FR_LOG);
fr->ipfr_off = (ip->ip_off & 0x1fff) + (fin->fin_dlen >> 3);
ipfr_stats.ifs_new++;
ipfr_inuse++;
MUTEX_EXIT(&ipf_frag);
return 0;
}
/*
* check the fragment cache to see if there is already a record of this packet
* with its filter result known.
*/
int ipfr_knownfrag(ip, fin)
ip_t *ip;
fr_info_t *fin;
{
ipfr_t *f, frag;
u_int idx;
int ret;
/*
* For fragments, we record protocol, packet id, TOS and both IP#'s
* (these should all be the same for all fragments of a packet).
*/
frag.ipfr_p = ip->ip_p;
idx = ip->ip_p;
frag.ipfr_id = ip->ip_id;
idx += ip->ip_id;
frag.ipfr_tos = ip->ip_tos;
frag.ipfr_src.s_addr = ip->ip_src.s_addr;
idx += ip->ip_src.s_addr;
frag.ipfr_dst.s_addr = ip->ip_dst.s_addr;
idx += ip->ip_dst.s_addr;
idx *= 127;
idx %= IPFT_SIZE;
MUTEX_ENTER(&ipf_frag);
for (f = ipfr_heads[idx]; f; f = f->ipfr_next)
if (!bcmp((char *)&frag.ipfr_src, (char *)&f->ipfr_src,
IPFR_CMPSZ)) {
u_short atoff, off;
if (f != ipfr_heads[idx]) {
/*
* move fragment info. to the top of the list
* to speed up searches.
*/
if ((f->ipfr_prev->ipfr_next = f->ipfr_next))
f->ipfr_next->ipfr_prev = f->ipfr_prev;
f->ipfr_next = ipfr_heads[idx];
ipfr_heads[idx]->ipfr_prev = f;
f->ipfr_prev = NULL;
ipfr_heads[idx] = f;
}
ret = f->ipfr_pass;
off = ip->ip_off;
atoff = (off & 0x1fff) - (fin->fin_dlen >> 3);
/*
* If we've follwed the fragments, and this is the
* last (in order), shrink expiration time.
*/
if (atoff == f->ipfr_off) {
if (!(off & IP_MF))
f->ipfr_ttl = 1;
else
f->ipfr_off = off;
}
ipfr_stats.ifs_hits++;
MUTEX_EXIT(&ipf_frag);
return ret;
}
MUTEX_EXIT(&ipf_frag);
return 0;
}
/*
* Free memory in use by fragment state info. kept.
*/
void ipfr_unload()
{
ipfr_t **fp, *fr;
int idx;
#if !SOLARIS && defined(_KERNEL)
int s;
#endif
MUTEX_ENTER(&ipf_frag);
SPLNET(s);
for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
for (fp = &ipfr_heads[idx]; (fr = *fp); ) {
*fp = fr->ipfr_next;
KFREE(fr);
}
SPLX(s);
MUTEX_EXIT(&ipf_frag);
}
#ifdef _KERNEL
/*
* Slowly expire held state for fragments. Timeouts are set * in expectation
* of this being called twice per second.
*/
# if (BSD >= 199306) || SOLARIS
void ipfr_slowtimer()
# else
int ipfr_slowtimer()
# endif
{
ipfr_t **fp, *fr;
int s, idx;
MUTEX_ENTER(&ipf_frag);
SPLNET(s);
for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
for (fp = &ipfr_heads[idx]; (fr = *fp); ) {
--fr->ipfr_ttl;
if (fr->ipfr_ttl == 0) {
if (fr->ipfr_prev)
fr->ipfr_prev->ipfr_next =
fr->ipfr_next;
if (fr->ipfr_next)
fr->ipfr_next->ipfr_prev =
fr->ipfr_prev;
*fp = fr->ipfr_next;
ipfr_stats.ifs_expire++;
ipfr_inuse--;
KFREE(fr);
} else
fp = &fr->ipfr_next;
}
SPLX(s);
# if SOLARIS
MUTEX_EXIT(&ipf_frag);
fr_timeoutstate();
ip_natexpire();
ipfr_timer_id = timeout(ipfr_slowtimer, NULL, HZ/2);
# else
fr_timeoutstate();
ip_natexpire();
ip_slowtimo();
# if BSD < 199306
return 0;
# endif
# endif
}
#endif /* defined(_KERNEL) */

View File

@ -0,0 +1,928 @@
/* $NetBSD: ip_nat.c,v 1.1.1.1 1997/03/29 02:49:52 darrenr Exp $ */
/*
* (C)opyright 1995-1996 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* Added redirect stuff and a LOT of bug fixes. (mcn@EnGarde.com)
*/
#if !defined(lint) && defined(LIBC_SCCS)
static char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed";
static char rcsid[] = "$Id: ip_nat.c,v 1.1.1.1 1997/03/29 02:49:52 darrenr Exp $";
#endif
#if !defined(_KERNEL) && !defined(KERNEL)
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/uio.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#ifdef _KERNEL
# include <sys/systm.h>
#endif
#if !defined(__SVR4) && !defined(__svr4__)
# include <sys/mbuf.h>
#else
# include <sys/byteorder.h>
# include <sys/dditypes.h>
# include <sys/stream.h>
# include <sys/kmem.h>
#endif
#include <net/if.h>
#ifdef sun
#include <net/af.h>
#endif
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#ifdef RFC1825
#include <vpn/md5.h>
#include <vpn/ipsec.h>
extern struct ifnet vpnif;
#endif
#include <netinet/ip_var.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/tcpip.h>
#include <netinet/ip_icmp.h>
#include <netinet/ip_compat.h>
#include <netinet/ip_fil.h>
#include <netinet/ip_nat.h>
#include <netinet/ip_state.h>
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif
nat_t *nat_table[2][NAT_SIZE], *nat_instances = NULL;
ipnat_t *nat_list = NULL;
u_long nat_inuse = 0,
fr_defnatage = 1200;
natstat_t nat_stats;
#if SOLARIS
# ifndef _KERNEL
#define bzero(a,b) memset(a,0,b)
#define bcmp(a,b,c) memcpy(a,b,c)
#define bcopy(a,b,c) memmove(b,a,c)
# else
extern kmutex_t ipf_nat;
# endif
#endif
static int flush_nattable __P((void)), clear_natlist __P((void));
static void nattable_sync __P((void)), nat_delete __P((struct nat *));
static nat_t *nat_new __P((ipnat_t *, ip_t *, fr_info_t *, u_short, int));
static void fix_outcksum __P((u_short *, u_long));
static void fix_incksum __P((u_short *, u_long));
static void fix_outcksum(sp, n)
u_short *sp;
u_long n;
{
register u_short sumshort;
register u_long sum1;
#ifdef sparc
sum1 = (~(*sp)) & 0xffff;
#else
sum1 = (~ntohs(*sp)) & 0xffff;
#endif
sum1 += (n);
sum1 = (sum1 >> 16) + (sum1 & 0xffff);
/* Again */
sum1 = (sum1 >> 16) + (sum1 & 0xffff);
sumshort = ~(u_short)sum1;
*(sp) = htons(sumshort);
}
static void fix_incksum(sp, n)
u_short *sp;
u_long n;
{
register u_short sumshort;
register u_long sum1;
#ifdef sparc
sum1 = (~(*sp)) & 0xffff;
#else
sum1 = (~ntohs(*sp)) & 0xffff;
#endif
sum1 += ~(n) & 0xffff;
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.
*
* Inside (interface y) NAT Outside (interface x)
* -------------------- -+- -------------------------------------
* Packet going | out, processsed by ip_natout() for x
* ------------> | ------------>
* src=10.1.1.1 | src=192.1.1.1
* |
* | in, processed by ip_natin() for x
* <------------ | <------------
* dst=10.1.1.1 | dst=192.1.1.1
* -------------------- -+- -------------------------------------
* ip_natout() - changes ip_src and if required, sport
* - creates a new mapping, if required.
* ip_natin() - changes ip_dst and if required, dport
*
* In the NAT table, internal source is recorded as "in" and externally
* seen as "out".
*/
/*
* Handle ioctls which manipulate the NAT.
*/
int nat_ioctl(data, cmd, mode)
caddr_t data;
int cmd, mode;
{
register ipnat_t *nat, *n = NULL, **np = NULL;
ipnat_t natd;
int error = 0, ret, s;
/*
* For add/delete, look to see if the NAT entry is already present
*/
MUTEX_ENTER(&ipf_nat);
SPLNET(s);
if ((cmd == SIOCADNAT) || (cmd == SIOCRMNAT)) {
IRCOPY(data, (char *)&natd, sizeof(natd));
nat = &natd;
for (np = &nat_list; (n = *np); np = &n->in_next)
if (!bcmp((char *)&nat->in_flags, (char *)&n->in_flags,
IPN_CMPSIZ))
break;
}
switch (cmd)
{
case SIOCADNAT :
if (!(mode & FWRITE)) {
error = EPERM;
break;
}
if (n) {
error = EEXIST;
break;
}
KMALLOC(n, ipnat_t *, sizeof(*n));
if (n == NULL) {
error = ENOMEM;
break;
}
IRCOPY((char *)data, (char *)n, sizeof(*n));
n->in_ifp = (void *)GETUNIT(n->in_ifname);
n->in_next = *np;
n->in_use = 0;
n->in_space = ~(0xffffffff & ntohl(n->in_outmsk));
if (n->in_space) /* lose 2: broadcast + network address */
n->in_space -= 2;
else
n->in_space = 1; /* single IP# mapping */
if (n->in_outmsk != 0xffffffff)
n->in_nip = ntohl(n->in_outip) + 1;
else
n->in_nip = ntohl(n->in_outip);
if (n->in_redir == NAT_MAP) {
n->in_pnext = ntohs(n->in_pmin);
/*
* Multiply by the number of ports made available.
*/
if (ntohs(n->in_pmax) > ntohs(n->in_pmin))
n->in_space *= (ntohs(n->in_pmax) -
ntohs(n->in_pmin));
}
/* Otherwise, these fields are preset */
*np = n;
break;
case SIOCRMNAT :
if (!(mode & FWRITE)) {
error = EPERM;
break;
}
if (!n) {
error = ESRCH;
break;
}
*np = n->in_next;
KFREE(n);
nattable_sync();
break;
case SIOCGNATS :
nat_stats.ns_table[0] = nat_table[0];
nat_stats.ns_table[1] = nat_table[1];
nat_stats.ns_list = nat_list;
nat_stats.ns_inuse = nat_inuse;
IWCOPY((char *)&nat_stats, (char *)data, sizeof(nat_stats));
break;
case SIOCGNATL :
{
natlookup_t nl;
IRCOPY((char *)data, (char *)&nl, sizeof(nl));
if (nat_lookupredir(&nl))
IWCOPY((char *)&nl, (char *)data, sizeof(nl));
else
error = ESRCH;
break;
}
case SIOCFLNAT :
if (!(mode & FWRITE)) {
error = EPERM;
break;
}
ret = flush_nattable();
IWCOPY((caddr_t)&ret, data, sizeof(ret));
break;
case SIOCCNATL :
if (!(mode & FWRITE)) {
error = EPERM;
break;
}
ret = clear_natlist();
IWCOPY((caddr_t)&ret, data, sizeof(ret));
break;
}
SPLX(s);
MUTEX_EXIT(&ipf_nat);
return error;
}
static void nat_delete(natd)
struct nat *natd;
{
register struct nat **natp, *nat;
for (natp = natd->nat_hstart[0]; (nat = *natp);
natp = &nat->nat_hnext[0])
if (nat == natd) {
*natp = nat->nat_hnext[0];
break;
}
for (natp = natd->nat_hstart[1]; (nat = *natp);
natp = &nat->nat_hnext[1])
if (nat == natd) {
*natp = nat->nat_hnext[1];
break;
}
if (natd->nat_ptr) {
natd->nat_ptr->in_space++;
natd->nat_ptr->in_use--;
}
KFREE(natd);
nat_inuse--;
}
/*
* flush_nattable - clear the NAT table of all mapping entries.
*/
static int flush_nattable()
{
register nat_t *nat, **natp;
register int j = 0;
/*
* Everything will be deleted, so lets just make it the deletions
* quicker.
*/
bzero((char *)nat_table[0], sizeof(nat_table[0]));
bzero((char *)nat_table[1], sizeof(nat_table[1]));
for (natp = &nat_instances; (nat = *natp); ) {
*natp = nat->nat_next;
nat_delete(nat);
j++;
}
return j;
}
/*
* I know this is O(N*M), but it can't be avoided.
*/
static void nattable_sync()
{
register nat_t *nat;
register ipnat_t *np;
int i;
for (i = NAT_SIZE - 1; i >= 0; i--)
for (nat = nat_instances; nat; nat = nat->nat_next) {
for (np = nat_list; np; np = np->in_next)
if (nat->nat_ptr == np)
break;
/*
* XXX - is it better to remove this if ? works the
* same if it is just "nat->nat_ptr = np".
*/
if (!np)
nat->nat_ptr = NULL;
}
}
/*
* clear_natlist - delete all entries in the active NAT mapping list.
*/
static int clear_natlist()
{
register ipnat_t *n, **np;
int i = 0;
for (np = &nat_list; (n = *np); i++) {
*np = n->in_next;
KFREE(n);
}
nattable_sync();
return i;
}
/*
* Create a new NAT table entry.
*/
static nat_t *nat_new(np, ip, fin, flags, direction)
ipnat_t *np;
ip_t *ip;
fr_info_t *fin;
u_short flags;
int direction;
{
register u_long sum1, sum2, sumd;
u_short port = 0, sport = 0, dport = 0, nport = 0;
struct in_addr in;
tcphdr_t *tcp = NULL;
nat_t *nat, **natp;
u_short nflags;
nflags = flags & np->in_flags;
if (flags & IPN_TCPUDP) {
tcp = (tcphdr_t *)fin->fin_dp;
sport = tcp->th_sport;
dport = tcp->th_dport;
}
/* Give me a new nat */
KMALLOC(nat, nat_t *, sizeof(*nat));
if (nat == NULL)
return NULL;
bzero((char *)nat, sizeof(*nat));
nat->nat_flags = flags;
/*
* Search the current table for a match.
*/
if (direction == NAT_OUTBOUND) {
#if SOLARIS
ill_t *ill = fin->fin_ifp;
#else
struct ifnet *ifp = fin->fin_ifp;
#endif
/*
* If it's an outbound packet which doesn't match any existing
* record, then create a new port
*/
do {
port = 0;
in.s_addr = np->in_nip;
if (!in.s_addr && (np->in_outmsk == 0xffffffff)) {
#if SOLARIS
in.s_addr = ill->ill_ipif->ipif_local_addr;
#else
struct ifaddr *ifa;
struct sockaddr_in *sin;
ifa = ifp->if_addrlist;
# if BSD < 199306
sin = (struct sockaddr_in *)&ifa->ifa_addr;
# else
sin = (struct sockaddr_in *)ifa->ifa_addr;
# endif
bcopy((char *)&sin->sin_addr,
(char *)&in.s_addr,
sizeof(in.s_addr));
#endif
}
if (nflags & IPN_TCPUDP) {
port = htons(np->in_pnext++);
if (np->in_pnext >= ntohs(np->in_pmax)) {
np->in_pnext = ntohs(np->in_pmin);
np->in_space--;
if (np->in_outmsk != 0xffffffff)
np->in_nip++;
}
} else if (np->in_outmsk != 0xffffffff) {
np->in_space--;
np->in_nip++;
}
if (!port && (flags & IPN_TCPUDP))
port = sport;
if ((np->in_nip & ntohl(np->in_outmsk)) >
ntohl(np->in_outip))
np->in_nip = ntohl(np->in_outip) + 1;
} while (nat_inlookup(flags, ip->ip_dst, dport, in, port));
/* Setup the NAT table */
nat->nat_inip = ip->ip_src;
nat->nat_outip.s_addr = htonl(in.s_addr);
nat->nat_oip = ip->ip_dst;
sum1 = (ntohl(ip->ip_src.s_addr) & 0xffff) +
(ntohl(ip->ip_src.s_addr) >> 16) + ntohs(sport);
sum2 = (in.s_addr & 0xffff) + (in.s_addr >> 16) + ntohs(port);
if (flags & IPN_TCPUDP) {
nat->nat_inport = sport;
nat->nat_outport = port;
nat->nat_oport = dport;
}
} else {
/*
* Otherwise, it's an inbound packet. Most likely, we don't
* want to rewrite source ports and source addresses. Instead,
* we want to rewrite to a fixed internal address and fixed
* internal port.
*/
in.s_addr = ntohl(np->in_inip);
if (!(nport = np->in_pnext))
nport = dport;
nat->nat_inip.s_addr = htonl(in.s_addr);
nat->nat_outip = ip->ip_dst;
nat->nat_oip = ip->ip_src;
sum1 = (ntohl(ip->ip_dst.s_addr) & 0xffff) +
(ntohl(ip->ip_dst.s_addr) >> 16) + ntohs(dport);
sum2 = (in.s_addr & 0xffff) + (in.s_addr >> 16) + ntohs(nport);
if (flags & IPN_TCPUDP) {
nat->nat_inport = nport;
nat->nat_outport = dport;
nat->nat_oport = sport;
}
}
/* Do it twice */
sum1 = (sum1 & 0xffff) + (sum1 >> 16);
sum1 = (sum1 & 0xffff) + (sum1 >> 16);
/* Do it twice */
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
if (sum1 > sum2)
sum2--; /* Because ~1 == -2, We really need ~1 == -1 */
sumd = sum2 - sum1;
sumd = (sumd & 0xffff) + (sumd >> 16);
nat->nat_sumd = (sumd & 0xffff) + (sumd >> 16);
if ((flags & IPN_TCPUDP) && ((sport != port) || (dport != nport))) {
if (direction == NAT_OUTBOUND)
sum1 = (ntohl(ip->ip_src.s_addr) & 0xffff) +
(ntohl(ip->ip_src.s_addr) >> 16);
else
sum1 = (ntohl(ip->ip_dst.s_addr) & 0xffff) +
(ntohl(ip->ip_dst.s_addr) >> 16);
sum2 = (in.s_addr & 0xffff) + (in.s_addr >> 16);
/* Do it twice */
sum1 = (sum1 & 0xffff) + (sum1 >> 16);
sum1 = (sum1 & 0xffff) + (sum1 >> 16);
/* Do it twice */
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
if (sum1 > sum2)
sum2--; /* Because ~1 == -2, We really need ~1 == -1 */
sumd = sum2 - sum1;
sumd = (sumd & 0xffff) + (sumd >> 16);
nat->nat_ipsumd = (sumd & 0xffff) + (sumd >> 16);
} else
nat->nat_ipsumd = nat->nat_sumd;
in.s_addr = htonl(in.s_addr);
nat->nat_next = nat_instances;
nat_instances = nat;
natp = &nat_table[0][nat->nat_inip.s_addr % NAT_SIZE];
nat->nat_hstart[0] = natp;
nat->nat_hnext[0] = *natp;
*natp = nat;
natp = &nat_table[1][nat->nat_outip.s_addr % NAT_SIZE];
nat->nat_hstart[1] = natp;
nat->nat_hnext[1] = *natp;
*natp = nat;
nat->nat_ptr = np;
np->in_use++;
if (direction == NAT_OUTBOUND) {
if (flags & IPN_TCPUDP)
tcp->th_sport = htons(port);
} else {
if (flags & IPN_TCPUDP)
tcp->th_dport = htons(nport);
}
nat_stats.ns_added++;
nat_inuse++;
return nat;
}
/*
* NB: these lookups don't lock access to the list, it assume it has already
* been done!
*/
/*
* Lookup a nat entry based on the mapped destination ip address/port and
* real source address/port. We use this lookup when receiving a packet,
* we're looking for a table entry, based on the destination address.
* NOTE: THE PACKET BEING CHECKED (IF FOUND) HAS A MAPPING ALREADY.
*/
nat_t *nat_inlookup(flags, src, sport, mapdst, mapdport)
register int flags;
struct in_addr src , mapdst;
u_short sport, mapdport;
{
register nat_t *nat;
flags &= IPN_TCPUDP;
nat = nat_table[1][mapdst.s_addr % NAT_SIZE];
for (; nat; nat = nat->nat_hnext[1])
if (nat->nat_oip.s_addr == src.s_addr &&
nat->nat_outip.s_addr == mapdst.s_addr &&
flags == nat->nat_flags && (!flags ||
(nat->nat_oport == sport &&
nat->nat_outport == mapdport)))
return nat;
return NULL;
}
/*
* Lookup a nat entry based on the source 'real' ip address/port and
* destination address/port. We use this lookup when sending a packet out,
* we're looking for a table entry, based on the source address.
* NOTE: THE PACKET BEING CHECKED (IF FOUND) HAS A MAPPING ALREADY.
*/
nat_t *nat_outlookup(flags, src, sport, dst, dport)
register int flags;
struct in_addr src , dst;
u_short sport, dport;
{
register nat_t *nat;
flags &= IPN_TCPUDP;
nat = nat_table[0][src.s_addr % NAT_SIZE];
for (; nat; nat = nat->nat_hnext[0])
if (nat->nat_inip.s_addr == src.s_addr &&
nat->nat_oip.s_addr == dst.s_addr &&
flags == nat->nat_flags && (!flags ||
(nat->nat_inport == sport && nat->nat_oport == dport)))
return nat;
return NULL;
}
/*
* Lookup a nat entry based on the mapped source ip address/port and
* real destination address/port. We use this lookup when sending a packet
* out, we're looking for a table entry, based on the source address.
*/
nat_t *nat_lookupmapip(flags, mapsrc, mapsport, dst, dport)
register int flags;
struct in_addr mapsrc , dst;
u_short mapsport, dport;
{
register nat_t *nat;
flags &= IPN_TCPUDP;
nat = nat_table[1][mapsrc.s_addr % NAT_SIZE];
for (; nat; nat = nat->nat_hnext[0])
if (nat->nat_outip.s_addr == mapsrc.s_addr &&
nat->nat_oip.s_addr == dst.s_addr &&
flags == nat->nat_flags && (!flags ||
(nat->nat_outport == mapsport &&
nat->nat_oport == dport)))
return nat;
return NULL;
}
/*
* Lookup the NAT tables to search for a matching redirect
*/
nat_t *nat_lookupredir(np)
register natlookup_t *np;
{
nat_t *nat;
/*
* If nl_inip is non null, this is a lookup based on the real
* ip address. Else, we use the fake.
*/
if ((nat = nat_outlookup(IPN_TCPUDP, np->nl_inip, np->nl_inport,
np->nl_outip, np->nl_outport))) {
np->nl_inip = nat->nat_outip;
np->nl_inport = nat->nat_outport;
}
return nat;
}
/*
* Packets going out on the external interface go through this.
* Here, the source address requires alteration, if anything.
*/
int ip_natout(ip, hlen, fin)
ip_t *ip;
int hlen;
fr_info_t *fin;
{
register ipnat_t *np;
register u_long ipa;
tcphdr_t *tcp = NULL;
nat_t *nat;
u_short nflags = 0, sport = 0, dport = 0, *csump = NULL;
struct ifnet *ifp;
frentry_t *fr;
if ((fr = fin->fin_fr) && !(fr->fr_flags & FR_DUP) &&
fr->fr_tif.fd_ifp && fr->fr_tif.fd_ifp != (void *)-1)
ifp = fr->fr_tif.fd_ifp;
else
ifp = fin->fin_ifp;
if (!(ip->ip_off & 0x1fff) && !(fin->fin_fi.fi_fl & FI_SHORT)) {
if (ip->ip_p == IPPROTO_TCP)
nflags = IPN_TCP;
else if (ip->ip_p == IPPROTO_UDP)
nflags = IPN_UDP;
if (nflags) {
tcp = (tcphdr_t *)fin->fin_dp;
sport = tcp->th_sport;
dport = tcp->th_dport;
}
}
ipa = ip->ip_src.s_addr;
MUTEX_ENTER(&ipf_nat);
for (np = nat_list; np; np = np->in_next)
if ((np->in_ifp == ifp) && np->in_space &&
(!np->in_flags || (np->in_flags & nflags)) &&
((ipa & np->in_inmsk) == np->in_inip) &&
((np->in_redir == NAT_MAP) ||
(np->in_pnext == sport))) {
/*
* If there is no current entry in the nat table for
* this IP#, create one for it.
*/
if (!(nat = nat_outlookup(nflags, ip->ip_src, sport,
ip->ip_dst, dport))) {
if (np->in_redir == NAT_REDIRECT)
continue;
/*
* if it's a redirection, then we don't want
* to create new outgoing port stuff.
* Redirections are only for incoming
* connections.
*/
if (!(nat = nat_new(np, ip, fin, nflags,
NAT_OUTBOUND)))
break;
}
ip->ip_src = nat->nat_outip;
nat->nat_age = fr_defnatage; /* 5 mins */
/*
* Fix up checksums, not by recalculating them, but
* simply computing adjustments.
*/
#if SOLARIS
if (np->in_redir == NAT_MAP)
fix_outcksum(&ip->ip_sum, nat->nat_ipsumd);
else
fix_incksum(&ip->ip_sum, nat->nat_ipsumd);
#endif
if (nflags && !(ip->ip_off & 0x1fff) &&
!(fin->fin_fi.fi_fl & FI_SHORT)) {
if (nat->nat_outport)
tcp->th_sport = nat->nat_outport;
if (ip->ip_p == IPPROTO_TCP) {
csump = &tcp->th_sum;
fr_tcp_age(&nat->nat_age,
nat->nat_state, ip, fin,1);
} else if (ip->ip_p == IPPROTO_UDP) {
udphdr_t *udp = (udphdr_t *)tcp;
if (udp->uh_sum)
csump = &udp->uh_sum;
} else if (ip->ip_p == IPPROTO_ICMP) {
icmphdr_t *ic = (icmphdr_t *)tcp;
csump = &ic->icmp_cksum;
}
if (csump) {
if (np->in_redir == NAT_MAP)
fix_outcksum(csump,
nat->nat_sumd);
else
fix_incksum(csump,
nat->nat_sumd);
}
}
nat_stats.ns_mapped[1]++;
MUTEX_EXIT(&ipf_nat);
return 1;
}
MUTEX_EXIT(&ipf_nat);
return 0;
}
/*
* Packets coming in from the external interface go through this.
* Here, the destination address requires alteration, if anything.
*/
int ip_natin(ip, hlen, fin)
ip_t *ip;
int hlen;
fr_info_t *fin;
{
register ipnat_t *np;
register struct in_addr in;
struct ifnet *ifp = fin->fin_ifp;
tcphdr_t *tcp = NULL;
u_short sport = 0, dport = 0, nflags = 0, *csump = NULL;
nat_t *nat;
if (!(ip->ip_off & 0x1fff) && !(fin->fin_fi.fi_fl & FI_SHORT)) {
if (ip->ip_p == IPPROTO_TCP)
nflags = IPN_TCP;
else if (ip->ip_p == IPPROTO_UDP)
nflags = IPN_UDP;
if (nflags) {
tcp = (tcphdr_t *)((char *)ip + hlen);
dport = tcp->th_dport;
sport = tcp->th_sport;
}
}
in = ip->ip_dst;
MUTEX_ENTER(&ipf_nat);
for (np = nat_list; np; np = np->in_next)
if ((np->in_ifp == ifp) &&
(!np->in_flags || (nflags & np->in_flags)) &&
((in.s_addr & np->in_outmsk) == np->in_outip) &&
(np->in_redir == NAT_MAP || np->in_pmin == dport)) {
if (!(nat = nat_inlookup(nflags, ip->ip_src, sport,
ip->ip_dst, dport))) {
if (np->in_redir == NAT_MAP)
continue;
else {
/*
* If this rule (np) is a redirection,
* rather than a mapping, then do a
* nat_new. Otherwise, if it's just a
* mapping, do a continue;
*/
if (!(nat = nat_new(np, ip, fin,
nflags,
NAT_INBOUND)))
break;
}
}
ip->ip_dst = nat->nat_inip;
nat->nat_age = fr_defnatage;
/*
* Fix up checksums, not by recalculating them, but
* simply computing adjustments.
*/
#if SOLARIS
if (np->in_redir == NAT_MAP)
fix_incksum(&ip->ip_sum, nat->nat_ipsumd);
else
fix_outcksum(&ip->ip_sum, nat->nat_ipsumd);
#endif
if (nflags && !(ip->ip_off & 0x1fff) &&
!(fin->fin_fi.fi_fl & FI_SHORT)) {
if (nat->nat_inport)
tcp->th_dport = nat->nat_inport;
if (ip->ip_p == IPPROTO_TCP) {
csump = &tcp->th_sum;
fr_tcp_age(&nat->nat_age,
nat->nat_state, ip, fin,0);
} else if (ip->ip_p == IPPROTO_UDP) {
udphdr_t *udp = (udphdr_t *)tcp;
if (udp->uh_sum)
csump = &udp->uh_sum;
} else if (ip->ip_p == IPPROTO_ICMP) {
icmphdr_t *ic = (icmphdr_t *)tcp;
csump = &ic->icmp_cksum;
}
if (csump) {
if (np->in_redir == NAT_MAP)
fix_incksum(csump,
nat->nat_sumd);
else
fix_outcksum(csump,
nat->nat_sumd);
}
}
nat_stats.ns_mapped[0]++;
MUTEX_EXIT(&ipf_nat);
return 1;
}
MUTEX_EXIT(&ipf_nat);
return 0;
}
/*
* Free all memory used by NAT structures allocated at runtime.
*/
void ip_natunload()
{
int s;
MUTEX_ENTER(&ipf_nat);
SPLNET(s);
(void) clear_natlist();
(void) flush_nattable();
SPLX(s)
MUTEX_EXIT(&ipf_nat);
}
/*
* Slowly expire held state for NAT entries. Timeouts are set in
* expectation of this being called twice per second.
*/
void ip_natexpire()
{
register struct nat *nat, **natp;
int s;
MUTEX_ENTER(&ipf_nat);
SPLNET(s);
for (natp = &nat_instances; (nat = *natp); ) {
if (--nat->nat_age) {
natp = &nat->nat_next;
continue;
}
*natp = nat->nat_next;
nat_delete(nat);
nat_stats.ns_expire++;
}
SPLX(s);
MUTEX_EXIT(&ipf_nat);
}

View File

@ -0,0 +1,544 @@
/* $NetBSD: ip_state.c,v 1.1.1.1 1997/03/29 02:49:52 darrenr Exp $ */
/*
* (C)opyright 1995 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
#if !defined(lint) && defined(LIBC_SCCS)
static char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-1995 Darren Reed";
static char rcsid[] = "$Id: ip_state.c,v 1.1.1.1 1997/03/29 02:49:52 darrenr Exp $";
#endif
#if !defined(_KERNEL) && !defined(KERNEL)
# include <stdlib.h>
# include <string.h>
#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/uio.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#ifdef _KERNEL
# include <sys/systm.h>
#endif
#if !defined(__SVR4) && !defined(__svr4__)
# include <sys/mbuf.h>
#else
# include <sys/byteorder.h>
# include <sys/dditypes.h>
# include <sys/stream.h>
# include <sys/kmem.h>
#endif
#include <net/if.h>
#ifdef sun
#include <net/af.h>
#endif
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet/tcp.h>
#include <netinet/tcp_fsm.h>
#include <netinet/udp.h>
#include <netinet/tcpip.h>
#include <netinet/ip_icmp.h>
#include <netinet/ip_compat.h>
#include <netinet/ip_fil.h>
#include <netinet/ip_state.h>
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif
#define TCP_CLOSE (TH_FIN|TH_RST)
ipstate_t *ips_table[IPSTATE_SIZE];
int ips_num = 0;
ips_stat_t ips_stats;
#if SOLARIS
extern kmutex_t ipf_state;
# if !defined(_KERNEL)
#define bcopy(a,b,c) memmove(b,a,c)
# endif
#endif
#define FIVE_DAYS (2 * 5 * 86400) /* 5 days: half closed session */
u_long fr_tcpidletimeout = FIVE_DAYS,
fr_tcpclosewait = 60,
fr_tcplastack = 20,
fr_tcptimeout = 120,
fr_tcpclosed = 1,
fr_udptimeout = 120,
fr_icmptimeout = 120;
ips_stat_t *fr_statetstats()
{
ips_stats.iss_active = ips_num;
ips_stats.iss_table = ips_table;
return &ips_stats;
}
#define PAIRS(s1,d1,s2,d2) ((((s1) == (s2)) && ((d1) == (d2))) ||\
(((s1) == (d2)) && ((d1) == (s2))))
#define IPPAIR(s1,d1,s2,d2) PAIRS((s1).s_addr, (d1).s_addr, \
(s2).s_addr, (d2).s_addr)
/*
* Create a new ipstate structure and hang it off the hash table.
*/
int fr_addstate(ip, fin, pass)
ip_t *ip;
fr_info_t *fin;
u_int pass;
{
ipstate_t ips;
register ipstate_t *is = &ips;
register u_int hv;
if ((ip->ip_off & 0x1fff) || (fin->fin_fi.fi_fl & FI_SHORT))
return -1;
if (ips_num == IPSTATE_MAX) {
ips_stats.iss_max++;
return -1;
}
ips.is_age = 1;
ips.is_state[0] = 0;
ips.is_state[1] = 0;
/*
* Copy and calculate...
*/
hv = (is->is_p = ip->ip_p);
hv += (is->is_src.s_addr = ip->ip_src.s_addr);
hv += (is->is_dst.s_addr = ip->ip_dst.s_addr);
switch (ip->ip_p)
{
case IPPROTO_ICMP :
{
struct icmp *ic = (struct icmp *)fin->fin_dp;
switch (ic->icmp_type)
{
case ICMP_ECHO :
is->is_icmp.ics_type = 0;
hv += (is->is_icmp.ics_id = ic->icmp_id);
hv += (is->is_icmp.ics_seq = ic->icmp_seq);
break;
case ICMP_TSTAMP :
case ICMP_IREQ :
case ICMP_MASKREQ :
is->is_icmp.ics_type = ic->icmp_type + 1;
break;
default :
return -1;
}
ips_stats.iss_icmp++;
is->is_age = fr_icmptimeout;
break;
}
case IPPROTO_TCP :
{
register tcphdr_t *tcp = (tcphdr_t *)fin->fin_dp;
/*
* The endian of the ports doesn't matter, but the ack and
* sequence numbers do as we do mathematics on them later.
*/
hv += (is->is_dport = tcp->th_dport);
hv += (is->is_sport = tcp->th_sport);
is->is_seq = ntohl(tcp->th_seq);
is->is_ack = ntohl(tcp->th_ack);
is->is_swin = ntohs(tcp->th_win);
is->is_dwin = is->is_swin; /* start them the same */
ips_stats.iss_tcp++;
/*
* If we're creating state for a starting connectoin, start the
* timer on it as we'll never see an error if it fails to
* connect.
*/
if ((tcp->th_flags & (TH_SYN|TH_ACK)) == TH_SYN)
is->is_ack = 0; /* Trumpet WinSock 'ism */
fr_tcp_age(&is->is_age, is->is_state, ip, fin,
tcp->th_sport == is->is_sport);
break;
}
case IPPROTO_UDP :
{
register tcphdr_t *tcp = (tcphdr_t *)fin->fin_dp;
hv += (is->is_dport = tcp->th_dport);
hv += (is->is_sport = tcp->th_sport);
ips_stats.iss_udp++;
is->is_age = fr_udptimeout;
break;
}
default :
return -1;
}
KMALLOC(is, ipstate_t *, sizeof(*is));
if (is == NULL) {
ips_stats.iss_nomem++;
return -1;
}
bcopy((char *)&ips, (char *)is, sizeof(*is));
hv %= IPSTATE_SIZE;
MUTEX_ENTER(&ipf_state);
is->is_next = ips_table[hv];
ips_table[hv] = is;
is->is_pass = pass;
is->is_pkts = 1;
is->is_bytes = ip->ip_len;
if (pass & FR_LOGFIRST)
is->is_pass &= ~(FR_LOGFIRST|FR_LOG);
ips_num++;
MUTEX_EXIT(&ipf_state);
return 0;
}
/*
* check to see if a packet with TCP headers fits within the TCP window.
* change timeout depending on whether new packet is a SYN-ACK returning for a
* SYN or a RST or FIN which indicate time to close up shop.
*/
int fr_tcpstate(is, fin, ip, tcp, sport)
register ipstate_t *is;
fr_info_t *fin;
ip_t *ip;
tcphdr_t *tcp;
u_short sport;
{
register int seqskew, ackskew;
register u_short swin, dwin;
register tcp_seq seq, ack;
int source;
/*
* Find difference between last checked packet and this packet.
*/
seq = ntohl(tcp->th_seq);
ack = ntohl(tcp->th_ack);
if (sport == is->is_sport) {
seqskew = seq - is->is_seq;
ackskew = ack - is->is_ack;
} else {
seqskew = ack - is->is_seq;
if (!is->is_ack)
/*
* Must be a SYN-ACK in reply to a SYN.
*/
is->is_ack = seq;
ackskew = seq - is->is_ack;
}
/*
* Make skew values absolute
*/
if (seqskew < 0)
seqskew = -seqskew;
if (ackskew < 0)
ackskew = -ackskew;
/*
* If the difference in sequence and ack numbers is within the
* window size of the connection, store these values and match
* the packet.
*/
if ((source = (sport == is->is_sport))) {
swin = is->is_swin;
dwin = is->is_dwin;
} else {
dwin = is->is_swin;
swin = is->is_dwin;
}
if ((seqskew <= swin) && (ackskew <= dwin)) {
if (source) {
is->is_seq = seq;
is->is_ack = ack;
is->is_swin = ntohs(tcp->th_win);
} else {
is->is_seq = ack;
is->is_ack = seq;
is->is_dwin = ntohs(tcp->th_win);
}
ips_stats.iss_hits++;
/*
* Nearing end of connection, start timeout.
*/
fr_tcp_age(&is->is_age, is->is_state, ip, fin,
tcp->th_sport == is->is_sport);
return 1;
}
return 0;
}
/*
* Check if a packet has a registered state.
*/
int fr_checkstate(ip, fin)
ip_t *ip;
fr_info_t *fin;
{
register struct in_addr dst, src;
register ipstate_t *is, **isp;
register u_char pr;
struct icmp *ic;
tcphdr_t *tcp;
u_int hv, hlen, pass;
if ((ip->ip_off & 0x1fff) || (fin->fin_fi.fi_fl & FI_SHORT))
return 0;
hlen = fin->fin_hlen;
tcp = (tcphdr_t *)((char *)ip + hlen);
ic = (struct icmp *)tcp;
hv = (pr = ip->ip_p);
hv += (src.s_addr = ip->ip_src.s_addr);
hv += (dst.s_addr = ip->ip_dst.s_addr);
/*
* Search the hash table for matching packet header info.
*/
switch (ip->ip_p)
{
case IPPROTO_ICMP :
hv += ic->icmp_id;
hv += ic->icmp_seq;
hv %= IPSTATE_SIZE;
MUTEX_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) &&
IPPAIR(src, dst, is->is_src, is->is_dst)) {
/*
* If we have type 0 stored, allow any icmp
* replies through.
*/
if (is->is_icmp.ics_type &&
is->is_icmp.ics_type != ic->icmp_type)
continue;
is->is_age = fr_icmptimeout;
is->is_pkts++;
is->is_bytes += ip->ip_len;
ips_stats.iss_hits++;
MUTEX_EXIT(&ipf_state);
return is->is_pass;
}
MUTEX_EXIT(&ipf_state);
break;
case IPPROTO_TCP :
{
register u_short dport = tcp->th_dport, sport = tcp->th_sport;
hv += dport;
hv += sport;
hv %= IPSTATE_SIZE;
MUTEX_ENTER(&ipf_state);
for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_next) {
if ((is->is_p == pr) &&
PAIRS(sport, dport, is->is_sport, is->is_dport) &&
IPPAIR(src, dst, is->is_src, is->is_dst))
if (fr_tcpstate(is, fin, ip, tcp, sport)) {
#ifdef _KERNEL
MUTEX_EXIT(&ipf_state);
return pass;
#else
int pass = is->is_pass;
if (tcp->th_flags & TCP_CLOSE) {
*isp = is->is_next;
isp = &ips_table[hv];
KFREE(is);
}
return pass;
#endif
}
}
MUTEX_EXIT(&ipf_state);
break;
}
case IPPROTO_UDP :
{
register u_short dport = tcp->th_dport, sport = tcp->th_sport;
hv += dport;
hv += sport;
hv %= IPSTATE_SIZE;
/*
* Nothing else to match on but ports. and IP#'s
*/
MUTEX_ENTER(&ipf_state);
for (is = ips_table[hv]; is; is = is->is_next)
if ((is->is_p == pr) &&
PAIRS(sport, dport, is->is_sport, is->is_dport) &&
IPPAIR(src, dst, is->is_src, is->is_dst)) {
ips_stats.iss_hits++;
is->is_pkts++;
is->is_bytes += ip->ip_len;
is->is_age = fr_udptimeout;
pass = is->is_pass;
MUTEX_EXIT(&ipf_state);
return pass;
}
MUTEX_EXIT(&ipf_state);
break;
}
default :
break;
}
ips_stats.iss_miss++;
return 0;
}
/*
* Free memory in use by all state info. kept.
*/
void fr_stateunload()
{
register int i;
register ipstate_t *is, **isp;
int s;
MUTEX_ENTER(&ipf_state);
SPLNET(s);
for (i = 0; i < IPSTATE_SIZE; i++)
for (isp = &ips_table[i]; (is = *isp); ) {
*isp = is->is_next;
KFREE(is);
}
SPLX(s);
MUTEX_EXIT(&ipf_state);
}
/*
* Slowly expire held state for thingslike UDP and ICMP. Timeouts are set
* in expectation of this being called twice per second.
*/
void fr_timeoutstate()
{
register int i;
register ipstate_t *is, **isp;
int s;
MUTEX_ENTER(&ipf_state);
SPLNET(s);
for (i = 0; i < IPSTATE_SIZE; i++)
for (isp = &ips_table[i]; (is = *isp); )
if (is->is_age && !--is->is_age) {
*isp = is->is_next;
if (is->is_p == IPPROTO_TCP)
ips_stats.iss_fin++;
else
ips_stats.iss_expire++;
KFREE(is);
ips_num--;
} else
isp = &is->is_next;
SPLX(s);
MUTEX_EXIT(&ipf_state);
}
/*
* Original idea freom Pradeep Krishnan for use primarily with NAT code.
* (pkrishna@netcom.com)
*/
void fr_tcp_age(age, state, ip, fin, dir)
u_long *age;
u_char *state;
ip_t *ip;
fr_info_t *fin;
int dir;
{
tcphdr_t *tcp = (tcphdr_t *)fin->fin_dp;
u_char flags = tcp->th_flags;
int dlen, ostate;
ostate = state[1 - dir];
dlen = ip->ip_len - fin->fin_hlen - (tcp->th_off << 2);
if (flags & TH_RST) {
if (!(tcp->th_flags & TH_PUSH) && !dlen) {
*age = fr_tcpclosed;
state[dir] = TCPS_CLOSED;
} else {
*age = fr_tcpclosewait;
state[dir] = TCPS_CLOSE_WAIT;
}
return;
}
*age = fr_tcptimeout; /* 1 min */
switch(state[dir])
{
case TCPS_FIN_WAIT_2:
case TCPS_CLOSED:
if ((flags & TH_OPENING) == TH_OPENING)
state[dir] = TCPS_SYN_RECEIVED;
else if (flags & TH_SYN)
state[dir] = TCPS_SYN_SENT;
break;
case TCPS_SYN_RECEIVED:
if ((flags & (TH_FIN|TH_ACK)) == TH_ACK) {
state[dir] = TCPS_ESTABLISHED;
*age = fr_tcpidletimeout;
}
break;
case TCPS_SYN_SENT:
if ((flags & (TH_FIN|TH_ACK)) == TH_ACK) {
state[dir] = TCPS_ESTABLISHED;
*age = fr_tcpidletimeout;
}
break;
case TCPS_ESTABLISHED:
if (flags & TH_FIN) {
state[dir] = TCPS_CLOSE_WAIT;
if (!(flags & TH_PUSH) && !dlen &&
ostate > TCPS_ESTABLISHED)
*age = fr_tcplastack;
else
*age = fr_tcpclosewait;
} else
*age = fr_tcpidletimeout;
break;
case TCPS_CLOSE_WAIT:
if ((flags & TH_FIN) && !(flags & TH_PUSH) && !dlen &&
ostate > TCPS_ESTABLISHED) {
*age = fr_tcplastack;
state[dir] = TCPS_LAST_ACK;
} else
*age = fr_tcpclosewait;
break;
case TCPS_LAST_ACK:
if (flags & TH_ACK) {
state[dir] = TCPS_FIN_WAIT_2;
if (!(flags & TH_PUSH) && !dlen &&
ostate > TCPS_ESTABLISHED)
*age = fr_tcplastack;
else {
*age = fr_tcpclosewait;
state[dir] = TCPS_CLOSE_WAIT;
}
}
break;
}
}

View File

@ -1,3 +1,5 @@
/* $NetBSD: ipft_ef.c,v 1.1.1.2 1997/03/29 02:49:48 darrenr Exp $ */
/*
* (C)opyright 1993,1994,1995 by Darren Reed.
*
@ -47,10 +49,12 @@ etherfind -n -t
#if !defined(lint) && defined(LIBC_SCCS)
static char sccsid[] = "@(#)ipft_ef.c 1.6 2/4/96 (C)1995 Darren Reed";
static char rcsid[] = "$Id: ipft_ef.c,v 1.1.1.1 1997/01/05 13:09:04 mrg Exp $";
static char rcsid[] = "$Id: ipft_ef.c,v 1.1.1.2 1997/03/29 02:49:48 darrenr Exp $";
#endif
static int etherf_open(), etherf_close(), etherf_readip();
static int etherf_open __P((char *));
static int etherf_close __P((void));
static int etherf_readip __P((char *, int, char **, int *));
struct ipread etherf = { etherf_open, etherf_close, etherf_readip };

View File

@ -1,3 +1,5 @@
/* $NetBSD: ipft_hx.c,v 1.1.1.2 1997/03/29 02:49:52 darrenr Exp $ */
/*
* (C)opyright 1995 by Darren Reed.
*
@ -38,15 +40,15 @@
#if !defined(lint) && defined(LIBC_SCCS)
static char sccsid[] = "@(#)ipft_hx.c 1.1 3/9/96 (C) 1996 Darren Reed";
static char rcsid[] = "$Id: ipft_hx.c,v 1.1.1.1 1997/01/05 13:09:04 mrg Exp $";
static char rcsid[] = "$Id: ipft_hx.c,v 1.1.1.2 1997/03/29 02:49:52 darrenr Exp $";
#endif
extern int opts;
extern u_short portnum();
extern u_long buildopts();
static int hex_open(), hex_close(), hex_readip();
static char *readhex();
static int hex_open __P((char *));
static int hex_close __P((void));
static int hex_readip __P((char *, int, char **, int *));
static char *readhex __P((char *, char *));
struct ipread iphex = { hex_open, hex_close, hex_readip };
static FILE *tfp = NULL;
@ -85,7 +87,7 @@ static int hex_readip(buf, cnt, ifn, dir)
char *buf, **ifn;
int cnt, *dir;
{
register char *s;
register char *s, *t, *u;
struct ip *ip;
char line[513];
@ -96,8 +98,6 @@ int cnt, *dir;
return (char *)ip - buf;
*s = '\0';
}
if ((s = index(line, '\r')))
*s = '\0';
if ((s = index(line, '#')))
*s = '\0';
if (!*line)
@ -106,7 +106,30 @@ int cnt, *dir;
printf("input: %s\n", line);
fflush(stdout);
}
ip = (struct ip *)readhex(line, (char *)ip);
/*
* interpret start of line as possibly "[ifname]" or
* "[in/out,ifname]".
*/
*ifn = NULL;
*dir = 0;
if ((*buf == '[') && (s = index(line, ']'))) {
t = buf + 1;
if (t - s > 0) {
if ((u = index(t, ',')) && (u < s)) {
u++;
*ifn = u;
if (*t == 'i')
*dir = 0;
else if (*t == 'o')
*dir = 1;
} else
*ifn = t;
*s++ = '\0';
}
} else
s = line;
ip = (struct ip *)readhex(s, (char *)ip);
}
return -1;
}

View File

@ -1,3 +1,5 @@
/* $NetBSD: ipft_pc.c,v 1.1.1.2 1997/03/29 02:49:50 darrenr Exp $ */
/*
* (C)opyright 1993-1996 by Darren Reed.
*
@ -30,7 +32,7 @@
#include "pcap.h"
#if !defined(lint) && defined(LIBC_SCCS)
static char rcsid[] = "$Id: ipft_pc.c,v 1.1.1.1 1997/01/05 13:09:04 mrg Exp $";
static char rcsid[] = "$Id: ipft_pc.c,v 1.1.1.2 1997/03/29 02:49:50 darrenr Exp $";
#endif
struct llc {
@ -59,11 +61,15 @@ static struct llc llcs[DLT_MAX+1] = {
{ 0, 0, 0 } /* DLT_FDDI */
};
static int ipft_pcap_open(), ipft_pcap_close(), ipft_pcap_readip();
static int pcap_open __P((char *));
static int pcap_close __P((void));
static int pcap_readip __P((char *, int, char **, int *));
static void swap_hdr __P((pcaphdr_t *));
static int pcap_read_rec __P((struct pcap_pkthdr *));
static int pfd = -1, s_type = -1, swapped = 0;
struct ipread pcap = { ipft_pcap_open, ipft_pcap_close, ipft_pcap_readip };
struct ipread pcap = { pcap_open, pcap_close, pcap_readip };
#define SWAPLONG(y) \
((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff))
@ -81,7 +87,7 @@ pcaphdr_t *p;
p->pc_type = SWAPLONG(p->pc_type);
}
static int ipft_pcap_open(fname)
static int pcap_open(fname)
char *fname;
{
pcaphdr_t ph;
@ -122,7 +128,7 @@ char *fname;
}
static int ipft_ipft_pcap_close()
static int pcap_close()
{
return close(pfd);
}
@ -132,8 +138,8 @@ static int ipft_ipft_pcap_close()
* read in the header (and validate) which should be the first record
* in a pcap file.
*/
static int ipft_pcap_read_rec(rec)
struct ipft_pcap_pkthdr *rec;
static int pcap_read_rec(rec)
struct pcap_pkthdr *rec;
{
int n, p;
@ -160,15 +166,15 @@ struct ipft_pcap_pkthdr *rec;
* read an entire pcap packet record. only the data part is copied into
* the available buffer, with the number of bytes copied returned.
*/
static int ipft_pcap_read(buf, cnt)
static int pcap_read(buf, cnt)
char *buf;
int cnt;
{
struct ipft_pcap_pkthdr rec;
struct pcap_pkthdr rec;
static char *bufp = NULL;
int i, n;
if ((i = ipft_pcap_read_rec(&rec)) <= 0)
if ((i = pcap_read_rec(&rec)) <= 0)
return i;
if (!bufp)
@ -189,18 +195,18 @@ int cnt;
/*
* return only an IP packet read into buf
*/
static int ipft_ipft_pcap_readip(buf, cnt, ifn, dir)
static int pcap_readip(buf, cnt, ifn, dir)
char *buf, **ifn;
int cnt, *dir;
{
static char *bufp = NULL;
struct ipft_pcap_pkthdr rec;
struct pcap_pkthdr rec;
struct llc *l;
char *s, ty[4];
int i, n;
do {
if ((i = ipft_pcap_read_rec(&rec)) <= 0)
if ((i = pcap_read_rec(&rec)) <= 0)
return i;
if (!bufp)

View File

@ -1,3 +1,5 @@
/* $NetBSD: ipft_sn.c,v 1.1.1.2 1997/03/29 02:49:47 darrenr Exp $ */
/*
* (C)opyright 1993,1994,1995 by Darren Reed.
*
@ -33,7 +35,7 @@
#include "snoop.h"
#if !defined(lint) && defined(LIBC_SCCS)
static char rcsid[] = "$Id: ipft_sn.c,v 1.1.1.1 1997/01/05 13:09:04 mrg Exp $";
static char rcsid[] = "$Id: ipft_sn.c,v 1.1.1.2 1997/03/29 02:49:47 darrenr Exp $";
#endif
struct llc {
@ -59,9 +61,12 @@ static struct llc llcs[SDL_MAX+1] = {
{ 0, 0, 0 }, /* SDL_OTHER */
};
static int snoop_open(), snoop_close(), snoop_readip();
static int snoop_open __P((char *));
static int snoop_close __P((void));
static int snoop_readip __P((char *, int, char **, int *));
static int sfd = -1, s_type = -1;
static int snoop_read_rec __P((struct snooppkt *));
struct ipread snoop = { snoop_open, snoop_close, snoop_readip };

View File

@ -1,3 +1,5 @@
/* $NetBSD: ipft_td.c,v 1.1.1.2 1997/03/29 02:49:49 darrenr Exp $ */
/*
* (C)opyright 1993,1994,1995 by Darren Reed.
*
@ -56,10 +58,13 @@ tcpdump -nqte
#if !defined(lint) && defined(LIBC_SCCS)
static char sccsid[] = "@(#)ipft_td.c 1.8 2/4/96 (C)1995 Darren Reed";
static char rcsid[] = "$Id: ipft_td.c,v 1.1.1.1 1997/01/05 13:09:04 mrg Exp $";
static char rcsid[] = "$Id: ipft_td.c,v 1.1.1.2 1997/03/29 02:49:49 darrenr Exp $";
#endif
static int tcpd_open(), tcpd_close(), tcpd_readip();
static int tcpd_open __P((char *));
static int tcpd_close __P((void));
static int tcpd_readip __P((char *, int, char **, int *));
static int count_dots __P((char *));
struct ipread tcpd = { tcpd_open, tcpd_close, tcpd_readip };

View File

@ -1,3 +1,5 @@
/* $NetBSD: ipft_tx.c,v 1.1.1.2 1997/03/29 02:49:51 darrenr Exp $ */
/*
* (C)opyright 1995 by Darren Reed.
*
@ -40,15 +42,17 @@
#if !defined(lint) && defined(LIBC_SCCS)
static char sccsid[] = "@(#)ipft_tx.c 1.7 6/5/96 (C) 1993 Darren Reed";
static char rcsid[] = "$Id: ipft_tx.c,v 1.1.1.1 1997/01/05 13:09:05 mrg Exp $";
static char rcsid[] = "$Id: ipft_tx.c,v 1.1.1.2 1997/03/29 02:49:51 darrenr Exp $";
#endif
extern int opts;
extern u_long buildopts();
extern u_long buildopts __P((char *, char *));
static char *tx_proto = "";
static int text_open(), text_close(), text_readip(), parseline();
static int text_open __P((char *)), text_close __P((void));
static int text_readip __P((char *, int, char **, int *));
static int parseline __P((char *, struct ip *, char **, int *));
static char tcp_flagset[] = "FSRPAU";
static u_char tcp_flags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH,
@ -58,15 +62,15 @@ struct ipread iptext = { text_open, text_close, text_readip };
static FILE *tfp = NULL;
static int tfd = -1;
static u_long tx_hostnum();
static u_short tx_portnum();
static u_long tx_hostnum __P((char *, int *));
static u_short tx_portnum __P((char *));
/*
* returns an ip address as a long var as a result of either a DNS lookup or
* straight inet_addr() call
*/
u_long tx_hostnum(host, resolved)
static u_long tx_hostnum(host, resolved)
char *host;
int *resolved;
{
@ -95,7 +99,7 @@ int *resolved;
* find the port number given by the name, either from getservbyname() or
* straight atoi()
*/
u_short tx_portnum(name)
static u_short tx_portnum(name)
char *name;
{
struct servent *sp, *sp2;
@ -190,7 +194,7 @@ int cnt, *dir;
printf("input: %s\n", line);
*ifn = NULL;
*dir = 0;
if (!parseline(line, buf, ifn, dir))
if (!parseline(line, (struct ip *)buf, ifn, dir))
#if 0
return sizeof(struct tcpiphdr);
#else
@ -211,6 +215,8 @@ int *out;
char *cps[20], **cpp, c, ipopts[68];
int i, r;
if (*ifn)
free(*ifn);
bzero((char *)ip, MAX(sizeof(*tcp), sizeof(*ic)) + sizeof(*ip));
bzero((char *)tcp, sizeof(*tcp));
bzero((char *)ic, sizeof(*ic));
@ -236,7 +242,7 @@ int *out;
cpp++;
if (!*cpp)
return 1;
*ifn = *cpp++;
*ifn = strdup(*cpp++);
}
c = **cpp;

View File

@ -1,3 +1,5 @@
/* $NetBSD: ipt.c,v 1.1.1.2 1997/03/29 02:49:46 darrenr Exp $ */
/*
* (C)opyright 1993-1996 by Darren Reed.
*
@ -12,6 +14,7 @@
#include <strings.h>
#else
#include <sys/byteorder.h>
#include <sys/file.h>
#endif
#include <sys/types.h>
#include <sys/param.h>
@ -29,30 +32,29 @@
#include <netinet/ip_icmp.h>
#include <netinet/tcpip.h>
#include <net/if.h>
#include <netinet/ip_fil.h>
#include <netdb.h>
#include <arpa/nameser.h>
#include <arpa/inet.h>
#include <resolv.h>
#include <ctype.h>
#include <netinet/ip_compat.h>
#include <netinet/ip_fil.h>
#include "ipf.h"
#include "ipt.h"
#include <ctype.h>
#if !defined(lint) && defined(LIBC_SCCS)
static char sccsid[] = "@(#)ipt.c 1.19 6/3/96 (C) 1993-1996 Darren Reed";
static char rcsid[] = "$Id: ipt.c,v 1.1.1.1 1997/01/05 13:09:05 mrg Exp $";
static char rcsid[] = "$Id: ipt.c,v 1.1.1.2 1997/03/29 02:49:46 darrenr Exp $";
#endif
extern int fr_check();
extern char *optarg;
extern struct frentry *ipfilter[2][2];
/*extern struct ipread snoop, etherf, tcpd, pcap, iptext, iphex;*/
extern struct ipread snoop, etherf, tcpd, iptext, iphex;
extern void debug(), verbose();
struct frentry *ft_in = NULL, *ft_out = NULL;
extern struct frentry *ipfilter[2][2];
extern struct ipread snoop, etherf, tcpd, pcap, iptext, iphex;
extern struct ifnet *get_unit __P((char *));
extern void init_ifp __P((void));
int opts = 0;
int main __P((int, char *[]));
int main(argc,argv)
int argc;
@ -62,11 +64,12 @@ char *argv[];
struct frentry *f;
struct ip *ip;
u_long buf[64];
struct ifnet *ifp;
char c;
char *rules = NULL, *datain = NULL, *iface = NULL;
int fd, i, dir = 0;
while ((c = getopt(argc, argv, "bdEHi:I:Pr:STvX")) != -1)
while ((c = getopt(argc, argv, "bdEHi:I:oPr:STvX")) != -1)
switch (c)
{
case 'b' :
@ -81,6 +84,9 @@ char *argv[];
case 'I' :
iface = optarg;
break;
case 'o' :
opts |= OPT_SAVEOUT;
break;
case 'r' :
rules = optarg;
break;
@ -93,11 +99,9 @@ char *argv[];
case 'H' :
r = &iphex;
break;
#if 0
case 'P' :
r = &pcap;
break;
#endif
case 'S' :
r = &snoop;
break;
@ -148,23 +152,18 @@ char *argv[];
if (!(fr = parse(line)))
continue;
f = (struct frentry *)malloc(sizeof(*f));
if (fr->fr_flags & FR_INQUE) {
if (!ft_in)
ft_in = ipfilter[0][0] = f;
else
ft_in->fr_next = f, ft_in = f;
} else if (fr->fr_flags & FR_OUTQUE) {
if (!ft_out)
ft_out = ipfilter[1][0] = f;
else
ft_out->fr_next = f, ft_out = f;
}
bcopy((char *)fr, (char *)f, sizeof(*fr));
/* fake an `ioctl' call :) */
i = iplioctl(0, SIOCADDFR, (caddr_t)fr, FWRITE|FREAD);
if (opts & OPT_DEBUG)
fprintf(stderr,
"iplioctl(SIOCADDFR,%x,1) = %d\n", i);
}
(void)fclose(fp);
}
if (opts & OPT_SAVEOUT)
init_ifp();
if (datain)
fd = (*r->r_open)(datain);
else
@ -174,10 +173,12 @@ char *argv[];
exit(-1);
ip = (struct ip *)buf;
while ((i = (*r->r_readip)(buf, sizeof(buf), &iface, &dir)) > 0) {
while ((i = (*r->r_readip)((char *)buf, sizeof(buf),
&iface, &dir)) > 0) {
ifp = iface ? get_unit(iface) : NULL;
ip->ip_off = ntohs(ip->ip_off);
ip->ip_len = ntohs(ip->ip_len);
switch (fr_check(ip, ip->ip_hl << 2, iface, dir))
switch (fr_check(ip, ip->ip_hl << 2, ifp, dir, (char *)buf))
{
case -1 :
(void)printf("block");
@ -191,9 +192,11 @@ char *argv[];
}
if (!(opts & OPT_BRIEF)) {
putchar(' ');
printpacket(buf);
printpacket((struct ip *)buf);
printf("--------------");
}
if (dir && ifp && ip->ip_v)
(*ifp->if_output)(ifp, (void *)buf, NULL, 0);
putchar('\n');
dir = 0;
}

View File

@ -1,16 +1,27 @@
/* $NetBSD: ipt.h,v 1.1.1.2 1997/03/29 02:49:53 darrenr Exp $ */
/*
* (C)opyright 1993,1994,1995 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
* $Id: ipt.h,v 1.1.1.1 1997/01/05 13:09:05 mrg Exp $
* $Id: ipt.h,v 1.1.1.2 1997/03/29 02:49:53 darrenr Exp $
*/
#include <fcntl.h>
#ifdef __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
struct ipread {
int (*r_open)();
int (*r_close)();
int (*r_readip)();
int (*r_open) __P((char *));
int (*r_close) __P((void));
int (*r_readip) __P((char *, int, char **, int *));
};
extern void debug __P((char *, ...));
extern void verbose __P((char *, ...));

View File

@ -1,3 +1,5 @@
/* $NetBSD: misc.c,v 1.1.1.2 1997/03/29 02:49:51 darrenr Exp $ */
/*
* (C)opyright 1993,1994,1995 by Darren Reed.
*
@ -30,20 +32,18 @@
#include <netinet/ip_icmp.h>
#include <netinet/tcpip.h>
#include <net/if.h>
#include <netinet/ip_fil.h>
#include <netdb.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include <netinet/ip_fil.h>
#include "ipf.h"
#include "ipt.h"
#if !defined(lint) && defined(LIBC_SCCS)
static char sccsid[] = "@(#)misc.c 1.3 2/4/96 (C) 1995 Darren Reed";
static char rcsid[] = "$Id: misc.c,v 1.1.1.1 1997/01/05 13:09:05 mrg Exp $";
static char rcsid[] = "$Id: misc.c,v 1.1.1.2 1997/03/29 02:49:51 darrenr Exp $";
#endif
void debug(), verbose();
extern int opts;
@ -69,17 +69,35 @@ struct ip *ip;
}
void verbose(fmt, p1, p2, p3, p4, p5, p6, p7, p8, p9)
char *fmt, *p1, *p2, *p3, *p4, *p5, *p6, *p7,*p8,*p9;
#ifdef __STDC__
void verbose(char *fmt, ...)
#else
void verbose(fmt, va_alist)
char *fmt;
va_dcl
#endif
{
va_list pvar;
va_start(pvar, fmt);
if (opts & OPT_VERBOSE)
printf(fmt, p1, p2, p3, p4, p5, p6, p7, p8, p9);
vprintf(fmt, pvar);
va_end(pvar);
}
void debug(fmt, p1, p2, p3, p4, p5, p6, p7, p8, p9)
char *fmt, *p1, *p2, *p3, *p4, *p5, *p6, *p7,*p8,*p9;
#ifdef __STDC__
void debug(char *fmt, ...)
#else
void debug(fmt, va_alist)
char *fmt;
va_dcl
#endif
{
va_list pvar;
va_start(pvar, fmt);
if (opts & OPT_DEBUG)
printf(fmt, p1, p2, p3, p4, p5, p6, p7, p8, p9);
vprintf(fmt, pvar);
va_end(pvar);
}

137
usr.sbin/ipf/ipftest/opt.c Normal file
View File

@ -0,0 +1,137 @@
/* $NetBSD: opt.c,v 1.1.1.1 1997/03/29 02:49:50 darrenr Exp $ */
/*
* (C)opyright 1993,1994,1995 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet/tcp.h>
#include <netinet/tcpip.h>
#include <net/if.h>
#include <netinet/ip_compat.h>
#include "ipf.h"
#if !defined(lint) && defined(LIBC_SCCS)
static char sccsid[] = "@(#)opt.c 1.8 4/10/96 (C) 1993-1995 Darren Reed";
static char rcsid[] = "$Id: opt.c,v 1.1.1.1 1997/03/29 02:49:50 darrenr Exp $";
#endif
extern int opts;
struct ipopt_names ionames[] ={
{ IPOPT_NOP, 0x000001, 1, "nop" },
{ IPOPT_RR, 0x000002, 7, "rr" }, /* 1 route */
{ IPOPT_ZSU, 0x000004, 3, "zsu" },
{ IPOPT_MTUP, 0x000008, 3, "mtup" },
{ IPOPT_MTUR, 0x000010, 3, "mtur" },
{ IPOPT_ENCODE, 0x000020, 3, "encode" },
{ IPOPT_TS, 0x000040, 8, "ts" }, /* 1 TS */
{ IPOPT_TR, 0x000080, 3, "tr" },
{ IPOPT_SECURITY,0x000100, 11, "sec" },
{ IPOPT_SECURITY,0x000100, 11, "sec-class" },
{ IPOPT_LSRR, 0x000200, 7, "lsrr" }, /* 1 route */
{ IPOPT_E_SEC, 0x000400, 3, "e-sec" },
{ IPOPT_CIPSO, 0x000800, 3, "cipso" },
{ IPOPT_SATID, 0x001000, 4, "satid" },
{ IPOPT_SSRR, 0x002000, 7, "ssrr" }, /* 1 route */
{ IPOPT_ADDEXT, 0x004000, 3, "addext" },
{ IPOPT_VISA, 0x008000, 3, "visa" },
{ IPOPT_IMITD, 0x010000, 3, "imitd" },
{ IPOPT_EIP, 0x020000, 3, "eip" },
{ IPOPT_FINN, 0x040000, 3, "finn" },
{ 0, 0, 0, (char *)NULL } /* must be last */
};
struct ipopt_names secclass[] = {
{ IPSO_CLASS_RES4, 0x01, 0, "reserv-4" },
{ IPSO_CLASS_TOPS, 0x02, 0, "topsecret" },
{ IPSO_CLASS_SECR, 0x04, 0, "secret" },
{ IPSO_CLASS_RES3, 0x08, 0, "reserv-3" },
{ IPSO_CLASS_CONF, 0x10, 0, "confid" },
{ IPSO_CLASS_UNCL, 0x20, 0, "unclass" },
{ IPSO_CLASS_RES2, 0x40, 0, "reserv-2" },
{ IPSO_CLASS_RES1, 0x80, 0, "reserv-1" },
{ 0, 0, 0, NULL } /* must be last */
};
static u_char seclevel __P((char *));
static u_char seclevel(slevel)
char *slevel;
{
struct ipopt_names *so;
for (so = secclass; so->on_name; so++)
if (!strcasecmp(slevel, so->on_name))
break;
if (!so->on_name) {
fprintf(stderr, "no such security level: %s\n", slevel);
return 0;
}
return (u_char)so->on_value;
}
u_long buildopts(cp, op)
char *cp, *op;
{
struct ipopt_names *io;
u_char lvl;
u_long msk = 0;
char *s, *t;
int len = 0;
for (s = strtok(cp, ","); s; s = strtok(NULL, ",")) {
if ((t = strchr(s, '=')))
*t++ = '\0';
for (io = ionames; io->on_name; io++) {
if (strcasecmp(s, io->on_name) || (msk & io->on_bit))
continue;
if ((len + io->on_siz) > 48) {
fprintf(stderr, "options too long\n");
return 0;
}
len += io->on_siz;
*op++ = io->on_value;
if (io->on_siz > 1) {
*op++ = io->on_siz;
*op++ = IPOPT_MINOFF;
if (t && !strcasecmp(s, "sec-class")) {
lvl = seclevel(t);
*(op - 1) = lvl;
}
op += io->on_siz - 3;
if (len & 3) {
*op++ = IPOPT_NOP;
len++;
}
}
if (opts & OPT_DEBUG)
fprintf(stderr, "bo: %s %d %#x: %d\n",
io->on_name, io->on_value,
io->on_bit, len);
msk |= io->on_bit;
break;
}
if (!io->on_name) {
fprintf(stderr, "unknown IP option name %s\n", s);
return 0;
}
}
*op++ = IPOPT_EOL;
len++;
return len;
}

View File

@ -1,3 +1,5 @@
/* $NetBSD: snoop.h,v 1.1.1.2 1997/03/29 02:49:55 darrenr Exp $ */
/*
* (C)opyright 1993,1994,1995 by Darren Reed.
*
@ -8,7 +10,7 @@
/*
* written to comply with the RFC (1761) from Sun.
* $Id: snoop.h,v 1.1.1.1 1997/01/05 13:09:05 mrg Exp $
* $Id: snoop.h,v 1.1.1.2 1997/03/29 02:49:55 darrenr Exp $
*/
struct snoophdr {
char s_id[8];

View File

@ -0,0 +1,24 @@
results
1
2
3
4
5
6
7
8
9
10
11
12
i1
i2
i3
i4
i5
i6
i7
i8
i9
i10
i11

View File

@ -0,0 +1,39 @@
#
# (C)opyright 1993-1996 by Darren Reed.
#
# This code may be freely distributed as long as it retains this notice
# and is not changed in any way. The author accepts no responsibility
# for the use of this software. I hate legaleese, don't you ?
#
# where to put things.
#
BINDEST=/usr/local/bin
SBINDEST=/sbin
MANDIR=/usr/share/man
tests: first 0 ftests ptests
first:
-mkdir -p results
# Filtering tests
ftests: 1 2 3 4 5 6 7 8 9 10 11 12
# Rule parsing tests
ptests: i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11
0:
@(cd ..; make ipftest; )
1 2 3 4 5 6 7 8 9 10 11:
@./dotest $@
12:
@./hextest $@
i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11:
@./itest $@
clean:
/bin/rm -f 1 2 3 4 5 6 7 8 9 10 11 12 results/*
/bin/rm -f i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11

View File

@ -0,0 +1,26 @@
#!/bin/sh
if [ -f /usr/ucb/touch ] ; then
TOUCH=/usr/ucb/touch
else
if [ -f /usr/bin/touch ] ; then
TOUCH=/usr/bin/touch
else
if [ -f /bin/touch ] ; then
TOUCH=/bin/touch
fi
fi
fi
echo "$1...";
/bin/cp /dev/null results/$1
( while read rule; do
echo "$rule" | ../ipftest -br - -i input/$1 >> results/$1;
if [ $? -ne 0 ] ; then
exit 1;
fi
done ) < regress/$1
cmp expected/$1 results/$1
status=$?
if [ $status = 0 ] ; then
$TOUCH $1
fi
exit $status

View File

@ -0,0 +1,16 @@
block
block
nomatch
nomatch
pass
pass
nomatch
nomatch
nomatch
nomatch
block
block
nomatch
nomatch
pass
pass

View File

@ -0,0 +1,108 @@
nomatch
block
nomatch
nomatch
nomatch
nomatch
pass
pass
pass
nomatch
nomatch
pass
block
block
block
nomatch
nomatch
block
pass
pass
pass
nomatch
nomatch
pass
block
block
nomatch
nomatch
nomatch
block
pass
pass
nomatch
nomatch
nomatch
pass
block
block
block
block
block
block
pass
pass
pass
pass
pass
pass
nomatch
block
block
block
nomatch
block
nomatch
pass
pass
pass
nomatch
pass
nomatch
pass
nomatch
nomatch
nomatch
nomatch
nomatch
block
block
block
block
block
nomatch
pass
pass
pass
pass
pass
block
block
nomatch
block
nomatch
block
pass
pass
nomatch
pass
nomatch
pass
block
block
block
block
block
block
pass
pass
pass
pass
pass
pass
block
block
block
nomatch
nomatch
block

View File

@ -0,0 +1,66 @@
pass
pass
pass
pass
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
block
block
block
block
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
pass
pass
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
block
block
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
pass
pass
pass
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
block
block
block
nomatch
nomatch

View File

@ -0,0 +1,54 @@
pass
pass
pass
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
pass
pass
pass
pass
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
block
block
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
block
block
block
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
pass
nomatch
pass
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
block

View File

@ -0,0 +1,36 @@
block
block
nomatch
nomatch
nomatch
nomatch
pass
pass
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
block
block
nomatch
nomatch
nomatch
nomatch
pass
pass
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
block
block
nomatch
nomatch
nomatch
nomatch
pass
pass

View File

@ -0,0 +1,40 @@
nomatch
block
nomatch
nomatch
nomatch
nomatch
pass
nomatch
nomatch
nomatch
nomatch
block
block
nomatch
nomatch
nomatch
pass
pass
nomatch
nomatch
nomatch
block
block
block
nomatch
nomatch
pass
pass
pass
nomatch
block
block
block
block
block
pass
pass
pass
pass
pass

View File

@ -0,0 +1,40 @@
nomatch
block
nomatch
nomatch
nomatch
nomatch
pass
nomatch
nomatch
nomatch
nomatch
block
block
nomatch
nomatch
nomatch
pass
pass
nomatch
nomatch
nomatch
block
block
block
nomatch
nomatch
pass
pass
pass
nomatch
block
block
block
block
block
pass
pass
pass
pass
pass

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,54 @@
block
block
block
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
pass
pass
pass
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
block
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
pass
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
block
block
block
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
pass
pass
pass

View File

@ -0,0 +1,36 @@
block
nomatch
nomatch
nomatch
nomatch
nomatch
pass
nomatch
nomatch
nomatch
nomatch
nomatch
block
nomatch
block
nomatch
nomatch
nomatch
pass
nomatch
pass
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch

View File

@ -0,0 +1,108 @@
block
block
block
block
block
block
nomatch
nomatch
nomatch
pass
pass
nomatch
nomatch
nomatch
nomatch
nomatch
block
nomatch
nomatch
nomatch
nomatch
nomatch
pass
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
block
nomatch
nomatch
nomatch
nomatch
nomatch
pass
nomatch
nomatch
nomatch
nomatch
pass
pass
pass
pass
pass
pass
block
block
nomatch
nomatch
nomatch
nomatch
pass
pass
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
nomatch
block
block
nomatch

View File

@ -0,0 +1,11 @@
pass in from any to any
block out from any to any
log in from any to any
log body in from any to any
count in from any to any
pass in on ed0(!) from 127.0.0.1/32 to 127.0.0.1/32
block in log first on lo0(!) from any to any
pass in log body quick from any to any
block return-rst in quick on le0(!) proto tcp from any to any
block return-icmp in on qe0(!) from any to any
block return-icmp(host-unr) in on qe0(!) from any to any

View File

@ -0,0 +1,4 @@
pass in from 127.0.0.1/32 to 127.0.0.1/32 with opt sec
block in from any to any with not opt sec-class topsecret
block in from any to any with not opt sec-class topsecret,secret
pass in from any to any with opt sec-class topsecret,confid not opt sec-class unclass

View File

@ -0,0 +1,4 @@
pass in on ed0(!) proto tcp from 127.0.0.1/32 to 127.0.0.1/32 port = 23 keep state
block in log first on lo0(!) proto tcp/udp from any to any keep state
pass in proto udp from 127.0.0.1/32 to 127.0.0.1/32 port = 2049 keep frags
pass in proto udp from 127.0.0.1/32 to 127.0.0.1/32 port = 53 keep state keep frags

View File

@ -0,0 +1,6 @@
log in proto tcp from any to any
pass in proto tcp from any to any
pass in proto udp from 127.0.0.1/32 to 127.0.0.1/32
block in proto udp from any to any
block in proto 250 from any to any
pass in proto tcp/udp from any to any

View File

@ -0,0 +1,8 @@
log in from any to any
pass in from 128.0.0.0/24 to 128.0.0.0/16
pass in from 128.0.0.0/24 to 128.0.0.0/16
pass in from 128.0.0.0/24 to 128.0.0.0/16
pass in from 128.0.0.0/24 to 128.0.0.0/16
pass in from 128.0.0.0/24 to 128.0.0.0/16
pass in from 127.0.0.1/32 to 127.0.0.1/32
block in log from any to any

View File

@ -0,0 +1,7 @@
log in proto tcp from any port > 0 to any
log in proto tcp from any to any port > 0
pass in proto tcp from any port != 0 to any port 0 >< 65535
pass in proto udp from 127.0.0.1/32 port > 32000 to 127.0.0.1/32 port < 29000
block in proto udp from any port != 123 to any port < 123
block in proto tcp from any port = 25 to any port > 25
pass in proto tcp/udp from any port 1 >< 3 to any port 1 <> 3

View File

@ -0,0 +1,5 @@
log in from any to any
count in tos 0x80 from any to any
pass in on ed0(!) tos 0x40 from 127.0.0.1/32 to 127.0.0.1/32
block in log on lo0(!) ttl 0 from any to any
pass in quick ttl 1 from any to any

View File

@ -0,0 +1,4 @@
pass in on lo0(!) fastroute from any to any
pass in on lo0(!) dup-to qe0(!) from 127.0.0.1/32 to 127.0.0.1/32
pass in on qe0(!) dup-to qe0(!):127.0.0.1 from 127.0.0.1/32 to 127.0.0.1/32
block in quick on qe0(!) to qe1(!) from any to any

View File

@ -0,0 +1,3 @@
pass in on ed0(!) proto tcp from 127.0.0.1/32 to 127.0.0.1/32 port = 23 flags S/SA
block in on lo0(!) proto tcp from any to any flags A/FSRPAU
pass in on lo0(!) proto tcp from any to any flags /SPA

View File

@ -0,0 +1,2 @@
pass in proto icmp from 127.0.0.1/32 to 127.0.0.1/32 icmp-type timest
block in proto icmp from any to any icmp-type unreach code 1

View File

@ -0,0 +1,5 @@
pass in from 127.0.0.1/32 to 127.0.0.1/32 with short
block in from any to any with ipopt
pass in from any to any with opt nop,rr,zsu
pass in from any to any with opt nop,rr,zsu not opt lsrr,ssrr
pass in from 127.0.0.1/32 to 127.0.0.1/32 with not frag

View File

@ -0,0 +1,23 @@
#!/bin/sh
if [ -f /usr/ucb/touch ] ; then
TOUCH=/usr/ucb/touch
else
if [ -f /usr/bin/touch ] ; then
TOUCH=/usr/bin/touch
else
if [ -f /bin/touch ] ; then
TOUCH=/bin/touch
fi
fi
fi
echo "$1...";
/bin/cp /dev/null results/$1
( while read rule; do
echo "$rule" | ../ipftest -br - -Hi input/$1 >> results/$1;
done ) < regress/$1
cmp expected/$1 results/$1
status=$?
if [ $status = 0 ] ; then
$TOUCH $1
fi
exit $status

View File

@ -0,0 +1,4 @@
in 127.0.0.1 127.0.0.1
in 1.1.1.1 1.2.1.1
out 127.0.0.1 127.0.0.1
out 1.1.1.1 1.2.1.1

View File

@ -0,0 +1,6 @@
in 1.1.1.1 2.1.1.1 opt lsrr
in 1.1.1.1 2.1.1.1
in 1.1.1.1 2.1.1.1 opt ts
in 1.1.1.1 2.1.1.1 opt sec-class=topsecret
in 1.1.1.1 2.1.1.1 opt ssrr,sec-class=topsecret
in 1.1.1.1 2.1.1.1 opt sec

View File

@ -0,0 +1,11 @@
in tcp 1.1.1.1,1 2.1.2.2,23 S
in tcp 1.1.1.1,1 2.1.2.2,23 A
in tcp 2.1.2.2,23 1.1.1.1,1 A
in tcp 1.1.1.1,1 2.1.2.2,23 F
in tcp 1.1.1.1,1 2.1.2.2,23 A
in tcp 1.1.1.1,2 2.1.2.2,23 A
in udp 1.1.1.1,1 4.4.4.4,53
in udp 2.2.2.2,2 4.4.4.4,53
in udp 4.4.4.4,53 1.1.1.1,1
in udp 4.4.4.4,1023 1.1.1.1,2049
in udp 4.4.4.4,2049 1.1.1.1,1023

View File

@ -0,0 +1,35 @@
# 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF SYN
45 00 0028 0000 4000 3f 06 0000 01010101 02010101
0401 0019 00000000 00000000 50 02 2000 0000 0000
# 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF ACK
45 00 0028 0000 4000 3f 06 0000 01010101 02010101
0401 0019 00000000 00000000 50 10 2000 0000 0000
# 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF MF FO=0 ACK
45 00 0028 0000 6000 3f 06 0000 01010101 02010101
0401 0019 00000000 00000000 50 10 2000 0000 0000
# 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF FO=0
45 00 001c 0000 6000 3f 06 0000 01010101 02010101
0401 0019 00000000
# 1.1.1.1 -> 2.1.1.1 TTL=63 TCP DF FO=1 ACK
45 00 001c 0000 6001 3f 06 0000 01010101 02010101
00000000 50 10 2000
# 1.1.1.1 -> 2.1.1.1 TTL=63 UDP DF MF FO=0
45 00 0014 0000 6000 3f 11 0000 01010101 02010101
# 1.1.1.1,53 -> 2.1.1.1,53 TTL=63 UDP MF FO=0
45 00 0018 0000 2000 3f 11 0000 01010101 02010101
0035 0035
# 1.1.1.1,1 -> 2.1.1.1,1 TTL=63 UDP MF FO=0
45 00 001c 0000 2000 3f 11 0000 01010101 02010101
0001 0001 0004 0000
# 1.1.1.1,53 -> 2.1.1.1,53 TTL=63 UDP MF FO=0
45 00 001c 0000 2000 3f 11 0000 01010101 02010101
0035 0035 0004 0000

View File

@ -0,0 +1,39 @@
# 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF,MF,FO=0 SYN
45 00 0028 0001 4000 3f 06 0000 01010101 02010101
0401 0019 00000000 00000000 50 02 2000 0000 0000
# 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP MF ACK
45 00 0024 0002 2000 3f 06 0000 01010101 02010101
0401001900000000 0000000050102000
# 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP FO=2 ACK
45 00 002c 0002 0002 3f 06 0000 01010101 02010101
0000000000010203 0405060708090a0b 0c0d0e0f10111213
# 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF MF FO=0 SYN
45 00 0028 0003 6000 3f 06 0000 01010101 02010101
0401 0019 00000000 00000000 50 10 2000 0000 0000
# 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF FO=0
45 00 001c 0004 6000 3f 06 0000 01010101 02010101
0401 0019 00000000
# 1.1.1.1 -> 2.1.1.1 TTL=63 TCP DF FO=1 SYN
45 00 001c 0005 6001 3f 06 0000 01010101 02010101
00000000 50 10 2000
# 1.1.1.1 -> 2.1.1.1 TTL=63 UDP DF MF FO=0
45 00 0014 0006 6000 3f 11 0000 01010101 02010101
# 1.1.1.1,53 -> 2.1.1.1,53 TTL=63 UDP MF FO=0
45 00 0018 0007 2000 3f 11 0000 01010101 02010101
0035 0035
# 1.1.1.1,1 -> 2.1.1.1,1 TTL=63 UDP MF FO=0
45 00 001c 0008 2000 3f 11 0000 01010101 02010101
0035003500040000
# 1.1.1.1,53 -> 2.1.1.1,53 TTL=63 UDP FO=1
45 00 001c 0008 0001 3f 11 0000 01010101 02010101
0000000000000000

View File

@ -0,0 +1,6 @@
in tcp 127.0.0.1,1 127.0.0.1,21
in tcp 1.1.1.1,1 1.2.1.1,21
in udp 127.0.0.1,1 127.0.0.1,21
in udp 1.1.1.1,1 1.2.1.1,21
in icmp 127.0.0.1 127.0.0.1
in icmp 1.1.1.1 1.2.1.1

View File

@ -0,0 +1,5 @@
in 127.0.0.1 127.0.0.1
in 1.1.1.1 1.2.1.1
in 1.1.1.2 1.2.1.1
in 1.1.2.2 1.2.1.1
in 1.2.2.2 1.2.1.1

View File

@ -0,0 +1,5 @@
in 127.0.0.1 127.0.0.1
in 1.1.1.1 1.1.1.1
in 1.1.1.1 1.1.1.2
in 1.1.1.1 1.1.2.2
in 1.1.1.1 1.2.2.2

View File

@ -0,0 +1,28 @@
in tcp 1.1.1.1,0 2.2.2.2,2222
in tcp 1.1.1.1,1 2.2.2.2,2222
in tcp 1.1.1.1,23 2.2.2.2,2222
in tcp 1.1.1.1,21 2.2.2.2,2222
in tcp 1.1.1.1,1023 2.2.2.2,2222
in tcp 1.1.1.1,1024 2.2.2.2,2222
in tcp 1.1.1.1,1025 2.2.2.2,2222
in tcp 1.1.1.1,32767 2.2.2.2,2222
in tcp 1.1.1.1,32768 2.2.2.2,2222
in tcp 1.1.1.1,65535 2.2.2.2,2222
in tcp 1.1.1.1,5999 2.2.2.2,2222
in tcp 1.1.1.1,6000 2.2.2.2,2222
in tcp 1.1.1.1,6009 2.2.2.2,2222
in tcp 1.1.1.1,6010 2.2.2.2,2222
in udp 1.1.1.1,0 2.2.2.2,2222
in udp 1.1.1.1,1 2.2.2.2,2222
in udp 1.1.1.1,23 2.2.2.2,2222
in udp 1.1.1.1,21 2.2.2.2,2222
in udp 1.1.1.1,1023 2.2.2.2,2222
in udp 1.1.1.1,1024 2.2.2.2,2222
in udp 1.1.1.1,1025 2.2.2.2,2222
in udp 1.1.1.1,32767 2.2.2.2,2222
in udp 1.1.1.1,32768 2.2.2.2,2222
in udp 1.1.1.1,65535 2.2.2.2,2222
in udp 1.1.1.1,5999 2.2.2.2,2222
in udp 1.1.1.1,6000 2.2.2.2,2222
in udp 1.1.1.1,6009 2.2.2.2,2222
in udp 1.1.1.1,6010 2.2.2.2,2222

View File

@ -0,0 +1,28 @@
in tcp 2.2.2.2,2222 1.1.1.1,0
in tcp 2.2.2.2,2222 1.1.1.1,1
in tcp 2.2.2.2,2222 1.1.1.1,23
in tcp 2.2.2.2,2222 1.1.1.1,21
in tcp 2.2.2.2,2222 1.1.1.1,1023
in tcp 2.2.2.2,2222 1.1.1.1,1024
in tcp 2.2.2.2,2222 1.1.1.1,1025
in tcp 2.2.2.2,2222 1.1.1.1,32767
in tcp 2.2.2.2,2222 1.1.1.1,32768
in tcp 2.2.2.2,2222 1.1.1.1,65535
in tcp 2.2.2.2,2222 1.1.1.1,5999
in tcp 2.2.2.2,2222 1.1.1.1,6000
in tcp 2.2.2.2,2222 1.1.1.1,6009
in tcp 2.2.2.2,2222 1.1.1.1,6010
in udp 2.2.2.2,2222 1.1.1.1,0
in udp 2.2.2.2,2222 1.1.1.1,1
in udp 2.2.2.2,2222 1.1.1.1,23
in udp 2.2.2.2,2222 1.1.1.1,21
in udp 2.2.2.2,2222 1.1.1.1,1023
in udp 2.2.2.2,2222 1.1.1.1,1024
in udp 2.2.2.2,2222 1.1.1.1,1025
in udp 2.2.2.2,2222 1.1.1.1,32767
in udp 2.2.2.2,2222 1.1.1.1,32768
in udp 2.2.2.2,2222 1.1.1.1,65535
in udp 2.2.2.2,2222 1.1.1.1,5999
in udp 2.2.2.2,2222 1.1.1.1,6000
in udp 2.2.2.2,2222 1.1.1.1,6009
in udp 2.2.2.2,2222 1.1.1.1,6010

View File

@ -0,0 +1,9 @@
in icmp 1.1.1.1 2.1.1.1 echo
in icmp 1.1.1.1 2.1.1.1 echo,1
in icmp 1.1.1.1 2.1.1.1 echo,3
in icmp 1.1.1.1 2.1.1.1 unreach
in icmp 1.1.1.1 2.1.1.1 unreach,1
in icmp 1.1.1.1 2.1.1.1 unreach,3
in icmp 1.1.1.1 2.1.1.1 echorep
in icmp 1.1.1.1 2.1.1.1 echorep,1
in icmp 1.1.1.1 2.1.1.1 echorep,3

View File

@ -0,0 +1,6 @@
in tcp 1.1.1.1,1 2.1.2.2,1 S
in tcp 1.1.1.1,1 2.1.2.2,1 SA
in tcp 1.1.1.1,1 2.1.2.2,1 SF
in tcp 1.1.1.1,1 2.1.2.2,1 SFPAUR
in tcp 1.1.1.1,1 2.1.2.2,1 PAU
in tcp 1.1.1.1,1 2.1.2.2,1 A

View File

@ -0,0 +1,6 @@
in 1.1.1.1 2.1.1.1 opt lsrr
in 1.1.1.1 2.1.1.1 opt lsrr,ssrr
in 1.1.1.1 2.1.1.1 opt ts
in 1.1.1.1 2.1.1.1 opt sec-class=topsecret
in 1.1.1.1 2.1.1.1 opt ssrr,sec-class=topsecret
in 1.1.1.1 2.1.1.1 opt sec

View File

@ -0,0 +1,21 @@
#!/bin/sh
if [ -f /usr/ucb/touch ] ; then
TOUCH=/usr/ucb/touch
else
if [ -f /usr/bin/touch ] ; then
TOUCH=/usr/bin/touch
else
if [ -f /bin/touch ] ; then
TOUCH=/bin/touch
fi
fi
fi
echo "$1...";
/bin/cp /dev/null results/$1
../ipf -nvf regress/$1 2>/dev/null > results/$1
cmp expected/$1 results/$1
status=$?
if [ $status = 0 ] ; then
$TOUCH $1
fi
exit $status

View File

@ -0,0 +1,4 @@
block in all
pass in all
block out all
pass out all

View File

@ -0,0 +1,18 @@
block in from any to any and not ipopts
pass in from any to any and not opt sec-class topsecret
block in from any to any and not opt ssrr,sec-class topsecret
pass in from any to any and not opt ssrr,sec-class topsecret
block in from any to any and not opt ts,sec-class topsecret
pass in from any to any and not opt ts,sec-class topsecret
block in from any to any and not opt sec-class secret
pass in from any to any and not opt sec-class secret
block in from any to any and not opt lsrr,ssrr
pass in from any to any and not opt lsrr,ssrr
pass in from any to any and not ipopts
block in from any to any and not opt lsrr
pass in from any to any and not opt lsrr
block in from any to any and not opt ssrr,ts
pass in from any to any and not opt ssrr,ts
block in from any to any and not opt rr
pass in from any to any and not opt rr
block in from any to any and not opt sec-class topsecret

View File

@ -0,0 +1,6 @@
pass in proto tcp from any to any port = 23 flags S/SA keep state
block in proto tcp from any to any port = 23 flags S/SA keep state
pass in proto udp from any to any port = 53 keep frags
block in proto udp from any to any port = 53 keep frags
pass in proto udp from any to any port = 53 keep state
block in proto udp from any to any port = 53 keep state

View File

@ -0,0 +1,6 @@
pass in proto tcp from any port > 1024 to any port = 25 with not short
pass in proto tcp from any port > 1024 to any port = 25
block in proto tcp from any to any with short
block in proto tcp from any to any with frag
pass in proto udp from any port = 53 to any port = 53
block in proto udp from any port = 53 to any port = 53 with not short

View File

@ -0,0 +1,6 @@
pass in proto tcp from any to any port = 25 flags S/SA keep frags
block in proto tcp from any to any port = 25 flags S/SA keep frags
pass in proto udp from any to any port = 53 keep frags
block in proto udp from any to any port = 53 keep frags
pass in proto tcp from any to any port = 25 flags S/SA keep state keep frags
block in proto tcp from any to any port = 25 flags S/SA keep state keep frags

View File

@ -0,0 +1,6 @@
block in proto tcp from any to any
pass in proto tcp from any to any
block in proto udp from any to any
pass in proto udp from any to any
block in proto icmp from any to any
pass in proto icmp from any to any

View File

@ -0,0 +1,8 @@
block in from 1.1.1.1 to any
pass in from 1.1.1.1 to any
block in from 1.1.1.1/24 to any
pass in from 1.1.1.1/24 to any
block in from 1.1.1.1/16 to any
pass in from 1.1.1.1/16 to any
block in from 1.1.1.1/0 to any
pass in from 1.1.1.1/0 to any

View File

@ -0,0 +1,8 @@
block in from any to 1.1.1.1
pass in from any to 1.1.1.1
block in from any to 1.1.1.1/24
pass in from any to 1.1.1.1/24
block in from any to 1.1.1.1/16
pass in from any to 1.1.1.1/16
block in from any to 1.1.1.1/0
pass in from any to 1.1.1.1/0

View File

@ -0,0 +1,48 @@
block in proto tcp from any port = 23 to any
block in proto udp from any port = 23 to any
block in proto tcp/udp from any port = 23 to any
pass in proto tcp from any port <= 1023 to any
pass in proto udp from any port <= 1023 to any
pass in proto tcp/udp from any port <= 1023 to any
block in proto tcp from any port >= 1024 to any
block in proto udp from any port >= 1024 to any
block in proto tcp/udp from any port >= 1024 to any
pass in proto tcp from any port >= 1024 to any
pass in proto udp from any port >= 1024 to any
pass in proto tcp/udp from any port >= 1024 to any
block in proto tcp from any port 0 >< 512 to any
block in proto udp from any port 0 >< 512 to any
block in proto tcp/udp from any port 0 >< 512 to any
pass in proto tcp from any port 0 >< 512 to any
pass in proto udp from any port 0 >< 512 to any
pass in proto tcp/udp from any port 0 >< 512 to any
block in proto tcp from any port 6000 <> 6009 to any
block in proto udp from any port 6000 <> 6009 to any
block in proto tcp/udp from any port 6000 <> 6009 to any
pass in proto tcp from any port 6000 <> 6009 to any
pass in proto udp from any port 6000 <> 6009 to any
pass in proto tcp/udp from any port 6000 <> 6009 to any
pass in proto tcp from any port = 23 to any
pass in proto udp from any port = 23 to any
pass in proto tcp/udp from any port = 23 to any
block in proto tcp from any port != 21 to any
block in proto udp from any port != 21 to any
block in proto tcp/udp from any port != 21 to any
pass in proto tcp from any port != 21 to any
pass in proto udp from any port != 21 to any
pass in proto tcp/udp from any port != 21 to any
block in proto tcp from any port < 1024 to any
block in proto udp from any port < 1024 to any
block in proto tcp/udp from any port < 1024 to any
pass in proto tcp from any port < 1024 to any
pass in proto udp from any port < 1024 to any
pass in proto tcp/udp from any port < 1024 to any
block in proto tcp from any port > 1023 to any
block in proto udp from any port > 1023 to any
block in proto tcp/udp from any port > 1023 to any
pass in proto tcp from any port > 1023 to any
pass in proto udp from any port > 1023 to any
pass in proto tcp/udp from any port > 1023 to any
block in proto tcp from any port <= 1023 to any
block in proto udp from any port <= 1023 to any
block in proto tcp/udp from any port <= 1023 to any

View File

@ -0,0 +1,48 @@
block in proto tcp from any to any port = 23
block in proto udp from any to any port = 23
block in proto tcp/udp from any to any port = 23
pass in proto tcp from any to any port <= 1023
pass in proto udp from any to any port <= 1023
pass in proto tcp/udp from any to any port <= 1023
block in proto tcp from any to any port >= 1024
block in proto udp from any to any port >= 1024
block in proto tcp/udp from any to any port >= 1024
pass in proto tcp from any to any port >= 1024
pass in proto udp from any to any port >= 1024
pass in proto tcp/udp from any to any port >= 1024
block in proto tcp from any to any port 0 >< 512
block in proto udp from any to any port 0 >< 512
block in proto tcp/udp from any to any port 0 >< 512
pass in proto tcp from any to any port 0 >< 512
pass in proto udp from any to any port 0 >< 512
pass in proto tcp/udp from any to any port 0 >< 512
block in proto tcp from any to any port 6000 <> 6009
block in proto udp from any to any port 6000 <> 6009
block in proto tcp/udp from any to any port 6000 <> 6009
pass in proto tcp from any to any port 6000 <> 6009
pass in proto udp from any to any port 6000 <> 6009
pass in proto tcp/udp from any to any port 6000 <> 6009
pass in proto tcp from any to any port = 23
pass in proto udp from any to any port = 23
pass in proto tcp/udp from any to any port = 23
block in proto tcp from any to any port != 21
block in proto udp from any to any port != 21
block in proto tcp/udp from any to any port != 21
pass in proto tcp from any to any port != 21
pass in proto udp from any to any port != 21
pass in proto tcp/udp from any to any port != 21
block in proto tcp from any to any port < 1024
block in proto udp from any to any port < 1024
block in proto tcp/udp from any to any port < 1024
pass in proto tcp from any to any port < 1024
pass in proto udp from any to any port < 1024
pass in proto tcp/udp from any to any port < 1024
block in proto tcp from any to any port > 1023
block in proto udp from any to any port > 1023
block in proto tcp/udp from any to any port > 1023
pass in proto tcp from any to any port > 1023
pass in proto udp from any to any port > 1023
pass in proto tcp/udp from any to any port > 1023
block in proto tcp from any to any port <= 1023
block in proto udp from any to any port <= 1023
block in proto tcp/udp from any to any port <= 1023

View File

@ -0,0 +1,6 @@
block in proto icmp from any to any icmp-type echo
pass in proto icmp from any to any icmp-type echo
block in proto icmp from any to any icmp-type unreach code 3
pass in proto icmp from any to any icmp-type unreach code 3
block in proto icmp from any to any icmp-type echorep
pass in proto icmp from any to any icmp-type echorep

View File

@ -0,0 +1,6 @@
block in proto tcp from any to any flags S
pass in proto tcp from any to any flags S
block in proto tcp from any to any flags S/SA
pass in proto tcp from any to any flags S/SA
block in proto tcp from any to any flags S/APU
pass in proto tcp from any to any flags S/APU

View File

@ -0,0 +1,18 @@
block in from any to any with ipopts
pass in from any to any with opt sec-class topsecret
block in from any to any with opt ssrr,sec-class topsecret
pass in from any to any with opt ssrr,sec-class topsecret
block in from any to any with opt ts,sec-class topsecret
pass in from any to any with opt ts,sec-class topsecret
block in from any to any with opt sec-class secret
pass in from any to any with opt sec-class secret
block in from any to any with opt lsrr,ssrr
pass in from any to any with opt lsrr,ssrr
pass in from any to any with ipopts
block in from any to any with opt lsrr
pass in from any to any with opt lsrr
block in from any to any with opt ssrr,ts
pass in from any to any with opt ssrr,ts
block in from any to any with opt rr
pass in from any to any with opt rr
block in from any to any with opt sec-class topsecret

View File

@ -0,0 +1,11 @@
pass in all
block out all
log in all
log body in all
count in from any to any
pass in on ed0 from localhost to localhost
block in log first on lo0 from any to any
pass in log body quick from any to any
block return-rst in quick on le0 proto tcp from any to any
block return-icmp in on qe0 from any to any
block return-icmp(1) in on qe0 from any to any

View File

@ -0,0 +1,4 @@
pass in from localhost to localhost with opt sec
block in from any to any with not opt sec-class topsecret
block in from any to any with not opt sec-class topsecret,secret
pass in from any to any with opt sec-class topsecret,confid not opt sec-class unclass

View File

@ -0,0 +1,4 @@
pass in on ed0 proto tcp from localhost to localhost port = telnet keep state
block in log first on lo0 proto tcp/udp from any to any keep state
pass in proto udp from localhost to localhost port = 2049 keep frags
pass in proto udp from localhost to localhost port = 53 keep state keep frags

View File

@ -0,0 +1,6 @@
log in proto tcp all
pass in proto 6 from any to any
pass in proto udp from localhost to localhost
block in proto 17 from any to any
block in proto 250 from any to any
pass in proto tcp/udp from any to any

View File

@ -0,0 +1,8 @@
log in all
pass in from 128.0.0.1/24 to 128.0.0.1/16
pass in from 128.0.0.1/0xffffff00 to 128.0.0.1/0xffff0000
pass in from 128.0.0.1/255.255.255.0 to 128.0.0.1/255.255.0.0
pass in from 128.0.0.1 mask 0xffffff00 to 128.0.0.1 mask 0xffff0000
pass in from 128.0.0.1 mask 255.255.255.0 to 128.0.0.1 mask 255.255.0.0
pass in from localhost to localhost
block in log from 0/0 to 0/0

View File

@ -0,0 +1,7 @@
log in proto tcp from any port > 0 to any
log in proto tcp from any to any port > 0
pass in proto 6 from any port != 0 to any port 0 >< 65535
pass in proto 17 from localhost port > 32000 to localhost port < 29000
block in proto udp from any port != ntp to any port < ntp
block in proto tcp from any port = smtp to any port > 25
pass in proto tcp/udp from any port 1 >< 3 to any port 1 <> 3

View File

@ -0,0 +1,5 @@
log in all
count in tos 0x80 from any to any
pass in on ed0 tos 64 from localhost to localhost
block in log on lo0 ttl 0 from any to any
pass in quick ttl 1 from any to any

View File

@ -0,0 +1,4 @@
pass in on lo0 fastroute from any to any
pass in on lo0 dup-to qe0 from localhost to localhost
pass in on qe0 dup-to qe0:127.0.0.1 from localhost to localhost
block in quick on qe0 to qe1 from any to any

View File

@ -0,0 +1,3 @@
pass in on ed0 proto tcp from localhost to localhost port = 23 flags S/SA
block in on lo0 proto tcp from any to any flags A
pass in on lo0 proto tcp from any to any flags /SAP

View File

@ -0,0 +1,2 @@
pass in proto icmp from localhost to localhost icmp-type timest
block in proto icmp from any to any icmp-type unreach code 1

View File

@ -0,0 +1,5 @@
pass in from localhost to localhost with short
block in from any to any with ipopts
pass in from any to any with opt nop,rr,zsu
pass in from any to any with opt nop,rr,zsu not opt ssrr,lsrr
pass in from localhost to localhost with not frag

View File

@ -0,0 +1,6 @@
Ç . Ä..0þ CVSGexpected0ÇinputDG$regress

.cvsignore
!Makefile
"dotest
#hextest

View File

@ -1,7 +1,8 @@
# $NetBSD: Makefile,v 1.1.1.1 1997/01/05 13:09:04 mrg Exp $
# $NetBSD: Makefile,v 1.1.1.2 1997/03/29 02:49:46 darrenr Exp $
PROG= ipmon
MAN= ipmon.8
CFLAGS+= -DLOGFAC=LOG_LOCAL0 -I${.CURDIR}/../../../sbin/ipf
CFLAGS+= -DLOGFAC=LOG_LOCAL0 -I${.CURDIR}/../../sbin/ipf
.PATH: .${CURDIR}/../../sbin/ipf
.include <bsd.prog.mk>

View File

@ -1,9 +1,9 @@
# $NetBSD: Makefile,v 1.1.1.1 1997/01/05 13:09:04 mrg Exp $
# $NetBSD: Makefile,v 1.1.1.2 1997/03/29 02:50:04 darrenr Exp $
PROG= ipnat
SRCS= kmem.c ipnat.c
MAN= ipnat.8 ipnat.4 ipnat.5
CFLAGS+= -I${.CURDIR}/../../../sbin/ipf -I${.CURDIR}/../ipfstat
CFLAGS+= -I${.CURDIR}/../../sbin/ipf -I${.CURDIR}/../ipfstat
.PATH: ${.CURDIR}/../ipfstat
.PATH: ${.CURDIR}/../../sbin/ipf ${.CURDIR}/../ipfstat
.include <bsd.prog.mk>

View File

@ -4,7 +4,7 @@ ipnat \- user interface to the NAT
.SH SYNOPSIS
.B ipnat
[
.B \-lnrsv
.B \-lnrsvCF
]
.B \-f <\fIfilename\fP>
.SH DESCRIPTION
@ -18,6 +18,13 @@ Rules are added to the end of the internal lists, matching the order in
which they appear when given to \fBipnat\fP.
.SH OPTIONS
.TP
.B \-C
delete all entries in the current NAT listing (NAT rules)
.TP
.B \-F
delete all active entries in the current NAT table (currently active
NAT mappings)
.TP
.B \-l
Show the list of current NAT table entry mappings.
.TP