summaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
authorru <ru@FreeBSD.org>2001-06-18 15:54:04 +0000
committerru <ru@FreeBSD.org>2001-06-18 15:54:04 +0000
commit227ce6056bd3de96b51fd863a66296fc54c951b4 (patch)
treee8fc4082f747ca16466b1b6882edd1603261c931 /contrib
parent9d7cdee0caf49f464694398c5b692df5cb6eb3b1 (diff)
downloadFreeBSD-src-227ce6056bd3de96b51fd863a66296fc54c951b4.zip
FreeBSD-src-227ce6056bd3de96b51fd863a66296fc54c951b4.tar.gz
Removed duplicate copies of files already present in sys/contrib/ipfilter.
Not objected to by: -arch
Diffstat (limited to 'contrib')
-rw-r--r--contrib/ipfilter/fil.c2125
-rw-r--r--contrib/ipfilter/ip_auth.c550
-rw-r--r--contrib/ipfilter/ip_auth.h62
-rw-r--r--contrib/ipfilter/ip_compat.h1012
-rw-r--r--contrib/ipfilter/ip_fil.c1758
-rw-r--r--contrib/ipfilter/ip_fil.h631
-rw-r--r--contrib/ipfilter/ip_frag.c555
-rw-r--r--contrib/ipfilter/ip_frag.h66
-rw-r--r--contrib/ipfilter/ip_ftp_pxy.c786
-rw-r--r--contrib/ipfilter/ip_log.c502
-rw-r--r--contrib/ipfilter/ip_nat.c2737
-rw-r--r--contrib/ipfilter/ip_nat.h307
-rw-r--r--contrib/ipfilter/ip_proxy.c451
-rw-r--r--contrib/ipfilter/ip_proxy.h156
-rw-r--r--contrib/ipfilter/ip_raudio_pxy.c308
-rw-r--r--contrib/ipfilter/ip_rcmd_pxy.c173
-rw-r--r--contrib/ipfilter/ip_state.c1901
-rw-r--r--contrib/ipfilter/ip_state.h195
-rw-r--r--contrib/ipfilter/ipl.h17
-rw-r--r--contrib/ipfilter/mlfk_ipl.c197
20 files changed, 0 insertions, 14489 deletions
diff --git a/contrib/ipfilter/fil.c b/contrib/ipfilter/fil.c
deleted file mode 100644
index 2315a93..0000000
--- a/contrib/ipfilter/fil.c
+++ /dev/null
@@ -1,2125 +0,0 @@
-/*
- * Copyright (C) 1993-2000 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)
-static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$FreeBSD$";
-#endif
-
-#include <sys/errno.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/file.h>
-#if defined(__NetBSD__) && (NetBSD >= 199905) && !defined(IPFILTER_LKM) && \
- defined(_KERNEL)
-# include "opt_ipfilter_log.h"
-#endif
-#if (defined(KERNEL) || defined(_KERNEL)) && defined(__FreeBSD_version) && \
- (__FreeBSD_version >= 220000)
-# if (__FreeBSD_version >= 400000)
-# ifndef KLD_MODULE
-# include "opt_inet6.h"
-# endif
-# if (__FreeBSD_version == 400019)
-# define CSUM_DELAY_DATA
-# endif
-# endif
-# include <sys/filio.h>
-# include <sys/fcntl.h>
-#else
-# include <sys/ioctl.h>
-#endif
-#if (defined(_KERNEL) || defined(KERNEL)) && !defined(linux)
-# include <sys/systm.h>
-#else
-# include <stdio.h>
-# include <string.h>
-# include <stdlib.h>
-#endif
-#include <sys/uio.h>
-#if !defined(__SVR4) && !defined(__svr4__)
-# ifndef linux
-# include <sys/mbuf.h>
-# endif
-#else
-# include <sys/byteorder.h>
-# if SOLARIS2 < 5
-# include <sys/dditypes.h>
-# endif
-# include <sys/stream.h>
-#endif
-#ifndef linux
-# include <sys/protosw.h>
-# include <sys/socket.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>
-#ifndef linux
-# include <netinet/ip_var.h>
-#endif
-#if defined(__sgi) && defined(IFF_DRVRLOCK) /* IRIX 6 */
-# include <sys/hashing.h>
-# include <netinet/in_var.h>
-#endif
-#include <netinet/tcp.h>
-#include <netinet/udp.h>
-#include <netinet/ip_icmp.h>
-#include "netinet/ip_compat.h"
-#ifdef USE_INET6
-# include <netinet/icmp6.h>
-# if !SOLARIS && defined(_KERNEL)
-# include <netinet6/in6_var.h>
-# endif
-#endif
-#include <netinet/tcpip.h>
-#include "netinet/ip_fil.h"
-#include "netinet/ip_proxy.h"
-#include "netinet/ip_nat.h"
-#include "netinet/ip_frag.h"
-#include "netinet/ip_state.h"
-#include "netinet/ip_auth.h"
-# if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
-# include <sys/malloc.h>
-# if defined(_KERNEL) && !defined(IPFILTER_LKM)
-# include "opt_ipfilter.h"
-# endif
-# endif
-#ifndef MIN
-# define MIN(a,b) (((a)<(b))?(a):(b))
-#endif
-#include "netinet/ipl.h"
-
-#ifndef _KERNEL
-# include "ipf.h"
-# include "ipt.h"
-extern int opts;
-
-# define FR_VERBOSE(verb_pr) verbose verb_pr
-# define FR_DEBUG(verb_pr) debug verb_pr
-# define IPLLOG(a, c, d, e) ipllog()
-#else /* #ifndef _KERNEL */
-# define FR_VERBOSE(verb_pr)
-# define FR_DEBUG(verb_pr)
-# define IPLLOG(a, c, d, e) ipflog(a, c, d, e)
-# if SOLARIS || defined(__sgi)
-extern KRWLOCK_T ipf_mutex, ipf_auth, ipf_nat;
-extern kmutex_t ipf_rw;
-# endif
-# if SOLARIS
-# define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, \
- ip, qif)
-# else /* SOLARIS */
-# define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, ip)
-# endif /* SOLARIS || __sgi */
-#endif /* _KERNEL */
-
-
-struct filterstats frstats[2] = {{0,0,0,0,0},{0,0,0,0,0}};
-struct frentry *ipfilter[2][2] = { { NULL, NULL }, { NULL, NULL } },
-#ifdef USE_INET6
- *ipfilter6[2][2] = { { NULL, NULL }, { NULL, NULL } },
- *ipacct6[2][2] = { { NULL, NULL }, { NULL, NULL } },
-#endif
- *ipacct[2][2] = { { NULL, NULL }, { NULL, NULL } };
-struct frgroup *ipfgroups[3][2];
-int fr_flags = IPF_LOGGING;
-int fr_active = 0;
-int fr_chksrc = 0;
-int fr_minttl = 3;
-int fr_minttllog = 1;
-#if defined(IPFILTER_DEFAULT_BLOCK)
-int fr_pass = FR_NOMATCH|FR_BLOCK;
-#else
-int fr_pass = (IPF_DEFAULT_PASS|FR_NOMATCH);
-#endif
-char ipfilter_version[] = IPL_VERSION;
-
-fr_info_t frcache[2];
-
-static int frflushlist __P((int, minor_t, int *, frentry_t **));
-#ifdef _KERNEL
-static void frsynclist __P((frentry_t *));
-#endif
-
-
-/*
- * bit values for identifying presence of individual IP options
- */
-struct optlist ipopts[20] = {
- { IPOPT_NOP, 0x000001 },
- { IPOPT_RR, 0x000002 },
- { IPOPT_ZSU, 0x000004 },
- { IPOPT_MTUP, 0x000008 },
- { IPOPT_MTUR, 0x000010 },
- { IPOPT_ENCODE, 0x000020 },
- { IPOPT_TS, 0x000040 },
- { IPOPT_TR, 0x000080 },
- { IPOPT_SECURITY, 0x000100 },
- { IPOPT_LSRR, 0x000200 },
- { IPOPT_E_SEC, 0x000400 },
- { IPOPT_CIPSO, 0x000800 },
- { IPOPT_SATID, 0x001000 },
- { IPOPT_SSRR, 0x002000 },
- { IPOPT_ADDEXT, 0x004000 },
- { IPOPT_VISA, 0x008000 },
- { IPOPT_IMITD, 0x010000 },
- { IPOPT_EIP, 0x020000 },
- { IPOPT_FINN, 0x040000 },
- { 0, 0x000000 }
-};
-
-/*
- * bit values for identifying presence of individual IP security options
- */
-struct optlist secopt[8] = {
- { IPSO_CLASS_RES4, 0x01 },
- { IPSO_CLASS_TOPS, 0x02 },
- { IPSO_CLASS_SECR, 0x04 },
- { IPSO_CLASS_RES3, 0x08 },
- { IPSO_CLASS_CONF, 0x10 },
- { IPSO_CLASS_UNCL, 0x20 },
- { IPSO_CLASS_RES2, 0x40 },
- { IPSO_CLASS_RES1, 0x80 }
-};
-
-
-/*
- * compact the IP header into a structure which contains just the info.
- * which is useful for comparing IP headers with.
- */
-void fr_makefrip(hlen, ip, fin)
-int hlen;
-ip_t *ip;
-fr_info_t *fin;
-{
- u_short optmsk = 0, secmsk = 0, auth = 0;
- int i, mv, ol, off, p, plen, v;
- fr_ip_t *fi = &fin->fin_fi;
- struct optlist *op;
- u_char *s, opt;
- tcphdr_t *tcp;
-
- fin->fin_rev = 0;
- fin->fin_fr = NULL;
- fin->fin_tcpf = 0;
- fin->fin_data[0] = 0;
- fin->fin_data[1] = 0;
- fin->fin_rule = -1;
- fin->fin_group = -1;
-#ifdef _KERNEL
- fin->fin_icode = ipl_unreach;
-#endif
- v = fin->fin_v;
- fi->fi_v = v;
- fin->fin_hlen = hlen;
- if (v == 4) {
- fin->fin_id = ip->ip_id;
- fi->fi_tos = ip->ip_tos;
- off = (ip->ip_off & IP_OFFMASK) << 3;
- tcp = (tcphdr_t *)((char *)ip + hlen);
- (*(((u_short *)fi) + 1)) = (*(((u_short *)ip) + 4));
- fi->fi_src.i6[1] = 0;
- fi->fi_src.i6[2] = 0;
- fi->fi_src.i6[3] = 0;
- fi->fi_dst.i6[1] = 0;
- fi->fi_dst.i6[2] = 0;
- fi->fi_dst.i6[3] = 0;
- fi->fi_saddr = ip->ip_src.s_addr;
- fi->fi_daddr = ip->ip_dst.s_addr;
- p = ip->ip_p;
- fi->fi_fl = (hlen > sizeof(ip_t)) ? FI_OPTIONS : 0;
- if (ip->ip_off & 0x3fff)
- fi->fi_fl |= FI_FRAG;
- plen = ip->ip_len;
- fin->fin_dlen = plen - hlen;
- }
-#ifdef USE_INET6
- else if (v == 6) {
- ip6_t *ip6 = (ip6_t *)ip;
-
- off = 0;
- p = ip6->ip6_nxt;
- fi->fi_p = p;
- fi->fi_ttl = ip6->ip6_hlim;
- tcp = (tcphdr_t *)(ip6 + 1);
- fi->fi_src.in6 = ip6->ip6_src;
- fi->fi_dst.in6 = ip6->ip6_dst;
- fin->fin_id = (u_short)(ip6->ip6_flow & 0xffff);
- fi->fi_tos = 0;
- fi->fi_fl = 0;
- plen = ntohs(ip6->ip6_plen);
- fin->fin_dlen = plen;
- }
-#endif
- else
- return;
-
- fin->fin_off = off;
- fin->fin_plen = plen;
- fin->fin_dp = (void *)tcp;
-
- switch (p)
- {
-#ifdef USE_INET6
- case IPPROTO_ICMPV6 :
- {
- int minicmpsz = sizeof(struct icmp6_hdr);
- struct icmp6_hdr *icmp6;
-
- if (fin->fin_dlen > 1) {
- fin->fin_data[0] = *(u_short *)tcp;
-
- icmp6 = (struct icmp6_hdr *)tcp;
-
- switch (icmp6->icmp6_type)
- {
- case ICMP6_ECHO_REPLY :
- case ICMP6_ECHO_REQUEST :
- minicmpsz = ICMP6ERR_MINPKTLEN;
- break;
- case ICMP6_DST_UNREACH :
- case ICMP6_PACKET_TOO_BIG :
- case ICMP6_TIME_EXCEEDED :
- case ICMP6_PARAM_PROB :
- minicmpsz = ICMP6ERR_IPICMPHLEN;
- break;
- default :
- break;
- }
- }
-
- if (!(plen >= hlen + minicmpsz))
- fi->fi_fl |= FI_SHORT;
-
- break;
- }
-#endif
- case IPPROTO_ICMP :
- {
- int minicmpsz = sizeof(struct icmp);
- icmphdr_t *icmp;
-
- if (!off && (fin->fin_dlen > 1)) {
- fin->fin_data[0] = *(u_short *)tcp;
-
- icmp = (icmphdr_t *)tcp;
-
- if (icmp->icmp_type == ICMP_ECHOREPLY ||
- icmp->icmp_type == ICMP_ECHO)
- minicmpsz = ICMP_MINLEN;
-
- /*
- * type(1) + code(1) + cksum(2) + id(2) seq(2) +
- * 3*timestamp(3*4)
- */
- else if (icmp->icmp_type == ICMP_TSTAMP ||
- icmp->icmp_type == ICMP_TSTAMPREPLY)
- minicmpsz = 20;
-
- /*
- * type(1) + code(1) + cksum(2) + id(2) seq(2) +
- * mask(4)
- */
- else if (icmp->icmp_type == ICMP_MASKREQ ||
- icmp->icmp_type == ICMP_MASKREPLY)
- minicmpsz = 12;
- }
-
- if ((!(plen >= hlen + minicmpsz) && !off) ||
- (off && off < sizeof(struct icmp)))
- fi->fi_fl |= FI_SHORT;
-
- break;
- }
- case IPPROTO_TCP :
- fi->fi_fl |= FI_TCPUDP;
-#ifdef USE_INET6
- if (v == 6) {
- if (plen < sizeof(struct tcphdr))
- fi->fi_fl |= FI_SHORT;
- } else
-#endif
- if (v == 4) {
- if ((!IPMINLEN(ip, tcphdr) && !off) ||
- (off && off < sizeof(struct tcphdr)))
- fi->fi_fl |= FI_SHORT;
- }
- if (!(fi->fi_fl & FI_SHORT) && !off)
- fin->fin_tcpf = tcp->th_flags;
- goto getports;
- case IPPROTO_UDP :
- fi->fi_fl |= FI_TCPUDP;
-#ifdef USE_INET6
- if (v == 6) {
- if (plen < sizeof(struct udphdr))
- fi->fi_fl |= FI_SHORT;
- } else
-#endif
- if (v == 4) {
- if ((!IPMINLEN(ip, udphdr) && !off) ||
- (off && off < sizeof(struct udphdr)))
- fi->fi_fl |= FI_SHORT;
- }
-getports:
- if (!off && (fin->fin_dlen > 3)) {
- fin->fin_data[0] = ntohs(tcp->th_sport);
- fin->fin_data[1] = ntohs(tcp->th_dport);
- }
- break;
- default :
- break;
- }
-
-#ifdef USE_INET6
- if (v == 6) {
- fi->fi_optmsk = 0;
- fi->fi_secmsk = 0;
- fi->fi_auth = 0;
- return;
- }
-#endif
-
- for (s = (u_char *)(ip + 1), hlen -= (int)sizeof(*ip); hlen > 0; ) {
- opt = *s;
- if (opt == '\0')
- break;
- else if (opt == IPOPT_NOP)
- ol = 1;
- else {
- if (hlen < 2)
- break;
- ol = (int)*(s + 1);
- if (ol < 2 || ol > hlen)
- break;
- }
- for (i = 9, mv = 4; mv >= 0; ) {
- op = ipopts + i;
- if (opt == (u_char)op->ol_val) {
- optmsk |= op->ol_bit;
- if (opt == IPOPT_SECURITY) {
- struct optlist *sp;
- u_char sec;
- int j, m;
-
- sec = *(s + 2); /* classification */
- for (j = 3, m = 2; m >= 0; ) {
- sp = secopt + j;
- if (sec == sp->ol_val) {
- secmsk |= sp->ol_bit;
- auth = *(s + 3);
- auth *= 256;
- auth += *(s + 4);
- break;
- }
- if (sec < sp->ol_val)
- j -= m--;
- else
- j += m--;
- }
- }
- break;
- }
- if (opt < op->ol_val)
- i -= mv--;
- else
- i += mv--;
- }
- hlen -= ol;
- s += ol;
- }
- if (auth && !(auth & 0x0100))
- auth &= 0xff00;
- fi->fi_optmsk = optmsk;
- fi->fi_secmsk = secmsk;
- fi->fi_auth = auth;
-}
-
-
-/*
- * check an IP packet for TCP/UDP characteristics such as ports and flags.
- */
-int fr_tcpudpchk(ft, fin)
-frtuc_t *ft;
-fr_info_t *fin;
-{
- register u_short po, tup;
- register char i;
- register int err = 1;
-
- /*
- * Both ports should *always* be in the first fragment.
- * So far, I cannot find any cases where they can not be.
- *
- * compare destination ports
- */
- if ((i = (int)ft->ftu_dcmp)) {
- po = ft->ftu_dport;
- tup = fin->fin_data[1];
- /*
- * Do opposite test to that required and
- * continue if that succeeds.
- */
- if (!--i && tup != po) /* EQUAL */
- err = 0;
- else if (!--i && tup == po) /* NOTEQUAL */
- err = 0;
- else if (!--i && tup >= po) /* LESSTHAN */
- err = 0;
- else if (!--i && tup <= po) /* GREATERTHAN */
- err = 0;
- else if (!--i && tup > po) /* LT or EQ */
- err = 0;
- else if (!--i && tup < po) /* GT or EQ */
- err = 0;
- else if (!--i && /* Out of range */
- (tup >= po && tup <= ft->ftu_dtop))
- err = 0;
- else if (!--i && /* In range */
- (tup <= po || tup >= ft->ftu_dtop))
- err = 0;
- }
- /*
- * compare source ports
- */
- if (err && (i = (int)ft->ftu_scmp)) {
- po = ft->ftu_sport;
- tup = fin->fin_data[0];
- if (!--i && tup != po)
- err = 0;
- else if (!--i && tup == po)
- err = 0;
- else if (!--i && tup >= po)
- err = 0;
- else if (!--i && tup <= po)
- err = 0;
- else if (!--i && tup > po)
- err = 0;
- else if (!--i && tup < po)
- err = 0;
- else if (!--i && /* Out of range */
- (tup >= po && tup <= ft->ftu_stop))
- err = 0;
- else if (!--i && /* In range */
- (tup <= po || tup >= ft->ftu_stop))
- err = 0;
- }
-
- /*
- * If we don't have all the TCP/UDP header, then how can we
- * expect to do any sort of match on it ? If we were looking for
- * TCP flags, then NO match. If not, then match (which should
- * satisfy the "short" class too).
- */
- if (err && (fin->fin_fi.fi_p == IPPROTO_TCP)) {
- if (fin->fin_fi.fi_fl & FI_SHORT)
- return !(ft->ftu_tcpf | ft->ftu_tcpfm);
- /*
- * Match the flags ? If not, abort this match.
- */
- if (ft->ftu_tcpfm &&
- ft->ftu_tcpf != (fin->fin_tcpf & ft->ftu_tcpfm)) {
- FR_DEBUG(("f. %#x & %#x != %#x\n", fin->fin_tcpf,
- ft->ftu_tcpfm, ft->ftu_tcpf));
- err = 0;
- }
- }
- return err;
-}
-
-/*
- * Check the input/output list of rules for a match and result.
- * Could be per interface, but this gets real nasty when you don't have
- * kernel sauce.
- */
-int fr_scanlist(pass, ip, fin, m)
-u_32_t pass;
-ip_t *ip;
-register fr_info_t *fin;
-void *m;
-{
- register struct frentry *fr;
- register fr_ip_t *fi = &fin->fin_fi;
- int rulen, portcmp = 0, off, skip = 0, logged = 0;
- u_32_t passt;
-
- fr = fin->fin_fr;
- fin->fin_fr = NULL;
- fin->fin_rule = 0;
- fin->fin_group = 0;
- if (fin->fin_v == 4)
- off = ip->ip_off & IP_OFFMASK;
- else
- off = 0;
- pass |= (fi->fi_fl << 24);
-
- if ((fi->fi_fl & FI_TCPUDP) && (fin->fin_dlen > 3) && !off)
- portcmp = 1;
-
- for (rulen = 0; fr; fr = fr->fr_next, rulen++) {
- if (skip) {
- skip--;
- continue;
- }
- /*
- * In all checks below, a null (zero) value in the
- * filter struture is taken to mean a wildcard.
- *
- * check that we are working for the right interface
- */
-#ifdef _KERNEL
-# if BSD >= 199306
- if (fin->fin_out != 0) {
- if ((fr->fr_oifa &&
- fr->fr_oifa != ((mb_t *)m)->m_pkthdr.rcvif) ||
- (fr->fr_ifa && fr->fr_ifa != fin->fin_ifp))
- continue;
- } else
-# endif
- if (fr->fr_ifa && fr->fr_ifa != fin->fin_ifp)
- continue;
-#else
- if (opts & (OPT_VERBOSE|OPT_DEBUG))
- printf("\n");
- FR_VERBOSE(("%c", (pass & FR_PASS) ? 'p' :
- (pass & FR_AUTH) ? 'a' : 'b'));
- if (fr->fr_ifa && fr->fr_ifa != fin->fin_ifp)
- continue;
- FR_VERBOSE((":i"));
-#endif
- {
- register u_32_t *ld, *lm, *lip;
- register int i;
-
- lip = (u_32_t *)fi;
- lm = (u_32_t *)&fr->fr_mip;
- ld = (u_32_t *)&fr->fr_ip;
- i = ((*lip & *lm) != *ld);
- FR_DEBUG(("0. %#08x & %#08x != %#08x\n",
- *lip, *lm, *ld));
- if (i)
- continue;
- /*
- * We now know whether the packet version and the
- * rule version match, along with protocol, ttl and
- * tos.
- */
- lip++, lm++, ld++;
- /*
- * Unrolled loops (4 each, for 32 bits).
- */
- i |= ((*lip & *lm) != *ld) << 19;
- FR_DEBUG(("1a. %#08x & %#08x != %#08x\n",
- *lip, *lm, *ld));
- if (fi->fi_v == 6) {
- lip++, lm++, ld++;
- i |= ((*lip & *lm) != *ld) << 19;
- FR_DEBUG(("1b. %#08x & %#08x != %#08x\n",
- *lip, *lm, *ld));
- lip++, lm++, ld++;
- i |= ((*lip & *lm) != *ld) << 19;
- FR_DEBUG(("1c. %#08x & %#08x != %#08x\n",
- *lip, *lm, *ld));
- lip++, lm++, ld++;
- i |= ((*lip & *lm) != *ld) << 19;
- FR_DEBUG(("1d. %#08x & %#08x != %#08x\n",
- *lip, *lm, *ld));
- } else {
- lip += 3;
- lm += 3;
- ld += 3;
- }
- i ^= (fr->fr_flags & FR_NOTSRCIP);
- if (i)
- continue;
- lip++, lm++, ld++;
- i |= ((*lip & *lm) != *ld) << 20;
- FR_DEBUG(("2a. %#08x & %#08x != %#08x\n",
- *lip, *lm, *ld));
- if (fi->fi_v == 6) {
- lip++, lm++, ld++;
- i |= ((*lip & *lm) != *ld) << 20;
- FR_DEBUG(("2b. %#08x & %#08x != %#08x\n",
- *lip, *lm, *ld));
- lip++, lm++, ld++;
- i |= ((*lip & *lm) != *ld) << 20;
- FR_DEBUG(("2c. %#08x & %#08x != %#08x\n",
- *lip, *lm, *ld));
- lip++, lm++, ld++;
- i |= ((*lip & *lm) != *ld) << 20;
- FR_DEBUG(("2d. %#08x & %#08x != %#08x\n",
- *lip, *lm, *ld));
- } else {
- lip += 3;
- lm += 3;
- ld += 3;
- }
- i ^= (fr->fr_flags & FR_NOTDSTIP);
- if (i)
- continue;
- lip++, lm++, ld++;
- i |= ((*lip & *lm) != *ld);
- FR_DEBUG(("3. %#08x & %#08x != %#08x\n",
- *lip, *lm, *ld));
- lip++, lm++, ld++;
- i |= ((*lip & *lm) != *ld);
- FR_DEBUG(("4. %#08x & %#08x != %#08x\n",
- *lip, *lm, *ld));
- if (i)
- continue;
- }
-
- /*
- * If a fragment, then only the first has what we're looking
- * for here...
- */
- if (!portcmp && (fr->fr_dcmp || fr->fr_scmp || fr->fr_tcpf ||
- fr->fr_tcpfm))
- continue;
- if (fi->fi_fl & FI_TCPUDP) {
- if (!fr_tcpudpchk(&fr->fr_tuc, fin))
- continue;
- } else if (fr->fr_icmpm || fr->fr_icmp) {
- if ((fi->fi_p != IPPROTO_ICMP) || off ||
- (fin->fin_dlen < 2))
- continue;
- if ((fin->fin_data[0] & fr->fr_icmpm) != fr->fr_icmp) {
- FR_DEBUG(("i. %#x & %#x != %#x\n",
- fin->fin_data[0], fr->fr_icmpm,
- fr->fr_icmp));
- continue;
- }
- }
- FR_VERBOSE(("*"));
- /*
- * Just log this packet...
- */
- passt = fr->fr_flags;
-#if (BSD >= 199306) && (defined(_KERNEL) || defined(KERNEL))
- if (securelevel <= 0)
-#endif
- if ((passt & FR_CALLNOW) && fr->fr_func)
- passt = (*fr->fr_func)(passt, ip, fin);
- fin->fin_fr = fr;
-#ifdef IPFILTER_LOG
- if ((passt & FR_LOGMASK) == FR_LOG) {
- if (!IPLLOG(passt, ip, fin, m)) {
- if (passt & FR_LOGORBLOCK)
- passt |= FR_BLOCK|FR_QUICK;
- ATOMIC_INCL(frstats[fin->fin_out].fr_skip);
- }
- ATOMIC_INCL(frstats[fin->fin_out].fr_pkl);
- logged = 1;
- }
-#endif /* IPFILTER_LOG */
- if (!(skip = fr->fr_skip) && (passt & FR_LOGMASK) != FR_LOG)
- pass = passt;
- FR_DEBUG(("pass %#x\n", pass));
- ATOMIC_INCL(fr->fr_hits);
- if (pass & FR_ACCOUNT)
- fr->fr_bytes += (U_QUAD_T)ip->ip_len;
- else
- fin->fin_icode = fr->fr_icode;
- fin->fin_rule = rulen;
- fin->fin_group = fr->fr_group;
- if (fr->fr_grp) {
- fin->fin_fr = fr->fr_grp;
- pass = fr_scanlist(pass, ip, fin, m);
- if (fin->fin_fr == NULL) {
- fin->fin_rule = rulen;
- fin->fin_group = fr->fr_group;
- fin->fin_fr = fr;
- }
- if (pass & FR_DONTCACHE)
- logged = 1;
- }
- if (pass & FR_QUICK)
- break;
- }
- if (logged)
- pass |= FR_DONTCACHE;
- return pass;
-}
-
-
-/*
- * frcheck - filter check
- * check using source and destination addresses/ports in a packet whether
- * or not to pass it on or not.
- */
-int fr_check(ip, hlen, ifp, out
-#if defined(_KERNEL) && SOLARIS
-, qif, mp)
-qif_t *qif;
-#else
-, mp)
-#endif
-mb_t **mp;
-ip_t *ip;
-int hlen;
-void *ifp;
-int out;
-{
- /*
- * The above really sucks, but short of writing a diff
- */
- fr_info_t frinfo, *fc;
- register fr_info_t *fin = &frinfo;
- int changed, error = EHOSTUNREACH, v = ip->ip_v;
- frentry_t *fr = NULL, *list;
- u_32_t pass, apass;
-#if !SOLARIS || !defined(_KERNEL)
- register mb_t *m = *mp;
-#endif
-
-#ifdef _KERNEL
- int p, len, drop = 0, logit = 0;
- mb_t *mc = NULL;
-# if !defined(__SVR4) && !defined(__svr4__)
-# ifdef __sgi
- char hbuf[(0xf << 2) + sizeof(struct icmp) + sizeof(ip_t) + 8];
-# endif
- int up;
-
-# ifdef M_CANFASTFWD
- /*
- * XXX For now, IP Filter and fast-forwarding of cached flows
- * XXX are mutually exclusive. Eventually, IP Filter should
- * XXX get a "can-fast-forward" filter rule.
- */
- m->m_flags &= ~M_CANFASTFWD;
-# endif /* M_CANFASTFWD */
-# ifdef CSUM_DELAY_DATA
- /*
- * disable delayed checksums.
- */
- if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
- in_delayed_cksum(m);
- m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
- }
-# endif /* CSUM_DELAY_DATA */
-
-# ifdef USE_INET6
- if (v == 6) {
- len = ntohs(((ip6_t*)ip)->ip6_plen);
- p = ((ip6_t *)ip)->ip6_nxt;
- } else
-# endif
- {
- p = ip->ip_p;
- len = ip->ip_len;
- }
-
- if ((p == IPPROTO_TCP || p == IPPROTO_UDP || p == IPPROTO_ICMP
-# ifdef USE_INET6
- || (v == 6 && p == IPPROTO_ICMPV6)
-# endif
- )) {
- int plen = 0;
-
- if ((v == 6) || (ip->ip_off & IP_OFFMASK) == 0)
- switch(p)
- {
- case IPPROTO_TCP:
- plen = sizeof(tcphdr_t);
- break;
- case IPPROTO_UDP:
- plen = sizeof(udphdr_t);
- break;
- /* 96 - enough for complete ICMP error IP header */
- case IPPROTO_ICMP:
- plen = ICMPERR_MAXPKTLEN - sizeof(ip_t);
- break;
-# ifdef USE_INET6
- case IPPROTO_ICMPV6 :
- /*
- * XXX does not take intermediate header
- * into account
- */
- plen = ICMP6ERR_MINPKTLEN + 8 - sizeof(ip6_t);
- break;
-# endif
- }
- up = MIN(hlen + plen, len);
-
- if (up > m->m_len) {
-# ifdef __sgi
- /* Under IRIX, avoid m_pullup as it makes ping <hostname> panic */
- if ((up > sizeof(hbuf)) || (m_length(m) < up)) {
- ATOMIC_INCL(frstats[out].fr_pull[1]);
- return -1;
- }
- m_copydata(m, 0, up, hbuf);
- ATOMIC_INCL(frstats[out].fr_pull[0]);
- ip = (ip_t *)hbuf;
-# else /* __ sgi */
-# ifndef linux
- if ((*mp = m_pullup(m, up)) == 0) {
- ATOMIC_INCL(frstats[out].fr_pull[1]);
- return -1;
- } else {
- ATOMIC_INCL(frstats[out].fr_pull[0]);
- m = *mp;
- ip = mtod(m, ip_t *);
- }
-# endif /* !linux */
-# endif /* __sgi */
- } else
- up = 0;
- } else
- up = 0;
-# endif /* !defined(__SVR4) && !defined(__svr4__) */
-# if SOLARIS
- mb_t *m = qif->qf_m;
-
- if ((u_int)ip & 0x3)
- return 2;
- fin->fin_qfm = m;
- fin->fin_qif = qif;
-# endif
-#endif /* _KERNEL */
-
- /*
- * Be careful here: ip_id is in network byte order when called
- * from ip_output()
- */
- if ((out) && (v == 4))
- ip->ip_id = ntohs(ip->ip_id);
-
- changed = 0;
- fin->fin_ifp = ifp;
- fin->fin_v = v;
- fin->fin_out = out;
- fin->fin_mp = mp;
- fr_makefrip(hlen, ip, fin);
-
-#ifdef _KERNEL
-# ifdef USE_INET6
- if (v == 6) {
- ATOMIC_INCL(frstats[0].fr_ipv6[out]);
- if (((ip6_t *)ip)->ip6_hlim < fr_minttl) {
- ATOMIC_INCL(frstats[0].fr_badttl);
- if (fr_minttllog)
- logit = -2;
- }
- } else
-# endif
- if (!out) {
- if (fr_chksrc && !fr_verifysrc(ip->ip_src, ifp)) {
- ATOMIC_INCL(frstats[0].fr_badsrc);
- if (fr_chksrc == 2)
- logit = -2;
- } else if (ip->ip_ttl < fr_minttl) {
- ATOMIC_INCL(frstats[0].fr_badttl);
- if (fr_minttllog)
- logit = -3;
- }
- }
- if (drop) {
-# ifdef IPFILTER_LOG
- if (logit) {
- fin->fin_group = logit;
- pass = FR_INQUE|FR_NOMATCH|FR_LOGB;
- (void) IPLLOG(pass, ip, fin, m);
- }
-# endif
-# if !SOLARIS
- m_freem(m);
-# endif
- return error;
- }
-#endif
- pass = fr_pass;
- if (fin->fin_fi.fi_fl & FI_SHORT) {
- ATOMIC_INCL(frstats[out].fr_short);
- }
-
- READ_ENTER(&ipf_mutex);
-
- if (fin->fin_fi.fi_fl & FI_SHORT)
- ATOMIC_INCL(frstats[out].fr_short);
-
- /*
- * Check auth now. This, combined with the check below to see if apass
- * is 0 is to ensure that we don't count the packet twice, which can
- * otherwise occur when we reprocess it. As it is, we only count it
- * after it has no auth. table matchup. This also stops NAT from
- * occuring until after the packet has been auth'd.
- */
- apass = fr_checkauth(ip, fin);
-
- if (!out) {
-#ifdef USE_INET6
- if (v == 6)
- list = ipacct6[0][fr_active];
- else
-#endif
- list = ipacct[0][fr_active];
- changed = ip_natin(ip, fin);
- if (!apass && (fin->fin_fr = list) &&
- (fr_scanlist(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT)) {
- ATOMIC_INCL(frstats[0].fr_acct);
- }
- }
-
- if (apass || (!(fr = ipfr_knownfrag(ip, fin)) &&
- !(fr = fr_checkstate(ip, fin)))) {
- /*
- * If a packet is found in the auth table, then skip checking
- * the access lists for permission but we do need to consider
- * the result as if it were from the ACL's.
- */
- if (!apass) {
- fc = frcache + out;
- if (!bcmp((char *)fin, (char *)fc, FI_CSIZE)) {
- /*
- * copy cached data so we can unlock the mutex
- * earlier.
- */
- bcopy((char *)fc, (char *)fin, FI_COPYSIZE);
- ATOMIC_INCL(frstats[out].fr_chit);
- if ((fr = fin->fin_fr)) {
- ATOMIC_INCL(fr->fr_hits);
- pass = fr->fr_flags;
- }
- } else {
-#ifdef USE_INET6
- if (v == 6)
- list = ipfilter6[out][fr_active];
- else
-#endif
- list = ipfilter[out][fr_active];
- if ((fin->fin_fr = list))
- pass = fr_scanlist(fr_pass, ip, fin, m);
- if (!(pass & (FR_KEEPSTATE|FR_DONTCACHE)))
- bcopy((char *)fin, (char *)fc,
- FI_COPYSIZE);
- if (pass & FR_NOMATCH) {
- ATOMIC_INCL(frstats[out].fr_nom);
- }
- }
- fr = fin->fin_fr;
- } else
- pass = apass;
-
- /*
- * If we fail to add a packet to the authorization queue,
- * then we drop the packet later. However, if it was added
- * then pretend we've dropped it already.
- */
- if ((pass & FR_AUTH))
- if (fr_newauth((mb_t *)m, fin, ip) != 0)
-#ifdef _KERNEL
- m = *mp = NULL;
-#else
- ;
-#endif
-
- if (pass & FR_PREAUTH) {
- READ_ENTER(&ipf_auth);
- if ((fin->fin_fr = ipauth) &&
- (pass = fr_scanlist(0, ip, fin, m))) {
- ATOMIC_INCL(fr_authstats.fas_hits);
- } else {
- ATOMIC_INCL(fr_authstats.fas_miss);
- }
- RWLOCK_EXIT(&ipf_auth);
- }
-
- fin->fin_fr = fr;
- if ((pass & (FR_KEEPFRAG|FR_KEEPSTATE)) == FR_KEEPFRAG) {
- if (fin->fin_fi.fi_fl & FI_FRAG) {
- if (ipfr_newfrag(ip, fin, pass) == -1) {
- ATOMIC_INCL(frstats[out].fr_bnfr);
- } else {
- ATOMIC_INCL(frstats[out].fr_nfr);
- }
- } else {
- ATOMIC_INCL(frstats[out].fr_cfr);
- }
- }
- if (pass & FR_KEEPSTATE) {
- if (fr_addstate(ip, fin, 0) == NULL) {
- ATOMIC_INCL(frstats[out].fr_bads);
- } else {
- ATOMIC_INCL(frstats[out].fr_ads);
- }
- }
- } else if (fr != NULL) {
- pass = fr->fr_flags;
- if (pass & FR_LOGFIRST)
- pass &= ~(FR_LOGFIRST|FR_LOG);
- }
-
-#if (BSD >= 199306) && (defined(_KERNEL) || defined(KERNEL))
- if (securelevel <= 0)
-#endif
- if (fr && fr->fr_func && !(pass & FR_CALLNOW))
- pass = (*fr->fr_func)(pass, ip, fin);
-
- /*
- * Only count/translate packets which will be passed on, out the
- * interface.
- */
- if (out && (pass & FR_PASS)) {
-#ifdef USE_INET6
- if (v == 6)
- list = ipacct6[1][fr_active];
- else
-#endif
- list = ipacct[1][fr_active];
- if ((fin->fin_fr = list) &&
- (fr_scanlist(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT)) {
- ATOMIC_INCL(frstats[1].fr_acct);
- }
- fin->fin_fr = fr;
- changed = ip_natout(ip, fin);
- } else
- fin->fin_fr = fr;
- RWLOCK_EXIT(&ipf_mutex);
-
-#ifdef IPFILTER_LOG
- if ((fr_flags & FF_LOGGING) || (pass & FR_LOGMASK)) {
- if ((fr_flags & FF_LOGNOMATCH) && (pass & FR_NOMATCH)) {
- pass |= FF_LOGNOMATCH;
- ATOMIC_INCL(frstats[out].fr_npkl);
- goto logit;
- } else if (((pass & FR_LOGMASK) == FR_LOGP) ||
- ((pass & FR_PASS) && (fr_flags & FF_LOGPASS))) {
- if ((pass & FR_LOGMASK) != FR_LOGP)
- pass |= FF_LOGPASS;
- ATOMIC_INCL(frstats[out].fr_ppkl);
- goto logit;
- } else if (((pass & FR_LOGMASK) == FR_LOGB) ||
- ((pass & FR_BLOCK) && (fr_flags & FF_LOGBLOCK))) {
- if ((pass & FR_LOGMASK) != FR_LOGB)
- pass |= FF_LOGBLOCK;
- ATOMIC_INCL(frstats[out].fr_bpkl);
-logit:
- if (!IPLLOG(pass, ip, fin, m)) {
- ATOMIC_INCL(frstats[out].fr_skip);
- if ((pass & (FR_PASS|FR_LOGORBLOCK)) ==
- (FR_PASS|FR_LOGORBLOCK))
- pass ^= FR_PASS|FR_BLOCK;
- }
- }
- }
-#endif /* IPFILTER_LOG */
-
- if ((out) && (v == 4))
- ip->ip_id = htons(ip->ip_id);
-
-#ifdef _KERNEL
- /*
- * Only allow FR_DUP to work if a rule matched - it makes no sense to
- * set FR_DUP as a "default" as there are no instructions about where
- * to send the packet.
- */
- if (fr && (pass & FR_DUP))
-# if SOLARIS
- mc = dupmsg(m);
-# else
-# ifndef linux
- mc = m_copy(m, 0, M_COPYALL);
-# else
- ;
-# endif
-# endif
-#endif
- if (pass & FR_PASS) {
- ATOMIC_INCL(frstats[out].fr_pass);
- } else if (pass & FR_BLOCK) {
- ATOMIC_INCL(frstats[out].fr_block);
- /*
- * Should we return an ICMP packet to indicate error
- * status passing through the packet filter ?
- * WARNING: ICMP error packets AND TCP RST packets should
- * ONLY be sent in repsonse to incoming packets. Sending them
- * in response to outbound packets can result in a panic on
- * some operating systems.
- */
- if (!out) {
-#ifdef _KERNEL
- if (pass & FR_RETICMP) {
- int dst;
-
- if ((pass & FR_RETMASK) == FR_FAKEICMP)
- dst = 1;
- else
- dst = 0;
- send_icmp_err(ip, ICMP_UNREACH, fin, dst);
- ATOMIC_INCL(frstats[0].fr_ret);
- } else if (((pass & FR_RETMASK) == FR_RETRST) &&
- !(fin->fin_fi.fi_fl & FI_SHORT)) {
- if (send_reset(ip, fin) == 0) {
- ATOMIC_INCL(frstats[1].fr_ret);
- }
- }
-#else
- if ((pass & FR_RETMASK) == FR_RETICMP) {
- verbose("- ICMP unreachable sent\n");
- ATOMIC_INCL(frstats[0].fr_ret);
- } else if ((pass & FR_RETMASK) == FR_FAKEICMP) {
- verbose("- forged ICMP unreachable sent\n");
- ATOMIC_INCL(frstats[0].fr_ret);
- } else if (((pass & FR_RETMASK) == FR_RETRST) &&
- !(fin->fin_fi.fi_fl & FI_SHORT)) {
- verbose("- TCP RST sent\n");
- ATOMIC_INCL(frstats[1].fr_ret);
- }
-#endif
- } else {
- if (pass & FR_RETRST)
- error = ECONNRESET;
- }
- }
-
- /*
- * If we didn't drop off the bottom of the list of rules (and thus
- * the 'current' rule fr is not NULL), then we may have some extra
- * instructions about what to do with a packet.
- * Once we're finished return to our caller, freeing the packet if
- * we are dropping it (* BSD ONLY *).
- */
- if ((changed == -1) && (pass & FR_PASS)) {
- pass &= ~FR_PASS;
- pass |= FR_BLOCK;
- }
-#if defined(_KERNEL)
-# if !SOLARIS
-# if !defined(linux)
- if (fr) {
- frdest_t *fdp = &fr->fr_tif;
-
- if (((pass & FR_FASTROUTE) && !out) ||
- (fdp->fd_ifp && fdp->fd_ifp != (struct ifnet *)-1)) {
- if (ipfr_fastroute(m, fin, fdp) == 0)
- m = *mp = NULL;
- }
- if (mc)
- ipfr_fastroute(mc, fin, &fr->fr_dif);
- }
- if (!(pass & FR_PASS) && m)
- m_freem(m);
-# ifdef __sgi
- else if (changed && up && m)
- m_copyback(m, 0, up, hbuf);
-# endif
-# endif /* !linux */
-# else /* !SOLARIS */
- if (fr) {
- frdest_t *fdp = &fr->fr_tif;
-
- if (((pass & FR_FASTROUTE) && !out) ||
- (fdp->fd_ifp && fdp->fd_ifp != (struct ifnet *)-1)) {
- if (ipfr_fastroute(ip, m, mp, fin, fdp) == 0)
- m = *mp = NULL;
- }
- if (mc)
- ipfr_fastroute(ip, mc, mp, fin, &fr->fr_dif);
- }
-# endif /* !SOLARIS */
- return (pass & FR_PASS) ? 0 : error;
-#else /* _KERNEL */
- if (pass & FR_NOMATCH)
- return 1;
- if (pass & FR_PASS)
- return 0;
- if (pass & FR_AUTH)
- return -2;
- return -1;
-#endif /* _KERNEL */
-}
-
-
-/*
- * ipf_cksum
- * addr should be 16bit aligned and len is in bytes.
- * length is in bytes
- */
-u_short ipf_cksum(addr, len)
-register u_short *addr;
-register int len;
-{
- register u_32_t sum = 0;
-
- for (sum = 0; len > 1; len -= 2)
- sum += *addr++;
-
- /* mop up an odd byte, if necessary */
- if (len == 1)
- sum += *(u_char *)addr;
-
- /*
- * add back carry outs from top 16 bits to low 16 bits
- */
- sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
- sum += (sum >> 16); /* add carry */
- return (u_short)(~sum);
-}
-
-
-/*
- * NB: This function assumes we've pullup'd enough for all of the IP header
- * and the TCP header. We also assume that data blocks aren't allocated in
- * odd sizes.
- */
-u_short fr_tcpsum(m, ip, tcp)
-mb_t *m;
-ip_t *ip;
-tcphdr_t *tcp;
-{
- u_short *sp, slen, ts;
- u_int sum, sum2;
- int hlen;
-
- /*
- * Add up IP Header portion
- */
- hlen = ip->ip_hl << 2;
- slen = ip->ip_len - hlen;
- sum = htons((u_short)ip->ip_p);
- sum += htons(slen);
- sp = (u_short *)&ip->ip_src;
- sum += *sp++; /* ip_src */
- sum += *sp++;
- sum += *sp++; /* ip_dst */
- sum += *sp++;
- ts = tcp->th_sum;
- tcp->th_sum = 0;
-#ifdef KERNEL
-# if SOLARIS
- sum2 = ip_cksum(m, hlen, sum); /* hlen == offset */
- sum2 = (sum2 & 0xffff) + (sum2 >> 16);
- sum2 = ~sum2 & 0xffff;
-# else /* SOLARIS */
-# if defined(BSD) || defined(sun)
-# if BSD >= 199306
- m->m_data += hlen;
-# else
- m->m_off += hlen;
-# endif
- m->m_len -= hlen;
- sum2 = in_cksum(m, slen);
- m->m_len += hlen;
-# if BSD >= 199306
- m->m_data -= hlen;
-# else
- m->m_off -= hlen;
-# endif
- /*
- * Both sum and sum2 are partial sums, so combine them together.
- */
- sum = (sum & 0xffff) + (sum >> 16);
- sum = ~sum & 0xffff;
- sum2 += sum;
- sum2 = (sum2 & 0xffff) + (sum2 >> 16);
-# else /* defined(BSD) || defined(sun) */
-{
- union {
- u_char c[2];
- u_short s;
- } bytes;
- u_short len = ip->ip_len;
-# if defined(__sgi)
- int add;
-# endif
-
- /*
- * Add up IP Header portion
- */
- sp = (u_short *)&ip->ip_src;
- len -= (ip->ip_hl << 2);
- sum = ntohs(IPPROTO_TCP);
- sum += htons(len);
- sum += *sp++; /* ip_src */
- sum += *sp++;
- sum += *sp++; /* ip_dst */
- sum += *sp++;
- if (sp != (u_short *)tcp)
- sp = (u_short *)tcp;
- sum += *sp++; /* sport */
- sum += *sp++; /* dport */
- sum += *sp++; /* seq */
- sum += *sp++;
- sum += *sp++; /* ack */
- sum += *sp++;
- sum += *sp++; /* off */
- sum += *sp++; /* win */
- sum += *sp++; /* Skip over checksum */
- sum += *sp++; /* urp */
-
-# ifdef __sgi
- /*
- * In case we had to copy the IP & TCP header out of mbufs,
- * skip over the mbuf bits which are the header
- */
- if ((caddr_t)ip != mtod(m, caddr_t)) {
- hlen = (caddr_t)sp - (caddr_t)ip;
- while (hlen) {
- add = MIN(hlen, m->m_len);
- sp = (u_short *)(mtod(m, caddr_t) + add);
- hlen -= add;
- if (add == m->m_len) {
- m = m->m_next;
- if (!hlen) {
- if (!m)
- break;
- sp = mtod(m, u_short *);
- }
- PANIC((!m),("fr_tcpsum(1): not enough data"));
- }
- }
- }
-# endif
-
- if (!(len -= sizeof(*tcp)))
- goto nodata;
- while (len > 1) {
- if (((caddr_t)sp - mtod(m, caddr_t)) >= m->m_len) {
- m = m->m_next;
- PANIC((!m),("fr_tcpsum(2): not enough data"));
- sp = mtod(m, u_short *);
- }
- if (((caddr_t)(sp + 1) - mtod(m, caddr_t)) > m->m_len) {
- bytes.c[0] = *(u_char *)sp;
- m = m->m_next;
- PANIC((!m),("fr_tcpsum(3): not enough data"));
- sp = mtod(m, u_short *);
- bytes.c[1] = *(u_char *)sp;
- sum += bytes.s;
- sp = (u_short *)((u_char *)sp + 1);
- }
- if ((u_long)sp & 1) {
- bcopy((char *)sp++, (char *)&bytes.s, sizeof(bytes.s));
- sum += bytes.s;
- } else
- sum += *sp++;
- len -= 2;
- }
- if (len)
- sum += ntohs(*(u_char *)sp << 8);
-nodata:
- while (sum > 0xffff)
- sum = (sum & 0xffff) + (sum >> 16);
- sum2 = (u_short)(~sum & 0xffff);
-}
-# endif /* defined(BSD) || defined(sun) */
-# endif /* SOLARIS */
-#else /* KERNEL */
- sum2 = 0;
-#endif /* KERNEL */
- tcp->th_sum = ts;
- return sum2;
-}
-
-
-#if defined(_KERNEL) && ( ((BSD < 199306) && !SOLARIS) || defined(__sgi) )
-/*
- * Copyright (c) 1982, 1986, 1988, 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
- * $Id: fil.c,v 2.35.2.30 2000/12/17 05:49:22 darrenr Exp $
- */
-/*
- * Copy data from an mbuf chain starting "off" bytes from the beginning,
- * continuing for "len" bytes, into the indicated buffer.
- */
-void
-m_copydata(m, off, len, cp)
- register mb_t *m;
- register int off;
- register int len;
- caddr_t cp;
-{
- register unsigned count;
-
- if (off < 0 || len < 0)
- panic("m_copydata");
- while (off > 0) {
- if (m == 0)
- panic("m_copydata");
- if (off < m->m_len)
- break;
- off -= m->m_len;
- m = m->m_next;
- }
- while (len > 0) {
- if (m == 0)
- panic("m_copydata");
- count = MIN(m->m_len - off, len);
- bcopy(mtod(m, caddr_t) + off, cp, count);
- len -= count;
- cp += count;
- off = 0;
- m = m->m_next;
- }
-}
-
-
-# ifndef linux
-/*
- * Copy data from a buffer back into the indicated mbuf chain,
- * starting "off" bytes from the beginning, extending the mbuf
- * chain if necessary.
- */
-void
-m_copyback(m0, off, len, cp)
- struct mbuf *m0;
- register int off;
- register int len;
- caddr_t cp;
-{
- register int mlen;
- register struct mbuf *m = m0, *n;
- int totlen = 0;
-
- if (m0 == 0)
- return;
- while (off > (mlen = m->m_len)) {
- off -= mlen;
- totlen += mlen;
- if (m->m_next == 0) {
- n = m_getclr(M_DONTWAIT, m->m_type);
- if (n == 0)
- goto out;
- n->m_len = min(MLEN, len + off);
- m->m_next = n;
- }
- m = m->m_next;
- }
- while (len > 0) {
- mlen = min (m->m_len - off, len);
- bcopy(cp, off + mtod(m, caddr_t), (unsigned)mlen);
- cp += mlen;
- len -= mlen;
- mlen += off;
- off = 0;
- totlen += mlen;
- if (len == 0)
- break;
- if (m->m_next == 0) {
- n = m_get(M_DONTWAIT, m->m_type);
- if (n == 0)
- break;
- n->m_len = min(MLEN, len);
- m->m_next = n;
- }
- m = m->m_next;
- }
-out:
-#if 0
- if (((m = m0)->m_flags & M_PKTHDR) && (m->m_pkthdr.len < totlen))
- m->m_pkthdr.len = totlen;
-#endif
- return;
-}
-# endif /* linux */
-#endif /* (_KERNEL) && ( ((BSD < 199306) && !SOLARIS) || __sgi) */
-
-
-frgroup_t *fr_findgroup(num, flags, which, set, fgpp)
-u_32_t num, flags;
-minor_t which;
-int set;
-frgroup_t ***fgpp;
-{
- frgroup_t *fg, **fgp;
-
- if (which == IPL_LOGAUTH)
- fgp = &ipfgroups[2][set];
- else if (flags & FR_ACCOUNT)
- fgp = &ipfgroups[1][set];
- else if (flags & (FR_OUTQUE|FR_INQUE))
- fgp = &ipfgroups[0][set];
- else
- return NULL;
- num &= 0xffff;
-
- while ((fg = *fgp))
- if (fg->fg_num == num)
- break;
- else
- fgp = &fg->fg_next;
- if (fgpp)
- *fgpp = fgp;
- return fg;
-}
-
-
-frgroup_t *fr_addgroup(num, fp, which, set)
-u_32_t num;
-frentry_t *fp;
-minor_t which;
-int set;
-{
- frgroup_t *fg, **fgp;
-
- if ((fg = fr_findgroup(num, fp->fr_flags, which, set, &fgp)))
- return fg;
-
- KMALLOC(fg, frgroup_t *);
- if (fg) {
- fg->fg_num = num;
- fg->fg_next = *fgp;
- fg->fg_head = fp;
- fg->fg_start = &fp->fr_grp;
- *fgp = fg;
- }
- return fg;
-}
-
-
-void fr_delgroup(num, flags, which, set)
-u_32_t num, flags;
-minor_t which;
-int set;
-{
- frgroup_t *fg, **fgp;
-
- if (!(fg = fr_findgroup(num, flags, which, set, &fgp)))
- return;
-
- *fgp = fg->fg_next;
- KFREE(fg);
-}
-
-
-
-/*
- * recursively flush rules from the list, descending groups as they are
- * encountered. if a rule is the head of a group and it has lost all its
- * group members, then also delete the group reference.
- */
-static int frflushlist(set, unit, nfreedp, listp)
-int set;
-minor_t unit;
-int *nfreedp;
-frentry_t **listp;
-{
- register int freed = 0, i;
- register frentry_t *fp;
-
- while ((fp = *listp)) {
- *listp = fp->fr_next;
- if (fp->fr_grp) {
- i = frflushlist(set, unit, nfreedp, &fp->fr_grp);
- MUTEX_ENTER(&ipf_rw);
- fp->fr_ref -= i;
- MUTEX_EXIT(&ipf_rw);
- }
-
- ATOMIC_DEC32(fp->fr_ref);
- if (fp->fr_grhead) {
- fr_delgroup(fp->fr_grhead, fp->fr_flags,
- unit, set);
- fp->fr_grhead = 0;
- }
- if (fp->fr_ref == 0) {
- KFREE(fp);
- freed++;
- } else
- fp->fr_next = NULL;
- }
- *nfreedp += freed;
- return freed;
-}
-
-
-int frflush(unit, flags)
-minor_t unit;
-int flags;
-{
- int flushed = 0, set;
-
- if (unit != IPL_LOGIPF)
- return 0;
- WRITE_ENTER(&ipf_mutex);
- bzero((char *)frcache, sizeof(frcache[0]) * 2);
-
- set = fr_active;
- if (flags & FR_INACTIVE)
- set = 1 - set;
-
- if (flags & FR_OUTQUE) {
-#ifdef USE_INET6
- (void) frflushlist(set, unit, &flushed, &ipfilter6[1][set]);
- (void) frflushlist(set, unit, &flushed, &ipacct6[1][set]);
-#endif
- (void) frflushlist(set, unit, &flushed, &ipfilter[1][set]);
- (void) frflushlist(set, unit, &flushed, &ipacct[1][set]);
- }
- if (flags & FR_INQUE) {
-#ifdef USE_INET6
- (void) frflushlist(set, unit, &flushed, &ipfilter6[0][set]);
- (void) frflushlist(set, unit, &flushed, &ipacct6[0][set]);
-#endif
- (void) frflushlist(set, unit, &flushed, &ipfilter[0][set]);
- (void) frflushlist(set, unit, &flushed, &ipacct[0][set]);
- }
- RWLOCK_EXIT(&ipf_mutex);
- return flushed;
-}
-
-
-char *memstr(src, dst, slen, dlen)
-char *src, *dst;
-int slen, dlen;
-{
- char *s = NULL;
-
- while (dlen >= slen) {
- if (bcmp(src, dst, slen) == 0) {
- s = dst;
- break;
- }
- dst++;
- dlen--;
- }
- return s;
-}
-
-
-void fixskip(listp, rp, addremove)
-frentry_t **listp, *rp;
-int addremove;
-{
- frentry_t *fp;
- int rules = 0, rn = 0;
-
- for (fp = *listp; fp && (fp != rp); fp = fp->fr_next, rules++)
- ;
-
- if (!fp)
- return;
-
- for (fp = *listp; fp && (fp != rp); fp = fp->fr_next, rn++)
- if (fp->fr_skip && (rn + fp->fr_skip >= rules))
- fp->fr_skip += addremove;
-}
-
-
-#ifdef _KERNEL
-/*
- * count consecutive 1's in bit mask. If the mask generated by counting
- * consecutive 1's is different to that passed, return -1, else return #
- * of bits.
- */
-int countbits(ip)
-u_32_t ip;
-{
- u_32_t ipn;
- int cnt = 0, i, j;
-
- ip = ipn = ntohl(ip);
- for (i = 32; i; i--, ipn *= 2)
- if (ipn & 0x80000000)
- cnt++;
- else
- break;
- ipn = 0;
- for (i = 32, j = cnt; i; i--, j--) {
- ipn *= 2;
- if (j > 0)
- ipn++;
- }
- if (ipn == ip)
- return cnt;
- return -1;
-}
-
-
-/*
- * return the first IP Address associated with an interface
- */
-int fr_ifpaddr(v, ifptr, inp)
-int v;
-void *ifptr;
-struct in_addr *inp;
-{
-# ifdef USE_INET6
- struct in6_addr *inp6 = NULL;
-# endif
-# if SOLARIS
- ill_t *ill = ifptr;
-# else
- struct ifnet *ifp = ifptr;
-# endif
- struct in_addr in;
-
-# if SOLARIS
-# ifdef USE_INET6
- if (v == 6) {
- struct in6_addr in6;
-
- /*
- * First is always link local.
- */
- if (ill->ill_ipif->ipif_next)
- in6 = ill->ill_ipif->ipif_next->ipif_v6lcl_addr;
- else
- bzero((char *)&in6, sizeof(in6));
- bcopy((char *)&in6, (char *)inp, sizeof(in6));
- } else
-# endif
- {
- in.s_addr = ill->ill_ipif->ipif_local_addr;
- *inp = in;
- }
-# else /* SOLARIS */
-# if linux
- ;
-# else /* linux */
- struct sockaddr_in *sin;
- struct ifaddr *ifa;
-
-# if (__FreeBSD_version >= 300000)
- ifa = TAILQ_FIRST(&ifp->if_addrhead);
-# else
-# if defined(__NetBSD__) || defined(__OpenBSD__)
- ifa = ifp->if_addrlist.tqh_first;
-# else
-# if defined(__sgi) && defined(IFF_DRVRLOCK) /* IRIX 6 */
- ifa = &((struct in_ifaddr *)ifp->in_ifaddr)->ia_ifa;
-# else
- ifa = ifp->if_addrlist;
-# endif
-# endif /* __NetBSD__ || __OpenBSD__ */
-# endif /* __FreeBSD_version >= 300000 */
-# if (BSD < 199306) && !(/*IRIX6*/defined(__sgi) && defined(IFF_DRVRLOCK))
- sin = (struct sockaddr_in *)&ifa->ifa_addr;
-# else
- sin = (struct sockaddr_in *)ifa->ifa_addr;
- while (sin && ifa) {
- if ((v == 4) && (sin->sin_family == AF_INET))
- break;
-# ifdef USE_INET6
- if ((v == 6) && (sin->sin_family == AF_INET6)) {
- inp6 = &((struct sockaddr_in6 *)sin)->sin6_addr;
- if (!IN6_IS_ADDR_LINKLOCAL(inp6) &&
- !IN6_IS_ADDR_LOOPBACK(inp6))
- break;
- }
-# endif
-# if (__FreeBSD_version >= 300000)
- ifa = TAILQ_NEXT(ifa, ifa_link);
-# else
-# if defined(__NetBSD__) || defined(__OpenBSD__)
- ifa = ifa->ifa_list.tqe_next;
-# else
- ifa = ifa->ifa_next;
-# endif
-# endif /* __FreeBSD_version >= 300000 */
- if (ifa)
- sin = (struct sockaddr_in *)ifa->ifa_addr;
- }
- if (ifa == NULL)
- sin = NULL;
- if (sin == NULL)
- return -1;
-# endif /* (BSD < 199306) && (!__sgi && IFF_DRVLOCK) */
-# ifdef USE_INET6
- if (v == 6)
- bcopy((char *)inp6, (char *)inp, sizeof(*inp6));
- else
-# endif
- {
- in = sin->sin_addr;
- *inp = in;
- }
-# endif /* linux */
-# endif /* SOLARIS */
- 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, fr->fr_ip.fi_v);
- if (fr->fr_ifa == NULL)
- fr->fr_ifa = (void *)-1;
- }
- if (fr->fr_grp)
- frsynclist(fr->fr_grp);
- }
-}
-
-
-void frsync()
-{
-# if !SOLARIS
- 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);
- ip_statesync(ifp);
- }
- ip_natsync((struct ifnet *)-1);
-# 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]);
-#ifdef USE_INET6
- frsynclist(ipacct6[0][fr_active]);
- frsynclist(ipacct6[1][fr_active]);
- frsynclist(ipfilter6[0][fr_active]);
- frsynclist(ipfilter6[1][fr_active]);
-#endif
- RWLOCK_EXIT(&ipf_mutex);
-}
-
-
-/*
- * In the functions below, bcopy() is called because the pointer being
- * copied _from_ in this instance is a pointer to a char buf (which could
- * end up being unaligned) and on the kernel's local stack.
- */
-int ircopyptr(a, b, c)
-void *a, *b;
-size_t c;
-{
- caddr_t ca;
- int err;
-
-#if SOLARIS
- if (copyin(a, (char *)&ca, sizeof(ca)))
- return EFAULT;
-#else
- bcopy(a, &ca, sizeof(ca));
-#endif
- err = copyin(ca, b, c);
- if (err)
- err = EFAULT;
- return err;
-}
-
-
-int iwcopyptr(a, b, c)
-void *a, *b;
-size_t c;
-{
- caddr_t ca;
- int err;
-
-#if SOLARIS
- if (copyin(b, (char *)&ca, sizeof(ca)))
- return EFAULT;
-#else
- bcopy(b, &ca, sizeof(ca));
-#endif
- err = copyout(a, ca, c);
- if (err)
- err = EFAULT;
- return err;
-}
-
-#else /* _KERNEL */
-
-
-/*
- * return the first IP Address associated with an interface
- */
-int fr_ifpaddr(v, ifptr, inp)
-int v;
-void *ifptr;
-struct in_addr *inp;
-{
- return 0;
-}
-
-
-int ircopyptr(a, b, c)
-void *a, *b;
-size_t c;
-{
- caddr_t ca;
-
- bcopy(a, &ca, sizeof(ca));
- bcopy(ca, b, c);
- return 0;
-}
-
-
-int iwcopyptr(a, b, c)
-void *a, *b;
-size_t c;
-{
- caddr_t ca;
-
- bcopy(b, &ca, sizeof(ca));
- bcopy(a, ca, c);
- return 0;
-}
-
-
-#endif
-
-
-int fr_lock(data, lockp)
-caddr_t data;
-int *lockp;
-{
- int arg, error;
-
- error = IRCOPY(data, (caddr_t)&arg, sizeof(arg));
- if (!error) {
- error = IWCOPY((caddr_t)lockp, data, sizeof(*lockp));
- if (!error)
- *lockp = arg;
- }
- return error;
-}
-
-
-void fr_getstat(fiop)
-friostat_t *fiop;
-{
- bcopy((char *)frstats, (char *)fiop->f_st, sizeof(filterstats_t) * 2);
- fiop->f_locks[0] = fr_state_lock;
- fiop->f_locks[1] = fr_nat_lock;
- fiop->f_locks[2] = fr_frag_lock;
- fiop->f_locks[3] = fr_auth_lock;
- fiop->f_fin[0] = ipfilter[0][0];
- fiop->f_fin[1] = ipfilter[0][1];
- fiop->f_fout[0] = ipfilter[1][0];
- fiop->f_fout[1] = ipfilter[1][1];
- fiop->f_acctin[0] = ipacct[0][0];
- fiop->f_acctin[1] = ipacct[0][1];
- fiop->f_acctout[0] = ipacct[1][0];
- fiop->f_acctout[1] = ipacct[1][1];
-#ifdef USE_INET6
- fiop->f_fin6[0] = ipfilter6[0][0];
- fiop->f_fin6[1] = ipfilter6[0][1];
- fiop->f_fout6[0] = ipfilter6[1][0];
- fiop->f_fout6[1] = ipfilter6[1][1];
- fiop->f_acctin6[0] = ipacct6[0][0];
- fiop->f_acctin6[1] = ipacct6[0][1];
- fiop->f_acctout6[0] = ipacct6[1][0];
- fiop->f_acctout6[1] = ipacct6[1][1];
-#else
- fiop->f_fin6[0] = NULL;
- fiop->f_fin6[1] = NULL;
- fiop->f_fout6[0] = NULL;
- fiop->f_fout6[1] = NULL;
- fiop->f_acctin6[0] = NULL;
- fiop->f_acctin6[1] = NULL;
- fiop->f_acctout6[0] = NULL;
- fiop->f_acctout6[1] = NULL;
-#endif
- fiop->f_active = fr_active;
- fiop->f_froute[0] = ipl_frouteok[0];
- fiop->f_froute[1] = ipl_frouteok[1];
-
- fiop->f_running = fr_running;
- fiop->f_groups[0][0] = ipfgroups[0][0];
- fiop->f_groups[0][1] = ipfgroups[0][1];
- fiop->f_groups[1][0] = ipfgroups[1][0];
- fiop->f_groups[1][1] = ipfgroups[1][1];
- fiop->f_groups[2][0] = ipfgroups[2][0];
- fiop->f_groups[2][1] = ipfgroups[2][1];
-#ifdef IPFILTER_LOG
- fiop->f_logging = 1;
-#else
- fiop->f_logging = 0;
-#endif
- fiop->f_defpass = fr_pass;
- strncpy(fiop->f_version, ipfilter_version, sizeof(fiop->f_version));
-}
-
-
-#ifdef USE_INET6
-int icmptoicmp6types[ICMP_MAXTYPE+1] = {
- ICMP6_ECHO_REPLY, /* 0: ICMP_ECHOREPLY */
- -1, /* 1: UNUSED */
- -1, /* 2: UNUSED */
- ICMP6_DST_UNREACH, /* 3: ICMP_UNREACH */
- -1, /* 4: ICMP_SOURCEQUENCH */
- ND_REDIRECT, /* 5: ICMP_REDIRECT */
- -1, /* 6: UNUSED */
- -1, /* 7: UNUSED */
- ICMP6_ECHO_REQUEST, /* 8: ICMP_ECHO */
- -1, /* 9: UNUSED */
- -1, /* 10: UNUSED */
- ICMP6_TIME_EXCEEDED, /* 11: ICMP_TIMXCEED */
- ICMP6_PARAM_PROB, /* 12: ICMP_PARAMPROB */
- -1, /* 13: ICMP_TSTAMP */
- -1, /* 14: ICMP_TSTAMPREPLY */
- -1, /* 15: ICMP_IREQ */
- -1, /* 16: ICMP_IREQREPLY */
- -1, /* 17: ICMP_MASKREQ */
- -1, /* 18: ICMP_MASKREPLY */
-};
-
-
-int icmptoicmp6unreach[ICMP_MAX_UNREACH] = {
- ICMP6_DST_UNREACH_ADDR, /* 0: ICMP_UNREACH_NET */
- ICMP6_DST_UNREACH_ADDR, /* 1: ICMP_UNREACH_HOST */
- -1, /* 2: ICMP_UNREACH_PROTOCOL */
- ICMP6_DST_UNREACH_NOPORT, /* 3: ICMP_UNREACH_PORT */
- -1, /* 4: ICMP_UNREACH_NEEDFRAG */
- ICMP6_DST_UNREACH_NOTNEIGHBOR, /* 5: ICMP_UNREACH_SRCFAIL */
- ICMP6_DST_UNREACH_ADDR, /* 6: ICMP_UNREACH_NET_UNKNOWN */
- ICMP6_DST_UNREACH_ADDR, /* 7: ICMP_UNREACH_HOST_UNKNOWN */
- -1, /* 8: ICMP_UNREACH_ISOLATED */
- ICMP6_DST_UNREACH_ADMIN, /* 9: ICMP_UNREACH_NET_PROHIB */
- ICMP6_DST_UNREACH_ADMIN, /* 10: ICMP_UNREACH_HOST_PROHIB */
- -1, /* 11: ICMP_UNREACH_TOSNET */
- -1, /* 12: ICMP_UNREACH_TOSHOST */
- ICMP6_DST_UNREACH_ADMIN, /* 13: ICMP_UNREACH_ADMIN_PROHIBIT */
-};
-#endif
diff --git a/contrib/ipfilter/ip_auth.c b/contrib/ipfilter/ip_auth.c
deleted file mode 100644
index a453610..0000000
--- a/contrib/ipfilter/ip_auth.c
+++ /dev/null
@@ -1,550 +0,0 @@
-/*
- * Copyright (C) 1998-2000 by Darren Reed & Guido van Rooij.
- *
- * 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)
-static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.11.2.5 2001/01/10 06:18:35 darrenr Exp $";
-#endif
-
-#include <sys/errno.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/file.h>
-#if !defined(_KERNEL) && !defined(KERNEL)
-# include <stdio.h>
-# include <stdlib.h>
-# include <string.h>
-#endif
-#if (defined(KERNEL) || defined(_KERNEL)) && (__FreeBSD_version >= 220000)
-# include <sys/filio.h>
-# include <sys/fcntl.h>
-#else
-# include <sys/ioctl.h>
-#endif
-#include <sys/uio.h>
-#ifndef linux
-# include <sys/protosw.h>
-#endif
-#include <sys/socket.h>
-#if (defined(_KERNEL) || defined(KERNEL)) && !defined(linux)
-# include <sys/systm.h>
-#endif
-#if !defined(__SVR4) && !defined(__svr4__)
-# ifndef linux
-# include <sys/mbuf.h>
-# endif
-#else
-# include <sys/filio.h>
-# include <sys/byteorder.h>
-# ifdef _KERNEL
-# include <sys/dditypes.h>
-# endif
-# include <sys/stream.h>
-# include <sys/kmem.h>
-#endif
-#if (_BSDI_VERSION >= 199802) || (__FreeBSD_version >= 400000)
-# include <sys/queue.h>
-#endif
-#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(bsdi)
-# include <machine/cpu.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>
-#ifndef KERNEL
-# define KERNEL
-# define NOT_KERNEL
-#endif
-#ifndef linux
-# include <netinet/ip_var.h>
-#endif
-#ifdef NOT_KERNEL
-# undef KERNEL
-#endif
-#ifdef __sgi
-# ifdef IFF_DRVRLOCK /* IRIX6 */
-# include <sys/hashing.h>
-# endif
-#endif
-#include <netinet/tcp.h>
-#if defined(__sgi) && !defined(IFF_DRVRLOCK) /* IRIX < 6 */
-extern struct ifqueue ipintrq; /* ip packet input queue */
-#else
-# ifndef linux
-# if __FreeBSD_version >= 300000
-# include <net/if_var.h>
-# endif
-# include <netinet/in_var.h>
-# include <netinet/tcp_fsm.h>
-# endif
-#endif
-#include <netinet/udp.h>
-#include <netinet/ip_icmp.h>
-#include "netinet/ip_compat.h"
-#include <netinet/tcpip.h>
-#include "netinet/ip_fil.h"
-#include "netinet/ip_auth.h"
-#if !SOLARIS && !defined(linux)
-# include <net/netisr.h>
-# ifdef __FreeBSD__
-# include <machine/cpufunc.h>
-# endif
-#endif
-#if (__FreeBSD_version >= 300000)
-# include <sys/malloc.h>
-# if (defined(_KERNEL) || defined(KERNEL)) && !defined(IPFILTER_LKM)
-# include <sys/libkern.h>
-# include <sys/systm.h>
-# endif
-#endif
-
-
-
-#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
-extern KRWLOCK_T ipf_auth;
-extern kmutex_t ipf_authmx;
-# if SOLARIS
-extern kcondvar_t ipfauthwait;
-# endif
-#endif
-#ifdef linux
-static struct wait_queue *ipfauthwait = NULL;
-#endif
-
-int fr_authsize = FR_NUMAUTH;
-int fr_authused = 0;
-int fr_defaultauthage = 600;
-int fr_auth_lock = 0;
-fr_authstat_t fr_authstats;
-static frauth_t fr_auth[FR_NUMAUTH];
-mb_t *fr_authpkts[FR_NUMAUTH];
-static int fr_authstart = 0, fr_authend = 0, fr_authnext = 0;
-static frauthent_t *fae_list = NULL;
-frentry_t *ipauth = NULL;
-
-
-/*
- * Check if a packet has authorization. If the packet is found to match an
- * authorization result and that would result in a feedback loop (i.e. it
- * will end up returning FR_AUTH) then return FR_BLOCK instead.
- */
-u_32_t fr_checkauth(ip, fin)
-ip_t *ip;
-fr_info_t *fin;
-{
- u_short id = ip->ip_id;
- u_32_t pass;
- int i;
-
- if (fr_auth_lock)
- return 0;
-
- READ_ENTER(&ipf_auth);
- for (i = fr_authstart; i != fr_authend; ) {
- /*
- * index becomes -2 only after an SIOCAUTHW. Check this in
- * case the same packet gets sent again and it hasn't yet been
- * auth'd.
- */
- if ((fr_auth[i].fra_index == -2) &&
- (id == fr_auth[i].fra_info.fin_id) &&
- !bcmp((char *)fin,(char *)&fr_auth[i].fra_info,FI_CSIZE)) {
- /*
- * Avoid feedback loop.
- */
- if (!(pass = fr_auth[i].fra_pass) || (pass & FR_AUTH))
- pass = FR_BLOCK;
- RWLOCK_EXIT(&ipf_auth);
- WRITE_ENTER(&ipf_auth);
- fr_authstats.fas_hits++;
- fr_auth[i].fra_index = -1;
- fr_authused--;
- if (i == fr_authstart) {
- while (fr_auth[i].fra_index == -1) {
- i++;
- if (i == FR_NUMAUTH)
- i = 0;
- fr_authstart = i;
- if (i == fr_authend)
- break;
- }
- if (fr_authstart == fr_authend) {
- fr_authnext = 0;
- fr_authstart = fr_authend = 0;
- }
- }
- RWLOCK_EXIT(&ipf_auth);
- return pass;
- }
- i++;
- if (i == FR_NUMAUTH)
- i = 0;
- }
- fr_authstats.fas_miss++;
- RWLOCK_EXIT(&ipf_auth);
- return 0;
-}
-
-
-/*
- * Check if we have room in the auth array to hold details for another packet.
- * If we do, store it and wake up any user programs which are waiting to
- * hear about these events.
- */
-int fr_newauth(m, fin, ip)
-mb_t *m;
-fr_info_t *fin;
-ip_t *ip;
-{
-#if defined(_KERNEL) && SOLARIS
- qif_t *qif = fin->fin_qif;
-#endif
- int i;
-
- if (fr_auth_lock)
- return 0;
-
- WRITE_ENTER(&ipf_auth);
- if (fr_authstart > fr_authend) {
- fr_authstats.fas_nospace++;
- RWLOCK_EXIT(&ipf_auth);
- return 0;
- } else {
- if ((fr_authstart == 0) && (fr_authend == FR_NUMAUTH - 1)) {
- fr_authstats.fas_nospace++;
- RWLOCK_EXIT(&ipf_auth);
- return 0;
- }
- }
-
- fr_authstats.fas_added++;
- fr_authused++;
- i = fr_authend++;
- if (fr_authend == FR_NUMAUTH)
- fr_authend = 0;
- RWLOCK_EXIT(&ipf_auth);
- fr_auth[i].fra_index = i;
- fr_auth[i].fra_pass = 0;
- fr_auth[i].fra_age = fr_defaultauthage;
- bcopy((char *)fin, (char *)&fr_auth[i].fra_info, sizeof(*fin));
-#if !defined(sparc) && !defined(m68k)
- /*
- * No need to copyback here as we want to undo the changes, not keep
- * them.
- */
-# if SOLARIS && defined(_KERNEL)
- if ((ip == (ip_t *)m->b_rptr) && (ip->ip_v == 4))
-# endif
- {
- register u_short bo;
-
- bo = ip->ip_len;
- ip->ip_len = htons(bo);
-# if !SOLARIS && !defined(__NetBSD__)
- /* 4.4BSD converts this ip_input.c, but I don't in solaris.c */
- bo = ip->ip_id;
- ip->ip_id = htons(bo);
-# endif
- bo = ip->ip_off;
- ip->ip_off = htons(bo);
- }
-#endif
-#if SOLARIS && defined(_KERNEL)
- m->b_rptr -= qif->qf_off;
- fr_authpkts[i] = *(mblk_t **)fin->fin_mp;
- fr_auth[i].fra_q = qif->qf_q;
- cv_signal(&ipfauthwait);
-#else
- fr_authpkts[i] = m;
-# if defined(linux) && defined(_KERNEL)
- wake_up_interruptible(&ipfauthwait);
-# else
- WAKEUP(&fr_authnext);
-# endif
-#endif
- return 1;
-}
-
-
-int fr_auth_ioctl(data, cmd, fr, frptr)
-caddr_t data;
-#if defined(__NetBSD__) || defined(__OpenBSD__) || (FreeBSD_version >= 300003)
-u_long cmd;
-#else
-int cmd;
-#endif
-frentry_t *fr, **frptr;
-{
- mb_t *m;
-#if defined(_KERNEL) && !SOLARIS
- struct ifqueue *ifq;
-#endif
- frauth_t auth, *au = &auth;
- frauthent_t *fae, **faep;
- int i, error = 0;
-
- switch (cmd)
- {
- case SIOCSTLCK :
- error = fr_lock(data, &fr_auth_lock);
- break;
- case SIOCINIFR :
- case SIOCRMIFR :
- case SIOCADIFR :
- error = EINVAL;
- break;
- case SIOCINAFR :
- error = EINVAL;
- break;
- case SIOCRMAFR :
- case SIOCADAFR :
- for (faep = &fae_list; (fae = *faep); )
- if (&fae->fae_fr == fr)
- break;
- else
- faep = &fae->fae_next;
- if (cmd == SIOCRMAFR) {
- if (!fae)
- error = ESRCH;
- else {
- WRITE_ENTER(&ipf_auth);
- *faep = fae->fae_next;
- *frptr = fr->fr_next;
- RWLOCK_EXIT(&ipf_auth);
- KFREE(fae);
- }
- } else {
- KMALLOC(fae, frauthent_t *);
- if (fae != NULL) {
- bcopy((char *)fr, (char *)&fae->fae_fr,
- sizeof(*fr));
- WRITE_ENTER(&ipf_auth);
- fae->fae_age = fr_defaultauthage;
- fae->fae_fr.fr_hits = 0;
- fae->fae_fr.fr_next = *frptr;
- *frptr = &fae->fae_fr;
- fae->fae_next = *faep;
- *faep = fae;
- ipauth = &fae_list->fae_fr;
- RWLOCK_EXIT(&ipf_auth);
- } else
- error = ENOMEM;
- }
- break;
- case SIOCATHST:
- READ_ENTER(&ipf_auth);
- fr_authstats.fas_faelist = fae_list;
- RWLOCK_EXIT(&ipf_auth);
- error = IWCOPYPTR((char *)&fr_authstats, data,
- sizeof(fr_authstats));
- break;
- case SIOCAUTHW:
-fr_authioctlloop:
- READ_ENTER(&ipf_auth);
- if ((fr_authnext != fr_authend) && fr_authpkts[fr_authnext]) {
- error = IWCOPYPTR((char *)&fr_auth[fr_authnext], data,
- sizeof(frauth_t));
- RWLOCK_EXIT(&ipf_auth);
- if (error)
- break;
- WRITE_ENTER(&ipf_auth);
- fr_authnext++;
- if (fr_authnext == FR_NUMAUTH)
- fr_authnext = 0;
- RWLOCK_EXIT(&ipf_auth);
- return 0;
- }
-#ifdef _KERNEL
-# if SOLARIS
- mutex_enter(&ipf_authmx);
- if (!cv_wait_sig(&ipfauthwait, &ipf_authmx)) {
- mutex_exit(&ipf_authmx);
- return EINTR;
- }
- mutex_exit(&ipf_authmx);
-# else
-# ifdef linux
- interruptible_sleep_on(&ipfauthwait);
- if (current->signal & ~current->blocked)
- error = -EINTR;
-# else
- error = SLEEP(&fr_authnext, "fr_authnext");
-# endif
-# endif
-#endif
- RWLOCK_EXIT(&ipf_auth);
- if (!error)
- goto fr_authioctlloop;
- break;
- case SIOCAUTHR:
- error = IRCOPYPTR(data, (caddr_t)&auth, sizeof(auth));
- if (error)
- return error;
- WRITE_ENTER(&ipf_auth);
- i = au->fra_index;
- if ((i < 0) || (i > FR_NUMAUTH) ||
- (fr_auth[i].fra_info.fin_id != au->fra_info.fin_id)) {
- RWLOCK_EXIT(&ipf_auth);
- return EINVAL;
- }
- m = fr_authpkts[i];
- fr_auth[i].fra_index = -2;
- fr_auth[i].fra_pass = au->fra_pass;
- fr_authpkts[i] = NULL;
-#ifdef _KERNEL
- RWLOCK_EXIT(&ipf_auth);
-# ifndef linux
- if (m && au->fra_info.fin_out) {
-# if SOLARIS
- error = fr_qout(fr_auth[i].fra_q, m);
-# else /* SOLARIS */
-# if (_BSDI_VERSION >= 199802) || defined(__OpenBSD__)
- error = ip_output(m, NULL, NULL, IP_FORWARDING, NULL,
- NULL);
-# else
- error = ip_output(m, NULL, NULL, IP_FORWARDING, NULL);
-# endif
-# endif /* SOLARIS */
- if (error)
- fr_authstats.fas_sendfail++;
- else
- fr_authstats.fas_sendok++;
- } else if (m) {
-# if SOLARIS
- error = fr_qin(fr_auth[i].fra_q, m);
-# else /* SOLARIS */
- ifq = &ipintrq;
- if (IF_QFULL(ifq)) {
- IF_DROP(ifq);
- m_freem(m);
- error = ENOBUFS;
- } else {
- IF_ENQUEUE(ifq, m);
- schednetisr(NETISR_IP);
- }
-# endif /* SOLARIS */
- if (error)
- fr_authstats.fas_quefail++;
- else
- fr_authstats.fas_queok++;
- } else
- error = EINVAL;
-# endif
-# if SOLARIS
- if (error)
- error = EINVAL;
-# else
- /*
- * If we experience an error which will result in the packet
- * not being processed, make sure we advance to the next one.
- */
- if (error == ENOBUFS) {
- fr_authused--;
- fr_auth[i].fra_index = -1;
- fr_auth[i].fra_pass = 0;
- if (i == fr_authstart) {
- while (fr_auth[i].fra_index == -1) {
- i++;
- if (i == FR_NUMAUTH)
- i = 0;
- fr_authstart = i;
- if (i == fr_authend)
- break;
- }
- if (fr_authstart == fr_authend) {
- fr_authnext = 0;
- fr_authstart = fr_authend = 0;
- }
- }
- }
-# endif
-#endif /* _KERNEL */
- break;
- default :
- error = EINVAL;
- break;
- }
- return error;
-}
-
-
-#ifdef _KERNEL
-/*
- * Free all network buffer memory used to keep saved packets.
- */
-void fr_authunload()
-{
- register int i;
- register frauthent_t *fae, **faep;
- mb_t *m;
-
- WRITE_ENTER(&ipf_auth);
- for (i = 0; i < FR_NUMAUTH; i++) {
- if ((m = fr_authpkts[i])) {
- FREE_MB_T(m);
- fr_authpkts[i] = NULL;
- fr_auth[i].fra_index = -1;
- }
- }
-
-
- for (faep = &fae_list; (fae = *faep); ) {
- *faep = fae->fae_next;
- KFREE(fae);
- }
- ipauth = NULL;
- RWLOCK_EXIT(&ipf_auth);
-}
-
-
-/*
- * Slowly expire held auth records. Timeouts are set
- * in expectation of this being called twice per second.
- */
-void fr_authexpire()
-{
- register int i;
- register frauth_t *fra;
- register frauthent_t *fae, **faep;
- mb_t *m;
-#if !SOLARIS
- int s;
-#endif
-
- if (fr_auth_lock)
- return;
-
- SPL_NET(s);
- WRITE_ENTER(&ipf_auth);
- for (i = 0, fra = fr_auth; i < FR_NUMAUTH; i++, fra++) {
- if ((!--fra->fra_age) && (m = fr_authpkts[i])) {
- FREE_MB_T(m);
- fr_authpkts[i] = NULL;
- fr_auth[i].fra_index = -1;
- fr_authstats.fas_expire++;
- fr_authused--;
- }
- }
-
- for (faep = &fae_list; (fae = *faep); ) {
- if (!--fae->fae_age) {
- *faep = fae->fae_next;
- KFREE(fae);
- fr_authstats.fas_expire++;
- } else
- faep = &fae->fae_next;
- }
- ipauth = &fae_list->fae_fr;
- RWLOCK_EXIT(&ipf_auth);
- SPL_X(s);
-}
-#endif
diff --git a/contrib/ipfilter/ip_auth.h b/contrib/ipfilter/ip_auth.h
deleted file mode 100644
index 681a6e5..0000000
--- a/contrib/ipfilter/ip_auth.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 1997-2000 by Darren Reed & Guido Van Rooij.
- *
- * 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: ip_auth.h,v 2.3.2.2 2000/10/19 15:38:44 darrenr Exp $
- *
- */
-#ifndef __IP_AUTH_H__
-#define __IP_AUTH_H__
-
-#define FR_NUMAUTH 32
-
-typedef struct frauth {
- int fra_age;
- int fra_index;
- u_32_t fra_pass;
- fr_info_t fra_info;
-#if SOLARIS
- queue_t *fra_q;
-#endif
-} frauth_t;
-
-typedef struct frauthent {
- struct frentry fae_fr;
- struct frauthent *fae_next;
- u_long fae_age;
-} frauthent_t;
-
-typedef struct fr_authstat {
- U_QUAD_T fas_hits;
- U_QUAD_T fas_miss;
- u_long fas_nospace;
- u_long fas_added;
- u_long fas_sendfail;
- u_long fas_sendok;
- u_long fas_queok;
- u_long fas_quefail;
- u_long fas_expire;
- frauthent_t *fas_faelist;
-} fr_authstat_t;
-
-
-extern frentry_t *ipauth;
-extern struct fr_authstat fr_authstats;
-extern int fr_defaultauthage;
-extern int fr_authsize;
-extern int fr_authused;
-extern int fr_auth_lock;
-extern u_32_t fr_checkauth __P((ip_t *, fr_info_t *));
-extern void fr_authexpire __P((void));
-extern void fr_authunload __P((void));
-extern mb_t *fr_authpkts[];
-extern int fr_newauth __P((mb_t *, fr_info_t *, ip_t *));
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-extern int fr_auth_ioctl __P((caddr_t, u_long, frentry_t *, frentry_t **));
-#else
-extern int fr_auth_ioctl __P((caddr_t, int, frentry_t *, frentry_t **));
-#endif
-#endif /* __IP_AUTH_H__ */
diff --git a/contrib/ipfilter/ip_compat.h b/contrib/ipfilter/ip_compat.h
deleted file mode 100644
index ed71f36..0000000
--- a/contrib/ipfilter/ip_compat.h
+++ /dev/null
@@ -1,1012 +0,0 @@
-/*
- * Copyright (C) 1993-2000 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.
- *
- * @(#)ip_compat.h 1.8 1/14/96
- * $Id: ip_compat.h,v 2.26.2.9 2001/01/14 14:58:01 darrenr Exp $
- */
-
-#ifndef __IP_COMPAT_H__
-#define __IP_COMPAT_H__
-
-#ifndef __P
-# ifdef __STDC__
-# define __P(x) x
-# else
-# define __P(x) ()
-# endif
-#endif
-#ifndef __STDC__
-# undef const
-# define const
-#endif
-
-#ifndef SOLARIS
-#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
-#endif
-#if SOLARIS2 >= 8
-# ifndef USE_INET6
-# define USE_INET6
-# endif
-#endif
-
-#if defined(_KERNEL) || defined(KERNEL) || defined(__KERNEL__)
-# undef KERNEL
-# undef _KERNEL
-# undef __KERNEL__
-# define KERNEL
-# define _KERNEL
-# define __KERNEL__
-#endif
-
-#if defined(__SVR4) || defined(__svr4__) || defined(__sgi)
-#define index strchr
-# if !defined(KERNEL)
-# define bzero(a,b) memset(a,0,b)
-# define bcmp memcmp
-# define bcopy(a,b,c) memmove(b,a,c)
-# endif
-#endif
-
-#ifndef offsetof
-#define offsetof(t,m) (int)((&((t *)0L)->m))
-#endif
-
-#if defined(__sgi) || defined(bsdi)
-struct ether_addr {
- u_char ether_addr_octet[6];
-};
-#endif
-
-#if defined(__sgi) && !defined(IPFILTER_LKM)
-# ifdef __STDC__
-# define IPL_EXTERN(ep) ipfilter##ep
-# else
-# define IPL_EXTERN(ep) ipfilter/**/ep
-# endif
-#else
-# ifdef __STDC__
-# define IPL_EXTERN(ep) ipl##ep
-# else
-# define IPL_EXTERN(ep) ipl/**/ep
-# endif
-#endif
-
-#ifdef linux
-# include <sys/sysmacros.h>
-#endif
-#if SOLARIS
-# define MTYPE(m) ((m)->b_datap->db_type)
-# include <sys/isa_defs.h>
-# include <sys/ioccom.h>
-# include <sys/sysmacros.h>
-# include <sys/kmem.h>
-/*
- * because Solaris 2 defines these in two places :-/
- */
-# undef IPOPT_EOL
-# undef IPOPT_NOP
-# undef IPOPT_LSRR
-# undef IPOPT_RR
-# undef IPOPT_SSRR
-# ifndef KERNEL
-# define _KERNEL
-# undef RES_INIT
-# if SOLARIS2 >= 8
-# include <netinet/ip6.h>
-# endif
-# include <inet/common.h>
-# include <inet/ip.h>
-# include <inet/ip_ire.h>
-# undef _KERNEL
-# else /* _KERNEL */
-# if SOLARIS2 >= 8
-# include <netinet/ip6.h>
-# endif
-# include <inet/common.h>
-# include <inet/ip.h>
-# include <inet/ip_ire.h>
-# endif /* _KERNEL */
-# if SOLARIS2 >= 8
-# include <inet/ip_if.h>
-# include <netinet/ip6.h>
-# define ipif_local_addr ipif_lcl_addr
-/* Only defined in private include file */
-# ifndef V4_PART_OF_V6
-# define V4_PART_OF_V6(v6) v6.s6_addr32[3]
-# endif
-# endif
-#else
-# if !defined(__sgi)
-typedef int minor_t;
-#endif
-#endif /* SOLARIS */
-#define IPMINLEN(i, h) ((i)->ip_len >= ((i)->ip_hl * 4 + sizeof(struct h)))
-
-#if defined(__FreeBSD__) && (__FreeBSD__ >= 5) && defined(_KERNEL)
-# include <machine/in_cksum.h>
-#endif
-
-#ifndef IP_OFFMASK
-#define IP_OFFMASK 0x1fff
-#endif
-
-#if BSD > 199306
-# define USE_QUAD_T
-# define U_QUAD_T u_quad_t
-# define QUAD_T quad_t
-#else /* BSD > 199306 */
-# define U_QUAD_T u_long
-# define QUAD_T long
-#endif /* BSD > 199306 */
-
-
-/*
- * These operating systems already take care of the problem for us.
- */
-#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) || \
- defined(__sgi)
-typedef u_int32_t u_32_t;
-# if defined(_KERNEL) && !defined(IPFILTER_LKM)
-# if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 104110000)
-# include "opt_inet.h"
-# endif
-# if defined(__FreeBSD_version) && (__FreeBSD_version >= 400000) && \
- !defined(KLD_MODULE)
-# include "opt_inet6.h"
-# endif
-# ifdef INET6
-# define USE_INET6
-# endif
-# endif
-#else
-/*
- * Really, any arch where sizeof(long) != sizeof(int).
- */
-# if defined(__alpha__) || defined(__alpha) || defined(_LP64)
-typedef unsigned int u_32_t;
-# else
-# if SOLARIS2 >= 6
-typedef uint32_t u_32_t;
-# else
-typedef unsigned int u_32_t;
-# endif
-# endif
-#endif /* __NetBSD__ || __OpenBSD__ || __FreeBSD__ || __sgi */
-
-#ifdef USE_INET6
-# if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)
-# include <netinet/ip6.h>
-# ifdef _KERNEL
-# include <netinet6/ip6_var.h>
-# endif
-typedef struct ip6_hdr ip6_t;
-# endif
-union i6addr {
- u_32_t i6[4];
- struct in_addr in4;
- struct in6_addr in6;
-};
-#else
-union i6addr {
- u_32_t i6[4];
- struct in_addr in4;
-};
-#endif
-
-#define IP6CMP(a,b) bcmp((char *)&(a), (char *)&(b), sizeof(a))
-#define IP6EQ(a,b) (bcmp((char *)&(a), (char *)&(b), sizeof(a)) == 0)
-#define IP6NEQ(a,b) (bcmp((char *)&(a), (char *)&(b), sizeof(a)) != 0)
-
-#ifndef MAX
-#define MAX(a,b) (((a) > (b)) ? (a) : (b))
-#endif
-
-/*
- * Security Options for Intenet Protocol (IPSO) as defined in RFC 1108.
- *
- * Basic Option
- *
- * 00000001 - (Reserved 4)
- * 00111101 - Top Secret
- * 01011010 - Secret
- * 10010110 - Confidential
- * 01100110 - (Reserved 3)
- * 11001100 - (Reserved 2)
- * 10101011 - Unclassified
- * 11110001 - (Reserved 1)
- */
-#define IPSO_CLASS_RES4 0x01
-#define IPSO_CLASS_TOPS 0x3d
-#define IPSO_CLASS_SECR 0x5a
-#define IPSO_CLASS_CONF 0x96
-#define IPSO_CLASS_RES3 0x66
-#define IPSO_CLASS_RES2 0xcc
-#define IPSO_CLASS_UNCL 0xab
-#define IPSO_CLASS_RES1 0xf1
-
-#define IPSO_AUTH_GENSER 0x80
-#define IPSO_AUTH_ESI 0x40
-#define IPSO_AUTH_SCI 0x20
-#define IPSO_AUTH_NSA 0x10
-#define IPSO_AUTH_DOE 0x08
-#define IPSO_AUTH_UN 0x06
-#define IPSO_AUTH_FTE 0x01
-
-/*
- * IP option #defines
- */
-/*#define IPOPT_RR 7 */
-#define IPOPT_ZSU 10 /* ZSU */
-#define IPOPT_MTUP 11 /* MTUP */
-#define IPOPT_MTUR 12 /* MTUR */
-#define IPOPT_ENCODE 15 /* ENCODE */
-/*#define IPOPT_TS 68 */
-#define IPOPT_TR 82 /* TR */
-/*#define IPOPT_SECURITY 130 */
-/*#define IPOPT_LSRR 131 */
-#define IPOPT_E_SEC 133 /* E-SEC */
-#define IPOPT_CIPSO 134 /* CIPSO */
-/*#define IPOPT_SATID 136 */
-#ifndef IPOPT_SID
-# define IPOPT_SID IPOPT_SATID
-#endif
-/*#define IPOPT_SSRR 137 */
-#define IPOPT_ADDEXT 147 /* ADDEXT */
-#define IPOPT_VISA 142 /* VISA */
-#define IPOPT_IMITD 144 /* IMITD */
-#define IPOPT_EIP 145 /* EIP */
-#define IPOPT_FINN 205 /* FINN */
-
-
-#if defined(__FreeBSD__) && (defined(KERNEL) || defined(_KERNEL))
-# ifdef IPFILTER_LKM
-# include <osreldate.h>
-# define ACTUALLY_LKM_NOT_KERNEL
-# else
-# include <sys/osreldate.h>
-# endif
-# if __FreeBSD__ < 3
-# include <machine/spl.h>
-# else
-# if __FreeBSD__ == 3
-# if defined(IPFILTER_LKM) && !defined(ACTUALLY_LKM_NOT_KERNEL)
-# define ACTUALLY_LKM_NOT_KERNEL
-# endif
-# endif
-# endif
-#endif /* __FreeBSD__ && KERNEL */
-
-/*
- * Build some macros and #defines to enable the same code to compile anywhere
- * Well, that's the idea, anyway :-)
- */
-#if !SOLARIS || (SOLARIS2 < 6) || !defined(KERNEL)
-# define ATOMIC_INCL ATOMIC_INC
-# define ATOMIC_INC64 ATOMIC_INC
-# define ATOMIC_INC32 ATOMIC_INC
-# define ATOMIC_INC16 ATOMIC_INC
-# define ATOMIC_DECL ATOMIC_DEC
-# define ATOMIC_DEC64 ATOMIC_DEC
-# define ATOMIC_DEC32 ATOMIC_DEC
-# define ATOMIC_DEC16 ATOMIC_DEC
-#endif
-#ifdef __sgi
-# define hz HZ
-# include <sys/ksynch.h>
-# define IPF_LOCK_PL plhi
-# include <sys/sema.h>
-#undef kmutex_t
-typedef struct {
- lock_t *l;
- int pl;
-} kmutex_t;
-# undef MUTEX_INIT
-# undef MUTEX_DESTROY
-#endif
-#ifdef KERNEL
-# if SOLARIS
-# if SOLARIS2 >= 6
-# include <sys/atomic.h>
-# if SOLARIS2 == 6
-# define ATOMIC_INCL(x) atomic_add_long((uint32_t*)&(x), 1)
-# define ATOMIC_DECL(x) atomic_add_long((uint32_t*)&(x), -1)
-# else
-# define ATOMIC_INCL(x) atomic_add_long(&(x), 1)
-# define ATOMIC_DECL(x) atomic_add_long(&(x), -1)
-# endif
-# define ATOMIC_INC64(x) atomic_add_64((uint64_t*)&(x), 1)
-# define ATOMIC_INC32(x) atomic_add_32((uint32_t*)&(x), 1)
-# define ATOMIC_INC16(x) atomic_add_16((uint16_t*)&(x), 1)
-# define ATOMIC_DEC64(x) atomic_add_64((uint64_t*)&(x), -1)
-# define ATOMIC_DEC32(x) atomic_add_32((uint32_t*)&(x), -1)
-# define ATOMIC_DEC16(x) atomic_add_16((uint16_t*)&(x), -1)
-# else
-# define ATOMIC_INC(x) { mutex_enter(&ipf_rw); (x)++; \
- mutex_exit(&ipf_rw); }
-# define ATOMIC_DEC(x) { mutex_enter(&ipf_rw); (x)--; \
- mutex_exit(&ipf_rw); }
-# endif
-# define MUTEX_ENTER(x) mutex_enter(x)
-# if 1
-# define KRWLOCK_T krwlock_t
-# define READ_ENTER(x) rw_enter(x, RW_READER)
-# define WRITE_ENTER(x) rw_enter(x, RW_WRITER)
-# define RW_UPGRADE(x) { if (rw_tryupgrade(x) == 0) { \
- rw_exit(x); \
- rw_enter(x, RW_WRITER); } \
- }
-# define MUTEX_DOWNGRADE(x) rw_downgrade(x)
-# define RWLOCK_INIT(x, y, z) rw_init((x), (y), RW_DRIVER, (z))
-# define RWLOCK_EXIT(x) rw_exit(x)
-# define RW_DESTROY(x) rw_destroy(x)
-# else
-# define KRWLOCK_T kmutex_t
-# define READ_ENTER(x) mutex_enter(x)
-# define WRITE_ENTER(x) mutex_enter(x)
-# define MUTEX_DOWNGRADE(x) ;
-# define RWLOCK_INIT(x, y, z) mutex_init((x), (y), MUTEX_DRIVER, (z))
-# define RWLOCK_EXIT(x) mutex_exit(x)
-# define RW_DESTROY(x) mutex_destroy(x)
-# endif
-# define MUTEX_INIT(x, y, z) mutex_init((x), (y), MUTEX_DRIVER, (z))
-# define MUTEX_DESTROY(x) mutex_destroy(x)
-# define MUTEX_EXIT(x) mutex_exit(x)
-# define MTOD(m,t) (t)((m)->b_rptr)
-# define IRCOPY(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c))
-# define IWCOPY(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c))
-# define IRCOPYPTR ircopyptr
-# define IWCOPYPTR iwcopyptr
-# define FREE_MB_T(m) freemsg(m)
-# define SPL_NET(x) ;
-# define SPL_IMP(x) ;
-# undef SPL_X
-# define SPL_X(x) ;
-# ifdef sparc
-# define ntohs(x) (x)
-# define ntohl(x) (x)
-# define htons(x) (x)
-# define htonl(x) (x)
-# endif /* sparc */
-# define KMALLOC(a,b) (a) = (b)kmem_alloc(sizeof(*(a)), KM_NOSLEEP)
-# define KMALLOCS(a,b,c) (a) = (b)kmem_alloc((c), KM_NOSLEEP)
-# define GET_MINOR(x) getminor(x)
-typedef struct qif {
- struct qif *qf_next;
- ill_t *qf_ill;
- kmutex_t qf_lock;
- void *qf_iptr;
- void *qf_optr;
- queue_t *qf_in;
- queue_t *qf_out;
- struct qinit *qf_wqinfo;
- struct qinit *qf_rqinfo;
- struct qinit qf_wqinit;
- struct qinit qf_rqinit;
- mblk_t *qf_m; /* These three fields are for passing data up from */
- queue_t *qf_q; /* fr_qin and fr_qout to the packet processing. */
- size_t qf_off;
- size_t qf_len; /* this field is used for in ipfr_fastroute */
- char qf_name[8];
- /*
- * in case the ILL has disappeared...
- */
- size_t qf_hl; /* header length */
- int qf_sap;
-} qif_t;
-extern ill_t *get_unit __P((char *, int));
-# define GETUNIT(n, v) get_unit(n, v)
-# define IFNAME(x) ((ill_t *)x)->ill_name
-# else /* SOLARIS */
-# if defined(__sgi)
-# define ATOMIC_INC(x) { MUTEX_ENTER(&ipf_rw); \
- (x)++; MUTEX_EXIT(&ipf_rw); }
-# define ATOMIC_DEC(x) { MUTEX_ENTER(&ipf_rw); \
- (x)--; MUTEX_EXIT(&ipf_rw); }
-# define MUTEX_ENTER(x) (x)->pl = LOCK((x)->l, IPF_LOCK_PL);
-# define KRWLOCK_T kmutex_t
-# define READ_ENTER(x) MUTEX_ENTER(x)
-# define WRITE_ENTER(x) MUTEX_ENTER(x)
-# define RW_UPGRADE(x) ;
-# define MUTEX_DOWNGRADE(x) ;
-# define RWLOCK_EXIT(x) MUTEX_EXIT(x)
-# define MUTEX_EXIT(x) UNLOCK((x)->l, (x)->pl);
-# define MUTEX_INIT(x,y,z) (x)->l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP)
-# define MUTEX_DESTROY(x) LOCK_DEALLOC((x)->l)
-# else /* __sgi */
-# define ATOMIC_INC(x) (x)++
-# define ATOMIC_DEC(x) (x)--
-# define MUTEX_ENTER(x) ;
-# define READ_ENTER(x) ;
-# define WRITE_ENTER(x) ;
-# define RW_UPGRADE(x) ;
-# define MUTEX_DOWNGRADE(x) ;
-# define RWLOCK_EXIT(x) ;
-# define MUTEX_EXIT(x) ;
-# define MUTEX_INIT(x,y,z) ;
-# define MUTEX_DESTROY(x) ;
-# endif /* __sgi */
-# ifndef linux
-# define FREE_MB_T(m) m_freem(m)
-# define MTOD(m,t) mtod(m,t)
-# define IRCOPY(a,b,c) (bcopy((a), (b), (c)), 0)
-# define IWCOPY(a,b,c) (bcopy((a), (b), (c)), 0)
-# define IRCOPYPTR ircopyptr
-# define IWCOPYPTR iwcopyptr
-# endif /* !linux */
-# endif /* SOLARIS */
-
-# ifdef sun
-# if !SOLARIS
-# include <sys/kmem_alloc.h>
-# define GETUNIT(n, v) ifunit(n, IFNAMSIZ)
-# define IFNAME(x) ((struct ifnet *)x)->if_name
-# endif
-# else
-# ifndef linux
-# define GETUNIT(n, v) ifunit(n)
-# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
- (defined(OpenBSD) && (OpenBSD >= 199603))
-# define IFNAME(x) ((struct ifnet *)x)->if_xname
-# else
-# define IFNAME(x) ((struct ifnet *)x)->if_name
-# endif
-# endif
-# endif /* sun */
-
-# if defined(sun) && !defined(linux) || defined(__sgi)
-# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d)
-# define SLEEP(id, n) sleep((id), PZERO+1)
-# define WAKEUP(id) wakeup(id)
-# define KFREE(x) kmem_free((char *)(x), sizeof(*(x)))
-# define KFREES(x,s) kmem_free((char *)(x), (s))
-# if !SOLARIS
-extern void m_copydata __P((struct mbuf *, int, int, caddr_t));
-extern void m_copyback __P((struct mbuf *, int, int, caddr_t));
-# endif
-# ifdef __sgi
-# include <sys/kmem.h>
-# include <sys/ddi.h>
-# define KMALLOC(a,b) (a) = (b)kmem_alloc(sizeof(*(a)), KM_NOSLEEP)
-# define KMALLOCS(a,b,c) (a) = (b)kmem_alloc((c), KM_NOSLEEP)
-# define GET_MINOR(x) getminor(x)
-# else
-# if !SOLARIS
-# define KMALLOC(a,b) (a) = (b)new_kmem_alloc(sizeof(*(a)), \
- KMEM_NOSLEEP)
-# define KMALLOCS(a,b,c) (a) = (b)new_kmem_alloc((c), KMEM_NOSLEEP)
-# endif /* SOLARIS */
-# endif /* __sgi */
-# endif /* sun && !linux */
-# ifndef GET_MINOR
-# define GET_MINOR(x) minor(x)
-# endif
-# if (BSD >= 199306) || defined(__FreeBSD__)
-# include <vm/vm.h>
-# if !defined(__FreeBSD__) || (defined (__FreeBSD__) && __FreeBSD__>=3)
-# include <vm/vm_extern.h>
-# include <sys/proc.h>
-extern vm_map_t kmem_map;
-# else /* !__FreeBSD__ || (__FreeBSD__ && __FreeBSD__>=3) */
-# include <vm/vm_kern.h>
-# endif /* !__FreeBSD__ || (__FreeBSD__ && __FreeBSD__>=3) */
-# ifdef M_PFIL
-# define KMALLOC(a, b) MALLOC((a), b, sizeof(*(a)), M_PFIL, M_NOWAIT)
-# define KMALLOCS(a, b, c) MALLOC((a), b, (c), M_PFIL, M_NOWAIT)
-# define KFREE(x) FREE((x), M_PFIL)
-# define KFREES(x,s) FREE((x), M_PFIL)
-# else
-# define KMALLOC(a, b) MALLOC((a), b, sizeof(*(a)), M_TEMP, M_NOWAIT)
-# define KMALLOCS(a, b, c) MALLOC((a), b, (c), M_TEMP, M_NOWAIT)
-# define KFREE(x) FREE((x), M_TEMP)
-# define KFREES(x,s) FREE((x), M_TEMP)
-# endif /* M_PFIL */
-# define UIOMOVE(a,b,c,d) uiomove(a,b,d)
-# define SLEEP(id, n) tsleep((id), PPAUSE|PCATCH, n, 0)
-# define WAKEUP(id) wakeup(id)
-# endif /* BSD */
-# if defined(NetBSD) && NetBSD <= 1991011 && NetBSD >= 199407
-# define SPL_NET(x) x = splsoftnet()
-# define SPL_X(x) (void) splx(x)
-# else
-# if !SOLARIS && !defined(linux)
-# define SPL_IMP(x) x = splimp()
-# define SPL_NET(x) x = splnet()
-# define SPL_X(x) (void) splx(x)
-# endif
-# endif /* NetBSD && NetBSD <= 1991011 && NetBSD >= 199407 */
-# define PANIC(x,y) if (x) panic y
-#else /* KERNEL */
-# define SLEEP(x,y) ;
-# define WAKEUP(x) ;
-# define PANIC(x,y) ;
-# define ATOMIC_INC(x) (x)++
-# define ATOMIC_DEC(x) (x)--
-# define MUTEX_ENTER(x) ;
-# define READ_ENTER(x) ;
-# define MUTEX_INIT(x,y,z) ;
-# define MUTEX_DESTROY(x) ;
-# define WRITE_ENTER(x) ;
-# define RW_UPGRADE(x) ;
-# define MUTEX_DOWNGRADE(x) ;
-# define RWLOCK_EXIT(x) ;
-# define MUTEX_EXIT(x) ;
-# define SPL_NET(x) ;
-# define SPL_IMP(x) ;
-# undef SPL_X
-# define SPL_X(x) ;
-# define KMALLOC(a,b) (a) = (b)malloc(sizeof(*a))
-# define KMALLOCS(a,b,c) (a) = (b)malloc(c)
-# define KFREE(x) free(x)
-# define KFREES(x,s) free(x)
-# define GETUNIT(x, v) get_unit(x,v)
-# define IRCOPY(a,b,c) (bcopy((a), (b), (c)), 0)
-# define IWCOPY(a,b,c) (bcopy((a), (b), (c)), 0)
-# define IRCOPYPTR ircopyptr
-# define IWCOPYPTR iwcopyptr
-#endif /* KERNEL */
-
-#if SOLARIS
-typedef mblk_t mb_t;
-# if SOLARIS2 >= 7
-# ifdef lint
-# define ALIGN32(ptr) (ptr ? 0L : 0L)
-# define ALIGN16(ptr) (ptr ? 0L : 0L)
-# else
-# define ALIGN32(ptr) (ptr)
-# define ALIGN16(ptr) (ptr)
-# endif
-# endif
-#else
-# ifdef linux
-# ifndef kernel
-typedef struct mb {
- struct mb *next;
- u_int len;
- u_char *data;
-} mb_t;
-# else
-typedef struct sk_buff mb_t;
-# endif
-# else
-typedef struct mbuf mb_t;
-# endif
-#endif /* SOLARIS */
-
-#if defined(linux) || defined(__sgi)
-/*
- * These #ifdef's are here mainly for linux, but who knows, they may
- * not be in other places or maybe one day linux will grow up and some
- * of these will turn up there too.
- */
-#ifndef ICMP_MINLEN
-# define ICMP_MINLEN 8
-#endif
-#ifndef ICMP_UNREACH
-# define ICMP_UNREACH ICMP_DEST_UNREACH
-#endif
-#ifndef ICMP_SOURCEQUENCH
-# define ICMP_SOURCEQUENCH ICMP_SOURCE_QUENCH
-#endif
-#ifndef ICMP_TIMXCEED
-# define ICMP_TIMXCEED ICMP_TIME_EXCEEDED
-#endif
-#ifndef ICMP_PARAMPROB
-# define ICMP_PARAMPROB ICMP_PARAMETERPROB
-#endif
-#ifndef ICMP_TSTAMP
-# define ICMP_TSTAMP ICMP_TIMESTAMP
-#endif
-#ifndef ICMP_TSTAMPREPLY
-# define ICMP_TSTAMPREPLY ICMP_TIMESTAMPREPLY
-#endif
-#ifndef ICMP_IREQ
-# define ICMP_IREQ ICMP_INFO_REQUEST
-#endif
-#ifndef ICMP_IREQREPLY
-# define ICMP_IREQREPLY ICMP_INFO_REPLY
-#endif
-#ifndef ICMP_MASKREQ
-# define ICMP_MASKREQ ICMP_ADDRESS
-#endif
-#ifndef ICMP_MASKREPLY
-# define ICMP_MASKREPLY ICMP_ADDRESSREPLY
-#endif
-#ifndef IPVERSION
-# define IPVERSION 4
-#endif
-#ifndef IPOPT_MINOFF
-# define IPOPT_MINOFF 4
-#endif
-#ifndef IPOPT_COPIED
-# define IPOPT_COPIED(x) ((x)&0x80)
-#endif
-#ifndef IPOPT_EOL
-# define IPOPT_EOL 0
-#endif
-#ifndef IPOPT_NOP
-# define IPOPT_NOP 1
-#endif
-#ifndef IP_MF
-# define IP_MF ((u_short)0x2000)
-#endif
-#ifndef ETHERTYPE_IP
-# define ETHERTYPE_IP ((u_short)0x0800)
-#endif
-#ifndef TH_FIN
-# define TH_FIN 0x01
-#endif
-#ifndef TH_SYN
-# define TH_SYN 0x02
-#endif
-#ifndef TH_RST
-# define TH_RST 0x04
-#endif
-#ifndef TH_PUSH
-# define TH_PUSH 0x08
-#endif
-#ifndef TH_ACK
-# define TH_ACK 0x10
-#endif
-#ifndef TH_URG
-# define TH_URG 0x20
-#endif
-#ifndef IPOPT_EOL
-# define IPOPT_EOL 0
-#endif
-#ifndef IPOPT_NOP
-# define IPOPT_NOP 1
-#endif
-#ifndef IPOPT_RR
-# define IPOPT_RR 7
-#endif
-#ifndef IPOPT_TS
-# define IPOPT_TS 68
-#endif
-#ifndef IPOPT_SECURITY
-# define IPOPT_SECURITY 130
-#endif
-#ifndef IPOPT_LSRR
-# define IPOPT_LSRR 131
-#endif
-#ifndef IPOPT_SATID
-# define IPOPT_SATID 136
-#endif
-#ifndef IPOPT_SSRR
-# define IPOPT_SSRR 137
-#endif
-#ifndef IPOPT_SECUR_UNCLASS
-# define IPOPT_SECUR_UNCLASS ((u_short)0x0000)
-#endif
-#ifndef IPOPT_SECUR_CONFID
-# define IPOPT_SECUR_CONFID ((u_short)0xf135)
-#endif
-#ifndef IPOPT_SECUR_EFTO
-# define IPOPT_SECUR_EFTO ((u_short)0x789a)
-#endif
-#ifndef IPOPT_SECUR_MMMM
-# define IPOPT_SECUR_MMMM ((u_short)0xbc4d)
-#endif
-#ifndef IPOPT_SECUR_RESTR
-# define IPOPT_SECUR_RESTR ((u_short)0xaf13)
-#endif
-#ifndef IPOPT_SECUR_SECRET
-# define IPOPT_SECUR_SECRET ((u_short)0xd788)
-#endif
-#ifndef IPOPT_SECUR_TOPSECRET
-# define IPOPT_SECUR_TOPSECRET ((u_short)0x6bc5)
-#endif
-#ifndef IPOPT_OLEN
-# define IPOPT_OLEN 1
-#endif
-#endif /* linux || __sgi */
-
-#ifdef linux
-#include <linux/in_systm.h>
-/*
- * TCP States
- */
-#define TCPS_CLOSED 0 /* closed */
-#define TCPS_LISTEN 1 /* listening for connection */
-#define TCPS_SYN_SENT 2 /* active, have sent syn */
-#define TCPS_SYN_RECEIVED 3 /* have send and received syn */
-/* states < TCPS_ESTABLISHED are those where connections not established */
-#define TCPS_ESTABLISHED 4 /* established */
-#define TCPS_CLOSE_WAIT 5 /* rcvd fin, waiting for close */
-/* states > TCPS_CLOSE_WAIT are those where user has closed */
-#define TCPS_FIN_WAIT_1 6 /* have closed, sent fin */
-#define TCPS_CLOSING 7 /* closed xchd FIN; await FIN ACK */
-#define TCPS_LAST_ACK 8 /* had fin and close; await FIN ACK */
-/* states > TCPS_CLOSE_WAIT && < TCPS_FIN_WAIT_2 await ACK of FIN */
-#define TCPS_FIN_WAIT_2 9 /* have closed, fin is acked */
-#define TCPS_TIME_WAIT 10 /* in 2*msl quiet wait after close */
-
-/*
- * file flags.
- */
-#ifdef WRITE
-#define FWRITE WRITE
-#define FREAD READ
-#else
-#define FWRITE _IOC_WRITE
-#define FREAD _IOC_READ
-#endif
-/*
- * mbuf related problems.
- */
-#define mtod(m,t) (t)((m)->data)
-#define m_len len
-#define m_next next
-
-#ifdef IP_DF
-#undef IP_DF
-#endif
-#define IP_DF 0x4000
-
-typedef struct {
- __u16 th_sport;
- __u16 th_dport;
- __u32 th_seq;
- __u32 th_ack;
-# if defined(__i386__) || defined(__MIPSEL__) || defined(__alpha__) ||\
- defined(vax)
- __u8 th_res:4;
- __u8 th_off:4;
-#else
- __u8 th_off:4;
- __u8 th_res:4;
-#endif
- __u8 th_flags;
- __u16 th_win;
- __u16 th_sum;
- __u16 th_urp;
-} tcphdr_t;
-
-typedef struct {
- __u16 uh_sport;
- __u16 uh_dport;
- __u16 uh_ulen;
- __u16 uh_sum;
-} udphdr_t;
-
-typedef struct {
-# if defined(__i386__) || defined(__MIPSEL__) || defined(__alpha__) ||\
- defined(vax)
- __u8 ip_hl:4;
- __u8 ip_v:4;
-# else
- __u8 ip_v:4;
- __u8 ip_hl:4;
-# endif
- __u8 ip_tos;
- __u16 ip_len;
- __u16 ip_id;
- __u16 ip_off;
- __u8 ip_ttl;
- __u8 ip_p;
- __u16 ip_sum;
- struct in_addr ip_src;
- struct in_addr ip_dst;
-} ip_t;
-
-/*
- * Structure of an icmp header.
- */
-typedef struct icmp {
- __u8 icmp_type; /* type of message, see below */
- __u8 icmp_code; /* type sub code */
- __u16 icmp_cksum; /* ones complement cksum of struct */
- union {
- __u8 ih_pptr; /* ICMP_PARAMPROB */
- struct in_addr ih_gwaddr; /* ICMP_REDIRECT */
- struct ih_idseq {
- __u16 icd_id;
- __u16 icd_seq;
- } ih_idseq;
- int ih_void;
- } icmp_hun;
-# define icmp_pptr icmp_hun.ih_pptr
-# define icmp_gwaddr icmp_hun.ih_gwaddr
-# define icmp_id icmp_hun.ih_idseq.icd_id
-# define icmp_seq icmp_hun.ih_idseq.icd_seq
-# define icmp_void icmp_hun.ih_void
- union {
- struct id_ts {
- n_time its_otime;
- n_time its_rtime;
- n_time its_ttime;
- } id_ts;
- struct id_ip {
- ip_t idi_ip;
- /* options and then 64 bits of data */
- } id_ip;
- u_long id_mask;
- char id_data[1];
- } icmp_dun;
-# define icmp_otime icmp_dun.id_ts.its_otime
-# define icmp_rtime icmp_dun.id_ts.its_rtime
-# define icmp_ttime icmp_dun.id_ts.its_ttime
-# define icmp_ip icmp_dun.id_ip.idi_ip
-# define icmp_mask icmp_dun.id_mask
-# define icmp_data icmp_dun.id_data
-} icmphdr_t;
-
-# ifndef LINUX_IPOVLY
-# define LINUX_IPOVLY
-struct ipovly {
- caddr_t ih_next, ih_prev; /* for protocol sequence q's */
- u_char ih_x1; /* (unused) */
- u_char ih_pr; /* protocol */
- short ih_len; /* protocol length */
- struct in_addr ih_src; /* source internet address */
- struct in_addr ih_dst; /* destination internet address */
-};
-# endif
-
-typedef struct {
- __u8 ether_dhost[6];
- __u8 ether_shost[6];
- __u16 ether_type;
-} ether_header_t;
-
-typedef struct uio {
- int uio_resid;
- int uio_rw;
- caddr_t uio_buf;
-} uio_t;
-
-# define UIO_READ 0
-# define UIO_WRITE 1
-# define UIOMOVE(a, b, c, d) uiomove(a,b,c,d)
-
-/*
- * For masking struct ifnet onto struct device
- */
-# define if_name name
-
-# ifdef KERNEL
-# define GETUNIT(x, v) dev_get(x)
-# define FREE_MB_T(m) kfree_skb(m, FREE_WRITE)
-# define uniqtime do_gettimeofday
-# undef INT_MAX
-# undef UINT_MAX
-# undef LONG_MAX
-# undef ULONG_MAX
-# include <linux/netdevice.h>
-# define SPL_X(x)
-# define SPL_NET(x)
-# define SPL_IMP(x)
-
-# define bcmp(a,b,c) memcmp(a,b,c)
-# define bcopy(a,b,c) memcpy(b,a,c)
-# define bzero(a,c) memset(a,0,c)
-
-# define UNITNAME(n) dev_get((n))
-
-# define KMALLOC(a,b) (a) = (b)kmalloc(sizeof(*(a)), GFP_ATOMIC)
-# define KMALLOCS(a,b,c) (a) = (b)kmalloc((c), GFP_ATOMIC)
-# define KFREE(x) kfree_s((x), sizeof(*(x)))
-# define KFREES(x,s) kfree_s((x), (s))
-#define IRCOPY(const void *a, void *b, size_t c) { \
- int error; \
-
- error = verify_area(VERIFY_READ, a ,c); \
- if (!error) \
- memcpy_fromfs(b, a, c); \
- return error; \
-}
-static inline int IWCOPY(const void *a, void *b, size_t c)
-{
- int error;
-
- error = verify_area(VERIFY_WRITE, b, c);
- if (!error)
- memcpy_tofs(b, a, c);
- return error;
-}
-static inline int IRCOPYPTR(const void *a, void *b, size_t c) {
- caddr_t ca;
- int error;
-
- error = verify_area(VERIFY_READ, a ,sizeof(ca));
- if (!error) {
- memcpy_fromfs(ca, a, sizeof(ca));
- error = verify_area(VERIFY_READ, ca , c);
- if (!error)
- memcpy_fromfs(b, ca, c);
- }
- return error;
-}
-static inline int IWCOPYPTR(const void *a, void *b, size_t c) {
- caddr_t ca;
- int error;
-
-
- error = verify_area(VERIFY_READ, b ,sizeof(ca));
- if (!error) {
- memcpy_fromfs(ca, b, sizeof(ca));
- error = verify_area(VERIFY_WRITE, ca, c);
- if (!error)
- memcpy_tofs(ca, a, c);
- }
- return error;
-}
-# else
-# define __KERNEL__
-# undef INT_MAX
-# undef UINT_MAX
-# undef LONG_MAX
-# undef ULONG_MAX
-# define s8 __s8
-# define u8 __u8
-# define s16 __s16
-# define u16 __u16
-# define s32 __s32
-# define u32 __u32
-# include <linux/netdevice.h>
-# undef __KERNEL__
-# endif
-# define ifnet device
-#else
-typedef struct tcphdr tcphdr_t;
-typedef struct udphdr udphdr_t;
-typedef struct icmp icmphdr_t;
-typedef struct ip ip_t;
-typedef struct ether_header ether_header_t;
-#endif /* linux */
-typedef struct tcpiphdr tcpiphdr_t;
-
-#if defined(hpux) || defined(linux)
-struct ether_addr {
- char ether_addr_octet[6];
-};
-#endif
-
-/*
- * XXX - This is one of those *awful* hacks which nobody likes
- */
-#ifdef ultrix
-#define A_A
-#else
-#define A_A &
-#endif
-
-#ifndef ICMP_ROUTERADVERT
-# define ICMP_ROUTERADVERT 9
-#endif
-#ifndef ICMP_ROUTERSOLICIT
-# define ICMP_ROUTERSOLICIT 10
-#endif
-#undef ICMP_MAX_UNREACH
-#define ICMP_MAX_UNREACH 14
-#undef ICMP_MAXTYPE
-#define ICMP_MAXTYPE 18
-/*
- * ICMP error replies have an IP header (20 bytes), 8 bytes of ICMP data,
- * another IP header and then 64 bits of data, totalling 56. Of course,
- * the last 64 bits is dependant on that being available.
- */
-#define ICMPERR_ICMPHLEN 8
-#define ICMPERR_IPICMPHLEN (20 + 8)
-#define ICMPERR_MINPKTLEN (20 + 8 + 20)
-#define ICMPERR_MAXPKTLEN (20 + 8 + 20 + 8)
-#define ICMP6ERR_MINPKTLEN (40 + 8)
-#define ICMP6ERR_IPICMPHLEN (40 + 8 + 40)
-
-/*
- * ECN is a new addition to TCP - RFC 2481
- */
-#ifndef TH_ECN
-# define TH_ECN 0x40
-#endif
-#ifndef TH_CWR
-# define TH_CWR 0x80
-#endif
-#define TH_ECNALL (TH_ECN|TH_CWR)
-
-#define TCPF_ALL (TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG|TH_ECN|TH_CWR)
-
-#endif /* __IP_COMPAT_H__ */
diff --git a/contrib/ipfilter/ip_fil.c b/contrib/ipfilter/ip_fil.c
deleted file mode 100644
index 9253775..0000000
--- a/contrib/ipfilter/ip_fil.c
+++ /dev/null
@@ -1,1758 +0,0 @@
-/*
- * Copyright (C) 1993-2000 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)
-static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.42.2.17 2000/10/19 15:39:42 darrenr Exp $";
-#endif
-
-#ifndef SOLARIS
-#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
-#endif
-
-#if defined(KERNEL) && !defined(_KERNEL)
-# define _KERNEL
-#endif
-#if defined(_KERNEL) && defined(__FreeBSD_version) && \
- (__FreeBSD_version >= 400000) && !defined(KLD_MODULE)
-#include "opt_inet6.h"
-#endif
-#include <sys/param.h>
-#if defined(__NetBSD__) && (NetBSD >= 199905) && !defined(IPFILTER_LKM) && \
- defined(_KERNEL)
-# include "opt_ipfilter_log.h"
-#endif
-#if defined(__FreeBSD__) && !defined(__FreeBSD_version)
-# if !defined(_KERNEL) || defined(IPFILTER_LKM)
-# include <osreldate.h>
-# endif
-#endif
-#ifndef _KERNEL
-# include <stdio.h>
-# include <string.h>
-# include <stdlib.h>
-# include <ctype.h>
-# include <fcntl.h>
-#endif
-#include <sys/errno.h>
-#include <sys/types.h>
-#include <sys/file.h>
-#if __FreeBSD_version >= 220000 && defined(_KERNEL)
-# include <sys/fcntl.h>
-# include <sys/filio.h>
-#else
-# include <sys/ioctl.h>
-#endif
-#include <sys/time.h>
-#ifdef _KERNEL
-# include <sys/systm.h>
-#endif
-#include <sys/uio.h>
-#if !SOLARIS
-# if (NetBSD > 199609) || (OpenBSD > 199603) || (__FreeBSD_version >= 300000)
-# include <sys/dirent.h>
-# else
-# include <sys/dir.h>
-# endif
-# include <sys/mbuf.h>
-#else
-# include <sys/filio.h>
-#endif
-#include <sys/protosw.h>
-#include <sys/socket.h>
-
-#include <net/if.h>
-#ifdef sun
-# include <net/af.h>
-#endif
-#if __FreeBSD_version >= 300000
-# include <net/if_var.h>
-# if defined(_KERNEL) && !defined(IPFILTER_LKM)
-# include "opt_ipfilter.h"
-# endif
-#endif
-#ifdef __sgi
-#include <sys/debug.h>
-# ifdef IFF_DRVRLOCK /* IRIX6 */
-#include <sys/hashing.h>
-# endif
-#endif
-#include <net/route.h>
-#include <netinet/in.h>
-#if !(defined(__sgi) && !defined(IFF_DRVRLOCK)) /* IRIX < 6 */
-# include <netinet/in_var.h>
-#endif
-#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>
-#ifndef _KERNEL
-# include <unistd.h>
-# include <syslog.h>
-#endif
-#include "netinet/ip_compat.h"
-#ifdef USE_INET6
-# include <netinet/icmp6.h>
-#endif
-#include "netinet/ip_fil.h"
-#include "netinet/ip_proxy.h"
-#include "netinet/ip_nat.h"
-#include "netinet/ip_frag.h"
-#include "netinet/ip_state.h"
-#include "netinet/ip_auth.h"
-#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
-# include <sys/malloc.h>
-#endif
-#ifndef MIN
-# define MIN(a,b) (((a)<(b))?(a):(b))
-#endif
-#if !SOLARIS && defined(_KERNEL) && !defined(__sgi)
-# include <sys/kernel.h>
-extern int ip_optcopy __P((struct ip *, struct ip *));
-#endif
-
-
-extern struct protosw inetsw[];
-
-#ifndef _KERNEL
-# include "ipt.h"
-static struct ifnet **ifneta = NULL;
-static int nifs = 0;
-#else
-# if (BSD < 199306) || defined(__sgi)
-extern int tcp_ttl;
-# endif
-#endif
-
-int ipl_unreach = ICMP_UNREACH_FILTER;
-u_long ipl_frouteok[2] = {0, 0};
-
-static int frzerostats __P((caddr_t));
-#if defined(__NetBSD__) || defined(__OpenBSD__) || (__FreeBSD_version >= 300003)
-static int frrequest __P((int, u_long, caddr_t, int));
-#else
-static int frrequest __P((int, int, caddr_t, int));
-#endif
-#ifdef _KERNEL
-static int (*fr_savep) __P((ip_t *, int, void *, int, struct mbuf **));
-static int send_ip __P((ip_t *, fr_info_t *, struct mbuf *));
-# ifdef __sgi
-extern kmutex_t ipf_rw;
-extern KRWLOCK_T ipf_mutex;
-# endif
-#else
-int ipllog __P((void));
-void init_ifp __P((void));
-# ifdef __sgi
-static int no_output __P((struct ifnet *, struct mbuf *,
- struct sockaddr *));
-static int write_output __P((struct ifnet *, struct mbuf *,
- struct sockaddr *));
-# else
-static int no_output __P((struct ifnet *, struct mbuf *,
- struct sockaddr *, struct rtentry *));
-static int write_output __P((struct ifnet *, struct mbuf *,
- struct sockaddr *, struct rtentry *));
-# endif
-#endif
-int fr_running = 0;
-
-#if (__FreeBSD_version >= 300000) && defined(_KERNEL)
-struct callout_handle ipfr_slowtimer_ch;
-#endif
-#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104230000)
-# include <sys/callout.h>
-struct callout ipfr_slowtimer_ch;
-#endif
-#if defined(__sgi) && defined(_KERNEL)
-toid_t ipfr_slowtimer_ch;
-#endif
-
-#if (_BSDI_VERSION >= 199510) && defined(_KERNEL)
-# include <sys/device.h>
-# include <sys/conf.h>
-
-struct cfdriver iplcd = {
- NULL, "ipl", NULL, NULL, DV_DULL, 0
-};
-
-struct devsw iplsw = {
- &iplcd,
- iplopen, iplclose, iplread, nowrite, iplioctl, noselect, nommap,
- nostrat, nodump, nopsize, 0,
- nostop
-};
-#endif /* _BSDI_VERSION >= 199510 && _KERNEL */
-
-#if defined(__NetBSD__) || defined(__OpenBSD__) || (_BSDI_VERSION >= 199701)
-# include <sys/conf.h>
-# if defined(NETBSD_PF)
-# include <net/pfil.h>
-/*
- * We provide the fr_checkp name just to minimize changes later.
- */
-int (*fr_checkp) __P((ip_t *ip, int hlen, void *ifp, int out, mb_t **mp));
-# endif /* NETBSD_PF */
-#endif /* __NetBSD__ */
-
-#ifdef _KERNEL
-# if defined(IPFILTER_LKM) && !defined(__sgi)
-int iplidentify(s)
-char *s;
-{
- if (strcmp(s, "ipl") == 0)
- return 1;
- return 0;
-}
-# endif /* IPFILTER_LKM */
-
-
-/*
- * Try to detect the case when compiling for NetBSD with pseudo-device
- */
-# if defined(__NetBSD__) && defined(PFIL_HOOKS)
-void
-ipfilterattach(count)
-int count;
-{
- if (iplattach() != 0)
- printf("IP Filter failed to attach\n");
-}
-# endif
-
-
-int iplattach()
-{
- char *defpass;
- int s;
-# if defined(__sgi) || (defined(NETBSD_PF) && (__NetBSD_Version__ >= 104200000))
- int error = 0;
-# endif
-
- SPL_NET(s);
- if (fr_running || (fr_checkp == fr_check)) {
- printf("IP Filter: already initialized\n");
- SPL_X(s);
- return EBUSY;
- }
-
-# ifdef IPFILTER_LOG
- ipflog_init();
-# endif
- if (nat_init() == -1)
- return -1;
- if (fr_stateinit() == -1)
- return -1;
- if (appr_init() == -1)
- return -1;
-
-# ifdef NETBSD_PF
-# if __NetBSD_Version__ >= 104200000
- error = pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
- &inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
- if (error) {
-# ifdef USE_INET6
- goto pfil_error;
-# else
- appr_unload();
- ip_natunload();
- fr_stateunload();
- return error;
-# endif
- }
-# else
- pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT);
-# endif
-# ifdef USE_INET6
- error = pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
- &inetsw[ip_protox[IPPROTO_IPV6]].pr_pfh);
- if (error) {
- pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
- &inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
-pfil_error:
- appr_unload();
- ip_natunload();
- fr_stateunload();
- return error;
- }
-# endif
-# endif
-
-# ifdef __sgi
- error = ipfilter_sgi_attach();
- if (error) {
- SPL_X(s);
- appr_unload();
- ip_natunload();
- fr_stateunload();
- return error;
- }
-# endif
-
- bzero((char *)frcache, sizeof(frcache));
- fr_savep = fr_checkp;
- fr_checkp = fr_check;
- fr_running = 1;
-
- SPL_X(s);
- if (fr_pass & FR_PASS)
- defpass = "pass";
- else if (fr_pass & FR_BLOCK)
- defpass = "block";
- else
- defpass = "no-match -> block";
-
- printf("%s initialized. Default = %s all, Logging = %s\n",
- ipfilter_version, defpass,
-# ifdef IPFILTER_LOG
- "enabled");
-# else
- "disabled");
-# endif
-#ifdef _KERNEL
-# if defined(__NetBSD__) && (__NetBSD_Version__ >= 104230000)
- callout_init(&ipfr_slowtimer_ch);
- callout_reset(&ipfr_slowtimer_ch, hz / 2, ipfr_slowtimer, NULL);
-# else
-# if (__FreeBSD_version >= 300000) || defined(__sgi)
- ipfr_slowtimer_ch = timeout(ipfr_slowtimer, NULL, hz/2);
-# else
- timeout(ipfr_slowtimer, NULL, hz/2);
-# endif
-# endif
-#endif
- return 0;
-}
-
-
-/*
- * Disable the filter by removing the hooks from the IP input/output
- * stream.
- */
-int ipldetach()
-{
- int s, i = FR_INQUE|FR_OUTQUE;
-#if defined(NETBSD_PF) && (__NetBSD_Version__ >= 104200000)
- int error = 0;
-#endif
-
-#ifdef _KERNEL
-# if defined(__NetBSD__) && (__NetBSD_Version__ >= 104230000)
- callout_stop(&ipfr_slowtimer_ch);
-# else
-# if (__FreeBSD_version >= 300000)
- untimeout(ipfr_slowtimer, NULL, ipfr_slowtimer_ch);
-# else
-# ifdef __sgi
- untimeout(ipfr_slowtimer_ch);
-# else
- untimeout(ipfr_slowtimer, NULL);
-# endif
-# endif /* FreeBSD */
-# endif /* NetBSD */
-#endif
- SPL_NET(s);
- if (!fr_running)
- {
- printf("IP Filter: not initialized\n");
- SPL_X(s);
- return 0;
- }
-
- printf("%s unloaded\n", ipfilter_version);
-
- fr_checkp = fr_savep;
- i = frflush(IPL_LOGIPF, i);
- fr_running = 0;
-
-# ifdef NETBSD_PF
-# if __NetBSD_Version__ >= 104200000
- error = pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
- &inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
- if (error)
- return error;
-# else
- pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT);
-# endif
-# ifdef USE_INET6
- error = pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
- &inetsw[ip_protox[IPPROTO_IPV6]].pr_pfh);
- if (error)
- return error;
-# endif
-# endif
-
-# ifdef __sgi
- ipfilter_sgi_detach();
-# endif
-
- appr_unload();
- ipfr_unload();
- ip_natunload();
- fr_stateunload();
- fr_authunload();
-
- SPL_X(s);
- return 0;
-}
-#endif /* _KERNEL */
-
-
-static int frzerostats(data)
-caddr_t data;
-{
- friostat_t fio;
- int error;
-
- fr_getstat(&fio);
- error = IWCOPYPTR((caddr_t)&fio, data, sizeof(fio));
- if (error)
- return EFAULT;
-
- bzero((char *)frstats, sizeof(*frstats) * 2);
-
- return 0;
-}
-
-
-/*
- * Filter ioctl interface.
- */
-#ifdef __sgi
-int IPL_EXTERN(ioctl)(dev_t dev, int cmd, caddr_t data, int mode
-# ifdef _KERNEL
- , cred_t *cp, int *rp
-# endif
-)
-#else
-int IPL_EXTERN(ioctl)(dev, cmd, data, mode
-# if (defined(_KERNEL) && ((_BSDI_VERSION >= 199510) || (BSD >= 199506) || \
- (NetBSD >= 199511) || (__FreeBSD_version >= 220000) || \
- defined(__OpenBSD__)))
-, p)
-struct proc *p;
-# else
-)
-# endif
-dev_t dev;
-# if defined(__NetBSD__) || defined(__OpenBSD__) || \
- (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000)
-u_long cmd;
-# else
-int cmd;
-# endif
-caddr_t data;
-int mode;
-#endif /* __sgi */
-{
-#if defined(_KERNEL) && !SOLARIS
- int s;
-#endif
- int error = 0, unit = 0, tmp;
-
-#if (BSD >= 199306) && defined(_KERNEL)
- if ((securelevel >= 2) && (mode & FWRITE))
- return EPERM;
-#endif
-#ifdef _KERNEL
- unit = GET_MINOR(dev);
- if ((IPL_LOGMAX < unit) || (unit < 0))
- return ENXIO;
-#else
- unit = dev;
-#endif
-
- SPL_NET(s);
-
- if (unit == IPL_LOGNAT) {
- if (fr_running)
- error = nat_ioctl(data, cmd, mode);
- else
- error = EIO;
- SPL_X(s);
- return error;
- }
- if (unit == IPL_LOGSTATE) {
- if (fr_running)
- error = fr_state_ioctl(data, cmd, mode);
- else
- error = EIO;
- SPL_X(s);
- return error;
- }
- if (unit == IPL_LOGAUTH) {
- if (!fr_running)
- return EIO;
- error = fr_auth_ioctl(data, cmd, NULL, NULL);
- SPL_X(s);
- return error;
- }
-
- switch (cmd) {
- case FIONREAD :
-#ifdef IPFILTER_LOG
- error = IWCOPY((caddr_t)&iplused[IPL_LOGIPF], (caddr_t)data,
- sizeof(iplused[IPL_LOGIPF]));
-#endif
- break;
-#if !defined(IPFILTER_LKM) && defined(_KERNEL)
- case SIOCFRENB :
- {
- u_int enable;
-
- if (!(mode & FWRITE))
- error = EPERM;
- else {
- error = IRCOPY(data, (caddr_t)&enable, sizeof(enable));
- if (error)
- break;
- if (enable)
- error = iplattach();
- else
- error = ipldetach();
- }
- break;
- }
-#endif
- case SIOCSETFF :
- if (!(mode & FWRITE))
- error = EPERM;
- else
- error = IRCOPY(data, (caddr_t)&fr_flags,
- sizeof(fr_flags));
- break;
- case SIOCGETFF :
- error = IWCOPY((caddr_t)&fr_flags, data, sizeof(fr_flags));
- break;
- case SIOCINAFR :
- case SIOCRMAFR :
- case SIOCADAFR :
- case SIOCZRLST :
- if (!(mode & FWRITE))
- error = EPERM;
- else
- error = frrequest(unit, cmd, data, fr_active);
- break;
- case SIOCINIFR :
- case SIOCRMIFR :
- case SIOCADIFR :
- if (!(mode & FWRITE))
- error = EPERM;
- else
- error = frrequest(unit, cmd, data, 1 - fr_active);
- break;
- case SIOCSWAPA :
- if (!(mode & FWRITE))
- error = EPERM;
- else {
- bzero((char *)frcache, sizeof(frcache[0]) * 2);
- *(u_int *)data = fr_active;
- fr_active = 1 - fr_active;
- }
- break;
- case SIOCGETFS :
- {
- friostat_t fio;
-
- fr_getstat(&fio);
- error = IWCOPYPTR((caddr_t)&fio, data, sizeof(fio));
- if (error)
- return EFAULT;
- break;
- }
- case SIOCFRZST :
- if (!(mode & FWRITE))
- error = EPERM;
- else
- error = frzerostats(data);
- break;
- case SIOCIPFFL :
- if (!(mode & FWRITE))
- error = EPERM;
- else {
- error = IRCOPY(data, (caddr_t)&tmp, sizeof(tmp));
- if (!error) {
- tmp = frflush(unit, tmp);
- error = IWCOPY((caddr_t)&tmp, data,
- sizeof(tmp));
- }
- }
- break;
- case SIOCSTLCK :
- error = IRCOPY(data, (caddr_t)&tmp, sizeof(tmp));
- if (!error) {
- fr_state_lock = tmp;
- fr_nat_lock = tmp;
- fr_frag_lock = tmp;
- fr_auth_lock = tmp;
- } else
- error = EFAULT;
- break;
-#ifdef IPFILTER_LOG
- case SIOCIPFFB :
- if (!(mode & FWRITE))
- error = EPERM;
- else
- *(int *)data = ipflog_clear(unit);
- break;
-#endif /* IPFILTER_LOG */
- case SIOCGFRST :
- error = IWCOPYPTR((caddr_t)ipfr_fragstats(), data,
- sizeof(ipfrstat_t));
- if (error)
- return EFAULT;
- break;
- case SIOCAUTHW :
- case SIOCAUTHR :
- if (!(mode & FWRITE)) {
- error = EPERM;
- break;
- }
- case SIOCFRSYN :
- if (!(mode & FWRITE))
- error = EPERM;
- else {
-#if defined(_KERNEL) && defined(__sgi)
- ipfsync();
-#endif
- frsync();
- }
- break;
- default :
- error = EINVAL;
- break;
- }
- SPL_X(s);
- return error;
-}
-
-
-void fr_forgetifp(ifp)
-void *ifp;
-{
- register frentry_t *f;
-
- WRITE_ENTER(&ipf_mutex);
- for (f = ipacct[0][fr_active]; (f != NULL); f = f->fr_next)
- if (f->fr_ifa == ifp)
- f->fr_ifa = (void *)-1;
- for (f = ipacct[1][fr_active]; (f != NULL); f = f->fr_next)
- if (f->fr_ifa == ifp)
- f->fr_ifa = (void *)-1;
- for (f = ipfilter[0][fr_active]; (f != NULL); f = f->fr_next)
- if (f->fr_ifa == ifp)
- f->fr_ifa = (void *)-1;
- for (f = ipfilter[1][fr_active]; (f != NULL); f = f->fr_next)
- if (f->fr_ifa == ifp)
- f->fr_ifa = (void *)-1;
-#ifdef USE_INET6
- for (f = ipacct6[0][fr_active]; (f != NULL); f = f->fr_next)
- if (f->fr_ifa == ifp)
- f->fr_ifa = (void *)-1;
- for (f = ipacct6[1][fr_active]; (f != NULL); f = f->fr_next)
- if (f->fr_ifa == ifp)
- f->fr_ifa = (void *)-1;
- for (f = ipfilter6[0][fr_active]; (f != NULL); f = f->fr_next)
- if (f->fr_ifa == ifp)
- f->fr_ifa = (void *)-1;
- for (f = ipfilter6[1][fr_active]; (f != NULL); f = f->fr_next)
- if (f->fr_ifa == ifp)
- f->fr_ifa = (void *)-1;
-#endif
- RWLOCK_EXIT(&ipf_mutex);
- ip_natsync(ifp);
-}
-
-
-static int frrequest(unit, req, data, set)
-int unit;
-#if defined(__NetBSD__) || defined(__OpenBSD__) || (__FreeBSD_version >= 300003)
-u_long req;
-#else
-int req;
-#endif
-int set;
-caddr_t data;
-{
- register frentry_t *fp, *f, **fprev;
- register frentry_t **ftail;
- frentry_t frd;
- frdest_t *fdp;
- frgroup_t *fg = NULL;
- u_int *p, *pp;
- int error = 0, in;
- u_int group;
-
- fp = &frd;
- error = IRCOPYPTR(data, (caddr_t)fp, sizeof(*fp));
- if (error)
- return EFAULT;
- fp->fr_ref = 0;
-#if (BSD >= 199306) && defined(_KERNEL)
- if ((securelevel > 0) && (fp->fr_func != NULL))
- return EPERM;
-#endif
-
- /*
- * Check that the group number does exist and that if a head group
- * has been specified, doesn't exist.
- */
- if ((req != SIOCZRLST) && fp->fr_grhead &&
- fr_findgroup((u_int)fp->fr_grhead, fp->fr_flags, unit, set, NULL))
- return EEXIST;
- if ((req != SIOCZRLST) && fp->fr_group &&
- !fr_findgroup((u_int)fp->fr_group, fp->fr_flags, unit, set, NULL))
- return ESRCH;
-
- in = (fp->fr_flags & FR_INQUE) ? 0 : 1;
-
- if (unit == IPL_LOGAUTH)
- ftail = fprev = &ipauth;
- else if ((fp->fr_flags & FR_ACCOUNT) && (fp->fr_v == 4))
- ftail = fprev = &ipacct[in][set];
- else if ((fp->fr_flags & (FR_OUTQUE|FR_INQUE)) && (fp->fr_v == 4))
- ftail = fprev = &ipfilter[in][set];
-#ifdef USE_INET6
- else if ((fp->fr_flags & FR_ACCOUNT) && (fp->fr_v == 6))
- ftail = fprev = &ipacct6[in][set];
- else if ((fp->fr_flags & (FR_OUTQUE|FR_INQUE)) && (fp->fr_v == 6))
- ftail = fprev = &ipfilter6[in][set];
-#endif
- else
- return ESRCH;
-
- if ((group = fp->fr_group)) {
- if (!(fg = fr_findgroup(group, fp->fr_flags, unit, set, NULL)))
- return ESRCH;
- ftail = fprev = fg->fg_start;
- }
-
- bzero((char *)frcache, sizeof(frcache[0]) * 2);
-
- if (*fp->fr_ifname) {
- fp->fr_ifa = GETUNIT(fp->fr_ifname, fp->fr_v);
- if (!fp->fr_ifa)
- fp->fr_ifa = (void *)-1;
- }
-#if BSD >= 199306
- if (*fp->fr_oifname) {
- fp->fr_oifa = GETUNIT(fp->fr_oifname, fp->fr_v);
- if (!fp->fr_oifa)
- fp->fr_oifa = (void *)-1;
- }
-#endif
-
- fdp = &fp->fr_dif;
- fp->fr_flags &= ~FR_DUP;
- if (*fdp->fd_ifname) {
- fdp->fd_ifp = GETUNIT(fdp->fd_ifname, fp->fr_v);
- if (!fdp->fd_ifp)
- fdp->fd_ifp = (struct ifnet *)-1;
- else
- fp->fr_flags |= FR_DUP;
- }
-
- fdp = &fp->fr_tif;
- if (*fdp->fd_ifname) {
- fdp->fd_ifp = GETUNIT(fdp->fd_ifname, fp->fr_v);
- if (!fdp->fd_ifp)
- fdp->fd_ifp = (struct ifnet *)-1;
- }
-
- /*
- * Look for a matching filter rule, but don't include the next or
- * interface pointer in the comparison (fr_next, fr_ifa).
- */
- for (fp->fr_cksum = 0, p = (u_int *)&fp->fr_ip, pp = &fp->fr_cksum;
- p < pp; p++)
- fp->fr_cksum += *p;
-
- for (; (f = *ftail); ftail = &f->fr_next)
- if ((fp->fr_cksum == f->fr_cksum) &&
- !bcmp((char *)&f->fr_ip, (char *)&fp->fr_ip, FR_CMPSIZ))
- break;
-
- /*
- * If zero'ing statistics, copy current to caller and zero.
- */
- if (req == SIOCZRLST) {
- if (!f)
- return ESRCH;
- error = IWCOPYPTR((caddr_t)f, data, sizeof(*f));
- if (error)
- return EFAULT;
- f->fr_hits = 0;
- f->fr_bytes = 0;
- return 0;
- }
-
- if (!f) {
- if (req != SIOCINAFR && req != SIOCINIFR)
- while ((f = *ftail))
- ftail = &f->fr_next;
- else {
- if (fp->fr_hits) {
- ftail = fprev;
- while (--fp->fr_hits && (f = *ftail))
- ftail = &f->fr_next;
- }
- f = NULL;
- }
- }
-
- if (req == SIOCRMAFR || req == SIOCRMIFR) {
- if (!f)
- error = ESRCH;
- else {
- /*
- * Only return EBUSY if there is a group list, else
- * it's probably just state information referencing
- * the rule.
- */
- if ((f->fr_ref > 1) && f->fr_grp)
- return EBUSY;
- if (fg && fg->fg_head)
- fg->fg_head->fr_ref--;
- if (unit == IPL_LOGAUTH)
- return fr_auth_ioctl(data, req, f, ftail);
- if (f->fr_grhead)
- fr_delgroup((u_int)f->fr_grhead, fp->fr_flags,
- unit, set);
- fixskip(fprev, f, -1);
- *ftail = f->fr_next;
- f->fr_next = NULL;
- if (f->fr_ref == 0)
- KFREE(f);
- }
- } else {
- if (f)
- error = EEXIST;
- else {
- if (unit == IPL_LOGAUTH)
- return fr_auth_ioctl(data, req, fp, ftail);
- KMALLOC(f, frentry_t *);
- if (f != NULL) {
- if (fg && fg->fg_head)
- fg->fg_head->fr_ref++;
- bcopy((char *)fp, (char *)f, sizeof(*f));
- f->fr_ref = 1;
- f->fr_hits = 0;
- f->fr_next = *ftail;
- *ftail = f;
- if (req == SIOCINIFR || req == SIOCINAFR)
- fixskip(fprev, f, 1);
- f->fr_grp = NULL;
- if ((group = f->fr_grhead))
- fg = fr_addgroup(group, f, unit, set);
- } else
- error = ENOMEM;
- }
- }
- return (error);
-}
-
-
-#ifdef _KERNEL
-/*
- * routines below for saving IP headers to buffer
- */
-# ifdef __sgi
-# ifdef _KERNEL
-int IPL_EXTERN(open)(dev_t *pdev, int flags, int devtype, cred_t *cp)
-# else
-int IPL_EXTERN(open)(dev_t dev, int flags)
-# endif
-# else
-int IPL_EXTERN(open)(dev, flags
-# if ((_BSDI_VERSION >= 199510) || (BSD >= 199506) || (NetBSD >= 199511) || \
- (__FreeBSD_version >= 220000) || defined(__OpenBSD__)) && defined(_KERNEL)
-, devtype, p)
-int devtype;
-struct proc *p;
-# else
-)
-# endif
-dev_t dev;
-int flags;
-# endif /* __sgi */
-{
-# if defined(__sgi) && defined(_KERNEL)
- u_int min = geteminor(*pdev);
-# else
- u_int min = GET_MINOR(dev);
-# endif
-
- if (IPL_LOGMAX < min)
- min = ENXIO;
- else
- min = 0;
- return min;
-}
-
-
-# ifdef __sgi
-int IPL_EXTERN(close)(dev_t dev, int flags, int devtype, cred_t *cp)
-#else
-int IPL_EXTERN(close)(dev, flags
-# if ((_BSDI_VERSION >= 199510) || (BSD >= 199506) || (NetBSD >= 199511) || \
- (__FreeBSD_version >= 220000) || defined(__OpenBSD__)) && defined(_KERNEL)
-, devtype, p)
-int devtype;
-struct proc *p;
-# else
-)
-# endif
-dev_t dev;
-int flags;
-# endif /* __sgi */
-{
- u_int min = GET_MINOR(dev);
-
- if (IPL_LOGMAX < min)
- min = ENXIO;
- else
- min = 0;
- return min;
-}
-
-/*
- * iplread/ipllog
- * both of these must operate with at least splnet() lest they be
- * called during packet processing and cause an inconsistancy to appear in
- * the filter lists.
- */
-# ifdef __sgi
-int IPL_EXTERN(read)(dev_t dev, uio_t *uio, cred_t *crp)
-# else
-# if BSD >= 199306
-int IPL_EXTERN(read)(dev, uio, ioflag)
-int ioflag;
-# else
-int IPL_EXTERN(read)(dev, uio)
-# endif
-dev_t dev;
-register struct uio *uio;
-# endif /* __sgi */
-{
-# ifdef IPFILTER_LOG
- return ipflog_read(GET_MINOR(dev), uio);
-# else
- return ENXIO;
-# endif
-}
-
-
-/*
- * send_reset - this could conceivably be a call to tcp_respond(), but that
- * requires a large amount of setting up and isn't any more efficient.
- */
-int send_reset(oip, fin)
-struct ip *oip;
-fr_info_t *fin;
-{
- struct tcphdr *tcp, *tcp2;
- int tlen = 0, hlen;
- struct mbuf *m;
-#ifdef USE_INET6
- ip6_t *ip6, *oip6 = (ip6_t *)oip;
-#endif
- ip_t *ip;
-
- tcp = (struct tcphdr *)fin->fin_dp;
- if (tcp->th_flags & TH_RST)
- return -1; /* feedback loop */
-# if (BSD < 199306) || defined(__sgi)
- m = m_get(M_DONTWAIT, MT_HEADER);
-# else
- m = m_gethdr(M_DONTWAIT, MT_HEADER);
-# endif
- if (m == NULL)
- return ENOBUFS;
- if (m == NULL)
- return -1;
-
- tlen = oip->ip_len - fin->fin_hlen - (tcp->th_off << 2) +
- ((tcp->th_flags & TH_SYN) ? 1 : 0) +
- ((tcp->th_flags & TH_FIN) ? 1 : 0);
-
-#ifdef USE_INET6
- hlen = (fin->fin_v == 6) ? sizeof(ip6_t) : sizeof(ip_t);
-#else
- hlen = sizeof(ip_t);
-#endif
- m->m_len = sizeof(*tcp2) + hlen;
-# if BSD >= 199306
- m->m_data += max_linkhdr;
- m->m_pkthdr.len = m->m_len;
- m->m_pkthdr.rcvif = (struct ifnet *)0;
-# endif
- ip = mtod(m, struct ip *);
-# ifdef USE_INET6
- ip6 = (ip6_t *)ip;
-# endif
- bzero((char *)ip, sizeof(*tcp2) + hlen);
- tcp2 = (struct tcphdr *)((char *)ip + hlen);
-
- tcp2->th_sport = tcp->th_dport;
- tcp2->th_dport = tcp->th_sport;
- if (tcp->th_flags & TH_ACK) {
- tcp2->th_seq = tcp->th_ack;
- tcp2->th_flags = TH_RST;
- } else {
- tcp2->th_ack = ntohl(tcp->th_seq);
- tcp2->th_ack += tlen;
- tcp2->th_ack = htonl(tcp2->th_ack);
- tcp2->th_flags = TH_RST|TH_ACK;
- }
- tcp2->th_off = sizeof(*tcp2) >> 2;
-# ifdef USE_INET6
- if (fin->fin_v == 6) {
- ip6->ip6_plen = htons(sizeof(struct tcphdr));
- ip6->ip6_nxt = IPPROTO_TCP;
- ip6->ip6_src = oip6->ip6_dst;
- ip6->ip6_dst = oip6->ip6_src;
- tcp2->th_sum = in6_cksum(m, IPPROTO_TCP,
- sizeof(*ip6), sizeof(*tcp2));
- return send_ip(oip, fin, m);
- }
-# endif
- ip->ip_p = IPPROTO_TCP;
- ip->ip_len = htons(sizeof(struct tcphdr));
- ip->ip_src.s_addr = oip->ip_dst.s_addr;
- ip->ip_dst.s_addr = oip->ip_src.s_addr;
- tcp2->th_sum = in_cksum(m, hlen + sizeof(*tcp2));
- ip->ip_len = hlen + sizeof(*tcp2);
- return send_ip(oip, fin, m);
-}
-
-
-static int send_ip(oip, fin, m)
-ip_t *oip;
-fr_info_t *fin;
-struct mbuf *m;
-{
- ip_t *ip;
-
- ip = mtod(m, ip_t *);
-
- ip->ip_v = fin->fin_v;
- if (ip->ip_v == 4) {
- ip->ip_hl = (sizeof(*oip) >> 2);
- ip->ip_v = IPVERSION;
- ip->ip_tos = oip->ip_tos;
- ip->ip_id = oip->ip_id;
- ip->ip_off = 0;
-# if (BSD < 199306) || defined(__sgi)
- ip->ip_ttl = tcp_ttl;
-# else
- ip->ip_ttl = ip_defttl;
-# endif
- ip->ip_sum = 0;
- }
-# ifdef USE_INET6
- else if (ip->ip_v == 6) {
- ip6_t *ip6 = (ip6_t *)ip;
-
- ip6->ip6_hlim = 127;
-
- return ip6_output(m, NULL, NULL, 0, NULL, NULL);
- }
-# endif
-# ifdef IPSEC
- m->m_pkthdr.rcvif = NULL;
-# endif
- return ipfr_fastroute(m, fin, NULL);
-}
-
-
-int send_icmp_err(oip, type, fin, dst)
-ip_t *oip;
-int type;
-fr_info_t *fin;
-int dst;
-{
- int err, hlen = 0, xtra = 0, iclen, ohlen = 0, avail, code;
- struct in_addr dst4;
- struct icmp *icmp;
- struct mbuf *m;
- void *ifp;
-#ifdef USE_INET6
- ip6_t *ip6, *oip6 = (ip6_t *)oip;
- struct in6_addr dst6;
-#endif
- ip_t *ip;
-
- if ((type < 0) || (type > ICMP_MAXTYPE))
- return -1;
-
- code = fin->fin_icode;
-#ifdef USE_INET6
- if ((code < 0) || (code > sizeof(icmptoicmp6unreach)/sizeof(int)))
- return -1;
-#endif
-
- avail = 0;
- m = NULL;
- ifp = fin->fin_ifp;
- if (fin->fin_v == 4) {
- if ((oip->ip_p == IPPROTO_ICMP) &&
- !(fin->fin_fi.fi_fl & FI_SHORT))
- switch (ntohs(fin->fin_data[0]) >> 8)
- {
- case ICMP_ECHO :
- case ICMP_TSTAMP :
- case ICMP_IREQ :
- case ICMP_MASKREQ :
- break;
- default :
- return 0;
- }
-
-# if (BSD < 199306) || defined(__sgi)
- avail = MLEN;
- m = m_get(M_DONTWAIT, MT_HEADER);
-# else
- avail = MHLEN;
- m = m_gethdr(M_DONTWAIT, MT_HEADER);
-# endif
- if (m == NULL)
- return ENOBUFS;
-
- if (dst == 0) {
- if (fr_ifpaddr(4, ifp, &dst4) == -1)
- return -1;
- } else
- dst4.s_addr = oip->ip_dst.s_addr;
-
- hlen = sizeof(ip_t);
- ohlen = oip->ip_hl << 2;
- xtra = 8;
- }
-
-#ifdef USE_INET6
- else if (fin->fin_v == 6) {
- hlen = sizeof(ip6_t);
- ohlen = sizeof(ip6_t);
- type = icmptoicmp6types[type];
- if (type == ICMP6_DST_UNREACH)
- code = icmptoicmp6unreach[code];
-
- MGETHDR(m, M_DONTWAIT, MT_HEADER);
- if (!m)
- return ENOBUFS;
-
- MCLGET(m, M_DONTWAIT);
- if ((m->m_flags & M_EXT) == 0) {
- m_freem(m);
- return ENOBUFS;
- }
-# ifdef M_TRAILINGSPACE
- m->m_len = 0;
- avail = M_TRAILINGSPACE(m);
-# else
- avail = (m->m_flags & M_EXT) ? MCLBYTES : MHLEN;
-# endif
- xtra = MIN(ntohs(oip6->ip6_plen) + sizeof(ip6_t),
- avail - hlen - sizeof(*icmp) - max_linkhdr);
- if (dst == 0) {
- if (fr_ifpaddr(6, ifp, (struct in_addr *)&dst6) == -1)
- return -1;
- } else
- dst6 = oip6->ip6_dst;
- }
-#endif
-
- iclen = hlen + sizeof(*icmp);
-# if BSD >= 199306
- avail -= (max_linkhdr + iclen);
- m->m_data += max_linkhdr;
- m->m_pkthdr.rcvif = (struct ifnet *)0;
- if (xtra > avail)
- xtra = avail;
- iclen += xtra;
- m->m_pkthdr.len = iclen;
-#else
- avail -= (m->m_off + iclen);
- if (xtra > avail)
- xtra = avail;
- iclen += xtra;
-#endif
- m->m_len = iclen;
- ip = mtod(m, ip_t *);
- icmp = (struct icmp *)((char *)ip + hlen);
- bzero((char *)ip, iclen);
-
- icmp->icmp_type = type;
- icmp->icmp_code = fin->fin_icode;
- icmp->icmp_cksum = 0;
-#ifdef icmp_nextmtu
- if (type == ICMP_UNREACH &&
- fin->fin_icode == ICMP_UNREACH_NEEDFRAG && ifp)
- icmp->icmp_nextmtu = htons(((struct ifnet *) ifp)->if_mtu);
-#endif
-
- if (avail) {
- bcopy((char *)oip, (char *)&icmp->icmp_ip, MIN(ohlen, avail));
- avail -= MIN(ohlen, avail);
- }
-
-#ifdef USE_INET6
- ip6 = (ip6_t *)ip;
- if (fin->fin_v == 6) {
- ip6->ip6_flow = 0;
- ip6->ip6_plen = htons(iclen - hlen);
- ip6->ip6_nxt = IPPROTO_ICMPV6;
- ip6->ip6_hlim = 0;
- ip6->ip6_src = dst6;
- ip6->ip6_dst = oip6->ip6_src;
- if (avail)
- bcopy((char *)oip + ohlen,
- (char *)&icmp->icmp_ip + ohlen, avail);
- icmp->icmp_cksum = in6_cksum(m, IPPROTO_ICMPV6,
- sizeof(*ip6), iclen - hlen);
- } else
-#endif
- {
- ip->ip_src.s_addr = dst4.s_addr;
- ip->ip_dst.s_addr = oip->ip_src.s_addr;
-
- if (avail > 8)
- avail = 8;
- if (avail)
- bcopy((char *)oip + ohlen,
- (char *)&icmp->icmp_ip + ohlen, avail);
- icmp->icmp_cksum = ipf_cksum((u_short *)icmp,
- sizeof(*icmp) + 8);
- ip->ip_len = iclen;
- ip->ip_p = IPPROTO_ICMP;
- }
- err = send_ip(oip, fin, m);
- return err;
-}
-
-
-# if !defined(IPFILTER_LKM) && (__FreeBSD_version < 300000) && !defined(__sgi)
-# if (BSD < 199306)
-int iplinit __P((void));
-
-int
-# else
-void iplinit __P((void));
-
-void
-# endif
-iplinit()
-{
- if (iplattach() != 0)
- printf("IP Filter failed to attach\n");
- ip_init();
-}
-# endif /* ! __NetBSD__ */
-
-
-size_t mbufchainlen(m0)
-register struct mbuf *m0;
-{
- register size_t len = 0;
-
- for (; m0; m0 = m0->m_next)
- len += m0->m_len;
- return len;
-}
-
-
-int ipfr_fastroute(m0, fin, fdp)
-struct mbuf *m0;
-fr_info_t *fin;
-frdest_t *fdp;
-{
- register struct ip *ip, *mhip;
- register struct mbuf *m = m0;
- register struct route *ro;
- int len, off, error = 0, hlen, code;
- struct ifnet *ifp, *sifp;
- struct sockaddr_in *dst;
- struct route iproute;
- frentry_t *fr;
-
- hlen = fin->fin_hlen;
- ip = mtod(m0, struct ip *);
-
-#ifdef USE_INET6
- if (ip->ip_v == 6) {
- /*
- * currently "to <if>" and "to <if>:ip#" are not supported
- * for IPv6
- */
- return ip6_output(m0, NULL, NULL, 0, NULL, NULL);
- }
-#endif
- /*
- * Route packet.
- */
- ro = &iproute;
- bzero((caddr_t)ro, sizeof (*ro));
- dst = (struct sockaddr_in *)&ro->ro_dst;
- dst->sin_family = AF_INET;
-
- fr = fin->fin_fr;
- if (fdp)
- ifp = fdp->fd_ifp;
- else {
- ifp = fin->fin_ifp;
- dst->sin_addr = ip->ip_dst;
- }
-
- /*
- * 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) && (fin->fin_rev != 0)) {
- if ((ifp != NULL) && (fdp == &fr->fr_tif))
- return -1;
- dst->sin_addr = ip->ip_dst;
- } else if (fdp)
- dst->sin_addr = fdp->fd_ip.s_addr ? fdp->fd_ip : ip->ip_dst;
-
-# if BSD >= 199306
- dst->sin_len = sizeof(*dst);
-# endif
-# if (BSD >= 199306) && !defined(__NetBSD__) && !defined(__bsdi__) && \
- !defined(__OpenBSD__)
-# ifdef RTF_CLONING
- rtalloc_ign(ro, RTF_CLONING);
-# else
- rtalloc_ign(ro, RTF_PRCLONING);
-# endif
-# else
- rtalloc(ro);
-# endif
- if (!ifp) {
- if (!fr || !(fr->fr_flags & FR_FASTROUTE)) {
- error = -2;
- goto bad;
- }
- if (ro->ro_rt == 0 || (ifp = ro->ro_rt->rt_ifp) == 0) {
- if (in_localaddr(ip->ip_dst))
- error = EHOSTUNREACH;
- else
- error = ENETUNREACH;
- goto bad;
- }
- if (ro->ro_rt->rt_flags & RTF_GATEWAY)
- dst = (struct sockaddr_in *)&ro->ro_rt->rt_gateway;
- }
- if (ro->ro_rt)
- ro->ro_rt->rt_use++;
-
- /*
- * For input packets which are being "fastrouted", they won't
- * go back through output filtering and miss their chance to get
- * NAT'd and counted.
- */
- fin->fin_ifp = ifp;
- if (fin->fin_out == 0) {
- fin->fin_out = 1;
- if ((fin->fin_fr = ipacct[1][fr_active]) &&
- (fr_scanlist(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT)) {
- ATOMIC_INCL(frstats[1].fr_acct);
- }
- fin->fin_fr = NULL;
- if (!fr || !(fr->fr_flags & FR_RETMASK))
- (void) fr_checkstate(ip, fin);
- (void) ip_natout(ip, fin);
- } else
- ip->ip_sum = 0;
- /*
- * If small enough for interface, can just send directly.
- */
- if (ip->ip_len <= ifp->if_mtu) {
-# if BSD >= 199306
- int i = 0;
-
-# ifdef MCLISREFERENCED
- if ((m->m_flags & M_EXT) && MCLISREFERENCED(m))
-# else
- if (m->m_flags & M_EXT)
-# endif
- i = 1;
-# endif
-# ifndef sparc
- ip->ip_id = htons(ip->ip_id);
- ip->ip_len = htons(ip->ip_len);
- ip->ip_off = htons(ip->ip_off);
-# endif
- if (!ip->ip_sum)
- ip->ip_sum = in_cksum(m, hlen);
-# if BSD >= 199306
- error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst,
- ro->ro_rt);
- if (i) {
- ip->ip_id = ntohs(ip->ip_id);
- ip->ip_len = ntohs(ip->ip_len);
- ip->ip_off = ntohs(ip->ip_off);
- }
-# else
- error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst);
-# endif
- goto done;
- }
- /*
- * Too large for interface; fragment if possible.
- * Must be able to put at least 8 bytes per fragment.
- */
- if (ip->ip_off & IP_DF) {
- error = EMSGSIZE;
- goto bad;
- }
- len = (ifp->if_mtu - hlen) &~ 7;
- if (len < 8) {
- error = EMSGSIZE;
- goto bad;
- }
-
- {
- int mhlen, firstlen = len;
- struct mbuf **mnext = &m->m_act;
-
- /*
- * Loop through length of segment after first fragment,
- * make new header and copy data of each part and link onto chain.
- */
- m0 = m;
- mhlen = sizeof (struct ip);
- for (off = hlen + len; off < ip->ip_len; off += len) {
-# ifdef MGETHDR
- MGETHDR(m, M_DONTWAIT, MT_HEADER);
-# else
- MGET(m, M_DONTWAIT, MT_HEADER);
-# endif
- if (m == 0) {
- error = ENOBUFS;
- goto bad;
- }
-# if BSD >= 199306
- m->m_data += max_linkhdr;
-# else
- m->m_off = MMAXOFF - hlen;
-# endif
- mhip = mtod(m, struct ip *);
- bcopy((char *)ip, (char *)mhip, sizeof(*ip));
- if (hlen > sizeof (struct ip)) {
- mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip);
- mhip->ip_hl = mhlen >> 2;
- }
- m->m_len = mhlen;
- mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF);
- if (ip->ip_off & IP_MF)
- mhip->ip_off |= IP_MF;
- if (off + len >= ip->ip_len)
- len = ip->ip_len - off;
- else
- mhip->ip_off |= IP_MF;
- mhip->ip_len = htons((u_short)(len + mhlen));
- m->m_next = m_copy(m0, off, len);
- if (m->m_next == 0) {
- 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
- mhip->ip_sum = 0;
- mhip->ip_sum = in_cksum(m, mhlen);
- *mnext = m;
- mnext = &m->m_act;
- }
- /*
- * Update first fragment by trimming what's been copied out
- * and updating header, then send each fragment (in order).
- */
- m_adj(m0, hlen + firstlen - ip->ip_len);
- ip->ip_len = htons((u_short)(hlen + firstlen));
- ip->ip_off = htons((u_short)(ip->ip_off | IP_MF));
- ip->ip_sum = 0;
- ip->ip_sum = in_cksum(m0, hlen);
-sendorfree:
- for (m = m0; m; m = m0) {
- m0 = m->m_act;
- m->m_act = 0;
- if (error == 0)
-# if BSD >= 199306
- error = (*ifp->if_output)(ifp, m,
- (struct sockaddr *)dst, ro->ro_rt);
-# else
- error = (*ifp->if_output)(ifp, m,
- (struct sockaddr *)dst);
-# endif
- else
- m_freem(m);
- }
- }
-done:
- if (!error)
- ipl_frouteok[0]++;
- else
- ipl_frouteok[1]++;
-
- if (ro->ro_rt)
- RTFREE(ro->ro_rt);
- return 0;
-bad:
- if (error == EMSGSIZE) {
- sifp = fin->fin_ifp;
- code = fin->fin_icode;
- fin->fin_icode = ICMP_UNREACH_NEEDFRAG;
- fin->fin_ifp = ifp;
- (void) send_icmp_err(ip, ICMP_UNREACH, fin, 1);
- fin->fin_ifp = sifp;
- fin->fin_icode = code;
- }
- m_freem(m);
- goto done;
-}
-
-
-int fr_verifysrc(ipa, ifp)
-struct in_addr ipa;
-void *ifp;
-{
- struct sockaddr_in *dst;
- struct route iproute;
-
- bzero((char *)&iproute, sizeof(iproute));
- dst = (struct sockaddr_in *)&iproute.ro_dst;
- dst->sin_family = AF_INET;
- dst->sin_addr = ipa;
-# if (BSD >= 199306) && !defined(__NetBSD__) && !defined(__bsdi__) && \
- !defined(__OpenBSD__)
-# ifdef RTF_CLONING
- rtalloc_ign(&iproute, RTF_CLONING);
-# else
- rtalloc_ign(&iproute, RTF_PRCLONING);
-# endif
-# else
- rtalloc(&iproute);
-# endif
- if (iproute.ro_rt == NULL)
- return 0;
- return (ifp == iproute.ro_rt->rt_ifp);
-}
-
-#else /* #ifdef _KERNEL */
-
-
-# ifdef __sgi
-static int no_output __P((struct ifnet *ifp, struct mbuf *m,
- struct sockaddr *s))
-# else
-static int no_output __P((struct ifnet *ifp, struct mbuf *m,
- struct sockaddr *s, struct rtentry *rt))
-# endif
-{
- return 0;
-}
-
-
-# ifdef __STDC__
-# ifdef __sgi
-static int write_output __P((struct ifnet *ifp, struct mbuf *m,
- struct sockaddr *s))
-# else
-static int write_output __P((struct ifnet *ifp, struct mbuf *m,
- struct sockaddr *s, struct rtentry *rt))
-# endif
-{
- ip_t *ip = (ip_t *)m;
-# else
-static int write_output(ifp, ip)
-struct ifnet *ifp;
-ip_t *ip;
-{
-# endif
- char fname[32];
- int fd;
-
-# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
- (defined(OpenBSD) && (OpenBSD >= 199603))
- sprintf(fname, "/tmp/%s", ifp->if_xname);
-# else
- sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit);
-# endif
- fd = open(fname, O_WRONLY|O_APPEND);
- if (fd == -1) {
- perror("open");
- return -1;
- }
- write(fd, (char *)ip, ntohs(ip->ip_len));
- close(fd);
- return 0;
-}
-
-
-struct ifnet *get_unit(name, v)
-char *name;
-int v;
-{
- struct ifnet *ifp, **ifa;
-# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
- (defined(OpenBSD) && (OpenBSD >= 199603))
- for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
- if (!strcmp(name, ifp->if_xname))
- return ifp;
- }
-# else
- char ifname[32], *s;
-
- for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
- (void) sprintf(ifname, "%s%d", ifp->if_name, ifp->if_unit);
- if (!strcmp(name, ifname))
- return ifp;
- }
-# endif
-
- if (!ifneta) {
- ifneta = (struct ifnet **)malloc(sizeof(ifp) * 2);
- if (!ifneta)
- return NULL;
- ifneta[1] = NULL;
- ifneta[0] = (struct ifnet *)calloc(1, sizeof(*ifp));
- if (!ifneta[0]) {
- free(ifneta);
- return NULL;
- }
- nifs = 1;
- } else {
- nifs++;
- ifneta = (struct ifnet **)realloc(ifneta,
- (nifs + 1) * sizeof(*ifa));
- if (!ifneta) {
- nifs = 0;
- return NULL;
- }
- ifneta[nifs] = NULL;
- ifneta[nifs - 1] = (struct ifnet *)malloc(sizeof(*ifp));
- if (!ifneta[nifs - 1]) {
- nifs--;
- return NULL;
- }
- }
- ifp = ifneta[nifs - 1];
-
-# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
- (defined(OpenBSD) && (OpenBSD >= 199603))
- strncpy(ifp->if_xname, name, sizeof(ifp->if_xname));
-# else
- for (s = name; *s && !isdigit(*s); s++)
- ;
- if (*s && isdigit(*s)) {
- ifp->if_unit = atoi(s);
- ifp->if_name = (char *)malloc(s - name + 1);
- strncpy(ifp->if_name, name, s - name);
- ifp->if_name[s - name] = '\0';
- } else {
- ifp->if_name = strdup(name);
- ifp->if_unit = -1;
- }
-# endif
- ifp->if_output = no_output;
- return ifp;
-}
-
-
-
-void init_ifp()
-{
- struct ifnet *ifp, **ifa;
- char fname[32];
- int fd;
-
-# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
- (defined(OpenBSD) && (OpenBSD >= 199603))
- for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
- ifp->if_output = write_output;
- sprintf(fname, "/tmp/%s", ifp->if_xname);
- fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600);
- if (fd == -1)
- perror("open");
- else
- close(fd);
- }
-# else
-
- for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
- ifp->if_output = write_output;
- sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit);
- fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600);
- if (fd == -1)
- perror("open");
- else
- close(fd);
- }
-# endif
-}
-
-
-int ipfr_fastroute(ip, fin, fdp)
-ip_t *ip;
-fr_info_t *fin;
-frdest_t *fdp;
-{
- struct ifnet *ifp = fdp->fd_ifp;
-
- if (!ifp)
- return 0; /* no routing table out here */
-
- ip->ip_len = htons((u_short)ip->ip_len);
- ip->ip_off = htons((u_short)(ip->ip_off | IP_MF));
- ip->ip_sum = 0;
-#ifdef __sgi
- (*ifp->if_output)(ifp, (void *)ip, NULL);
-#else
- (*ifp->if_output)(ifp, (void *)ip, NULL, 0);
-#endif
- return 0;
-}
-
-
-int ipllog __P((void))
-{
- verbose("l");
- return 0;
-}
-
-
-int send_reset(ip, ifp)
-ip_t *ip;
-struct ifnet *ifp;
-{
- verbose("- TCP RST sent\n");
- return 0;
-}
-
-
-int icmp_error(ip, ifp)
-ip_t *ip;
-struct ifnet *ifp;
-{
- verbose("- TCP RST sent\n");
- return 0;
-}
-
-
-void frsync()
-{
- return;
-}
-#endif /* _KERNEL */
diff --git a/contrib/ipfilter/ip_fil.h b/contrib/ipfilter/ip_fil.h
deleted file mode 100644
index 9dd75f0..0000000
--- a/contrib/ipfilter/ip_fil.h
+++ /dev/null
@@ -1,631 +0,0 @@
-/*
- * Copyright (C) 1993-2000 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.
- *
- * @(#)ip_fil.h 1.35 6/5/96
- * $FreeBSD$
- */
-
-#ifndef __IP_FIL_H__
-#define __IP_FIL_H__
-
-/*
- * Pathnames for various IP Filter control devices. Used by LKM
- * and userland, so defined here.
- */
-#define IPNAT_NAME "/dev/ipnat"
-#define IPSTATE_NAME "/dev/ipstate"
-#define IPAUTH_NAME "/dev/ipauth"
-
-#ifndef SOLARIS
-# define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
-#endif
-
-#if defined(KERNEL) && !defined(_KERNEL)
-# define _KERNEL
-#endif
-
-#ifndef __P
-# ifdef __STDC__
-# define __P(x) x
-# else
-# define __P(x) ()
-# endif
-#endif
-
-#if defined(__STDC__) || defined(__GNUC__)
-# define SIOCADAFR _IOW('r', 60, struct frentry *)
-# define SIOCRMAFR _IOW('r', 61, struct frentry *)
-# define SIOCSETFF _IOW('r', 62, u_int)
-# define SIOCGETFF _IOR('r', 63, u_int)
-# define SIOCGETFS _IOWR('r', 64, struct friostat *)
-# define SIOCIPFFL _IOWR('r', 65, int)
-# define SIOCIPFFB _IOR('r', 66, int)
-# define SIOCADIFR _IOW('r', 67, struct frentry *)
-# define SIOCRMIFR _IOW('r', 68, struct frentry *)
-# define SIOCSWAPA _IOR('r', 69, u_int)
-# define SIOCINAFR _IOW('r', 70, struct frentry *)
-# define SIOCINIFR _IOW('r', 71, struct frentry *)
-# define SIOCFRENB _IOW('r', 72, u_int)
-# define SIOCFRSYN _IOW('r', 73, u_int)
-# define SIOCFRZST _IOWR('r', 74, struct friostat *)
-# define SIOCZRLST _IOWR('r', 75, struct frentry *)
-# define SIOCAUTHW _IOWR('r', 76, struct fr_info *)
-# define SIOCAUTHR _IOWR('r', 77, struct fr_info *)
-# define SIOCATHST _IOWR('r', 78, struct fr_authstat *)
-# define SIOCSTLCK _IOWR('r', 79, u_int)
-# define SIOCSTPUT _IOWR('r', 80, struct ipstate_save *)
-# define SIOCSTGET _IOWR('r', 81, struct ipstate_save *)
-# define SIOCSTGSZ _IOWR('r', 82, struct natget *)
-# define SIOCGFRST _IOWR('r', 83, struct ipfrstat *)
-#else
-# define SIOCADAFR _IOW(r, 60, struct frentry *)
-# define SIOCRMAFR _IOW(r, 61, struct frentry *)
-# define SIOCSETFF _IOW(r, 62, u_int)
-# define SIOCGETFF _IOR(r, 63, u_int)
-# define SIOCGETFS _IOWR(r, 64, struct friostat *)
-# define SIOCIPFFL _IOWR(r, 65, int)
-# define SIOCIPFFB _IOR(r, 66, int)
-# define SIOCADIFR _IOW(r, 67, struct frentry *)
-# define SIOCRMIFR _IOW(r, 68, struct frentry *)
-# define SIOCSWAPA _IOR(r, 69, u_int)
-# define SIOCINAFR _IOW(r, 70, struct frentry *)
-# define SIOCINIFR _IOW(r, 71, struct frentry *)
-# define SIOCFRENB _IOW(r, 72, u_int)
-# define SIOCFRSYN _IOW(r, 73, u_int)
-# define SIOCFRZST _IOWR(r, 74, struct friostat *)
-# define SIOCZRLST _IOWR(r, 75, struct frentry *)
-# define SIOCAUTHW _IOWR(r, 76, struct fr_info *)
-# define SIOCAUTHR _IOWR(r, 77, struct fr_info *)
-# define SIOCATHST _IOWR(r, 78, struct fr_authstat *)
-# define SIOCSTLCK _IOWR(r, 79, u_int)
-# define SIOCSTPUT _IOWR(r, 80, struct ipstate_save *)
-# define SIOCSTGET _IOWR(r, 81, struct ipstate_save *)
-# define SIOCSTGSZ _IOWR(r, 82, struct natget *)
-# define SIOCGFRST _IOWR(r, 83, struct ipfrstat *)
-#endif
-#define SIOCADDFR SIOCADAFR
-#define SIOCDELFR SIOCRMAFR
-#define SIOCINSFR SIOCINAFR
-
-
-typedef struct fr_ip {
- u_32_t fi_v:4; /* IP version */
- u_32_t fi_fl:4; /* packet flags */
- u_32_t fi_tos:8; /* IP packet TOS */
- u_32_t fi_ttl:8; /* IP packet TTL */
- u_32_t fi_p:8; /* IP packet protocol */
- union i6addr fi_src; /* source address from packet */
- union i6addr fi_dst; /* destination address from packet */
- u_32_t fi_optmsk; /* bitmask composed from IP options */
- u_short fi_secmsk; /* bitmask composed from IP security options */
- u_short fi_auth; /* authentication code from IP sec. options */
-} fr_ip_t;
-
-#define FI_OPTIONS (FF_OPTIONS >> 24)
-#define FI_TCPUDP (FF_TCPUDP >> 24) /* TCP/UCP implied comparison*/
-#define FI_FRAG (FF_FRAG >> 24)
-#define FI_SHORT (FF_SHORT >> 24)
-#define FI_CMP (FI_OPTIONS|FI_TCPUDP|FI_SHORT)
-
-#define fi_saddr fi_src.in4.s_addr
-#define fi_daddr fi_dst.in4.s_addr
-
-
-/*
- * These are both used by the state and NAT code to indicate that one port or
- * the other should be treated as a wildcard.
- */
-#define FI_W_SPORT 0x00000100
-#define FI_W_DPORT 0x00000200
-#define FI_WILDP (FI_W_SPORT|FI_W_DPORT)
-#define FI_W_SADDR 0x00000400
-#define FI_W_DADDR 0x00000800
-#define FI_WILDA (FI_W_SADDR|FI_W_DADDR)
-#define FI_NEWFR 0x00001000
-
-typedef struct fr_info {
- void *fin_ifp; /* interface packet is `on' */
- struct fr_ip fin_fi; /* IP Packet summary */
- u_short fin_data[2]; /* TCP/UDP ports, ICMP code/type */
- u_char fin_out; /* in or out ? 1 == out, 0 == in */
- u_char fin_rev; /* state only: 1 = reverse */
- u_short fin_hlen; /* length of IP header in bytes */
- u_char fin_tcpf; /* TCP header flags (SYN, ACK, etc) */
- /* From here on is packet specific */
- u_char fin_icode; /* ICMP error to return */
- u_short fin_rule; /* rule # last matched */
- u_32_t fin_group; /* group number, -1 for none */
- struct frentry *fin_fr; /* last matching rule */
- char *fin_dp; /* start of data past IP header */
- u_short fin_dlen; /* length of data portion of packet */
- u_short fin_id; /* IP packet id field */
- void *fin_mp; /* pointer to pointer to mbuf */
-#if SOLARIS
- void *fin_qfm; /* pointer to mblk where pkt starts */
- void *fin_qif;
-#endif
- u_short fin_plen;
- u_short fin_off;
-} fr_info_t;
-
-#define fin_v fin_fi.fi_v
-
-/*
- * Size for compares on fr_info structures
- */
-#define FI_CSIZE offsetof(fr_info_t, fin_icode)
-
-/*
- * Size for copying cache fr_info structure
- */
-#define FI_COPYSIZE offsetof(fr_info_t, fin_dp)
-
-typedef struct frdest {
- void *fd_ifp;
- struct in_addr fd_ip;
- char fd_ifname[IFNAMSIZ];
-} frdest_t;
-
-typedef struct frpcmp {
- int frp_cmp; /* data for port comparisons */
- u_short frp_port; /* top port for <> and >< */
- u_short frp_top; /* top port for <> and >< */
-} frpcmp_t;
-
-typedef struct frtuc {
- u_char ftu_tcpfm; /* tcp flags mask */
- u_char ftu_tcpf; /* tcp flags */
- frpcmp_t ftu_src;
- frpcmp_t ftu_dst;
-} frtuc_t;
-
-#define ftu_scmp ftu_src.frp_cmp
-#define ftu_dcmp ftu_dst.frp_cmp
-#define ftu_sport ftu_src.frp_port
-#define ftu_dport ftu_dst.frp_port
-#define ftu_stop ftu_src.frp_top
-#define ftu_dtop ftu_dst.frp_top
-
-typedef struct frentry {
- struct frentry *fr_next;
- u_32_t fr_group; /* group to which this rule belongs */
- u_32_t fr_grhead; /* group # which this rule starts */
- struct frentry *fr_grp;
- int fr_ref; /* reference count - for grouping */
- void *fr_ifa;
-#if BSD >= 199306
- void *fr_oifa;
-#endif
- /*
- * These are only incremented when a packet matches this rule and
- * it is the last match
- */
- U_QUAD_T fr_hits;
- U_QUAD_T fr_bytes;
- /*
- * Fields after this may not change whilst in the kernel.
- */
- struct fr_ip fr_ip;
- struct fr_ip fr_mip; /* mask structure */
-
-
- u_short fr_icmpm; /* data for ICMP packets (mask) */
- u_short fr_icmp;
-
- frtuc_t fr_tuc;
- u_32_t fr_flags; /* per-rule flags && options (see below) */
- u_int fr_skip; /* # of rules to skip */
- u_int fr_loglevel; /* syslog log facility + priority */
- int (*fr_func) __P((int, ip_t *, fr_info_t *)); /* call this function */
- int fr_sap; /* For solaris only */
- u_char fr_icode; /* return ICMP code */
- char fr_ifname[IFNAMSIZ];
-#if BSD >= 199306
- char fr_oifname[IFNAMSIZ];
-#endif
- struct frdest fr_tif; /* "to" interface */
- struct frdest fr_dif; /* duplicate packet interfaces */
- u_int fr_cksum; /* checksum on filter rules for performance */
-} frentry_t;
-
-#define fr_v fr_ip.fi_v
-#define fr_proto fr_ip.fi_p
-#define fr_ttl fr_ip.fi_ttl
-#define fr_tos fr_ip.fi_tos
-#define fr_tcpfm fr_tuc.ftu_tcpfm
-#define fr_tcpf fr_tuc.ftu_tcpf
-#define fr_scmp fr_tuc.ftu_scmp
-#define fr_dcmp fr_tuc.ftu_dcmp
-#define fr_dport fr_tuc.ftu_dport
-#define fr_sport fr_tuc.ftu_sport
-#define fr_stop fr_tuc.ftu_stop
-#define fr_dtop fr_tuc.ftu_dtop
-#define fr_dst fr_ip.fi_dst.in4
-#define fr_src fr_ip.fi_src.in4
-#define fr_dmsk fr_mip.fi_dst.in4
-#define fr_smsk fr_mip.fi_src.in4
-
-#ifndef offsetof
-#define offsetof(t,m) (int)((&((t *)0L)->m))
-#endif
-#define FR_CMPSIZ (sizeof(struct frentry) - offsetof(frentry_t, fr_ip))
-
-/*
- * fr_flags
- */
-#define FR_BLOCK 0x00001 /* do not allow packet to pass */
-#define FR_PASS 0x00002 /* allow packet to pass */
-#define FR_OUTQUE 0x00004 /* outgoing packets */
-#define FR_INQUE 0x00008 /* ingoing packets */
-#define FR_LOG 0x00010 /* Log */
-#define FR_LOGB 0x00011 /* Log-fail */
-#define FR_LOGP 0x00012 /* Log-pass */
-#define FR_LOGBODY 0x00020 /* Log the body */
-#define FR_LOGFIRST 0x00040 /* Log the first byte if state held */
-#define FR_RETRST 0x00080 /* Return TCP RST packet - reset connection */
-#define FR_RETICMP 0x00100 /* Return ICMP unreachable packet */
-#define FR_FAKEICMP 0x00180 /* Return ICMP unreachable with fake source */
-#define FR_NOMATCH 0x00200 /* no match occured */
-#define FR_ACCOUNT 0x00400 /* count packet bytes */
-#define FR_KEEPFRAG 0x00800 /* keep fragment information */
-#define FR_KEEPSTATE 0x01000 /* keep `connection' state information */
-#define FR_INACTIVE 0x02000
-#define FR_QUICK 0x04000 /* match & stop processing list */
-#define FR_FASTROUTE 0x08000 /* bypass normal routing */
-#define FR_CALLNOW 0x10000 /* call another function (fr_func) if matches */
-#define FR_DUP 0x20000 /* duplicate packet */
-#define FR_LOGORBLOCK 0x40000 /* block the packet if it can't be logged */
-#define FR_NOTSRCIP 0x80000 /* not the src IP# */
-#define FR_NOTDSTIP 0x100000 /* not the dst IP# */
-#define FR_AUTH 0x200000 /* use authentication */
-#define FR_PREAUTH 0x400000 /* require preauthentication */
-#define FR_DONTCACHE 0x800000 /* don't cache the result */
-
-#define FR_LOGMASK (FR_LOG|FR_LOGP|FR_LOGB)
-#define FR_RETMASK (FR_RETICMP|FR_RETRST|FR_FAKEICMP)
-
-/*
- * These correspond to #define's for FI_* and are stored in fr_flags
- */
-#define FF_OPTIONS 0x01000000
-#define FF_TCPUDP 0x02000000
-#define FF_FRAG 0x04000000
-#define FF_SHORT 0x08000000
-/*
- * recognized flags for SIOCGETFF and SIOCSETFF, and get put in fr_flags
- */
-#define FF_LOGPASS 0x10000000
-#define FF_LOGBLOCK 0x20000000
-#define FF_LOGNOMATCH 0x40000000
-#define FF_LOGGING (FF_LOGPASS|FF_LOGBLOCK|FF_LOGNOMATCH)
-#define FF_BLOCKNONIP 0x80000000 /* Solaris2 Only */
-
-#define FR_NONE 0
-#define FR_EQUAL 1
-#define FR_NEQUAL 2
-#define FR_LESST 3
-#define FR_GREATERT 4
-#define FR_LESSTE 5
-#define FR_GREATERTE 6
-#define FR_OUTRANGE 7
-#define FR_INRANGE 8
-
-typedef struct filterstats {
- u_long fr_pass; /* packets allowed */
- u_long fr_block; /* packets denied */
- u_long fr_nom; /* packets which don't match any rule */
- u_long fr_short; /* packets which are short */
- u_long fr_ppkl; /* packets allowed and logged */
- u_long fr_bpkl; /* packets denied and logged */
- u_long fr_npkl; /* packets unmatched and logged */
- u_long fr_pkl; /* packets logged */
- u_long fr_skip; /* packets to be logged but buffer full */
- u_long fr_ret; /* packets for which a return is sent */
- u_long fr_acct; /* packets for which counting was performed */
- u_long fr_bnfr; /* bad attempts to allocate fragment state */
- u_long fr_nfr; /* new fragment state kept */
- u_long fr_cfr; /* add new fragment state but complete pkt */
- u_long fr_bads; /* bad attempts to allocate packet state */
- u_long fr_ads; /* new packet state kept */
- u_long fr_chit; /* cached hit */
- u_long fr_tcpbad; /* TCP checksum check failures */
- u_long fr_pull[2]; /* good and bad pullup attempts */
- u_long fr_badsrc; /* source received doesn't match route */
- u_long fr_badttl; /* TTL in packet doesn't reach minimum */
-#if SOLARIS
- u_long fr_notdata; /* PROTO/PCPROTO that have no data */
- u_long fr_nodata; /* mblks that have no data */
- u_long fr_bad; /* bad IP packets to the filter */
- u_long fr_notip; /* packets passed through no on ip queue */
- u_long fr_drop; /* packets dropped - no info for them! */
- u_long fr_copy; /* messages copied due to db_ref > 1 */
-#endif
- u_long fr_ipv6[2]; /* IPv6 packets in/out */
-} filterstats_t;
-
-/*
- * For SIOCGETFS
- */
-typedef struct friostat {
- struct filterstats f_st[2];
- struct frentry *f_fin[2];
- struct frentry *f_fout[2];
- struct frentry *f_acctin[2];
- struct frentry *f_acctout[2];
- struct frentry *f_fin6[2];
- struct frentry *f_fout6[2];
- struct frentry *f_acctin6[2];
- struct frentry *f_acctout6[2];
- struct frentry *f_auth;
- struct frgroup *f_groups[3][2];
- u_long f_froute[2];
- int f_defpass; /* default pass - from fr_pass */
- 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 */
- char f_version[32]; /* version string */
- int f_locks[4];
-} friostat_t;
-
-typedef struct optlist {
- u_short ol_val;
- int ol_bit;
-} optlist_t;
-
-
-/*
- * Group list structure.
- */
-typedef struct frgroup {
- u_32_t fg_num;
- struct frgroup *fg_next;
- struct frentry *fg_head;
- struct frentry **fg_start;
-} frgroup_t;
-
-
-/*
- * Log structure. Each packet header logged is prepended by one of these.
- * Following this in the log records read from the device will be an ipflog
- * structure which is then followed by any packet data.
- */
-typedef struct iplog {
- u_32_t ipl_magic;
- u_int ipl_count;
- u_long ipl_sec;
- u_long ipl_usec;
- size_t ipl_dsize;
- struct iplog *ipl_next;
-} iplog_t;
-
-#define IPL_MAGIC 0x49504c4d /* 'IPLM' */
-
-typedef struct ipflog {
-#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \
- (defined(OpenBSD) && (OpenBSD >= 199603))
- u_char fl_ifname[IFNAMSIZ];
-#else
- u_int fl_unit;
- u_char fl_ifname[4];
-#endif
- u_char fl_plen; /* extra data after hlen */
- u_char fl_hlen; /* length of IP headers saved */
- u_short fl_loglevel; /* syslog log level */
- u_32_t fl_rule;
- u_32_t fl_group;
- u_32_t fl_flags;
- u_32_t fl_lflags;
-} ipflog_t;
-
-
-#ifndef ICMP_UNREACH_FILTER
-# define ICMP_UNREACH_FILTER 13
-#endif
-
-#ifndef IPF_LOGGING
-# define IPF_LOGGING 0
-#endif
-#ifndef IPF_DEFAULT_PASS
-# define IPF_DEFAULT_PASS FR_PASS
-#endif
-
-#define IPMINLEN(i, h) ((i)->ip_len >= ((i)->ip_hl * 4 + sizeof(struct h)))
-#define IPLLOGSIZE 8192
-
-/*
- * Device filenames for reading log information. Use ipf on Solaris2 because
- * ipl is already a name used by something else.
- */
-#ifndef IPL_NAME
-# if SOLARIS
-# define IPL_NAME "/dev/ipf"
-# else
-# define IPL_NAME "/dev/ipl"
-# endif
-#endif
-#define IPL_NAT IPNAT_NAME
-#define IPL_STATE IPSTATE_NAME
-#define IPL_AUTH IPAUTH_NAME
-
-#define IPL_LOGIPF 0 /* Minor device #'s for accessing logs */
-#define IPL_LOGNAT 1
-#define IPL_LOGSTATE 2
-#define IPL_LOGAUTH 3
-#define IPL_LOGMAX 3
-
-#if !defined(CDEV_MAJOR) && defined (__FreeBSD_version) && \
- (__FreeBSD_version >= 220000)
-# define CDEV_MAJOR 79
-#endif
-
-/*
- * Post NetBSD 1.2 has the PFIL interface for packet filters. This turns
- * on those hooks. We don't need any special mods in non-IP Filter code
- * with this!
- */
-#if (defined(NetBSD) && (NetBSD > 199609) && (NetBSD <= 1991011)) || \
- (defined(NetBSD1_2) && NetBSD1_2 > 1)
-# if (NetBSD >= 199905)
-# define PFIL_HOOKS
-# endif
-# ifdef PFIL_HOOKS
-# define NETBSD_PF
-# endif
-#endif
-
-
-#ifndef _KERNEL
-extern int fr_check __P((ip_t *, int, void *, int, mb_t **));
-extern int (*fr_checkp) __P((ip_t *, int, void *, int, mb_t **));
-extern int send_reset __P((ip_t *, struct ifnet *));
-extern int icmp_error __P((ip_t *, struct ifnet *));
-extern int ipf_log __P((void));
-extern int ipfr_fastroute __P((ip_t *, fr_info_t *, frdest_t *));
-extern struct ifnet *get_unit __P((char *, int));
-# if defined(__NetBSD__) || defined(__OpenBSD__) || \
- (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000)
-extern int iplioctl __P((dev_t, u_long, caddr_t, int));
-# else
-extern int iplioctl __P((dev_t, int, caddr_t, int));
-# endif
-extern int iplopen __P((dev_t, int));
-extern int iplclose __P((dev_t, int));
-#else /* #ifndef _KERNEL */
-# if defined(__NetBSD__) && defined(PFIL_HOOKS)
-extern void ipfilterattach __P((int));
-# endif
-extern int iplattach __P((void));
-extern int ipl_enable __P((void));
-extern int ipl_disable __P((void));
-extern void ipflog_init __P((void));
-extern int ipflog_clear __P((minor_t));
-extern int ipflog_read __P((minor_t, struct uio *));
-extern int ipflog __P((u_int, ip_t *, fr_info_t *, mb_t *));
-extern int ipllog __P((int, fr_info_t *, void **, size_t *, int *, int));
-extern int send_icmp_err __P((ip_t *, int, fr_info_t *, int));
-extern int send_reset __P((ip_t *, fr_info_t *));
-# if SOLARIS
-extern int fr_check __P((ip_t *, int, void *, int, qif_t *, mb_t **));
-extern int (*fr_checkp) __P((ip_t *, int, void *,
- int, qif_t *, mb_t **));
-# if SOLARIS2 >= 7
-extern int iplioctl __P((dev_t, int, intptr_t, int, cred_t *, int *));
-# else
-extern int iplioctl __P((dev_t, int, int *, int, cred_t *, int *));
-# endif
-extern int iplopen __P((dev_t *, int, int, cred_t *));
-extern int iplclose __P((dev_t, int, int, cred_t *));
-extern int ipfsync __P((void));
-extern int ipfr_fastroute __P((ip_t *, mblk_t *, mblk_t **,
- fr_info_t *, frdest_t *));
-extern void copyin_mblk __P((mblk_t *, size_t, size_t, char *));
-extern void copyout_mblk __P((mblk_t *, size_t, size_t, char *));
-extern int fr_qin __P((queue_t *, mblk_t *));
-extern int fr_qout __P((queue_t *, mblk_t *));
-extern int iplread __P((dev_t, struct uio *, cred_t *));
-# else /* SOLARIS */
-extern int fr_check __P((ip_t *, int, void *, int, mb_t **));
-extern int (*fr_checkp) __P((ip_t *, int, void *, int, mb_t **));
-extern int ipfr_fastroute __P((mb_t *, fr_info_t *, frdest_t *));
-extern size_t mbufchainlen __P((mb_t *));
-# ifdef __sgi
-# include <sys/cred.h>
-extern int iplioctl __P((dev_t, int, caddr_t, int, cred_t *, int *));
-extern int iplopen __P((dev_t *, int, int, cred_t *));
-extern int iplclose __P((dev_t, int, int, cred_t *));
-extern int iplread __P((dev_t, struct uio *, cred_t *));
-extern int ipfsync __P((void));
-extern int ipfilter_sgi_attach __P((void));
-extern void ipfilter_sgi_detach __P((void));
-extern void ipfilter_sgi_intfsync __P((void));
-# else
-# ifdef IPFILTER_LKM
-extern int iplidentify __P((char *));
-# endif
-# if (_BSDI_VERSION >= 199510) || (__FreeBSD_version >= 220000) || \
- (NetBSD >= 199511) || defined(__OpenBSD__)
-# if defined(__NetBSD__) || (_BSDI_VERSION >= 199701) || \
- defined(__OpenBSD__) || (__FreeBSD_version >= 300000)
-extern int iplioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
-# else
-extern int iplioctl __P((dev_t, int, caddr_t, int, struct proc *));
-# endif
-extern int iplopen __P((dev_t, int, int, struct proc *));
-extern int iplclose __P((dev_t, int, int, struct proc *));
-# else
-# ifndef linux
-extern int iplopen __P((dev_t, int));
-extern int iplclose __P((dev_t, int));
-extern int iplioctl __P((dev_t, int, caddr_t, int));
-# else
-extern int iplioctl(struct inode *, struct file *, u_int, u_long);
-extern int iplopen __P((struct inode *, struct file *));
-extern void iplclose __P((struct inode *, struct file *));
-# endif /* !linux */
-# endif /* (_BSDI_VERSION >= 199510) */
-# if BSD >= 199306
-extern int iplread __P((dev_t, struct uio *, int));
-# else
-# ifndef linux
-extern int iplread __P((dev_t, struct uio *));
-# else
-extern int iplread(struct inode *, struct file *, char *, int);
-# endif /* !linux */
-# endif /* BSD >= 199306 */
-# endif /* __ sgi */
-# endif /* SOLARIS */
-#endif /* #ifndef _KERNEL */
-
-extern char *memstr __P((char *, char *, int, int));
-extern void fixskip __P((frentry_t **, frentry_t *, int));
-extern int countbits __P((u_32_t));
-extern int ipldetach __P((void));
-extern u_short ipf_cksum __P((u_short *, int));
-extern int ircopyptr __P((void *, void *, size_t));
-extern int iwcopyptr __P((void *, void *, size_t));
-
-extern int frflush __P((minor_t, int));
-extern void frsync __P((void));
-extern frgroup_t *fr_addgroup __P((u_32_t, frentry_t *, minor_t, int));
-extern void fr_delgroup __P((u_32_t, u_32_t, minor_t, int));
-extern frgroup_t *fr_findgroup __P((u_32_t, u_32_t, minor_t, int,
- frgroup_t ***));
-
-extern int fr_copytolog __P((int, char *, int));
-extern void fr_forgetifp __P((void *));
-extern void fr_getstat __P((struct friostat *));
-extern int fr_ifpaddr __P((int, void *, struct in_addr *));
-extern int fr_lock __P((caddr_t, int *));
-extern void fr_makefrip __P((int, ip_t *, fr_info_t *));
-extern u_short fr_tcpsum __P((mb_t *, ip_t *, tcphdr_t *));
-extern int fr_scanlist __P((u_32_t, ip_t *, fr_info_t *, void *));
-extern int fr_tcpudpchk __P((frtuc_t *, fr_info_t *));
-extern int fr_verifysrc __P((struct in_addr, void *));
-
-extern int ipl_unreach;
-extern int fr_running;
-extern u_long ipl_frouteok[2];
-extern int fr_pass;
-extern int fr_flags;
-extern int fr_active;
-extern int fr_chksrc;
-extern int fr_minttl;
-extern int fr_minttllog;
-extern fr_info_t frcache[2];
-extern char ipfilter_version[];
-extern iplog_t **iplh[IPL_LOGMAX+1], *iplt[IPL_LOGMAX+1];
-extern size_t iplused[IPL_LOGMAX + 1];
-extern struct frentry *ipfilter[2][2], *ipacct[2][2];
-#ifdef USE_INET6
-extern struct frentry *ipfilter6[2][2], *ipacct6[2][2];
-extern int icmptoicmp6types[ICMP_MAXTYPE+1];
-extern int icmptoicmp6unreach[ICMP_MAX_UNREACH];
-#endif
-extern struct frgroup *ipfgroups[3][2];
-extern struct filterstats frstats[];
-
-#endif /* __IP_FIL_H__ */
diff --git a/contrib/ipfilter/ip_frag.c b/contrib/ipfilter/ip_frag.c
deleted file mode 100644
index 556478d..0000000
--- a/contrib/ipfilter/ip_frag.c
+++ /dev/null
@@ -1,555 +0,0 @@
-/*
- * Copyright (C) 1993-2000 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)
-static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.10.2.7 2000/11/27 10:26:56 darrenr Exp $";
-#endif
-
-#if defined(KERNEL) && !defined(_KERNEL)
-# define _KERNEL
-#endif
-
-#include <sys/errno.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/file.h>
-#if !defined(_KERNEL) && !defined(KERNEL)
-# include <stdio.h>
-# include <string.h>
-# include <stdlib.h>
-#endif
-#if (defined(KERNEL) || defined(_KERNEL)) && (__FreeBSD_version >= 220000)
-# include <sys/filio.h>
-# include <sys/fcntl.h>
-#else
-# include <sys/ioctl.h>
-#endif
-#include <sys/uio.h>
-#ifndef linux
-# include <sys/protosw.h>
-#endif
-#include <sys/socket.h>
-#if defined(_KERNEL) && !defined(linux)
-# include <sys/systm.h>
-#endif
-#if !defined(__SVR4) && !defined(__svr4__)
-# if defined(_KERNEL) && !defined(__sgi)
-# include <sys/kernel.h>
-# endif
-# ifndef linux
-# include <sys/mbuf.h>
-# endif
-#else
-# include <sys/byteorder.h>
-# ifdef _KERNEL
-# include <sys/dditypes.h>
-# endif
-# 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>
-#ifndef linux
-# include <netinet/ip_var.h>
-#endif
-#include <netinet/tcp.h>
-#include <netinet/udp.h>
-#include <netinet/ip_icmp.h>
-#include "netinet/ip_compat.h"
-#include <netinet/tcpip.h>
-#include "netinet/ip_fil.h"
-#include "netinet/ip_proxy.h"
-#include "netinet/ip_nat.h"
-#include "netinet/ip_frag.h"
-#include "netinet/ip_state.h"
-#include "netinet/ip_auth.h"
-#if (__FreeBSD_version >= 300000)
-# include <sys/malloc.h>
-# if (defined(KERNEL) || defined(_KERNEL))
-# ifndef IPFILTER_LKM
-# include <sys/libkern.h>
-# include <sys/systm.h>
-# endif
-extern struct callout_handle ipfr_slowtimer_ch;
-# endif
-#endif
-#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104230000)
-# include <sys/callout.h>
-extern struct callout ipfr_slowtimer_ch;
-#endif
-
-
-static ipfr_t *ipfr_heads[IPFT_SIZE];
-static ipfr_t *ipfr_nattab[IPFT_SIZE];
-static ipfrstat_t ipfr_stats;
-static int ipfr_inuse = 0;
-
-int fr_ipfrttl = 120; /* 60 seconds */
-int fr_frag_lock = 0;
-
-#ifdef _KERNEL
-# if SOLARIS2 >= 7
-extern timeout_id_t ipfr_timer_id;
-# else
-extern int ipfr_timer_id;
-# endif
-#endif
-#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
-extern KRWLOCK_T ipf_frag, ipf_natfrag, ipf_nat, ipf_mutex;
-# if SOLARIS
-extern KRWLOCK_T ipf_solaris;
-# else
-KRWLOCK_T ipf_solaris;
-# endif
-extern kmutex_t ipf_rw;
-#endif
-
-
-static ipfr_t *ipfr_new __P((ip_t *, fr_info_t *, u_int, ipfr_t **));
-static ipfr_t *ipfr_lookup __P((ip_t *, fr_info_t *, ipfr_t **));
-static void ipfr_delete __P((ipfr_t *));
-
-
-ipfrstat_t *ipfr_fragstats()
-{
- ipfr_stats.ifs_table = ipfr_heads;
- ipfr_stats.ifs_nattab = ipfr_nattab;
- 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.
- */
-static ipfr_t *ipfr_new(ip, fin, pass, table)
-ip_t *ip;
-fr_info_t *fin;
-u_int pass;
-ipfr_t *table[];
-{
- ipfr_t **fp, *fra, frag;
- u_int idx;
-
- if (ipfr_inuse >= IPFT_SIZE)
- return NULL;
-
- 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;
- frag.ipfr_ifp = fin->fin_ifp;
- idx *= 127;
- idx %= IPFT_SIZE;
-
- /*
- * first, make sure it isn't already there...
- */
- for (fp = &table[idx]; (fra = *fp); fp = &fra->ipfr_next)
- if (!bcmp((char *)&frag.ipfr_src, (char *)&fra->ipfr_src,
- IPFR_CMPSZ)) {
- ATOMIC_INCL(ipfr_stats.ifs_exists);
- return NULL;
- }
-
- /*
- * allocate some memory, if possible, if not, just record that we
- * failed to do so.
- */
- KMALLOC(fra, ipfr_t *);
- if (fra == NULL) {
- ATOMIC_INCL(ipfr_stats.ifs_nomem);
- return NULL;
- }
-
- if ((fra->ipfr_rule = fin->fin_fr) != NULL) {
- ATOMIC_INC32(fin->fin_fr->fr_ref);
- }
-
-
- /*
- * Instert the fragment into the fragment table, copy the struct used
- * in the search using bcopy rather than reassign each field.
- * Set the ttl to the default and mask out logging from "pass"
- */
- if ((fra->ipfr_next = table[idx]))
- table[idx]->ipfr_prev = fra;
- fra->ipfr_prev = NULL;
- fra->ipfr_data = NULL;
- table[idx] = fra;
- bcopy((char *)&frag.ipfr_src, (char *)&fra->ipfr_src, IPFR_CMPSZ);
- fra->ipfr_ttl = fr_ipfrttl;
- /*
- * Compute the offset of the expected start of the next packet.
- */
- fra->ipfr_off = (ip->ip_off & IP_OFFMASK) + (fin->fin_dlen >> 3);
- ATOMIC_INCL(ipfr_stats.ifs_new);
- ATOMIC_INC32(ipfr_inuse);
- return fra;
-}
-
-
-int ipfr_newfrag(ip, fin, pass)
-ip_t *ip;
-fr_info_t *fin;
-u_int pass;
-{
- ipfr_t *ipf;
-
- if ((ip->ip_v != 4) || (fr_frag_lock))
- return -1;
- WRITE_ENTER(&ipf_frag);
- ipf = ipfr_new(ip, fin, pass, ipfr_heads);
- RWLOCK_EXIT(&ipf_frag);
- return ipf ? 0 : -1;
-}
-
-
-int ipfr_nat_newfrag(ip, fin, pass, nat)
-ip_t *ip;
-fr_info_t *fin;
-u_int pass;
-nat_t *nat;
-{
- ipfr_t *ipf;
-
- if ((ip->ip_v != 4) || (fr_frag_lock))
- return -1;
- WRITE_ENTER(&ipf_natfrag);
- ipf = ipfr_new(ip, fin, pass, ipfr_nattab);
- if (ipf != NULL) {
- ipf->ipfr_data = nat;
- nat->nat_data = ipf;
- }
- RWLOCK_EXIT(&ipf_natfrag);
- return ipf ? 0 : -1;
-}
-
-
-/*
- * check the fragment cache to see if there is already a record of this packet
- * with its filter result known.
- */
-static ipfr_t *ipfr_lookup(ip, fin, table)
-ip_t *ip;
-fr_info_t *fin;
-ipfr_t *table[];
-{
- ipfr_t *f, frag;
- u_int idx;
-
- /*
- * For fragments, we record protocol, packet id, TOS and both IP#'s
- * (these should all be the same for all fragments of a packet).
- *
- * build up a hash value to index the table with.
- */
- 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;
- frag.ipfr_ifp = fin->fin_ifp;
- idx *= 127;
- idx %= IPFT_SIZE;
-
- /*
- * check the table, careful to only compare the right amount of data
- */
- for (f = table[idx]; f; f = f->ipfr_next)
- if (!bcmp((char *)&frag.ipfr_src, (char *)&f->ipfr_src,
- IPFR_CMPSZ)) {
- u_short atoff, off;
-
- if (f != table[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 = table[idx];
- table[idx]->ipfr_prev = f;
- f->ipfr_prev = NULL;
- table[idx] = f;
- }
- 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 == f->ipfr_off) {
- if (!(ip->ip_off & IP_MF))
- f->ipfr_ttl = 1;
- else
- f->ipfr_off = atoff;
- }
- ATOMIC_INCL(ipfr_stats.ifs_hits);
- return f;
- }
- return NULL;
-}
-
-
-/*
- * functional interface for NAT lookups of the NAT fragment cache
- */
-nat_t *ipfr_nat_knownfrag(ip, fin)
-ip_t *ip;
-fr_info_t *fin;
-{
- nat_t *nat;
- ipfr_t *ipf;
-
- if ((ip->ip_v != 4) || (fr_frag_lock))
- return NULL;
- READ_ENTER(&ipf_natfrag);
- ipf = ipfr_lookup(ip, fin, ipfr_nattab);
- if (ipf != NULL) {
- nat = ipf->ipfr_data;
- /*
- * This is the last fragment for this packet.
- */
- if ((ipf->ipfr_ttl == 1) && (nat != NULL)) {
- nat->nat_data = NULL;
- ipf->ipfr_data = NULL;
- }
- } else
- nat = NULL;
- RWLOCK_EXIT(&ipf_natfrag);
- return nat;
-}
-
-
-/*
- * functional interface for normal lookups of the fragment cache
- */
-frentry_t *ipfr_knownfrag(ip, fin)
-ip_t *ip;
-fr_info_t *fin;
-{
- frentry_t *fr = NULL;
- ipfr_t *fra;
-
- if ((ip->ip_v != 4) || (fr_frag_lock))
- return NULL;
- READ_ENTER(&ipf_frag);
- fra = ipfr_lookup(ip, fin, ipfr_heads);
- if (fra != NULL)
- fr = fra->ipfr_rule;
- RWLOCK_EXIT(&ipf_frag);
- return fr;
-}
-
-
-/*
- * forget any references to this external object.
- */
-void ipfr_forget(nat)
-void *nat;
-{
- ipfr_t *fr;
- int idx;
-
- WRITE_ENTER(&ipf_natfrag);
- for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
- for (fr = ipfr_heads[idx]; fr; fr = fr->ipfr_next)
- if (fr->ipfr_data == nat)
- fr->ipfr_data = NULL;
-
- RWLOCK_EXIT(&ipf_natfrag);
-}
-
-
-static void ipfr_delete(fra)
-ipfr_t *fra;
-{
- frentry_t *fr;
-
- fr = fra->ipfr_rule;
- if (fr != NULL) {
- ATOMIC_DEC32(fr->fr_ref);
- if (fr->fr_ref == 0)
- KFREE(fr);
- }
- if (fra->ipfr_prev)
- fra->ipfr_prev->ipfr_next = fra->ipfr_next;
- if (fra->ipfr_next)
- fra->ipfr_next->ipfr_prev = fra->ipfr_prev;
- KFREE(fra);
-}
-
-
-/*
- * Free memory in use by fragment state info. kept.
- */
-void ipfr_unload()
-{
- ipfr_t **fp, *fra;
- nat_t *nat;
- int idx;
-
- WRITE_ENTER(&ipf_frag);
- for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
- for (fp = &ipfr_heads[idx]; (fra = *fp); ) {
- *fp = fra->ipfr_next;
- ipfr_delete(fra);
- }
- RWLOCK_EXIT(&ipf_frag);
-
- WRITE_ENTER(&ipf_nat);
- WRITE_ENTER(&ipf_natfrag);
- for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
- for (fp = &ipfr_nattab[idx]; (fra = *fp); ) {
- *fp = fra->ipfr_next;
- nat = fra->ipfr_data;
- if (nat != NULL) {
- if (nat->nat_data == fra)
- nat->nat_data = NULL;
- }
- ipfr_delete(fra);
- }
- RWLOCK_EXIT(&ipf_natfrag);
- RWLOCK_EXIT(&ipf_nat);
-}
-
-
-#ifdef _KERNEL
-void ipfr_fragexpire()
-{
- ipfr_t **fp, *fra;
- nat_t *nat;
- int idx;
-#if defined(_KERNEL)
-# if !SOLARIS
- int s;
-# endif
-#endif
-
- if (fr_frag_lock)
- return;
-
- SPL_NET(s);
- WRITE_ENTER(&ipf_frag);
-
- /*
- * Go through the entire table, looking for entries to expire,
- * decreasing the ttl by one for each entry. If it reaches 0,
- * remove it from the chain and free it.
- */
- for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
- for (fp = &ipfr_heads[idx]; (fra = *fp); ) {
- --fra->ipfr_ttl;
- if (fra->ipfr_ttl == 0) {
- *fp = fra->ipfr_next;
- ipfr_delete(fra);
- ATOMIC_INCL(ipfr_stats.ifs_expire);
- ATOMIC_DEC32(ipfr_inuse);
- } else
- fp = &fra->ipfr_next;
- }
- RWLOCK_EXIT(&ipf_frag);
-
- /*
- * Same again for the NAT table, except that if the structure also
- * still points to a NAT structure, and the NAT structure points back
- * at the one to be free'd, NULL the reference from the NAT struct.
- * NOTE: We need to grab both mutex's early, and in this order so as
- * to prevent a deadlock if both try to expire at the same time.
- */
- WRITE_ENTER(&ipf_nat);
- WRITE_ENTER(&ipf_natfrag);
- for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
- for (fp = &ipfr_nattab[idx]; (fra = *fp); ) {
- --fra->ipfr_ttl;
- if (fra->ipfr_ttl == 0) {
- ATOMIC_INCL(ipfr_stats.ifs_expire);
- ATOMIC_DEC32(ipfr_inuse);
- nat = fra->ipfr_data;
- if (nat != NULL) {
- if (nat->nat_data == fra)
- nat->nat_data = NULL;
- }
- *fp = fra->ipfr_next;
- ipfr_delete(fra);
- } else
- fp = &fra->ipfr_next;
- }
- RWLOCK_EXIT(&ipf_natfrag);
- RWLOCK_EXIT(&ipf_nat);
- SPL_X(s);
-}
-
-
-/*
- * Slowly expire held state for fragments. Timeouts are set * in expectation
- * of this being called twice per second.
- */
-# if (BSD >= 199306) || SOLARIS || defined(__sgi)
-# if defined(SOLARIS2) && (SOLARIS2 < 7)
-void ipfr_slowtimer()
-# else
-void ipfr_slowtimer __P((void *ptr))
-# endif
-# else
-int ipfr_slowtimer()
-# endif
-{
-#if defined(_KERNEL) && SOLARIS
- extern int fr_running;
-
- if (fr_running <= 0)
- return;
-#endif
-
- READ_ENTER(&ipf_solaris);
-#ifdef __sgi
- ipfilter_sgi_intfsync();
-#endif
-
- ipfr_fragexpire();
- fr_timeoutstate();
- ip_natexpire();
- fr_authexpire();
-# if SOLARIS
- ipfr_timer_id = timeout(ipfr_slowtimer, NULL, drv_usectohz(500000));
- RWLOCK_EXIT(&ipf_solaris);
-# else
-# if defined(__NetBSD__) && (__NetBSD_Version__ >= 104240000)
- callout_reset(&ipfr_slowtimer_ch, hz / 2, ipfr_slowtimer, NULL);
-# else
-# if (__FreeBSD_version >= 300000)
- ipfr_slowtimer_ch = timeout(ipfr_slowtimer, NULL, hz/2);
-# else
- timeout(ipfr_slowtimer, NULL, hz/2);
-# endif
-# if (BSD < 199306) && !defined(__sgi)
- return 0;
-# endif /* FreeBSD */
-# endif /* NetBSD */
-# endif /* SOLARIS */
-}
-#endif /* defined(_KERNEL) */
diff --git a/contrib/ipfilter/ip_frag.h b/contrib/ipfilter/ip_frag.h
deleted file mode 100644
index 362bcdd..0000000
--- a/contrib/ipfilter/ip_frag.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 1993-2000 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.
- *
- * @(#)ip_frag.h 1.5 3/24/96
- * $Id: ip_frag.h,v 2.4.2.2 2000/11/10 13:10:54 darrenr Exp $
- */
-
-#ifndef __IP_FRAG_H__
-#define __IP_FRAG_H__
-
-#define IPFT_SIZE 257
-
-typedef struct ipfr {
- struct ipfr *ipfr_next, *ipfr_prev;
- void *ipfr_data;
- struct in_addr ipfr_src;
- struct in_addr ipfr_dst;
- void *ipfr_ifp;
- u_short ipfr_id;
- u_char ipfr_p;
- u_char ipfr_tos;
- u_short ipfr_off;
- u_short ipfr_ttl;
- frentry_t *ipfr_rule;
-} ipfr_t;
-
-
-typedef struct ipfrstat {
- u_long ifs_exists; /* add & already exists */
- u_long ifs_nomem;
- u_long ifs_new;
- u_long ifs_hits;
- u_long ifs_expire;
- u_long ifs_inuse;
- struct ipfr **ifs_table;
- struct ipfr **ifs_nattab;
-} ipfrstat_t;
-
-#define IPFR_CMPSZ (4 + 4 + 2 + 1 + 1)
-
-extern int fr_ipfrttl;
-extern int fr_frag_lock;
-extern ipfrstat_t *ipfr_fragstats __P((void));
-extern int ipfr_newfrag __P((ip_t *, fr_info_t *, u_int));
-extern int ipfr_nat_newfrag __P((ip_t *, fr_info_t *, u_int, struct nat *));
-extern nat_t *ipfr_nat_knownfrag __P((ip_t *, fr_info_t *));
-extern frentry_t *ipfr_knownfrag __P((ip_t *, fr_info_t *));
-extern void ipfr_forget __P((void *));
-extern void ipfr_unload __P((void));
-extern void ipfr_fragexpire __P((void));
-
-#if (BSD >= 199306) || SOLARIS || defined(__sgi)
-# if defined(SOLARIS2) && (SOLARIS2 < 7)
-extern void ipfr_slowtimer __P((void));
-# else
-extern void ipfr_slowtimer __P((void *));
-# endif
-#else
-extern int ipfr_slowtimer __P((void));
-#endif /* (BSD >= 199306) || SOLARIS */
-
-#endif /* __IP_FIL_H__ */
diff --git a/contrib/ipfilter/ip_ftp_pxy.c b/contrib/ipfilter/ip_ftp_pxy.c
deleted file mode 100644
index ddca889..0000000
--- a/contrib/ipfilter/ip_ftp_pxy.c
+++ /dev/null
@@ -1,786 +0,0 @@
-/*
- * Simple FTP transparent proxy for in-kernel use. For use with the NAT
- * code.
- *
- * $Id: ip_ftp_pxy.c,v 2.7.2.20 2000/12/02 00:15:06 darrenr Exp $
- */
-#if SOLARIS && defined(_KERNEL)
-extern kmutex_t ipf_rw;
-#endif
-
-#define isdigit(x) ((x) >= '0' && (x) <= '9')
-#define isupper(x) (((unsigned)(x) >= 'A') && ((unsigned)(x) <= 'Z'))
-#define islower(x) (((unsigned)(x) >= 'a') && ((unsigned)(x) <= 'z'))
-#define isalpha(x) (isupper(x) || islower(x))
-#define toupper(x) (isupper(x) ? (x) : (x) - 'a' + 'A')
-
-#define IPF_FTP_PROXY
-
-#define IPF_MINPORTLEN 18
-#define IPF_MAXPORTLEN 30
-#define IPF_MIN227LEN 39
-#define IPF_MAX227LEN 51
-#define IPF_FTPBUFSZ 96 /* This *MUST* be >= 53! */
-
-
-int ippr_ftp_client __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int));
-int ippr_ftp_complete __P((char *, size_t));
-int ippr_ftp_in __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
-int ippr_ftp_init __P((void));
-int ippr_ftp_new __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
-int ippr_ftp_out __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
-int ippr_ftp_pasv __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *, int));
-int ippr_ftp_port __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *, int));
-int ippr_ftp_process __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int));
-int ippr_ftp_server __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int));
-int ippr_ftp_valid __P((char *, size_t));
-u_short ippr_ftp_atoi __P((char **));
-
-static frentry_t natfr;
-int ippr_ftp_pasvonly = 0;
-int ippr_ftp_insecure = 0;
-
-
-/*
- * Initialize local structures.
- */
-int ippr_ftp_init()
-{
- bzero((char *)&natfr, sizeof(natfr));
- natfr.fr_ref = 1;
- natfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE;
- return 0;
-}
-
-
-int ippr_ftp_new(fin, ip, aps, nat)
-fr_info_t *fin;
-ip_t *ip;
-ap_session_t *aps;
-nat_t *nat;
-{
- ftpinfo_t *ftp;
- ftpside_t *f;
-
- KMALLOC(ftp, ftpinfo_t *);
- if (ftp == NULL)
- return -1;
- aps->aps_data = ftp;
- aps->aps_psiz = sizeof(ftpinfo_t);
-
- bzero((char *)ftp, sizeof(*ftp));
- f = &ftp->ftp_side[0];
- f->ftps_rptr = f->ftps_buf;
- f->ftps_wptr = f->ftps_buf;
- f = &ftp->ftp_side[1];
- f->ftps_rptr = f->ftps_buf;
- f->ftps_wptr = f->ftps_buf;
- return 0;
-}
-
-
-int ippr_ftp_port(fin, ip, nat, f, dlen)
-fr_info_t *fin;
-ip_t *ip;
-nat_t *nat;
-ftpside_t *f;
-int dlen;
-{
- tcphdr_t *tcp, tcph, *tcp2 = &tcph;
- char newbuf[IPF_FTPBUFSZ], *s;
- u_short a5, a6, sp, dp;
- u_int a1, a2, a3, a4;
- struct in_addr swip;
- size_t nlen, olen;
- fr_info_t fi;
- int inc, off;
- nat_t *ipn;
- mb_t *m;
-#if SOLARIS
- mb_t *m1;
-#endif
-
- tcp = (tcphdr_t *)fin->fin_dp;
- /*
- * Check for client sending out PORT message.
- */
- if (dlen < IPF_MINPORTLEN)
- return 0;
- off = fin->fin_hlen + (tcp->th_off << 2);
- /*
- * Skip the PORT command + space
- */
- s = f->ftps_rptr + 5;
- /*
- * Pick out the address components, two at a time.
- */
- a1 = ippr_ftp_atoi(&s);
- if (!s)
- return 0;
- a2 = ippr_ftp_atoi(&s);
- if (!s)
- return 0;
- /*
- * check that IP address in the PORT/PASV reply is the same as the
- * sender of the command - prevents using PORT for port scanning.
- */
- a1 <<= 16;
- a1 |= a2;
- if (a1 != ntohl(nat->nat_inip.s_addr))
- return 0;
-
- a5 = ippr_ftp_atoi(&s);
- if (!s)
- return 0;
- if (*s == ')')
- s++;
-
- /*
- * check for CR-LF at the end.
- */
- if (*s == '\n')
- s--;
- if ((*s == '\r') && (*(s + 1) == '\n')) {
- s += 2;
- a6 = a5 & 0xff;
- } else
- return 0;
- a5 >>= 8;
- a5 &= 0xff;
- /*
- * Calculate new address parts for PORT command
- */
- a1 = ntohl(ip->ip_src.s_addr);
- a2 = (a1 >> 16) & 0xff;
- a3 = (a1 >> 8) & 0xff;
- a4 = a1 & 0xff;
- a1 >>= 24;
- olen = s - f->ftps_rptr;
- /* DO NOT change this to sprintf! */
- (void) sprintf(newbuf, "%s %u,%u,%u,%u,%u,%u\r\n",
- "PORT", a1, a2, a3, a4, a5, a6);
-
- nlen = strlen(newbuf);
- inc = nlen - olen;
- if ((inc + ip->ip_len) > 65535)
- return 0;
-
-#if SOLARIS
- m = fin->fin_qfm;
- for (m1 = m; m1->b_cont; m1 = m1->b_cont)
- ;
- if ((inc > 0) && (m1->b_datap->db_lim - m1->b_wptr < inc)) {
- mblk_t *nm;
-
- /* alloc enough to keep same trailer space for lower driver */
- nm = allocb(nlen, BPRI_MED);
- PANIC((!nm),("ippr_ftp_out: allocb failed"));
-
- nm->b_band = m1->b_band;
- nm->b_wptr += nlen;
-
- m1->b_wptr -= olen;
- PANIC((m1->b_wptr < m1->b_rptr),
- ("ippr_ftp_out: cannot handle fragmented data block"));
-
- linkb(m1, nm);
- } else {
- if (m1->b_datap->db_struiolim == m1->b_wptr)
- m1->b_datap->db_struiolim += inc;
- m1->b_datap->db_struioflag &= ~STRUIO_IP;
- m1->b_wptr += inc;
- }
- copyin_mblk(m, off, nlen, newbuf);
-#else
- m = *((mb_t **)fin->fin_mp);
- if (inc < 0)
- m_adj(m, inc);
- /* the mbuf chain will be extended if necessary by m_copyback() */
- m_copyback(m, off, nlen, newbuf);
-# ifdef M_PKTHDR
- if (!(m->m_flags & M_PKTHDR))
- m->m_pkthdr.len += inc;
-# endif
-#endif
- if (inc != 0) {
-#if SOLARIS || defined(__sgi)
- register u_32_t sum1, sum2;
-
- sum1 = ip->ip_len;
- sum2 = ip->ip_len + inc;
-
- /* Because ~1 == -2, We really need ~1 == -1 */
- if (sum1 > sum2)
- sum2--;
- sum2 -= sum1;
- sum2 = (sum2 & 0xffff) + (sum2 >> 16);
-
- fix_outcksum(&ip->ip_sum, sum2);
-#endif
- ip->ip_len += inc;
- }
-
- /*
- * Add skeleton NAT entry for connection which will come back the
- * other way.
- */
- sp = htons(a5 << 8 | a6);
- /*
- * Don't allow the PORT command to specify a port < 1024 due to
- * security crap.
- */
- if (ntohs(sp) < 1024)
- return 0;
- /*
- * The server may not make the connection back from port 20, but
- * it is the most likely so use it here to check for a conflicting
- * mapping.
- */
- dp = htons(fin->fin_data[1] - 1);
- ipn = nat_outlookup(fin->fin_ifp, IPN_TCP, nat->nat_p, nat->nat_inip,
- ip->ip_dst, (dp << 16) | sp, 0);
- if (ipn == NULL) {
- int slen;
-
- slen = ip->ip_len;
- ip->ip_len = fin->fin_hlen + sizeof(*tcp2);
- bcopy((char *)fin, (char *)&fi, sizeof(fi));
- bzero((char *)tcp2, sizeof(*tcp2));
- tcp2->th_win = htons(8192);
- tcp2->th_sport = sp;
- tcp2->th_off = 5;
- tcp2->th_dport = 0; /* XXX - don't specify remote port */
- fi.fin_data[0] = ntohs(sp);
- fi.fin_data[1] = 0;
- fi.fin_dlen = sizeof(*tcp2);
- fi.fin_dp = (char *)tcp2;
- fi.fin_fr = &natfr;
- swip = ip->ip_src;
- fi.fin_fi.fi_saddr = nat->nat_inip.s_addr;
- 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_len = slen;
- ip->ip_src = swip;
- }
- return APR_INC(inc);
-}
-
-
-int ippr_ftp_client(fin, ip, nat, ftp, dlen)
-fr_info_t *fin;
-nat_t *nat;
-ftpinfo_t *ftp;
-ip_t *ip;
-int dlen;
-{
- char *rptr, *wptr, cmd[6], c;
- ftpside_t *f;
- int inc, i;
-
- inc = 0;
- f = &ftp->ftp_side[0];
- rptr = f->ftps_rptr;
- wptr = f->ftps_wptr;
-
- for (i = 0; (i < 5) && (i < dlen); i++) {
- c = rptr[i];
- if (isalpha(c)) {
- cmd[i] = toupper(c);
- } else {
- cmd[i] = c;
- }
- }
- cmd[i] = '\0';
-
- if ((ftp->ftp_passok == 0) && !strncmp(cmd, "USER ", 5))
- ftp->ftp_passok = 1;
- else if ((ftp->ftp_passok == 2) && !strncmp(cmd, "PASS ", 5))
- ftp->ftp_passok = 3;
- else if ((ftp->ftp_passok == 4) && !ippr_ftp_pasvonly &&
- !strncmp(cmd, "PORT ", 5)) {
- inc = ippr_ftp_port(fin, ip, nat, f, dlen);
- } else if (ippr_ftp_insecure && !ippr_ftp_pasvonly &&
- !strncmp(cmd, "PORT ", 5)) {
- inc = ippr_ftp_port(fin, ip, nat, f, dlen);
- }
-
- while ((*rptr++ != '\n') && (rptr < wptr))
- ;
- f->ftps_rptr = rptr;
- return inc;
-}
-
-
-int ippr_ftp_pasv(fin, ip, nat, f, dlen)
-fr_info_t *fin;
-ip_t *ip;
-nat_t *nat;
-ftpside_t *f;
-int dlen;
-{
- tcphdr_t *tcp, tcph, *tcp2 = &tcph;
- struct in_addr swip, swip2;
- u_short a5, a6, sp, dp;
- u_int a1, a2, a3, a4;
- fr_info_t fi;
- nat_t *ipn;
- int inc;
- char *s;
-
- /*
- * Check for PASV reply message.
- */
- if (dlen < IPF_MIN227LEN)
- return 0;
- else if (strncmp(f->ftps_rptr, "227 Entering Passive Mode", 25))
- return 0;
-
- tcp = (tcphdr_t *)fin->fin_dp;
-
- /*
- * Skip the PORT command + space
- */
- s = f->ftps_rptr + 25;
- while (*s && !isdigit(*s))
- s++;
- /*
- * Pick out the address components, two at a time.
- */
- a1 = ippr_ftp_atoi(&s);
- if (!s)
- return 0;
- a2 = ippr_ftp_atoi(&s);
- if (!s)
- return 0;
-
- /*
- * check that IP address in the PORT/PASV reply is the same as the
- * sender of the command - prevents using PORT for port scanning.
- */
- a1 <<= 16;
- a1 |= a2;
- if (a1 != ntohl(nat->nat_oip.s_addr))
- return 0;
-
- a5 = ippr_ftp_atoi(&s);
- if (!s)
- return 0;
-
- if (*s == ')')
- s++;
- if (*s == '\n')
- s--;
- /*
- * check for CR-LF at the end.
- */
- if ((*s == '\r') && (*(s + 1) == '\n')) {
- s += 2;
- a6 = a5 & 0xff;
- } else
- return 0;
- a5 >>= 8;
- /*
- * Calculate new address parts for 227 reply
- */
- a1 = ntohl(ip->ip_src.s_addr);
- a2 = (a1 >> 16) & 0xff;
- a3 = (a1 >> 8) & 0xff;
- a4 = a1 & 0xff;
- a1 >>= 24;
- inc = 0;
-#if 0
- olen = s - f->ftps_rptr;
- (void) sprintf(newbuf, "%s %u,%u,%u,%u,%u,%u\r\n",
- "227 Entering Passive Mode", a1, a2, a3, a4, a5, a6);
- nlen = strlen(newbuf);
- inc = nlen - olen;
- if ((inc + ip->ip_len) > 65535)
- return 0;
-
-#if SOLARIS
- m = fin->fin_qfm;
- for (m1 = m; m1->b_cont; m1 = m1->b_cont)
- ;
- if ((inc > 0) && (m1->b_datap->db_lim - m1->b_wptr < inc)) {
- mblk_t *nm;
-
- /* alloc enough to keep same trailer space for lower driver */
- nm = allocb(nlen, BPRI_MED);
- PANIC((!nm),("ippr_ftp_out: allocb failed"));
-
- nm->b_band = m1->b_band;
- nm->b_wptr += nlen;
-
- m1->b_wptr -= olen;
- PANIC((m1->b_wptr < m1->b_rptr),
- ("ippr_ftp_out: cannot handle fragmented data block"));
-
- linkb(m1, nm);
- } else {
- m1->b_wptr += inc;
- }
- /*copyin_mblk(m, off, nlen, newbuf);*/
-#else /* SOLARIS */
- m = *((mb_t **)fin->fin_mp);
- if (inc < 0)
- m_adj(m, inc);
- /* the mbuf chain will be extended if necessary by m_copyback() */
- /*m_copyback(m, off, nlen, newbuf);*/
-#endif /* SOLARIS */
- if (inc != 0) {
-#if SOLARIS || defined(__sgi)
- register u_32_t sum1, sum2;
-
- sum1 = ip->ip_len;
- sum2 = ip->ip_len + inc;
-
- /* Because ~1 == -2, We really need ~1 == -1 */
- if (sum1 > sum2)
- sum2--;
- sum2 -= sum1;
- sum2 = (sum2 & 0xffff) + (sum2 >> 16);
-
- fix_outcksum(&ip->ip_sum, sum2);
-#endif /* SOLARIS || defined(__sgi) */
- ip->ip_len += inc;
- }
-#endif /* 0 */
-
- /*
- * Add skeleton NAT entry for connection which will come back the
- * other way.
- */
- sp = 0;
- dp = htons(fin->fin_data[1] - 1);
- ipn = nat_outlookup(fin->fin_ifp, IPN_TCP, nat->nat_p, nat->nat_inip,
- ip->ip_dst, (dp << 16) | sp, 0);
- if (ipn == NULL) {
- int slen;
-
- slen = ip->ip_len;
- ip->ip_len = fin->fin_hlen + sizeof(*tcp2);
- bcopy((char *)fin, (char *)&fi, sizeof(fi));
- bzero((char *)tcp2, sizeof(*tcp2));
- tcp2->th_win = htons(8192);
- tcp2->th_sport = 0; /* XXX - fake it for nat_new */
- tcp2->th_off = 5;
- fi.fin_data[1] = a5 << 8 | a6;
- fi.fin_dlen = sizeof(*tcp2);
- tcp2->th_dport = htons(fi.fin_data[1]);
- fi.fin_data[0] = 0;
- fi.fin_dp = (char *)tcp2;
- fi.fin_fr = &natfr;
- swip = ip->ip_src;
- swip2 = ip->ip_dst;
- fi.fin_fi.fi_daddr = ip->ip_src.s_addr;
- fi.fin_fi.fi_saddr = nat->nat_inip.s_addr;
- ip->ip_dst = ip->ip_src;
- ip->ip_src = nat->nat_inip;
- ipn = nat_new(nat->nat_ptr, ip, &fi, IPN_TCP|FI_W_SPORT,
- NAT_OUTBOUND);
- if (ipn != NULL) {
- ipn->nat_age = fr_defnatage;
- (void) fr_addstate(ip, &fi, FI_W_SPORT);
- }
- ip->ip_len = slen;
- ip->ip_src = swip;
- ip->ip_dst = swip2;
- }
- return inc;
-}
-
-
-int ippr_ftp_server(fin, ip, nat, ftp, dlen)
-fr_info_t *fin;
-ip_t *ip;
-nat_t *nat;
-ftpinfo_t *ftp;
-int dlen;
-{
- char *rptr, *wptr;
- ftpside_t *f;
- int inc;
-
- inc = 0;
- f = &ftp->ftp_side[1];
- rptr = f->ftps_rptr;
- wptr = f->ftps_wptr;
-
- if ((ftp->ftp_passok == 1) && !strncmp(rptr, "331", 3))
- ftp->ftp_passok = 2;
- else if ((ftp->ftp_passok == 3) && !strncmp(rptr, "230", 3))
- ftp->ftp_passok = 4;
- else if ((ftp->ftp_passok == 3) && !strncmp(rptr, "530", 3))
- ftp->ftp_passok = 0;
- else if ((ftp->ftp_passok == 4) && !strncmp(rptr, "227 ", 4)) {
- inc = ippr_ftp_pasv(fin, ip, nat, f, dlen);
- } else if (ippr_ftp_insecure && !strncmp(rptr, "227 ", 4)) {
- inc = ippr_ftp_pasv(fin, ip, nat, f, dlen);
- }
- while ((*rptr++ != '\n') && (rptr < wptr))
- ;
- f->ftps_rptr = rptr;
- return inc;
-}
-
-
-/*
- * Look to see if the buffer starts with something which we recognise as
- * being the correct syntax for the FTP protocol.
- */
-int ippr_ftp_valid(buf, len)
-char *buf;
-size_t len;
-{
- register char *s, c;
- register size_t i = len;
-
- if (i < 5)
- return 2;
- s = buf;
- c = *s++;
- i--;
-
- if (isdigit(c)) {
- c = *s++;
- i--;
- if (isdigit(c)) {
- c = *s++;
- i--;
- if (isdigit(c)) {
- c = *s++;
- i--;
- if ((c != '-') && (c != ' '))
- return 1;
- } else
- return 1;
- } else
- return 1;
- } else if (isalpha(c)) {
- c = *s++;
- i--;
- if (isalpha(c)) {
- c = *s++;
- i--;
- if (isalpha(c)) {
- c = *s++;
- i--;
- if (isalpha(c)) {
- c = *s++;
- i--;
- if ((c != ' ') && (c != '\r'))
- return 1;
- } else if ((c != ' ') && (c != '\r'))
- return 1;
- } else
- return 1;
- } else
- return 1;
- } else
- return 1;
- for (; i; i--) {
- c = *s++;
- if (c == '\n')
- return 0;
- }
- return 2;
-}
-
-
-int ippr_ftp_process(fin, ip, nat, ftp, rv)
-fr_info_t *fin;
-ip_t *ip;
-nat_t *nat;
-ftpinfo_t *ftp;
-int rv;
-{
- int mlen, len, off, inc, i, sel;
- char *rptr, *wptr;
- ftpside_t *f, *t;
- tcphdr_t *tcp;
- mb_t *m;
-
- tcp = (tcphdr_t *)fin->fin_dp;
- off = fin->fin_hlen + (tcp->th_off << 2);
-
-#if SOLARIS
- m = fin->fin_qfm;
-#else
- m = *((mb_t **)fin->fin_mp);
-#endif
-
-#if SOLARIS
- mlen = msgdsize(m) - off;
-#else
- mlen = mbufchainlen(m) - off;
-#endif
-
- t = &ftp->ftp_side[1 - rv];
- f = &ftp->ftp_side[rv];
- if (!mlen) {
- if (!t->ftps_seq ||
- (int)ntohl(tcp->th_ack) - (int)t->ftps_seq > 0)
- t->ftps_seq = ntohl(tcp->th_ack);
- f->ftps_len = 0;
- return 0;
- }
-
- inc = 0;
- rptr = f->ftps_rptr;
- wptr = f->ftps_wptr;
-
- sel = nat->nat_aps->aps_sel[1 - rv];
- if (rv)
- i = nat->nat_aps->aps_ackoff[sel];
- else
- i = nat->nat_aps->aps_seqoff[sel];
- /*
- * XXX - Ideally, this packet should get dropped because we now know
- * that it is out of order (and there is no real danger in doing so
- * apart from causing packets to go through here ordered).
- */
- if (f->ftps_len + f->ftps_seq == ntohl(tcp->th_seq))
- f->ftps_seq = ntohl(tcp->th_seq);
- else if (ntohl(tcp->th_seq) + i != f->ftps_seq) {
- return APR_ERR(-1);
- }
- f->ftps_len = mlen;
-
- while (mlen > 0) {
- len = MIN(mlen, FTP_BUFSZ / 2);
-
-#if SOLARIS
- copyout_mblk(m, off, len, wptr);
-#else
- m_copydata(m, off, len, wptr);
-#endif
- mlen -= len;
- off += len;
- wptr += len;
- f->ftps_wptr = wptr;
- if (f->ftps_junk == 2)
- f->ftps_junk = ippr_ftp_valid(rptr, wptr - rptr);
-
- while ((f->ftps_junk == 0) && (wptr > rptr)) {
- f->ftps_junk = ippr_ftp_valid(rptr, wptr - rptr);
- if (f->ftps_junk == 0) {
- len = wptr - rptr;
- f->ftps_rptr = rptr;
- if (rv)
- inc += ippr_ftp_server(fin, ip, nat,
- ftp, len);
- else
- inc += ippr_ftp_client(fin, ip, nat,
- ftp, len);
- rptr = f->ftps_rptr;
- }
- }
-
- while ((f->ftps_junk == 1) && (rptr < wptr)) {
- while ((rptr < wptr) && (*rptr != '\r'))
- rptr++;
-
- if (*rptr == '\r') {
- if (rptr + 1 < wptr) {
- if (*(rptr + 1) == '\n') {
- rptr += 2;
- f->ftps_junk = 0;
- } else
- rptr++;
- } else
- break;
- }
- }
- f->ftps_rptr = rptr;
-
- if (rptr == wptr) {
- rptr = wptr = f->ftps_buf;
- } else {
- if ((wptr > f->ftps_buf + FTP_BUFSZ / 2)) {
- i = wptr - rptr;
- if ((rptr == f->ftps_buf) ||
- (wptr - rptr > FTP_BUFSZ / 2)) {
- f->ftps_junk = 1;
- rptr = wptr = f->ftps_buf;
- } else {
- bcopy(rptr, f->ftps_buf, i);
- wptr = f->ftps_buf + i;
- rptr = f->ftps_buf;
- }
- }
- f->ftps_rptr = rptr;
- f->ftps_wptr = wptr;
- }
- }
-
- t->ftps_seq = ntohl(tcp->th_ack);
- f->ftps_rptr = rptr;
- f->ftps_wptr = wptr;
- return APR_INC(inc);
-}
-
-
-int ippr_ftp_out(fin, ip, aps, nat)
-fr_info_t *fin;
-ip_t *ip;
-ap_session_t *aps;
-nat_t *nat;
-{
- ftpinfo_t *ftp;
-
- ftp = aps->aps_data;
- if (ftp == NULL)
- return 0;
- return ippr_ftp_process(fin, ip, nat, ftp, 0);
-}
-
-
-int ippr_ftp_in(fin, ip, aps, nat)
-fr_info_t *fin;
-ip_t *ip;
-ap_session_t *aps;
-nat_t *nat;
-{
- ftpinfo_t *ftp;
-
- ftp = aps->aps_data;
- if (ftp == NULL)
- return 0;
- return ippr_ftp_process(fin, ip, nat, ftp, 1);
-}
-
-
-/*
- * ippr_ftp_atoi - implement a version of atoi which processes numbers in
- * pairs separated by commas (which are expected to be in the range 0 - 255),
- * returning a 16 bit number combining either side of the , as the MSB and
- * LSB.
- */
-u_short ippr_ftp_atoi(ptr)
-char **ptr;
-{
- register char *s = *ptr, c;
- register u_char i = 0, j = 0;
-
- while ((c = *s++) && isdigit(c)) {
- i *= 10;
- i += c - '0';
- }
- if (c != ',') {
- *ptr = NULL;
- return 0;
- }
- while ((c = *s++) && isdigit(c)) {
- j *= 10;
- j += c - '0';
- }
- *ptr = s;
- i &= 0xff;
- j &= 0xff;
- return (i << 8) | j;
-}
diff --git a/contrib/ipfilter/ip_log.c b/contrib/ipfilter/ip_log.c
deleted file mode 100644
index a7d1529..0000000
--- a/contrib/ipfilter/ip_log.c
+++ /dev/null
@@ -1,502 +0,0 @@
-/*
- * Copyright (C) 1997-2000 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: ip_log.c,v 2.1.2.2 1999/09/21 11:55:44 darrenr Exp $
- * $FreeBSD$
- */
-#include <sys/param.h>
-#if defined(KERNEL) && !defined(_KERNEL)
-# define _KERNEL
-#endif
-#if defined(__NetBSD__) && (NetBSD >= 199905) && !defined(IPFILTER_LKM)
-# include "opt_ipfilter_log.h"
-#endif
-#ifdef __FreeBSD__
-# if defined(_KERNEL) && !defined(IPFILTER_LKM)
-# if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
-# include "opt_ipfilter.h"
-# endif
-# else
-# ifdef KLD_MODULE
-# include <osreldate.h>
-# endif
-# endif
-#endif
-#ifdef IPFILTER_LOG
-# ifndef SOLARIS
-# define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
-# endif
-# ifndef _KERNEL
-# include <stdio.h>
-# include <string.h>
-# include <stdlib.h>
-# include <ctype.h>
-# endif
-# include <sys/errno.h>
-# include <sys/types.h>
-# include <sys/file.h>
-# if __FreeBSD_version >= 220000 && defined(_KERNEL)
-# include <sys/fcntl.h>
-# include <sys/filio.h>
-# else
-# include <sys/ioctl.h>
-# endif
-# include <sys/time.h>
-# if defined(_KERNEL) && !defined(linux)
-# include <sys/systm.h>
-# endif
-# include <sys/uio.h>
-# if !SOLARIS
-# if (NetBSD > 199609) || (OpenBSD > 199603) || (__FreeBSD_version >= 300000)
-# include <sys/dirent.h>
-# else
-# include <sys/dir.h>
-# endif
-# ifndef linux
-# include <sys/mbuf.h>
-# endif
-# else
-# include <sys/filio.h>
-# include <sys/cred.h>
-# include <sys/ddi.h>
-# include <sys/sunddi.h>
-# include <sys/ksynch.h>
-# include <sys/kmem.h>
-# include <sys/mkdev.h>
-# include <sys/dditypes.h>
-# include <sys/cmn_err.h>
-# endif
-# ifndef linux
-# include <sys/protosw.h>
-# endif
-# include <sys/socket.h>
-
-# include <net/if.h>
-# ifdef sun
-# include <net/af.h>
-# endif
-# if __FreeBSD_version >= 300000
-# include <net/if_var.h>
-# endif
-# include <net/route.h>
-# include <netinet/in.h>
-# ifdef __sgi
-# include <sys/ddi.h>
-# ifdef IFF_DRVRLOCK /* IRIX6 */
-# include <sys/hashing.h>
-# endif
-# endif
-# if !defined(linux) && !(defined(__sgi) && !defined(IFF_DRVRLOCK)) /*IRIX<6*/
-# include <netinet/in_var.h>
-# endif
-# include <netinet/in_systm.h>
-# include <netinet/ip.h>
-# include <netinet/tcp.h>
-# include <netinet/udp.h>
-# include <netinet/ip_icmp.h>
-# ifndef linux
-# include <netinet/ip_var.h>
-# endif
-# ifndef _KERNEL
-# include <syslog.h>
-# endif
-# include "netinet/ip_compat.h"
-# include <netinet/tcpip.h>
-# include "netinet/ip_fil.h"
-# include "netinet/ip_proxy.h"
-# include "netinet/ip_nat.h"
-# include "netinet/ip_frag.h"
-# include "netinet/ip_state.h"
-# include "netinet/ip_auth.h"
-# if (__FreeBSD_version >= 300000)
-# include <sys/malloc.h>
-# endif
-
-# ifndef MIN
-# define MIN(a,b) (((a)<(b))?(a):(b))
-# endif
-
-
-# if SOLARIS || defined(__sgi)
-extern kmutex_t ipl_mutex;
-# if SOLARIS
-extern kcondvar_t iplwait;
-# endif
-# endif
-
-iplog_t **iplh[IPL_LOGMAX+1], *iplt[IPL_LOGMAX+1], *ipll[IPL_LOGMAX+1];
-size_t iplused[IPL_LOGMAX+1];
-static fr_info_t iplcrc[IPL_LOGMAX+1];
-# ifdef linux
-static struct wait_queue *iplwait[IPL_LOGMAX+1];
-# endif
-
-
-/*
- * Initialise log buffers & pointers. Also iniialised the CRC to a local
- * secret for use in calculating the "last log checksum".
- */
-void ipflog_init()
-{
- int i;
-
- for (i = IPL_LOGMAX; i >= 0; i--) {
- iplt[i] = NULL;
- ipll[i] = NULL;
- iplh[i] = &iplt[i];
- iplused[i] = 0;
- bzero((char *)&iplcrc[i], sizeof(iplcrc[i]));
- }
-}
-
-
-/*
- * ipflog
- * Create a log record for a packet given that it has been triggered by a
- * rule (or the default setting). Calculate the transport protocol header
- * size using predetermined size of a couple of popular protocols and thus
- * how much data to copy into the log, including part of the data body if
- * requested.
- */
-int ipflog(flags, ip, fin, m)
-u_int flags;
-ip_t *ip;
-fr_info_t *fin;
-mb_t *m;
-{
- ipflog_t ipfl;
- register size_t mlen, hlen;
- size_t sizes[2];
- void *ptrs[2];
- int types[2];
- u_char p;
-# if SOLARIS
- ill_t *ifp = fin->fin_ifp;
-# else
- struct ifnet *ifp = fin->fin_ifp;
-# endif
-
- /*
- * calculate header size.
- */
- hlen = fin->fin_hlen;
- if (fin->fin_off == 0) {
- p = fin->fin_fi.fi_p;
- if (p == IPPROTO_TCP)
- hlen += MIN(sizeof(tcphdr_t), fin->fin_dlen);
- else if (p == IPPROTO_UDP)
- hlen += MIN(sizeof(udphdr_t), fin->fin_dlen);
- else if (p == IPPROTO_ICMP) {
- struct icmp *icmp;
-
- icmp = (struct icmp *)fin->fin_dp;
-
- /*
- * For ICMP, if the packet is an error packet, also
- * include the information about the packet which
- * caused the error.
- */
- switch (icmp->icmp_type)
- {
- case ICMP_UNREACH :
- case ICMP_SOURCEQUENCH :
- case ICMP_REDIRECT :
- case ICMP_TIMXCEED :
- case ICMP_PARAMPROB :
- hlen += MIN(sizeof(struct icmp) + 8,
- fin->fin_dlen);
- break;
- default :
- hlen += MIN(sizeof(struct icmp),
- fin->fin_dlen);
- break;
- }
- }
- }
- /*
- * Get the interface number and name to which this packet is
- * currently associated.
- */
-# if SOLARIS
- ipfl.fl_unit = (u_char)ifp->ill_ppa;
- bcopy(ifp->ill_name, ipfl.fl_ifname, MIN(ifp->ill_name_length, 4));
- mlen = (flags & FR_LOGBODY) ? MIN(msgdsize(m) - hlen, 128) : 0;
-# else
-# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \
- (defined(OpenBSD) && (OpenBSD >= 199603))
- strncpy(ipfl.fl_ifname, ifp->if_xname, IFNAMSIZ);
-# else
-# ifndef linux
- ipfl.fl_unit = (u_char)ifp->if_unit;
-# endif
- if ((ipfl.fl_ifname[0] = ifp->if_name[0]))
- if ((ipfl.fl_ifname[1] = ifp->if_name[1]))
- if ((ipfl.fl_ifname[2] = ifp->if_name[2]))
- ipfl.fl_ifname[3] = ifp->if_name[3];
-# endif
- mlen = (flags & FR_LOGBODY) ? MIN(fin->fin_plen - hlen, 128) : 0;
-# endif
- ipfl.fl_plen = (u_char)mlen;
- ipfl.fl_hlen = (u_char)hlen;
- ipfl.fl_rule = fin->fin_rule;
- ipfl.fl_group = fin->fin_group;
- if (fin->fin_fr != NULL)
- ipfl.fl_loglevel = fin->fin_fr->fr_loglevel;
- else
- ipfl.fl_loglevel = 0xffff;
- ipfl.fl_flags = flags;
- ptrs[0] = (void *)&ipfl;
- sizes[0] = sizeof(ipfl);
- types[0] = 0;
-# if SOLARIS
- /*
- * Are we copied from the mblk or an aligned array ?
- */
- if (ip == (ip_t *)m->b_rptr) {
- ptrs[1] = m;
- sizes[1] = hlen + mlen;
- types[1] = 1;
- } else {
- ptrs[1] = ip;
- sizes[1] = hlen + mlen;
- types[1] = 0;
- }
-# else
- ptrs[1] = m;
- sizes[1] = hlen + mlen;
- types[1] = 1;
-# endif
- return ipllog(IPL_LOGIPF, fin, ptrs, sizes, types, 2);
-}
-
-
-/*
- * ipllog
- */
-int ipllog(dev, fin, items, itemsz, types, cnt)
-int dev;
-fr_info_t *fin;
-void **items;
-size_t *itemsz;
-int *types, cnt;
-{
- caddr_t buf, s;
- iplog_t *ipl;
- size_t len;
- int i;
-
- /*
- * Check to see if this log record has a CRC which matches the last
- * record logged. If it does, just up the count on the previous one
- * rather than create a new one.
- */
- MUTEX_ENTER(&ipl_mutex);
- if (fin != NULL) {
- if ((ipll[dev] != NULL) &&
- bcmp((char *)fin, (char *)&iplcrc[dev], FI_CSIZE) == 0) {
- ipll[dev]->ipl_count++;
- MUTEX_EXIT(&ipl_mutex);
- return 1;
- }
- bcopy((char *)fin, (char *)&iplcrc[dev], FI_CSIZE);
- } else
- bzero((char *)&iplcrc[dev], FI_CSIZE);
- MUTEX_EXIT(&ipl_mutex);
-
- /*
- * Get the total amount of data to be logged.
- */
- for (i = 0, len = sizeof(iplog_t); i < cnt; i++)
- len += itemsz[i];
-
- /*
- * check that we have space to record this information and can
- * allocate that much.
- */
- KMALLOCS(buf, caddr_t, len);
- if (!buf)
- return 0;
- MUTEX_ENTER(&ipl_mutex);
- if ((iplused[dev] + len) > IPLLOGSIZE) {
- MUTEX_EXIT(&ipl_mutex);
- KFREES(buf, len);
- return 0;
- }
- iplused[dev] += len;
- MUTEX_EXIT(&ipl_mutex);
-
- /*
- * advance the log pointer to the next empty record and deduct the
- * amount of space we're going to use.
- */
- ipl = (iplog_t *)buf;
- ipl->ipl_magic = IPL_MAGIC;
- ipl->ipl_count = 1;
- ipl->ipl_next = NULL;
- ipl->ipl_dsize = len;
-# if SOLARIS || defined(sun) || defined(linux)
- uniqtime((struct timeval *)&ipl->ipl_sec);
-# else
-# if BSD >= 199306 || defined(__FreeBSD__) || defined(__sgi)
- microtime((struct timeval *)&ipl->ipl_sec);
-# endif
-# endif
-
- /*
- * Loop through all the items to be logged, copying each one to the
- * buffer. Use bcopy for normal data or the mb_t copyout routine.
- */
- for (i = 0, s = buf + sizeof(*ipl); i < cnt; i++) {
- if (types[i] == 0)
- bcopy(items[i], s, itemsz[i]);
- else if (types[i] == 1) {
-# if SOLARIS
- copyout_mblk(items[i], 0, itemsz[i], s);
-# else
- m_copydata(items[i], 0, itemsz[i], s);
-# endif
- }
- s += itemsz[i];
- }
- MUTEX_ENTER(&ipl_mutex);
- ipll[dev] = ipl;
- *iplh[dev] = ipl;
- iplh[dev] = &ipl->ipl_next;
-# if SOLARIS
- cv_signal(&iplwait);
- mutex_exit(&ipl_mutex);
-# else
- MUTEX_EXIT(&ipl_mutex);
-# ifdef linux
- wake_up_interruptible(&iplwait[dev]);
-# else
- wakeup(&iplh[dev]);
-# endif
-# endif
- return 1;
-}
-
-
-int ipflog_read(unit, uio)
-minor_t unit;
-struct uio *uio;
-{
- size_t dlen, copied;
- int error = 0;
- iplog_t *ipl;
-# if defined(_KERNEL) && !SOLARIS
- int s;
-# endif
-
- /*
- * Sanity checks. Make sure the minor # is valid and we're copying
- * a valid chunk of data.
- */
- if (IPL_LOGMAX < unit)
- return ENXIO;
- if (!uio->uio_resid)
- return 0;
- if ((uio->uio_resid < sizeof(iplog_t)) ||
- (uio->uio_resid > IPLLOGSIZE))
- return EINVAL;
-
- /*
- * Lock the log so we can snapshot the variables. Wait for a signal
- * if the log is empty.
- */
- SPL_NET(s);
- MUTEX_ENTER(&ipl_mutex);
-
- while (!iplused[unit] || !iplt[unit]) {
-# if SOLARIS && defined(_KERNEL)
- if (!cv_wait_sig(&iplwait, &ipl_mutex)) {
- MUTEX_EXIT(&ipl_mutex);
- return EINTR;
- }
-# else
-# ifdef linux
- interruptible_sleep_on(&iplwait[unit]);
- if (current->signal & ~current->blocked)
- return -EINTR;
-# else
- MUTEX_EXIT(&ipl_mutex);
- SPL_X(s);
- error = SLEEP(&iplh[unit], "ipl sleep");
- if (error)
- return error;
- SPL_NET(s);
- MUTEX_ENTER(&ipl_mutex);
-# endif /* linux */
-# endif /* SOLARIS */
- }
-
-# if BSD >= 199306 || defined(__FreeBSD__)
- uio->uio_rw = UIO_READ;
-# endif
-
- for (copied = 0; (ipl = iplt[unit]); copied += dlen) {
- dlen = ipl->ipl_dsize;
- if (dlen > uio->uio_resid)
- break;
- /*
- * Don't hold the mutex over the uiomove call.
- */
- iplt[unit] = ipl->ipl_next;
- iplused[unit] -= dlen;
- MUTEX_EXIT(&ipl_mutex);
- SPL_X(s);
- error = UIOMOVE((caddr_t)ipl, dlen, UIO_READ, uio);
- if (error) {
- SPL_NET(s);
- MUTEX_ENTER(&ipl_mutex);
- ipl->ipl_next = iplt[unit];
- iplt[unit] = ipl;
- iplused[unit] += dlen;
- break;
- }
- KFREES((caddr_t)ipl, dlen);
- SPL_NET(s);
- MUTEX_ENTER(&ipl_mutex);
- }
- if (!iplt[unit]) {
- iplused[unit] = 0;
- iplh[unit] = &iplt[unit];
- ipll[unit] = NULL;
- }
-
- MUTEX_EXIT(&ipl_mutex);
- SPL_X(s);
-# ifdef linux
- if (!error)
- return (int)copied;
- return -error;
-# else
- return error;
-# endif
-}
-
-
-int ipflog_clear(unit)
-minor_t unit;
-{
- iplog_t *ipl;
- int used;
-
- MUTEX_ENTER(&ipl_mutex);
- while ((ipl = iplt[unit])) {
- iplt[unit] = ipl->ipl_next;
- KFREES((caddr_t)ipl, ipl->ipl_dsize);
- }
- iplh[unit] = &iplt[unit];
- ipll[unit] = NULL;
- used = iplused[unit];
- iplused[unit] = 0;
- bzero((char *)&iplcrc[unit], FI_CSIZE);
- MUTEX_EXIT(&ipl_mutex);
- return used;
-}
-#endif /* IPFILTER_LOG */
diff --git a/contrib/ipfilter/ip_nat.c b/contrib/ipfilter/ip_nat.c
deleted file mode 100644
index e7e121a..0000000
--- a/contrib/ipfilter/ip_nat.c
+++ /dev/null
@@ -1,2737 +0,0 @@
-/*
- * Copyright (C) 1995-2000 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)
-static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.37.2.32 2001/01/10 06:19:11 darrenr Exp $";
-#endif
-
-#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL)
-#define _KERNEL
-#endif
-
-#include <sys/errno.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/file.h>
-#if defined(__NetBSD__) && (NetBSD >= 199905) && !defined(IPFILTER_LKM) && \
- defined(_KERNEL)
-# include "opt_ipfilter_log.h"
-#endif
-#if !defined(_KERNEL) && !defined(KERNEL)
-# include <stdio.h>
-# include <string.h>
-# include <stdlib.h>
-#endif
-#if (defined(KERNEL) || defined(_KERNEL)) && (__FreeBSD_version >= 220000)
-# include <sys/filio.h>
-# include <sys/fcntl.h>
-#else
-# include <sys/ioctl.h>
-#endif
-#include <sys/fcntl.h>
-#include <sys/uio.h>
-#ifndef linux
-# include <sys/protosw.h>
-#endif
-#include <sys/socket.h>
-#if defined(_KERNEL) && !defined(linux)
-# include <sys/systm.h>
-#endif
-#if !defined(__SVR4) && !defined(__svr4__)
-# ifndef linux
-# include <sys/mbuf.h>
-# endif
-#else
-# include <sys/filio.h>
-# include <sys/byteorder.h>
-# ifdef _KERNEL
-# include <sys/dditypes.h>
-# endif
-# include <sys/stream.h>
-# include <sys/kmem.h>
-#endif
-#if __FreeBSD_version >= 300000
-# include <sys/queue.h>
-#endif
-#include <net/if.h>
-#if __FreeBSD_version >= 300000
-# include <net/if_var.h>
-# if defined(_KERNEL) && !defined(IPFILTER_LKM)
-# include "opt_ipfilter.h"
-# endif
-#endif
-#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 __sgi
-# ifdef IFF_DRVRLOCK /* IRIX6 */
-#include <sys/hashing.h>
-#include <netinet/in_var.h>
-# endif
-#endif
-
-#ifdef RFC1825
-# include <vpn/md5.h>
-# include <vpn/ipsec.h>
-extern struct ifnet vpnif;
-#endif
-
-#ifndef linux
-# include <netinet/ip_var.h>
-#endif
-#include <netinet/tcp.h>
-#include <netinet/udp.h>
-#include <netinet/ip_icmp.h>
-#include "netinet/ip_compat.h"
-#include <netinet/tcpip.h>
-#include "netinet/ip_fil.h"
-#include "netinet/ip_proxy.h"
-#include "netinet/ip_nat.h"
-#include "netinet/ip_frag.h"
-#include "netinet/ip_state.h"
-#if (__FreeBSD_version >= 300000)
-# include <sys/malloc.h>
-#endif
-#ifndef MIN
-# define MIN(a,b) (((a)<(b))?(a):(b))
-#endif
-#undef SOCKADDR_IN
-#define SOCKADDR_IN struct sockaddr_in
-
-nat_t **nat_table[2] = { NULL, NULL },
- *nat_instances = NULL;
-ipnat_t *nat_list = NULL;
-u_int ipf_nattable_sz = NAT_TABLE_SZ;
-u_int ipf_natrules_sz = NAT_SIZE;
-u_int ipf_rdrrules_sz = RDR_SIZE;
-u_int ipf_hostmap_sz = HOSTMAP_SIZE;
-u_32_t nat_masks = 0;
-u_32_t rdr_masks = 0;
-ipnat_t **nat_rules = NULL;
-ipnat_t **rdr_rules = NULL;
-hostmap_t **maptable = NULL;
-
-u_long fr_defnatage = DEF_NAT_AGE,
- fr_defnaticmpage = 6; /* 3 seconds */
-natstat_t nat_stats;
-int fr_nat_lock = 0;
-#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
-extern kmutex_t ipf_rw;
-extern KRWLOCK_T ipf_nat;
-#endif
-
-static int nat_flushtable __P((void));
-static int nat_clearlist __P((void));
-static void nat_addnat __P((struct ipnat *));
-static void nat_addrdr __P((struct ipnat *));
-static void nat_delete __P((struct nat *));
-static void nat_delrdr __P((struct ipnat *));
-static void nat_delnat __P((struct ipnat *));
-static int fr_natgetent __P((caddr_t));
-static int fr_natgetsz __P((caddr_t));
-static int fr_natputent __P((caddr_t));
-static void nat_tabmove __P((nat_t *, u_32_t));
-static int nat_match __P((fr_info_t *, ipnat_t *, ip_t *));
-static hostmap_t *nat_hostmap __P((ipnat_t *, struct in_addr,
- struct in_addr));
-static void nat_hostmapdel __P((struct hostmap *));
-
-
-int nat_init()
-{
- KMALLOCS(nat_table[0], nat_t **, sizeof(nat_t *) * ipf_nattable_sz);
- if (nat_table[0] != NULL)
- bzero((char *)nat_table[0], ipf_nattable_sz * sizeof(nat_t *));
- else
- return -1;
-
- KMALLOCS(nat_table[1], nat_t **, sizeof(nat_t *) * ipf_nattable_sz);
- if (nat_table[1] != NULL)
- bzero((char *)nat_table[1], ipf_nattable_sz * sizeof(nat_t *));
- else
- return -1;
-
- KMALLOCS(nat_rules, ipnat_t **, sizeof(ipnat_t *) * ipf_natrules_sz);
- if (nat_rules != NULL)
- bzero((char *)nat_rules, ipf_natrules_sz * sizeof(ipnat_t *));
- else
- return -1;
-
- KMALLOCS(rdr_rules, ipnat_t **, sizeof(ipnat_t *) * ipf_rdrrules_sz);
- if (rdr_rules != NULL)
- bzero((char *)rdr_rules, ipf_rdrrules_sz * sizeof(ipnat_t *));
- else
- return -1;
-
- KMALLOCS(maptable, hostmap_t **, sizeof(hostmap_t *) * ipf_hostmap_sz);
- if (maptable != NULL)
- bzero((char *)maptable, sizeof(hostmap_t *) * ipf_hostmap_sz);
- else
- return -1;
- return 0;
-}
-
-
-static void nat_addrdr(n)
-ipnat_t *n;
-{
- ipnat_t **np;
- u_32_t j;
- u_int hv;
- int k;
-
- k = countbits(n->in_outmsk);
- if ((k >= 0) && (k != 32))
- rdr_masks |= 1 << k;
- j = (n->in_outip & n->in_outmsk);
- hv = NAT_HASH_FN(j, 0, ipf_rdrrules_sz);
- np = rdr_rules + hv;
- while (*np != NULL)
- np = &(*np)->in_rnext;
- n->in_rnext = NULL;
- n->in_prnext = np;
- *np = n;
-}
-
-
-static void nat_addnat(n)
-ipnat_t *n;
-{
- ipnat_t **np;
- u_32_t j;
- u_int hv;
- int k;
-
- k = countbits(n->in_inmsk);
- if ((k >= 0) && (k != 32))
- nat_masks |= 1 << k;
- j = (n->in_inip & n->in_inmsk);
- hv = NAT_HASH_FN(j, 0, ipf_natrules_sz);
- np = nat_rules + hv;
- while (*np != NULL)
- np = &(*np)->in_mnext;
- n->in_mnext = NULL;
- n->in_pmnext = np;
- *np = n;
-}
-
-
-static void nat_delrdr(n)
-ipnat_t *n;
-{
- if (n->in_rnext)
- n->in_rnext->in_prnext = n->in_prnext;
- *n->in_prnext = n->in_rnext;
-}
-
-
-static void nat_delnat(n)
-ipnat_t *n;
-{
- if (n->in_mnext)
- n->in_mnext->in_pmnext = n->in_pmnext;
- *n->in_pmnext = n->in_mnext;
-}
-
-
-/*
- * check if an ip address has already been allocated for a given mapping that
- * is not doing port based translation.
- *
- * Must be called with ipf_nat held as a write lock.
- */
-static struct hostmap *nat_hostmap(np, real, map)
-ipnat_t *np;
-struct in_addr real;
-struct in_addr map;
-{
- hostmap_t *hm;
- u_int hv;
-
- hv = real.s_addr % HOSTMAP_SIZE;
- for (hm = maptable[hv]; hm; hm = hm->hm_next)
- if ((hm->hm_realip.s_addr == real.s_addr) &&
- (np == hm->hm_ipnat)) {
- hm->hm_ref++;
- return hm;
- }
-
- KMALLOC(hm, hostmap_t *);
- if (hm) {
- hm->hm_next = maptable[hv];
- hm->hm_pnext = maptable + hv;
- if (maptable[hv])
- maptable[hv]->hm_pnext = &hm->hm_next;
- maptable[hv] = hm;
- hm->hm_ipnat = np;
- hm->hm_realip = real;
- hm->hm_mapip = map;
- hm->hm_ref = 1;
- }
- return hm;
-}
-
-
-/*
- * Must be called with ipf_nat held as a write lock.
- */
-static void nat_hostmapdel(hm)
-struct hostmap *hm;
-{
- ATOMIC_DEC32(hm->hm_ref);
- if (hm->hm_ref == 0) {
- if (hm->hm_next)
- hm->hm_next->hm_pnext = hm->hm_pnext;
- *hm->hm_pnext = hm->hm_next;
- KFREE(hm);
- }
-}
-
-
-void fix_outcksum(sp, n)
-u_short *sp;
-u_32_t n;
-{
- 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);
- /* Again */
- sum1 = (sum1 >> 16) + (sum1 & 0xffff);
- sumshort = ~(u_short)sum1;
- *(sp) = htons(sumshort);
-}
-
-
-void fix_incksum(sp, n)
-u_short *sp;
-u_32_t n;
-{
- 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
- 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);
-}
-
-
-/*
- * fix_datacksum is used *only* for the adjustments of checksums in the data
- * section of an IP packet.
- *
- * The only situation in which you need to do this is when NAT'ing an
- * ICMP error message. Such a message, contains in its body the IP header
- * of the original IP packet, that causes the error.
- *
- * You can't use fix_incksum or fix_outcksum in that case, because for the
- * kernel the data section of the ICMP error is just data, and no special
- * processing like hardware cksum or ntohs processing have been done by the
- * kernel on the data section.
- */
-void fix_datacksum(sp, n)
-u_short *sp;
-u_32_t n;
-{
- register u_short sumshort;
- register u_32_t sum1;
-
- if (!n)
- return;
-
- sum1 = (~ntohs(*sp)) & 0xffff;
- sum1 += (n);
- sum1 = (sum1 >> 16) + (sum1 & 0xffff);
- /* Again */
- sum1 = (sum1 >> 16) + (sum1 & 0xffff);
- sumshort = ~(u_short)sum1;
- *(sp) = htons(sumshort);
-}
-
-/*
- * How the NAT is organised and works.
- *
- * 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)
-#if defined(__NetBSD__) || defined(__OpenBSD__) || (__FreeBSD_version >= 300003)
-u_long cmd;
-#else
-int cmd;
-#endif
-caddr_t data;
-int mode;
-{
- register ipnat_t *nat, *nt, *n = NULL, **np = NULL;
- int error = 0, ret, arg;
- ipnat_t natd;
- u_32_t i, j;
-
-#if (BSD >= 199306) && defined(_KERNEL)
- if ((securelevel >= 2) && (mode & FWRITE))
- return EPERM;
-#endif
-
- nat = NULL; /* XXX gcc -Wuninitialized */
- KMALLOC(nt, ipnat_t *);
- if ((cmd == SIOCADNAT) || (cmd == SIOCRMNAT))
- error = IRCOPYPTR(data, (char *)&natd, sizeof(natd));
- else if (cmd == SIOCIPFFL) { /* SIOCFLNAT & SIOCCNATL */
- error = IRCOPY(data, (char *)&arg, sizeof(arg));
- if (error)
- error = EFAULT;
- }
-
- if (error)
- goto done;
-
- /*
- * For add/delete, look to see if the NAT entry is already present
- */
- WRITE_ENTER(&ipf_nat);
- if ((cmd == SIOCADNAT) || (cmd == SIOCRMNAT)) {
- nat = &natd;
- nat->in_flags &= IPN_USERFLAGS;
- if ((nat->in_redir & NAT_MAPBLK) == 0) {
- if ((nat->in_flags & IPN_SPLIT) == 0)
- nat->in_inip &= nat->in_inmsk;
- if ((nat->in_flags & IPN_IPRANGE) == 0)
- nat->in_outip &= nat->in_outmsk;
- }
- 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)
- {
-#ifdef IPFILTER_LOG
- case SIOCIPFFB :
- {
- int tmp;
-
- if (!(mode & FWRITE))
- error = EPERM;
- else {
- tmp = ipflog_clear(IPL_LOGNAT);
- IWCOPY((char *)&tmp, (char *)data, sizeof(tmp));
- }
- break;
- }
-#endif
- case SIOCADNAT :
- if (!(mode & FWRITE)) {
- error = EPERM;
- break;
- }
- if (n) {
- error = EEXIST;
- break;
- }
- if (nt == NULL) {
- error = ENOMEM;
- break;
- }
- n = nt;
- nt = NULL;
- bcopy((char *)nat, (char *)n, sizeof(*n));
- n->in_ifp = (void *)GETUNIT(n->in_ifname, 4);
- if (!n->in_ifp)
- n->in_ifp = (void *)-1;
- if (n->in_plabel[0] != '\0') {
- n->in_apr = appr_match(n->in_p, n->in_plabel);
- if (!n->in_apr) {
- error = ENOENT;
- break;
- }
- }
- n->in_next = NULL;
- *np = n;
-
- if (n->in_redir & NAT_REDIRECT) {
- n->in_flags &= ~IPN_NOTDST;
- nat_addrdr(n);
- }
- if (n->in_redir & (NAT_MAP|NAT_MAPBLK)) {
- n->in_flags &= ~IPN_NOTSRC;
- nat_addnat(n);
- }
-
- n->in_use = 0;
- if (n->in_redir & NAT_MAPBLK)
- n->in_space = USABLE_PORTS * ~ntohl(n->in_outmsk);
- else if (n->in_flags & IPN_AUTOPORTMAP)
- n->in_space = USABLE_PORTS * ~ntohl(n->in_inmsk);
- else if (n->in_flags & IPN_IPRANGE)
- n->in_space = ntohl(n->in_outmsk) - ntohl(n->in_outip);
- else if (n->in_flags & IPN_SPLIT)
- n->in_space = 2;
- else
- n->in_space = ~ntohl(n->in_outmsk);
- /*
- * Calculate the number of valid IP addresses in the output
- * mapping range. In all cases, the range is inclusive of
- * the start and ending IP addresses.
- * If to a CIDR address, lose 2: broadcast + network address
- * (so subtract 1)
- * If to a range, add one.
- * If to a single IP address, set to 1.
- */
- if (n->in_space) {
- if ((n->in_flags & IPN_IPRANGE) != 0)
- n->in_space += 1;
- else
- n->in_space -= 1;
- } else
- n->in_space = 1;
- if ((n->in_outmsk != 0xffffffff) && (n->in_outmsk != 0) &&
- ((n->in_flags & (IPN_IPRANGE|IPN_SPLIT)) == 0))
- n->in_nip = ntohl(n->in_outip) + 1;
- else if ((n->in_flags & IPN_SPLIT) &&
- (n->in_redir & NAT_REDIRECT))
- n->in_nip = ntohl(n->in_inip);
- 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) + 1);
- /*
- * Because two different sources can map to
- * different destinations but use the same
- * local IP#/port #.
- * If the result is smaller than in_space, then
- * we may have wrapped around 32bits.
- */
- i = n->in_inmsk;
- if ((i != 0) && (i != 0xffffffff)) {
- j = n->in_space * (~ntohl(i) + 1);
- if (j >= n->in_space)
- n->in_space = j;
- else
- n->in_space = 0xffffffff;
- }
- }
- /*
- * If no protocol is specified, multiple by 256.
- */
- if ((n->in_flags & IPN_TCPUDP) == 0) {
- j = n->in_space * 256;
- if (j >= n->in_space)
- n->in_space = j;
- else
- n->in_space = 0xffffffff;
- }
- }
- /* Otherwise, these fields are preset */
- n = NULL;
- nat_stats.ns_rules++;
- break;
- case SIOCRMNAT :
- if (!(mode & FWRITE)) {
- error = EPERM;
- n = NULL;
- break;
- }
- if (!n) {
- error = ESRCH;
- break;
- }
- if (n->in_redir & NAT_REDIRECT)
- nat_delrdr(n);
- if (n->in_redir & (NAT_MAPBLK|NAT_MAP))
- nat_delnat(n);
- if (nat_list == NULL) {
- nat_masks = 0;
- rdr_masks = 0;
- }
- *np = n->in_next;
- if (!n->in_use) {
- if (n->in_apr)
- appr_free(n->in_apr);
- KFREE(n);
- nat_stats.ns_rules--;
- } else {
- n->in_flags |= IPN_DELETE;
- n->in_next = NULL;
- }
- n = NULL;
- break;
- case SIOCGNATS :
- MUTEX_DOWNGRADE(&ipf_nat);
- 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_nattab_sz = ipf_nattable_sz;
- nat_stats.ns_rultab_sz = ipf_natrules_sz;
- nat_stats.ns_rdrtab_sz = ipf_rdrrules_sz;
- nat_stats.ns_instances = nat_instances;
- nat_stats.ns_apslist = ap_sess_list;
- error = IWCOPYPTR((char *)&nat_stats, (char *)data,
- sizeof(nat_stats));
- break;
- case SIOCGNATL :
- {
- natlookup_t nl;
-
- MUTEX_DOWNGRADE(&ipf_nat);
- error = IRCOPYPTR((char *)data, (char *)&nl, sizeof(nl));
- if (error)
- break;
-
- if (nat_lookupredir(&nl)) {
- error = IWCOPYPTR((char *)&nl, (char *)data,
- sizeof(nl));
- } else
- error = ESRCH;
- break;
- }
- case SIOCIPFFL : /* old SIOCFLNAT & SIOCCNATL */
- if (!(mode & FWRITE)) {
- error = EPERM;
- break;
- }
- error = 0;
- if (arg == 0)
- ret = nat_flushtable();
- else if (arg == 1)
- ret = nat_clearlist();
- else
- error = EINVAL;
- MUTEX_DOWNGRADE(&ipf_nat);
- if (!error) {
- error = IWCOPY((caddr_t)&ret, data, sizeof(ret));
- if (error)
- error = EFAULT;
- }
- break;
- case SIOCSTLCK :
- error = IRCOPY(data, (caddr_t)&arg, sizeof(arg));
- if (!error) {
- error = IWCOPY((caddr_t)&fr_nat_lock, data,
- sizeof(fr_nat_lock));
- if (!error)
- fr_nat_lock = arg;
- } else
- error = EFAULT;
- break;
- case SIOCSTPUT :
- if (fr_nat_lock)
- error = fr_natputent(data);
- else
- error = EACCES;
- break;
- case SIOCSTGSZ :
- if (fr_nat_lock)
- error = fr_natgetsz(data);
- else
- error = EACCES;
- break;
- case SIOCSTGET :
- if (fr_nat_lock)
- error = fr_natgetent(data);
- else
- error = EACCES;
- break;
- case FIONREAD :
-#ifdef IPFILTER_LOG
- arg = (int)iplused[IPL_LOGNAT];
- MUTEX_DOWNGRADE(&ipf_nat);
- error = IWCOPY((caddr_t)&arg, (caddr_t)data, sizeof(arg));
- if (error)
- error = EFAULT;
-#endif
- break;
- default :
- error = EINVAL;
- break;
- }
- RWLOCK_EXIT(&ipf_nat); /* READ/WRITE */
-done:
- if (nt)
- KFREE(nt);
- return error;
-}
-
-
-static int fr_natgetsz(data)
-caddr_t data;
-{
- ap_session_t *aps;
- nat_t *nat, *n;
- int error = 0;
- natget_t ng;
-
- error = IRCOPY(data, (caddr_t)&ng, sizeof(ng));
- if (error)
- return EFAULT;
-
- nat = ng.ng_ptr;
- if (!nat) {
- nat = nat_instances;
- ng.ng_sz = 0;
- if (nat == NULL) {
- error = IWCOPY((caddr_t)&ng, data, sizeof(ng));
- if (error)
- error = EFAULT;
- return error;
- }
- } else {
- /*
- * Make sure the pointer we're copying from exists in the
- * current list of entries. Security precaution to prevent
- * copying of random kernel data.
- */
- for (n = nat_instances; n; n = n->nat_next)
- if (n == nat)
- break;
- if (!n)
- return ESRCH;
- }
-
- ng.ng_sz = sizeof(nat_save_t);
- aps = nat->nat_aps;
- if ((aps != NULL) && (aps->aps_data != 0)) {
- ng.ng_sz += sizeof(ap_session_t);
- ng.ng_sz += aps->aps_psiz;
- }
-
- error = IWCOPY((caddr_t)&ng, data, sizeof(ng));
- if (error)
- error = EFAULT;
- return error;
-}
-
-
-static int fr_natgetent(data)
-caddr_t data;
-{
- nat_save_t ipn, *ipnp, *ipnn = NULL;
- register nat_t *n, *nat;
- ap_session_t *aps;
- int error;
-
- error = IRCOPY(data, (caddr_t)&ipnp, sizeof(ipnp));
- if (error)
- return EFAULT;
- error = IRCOPY((caddr_t)ipnp, (caddr_t)&ipn, sizeof(ipn));
- if (error)
- return EFAULT;
-
- nat = ipn.ipn_next;
- if (!nat) {
- nat = nat_instances;
- if (nat == NULL) {
- if (nat_instances == NULL)
- return ENOENT;
- return 0;
- }
- } else {
- /*
- * Make sure the pointer we're copying from exists in the
- * current list of entries. Security precaution to prevent
- * copying of random kernel data.
- */
- for (n = nat_instances; n; n = n->nat_next)
- if (n == nat)
- break;
- if (!n)
- return ESRCH;
- }
-
- ipn.ipn_next = nat->nat_next;
- ipn.ipn_dsize = 0;
- bcopy((char *)nat, (char *)&ipn.ipn_nat, sizeof(ipn.ipn_nat));
- ipn.ipn_nat.nat_data = NULL;
-
- if (nat->nat_ptr) {
- bcopy((char *)nat->nat_ptr, (char *)&ipn.ipn_ipnat,
- sizeof(ipn.ipn_ipnat));
- }
-
- if (nat->nat_fr)
- bcopy((char *)nat->nat_fr, (char *)&ipn.ipn_rule,
- sizeof(ipn.ipn_rule));
-
- if ((aps = nat->nat_aps)) {
- ipn.ipn_dsize = sizeof(*aps);
- if (aps->aps_data)
- ipn.ipn_dsize += aps->aps_psiz;
- KMALLOCS(ipnn, nat_save_t *, sizeof(*ipnn) + ipn.ipn_dsize);
- if (ipnn == NULL)
- return ENOMEM;
- bcopy((char *)&ipn, (char *)ipnn, sizeof(ipn));
-
- bcopy((char *)aps, ipnn->ipn_data, sizeof(*aps));
- if (aps->aps_data) {
- bcopy(aps->aps_data, ipnn->ipn_data + sizeof(*aps),
- aps->aps_psiz);
- ipnn->ipn_dsize += aps->aps_psiz;
- }
- error = IWCOPY((caddr_t)ipnn, ipnp,
- sizeof(ipn) + ipn.ipn_dsize);
- if (error)
- error = EFAULT;
- KFREES(ipnn, sizeof(*ipnn) + ipn.ipn_dsize);
- } else {
- error = IWCOPY((caddr_t)&ipn, ipnp, sizeof(ipn));
- if (error)
- error = EFAULT;
- }
- return error;
-}
-
-
-static int fr_natputent(data)
-caddr_t data;
-{
- nat_save_t ipn, *ipnp, *ipnn = NULL;
- register nat_t *n, *nat;
- ap_session_t *aps;
- frentry_t *fr;
- ipnat_t *in;
-
- int error;
-
- error = IRCOPY(data, (caddr_t)&ipnp, sizeof(ipnp));
- if (error)
- return EFAULT;
- error = IRCOPY((caddr_t)ipnp, (caddr_t)&ipn, sizeof(ipn));
- if (error)
- return EFAULT;
- nat = NULL;
- if (ipn.ipn_dsize) {
- KMALLOCS(ipnn, nat_save_t *, sizeof(ipn) + ipn.ipn_dsize);
- if (ipnn == NULL)
- return ENOMEM;
- bcopy((char *)&ipn, (char *)ipnn, sizeof(ipn));
- error = IRCOPY((caddr_t)ipnp, (caddr_t)ipn.ipn_data,
- ipn.ipn_dsize);
- if (error) {
- error = EFAULT;
- goto junkput;
- }
- } else
- ipnn = NULL;
-
- KMALLOC(nat, nat_t *);
- if (nat == NULL) {
- error = EFAULT;
- goto junkput;
- }
-
- bcopy((char *)&ipn.ipn_nat, (char *)nat, sizeof(*nat));
- /*
- * Initialize all these so that nat_delete() doesn't cause a crash.
- */
- nat->nat_phnext[0] = NULL;
- nat->nat_phnext[1] = NULL;
- fr = nat->nat_fr;
- nat->nat_fr = NULL;
- aps = nat->nat_aps;
- nat->nat_aps = NULL;
- in = nat->nat_ptr;
- nat->nat_ptr = NULL;
- nat->nat_data = NULL;
-
- /*
- * Restore the rule associated with this nat session
- */
- if (in) {
- KMALLOC(in, ipnat_t *);
- if (in == NULL) {
- error = ENOMEM;
- goto junkput;
- }
- nat->nat_ptr = in;
- bcopy((char *)&ipn.ipn_ipnat, (char *)in, sizeof(*in));
- in->in_use = 1;
- in->in_flags |= IPN_DELETE;
- in->in_next = NULL;
- in->in_rnext = NULL;
- in->in_prnext = NULL;
- in->in_mnext = NULL;
- in->in_pmnext = NULL;
- in->in_ifp = GETUNIT(in->in_ifname, 4);
- if (in->in_plabel[0] != '\0') {
- in->in_apr = appr_match(in->in_p, in->in_plabel);
- }
- }
-
- /*
- * Restore ap_session_t structure. Include the private data allocated
- * if it was there.
- */
- if (aps) {
- KMALLOC(aps, ap_session_t *);
- if (aps == NULL) {
- error = ENOMEM;
- goto junkput;
- }
- nat->nat_aps = aps;
- aps->aps_next = ap_sess_list;
- ap_sess_list = aps;
- bcopy(ipnn->ipn_data, (char *)aps, sizeof(*aps));
- if (in)
- aps->aps_apr = in->in_apr;
- if (aps->aps_psiz) {
- KMALLOCS(aps->aps_data, void *, aps->aps_psiz);
- if (aps->aps_data == NULL) {
- error = ENOMEM;
- goto junkput;
- }
- bcopy(ipnn->ipn_data + sizeof(*aps), aps->aps_data,
- aps->aps_psiz);
- } else {
- aps->aps_psiz = 0;
- aps->aps_data = NULL;
- }
- }
-
- /*
- * If there was a filtering rule associated with this entry then
- * build up a new one.
- */
- if (fr != NULL) {
- if (nat->nat_flags & FI_NEWFR) {
- KMALLOC(fr, frentry_t *);
- nat->nat_fr = fr;
- if (fr == NULL) {
- error = ENOMEM;
- goto junkput;
- }
- bcopy((char *)&ipn.ipn_fr, (char *)fr, sizeof(*fr));
- ipn.ipn_nat.nat_fr = fr;
- error = IWCOPY((caddr_t)&ipn, ipnp, sizeof(ipn));
- if (error) {
- error = EFAULT;
- goto junkput;
- }
- } else {
- for (n = nat_instances; n; n = n->nat_next)
- if (n->nat_fr == fr)
- break;
- if (!n) {
- error = ESRCH;
- goto junkput;
- }
- }
- }
-
- if (ipnn)
- KFREES(ipnn, sizeof(ipn) + ipn.ipn_dsize);
- nat_insert(nat);
- return 0;
-junkput:
- if (ipnn)
- KFREES(ipnn, sizeof(ipn) + ipn.ipn_dsize);
- if (nat)
- nat_delete(nat);
- return error;
-}
-
-
-/*
- * Delete a nat entry from the various lists and table.
- */
-static void nat_delete(natd)
-struct nat *natd;
-{
- struct ipnat *ipn;
-
- if (natd->nat_flags & FI_WILDP)
- nat_stats.ns_wilds--;
- if (natd->nat_hnext[0])
- natd->nat_hnext[0]->nat_phnext[0] = natd->nat_phnext[0];
- *natd->nat_phnext[0] = natd->nat_hnext[0];
- if (natd->nat_hnext[1])
- natd->nat_hnext[1]->nat_phnext[1] = natd->nat_phnext[1];
- *natd->nat_phnext[1] = natd->nat_hnext[1];
-
- if (natd->nat_fr != NULL) {
- ATOMIC_DEC32(natd->nat_fr->fr_ref);
- }
-
- if (natd->nat_hm != NULL)
- nat_hostmapdel(natd->nat_hm);
-
- /*
- * If there is an active reference from the nat entry to its parent
- * rule, decrement the rule's reference count and free it too if no
- * longer being used.
- */
- ipn = natd->nat_ptr;
- if (ipn != NULL) {
- ipn->in_space++;
- ipn->in_use--;
- if (!ipn->in_use && (ipn->in_flags & IPN_DELETE)) {
- if (ipn->in_apr)
- appr_free(ipn->in_apr);
- KFREE(ipn);
- nat_stats.ns_rules--;
- }
- }
-
- MUTEX_DESTROY(&natd->nat_lock);
- /*
- * If there's a fragment table entry too for this nat entry, then
- * dereference that as well.
- */
- ipfr_forget((void *)natd);
- aps_free(natd->nat_aps);
- nat_stats.ns_inuse--;
- KFREE(natd);
-}
-
-
-/*
- * nat_flushtable - clear the NAT table of all mapping entries.
- */
-static int nat_flushtable()
-{
- register nat_t *nat, **natp;
- register int j = 0;
-
- /*
- * ALL NAT mappings deleted, so lets just make the deletions
- * quicker.
- */
- if (nat_table[0] != NULL)
- bzero((char *)nat_table[0],
- sizeof(nat_table[0]) * ipf_nattable_sz);
- if (nat_table[1] != NULL)
- bzero((char *)nat_table[1],
- sizeof(nat_table[1]) * ipf_nattable_sz);
-
- for (natp = &nat_instances; (nat = *natp); ) {
- *natp = nat->nat_next;
-#ifdef IPFILTER_LOG
- nat_log(nat, NL_FLUSH);
-#endif
- nat_delete(nat);
- j++;
- }
- nat_stats.ns_inuse = 0;
- return j;
-}
-
-
-/*
- * nat_clearlist - delete all rules in the active NAT mapping list.
- */
-static int nat_clearlist()
-{
- register ipnat_t *n, **np = &nat_list;
- int i = 0;
-
- if (nat_rules != NULL)
- bzero((char *)nat_rules, sizeof(*nat_rules) * ipf_natrules_sz);
- if (rdr_rules != NULL)
- bzero((char *)rdr_rules, sizeof(*rdr_rules) * ipf_rdrrules_sz);
-
- while ((n = *np)) {
- *np = n->in_next;
- if (!n->in_use) {
- if (n->in_apr)
- appr_free(n->in_apr);
- KFREE(n);
- nat_stats.ns_rules--;
- } else {
- n->in_flags |= IPN_DELETE;
- n->in_next = NULL;
- }
- i++;
- }
- nat_masks = 0;
- rdr_masks = 0;
- return i;
-}
-
-
-/*
- * Create a new NAT table entry.
- * NOTE: assumes write lock on ipf_nat has been obtained already.
- */
-nat_t *nat_new(np, ip, fin, flags, direction)
-ipnat_t *np;
-ip_t *ip;
-fr_info_t *fin;
-u_int flags;
-int direction;
-{
- register u_32_t sum1, sum2, sumd, l;
- u_short port = 0, sport = 0, dport = 0, nport = 0;
- struct in_addr in, inb;
- tcphdr_t *tcp = NULL;
- hostmap_t *hm = NULL;
- nat_t *nat, *natl;
- u_short nflags;
-#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6)
- qif_t *qf = fin->fin_qif;
-#endif
-
- 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 *);
- if (nat == NULL) {
- nat_stats.ns_memfail++;
- return NULL;
- }
-
- bzero((char *)nat, sizeof(*nat));
- nat->nat_flags = flags;
- if (flags & FI_WILDP)
- nat_stats.ns_wilds++;
- /*
- * Search the current table for a match.
- */
- if (direction == NAT_OUTBOUND) {
- /*
- * Values at which the search for a free resouce starts.
- */
- u_32_t st_ip;
- u_short st_port;
-
- /*
- * If it's an outbound packet which doesn't match any existing
- * record, then create a new port
- */
- l = 0;
- st_ip = np->in_nip;
- st_port = np->in_pnext;
-
- do {
- port = 0;
- in.s_addr = htonl(np->in_nip);
- if (l == 0) {
- /*
- * Check to see if there is an existing NAT
- * setup for this IP address pair.
- */
- hm = nat_hostmap(np, ip->ip_src, in);
- if (hm != NULL)
- in.s_addr = hm->hm_mapip.s_addr;
- } else if ((l == 1) && (hm != NULL)) {
- nat_hostmapdel(hm);
- hm = NULL;
- }
- in.s_addr = ntohl(in.s_addr);
-
- nat->nat_hm = hm;
-
- if ((np->in_outmsk == 0xffffffff) &&
- (np->in_pnext == 0)) {
- if (l > 0)
- goto badnat;
- }
-
- if (np->in_redir & NAT_MAPBLK) {
- if ((l >= np->in_ppip) || ((l > 0) &&
- !(flags & IPN_TCPUDP)))
- goto badnat;
- /*
- * map-block - Calculate destination address.
- */
- in.s_addr = ntohl(ip->ip_src.s_addr);
- in.s_addr &= ntohl(~np->in_inmsk);
- inb.s_addr = in.s_addr;
- in.s_addr /= np->in_ippip;
- in.s_addr &= ntohl(~np->in_outmsk);
- in.s_addr += ntohl(np->in_outip);
- /*
- * Calculate destination port.
- */
- if ((flags & IPN_TCPUDP) &&
- (np->in_ppip != 0)) {
- port = ntohs(sport) + l;
- port %= np->in_ppip;
- port += np->in_ppip *
- (inb.s_addr % np->in_ippip);
- port += MAPBLK_MINPORT;
- port = htons(port);
- }
- } else if (!np->in_outip &&
- (np->in_outmsk == 0xffffffff)) {
- /*
- * 0/32 - use the interface's IP address.
- */
- if ((l > 0) ||
- fr_ifpaddr(4, fin->fin_ifp, &in) == -1)
- goto badnat;
- in.s_addr = ntohl(in.s_addr);
- } else if (!np->in_outip && !np->in_outmsk) {
- /*
- * 0/0 - use the original source address/port.
- */
- if (l > 0)
- goto badnat;
- in.s_addr = ntohl(ip->ip_src.s_addr);
- } else if ((np->in_outmsk != 0xffffffff) &&
- (np->in_pnext == 0) &&
- ((l > 0) || (hm == NULL)))
- np->in_nip++;
- natl = NULL;
-
- if ((nflags & IPN_TCPUDP) &&
- ((np->in_redir & NAT_MAPBLK) == 0) &&
- (np->in_flags & IPN_AUTOPORTMAP)) {
- if ((l > 0) && (l % np->in_ppip == 0)) {
- if (l > np->in_space) {
- goto badnat;
- } else if ((l > np->in_ppip) &&
- np->in_outmsk != 0xffffffff)
- np->in_nip++;
- }
- if (np->in_ppip != 0) {
- port = ntohs(sport);
- port += (l % np->in_ppip);
- port %= np->in_ppip;
- port += np->in_ppip *
- (ntohl(ip->ip_src.s_addr) %
- np->in_ippip);
- port += MAPBLK_MINPORT;
- port = htons(port);
- }
- } else if (((np->in_redir & NAT_MAPBLK) == 0) &&
- (nflags & IPN_TCPUDP) &&
- (np->in_pnext != 0)) {
- port = htons(np->in_pnext++);
- if (np->in_pnext > ntohs(np->in_pmax)) {
- np->in_pnext = ntohs(np->in_pmin);
- if (np->in_outmsk != 0xffffffff)
- np->in_nip++;
- }
- }
-
- if (np->in_flags & IPN_IPRANGE) {
- if (np->in_nip > ntohl(np->in_outmsk))
- np->in_nip = ntohl(np->in_outip);
- } else {
- if ((np->in_outmsk != 0xffffffff) &&
- ((np->in_nip + 1) & ntohl(np->in_outmsk)) >
- ntohl(np->in_outip))
- np->in_nip = ntohl(np->in_outip) + 1;
- }
-
- if (!port && (flags & IPN_TCPUDP))
- port = sport;
-
- /*
- * Here we do a lookup of the connection as seen from
- * the outside. If an IP# pair already exists, try
- * again. So if you have A->B becomes C->B, you can
- * also have D->E become C->E but not D->B causing
- * another C->B. Also take protocol and ports into
- * account when determining whether a pre-existing
- * NAT setup will cause an external conflict where
- * this is appropriate.
- */
- inb.s_addr = htonl(in.s_addr);
- natl = nat_inlookup(fin->fin_ifp, flags & ~FI_WILDP,
- (u_int)ip->ip_p, ip->ip_dst, inb,
- (port << 16) | dport, 1);
-
- /*
- * Has the search wrapped around and come back to the
- * start ?
- */
- if ((natl != NULL) &&
- (np->in_pnext != 0) && (st_port == np->in_pnext) &&
- (np->in_nip != 0) && (st_ip == np->in_nip))
- goto badnat;
- l++;
- } while (natl != NULL);
-
- if (np->in_space > 0)
- np->in_space--;
-
- /* 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;
- if (nat->nat_hm == NULL)
- nat->nat_hm = nat_hostmap(np, ip->ip_src,
- nat->nat_outip);
-
- sum1 = LONG_SUM(ntohl(ip->ip_src.s_addr)) + ntohs(sport);
- sum2 = LONG_SUM(in.s_addr) + ntohs(port);
-
- if (flags & IPN_TCPUDP) {
- nat->nat_inport = sport;
- nat->nat_outport = port; /* sport */
- 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.
- */
- if (np->in_flags & IPN_SPLIT) {
- in.s_addr = np->in_nip;
- if (np->in_inip == htonl(in.s_addr))
- np->in_nip = ntohl(np->in_inmsk);
- else {
- np->in_nip = ntohl(np->in_inip);
- if (np->in_flags & IPN_ROUNDR) {
- nat_delrdr(np);
- nat_addrdr(np);
- }
- }
- } else {
- in.s_addr = ntohl(np->in_inip);
- if (np->in_flags & IPN_ROUNDR) {
- nat_delrdr(np);
- nat_addrdr(np);
- }
- }
- if (!np->in_pnext)
- nport = dport;
- else {
- /*
- * Whilst not optimized for the case where
- * pmin == pmax, the gain is not significant.
- */
- nport = ntohs(dport) - ntohs(np->in_pmin) +
- ntohs(np->in_pnext);
- nport = htons(nport);
- }
-
- /*
- * When the redirect-to address is set to 0.0.0.0, just
- * assume a blank `forwarding' of the packet. We don't
- * setup any translation for this either.
- */
- if (in.s_addr == 0) {
- if (nport == dport)
- goto badnat;
- in.s_addr = ntohl(ip->ip_dst.s_addr);
- }
-
- nat->nat_inip.s_addr = htonl(in.s_addr);
- nat->nat_outip = ip->ip_dst;
- nat->nat_oip = ip->ip_src;
-
- sum1 = LONG_SUM(ntohl(ip->ip_dst.s_addr)) + ntohs(dport);
- sum2 = LONG_SUM(in.s_addr) + ntohs(nport);
-
- if (flags & IPN_TCPUDP) {
- nat->nat_inport = nport;
- nat->nat_outport = dport;
- nat->nat_oport = sport;
- }
- }
-
- CALC_SUMD(sum1, sum2, sumd);
- 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)
- sum1 = LONG_SUM(ntohl(ip->ip_src.s_addr));
- else
- sum1 = LONG_SUM(ntohl(ip->ip_dst.s_addr));
-
- sum2 = LONG_SUM(in.s_addr);
-
- CALC_SUMD(sum1, sum2, sumd);
- nat->nat_ipsumd = (sumd & 0xffff) + (sumd >> 16);
- } else
- nat->nat_ipsumd = nat->nat_sumd[0];
-
- in.s_addr = htonl(in.s_addr);
-
-#ifdef _KERNEL
- strncpy(nat->nat_ifname, IFNAME(fin->fin_ifp), IFNAMSIZ);
-#endif
- nat_insert(nat);
-
- nat->nat_dir = direction;
- nat->nat_ifp = fin->fin_ifp;
- nat->nat_ptr = np;
- nat->nat_p = ip->ip_p;
- nat->nat_bytes = 0;
- nat->nat_pkts = 0;
- nat->nat_fr = fin->fin_fr;
- if (nat->nat_fr != NULL) {
- ATOMIC_INC32(nat->nat_fr->fr_ref);
- }
- if (direction == NAT_OUTBOUND) {
- if (flags & IPN_TCPUDP)
- tcp->th_sport = port;
- } else {
- if (flags & IPN_TCPUDP)
- tcp->th_dport = nport;
- }
- np->in_use++;
-#ifdef IPFILTER_LOG
- nat_log(nat, (u_int)np->in_redir);
-#endif
- return nat;
-badnat:
- nat_stats.ns_badnat++;
- if ((hm = nat->nat_hm) != NULL)
- nat_hostmapdel(hm);
- KFREE(nat);
- return NULL;
-}
-
-
-void nat_insert(nat)
-nat_t *nat;
-{
- nat_t **natp;
- u_int hv;
-
- MUTEX_INIT(&nat->nat_lock, "nat entry lock", NULL);
-
- nat->nat_age = fr_defnatage;
- nat->nat_ifname[sizeof(nat->nat_ifname) - 1] = '\0';
- if (nat->nat_ifname[0] !='\0') {
- nat->nat_ifp = GETUNIT(nat->nat_ifname, 4);
- }
-
- nat->nat_next = nat_instances;
- nat_instances = nat;
-
- hv = NAT_HASH_FN(nat->nat_inip.s_addr, nat->nat_inport,
- ipf_nattable_sz);
- natp = &nat_table[0][hv];
- if (*natp)
- (*natp)->nat_phnext[0] = &nat->nat_hnext[0];
- nat->nat_phnext[0] = natp;
- nat->nat_hnext[0] = *natp;
- *natp = nat;
-
- hv = NAT_HASH_FN(nat->nat_outip.s_addr, nat->nat_outport,
- ipf_nattable_sz);
- natp = &nat_table[1][hv];
- if (*natp)
- (*natp)->nat_phnext[1] = &nat->nat_hnext[1];
- nat->nat_phnext[1] = natp;
- nat->nat_hnext[1] = *natp;
- *natp = nat;
-
- nat_stats.ns_added++;
- nat_stats.ns_inuse++;
-}
-
-
-nat_t *nat_icmplookup(ip, fin, dir)
-ip_t *ip;
-fr_info_t *fin;
-int dir;
-{
- icmphdr_t *icmp;
- tcphdr_t *tcp = NULL;
- ip_t *oip;
- int flags = 0, type, minlen;
-
- icmp = (icmphdr_t *)fin->fin_dp;
- /*
- * Does it at least have the return (basic) IP header ?
- * Only a basic IP header (no options) should be with an ICMP error
- * header.
- */
- if ((ip->ip_hl != 5) || (ip->ip_len < ICMPERR_MINPKTLEN))
- return NULL;
- type = icmp->icmp_type;
- /*
- * If it's not an error type, then return.
- */
- if ((type != ICMP_UNREACH) && (type != ICMP_SOURCEQUENCH) &&
- (type != ICMP_REDIRECT) && (type != ICMP_TIMXCEED) &&
- (type != ICMP_PARAMPROB))
- return NULL;
-
- oip = (ip_t *)((char *)fin->fin_dp + 8);
- minlen = (oip->ip_hl << 2);
- if (minlen < sizeof(ip_t))
- return NULL;
- if (ip->ip_len < ICMPERR_IPICMPHLEN + minlen)
- return NULL;
- /*
- * Is the buffer big enough for all of it ? It's the size of the IP
- * header claimed in the encapsulated part which is of concern. It
- * may be too big to be in this buffer but not so big that it's
- * outside the ICMP packet, leading to TCP deref's causing problems.
- * This is possible because we don't know how big oip_hl is when we
- * do the pullup early in fr_check() and thus can't gaurantee it is
- * all here now.
- */
-#ifdef _KERNEL
- {
- mb_t *m;
-
-# if SOLARIS
- m = fin->fin_qfm;
- if ((char *)oip + fin->fin_dlen - ICMPERR_ICMPHLEN > (char *)m->b_wptr)
- return NULL;
-# else
- m = *(mb_t **)fin->fin_mp;
- if ((char *)oip + fin->fin_dlen - ICMPERR_ICMPHLEN >
- (char *)ip + m->m_len)
- return NULL;
-# endif
- }
-#endif
-
- if (oip->ip_p == IPPROTO_TCP)
- flags = IPN_TCP;
- else if (oip->ip_p == IPPROTO_UDP)
- flags = IPN_UDP;
- if (flags & IPN_TCPUDP) {
- minlen += 8; /* + 64bits of data to get ports */
- if (ip->ip_len < ICMPERR_IPICMPHLEN + minlen)
- return NULL;
- tcp = (tcphdr_t *)((char *)oip + (oip->ip_hl << 2));
- if (dir == NAT_INBOUND)
- return nat_inlookup(fin->fin_ifp, flags,
- (u_int)oip->ip_p, oip->ip_dst, oip->ip_src,
- (tcp->th_sport << 16) | tcp->th_dport, 0);
- else
- return nat_outlookup(fin->fin_ifp, flags,
- (u_int)oip->ip_p, oip->ip_dst, oip->ip_src,
- (tcp->th_sport << 16) | tcp->th_dport, 0);
- }
- if (dir == NAT_INBOUND)
- return nat_inlookup(fin->fin_ifp, 0, (u_int)oip->ip_p,
- oip->ip_dst, oip->ip_src, 0, 0);
- else
- return nat_outlookup(fin->fin_ifp, 0, (u_int)oip->ip_p,
- oip->ip_dst, oip->ip_src, 0, 0);
-}
-
-
-/*
- * This should *ONLY* be used for incoming packets to make sure a NAT'd ICMP
- * packet gets correctly recognised.
- */
-nat_t *nat_icmp(ip, fin, nflags, dir)
-ip_t *ip;
-fr_info_t *fin;
-u_int *nflags;
-int dir;
-{
- u_32_t sum1, sum2, sumd, sumd2 = 0;
- struct in_addr in;
- icmphdr_t *icmp;
- udphdr_t *udp;
- nat_t *nat;
- ip_t *oip;
- int flags = 0;
-
- if ((fin->fin_fi.fi_fl & FI_SHORT) || (ip->ip_off & IP_OFFMASK))
- return NULL;
- /*
- * nat_icmplookup() will return NULL for `defective' packets.
- */
- if ((ip->ip_v != 4) || !(nat = nat_icmplookup(ip, fin, dir)))
- return NULL;
- *nflags = IPN_ICMPERR;
- icmp = (icmphdr_t *)fin->fin_dp;
- oip = (ip_t *)&icmp->icmp_ip;
- if (oip->ip_p == IPPROTO_TCP)
- flags = IPN_TCP;
- else if (oip->ip_p == IPPROTO_UDP)
- flags = IPN_UDP;
- udp = (udphdr_t *)((((char *)oip) + (oip->ip_hl << 2)));
- /*
- * Need to adjust ICMP header to include the real IP#'s and
- * port #'s. Only apply a checksum change relative to the
- * IP address change as it will be modified again in ip_natout
- * for both address and port. Two checksum changes are
- * necessary for the two header address changes. Be careful
- * to only modify the checksum once for the port # and twice
- * for the IP#.
- */
-
- /*
- * Step 1
- * Fix the IP addresses in the offending IP packet. You also need
- * to adjust the IP header checksum of that offending IP packet
- * and the ICMP checksum of the ICMP error message itself.
- *
- * Unfortunately, for UDP and TCP, the IP addresses are also contained
- * in the pseudo header that is used to compute the UDP resp. TCP
- * checksum. So, we must compensate that as well. Even worse, the
- * change in the UDP and TCP checksums require yet another
- * adjustment of the ICMP checksum of the ICMP error message.
- *
- * For the moment we forget about TCP, because that checksum is not
- * in the first 8 bytes, so it will not be available in most cases.
- */
-
- if (oip->ip_dst.s_addr == nat->nat_oip.s_addr) {
- sum1 = LONG_SUM(ntohl(oip->ip_src.s_addr));
- in = nat->nat_inip;
- oip->ip_src = in;
- } else {
- sum1 = LONG_SUM(ntohl(oip->ip_dst.s_addr));
- in = nat->nat_outip;
- oip->ip_dst = in;
- }
-
- sum2 = LONG_SUM(ntohl(in.s_addr));
-
- CALC_SUMD(sum1, sum2, sumd);
-
- if (nat->nat_dir == NAT_OUTBOUND) {
- /*
- * Fix IP checksum of the offending IP packet to adjust for
- * the change in the IP address.
- *
- * Normally, you would expect that the ICMP checksum of the
- * ICMP error message needs to be adjusted as well for the
- * IP address change in oip.
- * However, this is a NOP, because the ICMP checksum is
- * calculated over the complete ICMP packet, which includes the
- * changed oip IP addresses and oip->ip_sum. However, these
- * two changes cancel each other out (if the delta for
- * the IP address is x, then the delta for ip_sum is minus x),
- * so no change in the icmp_cksum is necessary.
- *
- * Be careful that nat_dir refers to the direction of the
- * offending IP packet (oip), not to its ICMP response (icmp)
- */
- fix_datacksum(&oip->ip_sum, sumd);
-
- /*
- * Fix UDP pseudo header checksum to compensate for the
- * IP address change.
- */
- if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
- /*
- * The UDP checksum is optional, only adjust it
- * if it has been set.
- */
- sum1 = ntohs(udp->uh_sum);
- fix_datacksum(&udp->uh_sum, sumd);
- sum2 = ntohs(udp->uh_sum);
-
- /*
- * Fix ICMP checksum to compensate the UDP
- * checksum adjustment.
- */
- CALC_SUMD(sum1, sum2, sumd);
- sumd2 = sumd;
- }
-
-#if 0
- /*
- * Fix TCP pseudo header checksum to compensate for the
- * IP address change. Before we can do the change, we
- * must make sure that oip is sufficient large to hold
- * the TCP checksum (normally it does not!).
- */
- if (oip->ip_p == IPPROTO_TCP) {
-
- }
-#endif
- } else {
-
- /*
- * Fix IP checksum of the offending IP packet to adjust for
- * the change in the IP address.
- *
- * Normally, you would expect that the ICMP checksum of the
- * ICMP error message needs to be adjusted as well for the
- * IP address change in oip.
- * However, this is a NOP, because the ICMP checksum is
- * calculated over the complete ICMP packet, which includes the
- * changed oip IP addresses and oip->ip_sum. However, these
- * two changes cancel each other out (if the delta for
- * the IP address is x, then the delta for ip_sum is minus x),
- * so no change in the icmp_cksum is necessary.
- *
- * Be careful that nat_dir refers to the direction of the
- * offending IP packet (oip), not to its ICMP response (icmp)
- */
- fix_datacksum(&oip->ip_sum, sumd);
-
-/* XXX FV : without having looked at Solaris source code, it seems unlikely
- * that SOLARIS would compensate this in the kernel (a body of an IP packet
- * in the data section of an ICMP packet). I have the feeling that this should
- * be unconditional, but I'm not in a position to check.
- */
-#if !SOLARIS && !defined(__sgi)
- /*
- * Fix UDP pseudo header checksum to compensate for the
- * IP address change.
- */
- if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
- /*
- * The UDP checksum is optional, only adjust it
- * if it has been set
- */
- sum1 = ntohs(udp->uh_sum);
- fix_datacksum(&udp->uh_sum, sumd);
- sum2 = ntohs(udp->uh_sum);
-
- /*
- * Fix ICMP checksum to compensate the UDP
- * checksum adjustment.
- */
- CALC_SUMD(sum1, sum2, sumd);
- sumd2 = sumd;
- }
-
-#if 0
- /*
- * Fix TCP pseudo header checksum to compensate for the
- * IP address change. Before we can do the change, we
- * must make sure that oip is sufficient large to hold
- * the TCP checksum (normally it does not!).
- */
- if (oip->ip_p == IPPROTO_TCP) {
-
- };
-#endif
-
-#endif
- }
-
- if ((flags & IPN_TCPUDP) != 0) {
- tcphdr_t *tcp;
-
- /*
- * XXX - what if this is bogus hl and we go off the end ?
- * In this case, nat_icmpinlookup() will have returned NULL.
- */
- tcp = (tcphdr_t *)udp;
-
- /*
- * Step 2 :
- * For offending TCP/UDP IP packets, translate the ports as
- * well, based on the NAT specification. Of course such
- * a change must be reflected in the ICMP checksum as well.
- *
- * Advance notice : Now it becomes complicated :-)
- *
- * Since the port fields are part of the TCP/UDP checksum
- * of the offending IP packet, you need to adjust that checksum
- * as well... but, if you change, you must change the icmp
- * checksum *again*, to reflect that change.
- *
- * To further complicate: the TCP checksum is not in the first
- * 8 bytes of the offending ip packet, so it most likely is not
- * available (we might have to fix that if the encounter a
- * device that returns more than 8 data bytes on icmp error)
- */
-
- if (nat->nat_oport == tcp->th_dport) {
- if (tcp->th_sport != nat->nat_inport) {
- /*
- * Fix ICMP checksum to compensate port
- * adjustment.
- */
- sum1 = ntohs(tcp->th_sport);
- sum2 = ntohs(nat->nat_inport);
- CALC_SUMD(sum1, sum2, sumd);
- sumd2 += sumd;
- tcp->th_sport = nat->nat_inport;
-
- /*
- * Fix udp checksum to compensate port
- * adjustment. NOTE : the offending IP packet
- * flows the other direction compared to the
- * ICMP message.
- *
- * The UDP checksum is optional, only adjust
- * it if it has been set.
- */
- if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
-
- sum1 = ntohs(udp->uh_sum);
- fix_datacksum(&udp->uh_sum, sumd);
- sum2 = ntohs(udp->uh_sum);
-
- /*
- * Fix ICMP checksum to
- * compensate UDP checksum
- * adjustment.
- */
- CALC_SUMD(sum1, sum2, sumd);
- sumd2 += sumd;
- }
- }
- } else {
- if (tcp->th_dport != nat->nat_outport) {
- /*
- * Fix ICMP checksum to compensate port
- * adjustment.
- */
- sum1 = ntohs(tcp->th_dport);
- sum2 = ntohs(nat->nat_outport);
- CALC_SUMD(sum1, sum2, sumd);
- sumd2 += sumd;
- tcp->th_dport = nat->nat_outport;
-
- /*
- * Fix udp checksum to compensate port
- * adjustment. NOTE : the offending IP
- * packet flows the other direction compared
- * to the ICMP message.
- *
- * The UDP checksum is optional, only adjust
- * it if it has been set.
- */
- if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
-
- sum1 = ntohs(udp->uh_sum);
- fix_datacksum(&udp->uh_sum, sumd);
- sum2 = ntohs(udp->uh_sum);
-
- /*
- * Fix ICMP checksum to compensate
- * UDP checksum adjustment.
- */
- CALC_SUMD(sum1, sum2, sumd);
- sumd2 += sumd;
- }
- }
- }
- if (sumd2) {
- sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16);
- sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16);
- if (nat->nat_dir == NAT_OUTBOUND) {
- fix_outcksum(&icmp->icmp_cksum, sumd2);
- } else {
- fix_incksum(&icmp->icmp_cksum, sumd2);
- }
- }
- }
- nat->nat_age = fr_defnaticmpage;
- 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(ifp, flags, p, src, mapdst, ports, rw)
-void *ifp;
-register u_int flags, p;
-struct in_addr src , mapdst;
-u_32_t ports;
-int rw;
-{
- register u_short sport, dport;
- register nat_t *nat;
- register int nflags;
- register u_32_t dst;
- u_int hv;
-
- dst = mapdst.s_addr;
- dport = ports >> 16;
- sport = ports & 0xffff;
- flags &= IPN_TCPUDP;
-
- hv = NAT_HASH_FN(dst, dport, ipf_nattable_sz);
- nat = nat_table[1][hv];
- for (; nat; nat = nat->nat_hnext[1]) {
- nflags = nat->nat_flags;
- if ((!ifp || ifp == nat->nat_ifp) &&
- nat->nat_oip.s_addr == src.s_addr &&
- nat->nat_outip.s_addr == dst &&
- (((p == 0) && (flags == (nat->nat_flags & IPN_TCPUDP)))
- || (p == nat->nat_p)) && (!flags ||
- (((nat->nat_oport == sport) || (nflags & FI_W_DPORT)) &&
- ((nat->nat_outport == dport) || (nflags & FI_W_SPORT)))))
- return nat;
- }
- if (!nat_stats.ns_wilds || !(flags & IPN_TCPUDP))
- return NULL;
- if (!rw) {
- RWLOCK_EXIT(&ipf_nat);
- }
- hv = NAT_HASH_FN(dst, 0, ipf_nattable_sz);
- if (!rw) {
- WRITE_ENTER(&ipf_nat);
- }
- nat = nat_table[1][hv];
- for (; nat; nat = nat->nat_hnext[1]) {
- nflags = nat->nat_flags;
- if (ifp && ifp != nat->nat_ifp)
- continue;
- if (!(nflags & IPN_TCPUDP))
- continue;
- if (!(nflags & FI_WILDP))
- continue;
- if (nat->nat_oip.s_addr != src.s_addr ||
- nat->nat_outip.s_addr != dst)
- continue;
- if (((nat->nat_oport == sport) || (nflags & FI_W_DPORT)) &&
- ((nat->nat_outport == dport) || (nflags & FI_W_SPORT))) {
- nat_tabmove(nat, ports);
- break;
- }
- }
- if (!rw) {
- MUTEX_DOWNGRADE(&ipf_nat);
- }
- return nat;
-}
-
-
-/*
- * This function is only called for TCP/UDP NAT table entries where the
- * original was placed in the table without hashing on the ports and we now
- * want to include hashing on port numbers.
- */
-static void nat_tabmove(nat, ports)
-nat_t *nat;
-u_32_t ports;
-{
- register u_short sport, dport;
- nat_t **natp;
- u_int hv;
-
- dport = ports >> 16;
- sport = ports & 0xffff;
-
- if (nat->nat_oport == dport) {
- nat->nat_inport = sport;
- nat->nat_outport = sport;
- }
-
- /*
- * Remove the NAT entry from the old location
- */
- if (nat->nat_hnext[0])
- nat->nat_hnext[0]->nat_phnext[0] = nat->nat_phnext[0];
- *nat->nat_phnext[0] = nat->nat_hnext[0];
-
- if (nat->nat_hnext[1])
- nat->nat_hnext[1]->nat_phnext[1] = nat->nat_phnext[1];
- *nat->nat_phnext[1] = nat->nat_hnext[1];
-
- /*
- * Add into the NAT table in the new position
- */
- hv = NAT_HASH_FN(nat->nat_inip.s_addr, sport, ipf_nattable_sz);
- natp = &nat_table[0][hv];
- if (*natp)
- (*natp)->nat_phnext[0] = &nat->nat_hnext[0];
- nat->nat_phnext[0] = natp;
- nat->nat_hnext[0] = *natp;
- *natp = nat;
-
- hv = NAT_HASH_FN(nat->nat_outip.s_addr, sport, ipf_nattable_sz);
- natp = &nat_table[1][hv];
- if (*natp)
- (*natp)->nat_phnext[1] = &nat->nat_hnext[1];
- nat->nat_phnext[1] = natp;
- nat->nat_hnext[1] = *natp;
- *natp = nat;
-}
-
-
-/*
- * 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(ifp, flags, p, src, dst, ports, rw)
-void *ifp;
-register u_int flags, p;
-struct in_addr src , dst;
-u_32_t ports;
-int rw;
-{
- register u_short sport, dport;
- register nat_t *nat;
- register int nflags;
- u_32_t srcip;
- u_int hv;
-
- sport = ports & 0xffff;
- dport = ports >> 16;
- flags &= IPN_TCPUDP;
- srcip = src.s_addr;
-
- hv = NAT_HASH_FN(srcip, sport, ipf_nattable_sz);
- nat = nat_table[0][hv];
- for (; nat; nat = nat->nat_hnext[0]) {
- nflags = nat->nat_flags;
-
- if ((!ifp || ifp == nat->nat_ifp) &&
- nat->nat_inip.s_addr == srcip &&
- nat->nat_oip.s_addr == dst.s_addr &&
- (((p == 0) && (flags == (nflags & IPN_TCPUDP)))
- || (p == nat->nat_p)) && (!flags ||
- ((nat->nat_inport == sport || nflags & FI_W_SPORT) &&
- (nat->nat_oport == dport || nflags & FI_W_DPORT))))
- return nat;
- }
- if (!nat_stats.ns_wilds || !(flags & IPN_TCPUDP))
- return NULL;
- if (!rw) {
- RWLOCK_EXIT(&ipf_nat);
- }
- hv = NAT_HASH_FN(srcip, 0, ipf_nattable_sz);
- if (!rw) {
- WRITE_ENTER(&ipf_nat);
- }
- nat = nat_table[0][hv];
- for (; nat; nat = nat->nat_hnext[0]) {
- nflags = nat->nat_flags;
- if (ifp && ifp != nat->nat_ifp)
- continue;
- if (!(nflags & IPN_TCPUDP))
- continue;
- if (!(nflags & FI_WILDP))
- continue;
- if ((nat->nat_inip.s_addr != srcip) ||
- (nat->nat_oip.s_addr != dst.s_addr))
- continue;
- if (((nat->nat_inport == sport) || (nflags & FI_W_SPORT)) &&
- ((nat->nat_oport == dport) || (nflags & FI_W_DPORT))) {
- nat_tabmove(nat, ports);
- break;
- }
- }
- if (!rw) {
- MUTEX_DOWNGRADE(&ipf_nat);
- }
- return nat;
-}
-
-
-/*
- * Lookup the NAT tables to search for a matching redirect
- */
-nat_t *nat_lookupredir(np)
-register natlookup_t *np;
-{
- u_32_t ports;
- nat_t *nat;
-
- ports = (np->nl_outport << 16) | np->nl_inport;
- /*
- * 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(NULL, np->nl_flags, 0, np->nl_inip,
- np->nl_outip, ports, 0))) {
- np->nl_realip = nat->nat_outip;
- np->nl_realport = nat->nat_outport;
- }
- return nat;
-}
-
-
-static int nat_match(fin, np, ip)
-fr_info_t *fin;
-ipnat_t *np;
-ip_t *ip;
-{
- frtuc_t *ft;
-
- if (ip->ip_v != 4)
- return 0;
-
- if (np->in_p && ip->ip_p != np->in_p)
- return 0;
- if (fin->fin_out) {
- if (!(np->in_redir & (NAT_MAP|NAT_MAPBLK)))
- return 0;
- if (((fin->fin_fi.fi_saddr & np->in_inmsk) != np->in_inip)
- ^ ((np->in_flags & IPN_NOTSRC) != 0))
- return 0;
- if (((fin->fin_fi.fi_daddr & np->in_srcmsk) != np->in_srcip)
- ^ ((np->in_flags & IPN_NOTDST) != 0))
- return 0;
- } else {
- if (!(np->in_redir & NAT_REDIRECT))
- return 0;
- if (((fin->fin_fi.fi_saddr & np->in_srcmsk) != np->in_srcip)
- ^ ((np->in_flags & IPN_NOTSRC) != 0))
- return 0;
- if (((fin->fin_fi.fi_daddr & np->in_outmsk) != np->in_outip)
- ^ ((np->in_flags & IPN_NOTDST) != 0))
- return 0;
- }
-
- ft = &np->in_tuc;
- if (!(fin->fin_fi.fi_fl & FI_TCPUDP) ||
- (fin->fin_fi.fi_fl & FI_SHORT) || (ip->ip_off & IP_OFFMASK)) {
- if (ft->ftu_scmp || ft->ftu_dcmp)
- return 0;
- return 1;
- }
-
- return fr_tcpudpchk(ft, fin);
-}
-
-
-/*
- * Packets going out on the external interface go through this.
- * Here, the source address requires alteration, if anything.
- */
-int ip_natout(ip, fin)
-ip_t *ip;
-fr_info_t *fin;
-{
- register ipnat_t *np = NULL;
- register u_32_t ipa;
- tcphdr_t *tcp = NULL;
- u_short sport = 0, dport = 0, *csump = NULL;
- struct ifnet *ifp;
- int natadd = 1;
- frentry_t *fr;
- u_int nflags = 0, hv, msk;
- u_32_t iph;
- nat_t *nat;
- int i;
-
- if (nat_list == NULL || (fr_nat_lock))
- return 0;
-
- 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 & IP_OFFMASK) && !(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 & IPN_TCPUDP)) {
- tcp = (tcphdr_t *)fin->fin_dp;
- sport = tcp->th_sport;
- dport = tcp->th_dport;
- }
- }
-
- ipa = ip->ip_src.s_addr;
-
- READ_ENTER(&ipf_nat);
-
- if ((ip->ip_p == IPPROTO_ICMP) &&
- (nat = nat_icmp(ip, fin, &nflags, NAT_OUTBOUND)))
- ;
- else if ((ip->ip_off & (IP_OFFMASK|IP_MF)) &&
- (nat = ipfr_nat_knownfrag(ip, fin)))
- natadd = 0;
- else if ((nat = nat_outlookup(ifp, nflags, (u_int)ip->ip_p,
- ip->ip_src, ip->ip_dst,
- (dport << 16) | sport, 0))) {
- nflags = nat->nat_flags;
- if ((nflags & (FI_W_SPORT|FI_W_DPORT)) != 0) {
- if ((nflags & FI_W_SPORT) &&
- (nat->nat_inport != sport))
- nat->nat_inport = sport;
- else if ((nflags & FI_W_DPORT) &&
- (nat->nat_oport != dport))
- nat->nat_oport = dport;
- if (nat->nat_outport == 0)
- nat->nat_outport = sport;
- nat->nat_flags &= ~(FI_W_DPORT|FI_W_SPORT);
- nflags = nat->nat_flags;
- nat_stats.ns_wilds--;
- }
- } else {
- RWLOCK_EXIT(&ipf_nat);
- WRITE_ENTER(&ipf_nat);
- /*
- * If there is no current entry in the nat table for this IP#,
- * create one for it (if there is a matching rule).
- */
- msk = 0xffffffff;
- i = 32;
-maskloop:
- iph = ipa & htonl(msk);
- hv = NAT_HASH_FN(iph, 0, ipf_natrules_sz);
- for (np = nat_rules[hv]; np; np = np->in_mnext)
- {
- if ((np->in_ifp && (np->in_ifp != ifp)) ||
- !np->in_space)
- continue;
- if ((np->in_flags & IPN_RF) &&
- !(np->in_flags & nflags))
- continue;
- if (np->in_flags & IPN_FILTER) {
- if (!nat_match(fin, np, ip))
- continue;
- } else if ((ipa & np->in_inmsk) != np->in_inip)
- continue;
- if (np->in_redir & (NAT_MAP|NAT_MAPBLK)) {
- if (*np->in_plabel && !appr_ok(ip, tcp, np))
- continue;
- /*
- * If it's a redirection, then we don't want to
- * create new outgoing port stuff.
- * Redirections are only for incoming
- * connections.
- */
- if (!(np->in_redir & (NAT_MAP|NAT_MAPBLK)))
- continue;
- if ((nat = nat_new(np, ip, fin, (u_int)nflags,
- NAT_OUTBOUND))) {
- np->in_hits++;
- break;
- }
- }
- }
- if ((np == NULL) && (i > 0)) {
- do {
- i--;
- msk <<= 1;
- } while ((i >= 0) && ((nat_masks & (1 << i)) == 0));
- if (i >= 0)
- goto maskloop;
- }
- MUTEX_DOWNGRADE(&ipf_nat);
- }
-
- /*
- * NOTE: ipf_nat must now only be held as a read lock
- */
- if (nat) {
- np = nat->nat_ptr;
- if (natadd && fin->fin_fi.fi_fl & FI_FRAG)
- ipfr_nat_newfrag(ip, fin, 0, nat);
- MUTEX_ENTER(&nat->nat_lock);
- nat->nat_age = fr_defnatage;
- nat->nat_bytes += ip->ip_len;
- nat->nat_pkts++;
- MUTEX_EXIT(&nat->nat_lock);
-
- /*
- * Fix up checksums, not by recalculating them, but
- * simply computing adjustments.
- */
- if (nflags == IPN_ICMPERR) {
- u_32_t s1, s2, sumd;
-
- s1 = LONG_SUM(ntohl(ip->ip_src.s_addr));
- s2 = LONG_SUM(ntohl(nat->nat_outip.s_addr));
- CALC_SUMD(s1, s2, sumd);
-
- if (nat->nat_dir == NAT_OUTBOUND)
- fix_incksum(&ip->ip_sum, sumd);
- else
- fix_outcksum(&ip->ip_sum, sumd);
- }
-#if SOLARIS || defined(__sgi)
- else {
- if (nat->nat_dir == NAT_OUTBOUND)
- fix_outcksum(&ip->ip_sum, nat->nat_ipsumd);
- else
- fix_incksum(&ip->ip_sum, nat->nat_ipsumd);
- }
-#endif
- ip->ip_src = nat->nat_outip;
-
- if (!(ip->ip_off & IP_OFFMASK) &&
- !(fin->fin_fi.fi_fl & FI_SHORT)) {
-
- if ((nat->nat_outport != 0) && (nflags & IPN_TCPUDP)) {
- tcp->th_sport = nat->nat_outport;
- fin->fin_data[0] = ntohs(tcp->th_sport);
- }
-
- if (ip->ip_p == IPPROTO_TCP) {
- csump = &tcp->th_sum;
- MUTEX_ENTER(&nat->nat_lock);
- fr_tcp_age(&nat->nat_age,
- nat->nat_tcpstate, fin, 1);
- if (nat->nat_age < fr_defnaticmpage)
- nat->nat_age = fr_defnaticmpage;
-#ifdef LARGE_NAT
- else if (nat->nat_age > fr_defnatage)
- nat->nat_age = fr_defnatage;
-#endif
- /*
- * Increase this because we may have
- * "keep state" following this too and
- * packet storms can occur if this is
- * removed too quickly.
- */
- if (nat->nat_age == fr_tcpclosed)
- nat->nat_age = fr_tcplastack;
- MUTEX_EXIT(&nat->nat_lock);
- } 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) {
- nat->nat_age = fr_defnaticmpage;
- }
-
- if (csump) {
- if (nat->nat_dir == NAT_OUTBOUND)
- fix_outcksum(csump, nat->nat_sumd[1]);
- else
- fix_incksum(csump, nat->nat_sumd[1]);
- }
- }
-
- if ((np->in_apr != NULL) && (np->in_dport == 0 ||
- (tcp != NULL && dport == np->in_dport))) {
- i = appr_check(ip, fin, nat);
- if (i == 0)
- i = 1;
- } else
- i = 1;
- ATOMIC_INCL(nat_stats.ns_mapped[1]);
- RWLOCK_EXIT(&ipf_nat); /* READ */
- return i;
- }
- RWLOCK_EXIT(&ipf_nat); /* READ/WRITE */
- return 0;
-}
-
-
-/*
- * Packets coming in from the external interface go through this.
- * Here, the destination address requires alteration, if anything.
- */
-int ip_natin(ip, fin)
-ip_t *ip;
-fr_info_t *fin;
-{
- register struct in_addr src;
- register struct in_addr in;
- register ipnat_t *np;
- u_int nflags = 0, natadd = 1, hv, msk;
- struct ifnet *ifp = fin->fin_ifp;
- tcphdr_t *tcp = NULL;
- u_short sport = 0, dport = 0, *csump = NULL;
- nat_t *nat;
- u_32_t iph;
- int i;
-
- if ((nat_list == NULL) || (ip->ip_v != 4) || (fr_nat_lock))
- return 0;
-
- if (!(ip->ip_off & IP_OFFMASK) && !(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 & IPN_TCPUDP)) {
- tcp = (tcphdr_t *)fin->fin_dp;
- dport = tcp->th_dport;
- sport = tcp->th_sport;
- }
- }
-
- in = ip->ip_dst;
- /* make sure the source address is to be redirected */
- src = ip->ip_src;
-
- READ_ENTER(&ipf_nat);
-
- if ((ip->ip_p == IPPROTO_ICMP) &&
- (nat = nat_icmp(ip, fin, &nflags, NAT_INBOUND)))
- ;
- else if ((ip->ip_off & (IP_OFFMASK|IP_MF)) &&
- (nat = ipfr_nat_knownfrag(ip, fin)))
- natadd = 0;
- else if ((nat = nat_inlookup(fin->fin_ifp, nflags, (u_int)ip->ip_p,
- ip->ip_src, in, (dport << 16) | sport,
- 0))) {
- nflags = nat->nat_flags;
- if ((nflags & (FI_W_SPORT|FI_W_DPORT)) != 0) {
- if ((nat->nat_oport != sport) && (nflags & FI_W_DPORT))
- nat->nat_oport = sport;
- else if ((nat->nat_outport != dport) &&
- (nflags & FI_W_SPORT))
- nat->nat_outport = dport;
- nat->nat_flags &= ~(FI_W_SPORT|FI_W_DPORT);
- nflags = nat->nat_flags;
- nat_stats.ns_wilds--;
- }
- } else {
- RWLOCK_EXIT(&ipf_nat);
- WRITE_ENTER(&ipf_nat);
- /*
- * If there is no current entry in the nat table for this IP#,
- * create one for it (if there is a matching rule).
- */
- msk = 0xffffffff;
- i = 32;
-maskloop:
- iph = in.s_addr & htonl(msk);
- hv = NAT_HASH_FN(iph, 0, ipf_rdrrules_sz);
- for (np = rdr_rules[hv]; np; np = np->in_rnext) {
- if ((np->in_ifp && (np->in_ifp != ifp)) ||
- (np->in_p && (np->in_p != ip->ip_p)) ||
- (np->in_flags && !(nflags & np->in_flags)))
- continue;
- if (np->in_flags & IPN_FILTER) {
- if (!nat_match(fin, np, ip))
- continue;
- } else if ((in.s_addr & np->in_outmsk) != np->in_outip)
- continue;
- if ((np->in_redir & NAT_REDIRECT) &&
- (!np->in_pmin || (np->in_flags & IPN_FILTER) ||
- ((ntohs(np->in_pmax) >= ntohs(dport)) &&
- (ntohs(dport) >= ntohs(np->in_pmin)))))
- if ((nat = nat_new(np, ip, fin, nflags,
- NAT_INBOUND))) {
- np->in_hits++;
- break;
- }
- }
-
- if ((np == NULL) && (i > 0)) {
- do {
- i--;
- msk <<= 1;
- } while ((i >= 0) && ((rdr_masks & (1 << i)) == 0));
- if (i >= 0)
- goto maskloop;
- }
- MUTEX_DOWNGRADE(&ipf_nat);
- }
-
- /*
- * NOTE: ipf_nat must now only be held as a read lock
- */
- if (nat) {
- np = nat->nat_ptr;
- fin->fin_fr = nat->nat_fr;
- if (natadd && fin->fin_fi.fi_fl & FI_FRAG)
- ipfr_nat_newfrag(ip, fin, 0, nat);
- if ((np->in_apr != NULL) && (np->in_dport == 0 ||
- (tcp != NULL && sport == np->in_dport))) {
- i = appr_check(ip, fin, nat);
- if (i == -1) {
- RWLOCK_EXIT(&ipf_nat);
- return i;
- }
- }
-
- MUTEX_ENTER(&nat->nat_lock);
- if (nflags != IPN_ICMPERR)
- nat->nat_age = fr_defnatage;
-
- nat->nat_bytes += ip->ip_len;
- nat->nat_pkts++;
- MUTEX_EXIT(&nat->nat_lock);
- ip->ip_dst = nat->nat_inip;
- fin->fin_fi.fi_daddr = nat->nat_inip.s_addr;
-
- /*
- * Fix up checksums, not by recalculating them, but
- * simply computing adjustments.
- */
-#if SOLARIS || defined(__sgi)
- if (nat->nat_dir == NAT_OUTBOUND)
- fix_incksum(&ip->ip_sum, nat->nat_ipsumd);
- else
- fix_outcksum(&ip->ip_sum, nat->nat_ipsumd);
-#endif
- if (!(ip->ip_off & IP_OFFMASK) &&
- !(fin->fin_fi.fi_fl & FI_SHORT)) {
-
- if ((nat->nat_inport != 0) && (nflags & IPN_TCPUDP)) {
- tcp->th_dport = nat->nat_inport;
- fin->fin_data[1] = ntohs(tcp->th_dport);
- }
-
- if (ip->ip_p == IPPROTO_TCP) {
- csump = &tcp->th_sum;
- MUTEX_ENTER(&nat->nat_lock);
- fr_tcp_age(&nat->nat_age,
- nat->nat_tcpstate, fin, 0);
- if (nat->nat_age < fr_defnaticmpage)
- nat->nat_age = fr_defnaticmpage;
-#ifdef LARGE_NAT
- else if (nat->nat_age > fr_defnatage)
- nat->nat_age = fr_defnatage;
-#endif
- /*
- * Increase this because we may have
- * "keep state" following this too and
- * packet storms can occur if this is
- * removed too quickly.
- */
- if (nat->nat_age == fr_tcpclosed)
- nat->nat_age = fr_tcplastack;
- MUTEX_EXIT(&nat->nat_lock);
- } 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) {
- nat->nat_age = fr_defnaticmpage;
- }
-
- if (csump) {
- if (nat->nat_dir == NAT_OUTBOUND)
- fix_incksum(csump, nat->nat_sumd[0]);
- else
- fix_outcksum(csump, nat->nat_sumd[0]);
- }
- }
- ATOMIC_INCL(nat_stats.ns_mapped[0]);
- RWLOCK_EXIT(&ipf_nat); /* READ */
- return 1;
- }
- RWLOCK_EXIT(&ipf_nat); /* READ/WRITE */
- return 0;
-}
-
-
-/*
- * Free all memory used by NAT structures allocated at runtime.
- */
-void ip_natunload()
-{
- WRITE_ENTER(&ipf_nat);
- (void) nat_clearlist();
- (void) nat_flushtable();
- RWLOCK_EXIT(&ipf_nat);
-
- if (nat_table[0] != NULL) {
- KFREES(nat_table[0], sizeof(nat_t *) * ipf_nattable_sz);
- nat_table[0] = NULL;
- }
- if (nat_table[1] != NULL) {
- KFREES(nat_table[1], sizeof(nat_t *) * ipf_nattable_sz);
- nat_table[1] = NULL;
- }
- if (nat_rules != NULL) {
- KFREES(nat_rules, sizeof(ipnat_t *) * ipf_natrules_sz);
- nat_rules = NULL;
- }
- if (rdr_rules != NULL) {
- KFREES(rdr_rules, sizeof(ipnat_t *) * ipf_rdrrules_sz);
- rdr_rules = NULL;
- }
- if (maptable != NULL) {
- KFREES(maptable, sizeof(hostmap_t *) * ipf_hostmap_sz);
- maptable = NULL;
- }
-}
-
-
-/*
- * 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;
-#if defined(_KERNEL) && !SOLARIS
- int s;
-#endif
-
- SPL_NET(s);
- WRITE_ENTER(&ipf_nat);
- for (natp = &nat_instances; (nat = *natp); ) {
- nat->nat_age--;
- if (nat->nat_age) {
- natp = &nat->nat_next;
- continue;
- }
- *natp = nat->nat_next;
-#ifdef IPFILTER_LOG
- nat_log(nat, NL_EXPIRE);
-#endif
- nat_delete(nat);
- nat_stats.ns_expire++;
- }
- RWLOCK_EXIT(&ipf_nat);
- SPL_X(s);
-}
-
-
-/*
- */
-void ip_natsync(ifp)
-void *ifp;
-{
- register ipnat_t *n;
- register nat_t *nat;
- register u_32_t sum1, sum2, sumd;
- struct in_addr in;
- ipnat_t *np;
- void *ifp2;
-#if defined(_KERNEL) && !SOLARIS
- int s;
-#endif
-
- /*
- * Change IP addresses for NAT sessions for any protocol except TCP
- * since it will break the TCP connection anyway.
- */
- SPL_NET(s);
- WRITE_ENTER(&ipf_nat);
- for (nat = nat_instances; nat; nat = nat->nat_next)
- if (((ifp == NULL) || (ifp == nat->nat_ifp)) &&
- !(nat->nat_flags & IPN_TCP) && (np = nat->nat_ptr) &&
- (np->in_outmsk == 0xffffffff) && !np->in_nip) {
- ifp2 = nat->nat_ifp;
- /*
- * Change the map-to address to be the same as the
- * new one.
- */
- sum1 = nat->nat_outip.s_addr;
- if (fr_ifpaddr(4, ifp2, &in) != -1)
- nat->nat_outip = in;
- sum2 = nat->nat_outip.s_addr;
-
- if (sum1 == sum2)
- continue;
- /*
- * Readjust the checksum adjustment to take into
- * account the new IP#.
- */
- CALC_SUMD(sum1, sum2, sumd);
- /* 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) {
- n->in_ifp = (void *)GETUNIT(n->in_ifname, 4);
- if (!n->in_ifp)
- n->in_ifp = (void *)-1;
- }
- RWLOCK_EXIT(&ipf_nat);
- SPL_X(s);
-}
-
-
-#ifdef IPFILTER_LOG
-void nat_log(nat, type)
-struct nat *nat;
-u_int type;
-{
- struct ipnat *np;
- struct natlog natl;
- void *items[1];
- size_t sizes[1];
- int rulen, types[1];
-
- natl.nl_inip = nat->nat_inip;
- natl.nl_outip = nat->nat_outip;
- natl.nl_origip = nat->nat_oip;
- natl.nl_bytes = nat->nat_bytes;
- natl.nl_pkts = nat->nat_pkts;
- natl.nl_origport = nat->nat_oport;
- natl.nl_inport = nat->nat_inport;
- natl.nl_outport = nat->nat_outport;
- natl.nl_p = nat->nat_p;
- natl.nl_type = type;
- natl.nl_rule = -1;
-#ifndef LARGE_NAT
- if (nat->nat_ptr != NULL) {
- for (rulen = 0, np = nat_list; np; np = np->in_next, rulen++)
- if (np == nat->nat_ptr) {
- natl.nl_rule = rulen;
- break;
- }
- }
-#endif
- items[0] = &natl;
- sizes[0] = sizeof(natl);
- types[0] = 0;
-
- (void) ipllog(IPL_LOGNAT, NULL, items, sizes, types, 1);
-}
-#endif
diff --git a/contrib/ipfilter/ip_nat.h b/contrib/ipfilter/ip_nat.h
deleted file mode 100644
index 22f8503..0000000
--- a/contrib/ipfilter/ip_nat.h
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright (C) 1995-2000 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.
- *
- * @(#)ip_nat.h 1.5 2/4/96
- * $Id: ip_nat.h,v 2.17.2.14 2000/11/18 03:58:04 darrenr Exp $
- */
-
-#ifndef __IP_NAT_H__
-#define __IP_NAT_H__
-
-#ifndef SOLARIS
-#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
-#endif
-
-#if defined(__STDC__) || defined(__GNUC__)
-#define SIOCADNAT _IOW('r', 60, struct ipnat *)
-#define SIOCRMNAT _IOW('r', 61, struct ipnat *)
-#define SIOCGNATS _IOWR('r', 62, struct natstat *)
-#define SIOCGNATL _IOWR('r', 63, struct natlookup *)
-#else
-#define SIOCADNAT _IOW(r, 60, struct ipnat *)
-#define SIOCRMNAT _IOW(r, 61, struct ipnat *)
-#define SIOCGNATS _IOWR(r, 62, struct natstat *)
-#define SIOCGNATL _IOWR(r, 63, struct natlookup *)
-#endif
-
-#undef LARGE_NAT /* define this if you're setting up a system to NAT
- * LARGE numbers of networks/hosts - i.e. in the
- * hundreds or thousands. In such a case, you should
- * also change the RDR_SIZE and NAT_SIZE below to more
- * appropriate sizes. The figures below were used for
- * a setup with 1000-2000 networks to NAT.
- */
-#define NAT_SIZE 127
-#define RDR_SIZE 127
-#define HOSTMAP_SIZE 127
-#define NAT_TABLE_SZ 127
-#ifdef LARGE_NAT
-#undef NAT_SIZE
-#undef RDR_SIZE
-#undef NAT_TABLE_SZ
-#undef HOSTMAP_SIZE 127
-#define NAT_SIZE 2047
-#define RDR_SIZE 2047
-#define NAT_TABLE_SZ 16383
-#define HOSTMAP_SIZE 8191
-#endif
-#ifndef APR_LABELLEN
-#define APR_LABELLEN 16
-#endif
-#define NAT_HW_CKSUM 0x80000000
-
-#define DEF_NAT_AGE 1200 /* 10 minutes (600 seconds) */
-
-struct ap_session;
-
-typedef struct nat {
- u_long nat_age;
- int nat_flags;
- u_32_t nat_sumd[2];
- u_32_t nat_ipsumd;
- void *nat_data;
- struct ap_session *nat_aps; /* proxy session */
- struct frentry *nat_fr; /* filter rule ptr if appropriate */
- struct in_addr nat_inip;
- struct in_addr nat_outip;
- struct in_addr nat_oip; /* other ip */
- U_QUAD_T nat_pkts;
- U_QUAD_T nat_bytes;
- u_short nat_oport; /* other port */
- u_short nat_inport;
- u_short nat_outport;
- u_short nat_use;
- u_char nat_tcpstate[2];
- u_char nat_p; /* protocol for NAT */
- struct ipnat *nat_ptr; /* pointer back to the rule */
- struct hostmap *nat_hm;
- struct nat *nat_next;
- struct nat *nat_hnext[2];
- struct nat **nat_phnext[2];
- void *nat_ifp;
- int nat_dir;
- char nat_ifname[IFNAMSIZ];
-#if SOLARIS || defined(__sgi)
- kmutex_t nat_lock;
-#endif
-} nat_t;
-
-typedef struct ipnat {
- struct ipnat *in_next;
- struct ipnat *in_rnext;
- struct ipnat **in_prnext;
- struct ipnat *in_mnext;
- struct ipnat **in_pmnext;
- void *in_ifp;
- void *in_apr;
- u_long in_space;
- u_int in_use;
- u_int in_hits;
- struct in_addr in_nextip;
- u_short in_pnext;
- u_short in_ippip; /* IP #'s per IP# */
- u_32_t in_flags; /* From here to in_dport must be reflected */
- u_short in_spare;
- u_short in_ppip; /* ports per IP */
- u_short in_port[2]; /* correctly in IPN_CMPSIZ */
- struct in_addr in_in[2];
- struct in_addr in_out[2];
- struct in_addr in_src[2];
- struct frtuc in_tuc;
- int in_redir; /* 0 if it's a mapping, 1 if it's a hard redir */
- char in_ifname[IFNAMSIZ];
- char in_plabel[APR_LABELLEN]; /* proxy label */
- char in_p; /* protocol */
-} ipnat_t;
-
-#define in_pmin in_port[0] /* Also holds static redir port */
-#define in_pmax in_port[1]
-#define in_nip in_nextip.s_addr
-#define in_inip in_in[0].s_addr
-#define in_inmsk in_in[1].s_addr
-#define in_outip in_out[0].s_addr
-#define in_outmsk in_out[1].s_addr
-#define in_srcip in_src[0].s_addr
-#define in_srcmsk in_src[1].s_addr
-#define in_scmp in_tuc.ftu_scmp
-#define in_dcmp in_tuc.ftu_dcmp
-#define in_stop in_tuc.ftu_stop
-#define in_dtop in_tuc.ftu_dtop
-#define in_sport in_tuc.ftu_sport
-#define in_dport in_tuc.ftu_dport
-
-#define NAT_OUTBOUND 0
-#define NAT_INBOUND 1
-
-#define NAT_MAP 0x01
-#define NAT_REDIRECT 0x02
-#define NAT_BIMAP (NAT_MAP|NAT_REDIRECT)
-#define NAT_MAPBLK 0x04
-/* 0x100 reserved for FI_W_SPORT */
-/* 0x200 reserved for FI_W_DPORT */
-/* 0x400 reserved for FI_W_SADDR */
-/* 0x800 reserved for FI_W_DADDR */
-/* 0x1000 reserved for FI_W_NEWFR */
-
-#define MAPBLK_MINPORT 1024 /* don't use reserved ports for src port */
-#define USABLE_PORTS (65536 - MAPBLK_MINPORT)
-
-#define IPN_CMPSIZ (sizeof(ipnat_t) - offsetof(ipnat_t, in_flags))
-
-typedef struct natlookup {
- struct in_addr nl_inip;
- struct in_addr nl_outip;
- struct in_addr nl_realip;
- int nl_flags;
- u_short nl_inport;
- u_short nl_outport;
- u_short nl_realport;
-} natlookup_t;
-
-
-typedef struct nat_save {
- void *ipn_next;
- struct nat ipn_nat;
- struct ipnat ipn_ipnat;
- struct frentry ipn_fr;
- int ipn_dsize;
- char ipn_data[4];
-} nat_save_t;
-
-#define ipn_rule ipn_nat.nat_fr
-
-typedef struct natget {
- void *ng_ptr;
- int ng_sz;
-} natget_t;
-
-
-typedef struct hostmap {
- struct hostmap *hm_next;
- struct hostmap **hm_pnext;
- struct ipnat *hm_ipnat;
- struct in_addr hm_realip;
- struct in_addr hm_mapip;
- int hm_ref;
-} hostmap_t;
-
-
-typedef struct natstat {
- u_long ns_mapped[2];
- u_long ns_rules;
- u_long ns_added;
- u_long ns_expire;
- u_long ns_inuse;
- u_long ns_logged;
- u_long ns_logfail;
- u_long ns_memfail;
- u_long ns_badnat;
- nat_t **ns_table[2];
- ipnat_t *ns_list;
- void *ns_apslist;
- u_int ns_nattab_sz;
- u_int ns_rultab_sz;
- u_int ns_rdrtab_sz;
- nat_t *ns_instances;
- u_int ns_wilds;
-} natstat_t;
-
-#define IPN_ANY 0x000
-#define IPN_TCP 0x001
-#define IPN_UDP 0x002
-#define IPN_TCPUDP (IPN_TCP|IPN_UDP)
-#define IPN_DELETE 0x004
-#define IPN_ICMPERR 0x008
-#define IPN_RF (IPN_TCPUDP|IPN_DELETE|IPN_ICMPERR)
-#define IPN_AUTOPORTMAP 0x010
-#define IPN_IPRANGE 0x020
-#define IPN_USERFLAGS (IPN_TCPUDP|IPN_AUTOPORTMAP|IPN_IPRANGE|IPN_SPLIT|\
- IPN_ROUNDR|IPN_FILTER|IPN_NOTSRC|IPN_NOTDST)
-#define IPN_FILTER 0x040
-#define IPN_SPLIT 0x080
-#define IPN_ROUNDR 0x100
-#define IPN_NOTSRC 0x080000
-#define IPN_NOTDST 0x100000
-
-
-typedef struct natlog {
- struct in_addr nl_origip;
- struct in_addr nl_outip;
- struct in_addr nl_inip;
- u_short nl_origport;
- u_short nl_outport;
- u_short nl_inport;
- u_short nl_type;
- int nl_rule;
- U_QUAD_T nl_pkts;
- U_QUAD_T nl_bytes;
- u_char nl_p;
-} natlog_t;
-
-
-#define NL_NEWMAP NAT_MAP
-#define NL_NEWRDR NAT_REDIRECT
-#define NL_NEWBIMAP NAT_BIMAP
-#define NL_NEWBLOCK NAT_MAPBLK
-#define NL_FLUSH 0xfffe
-#define NL_EXPIRE 0xffff
-
-#define NAT_HASH_FN(k,l,m) (((k) + ((k) >> 12) + l) % (m))
-
-#define LONG_SUM(in) (((in) & 0xffff) + ((in) >> 16))
-
-#define CALC_SUMD(s1, s2, sd) { \
- (s1) = ((s1) & 0xffff) + ((s1) >> 16); \
- (s2) = ((s2) & 0xffff) + ((s2) >> 16); \
- /* Do it twice */ \
- (s1) = ((s1) & 0xffff) + ((s1) >> 16); \
- (s2) = ((s2) & 0xffff) + ((s2) >> 16); \
- /* Because ~1 == -2, We really need ~1 == -1 */ \
- if ((s1) > (s2)) (s2)--; \
- (sd) = (s2) - (s1); \
- (sd) = ((sd) & 0xffff) + ((sd) >> 16); }
-
-
-extern u_int ipf_nattable_sz;
-extern u_int ipf_natrules_sz;
-extern u_int ipf_rdrrules_sz;
-extern int fr_nat_lock;
-extern void ip_natsync __P((void *));
-extern u_long fr_defnatage;
-extern u_long fr_defnaticmpage;
-extern nat_t **nat_table[2];
-extern nat_t *nat_instances;
-extern ipnat_t **nat_rules;
-extern ipnat_t **rdr_rules;
-extern natstat_t nat_stats;
-#if defined(__NetBSD__) || defined(__OpenBSD__) || (__FreeBSD_version >= 300003)
-extern int nat_ioctl __P((caddr_t, u_long, int));
-#else
-extern int nat_ioctl __P((caddr_t, int, int));
-#endif
-extern int nat_init __P((void));
-extern nat_t *nat_new __P((ipnat_t *, ip_t *, fr_info_t *, u_int, int));
-extern nat_t *nat_outlookup __P((void *, u_int, u_int, struct in_addr,
- struct in_addr, u_32_t, int));
-extern nat_t *nat_inlookup __P((void *, u_int, u_int, struct in_addr,
- struct in_addr, u_32_t, int));
-extern nat_t *nat_maplookup __P((void *, u_int, struct in_addr,
- struct in_addr));
-extern nat_t *nat_lookupredir __P((natlookup_t *));
-extern nat_t *nat_icmplookup __P((ip_t *, fr_info_t *, int));
-extern nat_t *nat_icmp __P((ip_t *, fr_info_t *, u_int *, int));
-extern void nat_insert __P((nat_t *));
-
-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_datacksum __P((u_short *, u_32_t));
-
-#endif /* __IP_NAT_H__ */
diff --git a/contrib/ipfilter/ip_proxy.c b/contrib/ipfilter/ip_proxy.c
deleted file mode 100644
index e1e55f1..0000000
--- a/contrib/ipfilter/ip_proxy.c
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * Copyright (C) 1997-2000 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)
-static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.9.2.1 2000/05/06 12:30:50 darrenr Exp $";
-#endif
-
-#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL)
-# define _KERNEL
-#endif
-
-#include <sys/errno.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/file.h>
-#if !defined(__FreeBSD_version)
-# include <sys/ioctl.h>
-#endif
-#include <sys/fcntl.h>
-#include <sys/uio.h>
-#if !defined(_KERNEL) && !defined(KERNEL)
-# include <stdio.h>
-# include <string.h>
-# include <stdlib.h>
-#endif
-#ifndef linux
-# include <sys/protosw.h>
-#endif
-#include <sys/socket.h>
-#if defined(_KERNEL)
-# if !defined(linux)
-# include <sys/systm.h>
-# else
-# include <linux/string.h>
-# endif
-#endif
-#if !defined(__SVR4) && !defined(__svr4__)
-# ifndef linux
-# include <sys/mbuf.h>
-# endif
-#else
-# include <sys/byteorder.h>
-# ifdef _KERNEL
-# include <sys/dditypes.h>
-# endif
-# include <sys/stream.h>
-# include <sys/kmem.h>
-#endif
-#if __FreeBSD__ > 2
-# include <sys/queue.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>
-#ifndef linux
-# include <netinet/ip_var.h>
-#endif
-#include <netinet/tcp.h>
-#include <netinet/udp.h>
-#include <netinet/ip_icmp.h>
-#include "netinet/ip_compat.h"
-#include <netinet/tcpip.h>
-#include "netinet/ip_fil.h"
-#include "netinet/ip_proxy.h"
-#include "netinet/ip_nat.h"
-#include "netinet/ip_state.h"
-#if (__FreeBSD_version >= 300000)
-# include <sys/malloc.h>
-#endif
-
-
-#ifndef MIN
-#define MIN(a,b) (((a)<(b))?(a):(b))
-#endif
-
-static ap_session_t *appr_new_session __P((aproxy_t *, ip_t *,
- fr_info_t *, nat_t *));
-static int appr_fixseqack __P((fr_info_t *, ip_t *, ap_session_t *, int ));
-
-
-#define AP_SESS_SIZE 53
-
-#if defined(_KERNEL) && !defined(linux)
-#include "netinet/ip_ftp_pxy.c"
-#include "netinet/ip_rcmd_pxy.c"
-#include "netinet/ip_raudio_pxy.c"
-#endif
-
-ap_session_t *ap_sess_tab[AP_SESS_SIZE];
-ap_session_t *ap_sess_list = NULL;
-aproxy_t *ap_proxylist = NULL;
-aproxy_t ap_proxies[] = {
-#ifdef IPF_FTP_PROXY
- { NULL, "ftp", (char)IPPROTO_TCP, 0, 0, ippr_ftp_init, NULL,
- ippr_ftp_new, ippr_ftp_in, ippr_ftp_out },
-#endif
-#ifdef IPF_RCMD_PROXY
- { NULL, "rcmd", (char)IPPROTO_TCP, 0, 0, ippr_rcmd_init, NULL,
- ippr_rcmd_new, NULL, ippr_rcmd_out },
-#endif
-#ifdef IPF_RAUDIO_PROXY
- { NULL, "raudio", (char)IPPROTO_TCP, 0, 0, ippr_raudio_init, NULL,
- ippr_raudio_new, ippr_raudio_in, ippr_raudio_out },
-#endif
- { NULL, "", '\0', 0, 0, NULL, NULL }
-};
-
-
-int appr_add(ap)
-aproxy_t *ap;
-{
- aproxy_t *a;
-
- for (a = ap_proxies; a->apr_p; a++)
- if ((a->apr_p == ap->apr_p) &&
- !strncmp(a->apr_label, ap->apr_label,
- sizeof(ap->apr_label)))
- return -1;
-
- for (a = ap_proxylist; a->apr_p; a = a->apr_next)
- if ((a->apr_p == ap->apr_p) &&
- !strncmp(a->apr_label, ap->apr_label,
- sizeof(ap->apr_label)))
- return -1;
- ap->apr_next = ap_proxylist;
- ap_proxylist = ap;
- return (*ap->apr_init)();
-}
-
-
-int appr_del(ap)
-aproxy_t *ap;
-{
- aproxy_t *a, **app;
-
- for (app = &ap_proxylist; (a = *app); app = &a->apr_next)
- if (a == ap) {
- if (ap->apr_ref != 0)
- return 1;
- *app = a->apr_next;
- return 0;
- }
- return -1;
-}
-
-
-int appr_ok(ip, tcp, nat)
-ip_t *ip;
-tcphdr_t *tcp;
-ipnat_t *nat;
-{
- aproxy_t *apr = nat->in_apr;
- u_short dport = nat->in_dport;
-
- if (!apr || (apr->apr_flags & APR_DELETE) ||
- (ip->ip_p != apr->apr_p))
- return 0;
- if ((tcp && (tcp->th_dport != dport)) || (!tcp && dport))
- return 0;
- return 1;
-}
-
-
-/*
- * Allocate a new application proxy structure and fill it in with the
- * relevant details. call the init function once complete, prior to
- * returning.
- */
-static ap_session_t *appr_new_session(apr, ip, fin, nat)
-aproxy_t *apr;
-ip_t *ip;
-fr_info_t *fin;
-nat_t *nat;
-{
- register ap_session_t *aps;
-
- if (!apr || (apr->apr_flags & APR_DELETE) || (ip->ip_p != apr->apr_p))
- return NULL;
-
- KMALLOC(aps, ap_session_t *);
- if (!aps)
- return NULL;
- bzero((char *)aps, sizeof(*aps));
- aps->aps_p = ip->ip_p;
- aps->aps_data = NULL;
- aps->aps_apr = apr;
- aps->aps_psiz = 0;
- if (apr->apr_new != NULL)
- if ((*apr->apr_new)(fin, ip, aps, nat) == -1) {
- KFREE(aps);
- return NULL;
- }
- aps->aps_nat = nat;
- aps->aps_next = ap_sess_list;
- ap_sess_list = aps;
- return aps;
-}
-
-
-/*
- * check to see if a packet should be passed through an active proxy routine
- * if one has been setup for it.
- */
-int appr_check(ip, fin, nat)
-ip_t *ip;
-fr_info_t *fin;
-nat_t *nat;
-{
- ap_session_t *aps;
- aproxy_t *apr;
- tcphdr_t *tcp = NULL;
- u_32_t sum;
- short rv;
- int err;
-
- if (nat->nat_aps == NULL)
- nat->nat_aps = appr_new_session(nat->nat_ptr->in_apr, ip,
- fin, nat);
- aps = nat->nat_aps;
- if ((aps != NULL) && (aps->aps_p == ip->ip_p)) {
- if (ip->ip_p == IPPROTO_TCP) {
- tcp = (tcphdr_t *)fin->fin_dp;
- /*
- * verify that the checksum is correct. If not, then
- * don't do anything with this packet.
- */
-#if SOLARIS && defined(_KERNEL)
- sum = fr_tcpsum(fin->fin_qfm, ip, tcp);
-#else
- sum = fr_tcpsum(*(mb_t **)fin->fin_mp, ip, tcp);
-#endif
- if (sum != tcp->th_sum) {
- frstats[fin->fin_out].fr_tcpbad++;
- return -1;
- }
- }
-
- apr = aps->aps_apr;
- err = 0;
- if (fin->fin_out != 0) {
- if (apr->apr_outpkt != NULL)
- err = (*apr->apr_outpkt)(fin, ip, aps, nat);
- } else {
- if (apr->apr_inpkt != NULL)
- err = (*apr->apr_inpkt)(fin, ip, aps, nat);
- }
-
- rv = APR_EXIT(err);
- if (rv == -1)
- return rv;
-
- if (tcp != NULL) {
- err = appr_fixseqack(fin, ip, aps, APR_INC(err));
-#if SOLARIS && defined(_KERNEL)
- tcp->th_sum = fr_tcpsum(fin->fin_qfm, ip, tcp);
-#else
- tcp->th_sum = fr_tcpsum(*(mb_t **)fin->fin_mp, ip, tcp);
-#endif
- }
- aps->aps_bytes += ip->ip_len;
- aps->aps_pkts++;
- return 1;
- }
- return 0;
-}
-
-
-aproxy_t *appr_match(pr, name)
-u_int pr;
-char *name;
-{
- aproxy_t *ap;
-
- for (ap = ap_proxies; ap->apr_p; ap++)
- if ((ap->apr_p == pr) &&
- !strncmp(name, ap->apr_label, sizeof(ap->apr_label))) {
- ap->apr_ref++;
- return ap;
- }
-
- for (ap = ap_proxylist; ap; ap = ap->apr_next)
- if ((ap->apr_p == pr) &&
- !strncmp(name, ap->apr_label, sizeof(ap->apr_label))) {
- ap->apr_ref++;
- return ap;
- }
- return NULL;
-}
-
-
-void appr_free(ap)
-aproxy_t *ap;
-{
- ap->apr_ref--;
-}
-
-
-void aps_free(aps)
-ap_session_t *aps;
-{
- ap_session_t *a, **ap;
-
- if (!aps)
- return;
-
- for (ap = &ap_sess_list; (a = *ap); ap = &a->aps_next)
- if (a == aps) {
- *ap = a->aps_next;
- break;
- }
-
- if ((aps->aps_data != NULL) && (aps->aps_psiz != 0))
- KFREES(aps->aps_data, aps->aps_psiz);
- KFREE(aps);
-}
-
-
-static int appr_fixseqack(fin, ip, aps, inc)
-fr_info_t *fin;
-ip_t *ip;
-ap_session_t *aps;
-int inc;
-{
- int sel, ch = 0, out, nlen;
- u_32_t seq1, seq2;
- tcphdr_t *tcp;
-
- tcp = (tcphdr_t *)fin->fin_dp;
- out = fin->fin_out;
- nlen = ip->ip_len;
- nlen -= (ip->ip_hl << 2) + (tcp->th_off << 2);
-
- if (out != 0) {
- seq1 = (u_32_t)ntohl(tcp->th_seq);
- sel = aps->aps_sel[out];
-
- /* switch to other set ? */
- if ((aps->aps_seqmin[!sel] > aps->aps_seqmin[sel]) &&
- (seq1 > aps->aps_seqmin[!sel]))
- sel = aps->aps_sel[out] = !sel;
-
- if (aps->aps_seqoff[sel]) {
- seq2 = aps->aps_seqmin[sel] - aps->aps_seqoff[sel];
- if (seq1 > seq2) {
- seq2 = aps->aps_seqoff[sel];
- seq1 += seq2;
- tcp->th_seq = htonl(seq1);
- ch = 1;
- }
- }
-
- if (inc && (seq1 > aps->aps_seqmin[!sel])) {
- aps->aps_seqmin[!sel] = seq1 + nlen - 1;
- aps->aps_seqoff[!sel] = aps->aps_seqoff[sel] + inc;
- }
-
- /***/
-
- seq1 = ntohl(tcp->th_ack);
- sel = aps->aps_sel[1 - out];
-
- /* switch to other set ? */
- if ((aps->aps_ackmin[!sel] > aps->aps_ackmin[sel]) &&
- (seq1 > aps->aps_ackmin[!sel]))
- sel = aps->aps_sel[1 - out] = !sel;
-
- if (aps->aps_ackoff[sel] && (seq1 > aps->aps_ackmin[sel])) {
- seq2 = aps->aps_ackoff[sel];
- tcp->th_ack = htonl(seq1 - seq2);
- ch = 1;
- }
- } else {
- seq1 = ntohl(tcp->th_seq);
- sel = aps->aps_sel[out];
-
- /* switch to other set ? */
- if ((aps->aps_ackmin[!sel] > aps->aps_ackmin[sel]) &&
- (seq1 > aps->aps_ackmin[!sel]))
- sel = aps->aps_sel[out] = !sel;
-
- if (aps->aps_ackoff[sel]) {
- seq2 = aps->aps_ackmin[sel] -
- aps->aps_ackoff[sel];
- if (seq1 > seq2) {
- seq2 = aps->aps_ackoff[sel];
- seq1 += seq2;
- tcp->th_seq = htonl(seq1);
- ch = 1;
- }
- }
-
- if (inc && (seq1 > aps->aps_ackmin[!sel])) {
- aps->aps_ackmin[!sel] = seq1 + nlen - 1;
- aps->aps_ackoff[!sel] = aps->aps_ackoff[sel] + inc;
- }
-
- /***/
-
- seq1 = ntohl(tcp->th_ack);
- sel = aps->aps_sel[1 - out];
-
- /* switch to other set ? */
- if ((aps->aps_seqmin[!sel] > aps->aps_seqmin[sel]) &&
- (seq1 > aps->aps_seqmin[!sel]))
- sel = aps->aps_sel[1 - out] = !sel;
-
- if (aps->aps_seqoff[sel] && (seq1 > aps->aps_seqmin[sel])) {
- seq2 = aps->aps_seqoff[sel];
- tcp->th_ack = htonl(seq1 - seq2);
- ch = 1;
- }
- }
- return ch ? 2 : 0;
-}
-
-
-int appr_init()
-{
- aproxy_t *ap;
- int err = 0;
-
- for (ap = ap_proxies; ap->apr_p; ap++) {
- err = (*ap->apr_init)();
- if (err != 0)
- break;
- }
- return err;
-}
-
-
-void appr_unload()
-{
- aproxy_t *ap;
-
- for (ap = ap_proxies; ap->apr_p; ap++)
- if (ap->apr_fini)
- (*ap->apr_fini)();
- for (ap = ap_proxylist; ap; ap = ap->apr_next)
- if (ap->apr_fini)
- (*ap->apr_fini)();
-}
diff --git a/contrib/ipfilter/ip_proxy.h b/contrib/ipfilter/ip_proxy.h
deleted file mode 100644
index 212900f..0000000
--- a/contrib/ipfilter/ip_proxy.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 1997-2000 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: ip_proxy.h,v 2.8.2.4 2000/12/02 00:15:03 darrenr Exp $
- */
-
-#ifndef __IP_PROXY_H__
-#define __IP_PROXY_H__
-
-#ifndef SOLARIS
-#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
-#endif
-
-#ifndef APR_LABELLEN
-#define APR_LABELLEN 16
-#endif
-#define AP_SESS_SIZE 53
-
-struct nat;
-struct ipnat;
-
-typedef struct ap_tcp {
- u_short apt_sport; /* source port */
- u_short apt_dport; /* destination port */
- short apt_sel[2]; /* {seq,ack}{off,min} set selector */
- short apt_seqoff[2]; /* sequence # difference */
- tcp_seq apt_seqmin[2]; /* don't change seq-off until after this */
- short apt_ackoff[2]; /* sequence # difference */
- tcp_seq apt_ackmin[2]; /* don't change seq-off until after this */
- u_char apt_state[2]; /* connection state */
-} ap_tcp_t;
-
-typedef struct ap_udp {
- u_short apu_sport; /* source port */
- u_short apu_dport; /* destination port */
-} ap_udp_t;
-
-typedef struct ap_session {
- struct aproxy *aps_apr;
- union {
- struct ap_tcp apu_tcp;
- struct ap_udp apu_udp;
- } aps_un;
- u_int aps_flags;
- U_QUAD_T aps_bytes; /* bytes sent */
- U_QUAD_T aps_pkts; /* packets sent */
- void *aps_nat; /* pointer back to nat struct */
- void *aps_data; /* private data */
- int aps_p; /* protocol */
- int aps_psiz; /* size of private data */
- struct ap_session *aps_hnext;
- struct ap_session *aps_next;
-} ap_session_t;
-
-#define aps_sport aps_un.apu_tcp.apt_sport
-#define aps_dport aps_un.apu_tcp.apt_dport
-#define aps_sel aps_un.apu_tcp.apt_sel
-#define aps_seqoff aps_un.apu_tcp.apt_seqoff
-#define aps_seqmin aps_un.apu_tcp.apt_seqmin
-#define aps_state aps_un.apu_tcp.apt_state
-#define aps_ackoff aps_un.apu_tcp.apt_ackoff
-#define aps_ackmin aps_un.apu_tcp.apt_ackmin
-
-
-typedef struct aproxy {
- struct aproxy *apr_next;
- char apr_label[APR_LABELLEN]; /* Proxy label # */
- u_char apr_p; /* protocol */
- int apr_ref; /* +1 per rule referencing it */
- int apr_flags;
- int (* apr_init) __P((void));
- void (* apr_fini) __P((void));
- int (* apr_new) __P((fr_info_t *, ip_t *,
- ap_session_t *, struct nat *));
- int (* apr_inpkt) __P((fr_info_t *, ip_t *,
- ap_session_t *, struct nat *));
- int (* apr_outpkt) __P((fr_info_t *, ip_t *,
- ap_session_t *, struct nat *));
-} aproxy_t;
-
-#define APR_DELETE 1
-
-#define APR_ERR(x) (((x) & 0xffff) << 16)
-#define APR_EXIT(x) (((x) >> 16) & 0xffff)
-#define APR_INC(x) ((x) & 0xffff)
-
-#define FTP_BUFSZ 160
-/*
- * For the ftp proxy.
- */
-typedef struct ftpside {
- char *ftps_rptr;
- char *ftps_wptr;
- u_32_t ftps_seq;
- u_32_t ftps_len;
- int ftps_junk;
- char ftps_buf[FTP_BUFSZ];
-} ftpside_t;
-
-typedef struct ftpinfo {
- u_int ftp_passok;
- ftpside_t ftp_side[2];
-} ftpinfo_t;
-
-/*
- * Real audio proxy structure and #defines
- */
-typedef struct {
- int rap_seenpna;
- int rap_seenver;
- int rap_version;
- int rap_eos; /* End Of Startup */
- int rap_gotid;
- int rap_gotlen;
- int rap_mode;
- int rap_sdone;
- u_short rap_plport;
- u_short rap_prport;
- u_short rap_srport;
- char rap_svr[19];
- u_32_t rap_sbf; /* flag to indicate which of the 19 bytes have
- * been filled
- */
- tcp_seq rap_sseq;
-} raudio_t;
-
-#define RA_ID_END 0
-#define RA_ID_UDP 1
-#define RA_ID_ROBUST 7
-
-#define RAP_M_UDP 1
-#define RAP_M_ROBUST 2
-#define RAP_M_TCP 4
-#define RAP_M_UDP_ROBUST (RAP_M_UDP|RAP_M_ROBUST)
-
-
-extern ap_session_t *ap_sess_tab[AP_SESS_SIZE];
-extern ap_session_t *ap_sess_list;
-extern aproxy_t ap_proxies[];
-extern int ippr_ftp_pasvonly;
-
-extern int appr_add __P((aproxy_t *));
-extern int appr_del __P((aproxy_t *));
-extern int appr_init __P((void));
-extern void appr_unload __P((void));
-extern int appr_ok __P((ip_t *, tcphdr_t *, struct ipnat *));
-extern void appr_free __P((aproxy_t *));
-extern void aps_free __P((ap_session_t *));
-extern int appr_check __P((ip_t *, fr_info_t *, struct nat *));
-extern aproxy_t *appr_match __P((u_int, char *));
-
-#endif /* __IP_PROXY_H__ */
diff --git a/contrib/ipfilter/ip_raudio_pxy.c b/contrib/ipfilter/ip_raudio_pxy.c
deleted file mode 100644
index 9ea437c..0000000
--- a/contrib/ipfilter/ip_raudio_pxy.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * $Id: ip_raudio_pxy.c,v 1.7.2.3 2000/10/27 22:54:04 darrenr Exp $
- */
-#if SOLARIS && defined(_KERNEL)
-extern kmutex_t ipf_rw;
-#endif
-
-#define IPF_RAUDIO_PROXY
-
-
-int ippr_raudio_init __P((void));
-int ippr_raudio_new __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
-int ippr_raudio_in __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
-int ippr_raudio_out __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
-
-static frentry_t raudiofr;
-
-
-/*
- * Real Audio application proxy initialization.
- */
-int ippr_raudio_init()
-{
- bzero((char *)&raudiofr, sizeof(raudiofr));
- raudiofr.fr_ref = 1;
- raudiofr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE;
- return 0;
-}
-
-
-/*
- * Setup for a new proxy to handle Real Audio.
- */
-int ippr_raudio_new(fin, ip, aps, nat)
-fr_info_t *fin;
-ip_t *ip;
-ap_session_t *aps;
-nat_t *nat;
-{
- raudio_t *rap;
-
-
- KMALLOCS(aps->aps_data, void *, sizeof(raudio_t));
- if (aps->aps_data == NULL)
- return -1;
-
- bzero(aps->aps_data, sizeof(raudio_t));
- rap = aps->aps_data;
- aps->aps_psiz = sizeof(raudio_t);
- rap->rap_mode = RAP_M_TCP; /* default is for TCP */
- return 0;
-}
-
-
-
-int ippr_raudio_out(fin, ip, aps, nat)
-fr_info_t *fin;
-ip_t *ip;
-ap_session_t *aps;
-nat_t *nat;
-{
- raudio_t *rap = aps->aps_data;
- unsigned char membuf[512 + 1], *s;
- u_short id = 0;
- tcphdr_t *tcp;
- int off, dlen;
- int len = 0;
- mb_t *m;
-#if SOLARIS
- mb_t *m1;
-#endif
-
- /*
- * If we've already processed the start messages, then nothing left
- * for the proxy to do.
- */
- if (rap->rap_eos == 1)
- return 0;
-
- tcp = (tcphdr_t *)fin->fin_dp;
- off = (ip->ip_hl << 2) + (tcp->th_off << 2);
- bzero(membuf, sizeof(membuf));
-#if SOLARIS
- m = fin->fin_qfm;
-
- dlen = msgdsize(m) - off;
- if (dlen <= 0)
- return 0;
- 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), (char *)membuf);
-#endif
- /*
- * In all the startup parsing, ensure that we don't go outside
- * the packet buffer boundary.
- */
- /*
- * Look for the start of connection "PNA" string if not seen yet.
- */
- if (rap->rap_seenpna == 0) {
- s = (u_char *)memstr("PNA", (char *)membuf, 3, dlen);
- if (s == NULL)
- return 0;
- s += 3;
- rap->rap_seenpna = 1;
- } else
- s = membuf;
-
- /*
- * Directly after the PNA will be the version number of this
- * connection.
- */
- if (rap->rap_seenpna == 1 && rap->rap_seenver == 0) {
- if ((s + 1) - membuf < dlen) {
- rap->rap_version = (*s << 8) | *(s + 1);
- s += 2;
- rap->rap_seenver = 1;
- } else
- return 0;
- }
-
- /*
- * Now that we've been past the PNA and version number, we're into the
- * startup messages block. This ends when a message with an ID of 0.
- */
- while ((rap->rap_eos == 0) && ((s + 1) - membuf < dlen)) {
- if (rap->rap_gotid == 0) {
- id = (*s << 8) | *(s + 1);
- s += 2;
- rap->rap_gotid = 1;
- if (id == RA_ID_END) {
- rap->rap_eos = 1;
- break;
- }
- } else if (rap->rap_gotlen == 0) {
- len = (*s << 8) | *(s + 1);
- s += 2;
- rap->rap_gotlen = 1;
- }
-
- if (rap->rap_gotid == 1 && rap->rap_gotlen == 1) {
- if (id == RA_ID_UDP) {
- rap->rap_mode &= ~RAP_M_TCP;
- rap->rap_mode |= RAP_M_UDP;
- rap->rap_plport = (*s << 8) | *(s + 1);
- } else if (id == RA_ID_ROBUST) {
- rap->rap_mode |= RAP_M_ROBUST;
- rap->rap_prport = (*s << 8) | *(s + 1);
- }
- s += len;
- rap->rap_gotlen = 0;
- rap->rap_gotid = 0;
- }
- }
- return 0;
-}
-
-
-int ippr_raudio_in(fin, ip, aps, nat)
-fr_info_t *fin;
-ip_t *ip;
-ap_session_t *aps;
-nat_t *nat;
-{
- unsigned char membuf[IPF_MAXPORTLEN + 1], *s;
- tcphdr_t *tcp, tcph, *tcp2 = &tcph;
- raudio_t *rap = aps->aps_data;
- struct in_addr swa, swb;
- int off, dlen, slen;
- int a1, a2, a3, a4;
- u_short sp, dp;
- fr_info_t fi;
- tcp_seq seq;
- nat_t *ipn;
- u_char swp;
- mb_t *m;
-#if SOLARIS
- mb_t *m1;
-#endif
-
- /*
- * 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;
- off = (ip->ip_hl << 2) + (tcp->th_off << 2);
- m = *(mb_t **)fin->fin_mp;
-
-#if SOLARIS
- m = fin->fin_qfm;
-
- dlen = msgdsize(m) - off;
- if (dlen <= 0)
- return 0;
- bzero(membuf, sizeof(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), (char *)membuf);
-#endif
-
- seq = ntohl(tcp->th_seq);
- /*
- * Check to see if the data in this packet is of interest to us.
- * We only care for the first 19 bytes coming back from the server.
- */
- if (rap->rap_sseq == 0) {
- s = (u_char *)memstr("PNA", (char *)membuf, 3, dlen);
- if (s == NULL)
- return 0;
- a1 = s - membuf;
- dlen -= a1;
- a1 = 0;
- rap->rap_sseq = seq;
- a2 = MIN(dlen, sizeof(rap->rap_svr));
- } else if (seq <= rap->rap_sseq + sizeof(rap->rap_svr)) {
- /*
- * seq # which is the start of data and from that the offset
- * into the buffer array.
- */
- a1 = seq - rap->rap_sseq;
- a2 = MIN(dlen, sizeof(rap->rap_svr));
- a2 -= a1;
- s = membuf;
- } else
- return 0;
-
- 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) || (!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));
- tcp2->th_off = 5;
- fi.fin_dp = (char *)tcp2;
- fi.fin_fr = &raudiofr;
- fi.fin_dlen = sizeof(*tcp2);
- tcp2->th_win = htons(8192);
- slen = ip->ip_len;
- ip->ip_len = fin->fin_hlen + sizeof(*tcp);
-
- 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_len = slen;
- ip->ip_src = swa;
- ip->ip_dst = swb;
- return 0;
-}
diff --git a/contrib/ipfilter/ip_rcmd_pxy.c b/contrib/ipfilter/ip_rcmd_pxy.c
deleted file mode 100644
index d017cf9..0000000
--- a/contrib/ipfilter/ip_rcmd_pxy.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * $Id: ip_rcmd_pxy.c,v 1.4.2.4 2000/11/01 14:34:20 darrenr Exp $
- */
-/*
- * Simple RCMD transparent proxy for in-kernel use. For use with the NAT
- * code.
- */
-#if SOLARIS && defined(_KERNEL)
-extern kmutex_t ipf_rw;
-#endif
-
-#define isdigit(x) ((x) >= '0' && (x) <= '9')
-
-#define IPF_RCMD_PROXY
-
-
-int ippr_rcmd_init __P((void));
-int ippr_rcmd_new __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
-int ippr_rcmd_out __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
-u_short ipf_rcmd_atoi __P((char *));
-int ippr_rcmd_portmsg __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
-
-static frentry_t rcmdfr;
-
-
-/*
- * RCMD application proxy initialization.
- */
-int ippr_rcmd_init()
-{
- bzero((char *)&rcmdfr, sizeof(rcmdfr));
- rcmdfr.fr_ref = 1;
- rcmdfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE;
- return 0;
-}
-
-
-/*
- * Setup for a new RCMD proxy.
- */
-int ippr_rcmd_new(fin, ip, aps, nat)
-fr_info_t *fin;
-ip_t *ip;
-ap_session_t *aps;
-nat_t *nat;
-{
- tcphdr_t *tcp = (tcphdr_t *)fin->fin_dp;
-
- aps->aps_psiz = sizeof(u_32_t);
- KMALLOCS(aps->aps_data, u_32_t *, sizeof(u_32_t));
- if (aps->aps_data == NULL)
- return -1;
- *(u_32_t *)aps->aps_data = 0;
- aps->aps_sport = tcp->th_sport;
- aps->aps_dport = tcp->th_dport;
- return 0;
-}
-
-
-/*
- * ipf_rcmd_atoi - implement a simple version of atoi
- */
-u_short ipf_rcmd_atoi(ptr)
-char *ptr;
-{
- register char *s = ptr, c;
- register u_short i = 0;
-
- while ((c = *s++) && isdigit(c)) {
- i *= 10;
- i += c - '0';
- }
- return i;
-}
-
-
-int ippr_rcmd_portmsg(fin, ip, aps, nat)
-fr_info_t *fin;
-ip_t *ip;
-ap_session_t *aps;
-nat_t *nat;
-{
- char portbuf[8], *s;
- struct in_addr swip;
- u_short sp, dp;
- int off, dlen;
- tcphdr_t *tcp, tcph, *tcp2 = &tcph;
- fr_info_t fi;
- nat_t *ipn;
- mb_t *m;
-#if SOLARIS
- mb_t *m1;
-#endif
-
- tcp = (tcphdr_t *)fin->fin_dp;
-
- if (tcp->th_flags & TH_SYN) {
- *(u_32_t *)aps->aps_data = htonl(ntohl(tcp->th_seq) + 1);
- return 0;
- }
-
- if ((*(u_32_t *)aps->aps_data != 0) &&
- (tcp->th_seq != *(u_32_t *)aps->aps_data))
- return 0;
-
- off = (ip->ip_hl << 2) + (tcp->th_off << 2);
-
-#if SOLARIS
- m = fin->fin_qfm;
-
- dlen = msgdsize(m) - off;
- bzero(portbuf, sizeof(portbuf));
- copyout_mblk(m, off, MIN(sizeof(portbuf), dlen), portbuf);
-#else
- m = *(mb_t **)fin->fin_mp;
- dlen = mbufchainlen(m) - off;
- bzero(portbuf, sizeof(portbuf));
- m_copydata(m, off, MIN(sizeof(portbuf), dlen), portbuf);
-#endif
-
- portbuf[sizeof(portbuf) - 1] = '\0';
- s = portbuf;
- sp = ipf_rcmd_atoi(s);
- if (!sp)
- return 0;
-
- /*
- * Add skeleton NAT entry for connection which will come back the
- * other way.
- */
- sp = htons(sp);
- dp = htons(fin->fin_data[1]);
- ipn = nat_outlookup(fin->fin_ifp, IPN_TCP, nat->nat_p, nat->nat_inip,
- ip->ip_dst, (dp << 16) | sp, 0);
- if (ipn == NULL) {
- int slen;
-
- slen = ip->ip_len;
- ip->ip_len = fin->fin_hlen + sizeof(*tcp);
- bcopy((char *)fin, (char *)&fi, sizeof(fi));
- bzero((char *)tcp2, sizeof(*tcp2));
- tcp2->th_win = htons(8192);
- tcp2->th_sport = sp;
- tcp2->th_dport = 0; /* XXX - don't specify remote port */
- tcp2->th_off = 5;
- fi.fin_data[0] = ntohs(sp);
- fi.fin_data[1] = 0;
- fi.fin_dp = (char *)tcp2;
- fi.fin_dlen = sizeof(*tcp2);
- 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;
- fi.fin_fr = &rcmdfr;
- (void) fr_addstate(ip, &fi, FI_W_DPORT);
- }
- ip->ip_len = slen;
- ip->ip_src = swip;
- }
- return 0;
-}
-
-
-int ippr_rcmd_out(fin, ip, aps, nat)
-fr_info_t *fin;
-ip_t *ip;
-ap_session_t *aps;
-nat_t *nat;
-{
- return ippr_rcmd_portmsg(fin, ip, aps, nat);
-}
diff --git a/contrib/ipfilter/ip_state.c b/contrib/ipfilter/ip_state.c
deleted file mode 100644
index 5d63969..0000000
--- a/contrib/ipfilter/ip_state.c
+++ /dev/null
@@ -1,1901 +0,0 @@
-/*
- * Copyright (C) 1995-2000 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)
-static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.30.2.28 2001/01/08 14:04:46 darrenr Exp $";
-#endif
-
-#include <sys/errno.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/file.h>
-#if defined(__NetBSD__) && (NetBSD >= 199905) && !defined(IPFILTER_LKM) && \
- defined(_KERNEL)
-# include "opt_ipfilter_log.h"
-#endif
-#if defined(_KERNEL) && defined(__FreeBSD_version) && \
- (__FreeBSD_version >= 400000) && !defined(KLD_MODULE)
-#include "opt_inet6.h"
-#endif
-#if !defined(_KERNEL) && !defined(KERNEL) && !defined(__KERNEL__)
-# include <stdio.h>
-# include <stdlib.h>
-# include <string.h>
-#else
-# ifdef linux
-# include <linux/kernel.h>
-# include <linux/module.h>
-# endif
-#endif
-#if (defined(KERNEL) || defined(_KERNEL)) && (__FreeBSD_version >= 220000)
-# include <sys/filio.h>
-# include <sys/fcntl.h>
-# if (__FreeBSD_version >= 300000) && !defined(IPFILTER_LKM)
-# include "opt_ipfilter.h"
-# endif
-#else
-# include <sys/ioctl.h>
-#endif
-#include <sys/time.h>
-#include <sys/uio.h>
-#ifndef linux
-# include <sys/protosw.h>
-#endif
-#include <sys/socket.h>
-#if (defined(_KERNEL) || defined(KERNEL)) && !defined(linux)
-# include <sys/systm.h>
-#endif
-#if !defined(__SVR4) && !defined(__svr4__)
-# ifndef linux
-# include <sys/mbuf.h>
-# endif
-#else
-# include <sys/filio.h>
-# include <sys/byteorder.h>
-# ifdef _KERNEL
-# include <sys/dditypes.h>
-# endif
-# 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/tcp.h>
-#ifndef linux
-# include <netinet/ip_var.h>
-# include <netinet/tcp_fsm.h>
-#endif
-#include <netinet/udp.h>
-#include <netinet/ip_icmp.h>
-#include "netinet/ip_compat.h"
-#include <netinet/tcpip.h>
-#include "netinet/ip_fil.h"
-#include "netinet/ip_nat.h"
-#include "netinet/ip_frag.h"
-#include "netinet/ip_proxy.h"
-#include "netinet/ip_state.h"
-#ifdef USE_INET6
-#include <netinet/icmp6.h>
-#endif
-#if (__FreeBSD_version >= 300000)
-# include <sys/malloc.h>
-# if (defined(_KERNEL) || defined(KERNEL)) && !defined(IPFILTER_LKM)
-# include <sys/libkern.h>
-# include <sys/systm.h>
-# endif
-#endif
-
-#ifndef MIN
-# define MIN(a,b) (((a)<(b))?(a):(b))
-#endif
-
-#define TCP_CLOSE (TH_FIN|TH_RST)
-
-static ipstate_t **ips_table = NULL;
-static ipstate_t *ips_list = NULL;
-static int ips_num = 0;
-static int ips_wild = 0;
-static ips_stat_t ips_stats;
-#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
-extern KRWLOCK_T ipf_state, ipf_mutex;
-extern kmutex_t ipf_rw;
-#endif
-
-#ifdef USE_INET6
-static frentry_t *fr_checkicmp6matchingstate __P((ip6_t *, fr_info_t *));
-#endif
-static int fr_matchsrcdst __P((ipstate_t *, union i6addr, union i6addr,
- fr_info_t *, tcphdr_t *));
-static frentry_t *fr_checkicmpmatchingstate __P((ip_t *, fr_info_t *));
-static int fr_matchicmpqueryreply __P((int, ipstate_t *, icmphdr_t *));
-static int fr_state_flush __P((int));
-static ips_stat_t *fr_statetstats __P((void));
-static void fr_delstate __P((ipstate_t *));
-static int fr_state_remove __P((caddr_t));
-static void fr_ipsmove __P((ipstate_t **, ipstate_t *, u_int));
-int fr_stputent __P((caddr_t));
-int fr_stgetent __P((caddr_t));
-void fr_stinsert __P((ipstate_t *));
-
-
-#define FIVE_DAYS (2 * 5 * 86400) /* 5 days: half closed session */
-
-#define TCP_MSL 240 /* 2 minutes */
-u_long fr_tcpidletimeout = FIVE_DAYS,
- fr_tcpclosewait = 2 * TCP_MSL,
- fr_tcplastack = 2 * TCP_MSL,
- fr_tcptimeout = 2 * TCP_MSL,
- fr_tcpclosed = 120,
- fr_tcphalfclosed = 2 * 2 * 3600, /* 2 hours */
- fr_udptimeout = 240,
- fr_icmptimeout = 120;
-int fr_statemax = IPSTATE_MAX,
- fr_statesize = IPSTATE_SIZE;
-int fr_state_doflush = 0,
- fr_state_lock = 0;
-
-static int icmpreplytype4[ICMP_MAXTYPE + 1];
-
-int fr_stateinit()
-{
- int i;
-
- KMALLOCS(ips_table, ipstate_t **, fr_statesize * sizeof(ipstate_t *));
- if (ips_table != NULL)
- bzero((char *)ips_table, fr_statesize * sizeof(ipstate_t *));
- else
- return -1;
-
- /* fill icmp reply type table */
- for (i = 0; i <= ICMP_MAXTYPE; i++)
- icmpreplytype4[i] = -1;
- icmpreplytype4[ICMP_ECHO] = ICMP_ECHOREPLY;
- icmpreplytype4[ICMP_TSTAMP] = ICMP_TSTAMPREPLY;
- icmpreplytype4[ICMP_IREQ] = ICMP_IREQREPLY;
- icmpreplytype4[ICMP_MASKREQ] = ICMP_MASKREPLY;
-
- return 0;
-}
-
-
-static ips_stat_t *fr_statetstats()
-{
- ips_stats.iss_active = ips_num;
- ips_stats.iss_table = ips_table;
- ips_stats.iss_list = ips_list;
- return &ips_stats;
-}
-
-
-/*
- * flush state tables. two actions currently defined:
- * which == 0 : flush all state table entries
- * which == 1 : flush TCP connections which have started to close but are
- * stuck for some reason.
- */
-static int fr_state_flush(which)
-int which;
-{
- register ipstate_t *is, **isp;
-#if defined(_KERNEL) && !SOLARIS
- int s;
-#endif
- int delete, removed = 0;
-
- SPL_NET(s);
- for (isp = &ips_list; (is = *isp); ) {
- delete = 0;
-
- switch (which)
- {
- case 0 :
- delete = 1;
- break;
- case 1 :
- if (is->is_p != IPPROTO_TCP)
- break;
- if ((is->is_state[0] != TCPS_ESTABLISHED) ||
- (is->is_state[1] != TCPS_ESTABLISHED))
- delete = 1;
- break;
- }
-
- if (delete) {
- if (is->is_p == IPPROTO_TCP)
- ips_stats.iss_fin++;
- else
- ips_stats.iss_expire++;
-#ifdef IPFILTER_LOG
- ipstate_log(is, ISL_FLUSH);
-#endif
- fr_delstate(is);
- removed++;
- } else
- isp = &is->is_next;
- }
- SPL_X(s);
- return removed;
-}
-
-
-static int fr_state_remove(data)
-caddr_t data;
-{
- ipstate_t *sp, st;
- int error;
-
- sp = &st;
- error = IRCOPYPTR(data, (caddr_t)&st, sizeof(st));
- if (error)
- return EFAULT;
-
- for (sp = ips_list; sp; sp = sp->is_next)
- if ((sp->is_p == st.is_p) && (sp->is_v == st.is_v) &&
- !bcmp((char *)&sp->is_src, (char *)&st.is_src,
- sizeof(st.is_src)) &&
- !bcmp((char *)&sp->is_dst, (char *)&st.is_src,
- sizeof(st.is_dst)) &&
- !bcmp((char *)&sp->is_ps, (char *)&st.is_ps,
- sizeof(st.is_ps))) {
- WRITE_ENTER(&ipf_state);
-#ifdef IPFILTER_LOG
- ipstate_log(sp, ISL_REMOVE);
-#endif
- fr_delstate(sp);
- RWLOCK_EXIT(&ipf_state);
- return 0;
- }
- return ESRCH;
-}
-
-
-int fr_state_ioctl(data, cmd, mode)
-caddr_t data;
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-u_long cmd;
-#else
-int cmd;
-#endif
-int mode;
-{
- int arg, ret, error = 0;
-
- switch (cmd)
- {
- case SIOCDELST :
- error = fr_state_remove(data);
- break;
- case SIOCIPFFL :
- error = IRCOPY(data, (caddr_t)&arg, sizeof(arg));
- if (error)
- break;
- if (arg == 0 || arg == 1) {
- WRITE_ENTER(&ipf_state);
- ret = fr_state_flush(arg);
- RWLOCK_EXIT(&ipf_state);
- error = IWCOPY((caddr_t)&ret, data, sizeof(ret));
- } else
- error = EINVAL;
- break;
-#ifdef IPFILTER_LOG
- case SIOCIPFFB :
- if (!(mode & FWRITE))
- error = EPERM;
- else {
- int tmp;
-
- tmp = ipflog_clear(IPL_LOGSTATE);
- IWCOPY((char *)&tmp, data, sizeof(tmp));
- }
- break;
-#endif
- case SIOCGETFS :
- error = IWCOPYPTR((caddr_t)fr_statetstats(), data,
- sizeof(ips_stat_t));
- break;
- case FIONREAD :
-#ifdef IPFILTER_LOG
- arg = (int)iplused[IPL_LOGSTATE];
- error = IWCOPY((caddr_t)&arg, (caddr_t)data, sizeof(arg));
-#endif
- break;
- case SIOCSTLCK :
- error = fr_lock(data, &fr_state_lock);
- break;
- case SIOCSTPUT :
- if (!fr_state_lock) {
- error = EACCES;
- break;
- }
- error = fr_stputent(data);
- break;
- case SIOCSTGET :
- if (!fr_state_lock) {
- error = EACCES;
- break;
- }
- error = fr_stgetent(data);
- break;
- default :
- error = EINVAL;
- break;
- }
- return error;
-}
-
-
-int fr_stgetent(data)
-caddr_t data;
-{
- register ipstate_t *is, *isn;
- ipstate_save_t ips, *ipsp;
- int error;
-
- error = IRCOPY(data, (caddr_t)&ipsp, sizeof(ipsp));
- if (error)
- return EFAULT;
- error = IRCOPY((caddr_t)ipsp, (caddr_t)&ips, sizeof(ips));
- if (error)
- return EFAULT;
-
- isn = ips.ips_next;
- if (!isn) {
- isn = ips_list;
- if (isn == NULL) {
- if (ips.ips_next == NULL)
- return ENOENT;
- return 0;
- }
- } else {
- /*
- * Make sure the pointer we're copying from exists in the
- * current list of entries. Security precaution to prevent
- * copying of random kernel data.
- */
- for (is = ips_list; is; is = is->is_next)
- if (is == isn)
- break;
- if (!is)
- return ESRCH;
- }
- ips.ips_next = isn->is_next;
- bcopy((char *)isn, (char *)&ips.ips_is, sizeof(ips.ips_is));
- if (isn->is_rule)
- bcopy((char *)isn->is_rule, (char *)&ips.ips_fr,
- sizeof(ips.ips_fr));
- error = IWCOPY((caddr_t)&ips, ipsp, sizeof(ips));
- if (error)
- error = EFAULT;
- return error;
-}
-
-
-int fr_stputent(data)
-caddr_t data;
-{
- register ipstate_t *is, *isn;
- ipstate_save_t ips, *ipsp;
- int error, out;
- frentry_t *fr;
-
- error = IRCOPY(data, (caddr_t)&ipsp, sizeof(ipsp));
- if (error)
- return EFAULT;
- error = IRCOPY((caddr_t)ipsp, (caddr_t)&ips, sizeof(ips));
- if (error)
- return EFAULT;
-
- KMALLOC(isn, ipstate_t *);
- if (isn == NULL)
- return ENOMEM;
-
- bcopy((char *)&ips.ips_is, (char *)isn, sizeof(*isn));
- fr = isn->is_rule;
- if (fr != NULL) {
- if (isn->is_flags & FI_NEWFR) {
- KMALLOC(fr, frentry_t *);
- if (fr == NULL) {
- KFREE(isn);
- return ENOMEM;
- }
- bcopy((char *)&ips.ips_fr, (char *)fr, sizeof(*fr));
- out = fr->fr_flags & FR_OUTQUE ? 1 : 0;
- isn->is_rule = fr;
- ips.ips_is.is_rule = fr;
- if (*fr->fr_ifname) {
- fr->fr_ifa = GETUNIT(fr->fr_ifname, fr->fr_v);
- if (fr->fr_ifa == NULL)
- fr->fr_ifa = (void *)-1;
-#ifdef _KERNEL
- else {
- strncpy(isn->is_ifname[out],
- IFNAME(fr->fr_ifa), IFNAMSIZ);
- isn->is_ifp[out] = fr->fr_ifa;
- }
-#endif
- } else
- fr->fr_ifa = NULL;
- /*
- * send a copy back to userland of what we ended up
- * to allow for verification.
- */
- error = IWCOPY((caddr_t)&ips, ipsp, sizeof(ips));
- if (error) {
- KFREE(isn);
- KFREE(fr);
- return EFAULT;
- }
- } else {
- for (is = ips_list; is; is = is->is_next)
- if (is->is_rule == fr)
- break;
- if (!is) {
- KFREE(isn);
- return ESRCH;
- }
- }
- }
- fr_stinsert(isn);
- return 0;
-}
-
-
-void fr_stinsert(is)
-register ipstate_t *is;
-{
- register u_int hv = is->is_hv;
-
- MUTEX_INIT(&is->is_lock, "ipf state entry", NULL);
-
- is->is_ifname[0][sizeof(is->is_ifname[0]) - 1] = '\0';
- if (is->is_ifname[0][0] != '\0') {
- is->is_ifp[0] = GETUNIT(is->is_ifname[0], is->is_v);
- }
- is->is_ifname[1][sizeof(is->is_ifname[0]) - 1] = '\0';
- if (is->is_ifname[1][0] != '\0') {
- is->is_ifp[1] = GETUNIT(is->is_ifname[1], is->is_v);
- }
-
- /*
- * add into list table.
- */
- if (ips_list)
- ips_list->is_pnext = &is->is_next;
- is->is_pnext = &ips_list;
- is->is_next = ips_list;
- ips_list = is;
- if (ips_table[hv])
- ips_table[hv]->is_phnext = &is->is_hnext;
- else
- ips_stats.iss_inuse++;
- is->is_phnext = ips_table + hv;
- is->is_hnext = ips_table[hv];
- ips_table[hv] = is;
- ips_num++;
-}
-
-
-/*
- * Create a new ipstate structure and hang it off the hash table.
- */
-ipstate_t *fr_addstate(ip, fin, flags)
-ip_t *ip;
-fr_info_t *fin;
-u_int flags;
-{
- register tcphdr_t *tcp = NULL;
- register ipstate_t *is;
- register u_int hv;
- ipstate_t ips;
- u_int pass;
- int out;
-
- if (fr_state_lock || (fin->fin_off & IP_OFFMASK) ||
- (fin->fin_fi.fi_fl & FI_SHORT))
- return NULL;
- if (ips_num == fr_statemax) {
- ips_stats.iss_max++;
- fr_state_doflush = 1;
- return NULL;
- }
- out = fin->fin_out;
- is = &ips;
- bzero((char *)is, sizeof(*is));
- ips.is_age = 1;
- ips.is_state[0] = 0;
- ips.is_state[1] = 0;
- /*
- * Copy and calculate...
- */
- hv = (is->is_p = fin->fin_fi.fi_p);
- is->is_src = fin->fin_fi.fi_src;
- hv += is->is_saddr;
- is->is_dst = fin->fin_fi.fi_dst;
- hv += is->is_daddr;
-#ifdef USE_INET6
- if (fin->fin_v == 6) {
- if (is->is_p == IPPROTO_ICMPV6) {
- if (IN6_IS_ADDR_MULTICAST(&is->is_dst.in6))
- flags |= FI_W_DADDR;
- if (out)
- hv -= is->is_daddr;
- else
- hv -= is->is_saddr;
- }
- }
-#endif
-
- switch (is->is_p)
- {
-#ifdef USE_INET6
- case IPPROTO_ICMPV6 :
-#endif
- case IPPROTO_ICMP :
- {
- struct icmp *ic = (struct icmp *)fin->fin_dp;
-
-#ifdef USE_INET6
- if ((is->is_p == IPPROTO_ICMPV6) &&
- ((ic->icmp_type & ICMP6_INFOMSG_MASK) == 0))
- return NULL;
-#endif
- switch (ic->icmp_type)
- {
-#ifdef USE_INET6
- case ICMP6_ECHO_REQUEST :
- is->is_icmp.ics_type = ICMP6_ECHO_REPLY;
- hv += (is->is_icmp.ics_id = ic->icmp_id);
- hv += (is->is_icmp.ics_seq = ic->icmp_seq);
- break;
- case ICMP6_MEMBERSHIP_QUERY :
- case ND_ROUTER_SOLICIT :
- case ND_NEIGHBOR_SOLICIT :
- is->is_icmp.ics_type = ic->icmp_type + 1;
- break;
-#endif
- case ICMP_ECHO :
- case ICMP_TSTAMP :
- case ICMP_IREQ :
- case ICMP_MASKREQ :
- is->is_icmp.ics_type = ic->icmp_type;
- hv += (is->is_icmp.ics_id = ic->icmp_id);
- hv += (is->is_icmp.ics_seq = ic->icmp_seq);
- break;
- default :
- return NULL;
- }
- ATOMIC_INCL(ips_stats.iss_icmp);
- is->is_age = fr_icmptimeout;
- break;
- }
- case IPPROTO_TCP :
- {
- tcp = (tcphdr_t *)fin->fin_dp;
-
- if (tcp->th_flags & TH_RST)
- return NULL;
- /*
- * The endian of the ports doesn't matter, but the ack and
- * sequence numbers do as we do mathematics on them later.
- */
- is->is_dport = tcp->th_dport;
- is->is_sport = tcp->th_sport;
- if ((flags & (FI_W_DPORT|FI_W_SPORT)) == 0) {
- hv += tcp->th_dport;
- hv += tcp->th_sport;
- }
- is->is_send = ntohl(tcp->th_seq) + fin->fin_dlen -
- (tcp->th_off << 2) +
- ((tcp->th_flags & TH_SYN) ? 1 : 0) +
- ((tcp->th_flags & TH_FIN) ? 1 : 0);
- is->is_maxsend = is->is_send;
- is->is_dend = 0;
- is->is_maxdwin = 1;
- is->is_maxswin = ntohs(tcp->th_win);
- if (is->is_maxswin == 0)
- is->is_maxswin = 1;
- /*
- * If we're creating state for a starting connection, start the
- * timer on it as we'll never see an error if it fails to
- * connect.
- */
- ATOMIC_INCL(ips_stats.iss_tcp);
- break;
- }
- case IPPROTO_UDP :
- {
- 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 += tcp->th_dport;
- hv += tcp->th_sport;
- }
- ATOMIC_INCL(ips_stats.iss_udp);
- is->is_age = fr_udptimeout;
- break;
- }
- default :
- return NULL;
- }
-
- KMALLOC(is, ipstate_t *);
- if (is == NULL) {
- ATOMIC_INCL(ips_stats.iss_nomem);
- return NULL;
- }
- bcopy((char *)&ips, (char *)is, sizeof(*is));
- hv %= fr_statesize;
- is->is_hv = hv;
- is->is_rule = fin->fin_fr;
- if (is->is_rule != NULL) {
- ATOMIC_INC32(is->is_rule->fr_ref);
- pass = is->is_rule->fr_flags;
- } else
- pass = fr_flags;
- WRITE_ENTER(&ipf_state);
-
- is->is_pass = pass;
- is->is_pkts = 1;
- is->is_bytes = fin->fin_dlen + fin->fin_hlen;
- /*
- * We want to check everything that is a property of this packet,
- * but we don't (automatically) care about it's fragment status as
- * this may change.
- */
- is->is_v = fin->fin_fi.fi_v;
- is->is_opt = fin->fin_fi.fi_optmsk;
- is->is_optmsk = 0xffffffff;
- is->is_sec = fin->fin_fi.fi_secmsk;
- is->is_secmsk = 0xffff;
- is->is_auth = fin->fin_fi.fi_auth;
- is->is_authmsk = 0xffff;
- is->is_flags = fin->fin_fi.fi_fl & FI_CMP;
- is->is_flags |= FI_CMP << 4;
- is->is_flags |= flags & (FI_WILDP|FI_WILDA);
- if (flags & (FI_WILDP|FI_WILDA))
- ips_wild++;
- is->is_ifp[1 - out] = NULL;
- is->is_ifp[out] = fin->fin_ifp;
-#ifdef _KERNEL
- strncpy(is->is_ifname[out], IFNAME(fin->fin_ifp), IFNAMSIZ);
-#endif
- is->is_ifname[1 - out][0] = '\0';
- if (pass & FR_LOGFIRST)
- is->is_pass &= ~(FR_LOGFIRST|FR_LOG);
- fr_stinsert(is);
- if (is->is_p == IPPROTO_TCP) {
- MUTEX_ENTER(&is->is_lock);
- fr_tcp_age(&is->is_age, is->is_state, fin,
- 0); /* 0 = packet from the source */
- MUTEX_EXIT(&is->is_lock);
- }
-#ifdef IPFILTER_LOG
- ipstate_log(is, ISL_NEW);
-#endif
- RWLOCK_EXIT(&ipf_state);
- fin->fin_rev = IP6NEQ(is->is_dst, fin->fin_fi.fi_dst);
- if (fin->fin_fi.fi_fl & FI_FRAG)
- ipfr_newfrag(ip, fin, pass ^ FR_KEEPSTATE);
- return is;
-}
-
-
-
-/*
- * 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)
-register ipstate_t *is;
-fr_info_t *fin;
-ip_t *ip;
-tcphdr_t *tcp;
-{
- register tcp_seq seq, ack, end;
- register int ackskew;
- tcpdata_t *fdata, *tdata;
- u_short win, maxwin;
- int ret = 0;
- int source;
-
- /*
- * Find difference between last checked packet and this packet.
- */
- source = IP6EQ(fin->fin_fi.fi_src, is->is_src);
- fdata = &is->is_tcp.ts_data[!source];
- tdata = &is->is_tcp.ts_data[source];
- seq = ntohl(tcp->th_seq);
- ack = ntohl(tcp->th_ack);
- win = ntohs(tcp->th_win);
- end = seq + fin->fin_dlen - (tcp->th_off << 2) +
- ((tcp->th_flags & TH_SYN) ? 1 : 0) +
- ((tcp->th_flags & TH_FIN) ? 1 : 0);
-
- MUTEX_ENTER(&is->is_lock);
- if (fdata->td_end == 0) {
- /*
- * Must be a (outgoing) SYN-ACK in reply to a SYN.
- */
- fdata->td_end = end;
- fdata->td_maxwin = 1;
- fdata->td_maxend = end + 1;
- }
-
- if (!(tcp->th_flags & TH_ACK)) { /* Pretend an ack was sent */
- ack = tdata->td_end;
- } else if (((tcp->th_flags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) &&
- (ack == 0)) {
- /* gross hack to get around certain broken tcp stacks */
- ack = tdata->td_end;
- }
-
- if (seq == end)
- seq = end = fdata->td_end;
-
- maxwin = tdata->td_maxwin;
- ackskew = tdata->td_end - ack;
-
-#define SEQ_GE(a,b) ((int)((a) - (b)) >= 0)
-#define SEQ_GT(a,b) ((int)((a) - (b)) > 0)
- if ((SEQ_GE(fdata->td_maxend, end)) &&
- (SEQ_GE(seq, fdata->td_end - maxwin)) &&
-/* XXX what about big packets */
-#define MAXACKWINDOW 66000
- (ackskew >= -MAXACKWINDOW) &&
- (ackskew <= MAXACKWINDOW)) {
- /* if ackskew < 0 then this should be due to fragented
- * packets. There is no way to know the length of the
- * total packet in advance.
- * We do know the total length from the fragment cache though.
- * Note however that there might be more sessions with
- * exactly the same source and destination paramters in the
- * state cache (and source and destination is the only stuff
- * that is saved in the fragment cache). Note further that
- * some TCP connections in the state cache are hashed with
- * sport and dport as well which makes it not worthwhile to
- * look for them.
- * Thus, when ackskew is negative but still seems to belong
- * to this session, we bump up the destinations end value.
- */
- if (ackskew < 0)
- tdata->td_end = ack;
-
- /* update max window seen */
- if (fdata->td_maxwin < win)
- fdata->td_maxwin = win;
- if (SEQ_GT(end, fdata->td_end))
- fdata->td_end = end;
- if (SEQ_GE(ack + win, tdata->td_maxend)) {
- tdata->td_maxend = ack + win;
- if (win == 0)
- tdata->td_maxend++;
- }
-
- ATOMIC_INCL(ips_stats.iss_hits);
- /*
- * Nearing end of connection, start timeout.
- */
- /* source ? 0 : 1 -> !source */
- fr_tcp_age(&is->is_age, is->is_state, fin, !source);
- ret = 1;
- }
- MUTEX_EXIT(&is->is_lock);
- return ret;
-}
-
-
-static int fr_matchsrcdst(is, src, dst, fin, tcp)
-ipstate_t *is;
-union i6addr src, dst;
-fr_info_t *fin;
-tcphdr_t *tcp;
-{
- int ret = 0, rev, out, flags;
- u_short sp, dp;
- void *ifp;
-
- rev = fin->fin_rev = IP6NEQ(is->is_dst, dst);
- ifp = fin->fin_ifp;
- out = fin->fin_out;
-
- if (tcp != NULL) {
- flags = is->is_flags;
- sp = tcp->th_sport;
- dp = tcp->th_dport;
- } else {
- flags = is->is_flags & FI_WILDA;
- sp = 0;
- dp = 0;
- }
-
- if (rev == 0) {
- if (!out) {
- if (is->is_ifpin == NULL || is->is_ifpin == ifp)
- ret = 1;
- } else {
- if (is->is_ifpout == NULL || is->is_ifpout == ifp)
- ret = 1;
- }
- } else {
- if (out) {
- if (is->is_ifpin == NULL || is->is_ifpin == ifp)
- ret = 1;
- } else {
- if (is->is_ifpout == NULL || is->is_ifpout == ifp)
- ret = 1;
- }
- }
- if (ret == 0)
- return 0;
- ret = 0;
-
- if (rev == 0) {
- if (
- (IP6EQ(is->is_dst, dst) || (flags & FI_W_DADDR)) &&
- (IP6EQ(is->is_src, src) || (flags & FI_W_SADDR)) &&
- (!tcp || ((sp == is->is_sport || flags & FI_W_SPORT) &&
- (dp == is->is_dport || flags & FI_W_DPORT)))) {
- ret = 1;
- }
- } else {
- if (
- (IP6EQ(is->is_dst, src) || (flags & FI_W_DADDR)) &&
- (IP6EQ(is->is_src, dst) || (flags & FI_W_SADDR)) &&
- (!tcp || ((sp == is->is_dport || flags & FI_W_DPORT) &&
- (dp == is->is_sport || flags & FI_W_SPORT)))) {
- ret = 1;
- }
- }
- if (ret == 0)
- return 0;
-
- /*
- * Whether or not this should be here, is questionable, but the aim
- * is to get this out of the main line.
- */
- if (tcp == NULL)
- flags = is->is_flags & (FI_CMP|(FI_CMP<<4));
-
- if (((fin->fin_fi.fi_fl & (flags >> 4)) != (flags & FI_CMP)) ||
- ((fin->fin_fi.fi_optmsk & is->is_optmsk) != is->is_opt) ||
- ((fin->fin_fi.fi_secmsk & is->is_secmsk) != is->is_sec) ||
- ((fin->fin_fi.fi_auth & is->is_authmsk) != is->is_auth))
- return 0;
-
- if ((flags & (FI_W_SPORT|FI_W_DPORT))) {
- if ((flags & FI_W_SPORT) != 0) {
- if (rev == 0) {
- is->is_sport = sp;
- is->is_send = htonl(tcp->th_seq);
- } else {
- is->is_sport = dp;
- is->is_send = htonl(tcp->th_ack);
- }
- is->is_maxsend = is->is_send + 1;
- } else if ((flags & FI_W_DPORT) != 0) {
- if (rev == 0) {
- is->is_dport = dp;
- is->is_dend = htonl(tcp->th_ack);
- } else {
- is->is_dport = sp;
- is->is_dend = htonl(tcp->th_seq);
- }
- is->is_maxdend = is->is_dend + 1;
- }
- is->is_flags &= ~(FI_W_SPORT|FI_W_DPORT);
- ips_wild--;
- }
-
- ret = -1;
-
- if (!rev) {
- if (out) {
- if (!is->is_ifpout)
- ret = 1;
- } else {
- if (!is->is_ifpin)
- ret = 0;
- }
- } else {
- if (out) {
- if (!is->is_ifpin)
- ret = 0;
- } else {
- if (!is->is_ifpout)
- ret = 1;
- }
- }
-
- if (ret >= 0) {
- is->is_ifp[ret] = ifp;
-#ifdef _KERNEL
- strncpy(is->is_ifname[out], IFNAME(fin->fin_ifp),
- sizeof(is->is_ifname[1]));
-#endif
- }
-#ifdef _KERNEL
- if (ret >= 0) {
- strncpy(is->is_ifname[out], IFNAME(fin->fin_ifp),
- sizeof(is->is_ifname[1]));
- }
-#endif
- return 1;
-}
-
-static int fr_matchicmpqueryreply(v, is, icmp)
-int v;
-ipstate_t *is;
-icmphdr_t *icmp;
-{
- if (v == 4) {
- /*
- * If we matched its type on the way in, then when going out
- * it will still be the same type.
- */
- if (((icmp->icmp_type == is->is_type) ||
- (icmpreplytype4[is->is_type] == icmp->icmp_type)) &&
- (icmp->icmp_id == is->is_icmp.ics_id) &&
- (icmp->icmp_seq == is->is_icmp.ics_seq)) {
- return 1;
- };
- }
-#ifdef USE_INET6
- else if (is->is_v == 6) {
- if ((is->is_type == ICMP6_ECHO_REPLY) &&
- (icmp->icmp_type == ICMP6_ECHO_REQUEST) &&
- (icmp->icmp_id == is->is_icmp.ics_id) &&
- (icmp->icmp_seq == is->is_icmp.ics_seq)) {
- return 1;
- };
- }
-#endif
- return 0;
-}
-
-static frentry_t *fr_checkicmpmatchingstate(ip, fin)
-ip_t *ip;
-fr_info_t *fin;
-{
- register ipstate_t *is, **isp;
- register u_short sport, dport;
- register u_char pr;
- union i6addr dst, src;
- struct icmp *ic;
- u_short savelen;
- icmphdr_t *icmp;
- fr_info_t ofin;
- int type, len;
- tcphdr_t *tcp;
- frentry_t *fr;
- ip_t *oip;
- u_int hv;
-
- /*
- * Does it at least have the return (basic) IP header ?
- * Only a basic IP header (no options) should be with
- * an ICMP error header.
- */
- if (((ip->ip_v != 4) || (ip->ip_hl != 5)) ||
- (fin->fin_plen < ICMPERR_MINPKTLEN))
- return NULL;
- ic = (struct icmp *)fin->fin_dp;
- type = ic->icmp_type;
- /*
- * If it's not an error type, then return
- */
- if ((type != ICMP_UNREACH) && (type != ICMP_SOURCEQUENCH) &&
- (type != ICMP_REDIRECT) && (type != ICMP_TIMXCEED) &&
- (type != ICMP_PARAMPROB))
- return NULL;
-
- oip = (ip_t *)((char *)ic + ICMPERR_ICMPHLEN);
- if (fin->fin_plen < ICMPERR_MAXPKTLEN + ((oip->ip_hl - 5) << 2))
- return NULL;
-
- /*
- * Sanity checks.
- */
- len = fin->fin_dlen - ICMPERR_ICMPHLEN;
- if ((len <= 0) || ((oip->ip_hl << 2) > len))
- return NULL;
-
- /*
- * Is the buffer big enough for all of it ? It's the size of the IP
- * header claimed in the encapsulated part which is of concern. It
- * may be too big to be in this buffer but not so big that it's
- * outside the ICMP packet, leading to TCP deref's causing problems.
- * This is possible because we don't know how big oip_hl is when we
- * do the pullup early in fr_check() and thus can't gaurantee it is
- * all here now.
- */
-#ifdef _KERNEL
- {
- mb_t *m;
-
-# if SOLARIS
- m = fin->fin_qfm;
- if ((char *)oip + len > (char *)m->b_wptr)
- return NULL;
-# else
- m = *(mb_t **)fin->fin_mp;
- if ((char *)oip + len > (char *)ip + m->m_len)
- return NULL;
-# endif
- }
-#endif
-
- /*
- * in the IPv4 case we must zero the i6addr union otherwise
- * the IP6EQ and IP6NEQ macros produce the wrong results because
- * of the 'junk' in the unused part of the union
- */
- bzero((char *)&src, sizeof(src));
- bzero((char *)&dst, sizeof(dst));
-
- if (oip->ip_p == IPPROTO_ICMP) {
- icmp = (icmphdr_t *)((char *)oip + (oip->ip_hl << 2));
-
- /*
- * 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);
- src.in4 = oip->ip_src;
- hv += src.in4.s_addr;
- dst.in4 = oip->ip_dst;
- hv += dst.in4.s_addr;
- hv += icmp->icmp_id;
- hv += icmp->icmp_seq;
- hv %= fr_statesize;
-
- savelen = oip->ip_len;
- oip->ip_len = len;
- ofin.fin_v = 4;
- fr_makefrip(oip->ip_hl << 2, oip, &ofin);
- oip->ip_len = savelen;
- 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_hnext)
- if ((is->is_p == pr) && (is->is_v == 4) &&
- fr_matchsrcdst(is, src, dst, &ofin, NULL) &&
- fr_matchicmpqueryreply(is->is_v, is, icmp)) {
- 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;
-
- tcp = (tcphdr_t *)((char *)oip + (oip->ip_hl << 2));
- dport = tcp->th_dport;
- sport = tcp->th_sport;
-
- hv = (pr = oip->ip_p);
- src.in4 = oip->ip_src;
- hv += src.in4.s_addr;
- dst.in4 = oip->ip_dst;
- hv += dst.in4.s_addr;
- hv += dport;
- hv += sport;
- hv %= fr_statesize;
- /*
- * we make an fin entry to be able to feed it to
- * matchsrcdst note that not all fields are encessary
- * but this is the cleanest way. Note further we fill
- * in fin_mp such that if someone uses it we'll get
- * a kernel panic. fr_matchsrcdst does not use this.
- *
- * watch out here, as ip is in host order and oip in network
- * order. Any change we make must be undone afterwards.
- */
- savelen = oip->ip_len;
- oip->ip_len = len;
- ofin.fin_v = 4;
- fr_makefrip(oip->ip_hl << 2, oip, &ofin);
- oip->ip_len = savelen;
- 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_hnext) {
- /*
- * Only allow this icmp though if the
- * encapsulated packet was allowed through the
- * other way around. Note that the minimal amount
- * of info present does not allow for checking against
- * tcp internals such as seq and ack numbers.
- */
- if ((is->is_p == pr) && (is->is_v == 4) &&
- fr_matchsrcdst(is, src, dst, &ofin, tcp)) {
- fr = is->is_rule;
- ips_stats.iss_hits++;
- is->is_pkts++;
- is->is_bytes += fin->fin_plen;
- /*
- * we deliberately do not touch the timeouts
- * for the accompanying state table entry.
- * It remains to be seen if that is correct. XXX
- */
- RWLOCK_EXIT(&ipf_state);
- return fr;
- }
- }
- RWLOCK_EXIT(&ipf_state);
- return NULL;
-}
-
-
-static void fr_ipsmove(isp, is, hv)
-ipstate_t **isp, *is;
-u_int hv;
-{
- u_int hvm;
-
- hvm = is->is_hv;
- /*
- * Remove the hash from the old location...
- */
- if (is->is_hnext)
- is->is_hnext->is_phnext = isp;
- *isp = is->is_hnext;
- if (ips_table[hvm] == NULL)
- ips_stats.iss_inuse--;
-
- /*
- * ...and put the hash in the new one.
- */
- hvm = hv % fr_statesize;
- is->is_hv = hvm;
- isp = &ips_table[hvm];
- if (*isp)
- (*isp)->is_phnext = &is->is_hnext;
- else
- ips_stats.iss_inuse++;
- is->is_phnext = isp;
- is->is_hnext = *isp;
- *isp = is;
-}
-
-
-/*
- * Check if a packet has a registered state.
- */
-frentry_t *fr_checkstate(ip, fin)
-ip_t *ip;
-fr_info_t *fin;
-{
- union i6addr dst, src;
- register ipstate_t *is, **isp;
- register u_char pr;
- u_int hv, hvm, hlen, tryagain, pass, v;
- struct icmp *ic;
- frentry_t *fr;
- tcphdr_t *tcp;
-
- if (fr_state_lock || (fin->fin_off & IP_OFFMASK) ||
- (fin->fin_fi.fi_fl & FI_SHORT))
- return NULL;
-
- is = NULL;
- hlen = fin->fin_hlen;
- tcp = (tcphdr_t *)((char *)ip + hlen);
- ic = (struct icmp *)tcp;
- hv = (pr = fin->fin_fi.fi_p);
- src = fin->fin_fi.fi_src;
- dst = fin->fin_fi.fi_dst;
- hv += src.in4.s_addr;
- hv += dst.in4.s_addr;
-
- /*
- * Search the hash table for matching packet header info.
- */
- v = fin->fin_fi.fi_v;
- switch (fin->fin_fi.fi_p)
- {
-#ifdef USE_INET6
- case IPPROTO_ICMPV6 :
- if (v == 6) {
- if (fin->fin_out)
- hv -= dst.in4.s_addr;
- else
- hv -= src.in4.s_addr;
- if ((ic->icmp_type == ICMP6_ECHO_REQUEST) ||
- (ic->icmp_type == ICMP6_ECHO_REPLY)) {
- hv += ic->icmp_id;
- hv += ic->icmp_seq;
- }
- }
-#endif
- case IPPROTO_ICMP :
- if (v == 4) {
- 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_hnext) {
- if ((is->is_p == pr) && (is->is_v == v) &&
- fr_matchsrcdst(is, src, dst, fin, NULL) &&
- fr_matchicmpqueryreply(v, is, ic)) {
- is->is_age = fr_icmptimeout;
- break;
- }
- }
- if (is != NULL)
- break;
- RWLOCK_EXIT(&ipf_state);
- /*
- * No matching icmp state entry. Perhaps this is a
- * response to another state entry.
- */
-#ifdef USE_INET6
- if (v == 6)
- fr = fr_checkicmp6matchingstate((ip6_t *)ip, fin);
- else
-#endif
- fr = fr_checkicmpmatchingstate(ip, fin);
- if (fr)
- return fr;
- break;
- case IPPROTO_TCP :
- {
- register u_short dport, sport;
- register int i;
-
- i = tcp->th_flags;
- /*
- * Just plain ignore RST flag set with either FIN or SYN.
- */
- if ((i & TH_RST) &&
- ((i & (TH_FIN|TH_SYN|TH_RST)) != TH_RST))
- break;
- case IPPROTO_UDP :
- dport = tcp->th_dport;
- sport = tcp->th_sport;
- tryagain = 0;
- hv += dport;
- hv += sport;
- READ_ENTER(&ipf_state);
-retry_tcpudp:
- hvm = hv % fr_statesize;
- for (isp = &ips_table[hvm]; (is = *isp); isp = &is->is_hnext)
- if ((is->is_p == pr) && (is->is_v == v) &&
- fr_matchsrcdst(is, src, dst, fin, tcp)) {
- if ((pr == IPPROTO_TCP)) {
- if (!fr_tcpstate(is, fin, ip, tcp)) {
- continue;
- }
- }
- break;
- }
- if (is != NULL) {
- if (tryagain &&
- !(is->is_flags & (FI_WILDP|FI_WILDA))) {
- hv += dport;
- hv += sport;
- fr_ipsmove(isp, is, hv);
- MUTEX_DOWNGRADE(&ipf_state);
- }
- break;
- }
- RWLOCK_EXIT(&ipf_state);
- if (!tryagain && ips_wild) {
- hv -= dport;
- hv -= sport;
- tryagain = 1;
- WRITE_ENTER(&ipf_state);
- goto retry_tcpudp;
- }
- break;
- }
- default :
- break;
- }
- if (is == NULL) {
- ATOMIC_INCL(ips_stats.iss_miss);
- return NULL;
- }
- MUTEX_ENTER(&is->is_lock);
- is->is_bytes += fin->fin_plen;
- ips_stats.iss_hits++;
- is->is_pkts++;
- MUTEX_EXIT(&is->is_lock);
- fr = is->is_rule;
- fin->fin_fr = fr;
- pass = is->is_pass;
-#ifndef _KERNEL
- if (tcp->th_flags & TCP_CLOSE)
- fr_delstate(is);
-#endif
- RWLOCK_EXIT(&ipf_state);
- if (fin->fin_fi.fi_fl & FI_FRAG)
- ipfr_newfrag(ip, fin, pass ^ FR_KEEPSTATE);
- return fr;
-}
-
-
-void ip_statesync(ifp)
-void *ifp;
-{
- register ipstate_t *is;
-
- WRITE_ENTER(&ipf_state);
- for (is = ips_list; is; is = is->is_next) {
- if (is->is_ifpin == ifp) {
- is->is_ifpin = GETUNIT(is->is_ifname[0], is->is_v);
- if (!is->is_ifpin)
- is->is_ifpin = (void *)-1;
- }
- if (is->is_ifpout == ifp) {
- is->is_ifpout = GETUNIT(is->is_ifname[1], is->is_v);
- if (!is->is_ifpout)
- is->is_ifpout = (void *)-1;
- }
- }
- RWLOCK_EXIT(&ipf_state);
-}
-
-
-/*
- * Must always be called with fr_ipfstate held as a write lock.
- */
-static void fr_delstate(is)
-ipstate_t *is;
-{
- frentry_t *fr;
-
- if (is->is_flags & (FI_WILDP|FI_WILDA))
- ips_wild--;
- if (is->is_next)
- is->is_next->is_pnext = is->is_pnext;
- *is->is_pnext = is->is_next;
- if (is->is_hnext)
- is->is_hnext->is_phnext = is->is_phnext;
- *is->is_phnext = is->is_hnext;
- if (ips_table[is->is_hv] == NULL)
- ips_stats.iss_inuse--;
-
- fr = is->is_rule;
- if (fr != NULL) {
- fr->fr_ref--;
- if (fr->fr_ref == 0) {
- KFREE(fr);
- }
- }
-#ifdef _KERNEL
- MUTEX_DESTROY(&is->is_lock);
-#endif
- KFREE(is);
- ips_num--;
-}
-
-
-/*
- * Free memory in use by all state info. kept.
- */
-void fr_stateunload()
-{
- register ipstate_t *is;
-
- WRITE_ENTER(&ipf_state);
- while ((is = ips_list))
- fr_delstate(is);
- ips_stats.iss_inuse = 0;
- ips_num = 0;
- RWLOCK_EXIT(&ipf_state);
- KFREES(ips_table, fr_statesize * sizeof(ipstate_t *));
- ips_table = NULL;
-}
-
-
-/*
- * 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 ipstate_t *is, **isp;
-#if defined(_KERNEL) && !SOLARIS
- int s;
-#endif
-
- SPL_NET(s);
- WRITE_ENTER(&ipf_state);
- for (isp = &ips_list; (is = *isp); )
- if (is->is_age && !--is->is_age) {
- if (is->is_p == IPPROTO_TCP)
- ips_stats.iss_fin++;
- else
- ips_stats.iss_expire++;
-#ifdef IPFILTER_LOG
- ipstate_log(is, ISL_EXPIRE);
-#endif
- fr_delstate(is);
- } 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);
-}
-
-
-/*
- * Original idea freom Pradeep Krishnan for use primarily with NAT code.
- * (pkrishna@netcom.com)
- *
- * Rewritten by Arjan de Vet <Arjan.deVet@adv.iae.nl>, 2000-07-29:
- *
- * - (try to) base state transitions on real evidence only,
- * i.e. packets that are sent and have been received by ipfilter;
- * diagram 18.12 of TCP/IP volume 1 by W. Richard Stevens was used.
- *
- * - deal with half-closed connections correctly;
- *
- * - store the state of the source in state[0] such that ipfstat
- * displays the state as source/dest instead of dest/source; the calls
- * to fr_tcp_age have been changed accordingly.
- *
- * Parameters:
- *
- * state[0] = state of source (host that initiated connection)
- * state[1] = state of dest (host that accepted the connection)
- *
- * dir == 0 : a packet from source to dest
- * dir == 1 : a packet from dest to source
- *
- */
-void fr_tcp_age(age, state, fin, dir)
-u_long *age;
-u_char *state;
-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 = fin->fin_plen - 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; /* default 4 mins */
-
- switch(state[dir])
- {
- case TCPS_CLOSED: /* 0 */
- if ((flags & TH_OPENING) == TH_OPENING) {
- /*
- * 'dir' received an S and sends SA in response,
- * CLOSED -> SYN_RECEIVED
- */
- state[dir] = TCPS_SYN_RECEIVED;
- *age = fr_tcptimeout;
- } else if ((flags & (TH_SYN|TH_ACK)) == TH_SYN) {
- /* 'dir' sent S, CLOSED -> SYN_SENT */
- state[dir] = TCPS_SYN_SENT;
- *age = fr_tcptimeout;
- }
- /*
- * The next piece of code makes it possible to get
- * already established connections into the state table
- * after a restart or reload of the filter rules; this
- * does not work when a strict 'flags S keep state' is
- * used for tcp connections of course
- */
- if ((flags & (TH_FIN|TH_SYN|TH_RST|TH_ACK)) == TH_ACK) {
- /* we saw an A, guess 'dir' is in ESTABLISHED mode */
- state[dir] = TCPS_ESTABLISHED;
- *age = fr_tcpidletimeout;
- }
- /*
- * TODO: besides regular ACK packets we can have other
- * packets as well; it is yet to be determined how we
- * should initialize the states in those cases
- */
- break;
-
- case TCPS_LISTEN: /* 1 */
- /* NOT USED */
- break;
-
- case TCPS_SYN_SENT: /* 2 */
- if ((flags & (TH_SYN|TH_FIN|TH_ACK)) == TH_ACK) {
- /*
- * We see an A from 'dir' which is in SYN_SENT
- * state: 'dir' sent an A in response to an SA
- * which it received, SYN_SENT -> ESTABLISHED
- */
- state[dir] = TCPS_ESTABLISHED;
- *age = fr_tcpidletimeout;
- } else if (flags & TH_FIN) {
- /*
- * We see an F from 'dir' which is in SYN_SENT
- * state and wants to close its side of the
- * connection; SYN_SENT -> FIN_WAIT_1
- */
- state[dir] = TCPS_FIN_WAIT_1;
- *age = fr_tcpidletimeout; /* or fr_tcptimeout? */
- } else if ((flags & TH_OPENING) == TH_OPENING) {
- /*
- * We see an SA from 'dir' which is already in
- * SYN_SENT state, this means we have a
- * simultaneous open; SYN_SENT -> SYN_RECEIVED
- */
- state[dir] = TCPS_SYN_RECEIVED;
- *age = fr_tcptimeout;
- }
- break;
-
- case TCPS_SYN_RECEIVED: /* 3 */
- if ((flags & (TH_SYN|TH_FIN|TH_ACK)) == TH_ACK) {
- /*
- * We see an A from 'dir' which was in SYN_RECEIVED
- * state so it must now be in established state,
- * SYN_RECEIVED -> ESTABLISHED
- */
- state[dir] = TCPS_ESTABLISHED;
- *age = fr_tcpidletimeout;
- } else if (flags & TH_FIN) {
- /*
- * We see an F from 'dir' which is in SYN_RECEIVED
- * state and wants to close its side of the connection;
- * SYN_RECEIVED -> FIN_WAIT_1
- */
- state[dir] = TCPS_FIN_WAIT_1;
- *age = fr_tcpidletimeout;
- }
- break;
-
- case TCPS_ESTABLISHED: /* 4 */
- if (flags & TH_FIN) {
- /*
- * 'dir' closed its side of the connection; this
- * gives us a half-closed connection;
- * ESTABLISHED -> FIN_WAIT_1
- */
- state[dir] = TCPS_FIN_WAIT_1;
- *age = fr_tcphalfclosed;
- } else if (flags & TH_ACK) {
- /* an ACK, should we exclude other flags here? */
- if (ostate == TCPS_FIN_WAIT_1) {
- /*
- * We know the other side did an active close,
- * so we are ACKing the recvd FIN packet (does
- * the window matching code guarantee this?)
- * and go into CLOSE_WAIT state; this gives us
- * a half-closed connection
- */
- state[dir] = TCPS_CLOSE_WAIT;
- *age = fr_tcphalfclosed;
- } else if (ostate < TCPS_CLOSE_WAIT)
- /*
- * Still a fully established connection,
- * reset timeout
- */
- *age = fr_tcpidletimeout;
- }
- break;
-
- case TCPS_CLOSE_WAIT: /* 5 */
- if (flags & TH_FIN) {
- /*
- * Application closed and 'dir' sent a FIN, we're now
- * going into LAST_ACK state
- */
- *age = fr_tcplastack;
- state[dir] = TCPS_LAST_ACK;
- } else {
- /*
- * We remain in CLOSE_WAIT because the other side has
- * closed already and we did not close our side yet;
- * reset timeout
- */
- *age = fr_tcphalfclosed;
- }
- break;
-
- case TCPS_FIN_WAIT_1: /* 6 */
- if ((flags & TH_ACK) && ostate > TCPS_CLOSE_WAIT) {
- /*
- * If the other side is not active anymore it has sent
- * us a FIN packet that we are ack'ing now with an ACK;
- * this means both sides have now closed the connection
- * and we go into TIME_WAIT
- */
- /*
- * XXX: how do we know we really are ACKing the FIN
- * packet here? does the window code guarantee that?
- */
- state[dir] = TCPS_TIME_WAIT;
- *age = fr_tcptimeout;
- } else
- /*
- * We closed our side of the connection already but the
- * other side is still active (ESTABLISHED/CLOSE_WAIT);
- * continue with this half-closed connection
- */
- *age = fr_tcphalfclosed;
- break;
-
- case TCPS_CLOSING: /* 7 */
- /* NOT USED */
- break;
-
- case TCPS_LAST_ACK: /* 8 */
- if (flags & TH_ACK) {
- if ((flags & TH_PUSH) || dlen)
- /*
- * There is still data to be delivered, reset
- * timeout
- */
- *age = fr_tcplastack;
- }
- /*
- * We cannot detect when we go out of LAST_ACK state to CLOSED
- * because that is based on the reception of ACK packets;
- * ipfilter can only detect that a packet has been sent by a
- * host
- */
- break;
-
- case TCPS_FIN_WAIT_2: /* 9 */
- /* NOT USED */
- break;
-
- case TCPS_TIME_WAIT: /* 10 */
- /* we're in 2MSL timeout now */
- break;
- }
-}
-
-
-#ifdef IPFILTER_LOG
-void ipstate_log(is, type)
-struct ipstate *is;
-u_int type;
-{
- struct ipslog ipsl;
- void *items[1];
- size_t sizes[1];
- int types[1];
-
- ipsl.isl_type = type;
- ipsl.isl_pkts = is->is_pkts;
- ipsl.isl_bytes = is->is_bytes;
- ipsl.isl_src = is->is_src;
- ipsl.isl_dst = is->is_dst;
- ipsl.isl_p = is->is_p;
- ipsl.isl_v = is->is_v;
- ipsl.isl_flags = is->is_flags;
- if (ipsl.isl_p == IPPROTO_TCP || ipsl.isl_p == IPPROTO_UDP) {
- ipsl.isl_sport = is->is_sport;
- ipsl.isl_dport = is->is_dport;
- if (ipsl.isl_p == IPPROTO_TCP) {
- ipsl.isl_state[0] = is->is_state[0];
- ipsl.isl_state[1] = is->is_state[1];
- }
- } else if (ipsl.isl_p == IPPROTO_ICMP)
- ipsl.isl_itype = is->is_icmp.ics_type;
- else {
- ipsl.isl_ps.isl_filler[0] = 0;
- ipsl.isl_ps.isl_filler[1] = 0;
- }
- items[0] = &ipsl;
- sizes[0] = sizeof(ipsl);
- types[0] = 0;
-
- (void) ipllog(IPL_LOGSTATE, NULL, items, sizes, types, 1);
-}
-#endif
-
-
-#ifdef USE_INET6
-frentry_t *fr_checkicmp6matchingstate(ip, fin)
-ip6_t *ip;
-fr_info_t *fin;
-{
- register ipstate_t *is, **isp;
- register u_short sport, dport;
- register u_char pr;
- struct icmp6_hdr *ic, *oic;
- union i6addr dst, src;
- u_short savelen;
- fr_info_t ofin;
- tcphdr_t *tcp;
- frentry_t *fr;
- ip6_t *oip;
- int type;
- u_int hv;
-
- /*
- * Does it at least have the return (basic) IP header ?
- * Only a basic IP header (no options) should be with
- * an ICMP error header.
- */
- if ((fin->fin_v != 6) || (fin->fin_plen < ICMP6ERR_MINPKTLEN))
- return NULL;
- ic = (struct icmp6_hdr *)fin->fin_dp;
- type = ic->icmp6_type;
- /*
- * If it's not an error type, then return
- */
- if ((type != ICMP6_DST_UNREACH) && (type != ICMP6_PACKET_TOO_BIG) &&
- (type != ICMP6_TIME_EXCEEDED) && (type != ICMP6_PARAM_PROB))
- return NULL;
-
- oip = (ip6_t *)((char *)ic + ICMPERR_ICMPHLEN);
- if (fin->fin_plen < sizeof(*oip))
- return NULL;
-
- if (oip->ip6_nxt == IPPROTO_ICMPV6) {
- oic = (struct icmp6_hdr *)(oip + 1);
- /*
- * 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 (!(oic->icmp6_type & ICMP6_INFOMSG_MASK))
- return NULL;
-
- /*
- * perform a lookup of the ICMP packet in the state table
- */
- hv = (pr = oip->ip6_nxt);
- src.in6 = oip->ip6_src;
- hv += src.in4.s_addr;
- dst.in6 = oip->ip6_dst;
- hv += dst.in4.s_addr;
- hv += oic->icmp6_id;
- hv += oic->icmp6_seq;
- hv %= fr_statesize;
-
- oip->ip6_plen = ntohs(oip->ip6_plen);
- ofin.fin_v = 6;
- fr_makefrip(sizeof(*oip), (ip_t *)oip, &ofin);
- oip->ip6_plen = htons(oip->ip6_plen);
- 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_hnext)
- if ((is->is_p == pr) &&
- (oic->icmp6_id == is->is_icmp.ics_id) &&
- (oic->icmp6_seq == is->is_icmp.ics_seq) &&
- 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 == ICMP6_ECHO_REPLY) &&
- (oic->icmp6_type == ICMP6_ECHO_REQUEST)) ||
- (is->is_type - 1 == oic->icmp6_type )) {
- ips_stats.iss_hits++;
- is->is_pkts++;
- is->is_bytes += fin->fin_plen;
- return is->is_rule;
- }
- }
- RWLOCK_EXIT(&ipf_state);
-
- return NULL;
- };
-
- if ((oip->ip6_nxt != IPPROTO_TCP) && (oip->ip6_nxt != IPPROTO_UDP))
- return NULL;
- tcp = (tcphdr_t *)(oip + 1);
- dport = tcp->th_dport;
- sport = tcp->th_sport;
-
- hv = (pr = oip->ip6_nxt);
- src.in6 = oip->ip6_src;
- hv += src.in4.s_addr;
- dst.in6 = oip->ip6_dst;
- hv += dst.in4.s_addr;
- hv += dport;
- hv += sport;
- hv %= fr_statesize;
- /*
- * we make an fin entry to be able to feed it to
- * matchsrcdst note that not all fields are encessary
- * but this is the cleanest way. Note further we fill
- * in fin_mp such that if someone uses it we'll get
- * a kernel panic. fr_matchsrcdst does not use this.
- *
- * watch out here, as ip is in host order and oip in network
- * order. Any change we make must be undone afterwards.
- */
- savelen = oip->ip6_plen;
- oip->ip6_plen = ip->ip6_plen - sizeof(*ip) - ICMPERR_ICMPHLEN;
- ofin.fin_v = 6;
- fr_makefrip(sizeof(*oip), (ip_t *)oip, &ofin);
- oip->ip6_plen = savelen;
- 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_hnext) {
- /*
- * Only allow this icmp though if the
- * encapsulated packet was allowed through the
- * other way around. Note that the minimal amount
- * of info present does not allow for checking against
- * tcp internals such as seq and ack numbers.
- */
- if ((is->is_p == pr) && (is->is_v == 6) &&
- fr_matchsrcdst(is, src, dst, &ofin, tcp)) {
- fr = is->is_rule;
- ips_stats.iss_hits++;
- /*
- * we must swap src and dst here because the icmp
- * comes the other way around
- */
- is->is_pkts++;
- is->is_bytes += fin->fin_plen;
- /*
- * we deliberately do not touch the timeouts
- * for the accompanying state table entry.
- * It remains to be seen if that is correct. XXX
- */
- RWLOCK_EXIT(&ipf_state);
- return fr;
- }
- }
- RWLOCK_EXIT(&ipf_state);
- return NULL;
-}
-#endif
diff --git a/contrib/ipfilter/ip_state.h b/contrib/ipfilter/ip_state.h
deleted file mode 100644
index 1d1bc00..0000000
--- a/contrib/ipfilter/ip_state.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 1995-2000 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.
- *
- * @(#)ip_state.h 1.3 1/12/96 (C) 1995 Darren Reed
- * $Id: ip_state.h,v 2.13.2.2 2000/08/23 11:01:31 darrenr Exp $
- */
-#ifndef __IP_STATE_H__
-#define __IP_STATE_H__
-
-#if defined(__STDC__) || defined(__GNUC__)
-# define SIOCDELST _IOW('r', 61, struct ipstate *)
-#else
-# define SIOCDELST _IOW(r, 61, struct ipstate *)
-#endif
-
-#define IPSTATE_SIZE 5737
-#define IPSTATE_MAX 4013 /* Maximum number of states held */
-
-#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)
-
-
-typedef struct udpstate {
- u_short us_sport;
- u_short us_dport;
-} udpstate_t;
-
-typedef struct icmpstate {
- u_short ics_id;
- u_short ics_seq;
- u_char ics_type;
-} icmpstate_t;
-
-typedef struct tcpdata {
- u_32_t td_end;
- u_32_t td_maxend;
- u_short td_maxwin;
-} tcpdata_t;
-
-typedef struct tcpstate {
- u_short ts_sport;
- u_short ts_dport;
- tcpdata_t ts_data[2];
- u_char ts_state[2];
-} tcpstate_t;
-
-typedef struct ipstate {
- struct ipstate *is_next;
- struct ipstate **is_pnext;
- struct ipstate *is_hnext;
- struct ipstate **is_phnext;
- u_long is_age;
- u_int is_pass;
- U_QUAD_T is_pkts;
- U_QUAD_T is_bytes;
- void *is_ifp[2];
- frentry_t *is_rule;
- union i6addr is_src;
- union i6addr is_dst;
- u_char is_p; /* Protocol */
- u_char is_v;
- u_int is_hv;
- u_32_t is_flags;
- u_32_t is_opt; /* packet options set */
- u_32_t is_optmsk; /* " " mask */
- u_short is_sec; /* security options set */
- u_short is_secmsk; /* " " mask */
- u_short is_auth; /* authentication options set */
- u_short is_authmsk; /* " " mask */
- union {
- icmpstate_t is_ics;
- tcpstate_t is_ts;
- udpstate_t is_us;
- } is_ps;
- char is_ifname[2][IFNAMSIZ];
-#if SOLARIS || defined(__sgi)
- kmutex_t is_lock;
-#endif
-} ipstate_t;
-
-#define is_saddr is_src.in4.s_addr
-#define is_daddr is_dst.in4.s_addr
-#define is_icmp is_ps.is_ics
-#define is_type is_icmp.ics_type
-#define is_code is_icmp.ics_code
-#define is_tcp is_ps.is_ts
-#define is_udp is_ps.is_us
-#define is_send is_tcp.ts_data[0].td_end
-#define is_dend is_tcp.ts_data[1].td_end
-#define is_maxswin is_tcp.ts_data[0].td_maxwin
-#define is_maxdwin is_tcp.ts_data[1].td_maxwin
-#define is_maxsend is_tcp.ts_data[0].td_maxend
-#define is_maxdend is_tcp.ts_data[1].td_maxend
-#define is_sport is_tcp.ts_sport
-#define is_dport is_tcp.ts_dport
-#define is_state is_tcp.ts_state
-#define is_ifpin is_ifp[0]
-#define is_ifpout is_ifp[1]
-
-#define TH_OPENING (TH_SYN|TH_ACK)
-/*
- * is_flags:
- * Bits 0 - 3 are use as a mask with the current packet's bits to check for
- * whether it is short, tcp/udp, a fragment or the presence of IP options.
- * Bits 4 - 7 are set from the initial packet and contain what the packet
- * anded with bits 0-3 must match.
- * Bits 8,9 are used to indicate wildcard source/destination port matching.
- */
-
-typedef struct ipstate_save {
- void *ips_next;
- struct ipstate ips_is;
- struct frentry ips_fr;
-} ipstate_save_t;
-
-#define ips_rule ips_is.is_rule
-
-
-typedef struct ipslog {
- U_QUAD_T isl_pkts;
- U_QUAD_T isl_bytes;
- union i6addr isl_src;
- union i6addr isl_dst;
- u_short isl_type;
- union {
- u_short isl_filler[2];
- u_short isl_ports[2];
- u_short isl_icmp;
- } isl_ps;
- u_char isl_v;
- u_char isl_p;
- u_char isl_flags;
- u_char isl_state[2];
-} ipslog_t;
-
-#define isl_sport isl_ps.isl_ports[0]
-#define isl_dport isl_ps.isl_ports[1]
-#define isl_itype isl_ps.isl_icmp
-
-#define ISL_NEW 0
-#define ISL_EXPIRE 0xffff
-#define ISL_FLUSH 0xfffe
-#define ISL_REMOVE 0xfffd
-
-
-typedef struct ips_stat {
- u_long iss_hits;
- u_long iss_miss;
- u_long iss_max;
- u_long iss_tcp;
- u_long iss_udp;
- u_long iss_icmp;
- u_long iss_nomem;
- u_long iss_expire;
- u_long iss_fin;
- u_long iss_active;
- u_long iss_logged;
- u_long iss_logfail;
- u_long iss_inuse;
- ipstate_t **iss_table;
- ipstate_t *iss_list;
-} ips_stat_t;
-
-
-extern u_long fr_tcpidletimeout;
-extern u_long fr_tcpclosewait;
-extern u_long fr_tcplastack;
-extern u_long fr_tcptimeout;
-extern u_long fr_tcpclosed;
-extern u_long fr_tcphalfclosed;
-extern u_long fr_udptimeout;
-extern u_long fr_icmptimeout;
-extern int fr_state_lock;
-extern int fr_stateinit __P((void));
-extern int fr_tcpstate __P((ipstate_t *, fr_info_t *, ip_t *, tcphdr_t *));
-extern ipstate_t *fr_addstate __P((ip_t *, fr_info_t *, u_int));
-extern frentry_t *fr_checkstate __P((ip_t *, fr_info_t *));
-extern void ip_statesync __P((void *));
-extern void fr_timeoutstate __P((void));
-extern void fr_tcp_age __P((u_long *, u_char *, fr_info_t *, int));
-extern void fr_stateunload __P((void));
-extern void ipstate_log __P((struct ipstate *, u_int));
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-extern int fr_state_ioctl __P((caddr_t, u_long, int));
-#else
-extern int fr_state_ioctl __P((caddr_t, int, int));
-#endif
-
-#endif /* __IP_STATE_H__ */
diff --git a/contrib/ipfilter/ipl.h b/contrib/ipfilter/ipl.h
deleted file mode 100644
index 3529d65..0000000
--- a/contrib/ipfilter/ipl.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (C) 1993-2000 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.
- *
- * @(#)ipl.h 1.21 6/5/96
- * $Id: ipl.h,v 2.15.2.17 2001/01/14 13:47:15 darrenr Exp $
- */
-
-#ifndef __IPL_H__
-#define __IPL_H__
-
-#define IPL_VERSION "IP Filter: v3.4.16"
-
-#endif
diff --git a/contrib/ipfilter/mlfk_ipl.c b/contrib/ipfilter/mlfk_ipl.c
deleted file mode 100644
index 0dc4ff2..0000000
--- a/contrib/ipfilter/mlfk_ipl.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright 1999 Guido van Rooij. All rights reserved.
- *
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE HOLDER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id: mlfk_ipl.c,v 2.1.2.6 2000/11/18 03:58:29 darrenr Exp $
- */
-
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/conf.h>
-#include <sys/socket.h>
-#include <sys/sysctl.h>
-#include <net/if.h>
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#if (__FreeBSD_version >= 199511)
-# include <net/route.h>
-# include <netinet/ip_var.h>
-# include <netinet/tcp.h>
-# include <netinet/tcpip.h>
-#endif
-
-
-#include <netinet/ipl.h>
-#include <netinet/ip_compat.h>
-#include <netinet/ip_fil.h>
-#include <netinet/ip_state.h>
-#include <netinet/ip_nat.h>
-#include <netinet/ip_auth.h>
-#include <netinet/ip_frag.h>
-#include <netinet/ip_proxy.h>
-
-static dev_t ipf_devs[IPL_LOGMAX + 1];
-
-SYSCTL_DECL(_net_inet);
-SYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW, 0, "IPF");
-SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &fr_flags, 0, "");
-SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_pass, CTLFLAG_RW, &fr_pass, 0, "");
-SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &fr_active, 0, "");
-SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RW,
- &fr_tcpidletimeout, 0, "");
-SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RW,
- &fr_tcpclosewait, 0, "");
-SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcplastack, CTLFLAG_RW,
- &fr_tcplastack, 0, "");
-SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RW,
- &fr_tcptimeout, 0, "");
-SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RW,
- &fr_tcpclosed, 0, "");
-SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RW,
- &fr_tcphalfclosed, 0, "");
-SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RW,
- &fr_udptimeout, 0, "");
-SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RW,
- &fr_icmptimeout, 0, "");
-SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_defnatage, CTLFLAG_RW,
- &fr_defnatage, 0, "");
-SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_ipfrttl, CTLFLAG_RW,
- &fr_ipfrttl, 0, "");
-SYSCTL_INT(_net_inet_ipf, OID_AUTO, ipl_unreach, CTLFLAG_RW,
- &ipl_unreach, 0, "");
-SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_running, CTLFLAG_RD,
- &fr_running, 0, "");
-SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_authsize, CTLFLAG_RD,
- &fr_authsize, 0, "");
-SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_authused, CTLFLAG_RD,
- &fr_authused, 0, "");
-SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_defaultauthage, CTLFLAG_RW,
- &fr_defaultauthage, 0, "");
-SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &fr_chksrc, 0, "");
-SYSCTL_INT(_net_inet_ipf, OID_AUTO, ippr_ftp_pasvonly, CTLFLAG_RW,
- &ippr_ftp_pasvonly, 0, "");
-SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &fr_minttl, 0, "");
-SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_minttllog, CTLFLAG_RW,
- &fr_minttllog, 0, "");
-
-#define CDEV_MAJOR 79
-static struct cdevsw ipl_cdevsw = {
- /* open */ iplopen,
- /* close */ iplclose,
- /* read */ iplread,
- /* write */ nowrite,
- /* ioctl */ iplioctl,
- /* poll */ nopoll,
- /* mmap */ nommap,
- /* strategy */ nostrategy,
- /* name */ "ipl",
- /* maj */ CDEV_MAJOR,
- /* dump */ nodump,
- /* psize */ nopsize,
- /* flags */ 0,
- /* bmaj */ -1
-};
-
-static int
-ipfilter_modevent(module_t mod, int type, void *unused)
-{
- char *c;
- int i, error = 0;
-
- switch (type) {
- case MOD_LOAD :
-
- error = iplattach();
- if (error)
- break;
-
- c = NULL;
- for(i=strlen(IPL_NAME); i>0; i--)
- if (IPL_NAME[i] == '/') {
- c = &IPL_NAME[i+1];
- break;
- }
- if (!c)
- c = IPL_NAME;
- ipf_devs[IPL_LOGIPF] =
- make_dev(&ipl_cdevsw, IPL_LOGIPF, 0, 0, 0600, c);
-
- c = NULL;
- for(i=strlen(IPL_NAT); i>0; i--)
- if (IPL_NAT[i] == '/') {
- c = &IPL_NAT[i+1];
- break;
- }
- if (!c)
- c = IPL_NAT;
- ipf_devs[IPL_LOGNAT] =
- make_dev(&ipl_cdevsw, IPL_LOGNAT, 0, 0, 0600, c);
-
- c = NULL;
- for(i=strlen(IPL_STATE); i>0; i--)
- if (IPL_STATE[i] == '/') {
- c = &IPL_STATE[i+1];
- break;
- }
- if (!c)
- c = IPL_STATE;
- ipf_devs[IPL_LOGSTATE] =
- make_dev(&ipl_cdevsw, IPL_LOGSTATE, 0, 0, 0600, c);
-
- c = NULL;
- for(i=strlen(IPL_AUTH); i>0; i--)
- if (IPL_AUTH[i] == '/') {
- c = &IPL_AUTH[i+1];
- break;
- }
- if (!c)
- c = IPL_AUTH;
- ipf_devs[IPL_LOGAUTH] =
- make_dev(&ipl_cdevsw, IPL_LOGAUTH, 0, 0, 0600, c);
-
- break;
- case MOD_UNLOAD :
- destroy_dev(ipf_devs[IPL_LOGIPF]);
- destroy_dev(ipf_devs[IPL_LOGNAT]);
- destroy_dev(ipf_devs[IPL_LOGSTATE]);
- destroy_dev(ipf_devs[IPL_LOGAUTH]);
- error = ipldetach();
- break;
- default:
- error = EINVAL;
- break;
- }
- return error;
-}
-
-static moduledata_t ipfiltermod = {
- IPL_VERSION,
- ipfilter_modevent,
- 0
-};
-DECLARE_MODULE(ipfilter, ipfiltermod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY);
OpenPOWER on IntegriCloud