diff options
author | peter <peter@FreeBSD.org> | 1999-10-10 15:09:59 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1999-10-10 15:09:59 +0000 |
commit | c5fae336058615ac8e0d149bdc8b7c6efc88d07b (patch) | |
tree | 6e714dd0327e7889cd95ee2f995266b8229a10b5 | |
parent | 76c8e9b267ecd06e50fdc045c919d158999307b0 (diff) | |
download | FreeBSD-src-c5fae336058615ac8e0d149bdc8b7c6efc88d07b.zip FreeBSD-src-c5fae336058615ac8e0d149bdc8b7c6efc88d07b.tar.gz |
Nuke the old antique copy of ipfilter from the tree. This is old enough
to be dangerous. It will better serve us as a port building a KLD,
ala SKIP.
The hooks are staying although it would be better to port and use
the NetBSD pfil interface rather than have custom hooks.
35 files changed, 0 insertions, 17662 deletions
diff --git a/sys/contrib/ipfilter/netinet/fil.c b/sys/contrib/ipfilter/netinet/fil.c deleted file mode 100644 index ee0ff90..0000000 --- a/sys/contrib/ipfilter/netinet/fil.c +++ /dev/null @@ -1,1329 +0,0 @@ -/* - * Copyright (C) 1993-1997 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-1996 Darren Reed"; -static const char rcsid[] = "@(#)$FreeBSD$"; -#endif - -#include "opt_ipfilter.h" - -#include <sys/errno.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/time.h> -#include <sys/file.h> -#if !defined(__FreeBSD__) -# 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> -# include <sys/dditypes.h> -# include <sys/stream.h> -#endif -#if defined(__FreeBSD__) -# include <sys/malloc.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 -#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" -#ifndef MIN -#define MIN(a,b) (((a)<(b))?(a):(b)) -#endif - -#ifndef _KERNEL -# include "ipf.h" -# include "ipt.h" -extern int opts; - -# define FR_IFVERBOSE(ex,second,verb_pr) if (ex) { verbose verb_pr; \ - second; } -# define FR_IFDEBUG(ex,second,verb_pr) if (ex) { debug verb_pr; \ - second; } -# define FR_VERBOSE(verb_pr) verbose verb_pr -# define FR_DEBUG(verb_pr) debug verb_pr -# define SEND_RESET(ip, qif, if, m) send_reset(ip, if) -# define IPLLOG(a, c, d, e) ipllog() -# define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, ip) -# if SOLARIS -# define ICMP_ERROR(b, ip, t, c, if, src) icmp_error(ip) -# else -# define ICMP_ERROR(b, ip, t, c, if, src) icmp_error(b, ip, if) -# endif -#else /* #ifndef _KERNEL */ -# define FR_IFVERBOSE(ex,second,verb_pr) ; -# define FR_IFDEBUG(ex,second,verb_pr) ; -# 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 kmutex_t ipf_mutex, ipf_auth; -# endif -# if SOLARIS -# define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, \ - ip, qif) -# define SEND_RESET(ip, qif, if) send_reset(ip, qif) -# define ICMP_ERROR(b, ip, t, c, if, src) \ - icmp_error(ip, t, c, if, src) -# else /* SOLARIS */ -# define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, ip) -# ifdef linux -# define SEND_RESET(ip, qif, if) send_reset((tcpiphdr_t *)ip,\ - ifp) -# else -# define SEND_RESET(ip, qif, if) send_reset((tcpiphdr_t *)ip) -# endif -# ifdef __sgi -# define ICMP_ERROR(b, ip, t, c, if, src) \ - icmp_error(b, t, c, if, src, if) -# else -# if BSD < 199103 -# ifdef linux -# define ICMP_ERROR(b, ip, t, c, if, src) icmp_send(b,t,c,0,if) -# else -# define ICMP_ERROR(b, ip, t, c, if, src) \ - icmp_error(mtod(b, ip_t *), t, c, if, src) -# endif /* linux */ -# else -# define ICMP_ERROR(b, ip, t, c, if, src) \ - icmp_error(b, t, c, (src).s_addr, if) -# endif /* BSD < 199103 */ -# endif /* __sgi */ -# 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 } }, - *ipacct[2][2] = { { NULL, NULL }, { NULL, NULL } }; -struct frgroup *ipfgroups[3][2]; -int fr_flags = IPF_LOGGING, fr_active = 0; -#if defined(IPFILTER_DEFAULT_BLOCK) -int fr_pass = FR_NOMATCH|FR_BLOCK; -#else -int fr_pass = (IPF_DEFAULT_PASS|FR_NOMATCH); -#endif - -fr_info_t frcache[2]; - -static void fr_makefrip __P((int, ip_t *, fr_info_t *)); -static int fr_tcpudpchk __P((frentry_t *, fr_info_t *)); -static int frflushlist __P((int, int, int *, frentry_t *, frentry_t **)); - - -/* - * bit values for identifying presence of individual IP options - */ -static 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 - */ -static 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. - */ -static void fr_makefrip(hlen, ip, fin) -int hlen; -ip_t *ip; -fr_info_t *fin; -{ - struct optlist *op; - tcphdr_t *tcp; - icmphdr_t *icmp; - fr_ip_t *fi = &fin->fin_fi; - u_short optmsk = 0, secmsk = 0, auth = 0; - int i, mv, ol, off; - u_char *s, opt; - - 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; - fin->fin_id = ip->ip_id; -#ifdef _KERNEL - fin->fin_icode = ipl_unreach; -#endif - fi->fi_v = ip->ip_v; - fi->fi_tos = ip->ip_tos; - fin->fin_hlen = hlen; - fin->fin_dlen = ip->ip_len - hlen; - tcp = (tcphdr_t *)((char *)ip + hlen); - icmp = (icmphdr_t *)tcp; - fin->fin_dp = (void *)tcp; - (*(((u_short *)fi) + 1)) = (*(((u_short *)ip) + 4)); - (*(((u_32_t *)fi) + 1)) = (*(((u_32_t *)ip) + 3)); - (*(((u_32_t *)fi) + 2)) = (*(((u_32_t *)ip) + 4)); - - fi->fi_fl = (hlen > sizeof(ip_t)) ? FI_OPTIONS : 0; - off = (ip->ip_off & 0x1fff) << 3; - if (ip->ip_off & 0x3fff) - fi->fi_fl |= FI_FRAG; - switch (ip->ip_p) - { - case IPPROTO_ICMP : - { - int minicmpsz = sizeof(struct icmp); - - if (!off && ip->ip_len > ICMP_MINLEN + hlen && - (icmp->icmp_type == ICMP_ECHOREPLY || - icmp->icmp_type == ICMP_UNREACH)) - minicmpsz = ICMP_MINLEN; - if ((!(ip->ip_len >= hlen + minicmpsz) && !off) || - (off && off < sizeof(struct icmp))) - fi->fi_fl |= FI_SHORT; - if (fin->fin_dlen > 1) - fin->fin_data[0] = *(u_short *)tcp; - break; - } - case IPPROTO_TCP : - fi->fi_fl |= FI_TCPUDP; - 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; - 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; - } - - - for (s = (u_char *)(ip + 1), hlen -= sizeof(*ip); hlen; ) { - if (!(opt = *s)) - break; - ol = (opt == IPOPT_NOP) ? 1 : (int)*(s+1); - if (opt > 1 && (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. - */ -static int fr_tcpudpchk(fr, fin) -frentry_t *fr; -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)fr->fr_dcmp)) { - po = fr->fr_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 <= fr->fr_dtop)) - err = 0; - else if (!--i && /* In range */ - (tup <= po || tup >= fr->fr_dtop)) - err = 0; - } - /* - * compare source ports - */ - if (err && (i = (int)fr->fr_scmp)) { - po = fr->fr_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 <= fr->fr_stop)) - err = 0; - else if (!--i && /* In range */ - (tup <= po || tup >= fr->fr_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 !(fr->fr_tcpf | fr->fr_tcpfm); - /* - * Match the flags ? If not, abort this match. - */ - if (fr->fr_tcpf && - fr->fr_tcpf != (fin->fin_tcpf & fr->fr_tcpfm)) { - FR_DEBUG(("f. %#x & %#x != %#x\n", fin->fin_tcpf, - fr->fr_tcpfm, fr->fr_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) -int 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; - - fr = fin->fin_fr; - fin->fin_fr = NULL; - fin->fin_rule = 0; - fin->fin_group = 0; - off = ip->ip_off & 0x1fff; - 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 (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[0] & lm[0]) != ld[0]); - FR_IFDEBUG(i,continue,("0. %#08x & %#08x != %#08x\n", - lip[0], lm[0], ld[0])); - i |= ((lip[1] & lm[1]) != ld[1]) << 21; - FR_IFDEBUG(i,continue,("1. %#08x & %#08x != %#08x\n", - lip[1], lm[1], ld[1])); - i |= ((lip[2] & lm[2]) != ld[2]) << 22; - FR_IFDEBUG(i,continue,("2. %#08x & %#08x != %#08x\n", - lip[2], lm[2], ld[2])); - i |= ((lip[3] & lm[3]) != ld[3]); - FR_IFDEBUG(i,continue,("3. %#08x & %#08x != %#08x\n", - lip[3], lm[3], ld[3])); - i |= ((lip[4] & lm[4]) != ld[4]); - FR_IFDEBUG(i,continue,("4. %#08x & %#08x != %#08x\n", - lip[4], lm[4], ld[4])); - i ^= (fi->fi_fl & (FR_NOTSRCIP|FR_NOTDSTIP)); - 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, 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... - */ - if (!(skip = fr->fr_skip)) - pass = fr->fr_flags; - if ((pass & FR_CALLNOW) && fr->fr_func) - pass = (*fr->fr_func)(pass, ip, fin); -#ifdef IPFILTER_LOG - if ((pass & FR_LOGMASK) == FR_LOG) { - if (!IPLLOG(fr->fr_flags, ip, fin, m)) - frstats[fin->fin_out].fr_skip++; - frstats[fin->fin_out].fr_pkl++; - } -#endif /* IPFILTER_LOG */ - FR_DEBUG(("pass %#x\n", pass)); - 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; - fin->fin_fr = fr; - 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_QUICK) - break; - } - return pass; -} - - -/* - * frcheck - filter check - * check using source and destination addresses/pors 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; - frentry_t *fr = NULL; - int pass, changed, apass, error = EHOSTUNREACH; -#if !SOLARIS || !defined(_KERNEL) - register mb_t *m = *mp; -#endif - -#ifdef _KERNEL - 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 */ - - if ((ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP || - ip->ip_p == IPPROTO_ICMP)) { - int plen = 0; - - switch(ip->ip_p) - { - case IPPROTO_TCP: - plen = sizeof(tcphdr_t); - break; - case IPPROTO_UDP: - plen = sizeof(udphdr_t); - break; - case IPPROTO_ICMP: - /* 96 - enough for complete ICMP error IP header */ - plen = sizeof(struct icmp) + sizeof(ip_t) + 8; - break; - } - up = MIN(hlen + plen, ip->ip_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)) { - frstats[out].fr_pull[1]++; - return -1; - } - m_copydata(m, 0, up, hbuf); - frstats[out].fr_pull[0]++; - ip = (ip_t *)hbuf; -#else -# ifndef linux - if ((*mp = m_pullup(m, up)) == 0) { - frstats[out].fr_pull[1]++; - return -1; - } else { - frstats[out].fr_pull[0]++; - m = *mp; - ip = mtod(m, ip_t *); - } -# endif -#endif - } else - up = 0; - } else - up = 0; -# endif -# if SOLARIS - mb_t *m = qif->qf_m; -# endif -#endif - fr_makefrip(hlen, ip, fin); - fin->fin_ifp = ifp; - fin->fin_out = out; - fin->fin_mp = mp; - - MUTEX_ENTER(&ipf_mutex); - - /* - * 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) { - changed = ip_natin(ip, hlen, fin); - if (!apass && (fin->fin_fr = ipacct[0][fr_active]) && - (FR_SCANLIST(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT)) - frstats[0].fr_acct++; - } - - if (apass || (!(pass = ipfr_knownfrag(ip, fin)) && - !(pass = 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); - frstats[out].fr_chit++; - if ((fr = fin->fin_fr)) { - fr->fr_hits++; - pass = fr->fr_flags; - } else - pass = fr_pass; - } else { - pass = fr_pass; - if ((fin->fin_fr = ipfilter[out][fr_active])) - pass = FR_SCANLIST(fr_pass, ip, fin, m); - bcopy((char *)fin, (char *)fc, FI_COPYSIZE); - if (pass & FR_NOMATCH) - 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(m, fin, ip, qif) != 0) -#ifdef _KERNEL - m = *mp = NULL; -#else - ; -#endif - - if (pass & FR_PREAUTH) { - MUTEX_ENTER(&ipf_auth); - if ((fin->fin_fr = ipauth) && - (pass = FR_SCANLIST(0, ip, fin, m))) - fr_authstats.fas_hits++; - else - fr_authstats.fas_miss++; - MUTEX_EXIT(&ipf_auth); - } - - if (pass & FR_KEEPFRAG) { - if (fin->fin_fi.fi_fl & FI_FRAG) { - if (ipfr_newfrag(ip, fin, pass) == -1) - frstats[out].fr_bnfr++; - else - frstats[out].fr_nfr++; - } else - frstats[out].fr_cfr++; - } - if (pass & FR_KEEPSTATE) { - if (fr_addstate(ip, fin, pass) == -1) - frstats[out].fr_bads++; - else - frstats[out].fr_ads++; - } - } - - 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)) { - if ((fin->fin_fr = ipacct[1][fr_active]) && - (FR_SCANLIST(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT)) - frstats[1].fr_acct++; - fin->fin_fr = NULL; - changed = ip_natout(ip, hlen, fin); - } - fin->fin_fr = fr; - MUTEX_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; - 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; - 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; - frstats[out].fr_bpkl++; -logit: - if (!IPLLOG(pass, ip, fin, m)) { - frstats[out].fr_skip++; - if ((pass & (FR_PASS|FR_LOGORBLOCK)) == - (FR_PASS|FR_LOGORBLOCK)) - pass ^= FR_PASS|FR_BLOCK; - } - } - } -#endif /* IPFILTER_LOG */ -#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) - frstats[out].fr_pass++; - else if (pass & FR_BLOCK) { - 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) { -# if SOLARIS - ICMP_ERROR(q, ip, ICMP_UNREACH, fin->fin_icode, - qif, ip->ip_src); -# else - ICMP_ERROR(m, ip, ICMP_UNREACH, fin->fin_icode, - ifp, ip->ip_src); - m = *mp = NULL; /* freed by icmp_error() */ -# endif - - frstats[0].fr_ret++; - } else if ((pass & FR_RETRST) && - !(fin->fin_fi.fi_fl & FI_SHORT)) { - if (SEND_RESET(ip, qif, ifp) == 0) - frstats[1].fr_ret++; - } -#else - if (pass & FR_RETICMP) { - verbose("- ICMP unreachable sent\n"); - frstats[0].fr_ret++; - } else if ((pass & FR_RETRST) && - !(fin->fin_fi.fi_fl & FI_SHORT)) { - verbose("- TCP RST sent\n"); - 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 defined(_KERNEL) -# if !SOLARIS -# if !defined(linux) - if (fr) { - frdest_t *fdp = &fr->fr_tif; - - if ((pass & FR_FASTROUTE) || - (fdp->fd_ifp && fdp->fd_ifp != (struct ifnet *)-1)) { - ipfr_fastroute(m, fin, fdp); - 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 */ - return (pass & FR_PASS) ? 0 : error; -# else /* !SOLARIS */ - if (fr) { - frdest_t *fdp = &fr->fr_tif; - - if ((pass & FR_FASTROUTE) || - (fdp->fd_ifp && fdp->fd_ifp != (struct ifnet *)-1)) { - ipfr_fastroute(qif, ip, m, mp, fin, fdp); - m = *mp = NULL; - } - if (mc) - ipfr_fastroute(qif, ip, mc, mp, fin, &fr->fr_dif); - } - return (pass & FR_PASS) ? changed : error; -# endif /* !SOLARIS */ -#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, len) -mb_t *m; -ip_t *ip; -tcphdr_t *tcp; -int len; -{ - union { - u_char c[2]; - u_short s; - } bytes; - u_32_t sum; - u_short *sp; -# if SOLARIS || defined(__sgi) - int add, hlen; -# endif - -# if SOLARIS - /* skip any leading M_PROTOs */ - while(m && (MTYPE(m) != M_DATA)) - m = m->b_cont; - PANIC((!m),("fr_tcpsum: no M_DATA")); -# endif - - /* - * Add up IP Header portion - */ - bytes.c[0] = 0; - bytes.c[1] = IPPROTO_TCP; - len -= (ip->ip_hl << 2); - sum = bytes.s; - sum += htons((u_short)len); - sp = (u_short *)&ip->ip_src; - sum += *sp++; - sum += *sp++; - sum += *sp++; - sum += *sp++; - if (sp != (u_short *)tcp) - sp = (u_short *)tcp; - sum += *sp++; - sum += *sp++; - sum += *sp++; - sum += *sp++; - sum += *sp++; - sum += *sp++; - sum += *sp++; - sum += *sp; - sp += 2; /* Skip over checksum */ - sum += *sp++; - -#if SOLARIS - /* - * In case we had to copy the IP & TCP header out of mblks, - * skip over the mblk bits which are the header - */ - if ((caddr_t)ip != (caddr_t)m->b_rptr) { - hlen = (caddr_t)sp - (caddr_t)ip; - while (hlen) { - add = MIN(hlen, m->b_wptr - m->b_rptr); - sp = (u_short *)((caddr_t)m->b_rptr + add); - hlen -= add; - if ((caddr_t)sp >= (caddr_t)m->b_wptr) { - m = m->b_cont; - PANIC((!m),("fr_tcpsum: not enough data")); - if (!hlen) - sp = (u_short *)m->b_rptr; - } - } - } -#endif -#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; - PANIC((!m),("fr_tcpsum: not enough data")); - if (!hlen) - sp = mtod(m, u_short *); - } - } - } -#endif - - if (!(len -= sizeof(*tcp))) - goto nodata; - while (len > 0) { -#if SOLARIS - while ((caddr_t)sp >= (caddr_t)m->b_wptr) { - m = m->b_cont; - PANIC((!m),("fr_tcpsum: not enough data")); - sp = (u_short *)m->b_rptr; - } -#else - while (((caddr_t)sp - mtod(m, caddr_t)) >= m->m_len) - { - m = m->m_next; - PANIC((!m),("fr_tcpsum: not enough data")); - sp = mtod(m, u_short *); - } -#endif /* SOLARIS */ - if (len < 2) - break; - if((u_32_t)sp & 1) { - bcopy((char *)sp++, (char *)&bytes.s, sizeof(bytes.s)); - sum += bytes.s; - } else - sum += *sp++; - len -= 2; - } - if (len) { - bytes.c[1] = 0; - bytes.c[0] = *(u_char *)sp; - sum += bytes.s; - } -nodata: - sum = (sum >> 16) + (sum & 0xffff); - sum += (sum >> 16); - sum = (u_short)((~sum) & 0xffff); - return sum; -} - - -#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 - * $FreeBSD$ - */ -/* - * 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_short num; -u_32_t flags; -int which, 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; - - 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_short num; -frentry_t *fp; -int which, set; -{ - frgroup_t *fg, **fgp; - - if ((fg = fr_findgroup(num, fp->fr_flags, which, set, &fgp))) - return fg; - - KMALLOC(fg, frgroup_t *, sizeof(*fg)); - 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_short num; -u_32_t flags; -int which, 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, list, listp) -int set, unit, *nfreedp; -frentry_t *list, **listp; -{ - register frentry_t *fp = list, *fpn; - register int freed = 0; - - while (fp) { - fpn = fp->fr_next; - if (fp->fr_grp) { - fp->fr_ref -= frflushlist(set, unit, nfreedp, - fp->fr_grp, &fp->fr_grp); - } - - if (fp->fr_ref == 1) { - if (fp->fr_grhead) - fr_delgroup(fp->fr_grhead, fp->fr_flags, unit, - set); - KFREE(fp); - *listp = fpn; - freed++; - } - fp = fpn; - } - *nfreedp += freed; - return freed; -} - - -void frflush(unit, result) -int unit; -int *result; -{ - int flags = *result, flushed = 0, set = fr_active; - - bzero((char *)frcache, sizeof(frcache[0]) * 2); - - if (flags & FR_INACTIVE) - set = 1 - set; - - if (unit == IPL_LOGIPF) { - if (flags & FR_OUTQUE) { - (void) frflushlist(set, unit, &flushed, - ipfilter[1][set], - &ipfilter[1][set]); - (void) frflushlist(set, unit, &flushed, - ipacct[1][set], &ipacct[1][set]); - } - if (flags & FR_INQUE) { - (void) frflushlist(set, unit, &flushed, - ipfilter[0][set], - &ipfilter[0][set]); - (void) frflushlist(set, unit, &flushed, - ipacct[0][set], &ipacct[0][set]); - } - } - - *result = flushed; -} diff --git a/sys/contrib/ipfilter/netinet/ip_auth.c b/sys/contrib/ipfilter/netinet/ip_auth.c deleted file mode 100644 index 4afda70..0000000 --- a/sys/contrib/ipfilter/netinet/ip_auth.c +++ /dev/null @@ -1,508 +0,0 @@ -/* - * Copyright (C) 1997 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[] = "@(#)$FreeBSD$"; -#endif - -#if defined(KERNEL) && !defined(_KERNEL) -#define _KERNEL -#endif -#define __FreeBSD_version 300000 /* just a hack - no <sys/osreldate.h> */ - -#if !defined(_KERNEL) && !defined(KERNEL) -# include <stdlib.h> -# include <string.h> -#endif -#include <sys/errno.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/time.h> -#include <sys/file.h> -#if 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__) -# ifndef linux -# include <sys/mbuf.h> -# endif -#else -# include <sys/filio.h> -# include <sys/byteorder.h> -# include <sys/dditypes.h> -# include <sys/stream.h> -# include <sys/kmem.h> -#endif -#if defined(KERNEL) && (__FreeBSD_version >= 300000) -# include <sys/malloc.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 -#if !defined(KERNEL) && (__FreeBSD_version >= 300000) -# include <net/if_var.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 -# 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 (SOLARIS || defined(__sgi)) && defined(_KERNEL) -extern kmutex_t ipf_auth; -# 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; -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. - */ -int fr_checkauth(ip, fin) -ip_t *ip; -fr_info_t *fin; -{ - u_short id = ip->ip_id; - u_32_t pass; - int i; - - MUTEX_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; - 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; - } - } - MUTEX_EXIT(&ipf_auth); - return pass; - } - i++; - if (i == FR_NUMAUTH) - i = 0; - } - fr_authstats.fas_miss++; - MUTEX_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 -#if defined(_KERNEL) && SOLARIS -, qif) -qif_t *qif; -#else -) -#endif -mb_t *m; -fr_info_t *fin; -ip_t *ip; -{ - int i; - - MUTEX_ENTER(&ipf_auth); - if ((fr_authstart > fr_authend) && (fr_authstart - fr_authend == -1)) { - fr_authstats.fas_nospace++; - MUTEX_EXIT(&ipf_auth); - return 0; - } - if (fr_authend - fr_authstart == FR_NUMAUTH - 1) { - fr_authstats.fas_nospace++; - MUTEX_EXIT(&ipf_auth); - return 0; - } - - fr_authstats.fas_added++; - fr_authused++; - i = fr_authend++; - if (fr_authend == FR_NUMAUTH) - fr_authend = 0; - MUTEX_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) -# endif - { - register u_short bo; - - bo = ip->ip_len; - ip->ip_len = htons(bo); -# if !SOLARIS /* 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) -# if !SOLARIS - struct ifqueue *ifq; - int s; -# endif -#endif - frauth_t auth, *au = &auth; - frauthent_t *fae, **faep; - int i, error = 0; - - switch (cmd) - { - case SIOCINIFR : - case SIOCRMIFR : - case SIOCADIFR : - error = EINVAL; - break; - case SIOCINAFR : - 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 { - *faep = fae->fae_next; - *frptr = fr->fr_next; - KFREE(fae); - } - } else { - KMALLOC(fae, frauthent_t *, sizeof(*fae)); - if (fae != NULL) { - IRCOPY((char *)data, (char *)&fae->fae_fr, - sizeof(fae->fae_fr)); - if (!fae->fae_age) - 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; - } else - error = ENOMEM; - } - break; - case SIOCATHST: - IWCOPY((char *)&fr_authstats, data, sizeof(fr_authstats)); - break; - case SIOCAUTHW: -fr_authioctlloop: - MUTEX_ENTER(&ipf_auth); - if ((fr_authnext != fr_authend) && fr_authpkts[fr_authnext]) { - IWCOPY((char *)&fr_auth[fr_authnext++], data, - sizeof(fr_info_t)); - if (fr_authnext == FR_NUMAUTH) - fr_authnext = 0; - MUTEX_EXIT(&ipf_auth); - return 0; - } -#ifdef _KERNEL -# if SOLARIS - if (!cv_wait_sig(&ipfauthwait, &ipf_auth)) { - mutex_exit(&ipf_auth); - return EINTR; - } -# else -# ifdef linux - interruptible_sleep_on(&ipfauthwait); - if (current->signal & ~current->blocked) - error = -EINTR; -# else - error = SLEEP(&fr_authnext, "fr_authnext"); -# endif -# endif -#endif - MUTEX_EXIT(&ipf_auth); - if (!error) - goto fr_authioctlloop; - break; - case SIOCAUTHR: - IRCOPY(data, (caddr_t)&auth, sizeof(auth)); - MUTEX_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)) { - MUTEX_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 - MUTEX_EXIT(&ipf_auth); - SPL_NET(s); -# ifndef linux - if (m && au->fra_info.fin_out) { -# if SOLARIS - error = fr_qout(fr_auth[i].fra_q, m); -# else /* SOLARIS */ - error = ip_output(m, NULL, NULL, IP_FORWARDING, NULL); -# 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 - SPL_X(s); -#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; - - MUTEX_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); - } - MUTEX_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 - - SPL_NET(s); - MUTEX_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 (!--fra->fra_age) { - *faep = fae->fae_next; - KFREE(fae); - fr_authstats.fas_expire++; - } else - faep = &fae->fae_next; - } - MUTEX_EXIT(&ipf_auth); - SPL_X(s); -} -#endif diff --git a/sys/contrib/ipfilter/netinet/ip_auth.h b/sys/contrib/ipfilter/netinet/ip_auth.h deleted file mode 100644 index 72e51b2..0000000 --- a/sys/contrib/ipfilter/netinet/ip_auth.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 1997 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. - * - * $FreeBSD$ - * - */ -#ifndef __IP_AUTH_H__ -#define __IP_AUTH_H__ - -#define FR_NUMAUTH 32 - -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; -} fr_authstat_t; - -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; - - -extern frentry_t *ipauth; -extern struct fr_authstat fr_authstats; -extern int fr_defaultauthage; -extern int fr_authstart; -extern int fr_authend; -extern int fr_authsize; -extern int fr_authused; -extern int fr_checkauth __P((ip_t *, fr_info_t *)); -extern void fr_authexpire __P((void)); -extern void fr_authunload __P((void)); -extern mb_t *fr_authpkts[]; -#if defined(_KERNEL) && SOLARIS -extern int fr_newauth __P((mb_t *, fr_info_t *, ip_t *, qif_t *)); -#else -extern int fr_newauth __P((mb_t *, fr_info_t *, ip_t *)); -#endif -#if defined(__NetBSD__) || defined(__OpenBSD__) || (__FreeBSD_version >= 300003) -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/sys/contrib/ipfilter/netinet/ip_compat.h b/sys/contrib/ipfilter/netinet/ip_compat.h deleted file mode 100644 index e3fd1fe..0000000 --- a/sys/contrib/ipfilter/netinet/ip_compat.h +++ /dev/null @@ -1,727 +0,0 @@ -/* - * Copyright (C) 1993-1997 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 - * $FreeBSD$ - */ - -#ifndef __IP_COMPAT_H__ -#define __IP_COMPAT_H__ - -#ifndef __P -# ifdef __STDC__ -# define __P(x) x -# else -# define __P(x) () -# define const -# endif -#endif - -#ifndef SOLARIS -#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4))) -#endif - -#if defined(_KERNEL) && !defined(KERNEL) -# define KERNEL -#endif -#if defined(KERNEL) && !defined(_KERNEL) -# define _KERNEL -#endif -#if!defined(__KERNEL__) && defined(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 - -#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/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 -# include <inet/common.h> -# include <inet/ip.h> -# include <inet/ip_ire.h> -# undef _KERNEL -# else /* _KERNEL */ -# include <inet/common.h> -# include <inet/ip.h> -# include <inet/ip_ire.h> -# endif /* _KERNEL */ -#endif /* SOLARIS */ -#define IPMINLEN(i, h) ((i)->ip_len >= ((i)->ip_hl * 4 + sizeof(struct h))) - -#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; -#else -/* - * Really, any arch where sizeof(long) != sizeof(int). - */ -# if defined(__alpha__) || defined(__alpha) -typedef unsigned int u_32_t; -# else -typedef unsigned long u_32_t; -# endif -#endif /* __NetBSD__ || __OpenBSD__ || __FreeBSD__ || __sgi */ - -#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) -# if __FreeBSD__ < 3 -# include <machine/spl.h> -# endif -# if defined(IPFILTER_LKM) && !defined(ACTUALLY_LKM_NOT_KERNEL) -# define ACTUALLY_LKM_NOT_KERNEL -# endif -#endif /* __FreeBSD__ && KERNEL */ - -/* - * Build some macros and #defines to enable the same code to compile anywhere - * Well, that's the idea, anyway :-) - */ -#ifdef KERNEL -# if SOLARIS -# define MUTEX_ENTER(x) mutex_enter(x) -# define MUTEX_EXIT(x) mutex_exit(x) -# define MTOD(m,t) (t)((m)->b_rptr) -# define IRCOPY(a,b,c) copyin((a), (b), (c)) -# define IWCOPY(a,b,c) copyout((a), (b), (c)) -# define 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,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. */ - int qf_off; - int qf_len; /* this field is used for in ipfr_fastroute */ - char qf_name[8]; - /* - * in case the ILL has disappeared... - */ - int qf_hl; /* header length */ -} qif_t; -extern ill_t *get_unit __P((char *)); -# define GETUNIT(n) get_unit((n)) -# else /* SOLARIS */ -# if defined(__sgi) -# include <sys/ksynch.h> -# define IPF_LOCK_PL plhi -# include <sys/sema.h> -#undef kmutex_t -typedef struct { - lock_t *l; - int pl; -} kmutex_t; -# define MUTEX_ENTER(x) (x)->pl = LOCK((x)->l, IPF_LOCK_PL); -# define MUTEX_EXIT(x) UNLOCK((x)->l, (x)->pl); -# else /* __sgi */ -# define MUTEX_ENTER(x) ; -# define MUTEX_EXIT(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)) -# define IWCOPY(a,b,c) bcopy((a), (b), (c)) -# endif /* !linux */ -# endif /* SOLARIS */ - -# ifdef sun -# if !SOLARIS -# include <sys/kmem_alloc.h> -# define GETUNIT(n) ifunit((n), IFNAMSIZ) -# endif -# else -# ifndef linux -# define GETUNIT(n) ifunit((n)) -# 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,c) (a) = (b)kmem_alloc((c), KM_NOSLEEP) -# define GET_MINOR(x) getminor(x) -# else -# if !SOLARIS -# define KMALLOC(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, 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, 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 MUTEX_ENTER(x) ; -# define MUTEX_EXIT(x) ; -# define SPL_NET(x) ; -# define SPL_IMP(x) ; -# undef SPL_X -# define SPL_X(x) ; -# define KMALLOC(a,b,c) (a) = (b)malloc(c) -# define KFREE(x) free(x) -# define KFREES(x,s) free(x) -# define GETUNIT(x) get_unit(x) -# define IRCOPY(a,b,c) bcopy((a), (b), (c)) -# define IWCOPY(a,b,c) bcopy((a), (b), (c)) -#endif /* KERNEL */ - -#if SOLARIS -typedef mblk_t mb_t; -#else -# ifdef linux -typedef struct sk_buff mb_t; -# 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 -/* - * 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. - */ -#define FWRITE WRITE -#define FREAD READ -/* - * mbuf related problems. - */ -#define mtod(m,t) (t)((m)->data) -#define m_len len -#define m_next next - -#define IP_DF 0x8000 - -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_hl:4; - __u8 ip_v: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 { - u_char icmp_type; /* type of message, see below */ - u_char icmp_code; /* type sub code */ - u_short icmp_cksum; /* ones complement cksum of struct */ - union { - u_char ih_pptr; /* ICMP_PARAMPROB */ - struct in_addr ih_gwaddr; /* ICMP_REDIRECT */ - struct ih_idseq { - n_short icd_id; - n_short 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) 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,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(a,b,c) { \ - error = verify_area(VERIFY_READ, (a) ,(c)); \ - if (!error) \ - memcpy_fromfs((b), (a), (c)); \ - } -# define IWCOPY(a,b,c) { \ - error = verify_area(VERIFY_WRITE, (b), (c)); \ - if (!error) \ - memcpy_tofs((b), (a), (c)); \ - } -# 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 - -#endif /* __IP_COMPAT_H__ */ diff --git a/sys/contrib/ipfilter/netinet/ip_fil.c b/sys/contrib/ipfilter/netinet/ip_fil.c deleted file mode 100644 index 2dbea5d..0000000 --- a/sys/contrib/ipfilter/netinet/ip_fil.c +++ /dev/null @@ -1,1255 +0,0 @@ -/* - * Copyright (C) 1993-1997 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-1995 Darren Reed"; -static const char rcsid[] = "@(#)$FreeBSD$"; -#endif - -#include "opt_ipfilter.h" - -#ifndef SOLARIS -#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4))) -#endif - -#if defined(KERNEL) && !defined(_KERNEL) -# define _KERNEL -#endif -#ifdef __FreeBSD__ -# if defined(_KERNEL) && !defined(IPFILTER_LKM) -# define __FreeBSD_version 300000 /* this will do as a hack */ -# else -# include <osreldate.h> -# endif -#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/param.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 >= 220000 -# 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> -# include <sys/malloc.h> -#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 <syslog.h> -#endif -#include "netinet/ip_compat.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" -#ifndef MIN -#define MIN(a,b) (((a)<(b))?(a):(b)) -#endif -#if !SOLARIS && defined(_KERNEL) -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) -static int (*fr_saveslowtimo) __P((void)); -# else -static void (*fr_saveslowtimo) __P((void)); -# endif -# if (BSD < 199306) || defined(__sgi) -extern int tcp_ttl; -# endif -#endif - -int ipl_inited = 0; -int ipl_unreach = ICMP_UNREACH_FILTER; -u_long ipl_frouteok[2] = {0, 0}; - -static void fixskip __P((frentry_t **, frentry_t *, int)); -static void frzerostats __P((caddr_t)); -static void frsync __P((void)); -#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 **)); -#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 - -#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; -{ - iplattach(); -} -# endif - - -int iplattach() -{ - char *defpass; - int s; -# ifdef __sgi - int error; -# endif - - SPL_NET(s); - if (ipl_inited || (fr_checkp == fr_check)) { - printf("IP Filter: already initialized\n"); - SPL_X(s); - return EBUSY; - } - -# ifdef NETBSD_PF - pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT); -# endif - -# ifdef __sgi - error = ipfilter_sgi_attach(); - if (error) { - SPL_X(s); - return error; - } -# endif - - ipl_inited = 1; - bzero((char *)frcache, sizeof(frcache)); - bzero((char *)nat_table, sizeof(nat_table)); - fr_savep = fr_checkp; - fr_checkp = fr_check; - fr_saveslowtimo = inetsw[0].pr_slowtimo; - inetsw[0].pr_slowtimo = ipfr_slowtimer; - -# ifdef IPFILTER_LOG - ipflog_init(); -# endif - SPL_X(s); - if (fr_pass & FR_PASS) - defpass = "pass"; - else if (fr_pass & FR_BLOCK) - defpass = "block"; - else - defpass = "no-match -> block"; - - printf("IP Filter: initialized. Default = %s all, Logging = %s\n", - defpass, -# ifdef IPFILTER_LOG - "enabled"); -# else - "disabled"); -# 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; - - SPL_NET(s); - if (!ipl_inited) - { - printf("IP Filter: not initialized\n"); - SPL_X(s); - return 0; - } - - fr_checkp = fr_savep; - inetsw[0].pr_slowtimo = fr_saveslowtimo; - frflush(IPL_LOGIPF, &i); - ipl_inited = 0; - -# ifdef NETBSD_PF - pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT); -# endif - -# ifdef __sgi - ipfilter_sgi_detach(); -# endif - - ipfr_unload(); - ip_natunload(); - fr_stateunload(); - fr_authunload(); - - SPL_X(s); - return 0; -} -#endif /* _KERNEL */ - - -static void frzerostats(data) -caddr_t data; -{ - struct friostat fio; - - bcopy((char *)frstats, (char *)fio.f_st, - sizeof(struct filterstats) * 2); - fio.f_fin[0] = ipfilter[0][0]; - fio.f_fin[1] = ipfilter[0][1]; - fio.f_fout[0] = ipfilter[1][0]; - fio.f_fout[1] = ipfilter[1][1]; - fio.f_acctin[0] = ipacct[0][0]; - fio.f_acctin[1] = ipacct[0][1]; - fio.f_acctout[0] = ipacct[1][0]; - fio.f_acctout[1] = ipacct[1][1]; - fio.f_active = fr_active; - fio.f_froute[0] = ipl_frouteok[0]; - fio.f_froute[1] = ipl_frouteok[1]; - IWCOPY((caddr_t)&fio, data, sizeof(fio)); - bzero((char *)frstats, sizeof(*frstats) * 2); -} - - -/* - * 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 ((_BSDI_VERSION >= 199510) || (BSD >= 199506) || (NetBSD >= 199511) || \ - (__FreeBSD_version >= 220000)) && defined(_KERNEL) -, p) -struct proc *p; -#else -) -#endif -dev_t dev; -#if defined(__NetBSD__) || defined(__OpenBSD__) || \ - (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300003) -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; - -#ifdef _KERNEL - unit = GET_MINOR(dev); - if ((IPL_LOGMAX < unit) || (unit < 0)) - return ENXIO; -#endif - - SPL_NET(s); - - if (unit == IPL_LOGNAT) { - error = nat_ioctl(data, cmd, mode); - SPL_X(s); - return error; - } - if (unit == IPL_LOGSTATE) { - error = fr_state_ioctl(data, cmd, mode); - SPL_X(s); - return error; - } - switch (cmd) { - case FIONREAD : -#ifdef IPFILTER_LOG - 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 { - IRCOPY(data, (caddr_t)&enable, sizeof(enable)); - if (enable) - error = iplattach(); - else - error = ipldetach(); - } - break; - } -#endif - case SIOCSETFF : - if (!(mode & FWRITE)) - error = EPERM; - else - IRCOPY(data, (caddr_t)&fr_flags, sizeof(fr_flags)); - break; - case SIOCGETFF : - 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 : - { - struct friostat fio; - - bcopy((char *)frstats, (char *)fio.f_st, - sizeof(struct filterstats) * 2); - fio.f_fin[0] = ipfilter[0][0]; - fio.f_fin[1] = ipfilter[0][1]; - fio.f_fout[0] = ipfilter[1][0]; - fio.f_fout[1] = ipfilter[1][1]; - fio.f_acctin[0] = ipacct[0][0]; - fio.f_acctin[1] = ipacct[0][1]; - fio.f_acctout[0] = ipacct[1][0]; - fio.f_acctout[1] = ipacct[1][1]; - fio.f_auth = ipauth; - fio.f_active = fr_active; - fio.f_froute[0] = ipl_frouteok[0]; - fio.f_froute[1] = ipl_frouteok[1]; - IWCOPY((caddr_t)&fio, data, sizeof(fio)); - break; - } - case SIOCFRZST : - if (!(mode & FWRITE)) - error = EPERM; - else - frzerostats(data); - break; - case SIOCIPFFL : - if (!(mode & FWRITE)) - error = EPERM; - else { - IRCOPY(data, (caddr_t)&tmp, sizeof(tmp)); - frflush(unit, &tmp); - IWCOPY((caddr_t)&tmp, data, sizeof(tmp)); - } - break; -#ifdef IPFILTER_LOG - case SIOCIPFFB : - if (!(mode & FWRITE)) - error = EPERM; - else - *(int *)data = ipflog_clear(unit); - break; -#endif /* IPFILTER_LOG */ - case SIOCGFRST : - IWCOPY((caddr_t)ipfr_fragstats(), data, sizeof(ipfrstat_t)); - break; - case SIOCAUTHW : - case SIOCAUTHR : - if (!(mode & FWRITE)) { - error = EPERM; - break; - } - case SIOCATHST : - error = fr_auth_ioctl(data, cmd, NULL, NULL); - 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; -} - - -static void frsync() -{ -#ifdef _KERNEL - struct ifnet *ifp; - -# if (__FreeBSD_version >= 300000) - for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next) -# elif defined(__OpenBSD__) || (NetBSD >= 199511) - for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next) -# else - for (ifp = ifnet; ifp; ifp = ifp->if_next) -# endif - ip_natsync(ifp); -#endif -} - - -static 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; -} - - -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; - int error = 0, in, group; - - fp = &frd; - IRCOPY(data, (caddr_t)fp, sizeof(*fp)); - - /* - * Check that the group number does exist and that if a head group - * has been specified, doesn't exist. - */ - if (fp->fr_grhead && - fr_findgroup(fp->fr_grhead, fp->fr_flags, unit, set, NULL)) - return EEXIST; - if (fp->fr_group && - !fr_findgroup(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) - ftail = fprev = &ipacct[in][set]; - else if (fp->fr_flags & (FR_OUTQUE|FR_INQUE)) - ftail = fprev = &ipfilter[in][set]; - 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); - if (!fp->fr_ifa) - fp->fr_ifa = (void *)-1; - } - - fdp = &fp->fr_dif; - fp->fr_flags &= ~FR_DUP; - if (*fdp->fd_ifname) { - fdp->fd_ifp = GETUNIT(fdp->fd_ifname); - 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); - 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 (; (f = *ftail); ftail = &f->fr_next) - if (bcmp((char *)&f->fr_ip, (char *)&fp->fr_ip, - FR_CMPSIZ) == 0) - break; - - /* - * If zero'ing statistics, copy current to caller and zero. - */ - if (req == SIOCZRLST) { - if (!f) - return ESRCH; - IWCOPY((caddr_t)f, data, sizeof(*f)); - f->fr_hits = 0; - f->fr_bytes = 0; - return 0; - } - - if (!f) { - ftail = fprev; - if (req != SIOCINAFR && req != SIOCINIFR) - while ((f = *ftail)) - ftail = &f->fr_next; - else if (fp->fr_hits) - while (--fp->fr_hits && (f = *ftail)) - ftail = &f->fr_next; - f = NULL; - } - - if (req == SIOCDELFR || req == SIOCRMIFR) { - if (!f) - error = ESRCH; - else { - if (f->fr_ref > 1) - 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(f->fr_grhead, fp->fr_flags, unit, - set); - fixskip(fprev, f, -1); - *ftail = f->fr_next; - KFREE(f); - } - } else { - if (f) - error = EEXIST; - else { - if (unit == IPL_LOGAUTH) - return fr_auth_ioctl(data, req, f, ftail); - KMALLOC(f, frentry_t *, sizeof(*f)); - 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(_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(_KERNEL) -, devtype, p) -int devtype; -struct proc *p; -# else -) -# endif -dev_t dev; -int flags; -#endif /* __sgi */ -{ - u_int min = GET_MINOR(dev); - - if (2 < 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(ti) -struct tcpiphdr *ti; -{ - struct tcpiphdr *tp; - struct tcphdr *tcp; - struct mbuf *m; - int tlen = 0, err; - ip_t *ip; -# if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000) - struct route ro; -# endif - - if (ti->ti_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); - m->m_data += max_linkhdr; -# endif - if (m == NULL) - return -1; - - if (ti->ti_flags & TH_SYN) - tlen = 1; - m->m_len = sizeof (struct tcpiphdr); -# if BSD >= 199306 - m->m_pkthdr.len = sizeof (struct tcpiphdr); - m->m_pkthdr.rcvif = (struct ifnet *)0; -# endif - bzero(mtod(m, char *), sizeof(struct tcpiphdr)); - ip = mtod(m, struct ip *); - tp = mtod(m, struct tcpiphdr *); - tcp = (struct tcphdr *)((char *)ip + sizeof(struct ip)); - - ip->ip_src.s_addr = ti->ti_dst.s_addr; - ip->ip_dst.s_addr = ti->ti_src.s_addr; - tcp->th_dport = ti->ti_sport; - tcp->th_sport = ti->ti_dport; - tcp->th_ack = htonl(ntohl(ti->ti_seq) + tlen); - tcp->th_off = sizeof(struct tcphdr) >> 2; - tcp->th_flags = TH_RST|TH_ACK; - tp->ti_pr = ((struct ip *)ti)->ip_p; - tp->ti_len = htons(sizeof(struct tcphdr)); - tcp->th_sum = in_cksum(m, sizeof(struct tcpiphdr)); - - ip->ip_tos = ((struct ip *)ti)->ip_tos; - ip->ip_p = ((struct ip *)ti)->ip_p; - ip->ip_len = sizeof (struct tcpiphdr); -# if (BSD < 199306) || defined(__sgi) - ip->ip_ttl = tcp_ttl; -# else - ip->ip_ttl = ip_defttl; -# endif - -# if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000) - bzero((char *)&ro, sizeof(ro)); - err = ip_output(m, (struct mbuf *)0, &ro, 0, 0); - if (ro.ro_rt) - RTFREE(ro.ro_rt); -# else - /* - * extra 0 in case of multicast - */ - err = ip_output(m, (struct mbuf *)0, 0, 0, 0); -# endif - 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() -{ - (void) iplattach(); - 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; -} - - -void 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; - struct ifnet *ifp = fdp->fd_ifp; - int len, off, error = 0; - int hlen = fin->fin_hlen; - struct route iproute; - struct sockaddr_in *dst; - - ip = mtod(m0, struct ip *); - /* - * Route packet. - */ - ro = &iproute; - bzero((caddr_t)ro, sizeof (*ro)); - dst = (struct sockaddr_in *)&ro->ro_dst; - dst->sin_family = AF_INET; - dst->sin_addr = fdp->fd_ip.s_addr ? fdp->fd_ip : ip->ip_dst; -# ifdef __bsdi__ - 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 (!(fin->fin_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. - */ - (void) ip_natout(ip, hlen, fin); - if (fin->fin_out) - ip->ip_sum = 0; - /* - * If small enough for interface, can just send directly. - */ - if (ip->ip_len <= ifp->if_mtu) { -# 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); -# 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) { - MGET(m, M_DONTWAIT, MT_HEADER); - 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; - } -# 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; -bad: - m_freem(m); - goto done; -} -#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 -{ -# if !(defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ - (defined(OpenBSD) && (OpenBSD >= 199603)) - ip_t *ip = (ip_t *)m; -# endif -# else -static int write_output(ifp, ip) -struct ifnet *ifp; -ip_t *ip; -{ -# endif - FILE *fp; - char fname[32]; - -# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ - (defined(OpenBSD) && (OpenBSD >= 199603)) - snprintf(fname, sizeof(fname), "/tmp/%s", ifp->if_xname); - if ((fp = fopen(fname, "a"))) { - fclose(fp); - } -# else - snprintf(fname, sizeof(fname), "/tmp/%s%d", ifp->if_name, ifp->if_unit); - if ((fp = fopen(fname, "a"))) { - fwrite((char *)ip, ntohs(ip->ip_len), 1, fp); - fclose(fp); - } -# endif - return 0; -} - - -struct ifnet *get_unit(name) -char *name; -{ - 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) snprintf(ifname, sizeof(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); - ifneta[1] = NULL; - ifneta[0] = (struct ifnet *)calloc(1, sizeof(*ifp)); - nifs = 1; - } else { - nifs++; - ifneta = (struct ifnet **)realloc(ifneta, - (nifs + 1) * sizeof(*ifa)); - ifneta[nifs] = NULL; - ifneta[nifs - 1] = (struct ifnet *)malloc(sizeof(*ifp)); - } - 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() -{ - FILE *fp; - struct ifnet *ifp, **ifa; - char fname[32]; -# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ - (defined(OpenBSD) && (OpenBSD >= 199603)) - for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) { - ifp->if_output = write_output; - snprintf(fname, sizeof(fname), "/tmp/%s", ifp->if_xname); - if ((fp = fopen(fname, "w"))) - fclose(fp); - } -# else - - for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) { - ifp->if_output = write_output; - snprintf(fname, sizeof(fname), - "/tmp/%s%d", ifp->if_name, ifp->if_unit); - if ((fp = fopen(fname, "w"))) - fclose(fp); - } -# endif -} - - -void ipfr_fastroute(ip, fin, fdp) -ip_t *ip; -fr_info_t *fin; -frdest_t *fdp; -{ - struct ifnet *ifp = fdp->fd_ifp; - - if (!ifp) - return; /* 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 -} - - -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; -} -#endif /* _KERNEL */ diff --git a/sys/contrib/ipfilter/netinet/ip_fil.h b/sys/contrib/ipfilter/netinet/ip_fil.h deleted file mode 100644 index 79f6896..0000000 --- a/sys/contrib/ipfilter/netinet/ip_fil.h +++ /dev/null @@ -1,525 +0,0 @@ -/* - * Copyright (C) 1993-1997 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 _IOR('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) -#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 _IOR(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) -#endif -#define SIOCADDFR SIOCADAFR -#define SIOCDELFR SIOCRMAFR -#define SIOCINSFR SIOCINAFR - -typedef struct fr_ip { - u_int fi_v:4; /* IP version */ - u_int fi_fl:4; /* packet flags */ - u_char fi_tos; - u_char fi_ttl; - u_char fi_p; - struct in_addr fi_src; - struct in_addr fi_dst; - u_32_t fi_optmsk; /* bitmask composed from IP options */ - u_short fi_secmsk; /* bitmask composed from IP security options */ - u_short fi_auth; -} 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) - -typedef struct fr_info { - struct fr_ip fin_fi; - u_short fin_data[2]; - u_short fin_out; - u_short fin_hlen; - u_char fin_tcpf; - u_char fin_icode; /* From here on is packet specific */ - u_short fin_rule; - u_short fin_group; - u_short fin_dlen; - u_short fin_id; - void *fin_ifp; - struct frentry *fin_fr; - char *fin_dp; /* start of data past IP header */ - void *fin_mp; -} fr_info_t; - -/* - * Size for compares on fr_info structures - */ -#define FI_CSIZE (sizeof(struct fr_ip) + sizeof(u_short) * 4 + \ - sizeof(u_char)) -/* - * Size for copying cache fr_info structure - */ -#define FI_COPYSIZE (sizeof(fr_info_t) - sizeof(void *) * 2) - -typedef struct frdest { - void *fd_ifp; - struct in_addr fd_ip; - char fd_ifname[IFNAMSIZ]; -} frdest_t; - -typedef struct frentry { - struct frentry *fr_next; - u_short fr_group; /* group to which this rule belongs */ - u_short fr_grhead; /* group # which this rule starts */ - struct frentry *fr_grp; - int fr_ref; /* reference count - for grouping */ - void *fr_ifa; - /* - * 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_char fr_tcpfm; /* tcp flags mask */ - u_char fr_tcpf; /* tcp flags */ - - u_short fr_icmpm; /* data for ICMP packets (mask) */ - u_short fr_icmp; - - u_char fr_scmp; /* data for port comparisons */ - u_char fr_dcmp; - u_short fr_dport; - u_short fr_sport; - u_short fr_stop; /* top port for <> and >< */ - u_short fr_dtop; /* top port for <> and >< */ - u_32_t fr_flags; /* per-rule flags && options (see below) */ - int fr_skip; /* # of rules to skip */ - int (*fr_func) __P((int, ip_t *, fr_info_t *)); /* call this function */ - char fr_icode; /* return ICMP code */ - char fr_ifname[IFNAMSIZ]; - struct frdest fr_tif; /* "to" interface */ - struct frdest fr_dif; /* duplicate packet interfaces */ -} frentry_t; - -#define fr_proto fr_ip.fi_p -#define fr_ttl fr_ip.fi_ttl -#define fr_tos fr_ip.fi_tos -#define fr_dst fr_ip.fi_dst -#define fr_src fr_ip.fi_src -#define fr_dmsk fr_mip.fi_dst -#define fr_smsk fr_mip.fi_src - -#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_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_LOGMASK (FR_LOG|FR_LOGP|FR_LOGB) - -/* - * 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_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 */ -#if SOLARIS - 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! */ -#endif -} 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_auth; - u_long f_froute[2]; - int f_active; -} friostat_t; - -typedef struct optlist { - u_short ol_val; - int ol_bit; -} optlist_t; - - -/* - * Group list structure. - */ -typedef struct frgroup { - u_short 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_long ipl_magic; - u_long ipl_sec; - u_long ipl_usec; - u_int ipl_len; - u_int ipl_count; - 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_rule; /* assume never more than 64k rules, total */ - u_short fl_group; - u_32_t fl_flags; -} 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 - -#ifndef _KERNEL -struct ifnet; -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 void ipfr_fastroute __P((ip_t *, fr_info_t *, frdest_t *)); -extern struct ifnet *get_unit __P((char *)); -# define FR_SCANLIST(p, ip, fi, m) fr_scanlist(p, ip, fi, m) -# if defined(__NetBSD__) || defined(__OpenBSD__) || \ - (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300003) -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 int 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((int)); -extern int ipflog_read __P((int, struct uio *)); -extern int ipflog __P((u_int, ip_t *, fr_info_t *, mb_t *)); -extern int ipllog __P((int, u_long, void **, size_t *, int *, int)); -# 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 **)); -extern int icmp_error __P((ip_t *, int, int, qif_t *, - struct in_addr)); -extern int iplioctl __P((dev_t, int, int, 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 ipfsync __P((void)); -extern int send_reset __P((ip_t *, qif_t *)); -extern int ipfr_fastroute __P((qif_t *, ip_t *, mblk_t *, mblk_t **, - fr_info_t *, frdest_t *)); -extern void copyin_mblk __P((mblk_t *, int, int, char *)); -extern void copyout_mblk __P((mblk_t *, int, int, char *)); -extern int fr_qin __P((queue_t *, mblk_t *)); -extern int fr_qout __P((queue_t *, mblk_t *)); -# ifdef IPFILTER_LOG -extern int iplread __P((dev_t, struct uio *, cred_t *)); -# endif -# 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 **)); -# ifdef linux -extern int send_reset __P((tcpiphdr_t *, struct ifnet *)); -# else -extern int send_reset __P((tcpiphdr_t *)); -# endif -extern void 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) -# if defined(__NetBSD__) || (_BSDI_VERSION >= 199701) || \ - (__FreeBSD_version >= 300003) -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 -# if defined(__OpenBSD__) -extern int iplioctl __P((dev_t, u_long, caddr_t, int)); -# else /* __OpenBSD__ */ -# ifndef linux -extern int iplioctl __P((dev_t, int, caddr_t, int)); -# else -extern int iplioctl(struct inode *, struct file *, u_int, u_long); -# endif -# endif /* __OpenBSD__ */ -# ifndef linux -extern int iplopen __P((dev_t, int)); -extern int iplclose __P((dev_t, int)); -# else -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 */ - -/* - * 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) -# define NETBSD_PF -#endif - -extern int ipldetach __P((void)); -extern u_short fr_tcpsum __P((mb_t *, ip_t *, tcphdr_t *, int)); -#define FR_SCANLIST(p, ip, fi, m) fr_scanlist(p, ip, fi, m) -extern int fr_scanlist __P((int, ip_t *, fr_info_t *, void *)); -extern u_short ipf_cksum __P((u_short *, int)); -extern int fr_copytolog __P((int, char *, int)); -extern void frflush __P((int, int *)); -extern frgroup_t *fr_addgroup __P((u_short, frentry_t *, int, int)); -extern frgroup_t *fr_findgroup __P((u_short, u_32_t, int, int, frgroup_t ***)); -extern void fr_delgroup __P((u_short, u_32_t, int, int)); -extern int ipl_unreach; -extern int ipl_inited; -extern u_long ipl_frouteok[2]; -extern int fr_pass; -extern int fr_flags; -extern int fr_active; -extern fr_info_t frcache[2]; -#ifdef IPFILTER_LOG -extern iplog_t **iplh[IPL_LOGMAX+1], *iplt[IPL_LOGMAX+1]; -extern int iplused[IPL_LOGMAX + 1]; -#endif -extern struct frentry *ipfilter[2][2], *ipacct[2][2]; -extern struct frgroup *ipfgroups[3][2]; -extern struct filterstats frstats[]; - -#endif /* __IP_FIL_H__ */ diff --git a/sys/contrib/ipfilter/netinet/ip_frag.c b/sys/contrib/ipfilter/netinet/ip_frag.c deleted file mode 100644 index de104e5..0000000 --- a/sys/contrib/ipfilter/netinet/ip_frag.c +++ /dev/null @@ -1,467 +0,0 @@ -/* - * Copyright (C) 1993-1997 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-1995 Darren Reed"; -static const char rcsid[] = "@(#)$FreeBSD$"; -#endif - -#if !defined(_KERNEL) && defined(KERNEL) -#define _KERNEL -#endif -#define __FreeBSD_version 300000 /* it's a hack, but close enough */ - -#if !defined(_KERNEL) && !defined(KERNEL) -# include <string.h> -# include <stdlib.h> -#endif -#include <sys/errno.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/time.h> -#include <sys/file.h> -#if defined(KERNEL) && (__FreeBSD_version >= 220000) -#include <sys/filio.h> -#include <sys/fcntl.h> -#include <sys/malloc.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__) -# ifndef linux -# include <sys/mbuf.h> -# endif -#else -# include <sys/byteorder.h> -# include <sys/dditypes.h> -# include <sys/stream.h> -# include <sys/kmem.h> -#endif -#if defined(KERNEL) && (__FreeBSD_version >= 300000) -#include <sys/malloc.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" - -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 */ -#ifdef _KERNEL -extern int ipfr_timer_id; -#endif -#if (SOLARIS || defined(__sgi)) && defined(_KERNEL) -extern kmutex_t ipf_frag; -extern kmutex_t ipf_natfrag; -extern kmutex_t ipf_nat; -#endif - - -static ipfr_t *ipfr_new __P((ip_t *, fr_info_t *, int, ipfr_t **)); -static ipfr_t *ipfr_lookup __P((ip_t *, fr_info_t *, 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; -int pass; -ipfr_t *table[]; -{ - ipfr_t **fp, *fr, frag; - u_int idx; - - frag.ipfr_p = ip->ip_p; - idx = ip->ip_p; - frag.ipfr_id = ip->ip_id; - idx += ip->ip_id; - frag.ipfr_tos = ip->ip_tos; - frag.ipfr_src.s_addr = ip->ip_src.s_addr; - idx += ip->ip_src.s_addr; - frag.ipfr_dst.s_addr = ip->ip_dst.s_addr; - idx += ip->ip_dst.s_addr; - idx *= 127; - idx %= IPFT_SIZE; - - /* - * first, make sure it isn't already there... - */ - for (fp = &table[idx]; (fr = *fp); fp = &fr->ipfr_next) - if (!bcmp((char *)&frag.ipfr_src, (char *)&fr->ipfr_src, - IPFR_CMPSZ)) { - ipfr_stats.ifs_exists++; - return NULL; - } - - /* - * allocate some memory, if possible, if not, just record that we - * failed to do so. - */ - KMALLOC(fr, ipfr_t *, sizeof(*fr)); - if (fr == NULL) { - ipfr_stats.ifs_nomem++; - return NULL; - } - - /* - * 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 ((fr->ipfr_next = table[idx])) - table[idx]->ipfr_prev = fr; - fr->ipfr_prev = NULL; - fr->ipfr_data = NULL; - table[idx] = fr; - bcopy((char *)&frag.ipfr_src, (char *)&fr->ipfr_src, IPFR_CMPSZ); - fr->ipfr_ttl = fr_ipfrttl; - fr->ipfr_pass = pass & ~(FR_LOGFIRST|FR_LOG); - /* - * Compute the offset of the expected start of the next packet. - */ - fr->ipfr_off = (ip->ip_off & 0x1fff) + (fin->fin_dlen >> 3); - ipfr_stats.ifs_new++; - ipfr_inuse++; - return fr; -} - - -int ipfr_newfrag(ip, fin, pass) -ip_t *ip; -fr_info_t *fin; -int pass; -{ - ipfr_t *ipf; - - MUTEX_ENTER(&ipf_frag); - ipf = ipfr_new(ip, fin, pass, ipfr_heads); - MUTEX_EXIT(&ipf_frag); - return ipf ? 0 : -1; -} - - -int ipfr_nat_newfrag(ip, fin, pass, nat) -ip_t *ip; -fr_info_t *fin; -int pass; -nat_t *nat; -{ - ipfr_t *ipf; - - MUTEX_ENTER(&ipf_natfrag); - if ((ipf = ipfr_new(ip, fin, pass, ipfr_nattab))) { - ipf->ipfr_data = nat; - nat->nat_data = ipf; - } - MUTEX_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; - 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; - atoff = off + (fin->fin_dlen >> 3); - /* - * If we've follwed the fragments, and this is the - * last (in order), shrink expiration time. - */ - if ((off & 0x1fff) == f->ipfr_off) { - if (!(off & IP_MF)) - f->ipfr_ttl = 1; - else - f->ipfr_off = atoff; - } - 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; - - MUTEX_ENTER(&ipf_natfrag); - ipf = ipfr_lookup(ip, fin, ipfr_nattab); - if (ipf) { - nat = ipf->ipfr_data; - /* - * This is the last fragment for this packet. - */ - if (ipf->ipfr_ttl == 1) { - nat->nat_data = NULL; - ipf->ipfr_data = NULL; - } - } else - nat = NULL; - MUTEX_EXIT(&ipf_natfrag); - return nat; -} - - -/* - * functional interface for normal lookups of the fragment cache - */ -int ipfr_knownfrag(ip, fin) -ip_t *ip; -fr_info_t *fin; -{ - int ret; - ipfr_t *ipf; - - MUTEX_ENTER(&ipf_frag); - ipf = ipfr_lookup(ip, fin, ipfr_heads); - ret = ipf ? ipf->ipfr_pass : 0; - MUTEX_EXIT(&ipf_frag); - return ret; -} - - -/* - * forget any references to this external object. - */ -void ipfr_forget(nat) -void *nat; -{ - ipfr_t *fr; - int idx; - - MUTEX_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; - - MUTEX_EXIT(&ipf_natfrag); -} - - -/* - * Free memory in use by fragment state info. kept. - */ -void ipfr_unload() -{ - ipfr_t **fp, *fr; - nat_t *nat; - int idx; - - MUTEX_ENTER(&ipf_frag); - for (idx = IPFT_SIZE - 1; idx >= 0; idx--) - for (fp = &ipfr_heads[idx]; (fr = *fp); ) { - *fp = fr->ipfr_next; - KFREE(fr); - } - MUTEX_EXIT(&ipf_frag); - - MUTEX_ENTER(&ipf_nat); - MUTEX_ENTER(&ipf_natfrag); - for (idx = IPFT_SIZE - 1; idx >= 0; idx--) - for (fp = &ipfr_nattab[idx]; (fr = *fp); ) { - *fp = fr->ipfr_next; - if ((nat = (nat_t *)fr->ipfr_data)) { - if (nat->nat_data == fr) - nat->nat_data = NULL; - } - KFREE(fr); - } - MUTEX_EXIT(&ipf_natfrag); - MUTEX_EXIT(&ipf_nat); -} - - -#ifdef _KERNEL -/* - * Slowly expire held state for fragments. Timeouts are set * in expectation - * of this being called twice per second. - */ -# if (BSD >= 199306) || SOLARIS || defined(__sgi) -void ipfr_slowtimer() -# else -int ipfr_slowtimer() -# endif -{ - ipfr_t **fp, *fr; - nat_t *nat; - int s, idx; - -#ifdef __sgi - ipfilter_sgi_intfsync(); -#endif - - SPL_NET(s); - MUTEX_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]; (fr = *fp); ) { - --fr->ipfr_ttl; - if (fr->ipfr_ttl == 0) { - if (fr->ipfr_prev) - fr->ipfr_prev->ipfr_next = - fr->ipfr_next; - if (fr->ipfr_next) - fr->ipfr_next->ipfr_prev = - fr->ipfr_prev; - *fp = fr->ipfr_next; - ipfr_stats.ifs_expire++; - ipfr_inuse--; - KFREE(fr); - } else - fp = &fr->ipfr_next; - } - MUTEX_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. - */ - MUTEX_ENTER(&ipf_nat); - MUTEX_ENTER(&ipf_natfrag); - for (idx = IPFT_SIZE - 1; idx >= 0; idx--) - for (fp = &ipfr_nattab[idx]; (fr = *fp); ) { - --fr->ipfr_ttl; - if (fr->ipfr_ttl == 0) { - if (fr->ipfr_prev) - fr->ipfr_prev->ipfr_next = - fr->ipfr_next; - if (fr->ipfr_next) - fr->ipfr_next->ipfr_prev = - fr->ipfr_prev; - *fp = fr->ipfr_next; - ipfr_stats.ifs_expire++; - ipfr_inuse--; - if ((nat = (nat_t *)fr->ipfr_data)) { - if (nat->nat_data == fr) - nat->nat_data = NULL; - } - KFREE(fr); - } else - fp = &fr->ipfr_next; - } - MUTEX_EXIT(&ipf_natfrag); - MUTEX_EXIT(&ipf_nat); - SPL_X(s); - fr_timeoutstate(); - ip_natexpire(); - fr_authexpire(); -# if SOLARIS - ipfr_timer_id = timeout(ipfr_slowtimer, NULL, drv_usectohz(500000)); -# else -# ifndef linux - ip_slowtimo(); -# endif -# if (BSD < 199306) && !defined(__sgi) - return 0; -# endif -# endif -} -#endif /* defined(_KERNEL) */ diff --git a/sys/contrib/ipfilter/netinet/ip_frag.h b/sys/contrib/ipfilter/netinet/ip_frag.h deleted file mode 100644 index c509050..0000000 --- a/sys/contrib/ipfilter/netinet/ip_frag.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 1993-1997 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 - * $FreeBSD$ - */ - -#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; - u_short ipfr_id; - u_char ipfr_p; - u_char ipfr_tos; - u_short ipfr_off; - u_short ipfr_ttl; - u_char ipfr_pass; -} 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 ipfrstat_t *ipfr_fragstats __P((void)); -extern int ipfr_newfrag __P((ip_t *, fr_info_t *, int)); -extern int ipfr_nat_newfrag __P((ip_t *, fr_info_t *, int, struct nat *)); -extern nat_t *ipfr_nat_knownfrag __P((ip_t *, fr_info_t *)); -extern int ipfr_knownfrag __P((ip_t *, fr_info_t *)); -extern void ipfr_forget __P((void *)); -extern void ipfr_unload __P((void)); - -#if (BSD >= 199306) || SOLARIS || defined(__sgi) -extern void ipfr_slowtimer __P((void)); -#else -extern int ipfr_slowtimer __P((void)); -#endif - -#endif /* __IP_FIL_H__ */ diff --git a/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c b/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c deleted file mode 100644 index 917dbb2..0000000 --- a/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Simple FTP transparent proxy for in-kernel use. For use with the NAT - * code. - * - * $FreeBSD$ - */ - -#define isdigit(x) ((x) >= '0' && (x) <= '9') - -#define IPF_FTP_PROXY - -#define IPF_MINPORTLEN 18 -#define IPF_MAXPORTLEN 30 - - -int ippr_ftp_init __P((fr_info_t *, ip_t *, tcphdr_t *, - ap_session_t *, nat_t *)); -int ippr_ftp_in __P((fr_info_t *, ip_t *, tcphdr_t *, - ap_session_t *, nat_t *)); -int ippr_ftp_out __P((fr_info_t *, ip_t *, tcphdr_t *, - ap_session_t *, nat_t *)); -u_short ipf_ftp_atoi __P((char **)); - - -/* - * FTP application proxy initialization. - */ -int ippr_ftp_init(fin, ip, tcp, aps, nat) -fr_info_t *fin; -ip_t *ip; -tcphdr_t *tcp; -ap_session_t *aps; -nat_t *nat; -{ - aps->aps_sport = tcp->th_sport; - aps->aps_dport = tcp->th_dport; - return 0; -} - - -int ippr_ftp_in(fin, ip, tcp, aps, nat) -fr_info_t *fin; -ip_t *ip; -tcphdr_t *tcp; -ap_session_t *aps; -nat_t *nat; -{ - u_32_t sum1, sum2; - short sel; - - if (tcp->th_sport == aps->aps_dport) { - sum2 = (u_32_t)ntohl(tcp->th_ack); - sel = aps->aps_sel; - if ((aps->aps_after[!sel] > aps->aps_after[sel]) && - (sum2 > aps->aps_after[!sel])) { - sel = aps->aps_sel = !sel; /* switch to other set */ - } - if (aps->aps_seqoff[sel] && (sum2 > aps->aps_after[sel])) { - sum1 = (u_32_t)aps->aps_seqoff[sel]; - tcp->th_ack = htonl(sum2 - sum1); - return 2; - } - } - return 0; -} - - -/* - * ipf_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 ipf_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; - return (i << 8) | j; -} - - -int ippr_ftp_out(fin, ip, tcp, aps, nat) -fr_info_t *fin; -ip_t *ip; -tcphdr_t *tcp; -ap_session_t *aps; -nat_t *nat; -{ - register u_32_t sum1, sum2; - char newbuf[IPF_MAXPORTLEN+1]; - char portbuf[IPF_MAXPORTLEN+1], *s; - int ch = 0, off = (ip->ip_hl << 2) + (tcp->th_off << 2); - u_int a1, a2, a3, a4; - u_short a5, a6; - int olen, dlen, nlen = 0, inc = 0; - tcphdr_t tcph, *tcp2 = &tcph; - void *savep; - nat_t *ipn; - struct in_addr swip; - mb_t *m = *(mb_t **)fin->fin_mp; - -#if SOLARIS - mb_t *m1; - - /* skip any leading M_PROTOs */ - while(m && (MTYPE(m) != M_DATA)) - m = m->b_cont; - PANIC((!m),("ippr_ftp_out: no M_DATA")); - - dlen = msgdsize(m) - off; - bzero(portbuf, sizeof(portbuf)); - copyout_mblk(m, off, MIN(sizeof(portbuf), dlen), portbuf); -#else - dlen = mbufchainlen(m) - off; - bzero(portbuf, sizeof(portbuf)); - m_copydata(m, off, MIN(sizeof(portbuf), dlen), portbuf); -#endif - portbuf[IPF_MAXPORTLEN] = '\0'; - - if ((dlen < IPF_MINPORTLEN) || strncmp(portbuf, "PORT ", 5)) - goto adjust_seqack; - - /* - * Skip the PORT command + space - */ - s = portbuf + 5; - /* - * Pick out the address components, two at a time. - */ - (void) ipf_ftp_atoi(&s); - if (!s) - goto adjust_seqack; - (void) ipf_ftp_atoi(&s); - if (!s) - goto adjust_seqack; - a5 = ipf_ftp_atoi(&s); - if (!s) - goto adjust_seqack; - /* - * check for CR-LF at the end. - */ - if (*s != '\n' || *(s - 1) != '\r') - goto adjust_seqack; - a6 = a5 & 0xff; - a5 >>= 8; - /* - * 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 - portbuf + 1; - (void) snprintf(newbuf, sizeof(newbuf), "PORT %d,%d,%d,%d,%d,%d\r\n", - a1, a2, a3, a4, a5, a6); - nlen = strlen(newbuf); - inc = nlen - olen; -#if SOLARIS - for (m1 = m; m1->b_cont; m1 = m1->b_cont) - ; - if (inc > 0) { - mblk_t *nm; - - /* alloc enough to keep same trailer space for lower driver */ - nm = allocb(nlen + m1->b_datap->db_lim - m1->b_wptr, 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 - 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 - if (inc) { -#if SOLARIS || defined(__sgi) - 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; - } - ch = 1; - - /* - * Add skeleton NAT entry for connection which will come back the - * other way. - */ - savep = fin->fin_dp; - fin->fin_dp = (char *)tcp2; - bzero((char *)tcp2, sizeof(*tcp2)); - tcp2->th_sport = htons(a5 << 8 | a6); - tcp2->th_dport = htons(20); - swip = ip->ip_src; - ip->ip_src = nat->nat_inip; - if ((ipn = nat_new(nat->nat_ptr, ip, fin, IPN_TCP, NAT_OUTBOUND))) - ipn->nat_age = fr_defnatage; - (void) fr_addstate(ip, fin, FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE); - ip->ip_src = swip; - fin->fin_dp = (char *)savep; - -adjust_seqack: - if (tcp->th_dport == aps->aps_dport) { - sum2 = (u_32_t)ntohl(tcp->th_seq); - off = aps->aps_sel; - if ((aps->aps_after[!off] > aps->aps_after[off]) && - (sum2 > aps->aps_after[!off])) { - off = aps->aps_sel = !off; /* switch to other set */ - } - if (aps->aps_seqoff[off]) { - sum1 = (u_32_t)aps->aps_after[off] - - aps->aps_seqoff[off]; - if (sum2 > sum1) { - sum1 = (u_32_t)aps->aps_seqoff[off]; - sum2 += sum1; - tcp->th_seq = htonl(sum2); - ch = 1; - } - } - - if (inc && (sum2 > aps->aps_after[!off])) { - aps->aps_after[!off] = sum2 + nlen - 1; - aps->aps_seqoff[!off] = aps->aps_seqoff[off] + inc; - } - } - return ch ? 2 : 0; -} diff --git a/sys/contrib/ipfilter/netinet/ip_log.c b/sys/contrib/ipfilter/netinet/ip_log.c deleted file mode 100644 index 3f73a3e..0000000 --- a/sys/contrib/ipfilter/netinet/ip_log.c +++ /dev/null @@ -1,483 +0,0 @@ -/* - * Copyright (C) 1997 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. - * - * $FreeBSD$ - */ -#include "opt_ipfilter.h" - -#ifdef IPFILTER_LOG -# ifndef SOLARIS -# define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4))) -# endif - -# if defined(KERNEL) && !defined(_KERNEL) -# define _KERNEL -# endif -# ifdef __FreeBSD__ -# if defined(_KERNEL) && !defined(IPFILTER_LKM) -# define __FreeBSD_version 300000 /* this will do as a hack */ -# else -# include <osreldate.h> -# endif -# 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/param.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) || defined(__FreeBSD__) -# 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 <sys/malloc.h> -# include <machine/random.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" -# 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]; -int iplused[IPL_LOGMAX+1]; -static u_long iplcrc[IPL_LOGMAX+1]; -static u_long iplcrcinit; -#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; - iplh[i] = &iplt[i]; - iplused[i] = 0; - } -# if defined(__FreeBSD__) && __FreeBSD_version >= 300000 - read_random(&iplcrcinit, sizeof iplcrcinit); -# else - { - struct timeval tv; - -#if BSD >= 199306 || defined(__FreeBSD__) || defined(__sgi) - microtime(&tv); -# else - uniqtime(&tv); -# endif - iplcrcinit = tv.tv_sec ^ (tv.tv_usec << 8) ^ tv.tv_usec; - } -# endif -} - - -/* - * 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 int mlen, hlen; - u_long crc; - size_t sizes[2]; - void *ptrs[2]; - int types[2]; -# if SOLARIS - ill_t *ifp = fin->fin_ifp; -# else - struct ifnet *ifp = fin->fin_ifp; -# endif - - /* - * calculate header size. - */ - hlen = fin->fin_hlen; - if (ip->ip_p == IPPROTO_TCP) - hlen += MIN(sizeof(tcphdr_t), fin->fin_dlen); - else if (ip->ip_p == IPPROTO_UDP) - hlen += MIN(sizeof(udphdr_t), fin->fin_dlen); - else if (ip->ip_p == IPPROTO_ICMP) { - struct icmp *icmp = (struct icmp *)((char *)ip + hlen); - - /* - * 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(ip->ip_len - 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; - 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 - crc = (ipf_cksum((u_short *)fin, FI_CSIZE) << 8) + iplcrcinit; - return ipllog(IPL_LOGIPF, crc, ptrs, sizes, types, 2); -} - - -/* - * ipllog - */ -int ipllog(dev, crc, items, itemsz, types, cnt) -int dev; -u_long crc; -void **items; -size_t *itemsz; -int *types, cnt; -{ - iplog_t *ipl; - caddr_t buf, s; - int len, 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. - */ - if (crc) { - MUTEX_ENTER(&ipl_mutex); - if ((iplcrc[dev] == crc) && *iplh[dev]) { - (*iplh[dev])->ipl_count++; - MUTEX_EXIT(&ipl_mutex); - return 1; - } - iplcrc[dev] = crc; - 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. - */ - KMALLOC(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); - *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) -int unit; -struct uio *uio; -{ - iplog_t *ipl; - int error = 0, dlen, copied; -# 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) || (unit < 0)) - 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 + sizeof(iplog_t) > uio->uio_resid) - break; - /* - * Don't hold the mutex over the uiomove call. - */ - iplt[unit] = ipl->ipl_next; - MUTEX_EXIT(&ipl_mutex); - SPL_X(s); - error = UIOMOVE((caddr_t)ipl, ipl->ipl_dsize, UIO_READ, uio); - KFREES((caddr_t)ipl, ipl->ipl_dsize); - if (error) - break; - SPL_NET(s); - MUTEX_ENTER(&ipl_mutex); - iplused[unit] -= dlen; - } - if (!ipl) { - iplused[unit] = 0; - iplh[unit] = &iplt[unit]; - } - - if (!error) { - MUTEX_EXIT(&ipl_mutex); - SPL_X(s); - } -#ifdef linux - if (!error) - return copied; - return -error; -#else - return error; -#endif -} - - -int ipflog_clear(unit) -int unit; -{ - iplog_t *ipl; - int used; - - while ((ipl = iplt[unit])) { - iplt[unit] = ipl->ipl_next; - KFREES((caddr_t)ipl, ipl->ipl_dsize); - } - iplh[unit] = &iplt[unit]; - used = iplused[unit]; - iplused[unit] = 0; - iplcrc[unit] = 0; - return used; -} -#endif /* IPFILTER_LOG */ diff --git a/sys/contrib/ipfilter/netinet/ip_nat.c b/sys/contrib/ipfilter/netinet/ip_nat.c deleted file mode 100644 index a8f8744..0000000 --- a/sys/contrib/ipfilter/netinet/ip_nat.c +++ /dev/null @@ -1,1373 +0,0 @@ -/* - * Copyright (C) 1995-1997 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[] = "@(#)$FreeBSD$"; -#endif - -#include "opt_ipfilter.h" -#define __FreeBSD_version 300000 /* it's a hack, but close enough */ - -#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL) -#define _KERNEL -#endif - -#if !defined(_KERNEL) && !defined(KERNEL) -# include <stdio.h> -# include <string.h> -# include <stdlib.h> -#endif -#include <sys/errno.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/time.h> -#include <sys/file.h> -#if 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> -# include <sys/dditypes.h> -# include <sys/stream.h> -# include <sys/kmem.h> -#endif -#if __FreeBSD_version >= 300000 -# include <sys/queue.h> -# include <sys/malloc.h> -#endif -#include <net/if.h> -#if __FreeBSD_version >= 300000 -# include <net/if_var.h> -#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" -#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][NAT_SIZE], *nat_instances = NULL; -static ipnat_t *nat_list = NULL; -u_long fr_defnatage = 1200, /* 10 minutes (600 seconds) */ - fr_defnaticmpage = 6; /* 3 seconds */ -static natstat_t nat_stats; -#if (SOLARIS || defined(__sgi)) && defined(_KERNEL) -extern kmutex_t ipf_nat; -#endif - -static int nat_flushtable __P((void)); -static int nat_clearlist __P((void)); -static void nat_delete __P((struct nat *)); -static int nat_ifpaddr __P((nat_t *, void *, struct in_addr *)); - - -#define LONG_SUM(in) (((in) & 0xffff) + ((in) >> 16)) - -#define CALC_SUMD(s1, s2, sd) { \ - /* Do it twice */ \ - (s1) = ((s1) & 0xffff) + ((s1) >> 16); \ - (s1) = ((s1) & 0xffff) + ((s1) >> 16); \ - /* Do it twice */ \ - (s2) = ((s2) & 0xffff) + ((s2) >> 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); } - -void fix_outcksum(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); -} - - -void fix_incksum(sp, n) -u_short *sp; -u_32_t n; -{ - register u_short sumshort; - register u_32_t sum1; - - if (!n) - return; -#ifdef sparc - sum1 = (~(*sp)) & 0xffff; -#else - sum1 = (~ntohs(*sp)) & 0xffff; -#endif - sum1 += ~(n) & 0xffff; - sum1 = (sum1 >> 16) + (sum1 & 0xffff); - /* Again */ - sum1 = (sum1 >> 16) + (sum1 & 0xffff); - sumshort = ~(u_short)sum1; - *(sp) = htons(sumshort); -} - - -/* - * How the NAT is organised and works. - * - * Inside (interface y) NAT Outside (interface x) - * -------------------- -+- ------------------------------------- - * Packet going | out, processsed by ip_natout() for x - * ------------> | ------------> - * src=10.1.1.1 | src=192.1.1.1 - * | - * | in, processed by ip_natin() for x - * <------------ | <------------ - * dst=10.1.1.1 | dst=192.1.1.1 - * -------------------- -+- ------------------------------------- - * ip_natout() - changes ip_src and if required, sport - * - creates a new mapping, if required. - * ip_natin() - changes ip_dst and if required, dport - * - * In the NAT table, internal source is recorded as "in" and externally - * seen as "out". - */ - -/* - * Handle ioctls which manipulate the NAT. - */ -int nat_ioctl(data, cmd, mode) -#if defined(__NetBSD__) || defined(__OpenBSD__) || (__FreeBSD_version >= 300003) -u_long cmd; -#else -int cmd; -#endif -caddr_t data; -int mode; -{ - register ipnat_t *nat, *n = NULL, **np = NULL; - ipnat_t natd; - int error = 0, ret; -#if defined(_KERNEL) && !SOLARIS - int s; -#endif - - nat = NULL; /* XXX gcc -Wuninitialized */ - - /* - * For add/delete, look to see if the NAT entry is already present - */ - SPL_NET(s); - MUTEX_ENTER(&ipf_nat); - if ((cmd == SIOCADNAT) || (cmd == SIOCRMNAT)) { - IRCOPY(data, (char *)&natd, sizeof(natd)); - nat = &natd; - nat->in_inip &= nat->in_inmsk; - 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) - { - case SIOCADNAT : - if (!(mode & FWRITE)) { - error = EPERM; - break; - } - if (n) { - error = EEXIST; - break; - } - KMALLOC(n, ipnat_t *, sizeof(*n)); - if (n == NULL) { - error = ENOMEM; - break; - } - bcopy((char *)nat, (char *)n, sizeof(*n)); - n->in_ifp = (void *)GETUNIT(n->in_ifname); - if (!n->in_ifp) - n->in_ifp = (void *)-1; - n->in_apr = ap_match(n->in_p, n->in_plabel); - n->in_next = *np; - n->in_use = 0; - n->in_space = ~(0xffffffff & ntohl(n->in_outmsk)); - if (n->in_space) /* lose 2: broadcast + network address */ - n->in_space -= 2; - else - n->in_space = 1; /* single IP# mapping */ - if ((n->in_outmsk != 0xffffffff) && n->in_outmsk) - n->in_nip = ntohl(n->in_outip) + 1; - else - n->in_nip = ntohl(n->in_outip); - if (n->in_redir & NAT_MAP) { - n->in_pnext = ntohs(n->in_pmin); - /* - * Multiply by the number of ports made available. - */ - if (ntohs(n->in_pmax) > ntohs(n->in_pmin)) - n->in_space *= (ntohs(n->in_pmax) - - ntohs(n->in_pmin)); - } - /* Otherwise, these fields are preset */ - *np = n; - nat_stats.ns_rules++; - break; - case SIOCRMNAT : - if (!(mode & FWRITE)) { - error = EPERM; - break; - } - if (!n) { - error = ESRCH; - break; - } - *np = n->in_next; - if (!n->in_use) { - if (n->in_apr) - ap_free(n->in_apr); - KFREE(n); - nat_stats.ns_rules--; - } else { - n->in_flags |= IPN_DELETE; - n->in_next = NULL; - } - break; - case SIOCGNATS : - nat_stats.ns_table[0] = nat_table[0]; - nat_stats.ns_table[1] = nat_table[1]; - nat_stats.ns_list = nat_list; - IWCOPY((char *)&nat_stats, (char *)data, sizeof(nat_stats)); - break; - case SIOCGNATL : - { - natlookup_t nl; - - IRCOPY((char *)data, (char *)&nl, sizeof(nl)); - - if (nat_lookupredir(&nl)) { - IWCOPY((char *)&nl, (char *)data, sizeof(nl)); - } else - error = ESRCH; - break; - } - case SIOCFLNAT : - if (!(mode & FWRITE)) { - error = EPERM; - break; - } - ret = nat_flushtable(); - (void) ap_unload(); - IWCOPY((caddr_t)&ret, data, sizeof(ret)); - break; - case SIOCCNATL : - if (!(mode & FWRITE)) { - error = EPERM; - break; - } - ret = nat_clearlist(); - IWCOPY((caddr_t)&ret, data, sizeof(ret)); - break; - case FIONREAD : -#ifdef IPFILTER_LOG - IWCOPY((caddr_t)&iplused[IPL_LOGNAT], (caddr_t)data, - sizeof(iplused[IPL_LOGNAT])); -#endif - break; - } - MUTEX_EXIT(&ipf_nat); - SPL_X(s); - return error; -} - - -/* - * Delete a nat entry from the various lists and table. - */ -static void nat_delete(natd) -struct nat *natd; -{ - register struct nat **natp, *nat; - struct ipnat *ipn; - - for (natp = natd->nat_hstart[0]; (nat = *natp); - natp = &nat->nat_hnext[0]) - if (nat == natd) { - *natp = nat->nat_hnext[0]; - break; - } - - for (natp = natd->nat_hstart[1]; (nat = *natp); - natp = &nat->nat_hnext[1]) - if (nat == natd) { - *natp = nat->nat_hnext[1]; - break; - } - - /* - * If 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. - */ - if ((ipn = natd->nat_ptr)) { - ipn->in_space++; - ipn->in_use--; - if (!ipn->in_use && (ipn->in_flags & IPN_DELETE)) { - if (ipn->in_apr) - ap_free(ipn->in_apr); - KFREE(ipn); - nat_stats.ns_rules--; - } - } - - /* - * If there's a fragment table entry too for this nat entry, then - * dereference that as well. - */ - ipfr_forget((void *)natd); - 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; - - /* - * Everything will be deleted, so lets just make it the deletions - * quicker. - */ - bzero((char *)nat_table[0], sizeof(nat_table[0])); - bzero((char *)nat_table[1], sizeof(nat_table[1])); - - for (natp = &nat_instances; (nat = *natp); ) { - *natp = nat->nat_next; - nat_delete(nat); - j++; - } - - return j; -} - - -/* - * nat_clearlist - delete all entries in the active NAT mapping list. - */ -static int nat_clearlist() -{ - register ipnat_t *n, **np = &nat_list; - int i = 0; - - while ((n = *np)) { - *np = n->in_next; - if (!n->in_use) { - if (n->in_apr) - ap_free(n->in_apr); - KFREE(n); - nat_stats.ns_rules--; - i++; - } else { - n->in_flags |= IPN_DELETE; - n->in_next = NULL; - } - } - nat_stats.ns_inuse = 0; - return i; -} - - -/* - * return the first IP Address associated with an interface - */ -static int nat_ifpaddr(nat, ifptr, inp) -nat_t *nat; -void *ifptr; -struct in_addr *inp; -{ -#if SOLARIS - ill_t *ill = ifptr; -#else - struct ifnet *ifp = ifptr; -#endif - struct in_addr in; - -#if SOLARIS - in.s_addr = ntohl(ill->ill_ipif->ipif_local_addr); -#else /* SOLARIS */ -# if linux - ; -# else /* linux */ - struct ifaddr *ifa; - struct sockaddr_in *sin; - -# 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 = (SOCKADDR_IN *)&ifa->ifa_addr; -# else - sin = (SOCKADDR_IN *)ifa->ifa_addr; - while (sin && ifa && - sin->sin_family != AF_INET) { -# 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 = (SOCKADDR_IN *)ifa->ifa_addr; - } - if (!ifa) - sin = NULL; - if (!sin) { - KFREE(nat); - return -1; - } -# endif /* (BSD < 199306) && (!__sgi && IFF_DRVLOCK) */ - in = sin->sin_addr; - in.s_addr = ntohl(in.s_addr); -# endif /* linux */ -#endif /* SOLARIS */ - *inp = in; - return 0; -} - - -/* - * Create a new NAT table entry. - */ -nat_t *nat_new(np, ip, fin, flags, direction) -ipnat_t *np; -ip_t *ip; -fr_info_t *fin; -u_short flags; -int direction; -{ - register u_32_t sum1, sum2, sumd, l; - u_short port = 0, sport = 0, dport = 0, nport = 0; - struct in_addr in; - tcphdr_t *tcp = NULL; - nat_t *nat, **natp; - u_short nflags; - - nflags = flags & np->in_flags; - if (flags & IPN_TCPUDP) { - tcp = (tcphdr_t *)fin->fin_dp; - sport = tcp->th_sport; - dport = tcp->th_dport; - } - - /* Give me a new nat */ - KMALLOC(nat, nat_t *, sizeof(*nat)); - if (nat == NULL) - return NULL; - - bzero((char *)nat, sizeof(*nat)); - nat->nat_flags = flags; - - /* - * Search the current table for a match. - */ - if (direction == NAT_OUTBOUND) { - /* - * If it's an outbound packet which doesn't match any existing - * record, then create a new port - */ - l = 0; - do { - l++; - port = 0; - in.s_addr = np->in_nip; - if (!in.s_addr && (np->in_outmsk == 0xffffffff)) { - if ((l > 1) || - nat_ifpaddr(nat, fin->fin_ifp, &in) == -1) { - KFREE(nat); - return NULL; - } - } else if (!in.s_addr && !np->in_outmsk) { - if (l > 1) { - KFREE(nat); - return NULL; - } - in.s_addr = ntohl(ip->ip_src.s_addr); - if (nflags & IPN_TCPUDP) - port = sport; - } else if (nflags & IPN_TCPUDP) { - port = htons(np->in_pnext++); - if (np->in_pnext >= ntohs(np->in_pmax)) { - np->in_pnext = ntohs(np->in_pmin); - np->in_space--; - if (np->in_outmsk != 0xffffffff) - np->in_nip++; - } - } else if (np->in_outmsk != 0xffffffff) { - np->in_space--; - np->in_nip++; - } - - if (!port && (flags & IPN_TCPUDP)) - port = sport; - if ((np->in_nip & ntohl(np->in_outmsk)) > - ntohl(np->in_outip)) - np->in_nip = ntohl(np->in_outip) + 1; - } while (nat_inlookup(fin->fin_ifp, flags, ip->ip_dst, - dport, in, port)); - - /* Setup the NAT table */ - nat->nat_inip = ip->ip_src; - nat->nat_outip.s_addr = htonl(in.s_addr); - nat->nat_oip = ip->ip_dst; - - sum1 = (ntohl(ip->ip_src.s_addr) & 0xffff) + - (ntohl(ip->ip_src.s_addr) >> 16) + ntohs(sport); - - sum2 = (in.s_addr & 0xffff) + (in.s_addr >> 16) + ntohs(port); - - if (flags & IPN_TCPUDP) { - nat->nat_inport = sport; - nat->nat_outport = port; - nat->nat_oport = dport; - } - } else { - - /* - * Otherwise, it's an inbound packet. Most likely, we don't - * want to rewrite source ports and source addresses. Instead, - * we want to rewrite to a fixed internal address and fixed - * internal port. - */ - in.s_addr = ntohl(np->in_inip); - if (!(nport = np->in_pnext)) - nport = dport; - - nat->nat_inip.s_addr = htonl(in.s_addr); - nat->nat_outip = ip->ip_dst; - nat->nat_oip = ip->ip_src; - - sum1 = (ntohl(ip->ip_dst.s_addr) & 0xffff) + - (ntohl(ip->ip_dst.s_addr) >> 16) + ntohs(dport); - - sum2 = (in.s_addr & 0xffff) + (in.s_addr >> 16) + ntohs(nport); - - if (flags & IPN_TCPUDP) { - nat->nat_inport = nport; - nat->nat_outport = dport; - nat->nat_oport = sport; - } - } - - /* Do it twice */ - sum1 = (sum1 & 0xffff) + (sum1 >> 16); - sum1 = (sum1 & 0xffff) + (sum1 >> 16); - - /* Do it twice */ - sum2 = (sum2 & 0xffff) + (sum2 >> 16); - sum2 = (sum2 & 0xffff) + (sum2 >> 16); - - if (sum1 > sum2) - sum2--; /* Because ~1 == -2, We really need ~1 == -1 */ - sumd = sum2 - sum1; - sumd = (sumd & 0xffff) + (sumd >> 16); - nat->nat_sumd = (sumd & 0xffff) + (sumd >> 16); - - if ((flags & IPN_TCPUDP) && ((sport != port) || (dport != nport))) { - if (direction == NAT_OUTBOUND) - sum1 = (ntohl(ip->ip_src.s_addr) & 0xffff) + - (ntohl(ip->ip_src.s_addr) >> 16); - else - sum1 = (ntohl(ip->ip_dst.s_addr) & 0xffff) + - (ntohl(ip->ip_dst.s_addr) >> 16); - - sum2 = (in.s_addr & 0xffff) + (in.s_addr >> 16); - - /* Do it twice */ - sum1 = (sum1 & 0xffff) + (sum1 >> 16); - sum1 = (sum1 & 0xffff) + (sum1 >> 16); - - /* Do it twice */ - sum2 = (sum2 & 0xffff) + (sum2 >> 16); - sum2 = (sum2 & 0xffff) + (sum2 >> 16); - - if (sum1 > sum2) - sum2--; /* Because ~1 == -2, We really need ~1 == -1 */ - sumd = sum2 - sum1; - sumd = (sumd & 0xffff) + (sumd >> 16); - nat->nat_ipsumd = (sumd & 0xffff) + (sumd >> 16); - } else - nat->nat_ipsumd = nat->nat_sumd; - - in.s_addr = htonl(in.s_addr); - nat->nat_next = nat_instances; - nat_instances = nat; - natp = &nat_table[0][nat->nat_inip.s_addr % NAT_SIZE]; - nat->nat_hstart[0] = natp; - nat->nat_hnext[0] = *natp; - *natp = nat; - natp = &nat_table[1][nat->nat_outip.s_addr % NAT_SIZE]; - nat->nat_hstart[1] = natp; - nat->nat_hnext[1] = *natp; - *natp = nat; - nat->nat_ptr = np; - nat->nat_bytes = 0; - nat->nat_pkts = 0; - nat->nat_ifp = fin->fin_ifp; - nat->nat_dir = direction; - if (direction == NAT_OUTBOUND) { - if (flags & IPN_TCPUDP) - tcp->th_sport = port; - } else { - if (flags & IPN_TCPUDP) - tcp->th_dport = nport; - } - nat_stats.ns_added++; - nat_stats.ns_inuse++; - np->in_use++; - return nat; -} - - -nat_t *nat_icmpinlookup(ip, fin) -ip_t *ip; -fr_info_t *fin; -{ - icmphdr_t *icmp; - tcphdr_t *tcp = NULL; - ip_t *oip; - int flags = 0, type; - - 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 < sizeof(*icmp) + sizeof(ip_t))) - 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); - if (oip->ip_p == IPPROTO_TCP) - flags = IPN_TCP; - else if (oip->ip_p == IPPROTO_UDP) - flags = IPN_UDP; - if (flags & IPN_TCPUDP) { - tcp = (tcphdr_t *)((char *)oip + (oip->ip_hl << 2)); - return nat_inlookup(fin->fin_ifp, flags, oip->ip_dst, - tcp->th_dport, oip->ip_src, tcp->th_sport); - } - return nat_inlookup(fin->fin_ifp, 0, oip->ip_src, 0, oip->ip_dst, 0); -} - - -/* - * This should *ONLY* be used for incoming packets to make sure a NAT'd ICMP - * packet gets correctly recognised. - */ -nat_t *nat_icmpin(ip, fin, nflags) -ip_t *ip; -fr_info_t *fin; -int *nflags; -{ - icmphdr_t *icmp; - nat_t *nat; - ip_t *oip; - int flags = 0; - - if (!(nat = nat_icmpinlookup(ip, fin))) - return NULL; - - *nflags = IPN_ICMPERR; - icmp = (icmphdr_t *)fin->fin_dp; - oip = (ip_t *)((char *)icmp + 8); - if (oip->ip_p == IPPROTO_TCP) - flags = IPN_TCP; - else if (oip->ip_p == IPPROTO_UDP) - flags = IPN_UDP; - /* - * Need to adjust ICMP header to include the real IP#'s and - * port #'s. Only apply a checksum change relative to the - * IP address change is it will be modified again in ip_natout - * 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#. - */ - if (flags & IPN_TCPUDP) { - tcphdr_t *tcp = (tcphdr_t *)(oip + 1); - u_32_t sum1, sum2, sumd; - struct in_addr in; - - if (nat->nat_dir == NAT_OUTBOUND) { - sum1 = LONG_SUM(ntohl(oip->ip_src.s_addr)); - in = nat->nat_outip; - oip->ip_src = in; - tcp->th_sport = nat->nat_outport; - } else { - sum1 = LONG_SUM(ntohl(oip->ip_dst.s_addr)); - in = nat->nat_inip; - oip->ip_dst = in; - tcp->th_dport = nat->nat_inport; - } - - sum2 = LONG_SUM(in.s_addr); - - CALC_SUMD(sum1, sum2, sumd); - sumd = (sumd & 0xffff) + (sumd >> 16); - - if (nat->nat_dir == NAT_OUTBOUND) { - fix_incksum(&oip->ip_sum, sumd); - fix_incksum(&icmp->icmp_cksum, sumd); - } else { - fix_outcksum(&oip->ip_sum, sumd); - fix_outcksum(&icmp->icmp_cksum, sumd); - } - - /* - * TCP checksum doesn't make it into the 1st eight - * bytes but UDP does. - */ - if (ip->ip_p == IPPROTO_UDP) { - udphdr_t *udp = (udphdr_t *)tcp; - - if (udp->uh_sum) { - if (nat->nat_dir == NAT_OUTBOUND) - fix_incksum(&udp->uh_sum, - nat->nat_sumd); - else - fix_outcksum(&udp->uh_sum, - nat->nat_sumd); - } - } - } else - ip->ip_dst = nat->nat_outip; - 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. - */ -#ifdef __STDC__ -nat_t *nat_inlookup(void *ifp, int flags, struct in_addr src, u_short sport, struct in_addr mapdst, u_short mapdport) -#else -nat_t *nat_inlookup(ifp, flags, src, sport, mapdst, mapdport) -void *ifp; -register int flags; -struct in_addr src , mapdst; -u_short sport, mapdport; -#endif -{ - register nat_t *nat; - - flags &= IPN_TCPUDP; - - nat = nat_table[1][mapdst.s_addr % NAT_SIZE]; - for (; nat; nat = nat->nat_hnext[1]) - if ((!ifp || ifp == nat->nat_ifp) && - nat->nat_oip.s_addr == src.s_addr && - nat->nat_outip.s_addr == mapdst.s_addr && - flags == nat->nat_flags && (!flags || - (nat->nat_oport == sport && - nat->nat_outport == mapdport))) - return nat; - return NULL; -} - - -/* - * Lookup a nat entry based on the source 'real' ip address/port and - * destination address/port. We use this lookup when sending a packet out, - * we're looking for a table entry, based on the source address. - * NOTE: THE PACKET BEING CHECKED (IF FOUND) HAS A MAPPING ALREADY. - */ -#ifdef __STDC__ -nat_t *nat_outlookup(void *ifp, int flags, struct in_addr src, u_short sport, struct in_addr dst, u_short dport) -#else -nat_t *nat_outlookup(ifp, flags, src, sport, dst, dport) -void *ifp; -register int flags; -struct in_addr src , dst; -u_short sport, dport; -#endif -{ - register nat_t *nat; - - flags &= IPN_TCPUDP; - - nat = nat_table[0][src.s_addr % NAT_SIZE]; - for (; nat; nat = nat->nat_hnext[0]) { - if ((!ifp || ifp == nat->nat_ifp) && - nat->nat_inip.s_addr == src.s_addr && - nat->nat_oip.s_addr == dst.s_addr && - flags == nat->nat_flags && (!flags || - (nat->nat_inport == sport && nat->nat_oport == dport))) - return nat; - } - return NULL; -} - - -/* - * Lookup a nat entry based on the mapped source ip address/port and - * real destination address/port. We use this lookup when sending a packet - * out, we're looking for a table entry, based on the source address. - */ -#ifdef __STDC__ -nat_t *nat_lookupmapip(void *ifp, int flags, struct in_addr mapsrc, u_short mapsport, struct in_addr dst, u_short dport) -#else -nat_t *nat_lookupmapip(ifp, flags, mapsrc, mapsport, dst, dport) -void *ifp; -register int flags; -struct in_addr mapsrc , dst; -u_short mapsport, dport; -#endif -{ - register nat_t *nat; - - flags &= IPN_TCPUDP; - - nat = nat_table[1][mapsrc.s_addr % NAT_SIZE]; - for (; nat; nat = nat->nat_hnext[0]) - if ((!ifp || ifp == nat->nat_ifp) && - nat->nat_oip.s_addr == dst.s_addr && - nat->nat_outip.s_addr == mapsrc.s_addr && - flags == nat->nat_flags && (!flags || - (nat->nat_outport == mapsport && - nat->nat_oport == dport))) - return nat; - return NULL; -} - - -/* - * Lookup the NAT tables to search for a matching redirect - */ -nat_t *nat_lookupredir(np) -register natlookup_t *np; -{ - nat_t *nat; - - /* - * If nl_inip is non null, this is a lookup based on the real - * ip address. Else, we use the fake. - */ - if ((nat = nat_outlookup(NULL, np->nl_flags, np->nl_inip, - np->nl_inport, np->nl_outip, - np->nl_outport))) { - np->nl_realip = nat->nat_outip; - np->nl_realport = nat->nat_outport; - } - return nat; -} - - -/* - * Packets going out on the external interface go through this. - * Here, the source address requires alteration, if anything. - */ -int ip_natout(ip, hlen, fin) -ip_t *ip; -int hlen; -fr_info_t *fin; -{ - register ipnat_t *np; - register u_32_t ipa; - tcphdr_t *tcp = NULL; - u_short nflags = 0, sport = 0, dport = 0, *csump = NULL; - struct ifnet *ifp; - frentry_t *fr; - nat_t *nat; - int natadd = 1; - - if ((fr = fin->fin_fr) && !(fr->fr_flags & FR_DUP) && - fr->fr_tif.fd_ifp && fr->fr_tif.fd_ifp != (void *)-1) - ifp = fr->fr_tif.fd_ifp; - else - ifp = fin->fin_ifp; - - if (!(ip->ip_off & 0x1fff) && !(fin->fin_fi.fi_fl & FI_SHORT)) { - if (ip->ip_p == IPPROTO_TCP) - nflags = IPN_TCP; - else if (ip->ip_p == IPPROTO_UDP) - nflags = IPN_UDP; - if (nflags) { - tcp = (tcphdr_t *)fin->fin_dp; - sport = tcp->th_sport; - dport = tcp->th_dport; - } - } - - ipa = ip->ip_src.s_addr; - - MUTEX_ENTER(&ipf_nat); - if ((ip->ip_off & (IP_OFFMASK|IP_MF)) && - (nat = ipfr_nat_knownfrag(ip, fin))) - natadd = 0; - else if ((nat = nat_outlookup(ifp, nflags, ip->ip_src, sport, - ip->ip_dst, dport))) - ; - else - /* - * If there is no current entry in the nat table for this IP#, - * create one for it (if there is a matching rule). - */ - for (np = nat_list; np; np = np->in_next) - if ((np->in_ifp == ifp) && np->in_space && - (!np->in_flags || (np->in_flags & nflags)) && - ((ipa & np->in_inmsk) == np->in_inip) && - ((np->in_redir & NAT_MAP) || - (np->in_pnext == sport))) { - if (*np->in_plabel && !ap_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)) - continue; - if ((nat = nat_new(np, ip, fin, nflags, - NAT_OUTBOUND))) -#ifdef IPFILTER_LOG - nat_log(nat, (u_short)np->in_redir); -#else - ; -#endif - break; - } - - if (nat) { - if (natadd && fin->fin_fi.fi_fl & FI_FRAG) - ipfr_nat_newfrag(ip, fin, 0, nat); - nat->nat_age = fr_defnatage; - ip->ip_src = nat->nat_outip; - nat->nat_bytes += ip->ip_len; - nat->nat_pkts++; - - /* - * Fix up checksums, not by recalculating them, but - * simply computing adjustments. - */ -#if SOLARIS || defined(__sgi) - if (nat->nat_dir == NAT_OUTBOUND) - fix_outcksum(&ip->ip_sum, nat->nat_ipsumd); - else - fix_incksum(&ip->ip_sum, nat->nat_ipsumd); -#endif - - if (nflags && !(ip->ip_off & 0x1fff) && - !(fin->fin_fi.fi_fl & FI_SHORT)) { - - if (nat->nat_outport) - tcp->th_sport = nat->nat_outport; - - if (ip->ip_p == IPPROTO_TCP) { - csump = &tcp->th_sum; - fr_tcp_age(&nat->nat_age, - nat->nat_state, ip, fin,1); - /* - * 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; - } else if (ip->ip_p == IPPROTO_UDP) { - udphdr_t *udp = (udphdr_t *)tcp; - - if (udp->uh_sum) - csump = &udp->uh_sum; - } else if (ip->ip_p == IPPROTO_ICMP) { - icmphdr_t *ic = (icmphdr_t *)tcp; - - csump = &ic->icmp_cksum; - } - if (csump) { - if (nat->nat_dir == NAT_OUTBOUND) - fix_outcksum(csump, - nat->nat_sumd); - else - fix_incksum(csump, - nat->nat_sumd); - } - } - (void) ap_check(ip, tcp, fin, nat); - nat_stats.ns_mapped[1]++; - MUTEX_EXIT(&ipf_nat); - return -2; - } - MUTEX_EXIT(&ipf_nat); - return 0; -} - - -/* - * Packets coming in from the external interface go through this. - * Here, the destination address requires alteration, if anything. - */ -int ip_natin(ip, hlen, fin) -ip_t *ip; -int hlen; -fr_info_t *fin; -{ - register ipnat_t *np; - register struct in_addr in; - struct ifnet *ifp = fin->fin_ifp; - tcphdr_t *tcp = NULL; - u_short sport = 0, dport = 0, *csump = NULL; - nat_t *nat; - int nflags = 0, natadd = 1; - - if (!(ip->ip_off & 0x1fff) && !(fin->fin_fi.fi_fl & FI_SHORT)) { - if (ip->ip_p == IPPROTO_TCP) - nflags = IPN_TCP; - else if (ip->ip_p == IPPROTO_UDP) - nflags = IPN_UDP; - if (nflags) { - tcp = (tcphdr_t *)((char *)ip + hlen); - dport = tcp->th_dport; - sport = tcp->th_sport; - } - } - - in = ip->ip_dst; - - MUTEX_ENTER(&ipf_nat); - - if ((ip->ip_p == IPPROTO_ICMP) && (nat = nat_icmpin(ip, fin, &nflags))) - ; - else if ((ip->ip_off & IP_OFFMASK) && - (nat = ipfr_nat_knownfrag(ip, fin))) - natadd = 0; - else if ((nat = nat_inlookup(fin->fin_ifp, nflags, ip->ip_src, sport, - ip->ip_dst, dport))) - ; - else - /* - * If there is no current entry in the nat table for this IP#, - * create one for it (if there is a matching rule). - */ - for (np = nat_list; np; np = np->in_next) - if ((np->in_ifp == ifp) && - (!np->in_flags || (nflags & np->in_flags)) && - ((in.s_addr & np->in_outmsk) == np->in_outip) && - (np->in_redir & NAT_REDIRECT) && - (!np->in_pmin || np->in_pmin == dport)) { - if ((nat = nat_new(np, ip, fin, nflags, - NAT_INBOUND))) -#ifdef IPFILTER_LOG - nat_log(nat, (u_short)np->in_redir); -#else - ; -#endif - break; - } - if (nat) { - if (natadd && fin->fin_fi.fi_fl & FI_FRAG) - ipfr_nat_newfrag(ip, fin, 0, nat); - (void) ap_check(ip, tcp, fin, nat); - - if (nflags != IPN_ICMPERR) - nat->nat_age = fr_defnatage; - - ip->ip_dst = nat->nat_inip; - nat->nat_bytes += ip->ip_len; - nat->nat_pkts++; - - /* - * 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 ((nflags & IPN_TCPUDP) && !(ip->ip_off & 0x1fff) && - !(fin->fin_fi.fi_fl & FI_SHORT)) { - - if (nat->nat_inport) - tcp->th_dport = nat->nat_inport; - - if (ip->ip_p == IPPROTO_TCP) { - csump = &tcp->th_sum; - fr_tcp_age(&nat->nat_age, - nat->nat_state, ip, fin,0); - /* - * 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; - } else if (ip->ip_p == IPPROTO_UDP) { - udphdr_t *udp = (udphdr_t *)tcp; - - if (udp->uh_sum) - csump = &udp->uh_sum; - } else if (ip->ip_p == IPPROTO_ICMP) { - icmphdr_t *ic = (icmphdr_t *)tcp; - - csump = &ic->icmp_cksum; - } - if (csump) { - if (nat->nat_dir == NAT_OUTBOUND) - fix_incksum(csump, - nat->nat_sumd); - else - fix_outcksum(csump, - nat->nat_sumd); - } - } - nat_stats.ns_mapped[0]++; - MUTEX_EXIT(&ipf_nat); - return -2; - } - MUTEX_EXIT(&ipf_nat); - return 0; -} - - -/* - * Free all memory used by NAT structures allocated at runtime. - */ -void ip_natunload() -{ - MUTEX_ENTER(&ipf_nat); - (void) nat_clearlist(); - (void) nat_flushtable(); - (void) ap_unload(); - MUTEX_EXIT(&ipf_nat); -} - - -/* - * Slowly expire held state for NAT entries. Timeouts are set in - * expectation of this being called twice per second. - */ -void ip_natexpire() -{ - register struct nat *nat, **natp; -#if defined(_KERNEL) && !SOLARIS - int s; -#endif - - SPL_NET(s); - MUTEX_ENTER(&ipf_nat); - for (natp = &nat_instances; (nat = *natp); ) { - 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++; - } - - ap_expire(); - - MUTEX_EXIT(&ipf_nat); - SPL_X(s); -} - - -/* - */ -#ifdef __STDC__ -void ip_natsync(void *ifp) -#else -void ip_natsync(ifp) -void *ifp; -#endif -{ - register nat_t *nat; - register u_32_t sum1, sum2, sumd; - struct in_addr in; - ipnat_t *np; -#if defined(_KERNEL) && !SOLARIS - int s; -#endif - - SPL_NET(s); - MUTEX_ENTER(&ipf_nat); - for (nat = nat_instances; nat; nat = nat->nat_next) - if ((ifp == nat->nat_ifp) && (np = nat->nat_ptr)) - if ((np->in_outmsk == 0xffffffff) && !np->in_nip) { - /* - * Change the map-to address to be the same - * as the new one. - */ - sum1 = nat->nat_outip.s_addr; - if (nat_ifpaddr(nat, ifp, &in) == -1) - nat->nat_outip.s_addr = htonl(in.s_addr); - sum2 = nat->nat_outip.s_addr; - - /* - * Readjust the checksum adjustment to take - * into account the new IP#. - * - * Do it twice - */ - sum1 = (sum1 & 0xffff) + (sum1 >> 16); - sum1 = (sum1 & 0xffff) + (sum1 >> 16); - - /* Do it twice */ - sum2 = (sum2 & 0xffff) + (sum2 >> 16); - sum2 = (sum2 & 0xffff) + (sum2 >> 16); - - /* Because ~1 == -2, We really need ~1 == -1 */ - if (sum1 > sum2) - sum2--; - sumd = sum2 - sum1; - sumd = (sumd & 0xffff) + (sumd >> 16); - sumd += nat->nat_sumd; - nat->nat_sumd = (sumd & 0xffff) + (sumd >> 16); - } - MUTEX_EXIT(&ipf_nat); - SPL_X(s); -} - - -#ifdef IPFILTER_LOG -# ifdef __STDC__ -void nat_log(struct nat *nat, u_short type) -# else -void nat_log(nat, type) -struct nat *nat; -u_short type; -# endif -{ - 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_type = type; - natl.nl_rule = -1; - if (nat->nat_ptr) { - for (rulen = 0, np = nat_list; np; np = np->in_next, rulen++) - if (np == nat->nat_ptr) { - natl.nl_rule = rulen; - break; - } - } - items[0] = &natl; - sizes[0] = sizeof(natl); - types[0] = 0; - - (void) ipllog(IPL_LOGNAT, 0, items, sizes, types, 1); -} -#endif diff --git a/sys/contrib/ipfilter/netinet/ip_nat.h b/sys/contrib/ipfilter/netinet/ip_nat.h deleted file mode 100644 index d02a844..0000000 --- a/sys/contrib/ipfilter/netinet/ip_nat.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 1995-1997 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 - * $FreeBSD$ - */ - -#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', 80, struct ipnat) -#define SIOCRMNAT _IOW('r', 81, struct ipnat) -#define SIOCGNATS _IOR('r', 82, struct natstat) -#define SIOCGNATL _IOWR('r', 83, struct natlookup) -#define SIOCGFRST _IOR('r', 84, struct ipfrstat) -#define SIOCGIPST _IOR('r', 85, struct ips_stat) -#define SIOCFLNAT _IOWR('r', 86, int) -#define SIOCCNATL _IOWR('r', 87, int) -#else -#define SIOCADNAT _IOW(r, 80, struct ipnat) -#define SIOCRMNAT _IOW(r, 81, struct ipnat) -#define SIOCGNATS _IOR(r, 82, struct natstat) -#define SIOCGNATL _IOWR(r, 83, struct natlookup) -#define SIOCGFRST _IOR(r, 84, struct ipfrstat) -#define SIOCGIPST _IOR(r, 85, struct ips_stat) -#define SIOCFLNAT _IOWR(r, 86, int) -#define SIOCCNATL _IOWR(r, 87, int) -#endif - -#define NAT_SIZE 367 -#ifndef APR_LABELLEN -#define APR_LABELLEN 16 -#endif - -typedef struct nat { - u_long nat_age; - int nat_flags; - u_32_t nat_sumd; - u_32_t nat_ipsumd; - void *nat_data; - 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_state[2]; - struct ipnat *nat_ptr; - struct nat *nat_next; - struct nat *nat_hnext[2]; - struct nat **nat_hstart[2]; - void *nat_ifp; - int nat_dir; -} nat_t; - -typedef struct ipnat { - struct ipnat *in_next; - void *in_ifp; - void *in_apr; - u_int in_space; - u_int in_use; - struct in_addr in_nextip; - u_short in_pnext; - u_short in_flags; - u_short in_port[2]; - struct in_addr in_in[2]; - struct in_addr in_out[2]; - 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 */ - u_short in_dport; -} 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 NAT_OUTBOUND 0 -#define NAT_INBOUND 1 - -#define NAT_MAP 0x01 -#define NAT_REDIRECT 0x02 -#define NAT_BIMAP (NAT_MAP|NAT_REDIRECT) - -#define IPN_CMPSIZ (sizeof(struct in_addr) * 4 + sizeof(u_short) * 3 + \ - sizeof(int) + IFNAMSIZ + APR_LABELLEN + sizeof(char)) - -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 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; - nat_t **ns_table[2]; - ipnat_t *ns_list; -} natstat_t; - -#define IPN_ANY 0x00 -#define IPN_TCP 0x01 -#define IPN_UDP 0x02 -#define IPN_TCPUDP 0x03 -#define IPN_DELETE 0x04 -#define IPN_ICMPERR 0x08 - - -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; -} natlog_t; - - -#define NL_NEWMAP NAT_MAP -#define NL_NEWRDR NAT_REDIRECT -#define NL_EXPIRE 0xffff - - -extern void ip_natsync __P((void *)); -extern u_long fr_defnatage; -extern u_long fr_defnaticmpage; -extern nat_t *nat_table[2][NAT_SIZE]; -#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 nat_t *nat_new __P((ipnat_t *, ip_t *, fr_info_t *, u_short, int)); -extern nat_t *nat_outlookup __P((void *, int, struct in_addr, u_short, - struct in_addr, u_short)); -extern nat_t *nat_inlookup __P((void *, int, struct in_addr, u_short, - struct in_addr, u_short)); -extern nat_t *nat_lookupredir __P((natlookup_t *)); -extern nat_t *nat_lookupmapip __P((void *, int, struct in_addr, u_short, - struct in_addr, u_short)); -extern nat_t *nat_icmpinlookup __P((ip_t *, fr_info_t *)); -extern nat_t *nat_icmpin __P((ip_t *, fr_info_t *, int *)); - -extern int ip_natout __P((ip_t *, int, fr_info_t *)); -extern int ip_natin __P((ip_t *, int, fr_info_t *)); -extern void ip_natunload __P((void)), ip_natexpire __P((void)); -extern void nat_log __P((struct nat *, u_short)); -extern void fix_incksum __P((u_short *, u_32_t)); -extern void fix_outcksum __P((u_short *, u_32_t)); - -#endif /* __IP_NAT_H__ */ diff --git a/sys/contrib/ipfilter/netinet/ip_proxy.c b/sys/contrib/ipfilter/netinet/ip_proxy.c deleted file mode 100644 index e604051..0000000 --- a/sys/contrib/ipfilter/netinet/ip_proxy.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright (C) 1997 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[] = "@(#)$FreeBSD$"; -#endif - -#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL) -# define _KERNEL -#endif - -#if !defined(_KERNEL) && !defined(KERNEL) -# include <stdio.h> -# include <string.h> -# include <stdlib.h> -#endif -#include <sys/errno.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/time.h> -#include <sys/file.h> -#if !defined(__FreeBSD__) -# 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) -# 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> -# include <sys/dditypes.h> -# include <sys/stream.h> -# include <sys/kmem.h> -#endif -#if __FreeBSD__ > 2 -# include <sys/queue.h> -# include <sys/malloc.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" - -#ifndef MIN -#define MIN(a,b) (((a)<(b))?(a):(b)) -#endif - -static ap_session_t *ap_find __P((ip_t *, tcphdr_t *)); -static ap_session_t *ap_new_session __P((aproxy_t *, ip_t *, tcphdr_t *, - fr_info_t *, nat_t *)); - -static int ap_matchsrcdst __P((ap_session_t *aps, struct in_addr src, - struct in_addr dst, void *tcp, u_short sport, - u_short dport)); - -#define AP_SESS_SIZE 53 - -#if defined(_KERNEL) && !defined(linux) -#include "netinet/ip_ftp_pxy.c" -#endif - -ap_session_t *ap_sess_tab[AP_SESS_SIZE]; -aproxy_t ap_proxies[] = { -#ifdef IPF_FTP_PROXY - { "ftp", (char)IPPROTO_TCP, 0, 0, ippr_ftp_init, ippr_ftp_in, ippr_ftp_out }, -#endif - { "", '\0', 0, 0, NULL, NULL } -}; - - -int ap_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->apr_flags & APR_DELETE)) || - (ip->ip_p != apr->apr_p)) - return 0; - if ((tcp && (tcp->th_dport != dport)) || (!tcp && dport)) - return 0; - return 1; -} - - -static int -ap_matchsrcdst(aps, src, dst, tcp, sport, dport) -ap_session_t *aps; -struct in_addr src, dst; -void *tcp; -u_short sport, dport; -{ - if (aps->aps_dst.s_addr == dst.s_addr) { - if ((aps->aps_src.s_addr == src.s_addr) && - (!tcp || ((sport == aps->aps_sport) && - (dport == aps->aps_dport)))) - return 1; - } else if (aps->aps_dst.s_addr == src.s_addr) { - if ((aps->aps_src.s_addr == dst.s_addr) && - (!tcp || ((sport == aps->aps_dport) && - (dport == aps->aps_sport)))) - return 1; - } - return 0; -} - - -static ap_session_t *ap_find(ip, tcp) -ip_t *ip; -tcphdr_t *tcp; -{ - register u_char p = ip->ip_p; - register ap_session_t *aps; - register u_short sp, dp; - register u_long hv; - struct in_addr src, dst; - - src = ip->ip_src, dst = ip->ip_dst; - sp = dp = 0; /* XXX gcc -Wunitialized */ - - hv = ip->ip_src.s_addr ^ ip->ip_dst.s_addr; - hv *= 651733; - if (tcp) { - sp = tcp->th_sport; - dp = tcp->th_dport; - hv ^= (sp + dp); - hv *= 5; - } - hv %= AP_SESS_SIZE; - - for (aps = ap_sess_tab[hv]; aps; aps = aps->aps_next) - if ((aps->aps_p == p) && - ap_matchsrcdst(aps, src, dst, tcp, sp, dp)) - break; - return aps; -} - - -/* - * 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 *ap_new_session(apr, ip, tcp, fin, nat) -aproxy_t *apr; -ip_t *ip; -tcphdr_t *tcp; -fr_info_t *fin; -nat_t *nat; -{ - register ap_session_t *aps; - u_short dport; - u_long hv; - - if (!apr || (apr && (apr->apr_flags & APR_DELETE)) || - (ip->ip_p != apr->apr_p)) - return NULL; - dport = nat->nat_ptr->in_dport; - if ((tcp && (tcp->th_dport != dport)) || (!tcp && dport)) - return NULL; - - hv = ip->ip_src.s_addr ^ ip->ip_dst.s_addr; - hv *= 651733; - if (tcp) { - hv ^= (tcp->th_sport + tcp->th_dport); - hv *= 5; - } - hv %= AP_SESS_SIZE; - - KMALLOC(aps, ap_session_t *, sizeof(*aps)); - if (!aps) - return NULL; - bzero((char *)aps, sizeof(*aps)); - aps->aps_apr = apr; - aps->aps_src = ip->ip_src; - aps->aps_dst = ip->ip_dst; - aps->aps_p = ip->ip_p; - aps->aps_tout = 1200; /* XXX */ - if (tcp) { - aps->aps_sport = tcp->th_sport; - aps->aps_dport = tcp->th_dport; - } - aps->aps_data = NULL; - aps->aps_psiz = 0; - aps->aps_next = ap_sess_tab[hv]; - ap_sess_tab[hv] = aps; - (void) (*apr->apr_init)(fin, ip, tcp, aps, nat); - return aps; -} - - -/* - * check to see if a packet should be passed through an active proxy routine - * if one has been setup for it. - */ -int ap_check(ip, tcp, fin, nat) -ip_t *ip; -tcphdr_t *tcp; -fr_info_t *fin; -nat_t *nat; -{ - ap_session_t *aps; - aproxy_t *apr; - int err; - - if (!(fin->fin_fi.fi_fl & FI_TCPUDP)) - tcp = NULL; - - if ((aps = ap_find(ip, tcp)) || - (aps = ap_new_session(nat->nat_ptr->in_apr, ip, tcp, fin, nat))) { - if (ip->ip_p == IPPROTO_TCP) { - /* - * verify that the checksum is correct. If not, then - * don't do anything with this packet. - */ - if (tcp->th_sum != fr_tcpsum(*(mb_t **)fin->fin_mp, - ip, tcp, ip->ip_len)) { - frstats[fin->fin_out].fr_tcpbad++; - return -1; - } - fr_tcp_age(&aps->aps_tout, aps->aps_state, ip, fin, - tcp->th_sport == aps->aps_sport); - } - - apr = aps->aps_apr; - err = 0; - if (fin->fin_out) { - if (apr->apr_outpkt) - err = (*apr->apr_outpkt)(fin, ip, tcp, - aps, nat); - } else { - if (apr->apr_inpkt) - err = (*apr->apr_inpkt)(fin, ip, tcp, - aps, nat); - } - if (err == 2) { - tcp->th_sum = fr_tcpsum(*(mb_t **)fin->fin_mp, ip, - tcp, ip->ip_len); - err = 0; - } - return err; - } - return -1; -} - - -aproxy_t *ap_match(pr, name) -u_char 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; - } - return NULL; -} - - -void ap_free(ap) -aproxy_t *ap; -{ - ap->apr_ref--; -} - - -void aps_free(aps) -ap_session_t *aps; -{ - if (aps->aps_data && aps->aps_psiz) - KFREES(aps->aps_data, aps->aps_psiz); - KFREE(aps); -} - - -void ap_unload() -{ - ap_session_t *aps; - int i; - - for (i = 0; i < AP_SESS_SIZE; i++) - while ((aps = ap_sess_tab[i])) { - ap_sess_tab[i] = aps->aps_next; - aps_free(aps); - } -} - - -void ap_expire() -{ - ap_session_t *aps, **apsp; - int i; - - for (i = 0; i < AP_SESS_SIZE; i++) - for (apsp = &ap_sess_tab[i]; (aps = *apsp); ) { - aps->aps_tout--; - if (!aps->aps_tout) { - ap_sess_tab[i] = aps->aps_next; - aps_free(aps); - *apsp = aps->aps_next; - } else - apsp = &aps->aps_next; - } -} diff --git a/sys/contrib/ipfilter/netinet/ip_proxy.h b/sys/contrib/ipfilter/netinet/ip_proxy.h deleted file mode 100644 index cd7e9f9..0000000 --- a/sys/contrib/ipfilter/netinet/ip_proxy.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 1997 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. - * - * $FreeBSD$ - */ - -#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; /* seqoff/after set selector */ - short apt_seqoff[2]; /* sequence # difference */ - tcp_seq apt_after[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; - struct in_addr aps_src; /* source IP# */ - struct in_addr aps_dst; /* destination IP# */ - u_char aps_p; /* protocol */ - union { - struct ap_tcp apu_tcp; - struct ap_udp apu_udp; - } aps_un; - u_int aps_flags; - QUAD_T aps_bytes; /* bytes sent */ - QUAD_T aps_pkts; /* packets sent */ - u_long aps_tout; /* time left before expiring */ - void *aps_data; /* private data */ - int aps_psiz; /* size of private data */ - 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_after aps_un.apu_tcp.apt_after -#define aps_state aps_un.apu_tcp.apt_state - - -typedef struct aproxy { - 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((fr_info_t *, ip_t *, tcphdr_t *, - ap_session_t *, struct nat *)); - int (* apr_inpkt) __P((fr_info_t *, ip_t *, tcphdr_t *, - ap_session_t *, struct nat *)); - int (* apr_outpkt) __P((fr_info_t *, ip_t *, tcphdr_t *, - ap_session_t *, struct nat *)); -} aproxy_t; - -#define APR_DELETE 1 - - -extern ap_session_t *ap_sess_tab[AP_SESS_SIZE]; -extern aproxy_t ap_proxies[]; - -extern int ap_ok __P((ip_t *, tcphdr_t *, struct ipnat *)); -extern void ap_unload __P((void)); -extern void ap_free __P((aproxy_t *)); -extern void aps_free __P((ap_session_t *)); -extern int ap_check __P((ip_t *, tcphdr_t *, fr_info_t *, struct nat *)); -extern aproxy_t *ap_match __P((u_char, char *)); -extern void ap_expire __P((void)); - -#endif /* __IP_PROXY_H__ */ diff --git a/sys/contrib/ipfilter/netinet/ip_state.c b/sys/contrib/ipfilter/netinet/ip_state.c deleted file mode 100644 index d5a3637..0000000 --- a/sys/contrib/ipfilter/netinet/ip_state.c +++ /dev/null @@ -1,799 +0,0 @@ -/* - * Copyright (C) 1995-1997 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-1995 Darren Reed"; -static const char rcsid[] = "@(#)$FreeBSD$"; -#endif - -#include "opt_ipfilter.h" -#if defined(KERNEL) && !defined(_KERNEL) -#define _KERNEL -#endif -#define __FreeBSD_version 300000 /* it's a hack, but close enough */ - -#if !defined(_KERNEL) && !defined(KERNEL) && !defined(__KERNEL__) -# include <stdlib.h> -# include <string.h> -#else -# ifdef linux -# include <linux/kernel.h> -# include <linux/module.h> -# endif -#endif -#include <sys/errno.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/file.h> -#if defined(KERNEL) && (__FreeBSD_version >= 220000) -# include <sys/filio.h> -# include <sys/fcntl.h> -# include <sys/malloc.h> -#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(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> -# include <sys/dditypes.h> -# include <sys/stream.h> -# include <sys/kmem.h> -#endif - -#include <net/if.h> -#ifdef sun -#include <net/af.h> -#endif -#include <net/route.h> -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <netinet/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" -#ifndef MIN -#define MIN(a,b) (((a)<(b))?(a):(b)) -#endif - -#define TCP_CLOSE (TH_FIN|TH_RST) - -static ipstate_t *ips_table[IPSTATE_SIZE]; -static int ips_num = 0; -static ips_stat_t ips_stats; -#if (SOLARIS || defined(__sgi)) && defined(_KERNEL) -extern kmutex_t ipf_state; -#endif - -static int fr_matchsrcdst __P((ipstate_t *, struct in_addr, struct in_addr, - fr_info_t *, void *, u_short, u_short)); -static int fr_state_flush __P((int)); -static ips_stat_t *fr_statetstats __P((void)); - - -#define FIVE_DAYS (2 * 5 * 86400) /* 5 days: half closed session */ - -u_long fr_tcpidletimeout = FIVE_DAYS, - fr_tcpclosewait = 60, - fr_tcplastack = 20, - fr_tcptimeout = 120, - fr_tcpclosed = 1, - fr_udptimeout = 120, - fr_icmptimeout = 120; - - -static ips_stat_t *fr_statetstats() -{ - ips_stats.iss_active = ips_num; - ips_stats.iss_table = ips_table; - 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 int i; - register ipstate_t *is, **isp; -#if defined(_KERNEL) && !SOLARIS - int s; -#endif - int delete, removed = 0; - - SPL_NET(s); - MUTEX_ENTER(&ipf_state); - for (i = 0; i < IPSTATE_SIZE; i++) - for (isp = &ips_table[i]; (is = *isp); ) { - delete = 0; - - switch (which) - { - case 0 : - delete = 1; - break; - case 1 : - if ((is->is_p == IPPROTO_TCP) && - (((is->is_state[0] <= TCPS_ESTABLISHED) && - (is->is_state[1] > TCPS_ESTABLISHED)) || - ((is->is_state[1] <= TCPS_ESTABLISHED) && - (is->is_state[0] > TCPS_ESTABLISHED)))) - delete = 1; - break; - } - - if (delete) { - *isp = is->is_next; - if (is->is_p == IPPROTO_TCP) - ips_stats.iss_fin++; - else - ips_stats.iss_expire++; -#ifdef IPFILTER_LOG - ipstate_log(is, ISL_FLUSH); -#endif - KFREE(is); - ips_num--; - removed++; - } else - isp = &is->is_next; - } - MUTEX_EXIT(&ipf_state); - SPL_X(s); - return removed; -} - - -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 SIOCIPFFL : - IRCOPY(data, (caddr_t)&arg, sizeof(arg)); - if (arg == 0 || arg == 1) { - ret = fr_state_flush(arg); - IWCOPY((caddr_t)&ret, data, sizeof(ret)); - } else - error = EINVAL; - break; - case SIOCGIPST : - IWCOPY((caddr_t)fr_statetstats(), data, sizeof(ips_stat_t)); - break; - case FIONREAD : -#ifdef IPFILTER_LOG - IWCOPY((caddr_t)&iplused[IPL_LOGSTATE], (caddr_t)data, - sizeof(iplused[IPL_LOGSTATE])); -#endif - break; - default : - return EINVAL; - } - return error; -} - - -/* - * Create a new ipstate structure and hang it off the hash table. - */ -int fr_addstate(ip, fin, pass) -ip_t *ip; -fr_info_t *fin; -u_int pass; -{ - ipstate_t ips; - register ipstate_t *is = &ips; - register u_int hv; - - if ((ip->ip_off & 0x1fff) || (fin->fin_fi.fi_fl & FI_SHORT)) - return -1; - if (ips_num == IPSTATE_MAX) { - ips_stats.iss_max++; - return -1; - } - ips.is_age = 1; - ips.is_state[0] = 0; - ips.is_state[1] = 0; - /* - * Copy and calculate... - */ - hv = (is->is_p = ip->ip_p); - hv += (is->is_src.s_addr = ip->ip_src.s_addr); - hv += (is->is_dst.s_addr = ip->ip_dst.s_addr); - - switch (ip->ip_p) - { - case IPPROTO_ICMP : - { - struct icmp *ic = (struct icmp *)fin->fin_dp; - - switch (ic->icmp_type) - { - case ICMP_ECHO : - is->is_icmp.ics_type = ICMP_ECHOREPLY; /* XXX */ - hv += (is->is_icmp.ics_id = ic->icmp_id); - hv += (is->is_icmp.ics_seq = ic->icmp_seq); - break; - case ICMP_TSTAMP : - case ICMP_IREQ : - case ICMP_MASKREQ : - is->is_icmp.ics_type = ic->icmp_type + 1; - break; - default : - return -1; - } - ips_stats.iss_icmp++; - is->is_age = fr_icmptimeout; - break; - } - case IPPROTO_TCP : - { - register tcphdr_t *tcp = (tcphdr_t *)fin->fin_dp; - - /* - * The endian of the ports doesn't matter, but the ack and - * sequence numbers do as we do mathematics on them later. - */ - hv += (is->is_dport = tcp->th_dport); - hv += (is->is_sport = tcp->th_sport); - is->is_seq = ntohl(tcp->th_seq); - is->is_ack = ntohl(tcp->th_ack); - is->is_swin = ntohs(tcp->th_win); - is->is_dwin = is->is_swin; /* start them the same */ - ips_stats.iss_tcp++; - /* - * If we're creating state for a starting connection, start the - * timer on it as we'll never see an error if it fails to - * connect. - */ - if ((tcp->th_flags & (TH_SYN|TH_ACK)) == TH_SYN) - is->is_ack = 0; /* Trumpet WinSock 'ism */ - fr_tcp_age(&is->is_age, is->is_state, ip, fin, - tcp->th_sport == is->is_sport); - break; - } - case IPPROTO_UDP : - { - register tcphdr_t *tcp = (tcphdr_t *)fin->fin_dp; - - hv += (is->is_dport = tcp->th_dport); - hv += (is->is_sport = tcp->th_sport); - ips_stats.iss_udp++; - is->is_age = fr_udptimeout; - break; - } - default : - return -1; - } - - KMALLOC(is, ipstate_t *, sizeof(*is)); - if (is == NULL) { - ips_stats.iss_nomem++; - return -1; - } - bcopy((char *)&ips, (char *)is, sizeof(*is)); - hv %= IPSTATE_SIZE; - MUTEX_ENTER(&ipf_state); - - is->is_pass = pass; - is->is_pkts = 1; - is->is_bytes = ip->ip_len; - /* - * Copy these from the rule itself. - */ - is->is_opt = fin->fin_fr->fr_ip.fi_optmsk; - is->is_optmsk = fin->fin_fr->fr_mip.fi_optmsk; - is->is_sec = fin->fin_fr->fr_ip.fi_secmsk; - is->is_secmsk = fin->fin_fr->fr_mip.fi_secmsk; - is->is_auth = fin->fin_fr->fr_ip.fi_auth; - is->is_authmsk = fin->fin_fr->fr_mip.fi_auth; - is->is_flags = fin->fin_fr->fr_ip.fi_fl; - is->is_flags |= fin->fin_fr->fr_mip.fi_fl << 4; - /* - * add into table. - */ - is->is_next = ips_table[hv]; - ips_table[hv] = is; - if (fin->fin_out) { - is->is_ifpin = NULL; - is->is_ifpout = fin->fin_ifp; - } else { - is->is_ifpin = fin->fin_ifp; - is->is_ifpout = NULL; - } - if (pass & FR_LOGFIRST) - is->is_pass &= ~(FR_LOGFIRST|FR_LOG); - ips_num++; -#ifdef IPFILTER_LOG - ipstate_log(is, ISL_NEW); -#endif - MUTEX_EXIT(&ipf_state); - if (fin->fin_fi.fi_fl & FI_FRAG) - ipfr_newfrag(ip, fin, pass ^ FR_KEEPSTATE); - return 0; -} - - -/* - * check to see if a packet with TCP headers fits within the TCP window. - * change timeout depending on whether new packet is a SYN-ACK returning for a - * SYN or a RST or FIN which indicate time to close up shop. - */ -int fr_tcpstate(is, fin, ip, tcp) -register ipstate_t *is; -fr_info_t *fin; -ip_t *ip; -tcphdr_t *tcp; -{ - register int seqskew, ackskew; - register u_short swin, dwin; - register tcp_seq seq, ack; - int source; - - /* - * Find difference between last checked packet and this packet. - */ - seq = ntohl(tcp->th_seq); - ack = ntohl(tcp->th_ack); - source = (ip->ip_src.s_addr == is->is_src.s_addr); - - if (!(tcp->th_flags & TH_ACK)) /* Pretend an ack was sent */ - ack = source ? is->is_ack : is->is_seq; - - if (source) { - if (!is->is_seq) - /* - * Must be an outgoing SYN-ACK in reply to a SYN. - */ - is->is_seq = seq; - seqskew = seq - is->is_seq; - ackskew = ack - is->is_ack; - } else { - if (!is->is_ack) - /* - * Must be a SYN-ACK in reply to a SYN. - */ - is->is_ack = seq; - ackskew = seq - is->is_ack; - seqskew = ack - is->is_seq; - } - - /* - * Make skew values absolute - */ - if (seqskew < 0) - seqskew = -seqskew; - if (ackskew < 0) - ackskew = -ackskew; - - /* - * If the difference in sequence and ack numbers is within the - * window size of the connection, store these values and match - * the packet. - */ - if (source) { - swin = is->is_swin; - dwin = is->is_dwin; - } else { - dwin = is->is_swin; - swin = is->is_dwin; - } - - if ((seqskew <= dwin) && (ackskew <= swin)) { - if (source) { - is->is_seq = seq; - is->is_ack = ack; - is->is_swin = ntohs(tcp->th_win); - } else { - is->is_seq = ack; - is->is_ack = seq; - is->is_dwin = ntohs(tcp->th_win); - } - ips_stats.iss_hits++; - is->is_pkts++; - is->is_bytes += ip->ip_len; - /* - * Nearing end of connection, start timeout. - */ - fr_tcp_age(&is->is_age, is->is_state, ip, fin, source); - return 1; - } - return 0; -} - - -static int fr_matchsrcdst(is, src, dst, fin, tcp, sp, dp) -ipstate_t *is; -struct in_addr src, dst; -fr_info_t *fin; -void *tcp; -u_short sp, dp; -{ - int ret = 0, rev, out; - void *ifp; - - rev = (is->is_dst.s_addr != dst.s_addr); - ifp = fin->fin_ifp; - out = fin->fin_out; - - if (!rev) { - if (out) { - if (!is->is_ifpout) - is->is_ifpout = ifp; - } else { - if (!is->is_ifpin) - is->is_ifpin = ifp; - } - } else { - if (out) { - if (!is->is_ifpin) - is->is_ifpin = ifp; - } else { - if (!is->is_ifpout) - is->is_ifpout = ifp; - } - } - - if (!rev) { - if (((out && is->is_ifpout == ifp) || - (!out && is->is_ifpin == ifp)) && - (is->is_dst.s_addr == dst.s_addr) && - (is->is_src.s_addr == src.s_addr) && - (!tcp || ((sp == is->is_sport) && - (dp == is->is_dport)))) { - ret = 1; - } - } else { - if (((out && is->is_ifpin == ifp) || - (!out && is->is_ifpout == ifp)) && - (is->is_dst.s_addr == src.s_addr) && - (is->is_src.s_addr == dst.s_addr) && - (!tcp || ((sp == is->is_dport) && - (dp == is->is_sport)))) { - ret = 1; - } - } - - /* - * Whether or not this should be here, is questionable, but the aim - * is to get this out of the main line. - */ - if (ret) { - if (((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) || - ((fin->fin_fi.fi_fl & (is->is_flags >> 4)) != - (is->is_flags & 0xf))) - ret = 0; - } - return ret; -} - - -/* - * Check if a packet has a registered state. - */ -int fr_checkstate(ip, fin) -ip_t *ip; -fr_info_t *fin; -{ - register struct in_addr dst, src; - register ipstate_t *is, **isp; - register u_char pr; - struct icmp *ic; - tcphdr_t *tcp; - u_int hv, hlen, pass; - - if ((ip->ip_off & 0x1fff) || (fin->fin_fi.fi_fl & FI_SHORT)) - return 0; - - hlen = fin->fin_hlen; - tcp = (tcphdr_t *)((char *)ip + hlen); - ic = (struct icmp *)tcp; - hv = (pr = ip->ip_p); - hv += (src.s_addr = ip->ip_src.s_addr); - hv += (dst.s_addr = ip->ip_dst.s_addr); - - /* - * Search the hash table for matching packet header info. - */ - switch (ip->ip_p) - { - case IPPROTO_ICMP : - hv += ic->icmp_id; - hv += ic->icmp_seq; - hv %= IPSTATE_SIZE; - MUTEX_ENTER(&ipf_state); - for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_next) - if ((is->is_p == pr) && - (ic->icmp_id == is->is_icmp.ics_id) && - (ic->icmp_seq == is->is_icmp.ics_seq) && - fr_matchsrcdst(is, src, dst, fin, NULL, 0, 0)) { - if (is->is_icmp.ics_type != ic->icmp_type) - continue; - is->is_age = fr_icmptimeout; - is->is_pkts++; - is->is_bytes += ip->ip_len; - ips_stats.iss_hits++; - pass = is->is_pass; - MUTEX_EXIT(&ipf_state); - return pass; - } - MUTEX_EXIT(&ipf_state); - break; - case IPPROTO_TCP : - { - register u_short dport = tcp->th_dport, sport = tcp->th_sport; - - hv += dport; - hv += sport; - hv %= IPSTATE_SIZE; - MUTEX_ENTER(&ipf_state); - for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_next) - if ((is->is_p == pr) && - fr_matchsrcdst(is, src, dst, fin, tcp, - sport, dport)) { - if (fr_tcpstate(is, fin, ip, tcp)) { - pass = is->is_pass; -#ifdef _KERNEL - MUTEX_EXIT(&ipf_state); -#else - - if (tcp->th_flags & TCP_CLOSE) { - *isp = is->is_next; - isp = &ips_table[hv]; - KFREE(is); - } -#endif - return pass; - } - } - MUTEX_EXIT(&ipf_state); - break; - } - case IPPROTO_UDP : - { - register u_short dport = tcp->th_dport, sport = tcp->th_sport; - - hv += dport; - hv += sport; - hv %= IPSTATE_SIZE; - /* - * Nothing else to match on but ports. and IP#'s - */ - MUTEX_ENTER(&ipf_state); - for (is = ips_table[hv]; is; is = is->is_next) - if ((is->is_p == pr) && - fr_matchsrcdst(is, src, dst, fin, - tcp, sport, dport)) { - ips_stats.iss_hits++; - is->is_pkts++; - is->is_bytes += ip->ip_len; - is->is_age = fr_udptimeout; - pass = is->is_pass; - MUTEX_EXIT(&ipf_state); - return pass; - } - MUTEX_EXIT(&ipf_state); - break; - } - default : - break; - } - ips_stats.iss_miss++; - return 0; -} - - -/* - * Free memory in use by all state info. kept. - */ -void fr_stateunload() -{ - register int i; - register ipstate_t *is, **isp; - - MUTEX_ENTER(&ipf_state); - for (i = 0; i < IPSTATE_SIZE; i++) - for (isp = &ips_table[i]; (is = *isp); ) { - *isp = is->is_next; - KFREE(is); - } - MUTEX_EXIT(&ipf_state); -} - - -/* - * Slowly expire held state for thingslike UDP and ICMP. Timeouts are set - * in expectation of this being called twice per second. - */ -void fr_timeoutstate() -{ - register int i; - register ipstate_t *is, **isp; -#if defined(_KERNEL) && !SOLARIS - int s; -#endif - - SPL_NET(s); - MUTEX_ENTER(&ipf_state); - for (i = 0; i < IPSTATE_SIZE; i++) - for (isp = &ips_table[i]; (is = *isp); ) - if (is->is_age && !--is->is_age) { - *isp = is->is_next; - if (is->is_p == IPPROTO_TCP) - ips_stats.iss_fin++; - else - ips_stats.iss_expire++; -#ifdef IPFILTER_LOG - ipstate_log(is, ISL_EXPIRE); -#endif - KFREE(is); - ips_num--; - } else - isp = &is->is_next; - MUTEX_EXIT(&ipf_state); - SPL_X(s); -} - - -/* - * Original idea freom Pradeep Krishnan for use primarily with NAT code. - * (pkrishna@netcom.com) - */ -void fr_tcp_age(age, state, ip, fin, dir) -u_long *age; -u_char *state; -ip_t *ip; -fr_info_t *fin; -int dir; -{ - tcphdr_t *tcp = (tcphdr_t *)fin->fin_dp; - u_char flags = tcp->th_flags; - int dlen, ostate; - - ostate = state[1 - dir]; - - dlen = ip->ip_len - fin->fin_hlen - (tcp->th_off << 2); - - if (flags & TH_RST) { - if (!(tcp->th_flags & TH_PUSH) && !dlen) { - *age = fr_tcpclosed; - state[dir] = TCPS_CLOSED; - } else { - *age = fr_tcpclosewait; - state[dir] = TCPS_CLOSE_WAIT; - } - return; - } - - *age = fr_tcptimeout; /* 1 min */ - - switch(state[dir]) - { - case TCPS_FIN_WAIT_2: - case TCPS_CLOSED: - if ((flags & TH_OPENING) == TH_OPENING) - state[dir] = TCPS_SYN_RECEIVED; - else if (flags & TH_SYN) - state[dir] = TCPS_SYN_SENT; - break; - case TCPS_SYN_RECEIVED: - if ((flags & (TH_FIN|TH_ACK)) == TH_ACK) { - state[dir] = TCPS_ESTABLISHED; - *age = fr_tcpidletimeout; - } - break; - case TCPS_SYN_SENT: - if ((flags & (TH_FIN|TH_ACK)) == TH_ACK) { - state[dir] = TCPS_ESTABLISHED; - *age = fr_tcpidletimeout; - } - break; - case TCPS_ESTABLISHED: - if (flags & TH_FIN) { - state[dir] = TCPS_CLOSE_WAIT; - if (!(flags & TH_PUSH) && !dlen && - ostate > TCPS_ESTABLISHED) - *age = fr_tcplastack; - else - *age = fr_tcpclosewait; - } else - *age = fr_tcpidletimeout; - break; - case TCPS_CLOSE_WAIT: - if ((flags & TH_FIN) && !(flags & TH_PUSH) && !dlen && - ostate > TCPS_ESTABLISHED) { - *age = fr_tcplastack; - state[dir] = TCPS_LAST_ACK; - } else - *age = fr_tcpclosewait; - break; - case TCPS_LAST_ACK: - if (flags & TH_ACK) { - state[dir] = TCPS_FIN_WAIT_2; - if (!(flags & TH_PUSH) && !dlen && - ostate > TCPS_ESTABLISHED) - *age = fr_tcplastack; - else { - *age = fr_tcpclosewait; - state[dir] = TCPS_CLOSE_WAIT; - } - } - break; - } -} - - -#ifdef IPFILTER_LOG -void ipstate_log(is, type) -struct ipstate *is; -u_short type; -{ - struct ipslog ipsl; - void *items[1]; - size_t sizes[1]; - int types[1]; - - 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_flags = is->is_flags; - ipsl.isl_type = type; - if (ipsl.isl_p == IPPROTO_TCP || ipsl.isl_p == IPPROTO_UDP) { - ipsl.isl_sport = is->is_sport; - ipsl.isl_dport = is->is_dport; - } 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, 0, items, sizes, types, 1); -} -#endif diff --git a/sys/contrib/ipfilter/netinet/ip_state.h b/sys/contrib/ipfilter/netinet/ip_state.h deleted file mode 100644 index 2b7e898..0000000 --- a/sys/contrib/ipfilter/netinet/ip_state.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 1995-1997 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 - * $FreeBSD$ - */ -#ifndef __IP_STATE_H__ -#define __IP_STATE_H__ - -#define IPSTATE_SIZE 257 -#define IPSTATE_MAX 2048 /* 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 tcpstate { - u_short ts_sport; - u_short ts_dport; - u_long ts_seq; - u_long ts_ack; - u_short ts_swin; - u_short ts_dwin; - u_char ts_state[2]; -} tcpstate_t; - -typedef struct ipstate { - struct ipstate *is_next; - u_long is_age; - u_int is_pass; - U_QUAD_T is_pkts; - U_QUAD_T is_bytes; - void *is_ifpin; - void *is_ifpout; - struct in_addr is_src; - struct in_addr is_dst; - u_char is_p; - u_char is_flags; - u_32_t is_opt; - u_32_t is_optmsk; - u_short is_sec; - u_short is_secmsk; - u_short is_auth; - u_short is_authmsk; - union { - icmpstate_t is_ics; - tcpstate_t is_ts; - udpstate_t is_us; - } is_ps; -} ipstate_t; - -#define is_icmp is_ps.is_ics -#define is_tcp is_ps.is_ts -#define is_udp is_ps.is_us -#define is_seq is_tcp.ts_seq -#define is_ack is_tcp.ts_ack -#define is_dwin is_tcp.ts_dwin -#define is_swin is_tcp.ts_swin -#define is_sport is_tcp.ts_sport -#define is_dport is_tcp.ts_dport -#define is_state is_tcp.ts_state - -#define TH_OPENING (TH_SYN|TH_ACK) - - -typedef struct ipslog { - U_QUAD_T isl_pkts; - U_QUAD_T isl_bytes; - struct in_addr isl_src; - struct in_addr isl_dst; - u_char isl_p; - u_char isl_flags; - u_short isl_type; - union { - u_short isl_filler[2]; - u_short isl_ports[2]; - u_short isl_icmp; - } isl_ps; -} 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 - - -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; - ipstate_t **iss_table; -} 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_udptimeout; -extern u_long fr_icmptimeout; -extern int fr_tcpstate __P((ipstate_t *, fr_info_t *, ip_t *, tcphdr_t *)); -extern int fr_addstate __P((ip_t *, fr_info_t *, u_int)); -extern int fr_checkstate __P((ip_t *, fr_info_t *)); -extern void fr_timeoutstate __P((void)); -extern void fr_tcp_age __P((u_long *, u_char *, ip_t *, fr_info_t *, int)); -extern void fr_stateunload __P((void)); -extern void ipstate_log __P((struct ipstate *, u_short)); -#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/sys/contrib/ipfilter/netinet/ipl.h b/sys/contrib/ipfilter/netinet/ipl.h deleted file mode 100644 index 0985545..0000000 --- a/sys/contrib/ipfilter/netinet/ipl.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) 1993-1997 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 - * $FreeBSD$ - */ - -#ifndef __IPL_H__ -#define __IPL_H__ - -#define IPL_VERSION "IP Filter v3.2.7" - -#endif diff --git a/sys/netinet/fil.c b/sys/netinet/fil.c deleted file mode 100644 index ee0ff90..0000000 --- a/sys/netinet/fil.c +++ /dev/null @@ -1,1329 +0,0 @@ -/* - * Copyright (C) 1993-1997 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-1996 Darren Reed"; -static const char rcsid[] = "@(#)$FreeBSD$"; -#endif - -#include "opt_ipfilter.h" - -#include <sys/errno.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/time.h> -#include <sys/file.h> -#if !defined(__FreeBSD__) -# 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> -# include <sys/dditypes.h> -# include <sys/stream.h> -#endif -#if defined(__FreeBSD__) -# include <sys/malloc.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 -#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" -#ifndef MIN -#define MIN(a,b) (((a)<(b))?(a):(b)) -#endif - -#ifndef _KERNEL -# include "ipf.h" -# include "ipt.h" -extern int opts; - -# define FR_IFVERBOSE(ex,second,verb_pr) if (ex) { verbose verb_pr; \ - second; } -# define FR_IFDEBUG(ex,second,verb_pr) if (ex) { debug verb_pr; \ - second; } -# define FR_VERBOSE(verb_pr) verbose verb_pr -# define FR_DEBUG(verb_pr) debug verb_pr -# define SEND_RESET(ip, qif, if, m) send_reset(ip, if) -# define IPLLOG(a, c, d, e) ipllog() -# define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, ip) -# if SOLARIS -# define ICMP_ERROR(b, ip, t, c, if, src) icmp_error(ip) -# else -# define ICMP_ERROR(b, ip, t, c, if, src) icmp_error(b, ip, if) -# endif -#else /* #ifndef _KERNEL */ -# define FR_IFVERBOSE(ex,second,verb_pr) ; -# define FR_IFDEBUG(ex,second,verb_pr) ; -# 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 kmutex_t ipf_mutex, ipf_auth; -# endif -# if SOLARIS -# define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, \ - ip, qif) -# define SEND_RESET(ip, qif, if) send_reset(ip, qif) -# define ICMP_ERROR(b, ip, t, c, if, src) \ - icmp_error(ip, t, c, if, src) -# else /* SOLARIS */ -# define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, ip) -# ifdef linux -# define SEND_RESET(ip, qif, if) send_reset((tcpiphdr_t *)ip,\ - ifp) -# else -# define SEND_RESET(ip, qif, if) send_reset((tcpiphdr_t *)ip) -# endif -# ifdef __sgi -# define ICMP_ERROR(b, ip, t, c, if, src) \ - icmp_error(b, t, c, if, src, if) -# else -# if BSD < 199103 -# ifdef linux -# define ICMP_ERROR(b, ip, t, c, if, src) icmp_send(b,t,c,0,if) -# else -# define ICMP_ERROR(b, ip, t, c, if, src) \ - icmp_error(mtod(b, ip_t *), t, c, if, src) -# endif /* linux */ -# else -# define ICMP_ERROR(b, ip, t, c, if, src) \ - icmp_error(b, t, c, (src).s_addr, if) -# endif /* BSD < 199103 */ -# endif /* __sgi */ -# 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 } }, - *ipacct[2][2] = { { NULL, NULL }, { NULL, NULL } }; -struct frgroup *ipfgroups[3][2]; -int fr_flags = IPF_LOGGING, fr_active = 0; -#if defined(IPFILTER_DEFAULT_BLOCK) -int fr_pass = FR_NOMATCH|FR_BLOCK; -#else -int fr_pass = (IPF_DEFAULT_PASS|FR_NOMATCH); -#endif - -fr_info_t frcache[2]; - -static void fr_makefrip __P((int, ip_t *, fr_info_t *)); -static int fr_tcpudpchk __P((frentry_t *, fr_info_t *)); -static int frflushlist __P((int, int, int *, frentry_t *, frentry_t **)); - - -/* - * bit values for identifying presence of individual IP options - */ -static 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 - */ -static 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. - */ -static void fr_makefrip(hlen, ip, fin) -int hlen; -ip_t *ip; -fr_info_t *fin; -{ - struct optlist *op; - tcphdr_t *tcp; - icmphdr_t *icmp; - fr_ip_t *fi = &fin->fin_fi; - u_short optmsk = 0, secmsk = 0, auth = 0; - int i, mv, ol, off; - u_char *s, opt; - - 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; - fin->fin_id = ip->ip_id; -#ifdef _KERNEL - fin->fin_icode = ipl_unreach; -#endif - fi->fi_v = ip->ip_v; - fi->fi_tos = ip->ip_tos; - fin->fin_hlen = hlen; - fin->fin_dlen = ip->ip_len - hlen; - tcp = (tcphdr_t *)((char *)ip + hlen); - icmp = (icmphdr_t *)tcp; - fin->fin_dp = (void *)tcp; - (*(((u_short *)fi) + 1)) = (*(((u_short *)ip) + 4)); - (*(((u_32_t *)fi) + 1)) = (*(((u_32_t *)ip) + 3)); - (*(((u_32_t *)fi) + 2)) = (*(((u_32_t *)ip) + 4)); - - fi->fi_fl = (hlen > sizeof(ip_t)) ? FI_OPTIONS : 0; - off = (ip->ip_off & 0x1fff) << 3; - if (ip->ip_off & 0x3fff) - fi->fi_fl |= FI_FRAG; - switch (ip->ip_p) - { - case IPPROTO_ICMP : - { - int minicmpsz = sizeof(struct icmp); - - if (!off && ip->ip_len > ICMP_MINLEN + hlen && - (icmp->icmp_type == ICMP_ECHOREPLY || - icmp->icmp_type == ICMP_UNREACH)) - minicmpsz = ICMP_MINLEN; - if ((!(ip->ip_len >= hlen + minicmpsz) && !off) || - (off && off < sizeof(struct icmp))) - fi->fi_fl |= FI_SHORT; - if (fin->fin_dlen > 1) - fin->fin_data[0] = *(u_short *)tcp; - break; - } - case IPPROTO_TCP : - fi->fi_fl |= FI_TCPUDP; - 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; - 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; - } - - - for (s = (u_char *)(ip + 1), hlen -= sizeof(*ip); hlen; ) { - if (!(opt = *s)) - break; - ol = (opt == IPOPT_NOP) ? 1 : (int)*(s+1); - if (opt > 1 && (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. - */ -static int fr_tcpudpchk(fr, fin) -frentry_t *fr; -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)fr->fr_dcmp)) { - po = fr->fr_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 <= fr->fr_dtop)) - err = 0; - else if (!--i && /* In range */ - (tup <= po || tup >= fr->fr_dtop)) - err = 0; - } - /* - * compare source ports - */ - if (err && (i = (int)fr->fr_scmp)) { - po = fr->fr_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 <= fr->fr_stop)) - err = 0; - else if (!--i && /* In range */ - (tup <= po || tup >= fr->fr_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 !(fr->fr_tcpf | fr->fr_tcpfm); - /* - * Match the flags ? If not, abort this match. - */ - if (fr->fr_tcpf && - fr->fr_tcpf != (fin->fin_tcpf & fr->fr_tcpfm)) { - FR_DEBUG(("f. %#x & %#x != %#x\n", fin->fin_tcpf, - fr->fr_tcpfm, fr->fr_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) -int 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; - - fr = fin->fin_fr; - fin->fin_fr = NULL; - fin->fin_rule = 0; - fin->fin_group = 0; - off = ip->ip_off & 0x1fff; - 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 (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[0] & lm[0]) != ld[0]); - FR_IFDEBUG(i,continue,("0. %#08x & %#08x != %#08x\n", - lip[0], lm[0], ld[0])); - i |= ((lip[1] & lm[1]) != ld[1]) << 21; - FR_IFDEBUG(i,continue,("1. %#08x & %#08x != %#08x\n", - lip[1], lm[1], ld[1])); - i |= ((lip[2] & lm[2]) != ld[2]) << 22; - FR_IFDEBUG(i,continue,("2. %#08x & %#08x != %#08x\n", - lip[2], lm[2], ld[2])); - i |= ((lip[3] & lm[3]) != ld[3]); - FR_IFDEBUG(i,continue,("3. %#08x & %#08x != %#08x\n", - lip[3], lm[3], ld[3])); - i |= ((lip[4] & lm[4]) != ld[4]); - FR_IFDEBUG(i,continue,("4. %#08x & %#08x != %#08x\n", - lip[4], lm[4], ld[4])); - i ^= (fi->fi_fl & (FR_NOTSRCIP|FR_NOTDSTIP)); - 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, 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... - */ - if (!(skip = fr->fr_skip)) - pass = fr->fr_flags; - if ((pass & FR_CALLNOW) && fr->fr_func) - pass = (*fr->fr_func)(pass, ip, fin); -#ifdef IPFILTER_LOG - if ((pass & FR_LOGMASK) == FR_LOG) { - if (!IPLLOG(fr->fr_flags, ip, fin, m)) - frstats[fin->fin_out].fr_skip++; - frstats[fin->fin_out].fr_pkl++; - } -#endif /* IPFILTER_LOG */ - FR_DEBUG(("pass %#x\n", pass)); - 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; - fin->fin_fr = fr; - 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_QUICK) - break; - } - return pass; -} - - -/* - * frcheck - filter check - * check using source and destination addresses/pors 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; - frentry_t *fr = NULL; - int pass, changed, apass, error = EHOSTUNREACH; -#if !SOLARIS || !defined(_KERNEL) - register mb_t *m = *mp; -#endif - -#ifdef _KERNEL - 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 */ - - if ((ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP || - ip->ip_p == IPPROTO_ICMP)) { - int plen = 0; - - switch(ip->ip_p) - { - case IPPROTO_TCP: - plen = sizeof(tcphdr_t); - break; - case IPPROTO_UDP: - plen = sizeof(udphdr_t); - break; - case IPPROTO_ICMP: - /* 96 - enough for complete ICMP error IP header */ - plen = sizeof(struct icmp) + sizeof(ip_t) + 8; - break; - } - up = MIN(hlen + plen, ip->ip_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)) { - frstats[out].fr_pull[1]++; - return -1; - } - m_copydata(m, 0, up, hbuf); - frstats[out].fr_pull[0]++; - ip = (ip_t *)hbuf; -#else -# ifndef linux - if ((*mp = m_pullup(m, up)) == 0) { - frstats[out].fr_pull[1]++; - return -1; - } else { - frstats[out].fr_pull[0]++; - m = *mp; - ip = mtod(m, ip_t *); - } -# endif -#endif - } else - up = 0; - } else - up = 0; -# endif -# if SOLARIS - mb_t *m = qif->qf_m; -# endif -#endif - fr_makefrip(hlen, ip, fin); - fin->fin_ifp = ifp; - fin->fin_out = out; - fin->fin_mp = mp; - - MUTEX_ENTER(&ipf_mutex); - - /* - * 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) { - changed = ip_natin(ip, hlen, fin); - if (!apass && (fin->fin_fr = ipacct[0][fr_active]) && - (FR_SCANLIST(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT)) - frstats[0].fr_acct++; - } - - if (apass || (!(pass = ipfr_knownfrag(ip, fin)) && - !(pass = 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); - frstats[out].fr_chit++; - if ((fr = fin->fin_fr)) { - fr->fr_hits++; - pass = fr->fr_flags; - } else - pass = fr_pass; - } else { - pass = fr_pass; - if ((fin->fin_fr = ipfilter[out][fr_active])) - pass = FR_SCANLIST(fr_pass, ip, fin, m); - bcopy((char *)fin, (char *)fc, FI_COPYSIZE); - if (pass & FR_NOMATCH) - 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(m, fin, ip, qif) != 0) -#ifdef _KERNEL - m = *mp = NULL; -#else - ; -#endif - - if (pass & FR_PREAUTH) { - MUTEX_ENTER(&ipf_auth); - if ((fin->fin_fr = ipauth) && - (pass = FR_SCANLIST(0, ip, fin, m))) - fr_authstats.fas_hits++; - else - fr_authstats.fas_miss++; - MUTEX_EXIT(&ipf_auth); - } - - if (pass & FR_KEEPFRAG) { - if (fin->fin_fi.fi_fl & FI_FRAG) { - if (ipfr_newfrag(ip, fin, pass) == -1) - frstats[out].fr_bnfr++; - else - frstats[out].fr_nfr++; - } else - frstats[out].fr_cfr++; - } - if (pass & FR_KEEPSTATE) { - if (fr_addstate(ip, fin, pass) == -1) - frstats[out].fr_bads++; - else - frstats[out].fr_ads++; - } - } - - 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)) { - if ((fin->fin_fr = ipacct[1][fr_active]) && - (FR_SCANLIST(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT)) - frstats[1].fr_acct++; - fin->fin_fr = NULL; - changed = ip_natout(ip, hlen, fin); - } - fin->fin_fr = fr; - MUTEX_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; - 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; - 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; - frstats[out].fr_bpkl++; -logit: - if (!IPLLOG(pass, ip, fin, m)) { - frstats[out].fr_skip++; - if ((pass & (FR_PASS|FR_LOGORBLOCK)) == - (FR_PASS|FR_LOGORBLOCK)) - pass ^= FR_PASS|FR_BLOCK; - } - } - } -#endif /* IPFILTER_LOG */ -#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) - frstats[out].fr_pass++; - else if (pass & FR_BLOCK) { - 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) { -# if SOLARIS - ICMP_ERROR(q, ip, ICMP_UNREACH, fin->fin_icode, - qif, ip->ip_src); -# else - ICMP_ERROR(m, ip, ICMP_UNREACH, fin->fin_icode, - ifp, ip->ip_src); - m = *mp = NULL; /* freed by icmp_error() */ -# endif - - frstats[0].fr_ret++; - } else if ((pass & FR_RETRST) && - !(fin->fin_fi.fi_fl & FI_SHORT)) { - if (SEND_RESET(ip, qif, ifp) == 0) - frstats[1].fr_ret++; - } -#else - if (pass & FR_RETICMP) { - verbose("- ICMP unreachable sent\n"); - frstats[0].fr_ret++; - } else if ((pass & FR_RETRST) && - !(fin->fin_fi.fi_fl & FI_SHORT)) { - verbose("- TCP RST sent\n"); - 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 defined(_KERNEL) -# if !SOLARIS -# if !defined(linux) - if (fr) { - frdest_t *fdp = &fr->fr_tif; - - if ((pass & FR_FASTROUTE) || - (fdp->fd_ifp && fdp->fd_ifp != (struct ifnet *)-1)) { - ipfr_fastroute(m, fin, fdp); - 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 */ - return (pass & FR_PASS) ? 0 : error; -# else /* !SOLARIS */ - if (fr) { - frdest_t *fdp = &fr->fr_tif; - - if ((pass & FR_FASTROUTE) || - (fdp->fd_ifp && fdp->fd_ifp != (struct ifnet *)-1)) { - ipfr_fastroute(qif, ip, m, mp, fin, fdp); - m = *mp = NULL; - } - if (mc) - ipfr_fastroute(qif, ip, mc, mp, fin, &fr->fr_dif); - } - return (pass & FR_PASS) ? changed : error; -# endif /* !SOLARIS */ -#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, len) -mb_t *m; -ip_t *ip; -tcphdr_t *tcp; -int len; -{ - union { - u_char c[2]; - u_short s; - } bytes; - u_32_t sum; - u_short *sp; -# if SOLARIS || defined(__sgi) - int add, hlen; -# endif - -# if SOLARIS - /* skip any leading M_PROTOs */ - while(m && (MTYPE(m) != M_DATA)) - m = m->b_cont; - PANIC((!m),("fr_tcpsum: no M_DATA")); -# endif - - /* - * Add up IP Header portion - */ - bytes.c[0] = 0; - bytes.c[1] = IPPROTO_TCP; - len -= (ip->ip_hl << 2); - sum = bytes.s; - sum += htons((u_short)len); - sp = (u_short *)&ip->ip_src; - sum += *sp++; - sum += *sp++; - sum += *sp++; - sum += *sp++; - if (sp != (u_short *)tcp) - sp = (u_short *)tcp; - sum += *sp++; - sum += *sp++; - sum += *sp++; - sum += *sp++; - sum += *sp++; - sum += *sp++; - sum += *sp++; - sum += *sp; - sp += 2; /* Skip over checksum */ - sum += *sp++; - -#if SOLARIS - /* - * In case we had to copy the IP & TCP header out of mblks, - * skip over the mblk bits which are the header - */ - if ((caddr_t)ip != (caddr_t)m->b_rptr) { - hlen = (caddr_t)sp - (caddr_t)ip; - while (hlen) { - add = MIN(hlen, m->b_wptr - m->b_rptr); - sp = (u_short *)((caddr_t)m->b_rptr + add); - hlen -= add; - if ((caddr_t)sp >= (caddr_t)m->b_wptr) { - m = m->b_cont; - PANIC((!m),("fr_tcpsum: not enough data")); - if (!hlen) - sp = (u_short *)m->b_rptr; - } - } - } -#endif -#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; - PANIC((!m),("fr_tcpsum: not enough data")); - if (!hlen) - sp = mtod(m, u_short *); - } - } - } -#endif - - if (!(len -= sizeof(*tcp))) - goto nodata; - while (len > 0) { -#if SOLARIS - while ((caddr_t)sp >= (caddr_t)m->b_wptr) { - m = m->b_cont; - PANIC((!m),("fr_tcpsum: not enough data")); - sp = (u_short *)m->b_rptr; - } -#else - while (((caddr_t)sp - mtod(m, caddr_t)) >= m->m_len) - { - m = m->m_next; - PANIC((!m),("fr_tcpsum: not enough data")); - sp = mtod(m, u_short *); - } -#endif /* SOLARIS */ - if (len < 2) - break; - if((u_32_t)sp & 1) { - bcopy((char *)sp++, (char *)&bytes.s, sizeof(bytes.s)); - sum += bytes.s; - } else - sum += *sp++; - len -= 2; - } - if (len) { - bytes.c[1] = 0; - bytes.c[0] = *(u_char *)sp; - sum += bytes.s; - } -nodata: - sum = (sum >> 16) + (sum & 0xffff); - sum += (sum >> 16); - sum = (u_short)((~sum) & 0xffff); - return sum; -} - - -#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 - * $FreeBSD$ - */ -/* - * 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_short num; -u_32_t flags; -int which, 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; - - 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_short num; -frentry_t *fp; -int which, set; -{ - frgroup_t *fg, **fgp; - - if ((fg = fr_findgroup(num, fp->fr_flags, which, set, &fgp))) - return fg; - - KMALLOC(fg, frgroup_t *, sizeof(*fg)); - 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_short num; -u_32_t flags; -int which, 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, list, listp) -int set, unit, *nfreedp; -frentry_t *list, **listp; -{ - register frentry_t *fp = list, *fpn; - register int freed = 0; - - while (fp) { - fpn = fp->fr_next; - if (fp->fr_grp) { - fp->fr_ref -= frflushlist(set, unit, nfreedp, - fp->fr_grp, &fp->fr_grp); - } - - if (fp->fr_ref == 1) { - if (fp->fr_grhead) - fr_delgroup(fp->fr_grhead, fp->fr_flags, unit, - set); - KFREE(fp); - *listp = fpn; - freed++; - } - fp = fpn; - } - *nfreedp += freed; - return freed; -} - - -void frflush(unit, result) -int unit; -int *result; -{ - int flags = *result, flushed = 0, set = fr_active; - - bzero((char *)frcache, sizeof(frcache[0]) * 2); - - if (flags & FR_INACTIVE) - set = 1 - set; - - if (unit == IPL_LOGIPF) { - if (flags & FR_OUTQUE) { - (void) frflushlist(set, unit, &flushed, - ipfilter[1][set], - &ipfilter[1][set]); - (void) frflushlist(set, unit, &flushed, - ipacct[1][set], &ipacct[1][set]); - } - if (flags & FR_INQUE) { - (void) frflushlist(set, unit, &flushed, - ipfilter[0][set], - &ipfilter[0][set]); - (void) frflushlist(set, unit, &flushed, - ipacct[0][set], &ipacct[0][set]); - } - } - - *result = flushed; -} diff --git a/sys/netinet/ip_auth.c b/sys/netinet/ip_auth.c deleted file mode 100644 index 4afda70..0000000 --- a/sys/netinet/ip_auth.c +++ /dev/null @@ -1,508 +0,0 @@ -/* - * Copyright (C) 1997 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[] = "@(#)$FreeBSD$"; -#endif - -#if defined(KERNEL) && !defined(_KERNEL) -#define _KERNEL -#endif -#define __FreeBSD_version 300000 /* just a hack - no <sys/osreldate.h> */ - -#if !defined(_KERNEL) && !defined(KERNEL) -# include <stdlib.h> -# include <string.h> -#endif -#include <sys/errno.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/time.h> -#include <sys/file.h> -#if 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__) -# ifndef linux -# include <sys/mbuf.h> -# endif -#else -# include <sys/filio.h> -# include <sys/byteorder.h> -# include <sys/dditypes.h> -# include <sys/stream.h> -# include <sys/kmem.h> -#endif -#if defined(KERNEL) && (__FreeBSD_version >= 300000) -# include <sys/malloc.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 -#if !defined(KERNEL) && (__FreeBSD_version >= 300000) -# include <net/if_var.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 -# 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 (SOLARIS || defined(__sgi)) && defined(_KERNEL) -extern kmutex_t ipf_auth; -# 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; -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. - */ -int fr_checkauth(ip, fin) -ip_t *ip; -fr_info_t *fin; -{ - u_short id = ip->ip_id; - u_32_t pass; - int i; - - MUTEX_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; - 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; - } - } - MUTEX_EXIT(&ipf_auth); - return pass; - } - i++; - if (i == FR_NUMAUTH) - i = 0; - } - fr_authstats.fas_miss++; - MUTEX_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 -#if defined(_KERNEL) && SOLARIS -, qif) -qif_t *qif; -#else -) -#endif -mb_t *m; -fr_info_t *fin; -ip_t *ip; -{ - int i; - - MUTEX_ENTER(&ipf_auth); - if ((fr_authstart > fr_authend) && (fr_authstart - fr_authend == -1)) { - fr_authstats.fas_nospace++; - MUTEX_EXIT(&ipf_auth); - return 0; - } - if (fr_authend - fr_authstart == FR_NUMAUTH - 1) { - fr_authstats.fas_nospace++; - MUTEX_EXIT(&ipf_auth); - return 0; - } - - fr_authstats.fas_added++; - fr_authused++; - i = fr_authend++; - if (fr_authend == FR_NUMAUTH) - fr_authend = 0; - MUTEX_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) -# endif - { - register u_short bo; - - bo = ip->ip_len; - ip->ip_len = htons(bo); -# if !SOLARIS /* 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) -# if !SOLARIS - struct ifqueue *ifq; - int s; -# endif -#endif - frauth_t auth, *au = &auth; - frauthent_t *fae, **faep; - int i, error = 0; - - switch (cmd) - { - case SIOCINIFR : - case SIOCRMIFR : - case SIOCADIFR : - error = EINVAL; - break; - case SIOCINAFR : - 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 { - *faep = fae->fae_next; - *frptr = fr->fr_next; - KFREE(fae); - } - } else { - KMALLOC(fae, frauthent_t *, sizeof(*fae)); - if (fae != NULL) { - IRCOPY((char *)data, (char *)&fae->fae_fr, - sizeof(fae->fae_fr)); - if (!fae->fae_age) - 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; - } else - error = ENOMEM; - } - break; - case SIOCATHST: - IWCOPY((char *)&fr_authstats, data, sizeof(fr_authstats)); - break; - case SIOCAUTHW: -fr_authioctlloop: - MUTEX_ENTER(&ipf_auth); - if ((fr_authnext != fr_authend) && fr_authpkts[fr_authnext]) { - IWCOPY((char *)&fr_auth[fr_authnext++], data, - sizeof(fr_info_t)); - if (fr_authnext == FR_NUMAUTH) - fr_authnext = 0; - MUTEX_EXIT(&ipf_auth); - return 0; - } -#ifdef _KERNEL -# if SOLARIS - if (!cv_wait_sig(&ipfauthwait, &ipf_auth)) { - mutex_exit(&ipf_auth); - return EINTR; - } -# else -# ifdef linux - interruptible_sleep_on(&ipfauthwait); - if (current->signal & ~current->blocked) - error = -EINTR; -# else - error = SLEEP(&fr_authnext, "fr_authnext"); -# endif -# endif -#endif - MUTEX_EXIT(&ipf_auth); - if (!error) - goto fr_authioctlloop; - break; - case SIOCAUTHR: - IRCOPY(data, (caddr_t)&auth, sizeof(auth)); - MUTEX_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)) { - MUTEX_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 - MUTEX_EXIT(&ipf_auth); - SPL_NET(s); -# ifndef linux - if (m && au->fra_info.fin_out) { -# if SOLARIS - error = fr_qout(fr_auth[i].fra_q, m); -# else /* SOLARIS */ - error = ip_output(m, NULL, NULL, IP_FORWARDING, NULL); -# 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 - SPL_X(s); -#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; - - MUTEX_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); - } - MUTEX_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 - - SPL_NET(s); - MUTEX_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 (!--fra->fra_age) { - *faep = fae->fae_next; - KFREE(fae); - fr_authstats.fas_expire++; - } else - faep = &fae->fae_next; - } - MUTEX_EXIT(&ipf_auth); - SPL_X(s); -} -#endif diff --git a/sys/netinet/ip_auth.h b/sys/netinet/ip_auth.h deleted file mode 100644 index 72e51b2..0000000 --- a/sys/netinet/ip_auth.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 1997 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. - * - * $FreeBSD$ - * - */ -#ifndef __IP_AUTH_H__ -#define __IP_AUTH_H__ - -#define FR_NUMAUTH 32 - -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; -} fr_authstat_t; - -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; - - -extern frentry_t *ipauth; -extern struct fr_authstat fr_authstats; -extern int fr_defaultauthage; -extern int fr_authstart; -extern int fr_authend; -extern int fr_authsize; -extern int fr_authused; -extern int fr_checkauth __P((ip_t *, fr_info_t *)); -extern void fr_authexpire __P((void)); -extern void fr_authunload __P((void)); -extern mb_t *fr_authpkts[]; -#if defined(_KERNEL) && SOLARIS -extern int fr_newauth __P((mb_t *, fr_info_t *, ip_t *, qif_t *)); -#else -extern int fr_newauth __P((mb_t *, fr_info_t *, ip_t *)); -#endif -#if defined(__NetBSD__) || defined(__OpenBSD__) || (__FreeBSD_version >= 300003) -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/sys/netinet/ip_compat.h b/sys/netinet/ip_compat.h deleted file mode 100644 index e3fd1fe..0000000 --- a/sys/netinet/ip_compat.h +++ /dev/null @@ -1,727 +0,0 @@ -/* - * Copyright (C) 1993-1997 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 - * $FreeBSD$ - */ - -#ifndef __IP_COMPAT_H__ -#define __IP_COMPAT_H__ - -#ifndef __P -# ifdef __STDC__ -# define __P(x) x -# else -# define __P(x) () -# define const -# endif -#endif - -#ifndef SOLARIS -#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4))) -#endif - -#if defined(_KERNEL) && !defined(KERNEL) -# define KERNEL -#endif -#if defined(KERNEL) && !defined(_KERNEL) -# define _KERNEL -#endif -#if!defined(__KERNEL__) && defined(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 - -#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/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 -# include <inet/common.h> -# include <inet/ip.h> -# include <inet/ip_ire.h> -# undef _KERNEL -# else /* _KERNEL */ -# include <inet/common.h> -# include <inet/ip.h> -# include <inet/ip_ire.h> -# endif /* _KERNEL */ -#endif /* SOLARIS */ -#define IPMINLEN(i, h) ((i)->ip_len >= ((i)->ip_hl * 4 + sizeof(struct h))) - -#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; -#else -/* - * Really, any arch where sizeof(long) != sizeof(int). - */ -# if defined(__alpha__) || defined(__alpha) -typedef unsigned int u_32_t; -# else -typedef unsigned long u_32_t; -# endif -#endif /* __NetBSD__ || __OpenBSD__ || __FreeBSD__ || __sgi */ - -#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) -# if __FreeBSD__ < 3 -# include <machine/spl.h> -# endif -# if defined(IPFILTER_LKM) && !defined(ACTUALLY_LKM_NOT_KERNEL) -# define ACTUALLY_LKM_NOT_KERNEL -# endif -#endif /* __FreeBSD__ && KERNEL */ - -/* - * Build some macros and #defines to enable the same code to compile anywhere - * Well, that's the idea, anyway :-) - */ -#ifdef KERNEL -# if SOLARIS -# define MUTEX_ENTER(x) mutex_enter(x) -# define MUTEX_EXIT(x) mutex_exit(x) -# define MTOD(m,t) (t)((m)->b_rptr) -# define IRCOPY(a,b,c) copyin((a), (b), (c)) -# define IWCOPY(a,b,c) copyout((a), (b), (c)) -# define 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,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. */ - int qf_off; - int qf_len; /* this field is used for in ipfr_fastroute */ - char qf_name[8]; - /* - * in case the ILL has disappeared... - */ - int qf_hl; /* header length */ -} qif_t; -extern ill_t *get_unit __P((char *)); -# define GETUNIT(n) get_unit((n)) -# else /* SOLARIS */ -# if defined(__sgi) -# include <sys/ksynch.h> -# define IPF_LOCK_PL plhi -# include <sys/sema.h> -#undef kmutex_t -typedef struct { - lock_t *l; - int pl; -} kmutex_t; -# define MUTEX_ENTER(x) (x)->pl = LOCK((x)->l, IPF_LOCK_PL); -# define MUTEX_EXIT(x) UNLOCK((x)->l, (x)->pl); -# else /* __sgi */ -# define MUTEX_ENTER(x) ; -# define MUTEX_EXIT(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)) -# define IWCOPY(a,b,c) bcopy((a), (b), (c)) -# endif /* !linux */ -# endif /* SOLARIS */ - -# ifdef sun -# if !SOLARIS -# include <sys/kmem_alloc.h> -# define GETUNIT(n) ifunit((n), IFNAMSIZ) -# endif -# else -# ifndef linux -# define GETUNIT(n) ifunit((n)) -# 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,c) (a) = (b)kmem_alloc((c), KM_NOSLEEP) -# define GET_MINOR(x) getminor(x) -# else -# if !SOLARIS -# define KMALLOC(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, 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, 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 MUTEX_ENTER(x) ; -# define MUTEX_EXIT(x) ; -# define SPL_NET(x) ; -# define SPL_IMP(x) ; -# undef SPL_X -# define SPL_X(x) ; -# define KMALLOC(a,b,c) (a) = (b)malloc(c) -# define KFREE(x) free(x) -# define KFREES(x,s) free(x) -# define GETUNIT(x) get_unit(x) -# define IRCOPY(a,b,c) bcopy((a), (b), (c)) -# define IWCOPY(a,b,c) bcopy((a), (b), (c)) -#endif /* KERNEL */ - -#if SOLARIS -typedef mblk_t mb_t; -#else -# ifdef linux -typedef struct sk_buff mb_t; -# 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 -/* - * 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. - */ -#define FWRITE WRITE -#define FREAD READ -/* - * mbuf related problems. - */ -#define mtod(m,t) (t)((m)->data) -#define m_len len -#define m_next next - -#define IP_DF 0x8000 - -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_hl:4; - __u8 ip_v: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 { - u_char icmp_type; /* type of message, see below */ - u_char icmp_code; /* type sub code */ - u_short icmp_cksum; /* ones complement cksum of struct */ - union { - u_char ih_pptr; /* ICMP_PARAMPROB */ - struct in_addr ih_gwaddr; /* ICMP_REDIRECT */ - struct ih_idseq { - n_short icd_id; - n_short 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) 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,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(a,b,c) { \ - error = verify_area(VERIFY_READ, (a) ,(c)); \ - if (!error) \ - memcpy_fromfs((b), (a), (c)); \ - } -# define IWCOPY(a,b,c) { \ - error = verify_area(VERIFY_WRITE, (b), (c)); \ - if (!error) \ - memcpy_tofs((b), (a), (c)); \ - } -# 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 - -#endif /* __IP_COMPAT_H__ */ diff --git a/sys/netinet/ip_fil.c b/sys/netinet/ip_fil.c deleted file mode 100644 index 2dbea5d..0000000 --- a/sys/netinet/ip_fil.c +++ /dev/null @@ -1,1255 +0,0 @@ -/* - * Copyright (C) 1993-1997 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-1995 Darren Reed"; -static const char rcsid[] = "@(#)$FreeBSD$"; -#endif - -#include "opt_ipfilter.h" - -#ifndef SOLARIS -#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4))) -#endif - -#if defined(KERNEL) && !defined(_KERNEL) -# define _KERNEL -#endif -#ifdef __FreeBSD__ -# if defined(_KERNEL) && !defined(IPFILTER_LKM) -# define __FreeBSD_version 300000 /* this will do as a hack */ -# else -# include <osreldate.h> -# endif -#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/param.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 >= 220000 -# 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> -# include <sys/malloc.h> -#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 <syslog.h> -#endif -#include "netinet/ip_compat.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" -#ifndef MIN -#define MIN(a,b) (((a)<(b))?(a):(b)) -#endif -#if !SOLARIS && defined(_KERNEL) -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) -static int (*fr_saveslowtimo) __P((void)); -# else -static void (*fr_saveslowtimo) __P((void)); -# endif -# if (BSD < 199306) || defined(__sgi) -extern int tcp_ttl; -# endif -#endif - -int ipl_inited = 0; -int ipl_unreach = ICMP_UNREACH_FILTER; -u_long ipl_frouteok[2] = {0, 0}; - -static void fixskip __P((frentry_t **, frentry_t *, int)); -static void frzerostats __P((caddr_t)); -static void frsync __P((void)); -#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 **)); -#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 - -#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; -{ - iplattach(); -} -# endif - - -int iplattach() -{ - char *defpass; - int s; -# ifdef __sgi - int error; -# endif - - SPL_NET(s); - if (ipl_inited || (fr_checkp == fr_check)) { - printf("IP Filter: already initialized\n"); - SPL_X(s); - return EBUSY; - } - -# ifdef NETBSD_PF - pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT); -# endif - -# ifdef __sgi - error = ipfilter_sgi_attach(); - if (error) { - SPL_X(s); - return error; - } -# endif - - ipl_inited = 1; - bzero((char *)frcache, sizeof(frcache)); - bzero((char *)nat_table, sizeof(nat_table)); - fr_savep = fr_checkp; - fr_checkp = fr_check; - fr_saveslowtimo = inetsw[0].pr_slowtimo; - inetsw[0].pr_slowtimo = ipfr_slowtimer; - -# ifdef IPFILTER_LOG - ipflog_init(); -# endif - SPL_X(s); - if (fr_pass & FR_PASS) - defpass = "pass"; - else if (fr_pass & FR_BLOCK) - defpass = "block"; - else - defpass = "no-match -> block"; - - printf("IP Filter: initialized. Default = %s all, Logging = %s\n", - defpass, -# ifdef IPFILTER_LOG - "enabled"); -# else - "disabled"); -# 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; - - SPL_NET(s); - if (!ipl_inited) - { - printf("IP Filter: not initialized\n"); - SPL_X(s); - return 0; - } - - fr_checkp = fr_savep; - inetsw[0].pr_slowtimo = fr_saveslowtimo; - frflush(IPL_LOGIPF, &i); - ipl_inited = 0; - -# ifdef NETBSD_PF - pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT); -# endif - -# ifdef __sgi - ipfilter_sgi_detach(); -# endif - - ipfr_unload(); - ip_natunload(); - fr_stateunload(); - fr_authunload(); - - SPL_X(s); - return 0; -} -#endif /* _KERNEL */ - - -static void frzerostats(data) -caddr_t data; -{ - struct friostat fio; - - bcopy((char *)frstats, (char *)fio.f_st, - sizeof(struct filterstats) * 2); - fio.f_fin[0] = ipfilter[0][0]; - fio.f_fin[1] = ipfilter[0][1]; - fio.f_fout[0] = ipfilter[1][0]; - fio.f_fout[1] = ipfilter[1][1]; - fio.f_acctin[0] = ipacct[0][0]; - fio.f_acctin[1] = ipacct[0][1]; - fio.f_acctout[0] = ipacct[1][0]; - fio.f_acctout[1] = ipacct[1][1]; - fio.f_active = fr_active; - fio.f_froute[0] = ipl_frouteok[0]; - fio.f_froute[1] = ipl_frouteok[1]; - IWCOPY((caddr_t)&fio, data, sizeof(fio)); - bzero((char *)frstats, sizeof(*frstats) * 2); -} - - -/* - * 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 ((_BSDI_VERSION >= 199510) || (BSD >= 199506) || (NetBSD >= 199511) || \ - (__FreeBSD_version >= 220000)) && defined(_KERNEL) -, p) -struct proc *p; -#else -) -#endif -dev_t dev; -#if defined(__NetBSD__) || defined(__OpenBSD__) || \ - (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300003) -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; - -#ifdef _KERNEL - unit = GET_MINOR(dev); - if ((IPL_LOGMAX < unit) || (unit < 0)) - return ENXIO; -#endif - - SPL_NET(s); - - if (unit == IPL_LOGNAT) { - error = nat_ioctl(data, cmd, mode); - SPL_X(s); - return error; - } - if (unit == IPL_LOGSTATE) { - error = fr_state_ioctl(data, cmd, mode); - SPL_X(s); - return error; - } - switch (cmd) { - case FIONREAD : -#ifdef IPFILTER_LOG - 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 { - IRCOPY(data, (caddr_t)&enable, sizeof(enable)); - if (enable) - error = iplattach(); - else - error = ipldetach(); - } - break; - } -#endif - case SIOCSETFF : - if (!(mode & FWRITE)) - error = EPERM; - else - IRCOPY(data, (caddr_t)&fr_flags, sizeof(fr_flags)); - break; - case SIOCGETFF : - 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 : - { - struct friostat fio; - - bcopy((char *)frstats, (char *)fio.f_st, - sizeof(struct filterstats) * 2); - fio.f_fin[0] = ipfilter[0][0]; - fio.f_fin[1] = ipfilter[0][1]; - fio.f_fout[0] = ipfilter[1][0]; - fio.f_fout[1] = ipfilter[1][1]; - fio.f_acctin[0] = ipacct[0][0]; - fio.f_acctin[1] = ipacct[0][1]; - fio.f_acctout[0] = ipacct[1][0]; - fio.f_acctout[1] = ipacct[1][1]; - fio.f_auth = ipauth; - fio.f_active = fr_active; - fio.f_froute[0] = ipl_frouteok[0]; - fio.f_froute[1] = ipl_frouteok[1]; - IWCOPY((caddr_t)&fio, data, sizeof(fio)); - break; - } - case SIOCFRZST : - if (!(mode & FWRITE)) - error = EPERM; - else - frzerostats(data); - break; - case SIOCIPFFL : - if (!(mode & FWRITE)) - error = EPERM; - else { - IRCOPY(data, (caddr_t)&tmp, sizeof(tmp)); - frflush(unit, &tmp); - IWCOPY((caddr_t)&tmp, data, sizeof(tmp)); - } - break; -#ifdef IPFILTER_LOG - case SIOCIPFFB : - if (!(mode & FWRITE)) - error = EPERM; - else - *(int *)data = ipflog_clear(unit); - break; -#endif /* IPFILTER_LOG */ - case SIOCGFRST : - IWCOPY((caddr_t)ipfr_fragstats(), data, sizeof(ipfrstat_t)); - break; - case SIOCAUTHW : - case SIOCAUTHR : - if (!(mode & FWRITE)) { - error = EPERM; - break; - } - case SIOCATHST : - error = fr_auth_ioctl(data, cmd, NULL, NULL); - 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; -} - - -static void frsync() -{ -#ifdef _KERNEL - struct ifnet *ifp; - -# if (__FreeBSD_version >= 300000) - for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next) -# elif defined(__OpenBSD__) || (NetBSD >= 199511) - for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next) -# else - for (ifp = ifnet; ifp; ifp = ifp->if_next) -# endif - ip_natsync(ifp); -#endif -} - - -static 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; -} - - -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; - int error = 0, in, group; - - fp = &frd; - IRCOPY(data, (caddr_t)fp, sizeof(*fp)); - - /* - * Check that the group number does exist and that if a head group - * has been specified, doesn't exist. - */ - if (fp->fr_grhead && - fr_findgroup(fp->fr_grhead, fp->fr_flags, unit, set, NULL)) - return EEXIST; - if (fp->fr_group && - !fr_findgroup(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) - ftail = fprev = &ipacct[in][set]; - else if (fp->fr_flags & (FR_OUTQUE|FR_INQUE)) - ftail = fprev = &ipfilter[in][set]; - 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); - if (!fp->fr_ifa) - fp->fr_ifa = (void *)-1; - } - - fdp = &fp->fr_dif; - fp->fr_flags &= ~FR_DUP; - if (*fdp->fd_ifname) { - fdp->fd_ifp = GETUNIT(fdp->fd_ifname); - 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); - 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 (; (f = *ftail); ftail = &f->fr_next) - if (bcmp((char *)&f->fr_ip, (char *)&fp->fr_ip, - FR_CMPSIZ) == 0) - break; - - /* - * If zero'ing statistics, copy current to caller and zero. - */ - if (req == SIOCZRLST) { - if (!f) - return ESRCH; - IWCOPY((caddr_t)f, data, sizeof(*f)); - f->fr_hits = 0; - f->fr_bytes = 0; - return 0; - } - - if (!f) { - ftail = fprev; - if (req != SIOCINAFR && req != SIOCINIFR) - while ((f = *ftail)) - ftail = &f->fr_next; - else if (fp->fr_hits) - while (--fp->fr_hits && (f = *ftail)) - ftail = &f->fr_next; - f = NULL; - } - - if (req == SIOCDELFR || req == SIOCRMIFR) { - if (!f) - error = ESRCH; - else { - if (f->fr_ref > 1) - 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(f->fr_grhead, fp->fr_flags, unit, - set); - fixskip(fprev, f, -1); - *ftail = f->fr_next; - KFREE(f); - } - } else { - if (f) - error = EEXIST; - else { - if (unit == IPL_LOGAUTH) - return fr_auth_ioctl(data, req, f, ftail); - KMALLOC(f, frentry_t *, sizeof(*f)); - 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(_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(_KERNEL) -, devtype, p) -int devtype; -struct proc *p; -# else -) -# endif -dev_t dev; -int flags; -#endif /* __sgi */ -{ - u_int min = GET_MINOR(dev); - - if (2 < 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(ti) -struct tcpiphdr *ti; -{ - struct tcpiphdr *tp; - struct tcphdr *tcp; - struct mbuf *m; - int tlen = 0, err; - ip_t *ip; -# if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000) - struct route ro; -# endif - - if (ti->ti_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); - m->m_data += max_linkhdr; -# endif - if (m == NULL) - return -1; - - if (ti->ti_flags & TH_SYN) - tlen = 1; - m->m_len = sizeof (struct tcpiphdr); -# if BSD >= 199306 - m->m_pkthdr.len = sizeof (struct tcpiphdr); - m->m_pkthdr.rcvif = (struct ifnet *)0; -# endif - bzero(mtod(m, char *), sizeof(struct tcpiphdr)); - ip = mtod(m, struct ip *); - tp = mtod(m, struct tcpiphdr *); - tcp = (struct tcphdr *)((char *)ip + sizeof(struct ip)); - - ip->ip_src.s_addr = ti->ti_dst.s_addr; - ip->ip_dst.s_addr = ti->ti_src.s_addr; - tcp->th_dport = ti->ti_sport; - tcp->th_sport = ti->ti_dport; - tcp->th_ack = htonl(ntohl(ti->ti_seq) + tlen); - tcp->th_off = sizeof(struct tcphdr) >> 2; - tcp->th_flags = TH_RST|TH_ACK; - tp->ti_pr = ((struct ip *)ti)->ip_p; - tp->ti_len = htons(sizeof(struct tcphdr)); - tcp->th_sum = in_cksum(m, sizeof(struct tcpiphdr)); - - ip->ip_tos = ((struct ip *)ti)->ip_tos; - ip->ip_p = ((struct ip *)ti)->ip_p; - ip->ip_len = sizeof (struct tcpiphdr); -# if (BSD < 199306) || defined(__sgi) - ip->ip_ttl = tcp_ttl; -# else - ip->ip_ttl = ip_defttl; -# endif - -# if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000) - bzero((char *)&ro, sizeof(ro)); - err = ip_output(m, (struct mbuf *)0, &ro, 0, 0); - if (ro.ro_rt) - RTFREE(ro.ro_rt); -# else - /* - * extra 0 in case of multicast - */ - err = ip_output(m, (struct mbuf *)0, 0, 0, 0); -# endif - 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() -{ - (void) iplattach(); - 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; -} - - -void 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; - struct ifnet *ifp = fdp->fd_ifp; - int len, off, error = 0; - int hlen = fin->fin_hlen; - struct route iproute; - struct sockaddr_in *dst; - - ip = mtod(m0, struct ip *); - /* - * Route packet. - */ - ro = &iproute; - bzero((caddr_t)ro, sizeof (*ro)); - dst = (struct sockaddr_in *)&ro->ro_dst; - dst->sin_family = AF_INET; - dst->sin_addr = fdp->fd_ip.s_addr ? fdp->fd_ip : ip->ip_dst; -# ifdef __bsdi__ - 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 (!(fin->fin_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. - */ - (void) ip_natout(ip, hlen, fin); - if (fin->fin_out) - ip->ip_sum = 0; - /* - * If small enough for interface, can just send directly. - */ - if (ip->ip_len <= ifp->if_mtu) { -# 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); -# 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) { - MGET(m, M_DONTWAIT, MT_HEADER); - 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; - } -# 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; -bad: - m_freem(m); - goto done; -} -#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 -{ -# if !(defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ - (defined(OpenBSD) && (OpenBSD >= 199603)) - ip_t *ip = (ip_t *)m; -# endif -# else -static int write_output(ifp, ip) -struct ifnet *ifp; -ip_t *ip; -{ -# endif - FILE *fp; - char fname[32]; - -# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ - (defined(OpenBSD) && (OpenBSD >= 199603)) - snprintf(fname, sizeof(fname), "/tmp/%s", ifp->if_xname); - if ((fp = fopen(fname, "a"))) { - fclose(fp); - } -# else - snprintf(fname, sizeof(fname), "/tmp/%s%d", ifp->if_name, ifp->if_unit); - if ((fp = fopen(fname, "a"))) { - fwrite((char *)ip, ntohs(ip->ip_len), 1, fp); - fclose(fp); - } -# endif - return 0; -} - - -struct ifnet *get_unit(name) -char *name; -{ - 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) snprintf(ifname, sizeof(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); - ifneta[1] = NULL; - ifneta[0] = (struct ifnet *)calloc(1, sizeof(*ifp)); - nifs = 1; - } else { - nifs++; - ifneta = (struct ifnet **)realloc(ifneta, - (nifs + 1) * sizeof(*ifa)); - ifneta[nifs] = NULL; - ifneta[nifs - 1] = (struct ifnet *)malloc(sizeof(*ifp)); - } - 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() -{ - FILE *fp; - struct ifnet *ifp, **ifa; - char fname[32]; -# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ - (defined(OpenBSD) && (OpenBSD >= 199603)) - for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) { - ifp->if_output = write_output; - snprintf(fname, sizeof(fname), "/tmp/%s", ifp->if_xname); - if ((fp = fopen(fname, "w"))) - fclose(fp); - } -# else - - for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) { - ifp->if_output = write_output; - snprintf(fname, sizeof(fname), - "/tmp/%s%d", ifp->if_name, ifp->if_unit); - if ((fp = fopen(fname, "w"))) - fclose(fp); - } -# endif -} - - -void ipfr_fastroute(ip, fin, fdp) -ip_t *ip; -fr_info_t *fin; -frdest_t *fdp; -{ - struct ifnet *ifp = fdp->fd_ifp; - - if (!ifp) - return; /* 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 -} - - -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; -} -#endif /* _KERNEL */ diff --git a/sys/netinet/ip_fil.h b/sys/netinet/ip_fil.h deleted file mode 100644 index 79f6896..0000000 --- a/sys/netinet/ip_fil.h +++ /dev/null @@ -1,525 +0,0 @@ -/* - * Copyright (C) 1993-1997 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 _IOR('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) -#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 _IOR(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) -#endif -#define SIOCADDFR SIOCADAFR -#define SIOCDELFR SIOCRMAFR -#define SIOCINSFR SIOCINAFR - -typedef struct fr_ip { - u_int fi_v:4; /* IP version */ - u_int fi_fl:4; /* packet flags */ - u_char fi_tos; - u_char fi_ttl; - u_char fi_p; - struct in_addr fi_src; - struct in_addr fi_dst; - u_32_t fi_optmsk; /* bitmask composed from IP options */ - u_short fi_secmsk; /* bitmask composed from IP security options */ - u_short fi_auth; -} 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) - -typedef struct fr_info { - struct fr_ip fin_fi; - u_short fin_data[2]; - u_short fin_out; - u_short fin_hlen; - u_char fin_tcpf; - u_char fin_icode; /* From here on is packet specific */ - u_short fin_rule; - u_short fin_group; - u_short fin_dlen; - u_short fin_id; - void *fin_ifp; - struct frentry *fin_fr; - char *fin_dp; /* start of data past IP header */ - void *fin_mp; -} fr_info_t; - -/* - * Size for compares on fr_info structures - */ -#define FI_CSIZE (sizeof(struct fr_ip) + sizeof(u_short) * 4 + \ - sizeof(u_char)) -/* - * Size for copying cache fr_info structure - */ -#define FI_COPYSIZE (sizeof(fr_info_t) - sizeof(void *) * 2) - -typedef struct frdest { - void *fd_ifp; - struct in_addr fd_ip; - char fd_ifname[IFNAMSIZ]; -} frdest_t; - -typedef struct frentry { - struct frentry *fr_next; - u_short fr_group; /* group to which this rule belongs */ - u_short fr_grhead; /* group # which this rule starts */ - struct frentry *fr_grp; - int fr_ref; /* reference count - for grouping */ - void *fr_ifa; - /* - * 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_char fr_tcpfm; /* tcp flags mask */ - u_char fr_tcpf; /* tcp flags */ - - u_short fr_icmpm; /* data for ICMP packets (mask) */ - u_short fr_icmp; - - u_char fr_scmp; /* data for port comparisons */ - u_char fr_dcmp; - u_short fr_dport; - u_short fr_sport; - u_short fr_stop; /* top port for <> and >< */ - u_short fr_dtop; /* top port for <> and >< */ - u_32_t fr_flags; /* per-rule flags && options (see below) */ - int fr_skip; /* # of rules to skip */ - int (*fr_func) __P((int, ip_t *, fr_info_t *)); /* call this function */ - char fr_icode; /* return ICMP code */ - char fr_ifname[IFNAMSIZ]; - struct frdest fr_tif; /* "to" interface */ - struct frdest fr_dif; /* duplicate packet interfaces */ -} frentry_t; - -#define fr_proto fr_ip.fi_p -#define fr_ttl fr_ip.fi_ttl -#define fr_tos fr_ip.fi_tos -#define fr_dst fr_ip.fi_dst -#define fr_src fr_ip.fi_src -#define fr_dmsk fr_mip.fi_dst -#define fr_smsk fr_mip.fi_src - -#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_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_LOGMASK (FR_LOG|FR_LOGP|FR_LOGB) - -/* - * 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_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 */ -#if SOLARIS - 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! */ -#endif -} 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_auth; - u_long f_froute[2]; - int f_active; -} friostat_t; - -typedef struct optlist { - u_short ol_val; - int ol_bit; -} optlist_t; - - -/* - * Group list structure. - */ -typedef struct frgroup { - u_short 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_long ipl_magic; - u_long ipl_sec; - u_long ipl_usec; - u_int ipl_len; - u_int ipl_count; - 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_rule; /* assume never more than 64k rules, total */ - u_short fl_group; - u_32_t fl_flags; -} 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 - -#ifndef _KERNEL -struct ifnet; -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 void ipfr_fastroute __P((ip_t *, fr_info_t *, frdest_t *)); -extern struct ifnet *get_unit __P((char *)); -# define FR_SCANLIST(p, ip, fi, m) fr_scanlist(p, ip, fi, m) -# if defined(__NetBSD__) || defined(__OpenBSD__) || \ - (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300003) -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 int 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((int)); -extern int ipflog_read __P((int, struct uio *)); -extern int ipflog __P((u_int, ip_t *, fr_info_t *, mb_t *)); -extern int ipllog __P((int, u_long, void **, size_t *, int *, int)); -# 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 **)); -extern int icmp_error __P((ip_t *, int, int, qif_t *, - struct in_addr)); -extern int iplioctl __P((dev_t, int, int, 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 ipfsync __P((void)); -extern int send_reset __P((ip_t *, qif_t *)); -extern int ipfr_fastroute __P((qif_t *, ip_t *, mblk_t *, mblk_t **, - fr_info_t *, frdest_t *)); -extern void copyin_mblk __P((mblk_t *, int, int, char *)); -extern void copyout_mblk __P((mblk_t *, int, int, char *)); -extern int fr_qin __P((queue_t *, mblk_t *)); -extern int fr_qout __P((queue_t *, mblk_t *)); -# ifdef IPFILTER_LOG -extern int iplread __P((dev_t, struct uio *, cred_t *)); -# endif -# 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 **)); -# ifdef linux -extern int send_reset __P((tcpiphdr_t *, struct ifnet *)); -# else -extern int send_reset __P((tcpiphdr_t *)); -# endif -extern void 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) -# if defined(__NetBSD__) || (_BSDI_VERSION >= 199701) || \ - (__FreeBSD_version >= 300003) -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 -# if defined(__OpenBSD__) -extern int iplioctl __P((dev_t, u_long, caddr_t, int)); -# else /* __OpenBSD__ */ -# ifndef linux -extern int iplioctl __P((dev_t, int, caddr_t, int)); -# else -extern int iplioctl(struct inode *, struct file *, u_int, u_long); -# endif -# endif /* __OpenBSD__ */ -# ifndef linux -extern int iplopen __P((dev_t, int)); -extern int iplclose __P((dev_t, int)); -# else -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 */ - -/* - * 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) -# define NETBSD_PF -#endif - -extern int ipldetach __P((void)); -extern u_short fr_tcpsum __P((mb_t *, ip_t *, tcphdr_t *, int)); -#define FR_SCANLIST(p, ip, fi, m) fr_scanlist(p, ip, fi, m) -extern int fr_scanlist __P((int, ip_t *, fr_info_t *, void *)); -extern u_short ipf_cksum __P((u_short *, int)); -extern int fr_copytolog __P((int, char *, int)); -extern void frflush __P((int, int *)); -extern frgroup_t *fr_addgroup __P((u_short, frentry_t *, int, int)); -extern frgroup_t *fr_findgroup __P((u_short, u_32_t, int, int, frgroup_t ***)); -extern void fr_delgroup __P((u_short, u_32_t, int, int)); -extern int ipl_unreach; -extern int ipl_inited; -extern u_long ipl_frouteok[2]; -extern int fr_pass; -extern int fr_flags; -extern int fr_active; -extern fr_info_t frcache[2]; -#ifdef IPFILTER_LOG -extern iplog_t **iplh[IPL_LOGMAX+1], *iplt[IPL_LOGMAX+1]; -extern int iplused[IPL_LOGMAX + 1]; -#endif -extern struct frentry *ipfilter[2][2], *ipacct[2][2]; -extern struct frgroup *ipfgroups[3][2]; -extern struct filterstats frstats[]; - -#endif /* __IP_FIL_H__ */ diff --git a/sys/netinet/ip_frag.c b/sys/netinet/ip_frag.c deleted file mode 100644 index de104e5..0000000 --- a/sys/netinet/ip_frag.c +++ /dev/null @@ -1,467 +0,0 @@ -/* - * Copyright (C) 1993-1997 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-1995 Darren Reed"; -static const char rcsid[] = "@(#)$FreeBSD$"; -#endif - -#if !defined(_KERNEL) && defined(KERNEL) -#define _KERNEL -#endif -#define __FreeBSD_version 300000 /* it's a hack, but close enough */ - -#if !defined(_KERNEL) && !defined(KERNEL) -# include <string.h> -# include <stdlib.h> -#endif -#include <sys/errno.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/time.h> -#include <sys/file.h> -#if defined(KERNEL) && (__FreeBSD_version >= 220000) -#include <sys/filio.h> -#include <sys/fcntl.h> -#include <sys/malloc.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__) -# ifndef linux -# include <sys/mbuf.h> -# endif -#else -# include <sys/byteorder.h> -# include <sys/dditypes.h> -# include <sys/stream.h> -# include <sys/kmem.h> -#endif -#if defined(KERNEL) && (__FreeBSD_version >= 300000) -#include <sys/malloc.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" - -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 */ -#ifdef _KERNEL -extern int ipfr_timer_id; -#endif -#if (SOLARIS || defined(__sgi)) && defined(_KERNEL) -extern kmutex_t ipf_frag; -extern kmutex_t ipf_natfrag; -extern kmutex_t ipf_nat; -#endif - - -static ipfr_t *ipfr_new __P((ip_t *, fr_info_t *, int, ipfr_t **)); -static ipfr_t *ipfr_lookup __P((ip_t *, fr_info_t *, 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; -int pass; -ipfr_t *table[]; -{ - ipfr_t **fp, *fr, frag; - u_int idx; - - frag.ipfr_p = ip->ip_p; - idx = ip->ip_p; - frag.ipfr_id = ip->ip_id; - idx += ip->ip_id; - frag.ipfr_tos = ip->ip_tos; - frag.ipfr_src.s_addr = ip->ip_src.s_addr; - idx += ip->ip_src.s_addr; - frag.ipfr_dst.s_addr = ip->ip_dst.s_addr; - idx += ip->ip_dst.s_addr; - idx *= 127; - idx %= IPFT_SIZE; - - /* - * first, make sure it isn't already there... - */ - for (fp = &table[idx]; (fr = *fp); fp = &fr->ipfr_next) - if (!bcmp((char *)&frag.ipfr_src, (char *)&fr->ipfr_src, - IPFR_CMPSZ)) { - ipfr_stats.ifs_exists++; - return NULL; - } - - /* - * allocate some memory, if possible, if not, just record that we - * failed to do so. - */ - KMALLOC(fr, ipfr_t *, sizeof(*fr)); - if (fr == NULL) { - ipfr_stats.ifs_nomem++; - return NULL; - } - - /* - * 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 ((fr->ipfr_next = table[idx])) - table[idx]->ipfr_prev = fr; - fr->ipfr_prev = NULL; - fr->ipfr_data = NULL; - table[idx] = fr; - bcopy((char *)&frag.ipfr_src, (char *)&fr->ipfr_src, IPFR_CMPSZ); - fr->ipfr_ttl = fr_ipfrttl; - fr->ipfr_pass = pass & ~(FR_LOGFIRST|FR_LOG); - /* - * Compute the offset of the expected start of the next packet. - */ - fr->ipfr_off = (ip->ip_off & 0x1fff) + (fin->fin_dlen >> 3); - ipfr_stats.ifs_new++; - ipfr_inuse++; - return fr; -} - - -int ipfr_newfrag(ip, fin, pass) -ip_t *ip; -fr_info_t *fin; -int pass; -{ - ipfr_t *ipf; - - MUTEX_ENTER(&ipf_frag); - ipf = ipfr_new(ip, fin, pass, ipfr_heads); - MUTEX_EXIT(&ipf_frag); - return ipf ? 0 : -1; -} - - -int ipfr_nat_newfrag(ip, fin, pass, nat) -ip_t *ip; -fr_info_t *fin; -int pass; -nat_t *nat; -{ - ipfr_t *ipf; - - MUTEX_ENTER(&ipf_natfrag); - if ((ipf = ipfr_new(ip, fin, pass, ipfr_nattab))) { - ipf->ipfr_data = nat; - nat->nat_data = ipf; - } - MUTEX_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; - 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; - atoff = off + (fin->fin_dlen >> 3); - /* - * If we've follwed the fragments, and this is the - * last (in order), shrink expiration time. - */ - if ((off & 0x1fff) == f->ipfr_off) { - if (!(off & IP_MF)) - f->ipfr_ttl = 1; - else - f->ipfr_off = atoff; - } - 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; - - MUTEX_ENTER(&ipf_natfrag); - ipf = ipfr_lookup(ip, fin, ipfr_nattab); - if (ipf) { - nat = ipf->ipfr_data; - /* - * This is the last fragment for this packet. - */ - if (ipf->ipfr_ttl == 1) { - nat->nat_data = NULL; - ipf->ipfr_data = NULL; - } - } else - nat = NULL; - MUTEX_EXIT(&ipf_natfrag); - return nat; -} - - -/* - * functional interface for normal lookups of the fragment cache - */ -int ipfr_knownfrag(ip, fin) -ip_t *ip; -fr_info_t *fin; -{ - int ret; - ipfr_t *ipf; - - MUTEX_ENTER(&ipf_frag); - ipf = ipfr_lookup(ip, fin, ipfr_heads); - ret = ipf ? ipf->ipfr_pass : 0; - MUTEX_EXIT(&ipf_frag); - return ret; -} - - -/* - * forget any references to this external object. - */ -void ipfr_forget(nat) -void *nat; -{ - ipfr_t *fr; - int idx; - - MUTEX_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; - - MUTEX_EXIT(&ipf_natfrag); -} - - -/* - * Free memory in use by fragment state info. kept. - */ -void ipfr_unload() -{ - ipfr_t **fp, *fr; - nat_t *nat; - int idx; - - MUTEX_ENTER(&ipf_frag); - for (idx = IPFT_SIZE - 1; idx >= 0; idx--) - for (fp = &ipfr_heads[idx]; (fr = *fp); ) { - *fp = fr->ipfr_next; - KFREE(fr); - } - MUTEX_EXIT(&ipf_frag); - - MUTEX_ENTER(&ipf_nat); - MUTEX_ENTER(&ipf_natfrag); - for (idx = IPFT_SIZE - 1; idx >= 0; idx--) - for (fp = &ipfr_nattab[idx]; (fr = *fp); ) { - *fp = fr->ipfr_next; - if ((nat = (nat_t *)fr->ipfr_data)) { - if (nat->nat_data == fr) - nat->nat_data = NULL; - } - KFREE(fr); - } - MUTEX_EXIT(&ipf_natfrag); - MUTEX_EXIT(&ipf_nat); -} - - -#ifdef _KERNEL -/* - * Slowly expire held state for fragments. Timeouts are set * in expectation - * of this being called twice per second. - */ -# if (BSD >= 199306) || SOLARIS || defined(__sgi) -void ipfr_slowtimer() -# else -int ipfr_slowtimer() -# endif -{ - ipfr_t **fp, *fr; - nat_t *nat; - int s, idx; - -#ifdef __sgi - ipfilter_sgi_intfsync(); -#endif - - SPL_NET(s); - MUTEX_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]; (fr = *fp); ) { - --fr->ipfr_ttl; - if (fr->ipfr_ttl == 0) { - if (fr->ipfr_prev) - fr->ipfr_prev->ipfr_next = - fr->ipfr_next; - if (fr->ipfr_next) - fr->ipfr_next->ipfr_prev = - fr->ipfr_prev; - *fp = fr->ipfr_next; - ipfr_stats.ifs_expire++; - ipfr_inuse--; - KFREE(fr); - } else - fp = &fr->ipfr_next; - } - MUTEX_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. - */ - MUTEX_ENTER(&ipf_nat); - MUTEX_ENTER(&ipf_natfrag); - for (idx = IPFT_SIZE - 1; idx >= 0; idx--) - for (fp = &ipfr_nattab[idx]; (fr = *fp); ) { - --fr->ipfr_ttl; - if (fr->ipfr_ttl == 0) { - if (fr->ipfr_prev) - fr->ipfr_prev->ipfr_next = - fr->ipfr_next; - if (fr->ipfr_next) - fr->ipfr_next->ipfr_prev = - fr->ipfr_prev; - *fp = fr->ipfr_next; - ipfr_stats.ifs_expire++; - ipfr_inuse--; - if ((nat = (nat_t *)fr->ipfr_data)) { - if (nat->nat_data == fr) - nat->nat_data = NULL; - } - KFREE(fr); - } else - fp = &fr->ipfr_next; - } - MUTEX_EXIT(&ipf_natfrag); - MUTEX_EXIT(&ipf_nat); - SPL_X(s); - fr_timeoutstate(); - ip_natexpire(); - fr_authexpire(); -# if SOLARIS - ipfr_timer_id = timeout(ipfr_slowtimer, NULL, drv_usectohz(500000)); -# else -# ifndef linux - ip_slowtimo(); -# endif -# if (BSD < 199306) && !defined(__sgi) - return 0; -# endif -# endif -} -#endif /* defined(_KERNEL) */ diff --git a/sys/netinet/ip_frag.h b/sys/netinet/ip_frag.h deleted file mode 100644 index c509050..0000000 --- a/sys/netinet/ip_frag.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 1993-1997 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 - * $FreeBSD$ - */ - -#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; - u_short ipfr_id; - u_char ipfr_p; - u_char ipfr_tos; - u_short ipfr_off; - u_short ipfr_ttl; - u_char ipfr_pass; -} 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 ipfrstat_t *ipfr_fragstats __P((void)); -extern int ipfr_newfrag __P((ip_t *, fr_info_t *, int)); -extern int ipfr_nat_newfrag __P((ip_t *, fr_info_t *, int, struct nat *)); -extern nat_t *ipfr_nat_knownfrag __P((ip_t *, fr_info_t *)); -extern int ipfr_knownfrag __P((ip_t *, fr_info_t *)); -extern void ipfr_forget __P((void *)); -extern void ipfr_unload __P((void)); - -#if (BSD >= 199306) || SOLARIS || defined(__sgi) -extern void ipfr_slowtimer __P((void)); -#else -extern int ipfr_slowtimer __P((void)); -#endif - -#endif /* __IP_FIL_H__ */ diff --git a/sys/netinet/ip_ftp_pxy.c b/sys/netinet/ip_ftp_pxy.c deleted file mode 100644 index 917dbb2..0000000 --- a/sys/netinet/ip_ftp_pxy.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Simple FTP transparent proxy for in-kernel use. For use with the NAT - * code. - * - * $FreeBSD$ - */ - -#define isdigit(x) ((x) >= '0' && (x) <= '9') - -#define IPF_FTP_PROXY - -#define IPF_MINPORTLEN 18 -#define IPF_MAXPORTLEN 30 - - -int ippr_ftp_init __P((fr_info_t *, ip_t *, tcphdr_t *, - ap_session_t *, nat_t *)); -int ippr_ftp_in __P((fr_info_t *, ip_t *, tcphdr_t *, - ap_session_t *, nat_t *)); -int ippr_ftp_out __P((fr_info_t *, ip_t *, tcphdr_t *, - ap_session_t *, nat_t *)); -u_short ipf_ftp_atoi __P((char **)); - - -/* - * FTP application proxy initialization. - */ -int ippr_ftp_init(fin, ip, tcp, aps, nat) -fr_info_t *fin; -ip_t *ip; -tcphdr_t *tcp; -ap_session_t *aps; -nat_t *nat; -{ - aps->aps_sport = tcp->th_sport; - aps->aps_dport = tcp->th_dport; - return 0; -} - - -int ippr_ftp_in(fin, ip, tcp, aps, nat) -fr_info_t *fin; -ip_t *ip; -tcphdr_t *tcp; -ap_session_t *aps; -nat_t *nat; -{ - u_32_t sum1, sum2; - short sel; - - if (tcp->th_sport == aps->aps_dport) { - sum2 = (u_32_t)ntohl(tcp->th_ack); - sel = aps->aps_sel; - if ((aps->aps_after[!sel] > aps->aps_after[sel]) && - (sum2 > aps->aps_after[!sel])) { - sel = aps->aps_sel = !sel; /* switch to other set */ - } - if (aps->aps_seqoff[sel] && (sum2 > aps->aps_after[sel])) { - sum1 = (u_32_t)aps->aps_seqoff[sel]; - tcp->th_ack = htonl(sum2 - sum1); - return 2; - } - } - return 0; -} - - -/* - * ipf_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 ipf_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; - return (i << 8) | j; -} - - -int ippr_ftp_out(fin, ip, tcp, aps, nat) -fr_info_t *fin; -ip_t *ip; -tcphdr_t *tcp; -ap_session_t *aps; -nat_t *nat; -{ - register u_32_t sum1, sum2; - char newbuf[IPF_MAXPORTLEN+1]; - char portbuf[IPF_MAXPORTLEN+1], *s; - int ch = 0, off = (ip->ip_hl << 2) + (tcp->th_off << 2); - u_int a1, a2, a3, a4; - u_short a5, a6; - int olen, dlen, nlen = 0, inc = 0; - tcphdr_t tcph, *tcp2 = &tcph; - void *savep; - nat_t *ipn; - struct in_addr swip; - mb_t *m = *(mb_t **)fin->fin_mp; - -#if SOLARIS - mb_t *m1; - - /* skip any leading M_PROTOs */ - while(m && (MTYPE(m) != M_DATA)) - m = m->b_cont; - PANIC((!m),("ippr_ftp_out: no M_DATA")); - - dlen = msgdsize(m) - off; - bzero(portbuf, sizeof(portbuf)); - copyout_mblk(m, off, MIN(sizeof(portbuf), dlen), portbuf); -#else - dlen = mbufchainlen(m) - off; - bzero(portbuf, sizeof(portbuf)); - m_copydata(m, off, MIN(sizeof(portbuf), dlen), portbuf); -#endif - portbuf[IPF_MAXPORTLEN] = '\0'; - - if ((dlen < IPF_MINPORTLEN) || strncmp(portbuf, "PORT ", 5)) - goto adjust_seqack; - - /* - * Skip the PORT command + space - */ - s = portbuf + 5; - /* - * Pick out the address components, two at a time. - */ - (void) ipf_ftp_atoi(&s); - if (!s) - goto adjust_seqack; - (void) ipf_ftp_atoi(&s); - if (!s) - goto adjust_seqack; - a5 = ipf_ftp_atoi(&s); - if (!s) - goto adjust_seqack; - /* - * check for CR-LF at the end. - */ - if (*s != '\n' || *(s - 1) != '\r') - goto adjust_seqack; - a6 = a5 & 0xff; - a5 >>= 8; - /* - * 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 - portbuf + 1; - (void) snprintf(newbuf, sizeof(newbuf), "PORT %d,%d,%d,%d,%d,%d\r\n", - a1, a2, a3, a4, a5, a6); - nlen = strlen(newbuf); - inc = nlen - olen; -#if SOLARIS - for (m1 = m; m1->b_cont; m1 = m1->b_cont) - ; - if (inc > 0) { - mblk_t *nm; - - /* alloc enough to keep same trailer space for lower driver */ - nm = allocb(nlen + m1->b_datap->db_lim - m1->b_wptr, 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 - 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 - if (inc) { -#if SOLARIS || defined(__sgi) - 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; - } - ch = 1; - - /* - * Add skeleton NAT entry for connection which will come back the - * other way. - */ - savep = fin->fin_dp; - fin->fin_dp = (char *)tcp2; - bzero((char *)tcp2, sizeof(*tcp2)); - tcp2->th_sport = htons(a5 << 8 | a6); - tcp2->th_dport = htons(20); - swip = ip->ip_src; - ip->ip_src = nat->nat_inip; - if ((ipn = nat_new(nat->nat_ptr, ip, fin, IPN_TCP, NAT_OUTBOUND))) - ipn->nat_age = fr_defnatage; - (void) fr_addstate(ip, fin, FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE); - ip->ip_src = swip; - fin->fin_dp = (char *)savep; - -adjust_seqack: - if (tcp->th_dport == aps->aps_dport) { - sum2 = (u_32_t)ntohl(tcp->th_seq); - off = aps->aps_sel; - if ((aps->aps_after[!off] > aps->aps_after[off]) && - (sum2 > aps->aps_after[!off])) { - off = aps->aps_sel = !off; /* switch to other set */ - } - if (aps->aps_seqoff[off]) { - sum1 = (u_32_t)aps->aps_after[off] - - aps->aps_seqoff[off]; - if (sum2 > sum1) { - sum1 = (u_32_t)aps->aps_seqoff[off]; - sum2 += sum1; - tcp->th_seq = htonl(sum2); - ch = 1; - } - } - - if (inc && (sum2 > aps->aps_after[!off])) { - aps->aps_after[!off] = sum2 + nlen - 1; - aps->aps_seqoff[!off] = aps->aps_seqoff[off] + inc; - } - } - return ch ? 2 : 0; -} diff --git a/sys/netinet/ip_log.c b/sys/netinet/ip_log.c deleted file mode 100644 index 3f73a3e..0000000 --- a/sys/netinet/ip_log.c +++ /dev/null @@ -1,483 +0,0 @@ -/* - * Copyright (C) 1997 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. - * - * $FreeBSD$ - */ -#include "opt_ipfilter.h" - -#ifdef IPFILTER_LOG -# ifndef SOLARIS -# define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4))) -# endif - -# if defined(KERNEL) && !defined(_KERNEL) -# define _KERNEL -# endif -# ifdef __FreeBSD__ -# if defined(_KERNEL) && !defined(IPFILTER_LKM) -# define __FreeBSD_version 300000 /* this will do as a hack */ -# else -# include <osreldate.h> -# endif -# 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/param.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) || defined(__FreeBSD__) -# 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 <sys/malloc.h> -# include <machine/random.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" -# 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]; -int iplused[IPL_LOGMAX+1]; -static u_long iplcrc[IPL_LOGMAX+1]; -static u_long iplcrcinit; -#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; - iplh[i] = &iplt[i]; - iplused[i] = 0; - } -# if defined(__FreeBSD__) && __FreeBSD_version >= 300000 - read_random(&iplcrcinit, sizeof iplcrcinit); -# else - { - struct timeval tv; - -#if BSD >= 199306 || defined(__FreeBSD__) || defined(__sgi) - microtime(&tv); -# else - uniqtime(&tv); -# endif - iplcrcinit = tv.tv_sec ^ (tv.tv_usec << 8) ^ tv.tv_usec; - } -# endif -} - - -/* - * 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 int mlen, hlen; - u_long crc; - size_t sizes[2]; - void *ptrs[2]; - int types[2]; -# if SOLARIS - ill_t *ifp = fin->fin_ifp; -# else - struct ifnet *ifp = fin->fin_ifp; -# endif - - /* - * calculate header size. - */ - hlen = fin->fin_hlen; - if (ip->ip_p == IPPROTO_TCP) - hlen += MIN(sizeof(tcphdr_t), fin->fin_dlen); - else if (ip->ip_p == IPPROTO_UDP) - hlen += MIN(sizeof(udphdr_t), fin->fin_dlen); - else if (ip->ip_p == IPPROTO_ICMP) { - struct icmp *icmp = (struct icmp *)((char *)ip + hlen); - - /* - * 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(ip->ip_len - 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; - 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 - crc = (ipf_cksum((u_short *)fin, FI_CSIZE) << 8) + iplcrcinit; - return ipllog(IPL_LOGIPF, crc, ptrs, sizes, types, 2); -} - - -/* - * ipllog - */ -int ipllog(dev, crc, items, itemsz, types, cnt) -int dev; -u_long crc; -void **items; -size_t *itemsz; -int *types, cnt; -{ - iplog_t *ipl; - caddr_t buf, s; - int len, 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. - */ - if (crc) { - MUTEX_ENTER(&ipl_mutex); - if ((iplcrc[dev] == crc) && *iplh[dev]) { - (*iplh[dev])->ipl_count++; - MUTEX_EXIT(&ipl_mutex); - return 1; - } - iplcrc[dev] = crc; - 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. - */ - KMALLOC(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); - *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) -int unit; -struct uio *uio; -{ - iplog_t *ipl; - int error = 0, dlen, copied; -# 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) || (unit < 0)) - 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 + sizeof(iplog_t) > uio->uio_resid) - break; - /* - * Don't hold the mutex over the uiomove call. - */ - iplt[unit] = ipl->ipl_next; - MUTEX_EXIT(&ipl_mutex); - SPL_X(s); - error = UIOMOVE((caddr_t)ipl, ipl->ipl_dsize, UIO_READ, uio); - KFREES((caddr_t)ipl, ipl->ipl_dsize); - if (error) - break; - SPL_NET(s); - MUTEX_ENTER(&ipl_mutex); - iplused[unit] -= dlen; - } - if (!ipl) { - iplused[unit] = 0; - iplh[unit] = &iplt[unit]; - } - - if (!error) { - MUTEX_EXIT(&ipl_mutex); - SPL_X(s); - } -#ifdef linux - if (!error) - return copied; - return -error; -#else - return error; -#endif -} - - -int ipflog_clear(unit) -int unit; -{ - iplog_t *ipl; - int used; - - while ((ipl = iplt[unit])) { - iplt[unit] = ipl->ipl_next; - KFREES((caddr_t)ipl, ipl->ipl_dsize); - } - iplh[unit] = &iplt[unit]; - used = iplused[unit]; - iplused[unit] = 0; - iplcrc[unit] = 0; - return used; -} -#endif /* IPFILTER_LOG */ diff --git a/sys/netinet/ip_nat.c b/sys/netinet/ip_nat.c deleted file mode 100644 index a8f8744..0000000 --- a/sys/netinet/ip_nat.c +++ /dev/null @@ -1,1373 +0,0 @@ -/* - * Copyright (C) 1995-1997 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[] = "@(#)$FreeBSD$"; -#endif - -#include "opt_ipfilter.h" -#define __FreeBSD_version 300000 /* it's a hack, but close enough */ - -#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL) -#define _KERNEL -#endif - -#if !defined(_KERNEL) && !defined(KERNEL) -# include <stdio.h> -# include <string.h> -# include <stdlib.h> -#endif -#include <sys/errno.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/time.h> -#include <sys/file.h> -#if 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> -# include <sys/dditypes.h> -# include <sys/stream.h> -# include <sys/kmem.h> -#endif -#if __FreeBSD_version >= 300000 -# include <sys/queue.h> -# include <sys/malloc.h> -#endif -#include <net/if.h> -#if __FreeBSD_version >= 300000 -# include <net/if_var.h> -#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" -#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][NAT_SIZE], *nat_instances = NULL; -static ipnat_t *nat_list = NULL; -u_long fr_defnatage = 1200, /* 10 minutes (600 seconds) */ - fr_defnaticmpage = 6; /* 3 seconds */ -static natstat_t nat_stats; -#if (SOLARIS || defined(__sgi)) && defined(_KERNEL) -extern kmutex_t ipf_nat; -#endif - -static int nat_flushtable __P((void)); -static int nat_clearlist __P((void)); -static void nat_delete __P((struct nat *)); -static int nat_ifpaddr __P((nat_t *, void *, struct in_addr *)); - - -#define LONG_SUM(in) (((in) & 0xffff) + ((in) >> 16)) - -#define CALC_SUMD(s1, s2, sd) { \ - /* Do it twice */ \ - (s1) = ((s1) & 0xffff) + ((s1) >> 16); \ - (s1) = ((s1) & 0xffff) + ((s1) >> 16); \ - /* Do it twice */ \ - (s2) = ((s2) & 0xffff) + ((s2) >> 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); } - -void fix_outcksum(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); -} - - -void fix_incksum(sp, n) -u_short *sp; -u_32_t n; -{ - register u_short sumshort; - register u_32_t sum1; - - if (!n) - return; -#ifdef sparc - sum1 = (~(*sp)) & 0xffff; -#else - sum1 = (~ntohs(*sp)) & 0xffff; -#endif - sum1 += ~(n) & 0xffff; - sum1 = (sum1 >> 16) + (sum1 & 0xffff); - /* Again */ - sum1 = (sum1 >> 16) + (sum1 & 0xffff); - sumshort = ~(u_short)sum1; - *(sp) = htons(sumshort); -} - - -/* - * How the NAT is organised and works. - * - * Inside (interface y) NAT Outside (interface x) - * -------------------- -+- ------------------------------------- - * Packet going | out, processsed by ip_natout() for x - * ------------> | ------------> - * src=10.1.1.1 | src=192.1.1.1 - * | - * | in, processed by ip_natin() for x - * <------------ | <------------ - * dst=10.1.1.1 | dst=192.1.1.1 - * -------------------- -+- ------------------------------------- - * ip_natout() - changes ip_src and if required, sport - * - creates a new mapping, if required. - * ip_natin() - changes ip_dst and if required, dport - * - * In the NAT table, internal source is recorded as "in" and externally - * seen as "out". - */ - -/* - * Handle ioctls which manipulate the NAT. - */ -int nat_ioctl(data, cmd, mode) -#if defined(__NetBSD__) || defined(__OpenBSD__) || (__FreeBSD_version >= 300003) -u_long cmd; -#else -int cmd; -#endif -caddr_t data; -int mode; -{ - register ipnat_t *nat, *n = NULL, **np = NULL; - ipnat_t natd; - int error = 0, ret; -#if defined(_KERNEL) && !SOLARIS - int s; -#endif - - nat = NULL; /* XXX gcc -Wuninitialized */ - - /* - * For add/delete, look to see if the NAT entry is already present - */ - SPL_NET(s); - MUTEX_ENTER(&ipf_nat); - if ((cmd == SIOCADNAT) || (cmd == SIOCRMNAT)) { - IRCOPY(data, (char *)&natd, sizeof(natd)); - nat = &natd; - nat->in_inip &= nat->in_inmsk; - 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) - { - case SIOCADNAT : - if (!(mode & FWRITE)) { - error = EPERM; - break; - } - if (n) { - error = EEXIST; - break; - } - KMALLOC(n, ipnat_t *, sizeof(*n)); - if (n == NULL) { - error = ENOMEM; - break; - } - bcopy((char *)nat, (char *)n, sizeof(*n)); - n->in_ifp = (void *)GETUNIT(n->in_ifname); - if (!n->in_ifp) - n->in_ifp = (void *)-1; - n->in_apr = ap_match(n->in_p, n->in_plabel); - n->in_next = *np; - n->in_use = 0; - n->in_space = ~(0xffffffff & ntohl(n->in_outmsk)); - if (n->in_space) /* lose 2: broadcast + network address */ - n->in_space -= 2; - else - n->in_space = 1; /* single IP# mapping */ - if ((n->in_outmsk != 0xffffffff) && n->in_outmsk) - n->in_nip = ntohl(n->in_outip) + 1; - else - n->in_nip = ntohl(n->in_outip); - if (n->in_redir & NAT_MAP) { - n->in_pnext = ntohs(n->in_pmin); - /* - * Multiply by the number of ports made available. - */ - if (ntohs(n->in_pmax) > ntohs(n->in_pmin)) - n->in_space *= (ntohs(n->in_pmax) - - ntohs(n->in_pmin)); - } - /* Otherwise, these fields are preset */ - *np = n; - nat_stats.ns_rules++; - break; - case SIOCRMNAT : - if (!(mode & FWRITE)) { - error = EPERM; - break; - } - if (!n) { - error = ESRCH; - break; - } - *np = n->in_next; - if (!n->in_use) { - if (n->in_apr) - ap_free(n->in_apr); - KFREE(n); - nat_stats.ns_rules--; - } else { - n->in_flags |= IPN_DELETE; - n->in_next = NULL; - } - break; - case SIOCGNATS : - nat_stats.ns_table[0] = nat_table[0]; - nat_stats.ns_table[1] = nat_table[1]; - nat_stats.ns_list = nat_list; - IWCOPY((char *)&nat_stats, (char *)data, sizeof(nat_stats)); - break; - case SIOCGNATL : - { - natlookup_t nl; - - IRCOPY((char *)data, (char *)&nl, sizeof(nl)); - - if (nat_lookupredir(&nl)) { - IWCOPY((char *)&nl, (char *)data, sizeof(nl)); - } else - error = ESRCH; - break; - } - case SIOCFLNAT : - if (!(mode & FWRITE)) { - error = EPERM; - break; - } - ret = nat_flushtable(); - (void) ap_unload(); - IWCOPY((caddr_t)&ret, data, sizeof(ret)); - break; - case SIOCCNATL : - if (!(mode & FWRITE)) { - error = EPERM; - break; - } - ret = nat_clearlist(); - IWCOPY((caddr_t)&ret, data, sizeof(ret)); - break; - case FIONREAD : -#ifdef IPFILTER_LOG - IWCOPY((caddr_t)&iplused[IPL_LOGNAT], (caddr_t)data, - sizeof(iplused[IPL_LOGNAT])); -#endif - break; - } - MUTEX_EXIT(&ipf_nat); - SPL_X(s); - return error; -} - - -/* - * Delete a nat entry from the various lists and table. - */ -static void nat_delete(natd) -struct nat *natd; -{ - register struct nat **natp, *nat; - struct ipnat *ipn; - - for (natp = natd->nat_hstart[0]; (nat = *natp); - natp = &nat->nat_hnext[0]) - if (nat == natd) { - *natp = nat->nat_hnext[0]; - break; - } - - for (natp = natd->nat_hstart[1]; (nat = *natp); - natp = &nat->nat_hnext[1]) - if (nat == natd) { - *natp = nat->nat_hnext[1]; - break; - } - - /* - * If 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. - */ - if ((ipn = natd->nat_ptr)) { - ipn->in_space++; - ipn->in_use--; - if (!ipn->in_use && (ipn->in_flags & IPN_DELETE)) { - if (ipn->in_apr) - ap_free(ipn->in_apr); - KFREE(ipn); - nat_stats.ns_rules--; - } - } - - /* - * If there's a fragment table entry too for this nat entry, then - * dereference that as well. - */ - ipfr_forget((void *)natd); - 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; - - /* - * Everything will be deleted, so lets just make it the deletions - * quicker. - */ - bzero((char *)nat_table[0], sizeof(nat_table[0])); - bzero((char *)nat_table[1], sizeof(nat_table[1])); - - for (natp = &nat_instances; (nat = *natp); ) { - *natp = nat->nat_next; - nat_delete(nat); - j++; - } - - return j; -} - - -/* - * nat_clearlist - delete all entries in the active NAT mapping list. - */ -static int nat_clearlist() -{ - register ipnat_t *n, **np = &nat_list; - int i = 0; - - while ((n = *np)) { - *np = n->in_next; - if (!n->in_use) { - if (n->in_apr) - ap_free(n->in_apr); - KFREE(n); - nat_stats.ns_rules--; - i++; - } else { - n->in_flags |= IPN_DELETE; - n->in_next = NULL; - } - } - nat_stats.ns_inuse = 0; - return i; -} - - -/* - * return the first IP Address associated with an interface - */ -static int nat_ifpaddr(nat, ifptr, inp) -nat_t *nat; -void *ifptr; -struct in_addr *inp; -{ -#if SOLARIS - ill_t *ill = ifptr; -#else - struct ifnet *ifp = ifptr; -#endif - struct in_addr in; - -#if SOLARIS - in.s_addr = ntohl(ill->ill_ipif->ipif_local_addr); -#else /* SOLARIS */ -# if linux - ; -# else /* linux */ - struct ifaddr *ifa; - struct sockaddr_in *sin; - -# 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 = (SOCKADDR_IN *)&ifa->ifa_addr; -# else - sin = (SOCKADDR_IN *)ifa->ifa_addr; - while (sin && ifa && - sin->sin_family != AF_INET) { -# 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 = (SOCKADDR_IN *)ifa->ifa_addr; - } - if (!ifa) - sin = NULL; - if (!sin) { - KFREE(nat); - return -1; - } -# endif /* (BSD < 199306) && (!__sgi && IFF_DRVLOCK) */ - in = sin->sin_addr; - in.s_addr = ntohl(in.s_addr); -# endif /* linux */ -#endif /* SOLARIS */ - *inp = in; - return 0; -} - - -/* - * Create a new NAT table entry. - */ -nat_t *nat_new(np, ip, fin, flags, direction) -ipnat_t *np; -ip_t *ip; -fr_info_t *fin; -u_short flags; -int direction; -{ - register u_32_t sum1, sum2, sumd, l; - u_short port = 0, sport = 0, dport = 0, nport = 0; - struct in_addr in; - tcphdr_t *tcp = NULL; - nat_t *nat, **natp; - u_short nflags; - - nflags = flags & np->in_flags; - if (flags & IPN_TCPUDP) { - tcp = (tcphdr_t *)fin->fin_dp; - sport = tcp->th_sport; - dport = tcp->th_dport; - } - - /* Give me a new nat */ - KMALLOC(nat, nat_t *, sizeof(*nat)); - if (nat == NULL) - return NULL; - - bzero((char *)nat, sizeof(*nat)); - nat->nat_flags = flags; - - /* - * Search the current table for a match. - */ - if (direction == NAT_OUTBOUND) { - /* - * If it's an outbound packet which doesn't match any existing - * record, then create a new port - */ - l = 0; - do { - l++; - port = 0; - in.s_addr = np->in_nip; - if (!in.s_addr && (np->in_outmsk == 0xffffffff)) { - if ((l > 1) || - nat_ifpaddr(nat, fin->fin_ifp, &in) == -1) { - KFREE(nat); - return NULL; - } - } else if (!in.s_addr && !np->in_outmsk) { - if (l > 1) { - KFREE(nat); - return NULL; - } - in.s_addr = ntohl(ip->ip_src.s_addr); - if (nflags & IPN_TCPUDP) - port = sport; - } else if (nflags & IPN_TCPUDP) { - port = htons(np->in_pnext++); - if (np->in_pnext >= ntohs(np->in_pmax)) { - np->in_pnext = ntohs(np->in_pmin); - np->in_space--; - if (np->in_outmsk != 0xffffffff) - np->in_nip++; - } - } else if (np->in_outmsk != 0xffffffff) { - np->in_space--; - np->in_nip++; - } - - if (!port && (flags & IPN_TCPUDP)) - port = sport; - if ((np->in_nip & ntohl(np->in_outmsk)) > - ntohl(np->in_outip)) - np->in_nip = ntohl(np->in_outip) + 1; - } while (nat_inlookup(fin->fin_ifp, flags, ip->ip_dst, - dport, in, port)); - - /* Setup the NAT table */ - nat->nat_inip = ip->ip_src; - nat->nat_outip.s_addr = htonl(in.s_addr); - nat->nat_oip = ip->ip_dst; - - sum1 = (ntohl(ip->ip_src.s_addr) & 0xffff) + - (ntohl(ip->ip_src.s_addr) >> 16) + ntohs(sport); - - sum2 = (in.s_addr & 0xffff) + (in.s_addr >> 16) + ntohs(port); - - if (flags & IPN_TCPUDP) { - nat->nat_inport = sport; - nat->nat_outport = port; - nat->nat_oport = dport; - } - } else { - - /* - * Otherwise, it's an inbound packet. Most likely, we don't - * want to rewrite source ports and source addresses. Instead, - * we want to rewrite to a fixed internal address and fixed - * internal port. - */ - in.s_addr = ntohl(np->in_inip); - if (!(nport = np->in_pnext)) - nport = dport; - - nat->nat_inip.s_addr = htonl(in.s_addr); - nat->nat_outip = ip->ip_dst; - nat->nat_oip = ip->ip_src; - - sum1 = (ntohl(ip->ip_dst.s_addr) & 0xffff) + - (ntohl(ip->ip_dst.s_addr) >> 16) + ntohs(dport); - - sum2 = (in.s_addr & 0xffff) + (in.s_addr >> 16) + ntohs(nport); - - if (flags & IPN_TCPUDP) { - nat->nat_inport = nport; - nat->nat_outport = dport; - nat->nat_oport = sport; - } - } - - /* Do it twice */ - sum1 = (sum1 & 0xffff) + (sum1 >> 16); - sum1 = (sum1 & 0xffff) + (sum1 >> 16); - - /* Do it twice */ - sum2 = (sum2 & 0xffff) + (sum2 >> 16); - sum2 = (sum2 & 0xffff) + (sum2 >> 16); - - if (sum1 > sum2) - sum2--; /* Because ~1 == -2, We really need ~1 == -1 */ - sumd = sum2 - sum1; - sumd = (sumd & 0xffff) + (sumd >> 16); - nat->nat_sumd = (sumd & 0xffff) + (sumd >> 16); - - if ((flags & IPN_TCPUDP) && ((sport != port) || (dport != nport))) { - if (direction == NAT_OUTBOUND) - sum1 = (ntohl(ip->ip_src.s_addr) & 0xffff) + - (ntohl(ip->ip_src.s_addr) >> 16); - else - sum1 = (ntohl(ip->ip_dst.s_addr) & 0xffff) + - (ntohl(ip->ip_dst.s_addr) >> 16); - - sum2 = (in.s_addr & 0xffff) + (in.s_addr >> 16); - - /* Do it twice */ - sum1 = (sum1 & 0xffff) + (sum1 >> 16); - sum1 = (sum1 & 0xffff) + (sum1 >> 16); - - /* Do it twice */ - sum2 = (sum2 & 0xffff) + (sum2 >> 16); - sum2 = (sum2 & 0xffff) + (sum2 >> 16); - - if (sum1 > sum2) - sum2--; /* Because ~1 == -2, We really need ~1 == -1 */ - sumd = sum2 - sum1; - sumd = (sumd & 0xffff) + (sumd >> 16); - nat->nat_ipsumd = (sumd & 0xffff) + (sumd >> 16); - } else - nat->nat_ipsumd = nat->nat_sumd; - - in.s_addr = htonl(in.s_addr); - nat->nat_next = nat_instances; - nat_instances = nat; - natp = &nat_table[0][nat->nat_inip.s_addr % NAT_SIZE]; - nat->nat_hstart[0] = natp; - nat->nat_hnext[0] = *natp; - *natp = nat; - natp = &nat_table[1][nat->nat_outip.s_addr % NAT_SIZE]; - nat->nat_hstart[1] = natp; - nat->nat_hnext[1] = *natp; - *natp = nat; - nat->nat_ptr = np; - nat->nat_bytes = 0; - nat->nat_pkts = 0; - nat->nat_ifp = fin->fin_ifp; - nat->nat_dir = direction; - if (direction == NAT_OUTBOUND) { - if (flags & IPN_TCPUDP) - tcp->th_sport = port; - } else { - if (flags & IPN_TCPUDP) - tcp->th_dport = nport; - } - nat_stats.ns_added++; - nat_stats.ns_inuse++; - np->in_use++; - return nat; -} - - -nat_t *nat_icmpinlookup(ip, fin) -ip_t *ip; -fr_info_t *fin; -{ - icmphdr_t *icmp; - tcphdr_t *tcp = NULL; - ip_t *oip; - int flags = 0, type; - - 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 < sizeof(*icmp) + sizeof(ip_t))) - 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); - if (oip->ip_p == IPPROTO_TCP) - flags = IPN_TCP; - else if (oip->ip_p == IPPROTO_UDP) - flags = IPN_UDP; - if (flags & IPN_TCPUDP) { - tcp = (tcphdr_t *)((char *)oip + (oip->ip_hl << 2)); - return nat_inlookup(fin->fin_ifp, flags, oip->ip_dst, - tcp->th_dport, oip->ip_src, tcp->th_sport); - } - return nat_inlookup(fin->fin_ifp, 0, oip->ip_src, 0, oip->ip_dst, 0); -} - - -/* - * This should *ONLY* be used for incoming packets to make sure a NAT'd ICMP - * packet gets correctly recognised. - */ -nat_t *nat_icmpin(ip, fin, nflags) -ip_t *ip; -fr_info_t *fin; -int *nflags; -{ - icmphdr_t *icmp; - nat_t *nat; - ip_t *oip; - int flags = 0; - - if (!(nat = nat_icmpinlookup(ip, fin))) - return NULL; - - *nflags = IPN_ICMPERR; - icmp = (icmphdr_t *)fin->fin_dp; - oip = (ip_t *)((char *)icmp + 8); - if (oip->ip_p == IPPROTO_TCP) - flags = IPN_TCP; - else if (oip->ip_p == IPPROTO_UDP) - flags = IPN_UDP; - /* - * Need to adjust ICMP header to include the real IP#'s and - * port #'s. Only apply a checksum change relative to the - * IP address change is it will be modified again in ip_natout - * 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#. - */ - if (flags & IPN_TCPUDP) { - tcphdr_t *tcp = (tcphdr_t *)(oip + 1); - u_32_t sum1, sum2, sumd; - struct in_addr in; - - if (nat->nat_dir == NAT_OUTBOUND) { - sum1 = LONG_SUM(ntohl(oip->ip_src.s_addr)); - in = nat->nat_outip; - oip->ip_src = in; - tcp->th_sport = nat->nat_outport; - } else { - sum1 = LONG_SUM(ntohl(oip->ip_dst.s_addr)); - in = nat->nat_inip; - oip->ip_dst = in; - tcp->th_dport = nat->nat_inport; - } - - sum2 = LONG_SUM(in.s_addr); - - CALC_SUMD(sum1, sum2, sumd); - sumd = (sumd & 0xffff) + (sumd >> 16); - - if (nat->nat_dir == NAT_OUTBOUND) { - fix_incksum(&oip->ip_sum, sumd); - fix_incksum(&icmp->icmp_cksum, sumd); - } else { - fix_outcksum(&oip->ip_sum, sumd); - fix_outcksum(&icmp->icmp_cksum, sumd); - } - - /* - * TCP checksum doesn't make it into the 1st eight - * bytes but UDP does. - */ - if (ip->ip_p == IPPROTO_UDP) { - udphdr_t *udp = (udphdr_t *)tcp; - - if (udp->uh_sum) { - if (nat->nat_dir == NAT_OUTBOUND) - fix_incksum(&udp->uh_sum, - nat->nat_sumd); - else - fix_outcksum(&udp->uh_sum, - nat->nat_sumd); - } - } - } else - ip->ip_dst = nat->nat_outip; - 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. - */ -#ifdef __STDC__ -nat_t *nat_inlookup(void *ifp, int flags, struct in_addr src, u_short sport, struct in_addr mapdst, u_short mapdport) -#else -nat_t *nat_inlookup(ifp, flags, src, sport, mapdst, mapdport) -void *ifp; -register int flags; -struct in_addr src , mapdst; -u_short sport, mapdport; -#endif -{ - register nat_t *nat; - - flags &= IPN_TCPUDP; - - nat = nat_table[1][mapdst.s_addr % NAT_SIZE]; - for (; nat; nat = nat->nat_hnext[1]) - if ((!ifp || ifp == nat->nat_ifp) && - nat->nat_oip.s_addr == src.s_addr && - nat->nat_outip.s_addr == mapdst.s_addr && - flags == nat->nat_flags && (!flags || - (nat->nat_oport == sport && - nat->nat_outport == mapdport))) - return nat; - return NULL; -} - - -/* - * Lookup a nat entry based on the source 'real' ip address/port and - * destination address/port. We use this lookup when sending a packet out, - * we're looking for a table entry, based on the source address. - * NOTE: THE PACKET BEING CHECKED (IF FOUND) HAS A MAPPING ALREADY. - */ -#ifdef __STDC__ -nat_t *nat_outlookup(void *ifp, int flags, struct in_addr src, u_short sport, struct in_addr dst, u_short dport) -#else -nat_t *nat_outlookup(ifp, flags, src, sport, dst, dport) -void *ifp; -register int flags; -struct in_addr src , dst; -u_short sport, dport; -#endif -{ - register nat_t *nat; - - flags &= IPN_TCPUDP; - - nat = nat_table[0][src.s_addr % NAT_SIZE]; - for (; nat; nat = nat->nat_hnext[0]) { - if ((!ifp || ifp == nat->nat_ifp) && - nat->nat_inip.s_addr == src.s_addr && - nat->nat_oip.s_addr == dst.s_addr && - flags == nat->nat_flags && (!flags || - (nat->nat_inport == sport && nat->nat_oport == dport))) - return nat; - } - return NULL; -} - - -/* - * Lookup a nat entry based on the mapped source ip address/port and - * real destination address/port. We use this lookup when sending a packet - * out, we're looking for a table entry, based on the source address. - */ -#ifdef __STDC__ -nat_t *nat_lookupmapip(void *ifp, int flags, struct in_addr mapsrc, u_short mapsport, struct in_addr dst, u_short dport) -#else -nat_t *nat_lookupmapip(ifp, flags, mapsrc, mapsport, dst, dport) -void *ifp; -register int flags; -struct in_addr mapsrc , dst; -u_short mapsport, dport; -#endif -{ - register nat_t *nat; - - flags &= IPN_TCPUDP; - - nat = nat_table[1][mapsrc.s_addr % NAT_SIZE]; - for (; nat; nat = nat->nat_hnext[0]) - if ((!ifp || ifp == nat->nat_ifp) && - nat->nat_oip.s_addr == dst.s_addr && - nat->nat_outip.s_addr == mapsrc.s_addr && - flags == nat->nat_flags && (!flags || - (nat->nat_outport == mapsport && - nat->nat_oport == dport))) - return nat; - return NULL; -} - - -/* - * Lookup the NAT tables to search for a matching redirect - */ -nat_t *nat_lookupredir(np) -register natlookup_t *np; -{ - nat_t *nat; - - /* - * If nl_inip is non null, this is a lookup based on the real - * ip address. Else, we use the fake. - */ - if ((nat = nat_outlookup(NULL, np->nl_flags, np->nl_inip, - np->nl_inport, np->nl_outip, - np->nl_outport))) { - np->nl_realip = nat->nat_outip; - np->nl_realport = nat->nat_outport; - } - return nat; -} - - -/* - * Packets going out on the external interface go through this. - * Here, the source address requires alteration, if anything. - */ -int ip_natout(ip, hlen, fin) -ip_t *ip; -int hlen; -fr_info_t *fin; -{ - register ipnat_t *np; - register u_32_t ipa; - tcphdr_t *tcp = NULL; - u_short nflags = 0, sport = 0, dport = 0, *csump = NULL; - struct ifnet *ifp; - frentry_t *fr; - nat_t *nat; - int natadd = 1; - - if ((fr = fin->fin_fr) && !(fr->fr_flags & FR_DUP) && - fr->fr_tif.fd_ifp && fr->fr_tif.fd_ifp != (void *)-1) - ifp = fr->fr_tif.fd_ifp; - else - ifp = fin->fin_ifp; - - if (!(ip->ip_off & 0x1fff) && !(fin->fin_fi.fi_fl & FI_SHORT)) { - if (ip->ip_p == IPPROTO_TCP) - nflags = IPN_TCP; - else if (ip->ip_p == IPPROTO_UDP) - nflags = IPN_UDP; - if (nflags) { - tcp = (tcphdr_t *)fin->fin_dp; - sport = tcp->th_sport; - dport = tcp->th_dport; - } - } - - ipa = ip->ip_src.s_addr; - - MUTEX_ENTER(&ipf_nat); - if ((ip->ip_off & (IP_OFFMASK|IP_MF)) && - (nat = ipfr_nat_knownfrag(ip, fin))) - natadd = 0; - else if ((nat = nat_outlookup(ifp, nflags, ip->ip_src, sport, - ip->ip_dst, dport))) - ; - else - /* - * If there is no current entry in the nat table for this IP#, - * create one for it (if there is a matching rule). - */ - for (np = nat_list; np; np = np->in_next) - if ((np->in_ifp == ifp) && np->in_space && - (!np->in_flags || (np->in_flags & nflags)) && - ((ipa & np->in_inmsk) == np->in_inip) && - ((np->in_redir & NAT_MAP) || - (np->in_pnext == sport))) { - if (*np->in_plabel && !ap_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)) - continue; - if ((nat = nat_new(np, ip, fin, nflags, - NAT_OUTBOUND))) -#ifdef IPFILTER_LOG - nat_log(nat, (u_short)np->in_redir); -#else - ; -#endif - break; - } - - if (nat) { - if (natadd && fin->fin_fi.fi_fl & FI_FRAG) - ipfr_nat_newfrag(ip, fin, 0, nat); - nat->nat_age = fr_defnatage; - ip->ip_src = nat->nat_outip; - nat->nat_bytes += ip->ip_len; - nat->nat_pkts++; - - /* - * Fix up checksums, not by recalculating them, but - * simply computing adjustments. - */ -#if SOLARIS || defined(__sgi) - if (nat->nat_dir == NAT_OUTBOUND) - fix_outcksum(&ip->ip_sum, nat->nat_ipsumd); - else - fix_incksum(&ip->ip_sum, nat->nat_ipsumd); -#endif - - if (nflags && !(ip->ip_off & 0x1fff) && - !(fin->fin_fi.fi_fl & FI_SHORT)) { - - if (nat->nat_outport) - tcp->th_sport = nat->nat_outport; - - if (ip->ip_p == IPPROTO_TCP) { - csump = &tcp->th_sum; - fr_tcp_age(&nat->nat_age, - nat->nat_state, ip, fin,1); - /* - * 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; - } else if (ip->ip_p == IPPROTO_UDP) { - udphdr_t *udp = (udphdr_t *)tcp; - - if (udp->uh_sum) - csump = &udp->uh_sum; - } else if (ip->ip_p == IPPROTO_ICMP) { - icmphdr_t *ic = (icmphdr_t *)tcp; - - csump = &ic->icmp_cksum; - } - if (csump) { - if (nat->nat_dir == NAT_OUTBOUND) - fix_outcksum(csump, - nat->nat_sumd); - else - fix_incksum(csump, - nat->nat_sumd); - } - } - (void) ap_check(ip, tcp, fin, nat); - nat_stats.ns_mapped[1]++; - MUTEX_EXIT(&ipf_nat); - return -2; - } - MUTEX_EXIT(&ipf_nat); - return 0; -} - - -/* - * Packets coming in from the external interface go through this. - * Here, the destination address requires alteration, if anything. - */ -int ip_natin(ip, hlen, fin) -ip_t *ip; -int hlen; -fr_info_t *fin; -{ - register ipnat_t *np; - register struct in_addr in; - struct ifnet *ifp = fin->fin_ifp; - tcphdr_t *tcp = NULL; - u_short sport = 0, dport = 0, *csump = NULL; - nat_t *nat; - int nflags = 0, natadd = 1; - - if (!(ip->ip_off & 0x1fff) && !(fin->fin_fi.fi_fl & FI_SHORT)) { - if (ip->ip_p == IPPROTO_TCP) - nflags = IPN_TCP; - else if (ip->ip_p == IPPROTO_UDP) - nflags = IPN_UDP; - if (nflags) { - tcp = (tcphdr_t *)((char *)ip + hlen); - dport = tcp->th_dport; - sport = tcp->th_sport; - } - } - - in = ip->ip_dst; - - MUTEX_ENTER(&ipf_nat); - - if ((ip->ip_p == IPPROTO_ICMP) && (nat = nat_icmpin(ip, fin, &nflags))) - ; - else if ((ip->ip_off & IP_OFFMASK) && - (nat = ipfr_nat_knownfrag(ip, fin))) - natadd = 0; - else if ((nat = nat_inlookup(fin->fin_ifp, nflags, ip->ip_src, sport, - ip->ip_dst, dport))) - ; - else - /* - * If there is no current entry in the nat table for this IP#, - * create one for it (if there is a matching rule). - */ - for (np = nat_list; np; np = np->in_next) - if ((np->in_ifp == ifp) && - (!np->in_flags || (nflags & np->in_flags)) && - ((in.s_addr & np->in_outmsk) == np->in_outip) && - (np->in_redir & NAT_REDIRECT) && - (!np->in_pmin || np->in_pmin == dport)) { - if ((nat = nat_new(np, ip, fin, nflags, - NAT_INBOUND))) -#ifdef IPFILTER_LOG - nat_log(nat, (u_short)np->in_redir); -#else - ; -#endif - break; - } - if (nat) { - if (natadd && fin->fin_fi.fi_fl & FI_FRAG) - ipfr_nat_newfrag(ip, fin, 0, nat); - (void) ap_check(ip, tcp, fin, nat); - - if (nflags != IPN_ICMPERR) - nat->nat_age = fr_defnatage; - - ip->ip_dst = nat->nat_inip; - nat->nat_bytes += ip->ip_len; - nat->nat_pkts++; - - /* - * 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 ((nflags & IPN_TCPUDP) && !(ip->ip_off & 0x1fff) && - !(fin->fin_fi.fi_fl & FI_SHORT)) { - - if (nat->nat_inport) - tcp->th_dport = nat->nat_inport; - - if (ip->ip_p == IPPROTO_TCP) { - csump = &tcp->th_sum; - fr_tcp_age(&nat->nat_age, - nat->nat_state, ip, fin,0); - /* - * 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; - } else if (ip->ip_p == IPPROTO_UDP) { - udphdr_t *udp = (udphdr_t *)tcp; - - if (udp->uh_sum) - csump = &udp->uh_sum; - } else if (ip->ip_p == IPPROTO_ICMP) { - icmphdr_t *ic = (icmphdr_t *)tcp; - - csump = &ic->icmp_cksum; - } - if (csump) { - if (nat->nat_dir == NAT_OUTBOUND) - fix_incksum(csump, - nat->nat_sumd); - else - fix_outcksum(csump, - nat->nat_sumd); - } - } - nat_stats.ns_mapped[0]++; - MUTEX_EXIT(&ipf_nat); - return -2; - } - MUTEX_EXIT(&ipf_nat); - return 0; -} - - -/* - * Free all memory used by NAT structures allocated at runtime. - */ -void ip_natunload() -{ - MUTEX_ENTER(&ipf_nat); - (void) nat_clearlist(); - (void) nat_flushtable(); - (void) ap_unload(); - MUTEX_EXIT(&ipf_nat); -} - - -/* - * Slowly expire held state for NAT entries. Timeouts are set in - * expectation of this being called twice per second. - */ -void ip_natexpire() -{ - register struct nat *nat, **natp; -#if defined(_KERNEL) && !SOLARIS - int s; -#endif - - SPL_NET(s); - MUTEX_ENTER(&ipf_nat); - for (natp = &nat_instances; (nat = *natp); ) { - 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++; - } - - ap_expire(); - - MUTEX_EXIT(&ipf_nat); - SPL_X(s); -} - - -/* - */ -#ifdef __STDC__ -void ip_natsync(void *ifp) -#else -void ip_natsync(ifp) -void *ifp; -#endif -{ - register nat_t *nat; - register u_32_t sum1, sum2, sumd; - struct in_addr in; - ipnat_t *np; -#if defined(_KERNEL) && !SOLARIS - int s; -#endif - - SPL_NET(s); - MUTEX_ENTER(&ipf_nat); - for (nat = nat_instances; nat; nat = nat->nat_next) - if ((ifp == nat->nat_ifp) && (np = nat->nat_ptr)) - if ((np->in_outmsk == 0xffffffff) && !np->in_nip) { - /* - * Change the map-to address to be the same - * as the new one. - */ - sum1 = nat->nat_outip.s_addr; - if (nat_ifpaddr(nat, ifp, &in) == -1) - nat->nat_outip.s_addr = htonl(in.s_addr); - sum2 = nat->nat_outip.s_addr; - - /* - * Readjust the checksum adjustment to take - * into account the new IP#. - * - * Do it twice - */ - sum1 = (sum1 & 0xffff) + (sum1 >> 16); - sum1 = (sum1 & 0xffff) + (sum1 >> 16); - - /* Do it twice */ - sum2 = (sum2 & 0xffff) + (sum2 >> 16); - sum2 = (sum2 & 0xffff) + (sum2 >> 16); - - /* Because ~1 == -2, We really need ~1 == -1 */ - if (sum1 > sum2) - sum2--; - sumd = sum2 - sum1; - sumd = (sumd & 0xffff) + (sumd >> 16); - sumd += nat->nat_sumd; - nat->nat_sumd = (sumd & 0xffff) + (sumd >> 16); - } - MUTEX_EXIT(&ipf_nat); - SPL_X(s); -} - - -#ifdef IPFILTER_LOG -# ifdef __STDC__ -void nat_log(struct nat *nat, u_short type) -# else -void nat_log(nat, type) -struct nat *nat; -u_short type; -# endif -{ - 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_type = type; - natl.nl_rule = -1; - if (nat->nat_ptr) { - for (rulen = 0, np = nat_list; np; np = np->in_next, rulen++) - if (np == nat->nat_ptr) { - natl.nl_rule = rulen; - break; - } - } - items[0] = &natl; - sizes[0] = sizeof(natl); - types[0] = 0; - - (void) ipllog(IPL_LOGNAT, 0, items, sizes, types, 1); -} -#endif diff --git a/sys/netinet/ip_nat.h b/sys/netinet/ip_nat.h deleted file mode 100644 index d02a844..0000000 --- a/sys/netinet/ip_nat.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 1995-1997 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 - * $FreeBSD$ - */ - -#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', 80, struct ipnat) -#define SIOCRMNAT _IOW('r', 81, struct ipnat) -#define SIOCGNATS _IOR('r', 82, struct natstat) -#define SIOCGNATL _IOWR('r', 83, struct natlookup) -#define SIOCGFRST _IOR('r', 84, struct ipfrstat) -#define SIOCGIPST _IOR('r', 85, struct ips_stat) -#define SIOCFLNAT _IOWR('r', 86, int) -#define SIOCCNATL _IOWR('r', 87, int) -#else -#define SIOCADNAT _IOW(r, 80, struct ipnat) -#define SIOCRMNAT _IOW(r, 81, struct ipnat) -#define SIOCGNATS _IOR(r, 82, struct natstat) -#define SIOCGNATL _IOWR(r, 83, struct natlookup) -#define SIOCGFRST _IOR(r, 84, struct ipfrstat) -#define SIOCGIPST _IOR(r, 85, struct ips_stat) -#define SIOCFLNAT _IOWR(r, 86, int) -#define SIOCCNATL _IOWR(r, 87, int) -#endif - -#define NAT_SIZE 367 -#ifndef APR_LABELLEN -#define APR_LABELLEN 16 -#endif - -typedef struct nat { - u_long nat_age; - int nat_flags; - u_32_t nat_sumd; - u_32_t nat_ipsumd; - void *nat_data; - 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_state[2]; - struct ipnat *nat_ptr; - struct nat *nat_next; - struct nat *nat_hnext[2]; - struct nat **nat_hstart[2]; - void *nat_ifp; - int nat_dir; -} nat_t; - -typedef struct ipnat { - struct ipnat *in_next; - void *in_ifp; - void *in_apr; - u_int in_space; - u_int in_use; - struct in_addr in_nextip; - u_short in_pnext; - u_short in_flags; - u_short in_port[2]; - struct in_addr in_in[2]; - struct in_addr in_out[2]; - 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 */ - u_short in_dport; -} 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 NAT_OUTBOUND 0 -#define NAT_INBOUND 1 - -#define NAT_MAP 0x01 -#define NAT_REDIRECT 0x02 -#define NAT_BIMAP (NAT_MAP|NAT_REDIRECT) - -#define IPN_CMPSIZ (sizeof(struct in_addr) * 4 + sizeof(u_short) * 3 + \ - sizeof(int) + IFNAMSIZ + APR_LABELLEN + sizeof(char)) - -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 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; - nat_t **ns_table[2]; - ipnat_t *ns_list; -} natstat_t; - -#define IPN_ANY 0x00 -#define IPN_TCP 0x01 -#define IPN_UDP 0x02 -#define IPN_TCPUDP 0x03 -#define IPN_DELETE 0x04 -#define IPN_ICMPERR 0x08 - - -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; -} natlog_t; - - -#define NL_NEWMAP NAT_MAP -#define NL_NEWRDR NAT_REDIRECT -#define NL_EXPIRE 0xffff - - -extern void ip_natsync __P((void *)); -extern u_long fr_defnatage; -extern u_long fr_defnaticmpage; -extern nat_t *nat_table[2][NAT_SIZE]; -#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 nat_t *nat_new __P((ipnat_t *, ip_t *, fr_info_t *, u_short, int)); -extern nat_t *nat_outlookup __P((void *, int, struct in_addr, u_short, - struct in_addr, u_short)); -extern nat_t *nat_inlookup __P((void *, int, struct in_addr, u_short, - struct in_addr, u_short)); -extern nat_t *nat_lookupredir __P((natlookup_t *)); -extern nat_t *nat_lookupmapip __P((void *, int, struct in_addr, u_short, - struct in_addr, u_short)); -extern nat_t *nat_icmpinlookup __P((ip_t *, fr_info_t *)); -extern nat_t *nat_icmpin __P((ip_t *, fr_info_t *, int *)); - -extern int ip_natout __P((ip_t *, int, fr_info_t *)); -extern int ip_natin __P((ip_t *, int, fr_info_t *)); -extern void ip_natunload __P((void)), ip_natexpire __P((void)); -extern void nat_log __P((struct nat *, u_short)); -extern void fix_incksum __P((u_short *, u_32_t)); -extern void fix_outcksum __P((u_short *, u_32_t)); - -#endif /* __IP_NAT_H__ */ diff --git a/sys/netinet/ip_proxy.c b/sys/netinet/ip_proxy.c deleted file mode 100644 index e604051..0000000 --- a/sys/netinet/ip_proxy.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright (C) 1997 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[] = "@(#)$FreeBSD$"; -#endif - -#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL) -# define _KERNEL -#endif - -#if !defined(_KERNEL) && !defined(KERNEL) -# include <stdio.h> -# include <string.h> -# include <stdlib.h> -#endif -#include <sys/errno.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/time.h> -#include <sys/file.h> -#if !defined(__FreeBSD__) -# 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) -# 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> -# include <sys/dditypes.h> -# include <sys/stream.h> -# include <sys/kmem.h> -#endif -#if __FreeBSD__ > 2 -# include <sys/queue.h> -# include <sys/malloc.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" - -#ifndef MIN -#define MIN(a,b) (((a)<(b))?(a):(b)) -#endif - -static ap_session_t *ap_find __P((ip_t *, tcphdr_t *)); -static ap_session_t *ap_new_session __P((aproxy_t *, ip_t *, tcphdr_t *, - fr_info_t *, nat_t *)); - -static int ap_matchsrcdst __P((ap_session_t *aps, struct in_addr src, - struct in_addr dst, void *tcp, u_short sport, - u_short dport)); - -#define AP_SESS_SIZE 53 - -#if defined(_KERNEL) && !defined(linux) -#include "netinet/ip_ftp_pxy.c" -#endif - -ap_session_t *ap_sess_tab[AP_SESS_SIZE]; -aproxy_t ap_proxies[] = { -#ifdef IPF_FTP_PROXY - { "ftp", (char)IPPROTO_TCP, 0, 0, ippr_ftp_init, ippr_ftp_in, ippr_ftp_out }, -#endif - { "", '\0', 0, 0, NULL, NULL } -}; - - -int ap_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->apr_flags & APR_DELETE)) || - (ip->ip_p != apr->apr_p)) - return 0; - if ((tcp && (tcp->th_dport != dport)) || (!tcp && dport)) - return 0; - return 1; -} - - -static int -ap_matchsrcdst(aps, src, dst, tcp, sport, dport) -ap_session_t *aps; -struct in_addr src, dst; -void *tcp; -u_short sport, dport; -{ - if (aps->aps_dst.s_addr == dst.s_addr) { - if ((aps->aps_src.s_addr == src.s_addr) && - (!tcp || ((sport == aps->aps_sport) && - (dport == aps->aps_dport)))) - return 1; - } else if (aps->aps_dst.s_addr == src.s_addr) { - if ((aps->aps_src.s_addr == dst.s_addr) && - (!tcp || ((sport == aps->aps_dport) && - (dport == aps->aps_sport)))) - return 1; - } - return 0; -} - - -static ap_session_t *ap_find(ip, tcp) -ip_t *ip; -tcphdr_t *tcp; -{ - register u_char p = ip->ip_p; - register ap_session_t *aps; - register u_short sp, dp; - register u_long hv; - struct in_addr src, dst; - - src = ip->ip_src, dst = ip->ip_dst; - sp = dp = 0; /* XXX gcc -Wunitialized */ - - hv = ip->ip_src.s_addr ^ ip->ip_dst.s_addr; - hv *= 651733; - if (tcp) { - sp = tcp->th_sport; - dp = tcp->th_dport; - hv ^= (sp + dp); - hv *= 5; - } - hv %= AP_SESS_SIZE; - - for (aps = ap_sess_tab[hv]; aps; aps = aps->aps_next) - if ((aps->aps_p == p) && - ap_matchsrcdst(aps, src, dst, tcp, sp, dp)) - break; - return aps; -} - - -/* - * 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 *ap_new_session(apr, ip, tcp, fin, nat) -aproxy_t *apr; -ip_t *ip; -tcphdr_t *tcp; -fr_info_t *fin; -nat_t *nat; -{ - register ap_session_t *aps; - u_short dport; - u_long hv; - - if (!apr || (apr && (apr->apr_flags & APR_DELETE)) || - (ip->ip_p != apr->apr_p)) - return NULL; - dport = nat->nat_ptr->in_dport; - if ((tcp && (tcp->th_dport != dport)) || (!tcp && dport)) - return NULL; - - hv = ip->ip_src.s_addr ^ ip->ip_dst.s_addr; - hv *= 651733; - if (tcp) { - hv ^= (tcp->th_sport + tcp->th_dport); - hv *= 5; - } - hv %= AP_SESS_SIZE; - - KMALLOC(aps, ap_session_t *, sizeof(*aps)); - if (!aps) - return NULL; - bzero((char *)aps, sizeof(*aps)); - aps->aps_apr = apr; - aps->aps_src = ip->ip_src; - aps->aps_dst = ip->ip_dst; - aps->aps_p = ip->ip_p; - aps->aps_tout = 1200; /* XXX */ - if (tcp) { - aps->aps_sport = tcp->th_sport; - aps->aps_dport = tcp->th_dport; - } - aps->aps_data = NULL; - aps->aps_psiz = 0; - aps->aps_next = ap_sess_tab[hv]; - ap_sess_tab[hv] = aps; - (void) (*apr->apr_init)(fin, ip, tcp, aps, nat); - return aps; -} - - -/* - * check to see if a packet should be passed through an active proxy routine - * if one has been setup for it. - */ -int ap_check(ip, tcp, fin, nat) -ip_t *ip; -tcphdr_t *tcp; -fr_info_t *fin; -nat_t *nat; -{ - ap_session_t *aps; - aproxy_t *apr; - int err; - - if (!(fin->fin_fi.fi_fl & FI_TCPUDP)) - tcp = NULL; - - if ((aps = ap_find(ip, tcp)) || - (aps = ap_new_session(nat->nat_ptr->in_apr, ip, tcp, fin, nat))) { - if (ip->ip_p == IPPROTO_TCP) { - /* - * verify that the checksum is correct. If not, then - * don't do anything with this packet. - */ - if (tcp->th_sum != fr_tcpsum(*(mb_t **)fin->fin_mp, - ip, tcp, ip->ip_len)) { - frstats[fin->fin_out].fr_tcpbad++; - return -1; - } - fr_tcp_age(&aps->aps_tout, aps->aps_state, ip, fin, - tcp->th_sport == aps->aps_sport); - } - - apr = aps->aps_apr; - err = 0; - if (fin->fin_out) { - if (apr->apr_outpkt) - err = (*apr->apr_outpkt)(fin, ip, tcp, - aps, nat); - } else { - if (apr->apr_inpkt) - err = (*apr->apr_inpkt)(fin, ip, tcp, - aps, nat); - } - if (err == 2) { - tcp->th_sum = fr_tcpsum(*(mb_t **)fin->fin_mp, ip, - tcp, ip->ip_len); - err = 0; - } - return err; - } - return -1; -} - - -aproxy_t *ap_match(pr, name) -u_char 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; - } - return NULL; -} - - -void ap_free(ap) -aproxy_t *ap; -{ - ap->apr_ref--; -} - - -void aps_free(aps) -ap_session_t *aps; -{ - if (aps->aps_data && aps->aps_psiz) - KFREES(aps->aps_data, aps->aps_psiz); - KFREE(aps); -} - - -void ap_unload() -{ - ap_session_t *aps; - int i; - - for (i = 0; i < AP_SESS_SIZE; i++) - while ((aps = ap_sess_tab[i])) { - ap_sess_tab[i] = aps->aps_next; - aps_free(aps); - } -} - - -void ap_expire() -{ - ap_session_t *aps, **apsp; - int i; - - for (i = 0; i < AP_SESS_SIZE; i++) - for (apsp = &ap_sess_tab[i]; (aps = *apsp); ) { - aps->aps_tout--; - if (!aps->aps_tout) { - ap_sess_tab[i] = aps->aps_next; - aps_free(aps); - *apsp = aps->aps_next; - } else - apsp = &aps->aps_next; - } -} diff --git a/sys/netinet/ip_proxy.h b/sys/netinet/ip_proxy.h deleted file mode 100644 index cd7e9f9..0000000 --- a/sys/netinet/ip_proxy.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 1997 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. - * - * $FreeBSD$ - */ - -#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; /* seqoff/after set selector */ - short apt_seqoff[2]; /* sequence # difference */ - tcp_seq apt_after[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; - struct in_addr aps_src; /* source IP# */ - struct in_addr aps_dst; /* destination IP# */ - u_char aps_p; /* protocol */ - union { - struct ap_tcp apu_tcp; - struct ap_udp apu_udp; - } aps_un; - u_int aps_flags; - QUAD_T aps_bytes; /* bytes sent */ - QUAD_T aps_pkts; /* packets sent */ - u_long aps_tout; /* time left before expiring */ - void *aps_data; /* private data */ - int aps_psiz; /* size of private data */ - 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_after aps_un.apu_tcp.apt_after -#define aps_state aps_un.apu_tcp.apt_state - - -typedef struct aproxy { - 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((fr_info_t *, ip_t *, tcphdr_t *, - ap_session_t *, struct nat *)); - int (* apr_inpkt) __P((fr_info_t *, ip_t *, tcphdr_t *, - ap_session_t *, struct nat *)); - int (* apr_outpkt) __P((fr_info_t *, ip_t *, tcphdr_t *, - ap_session_t *, struct nat *)); -} aproxy_t; - -#define APR_DELETE 1 - - -extern ap_session_t *ap_sess_tab[AP_SESS_SIZE]; -extern aproxy_t ap_proxies[]; - -extern int ap_ok __P((ip_t *, tcphdr_t *, struct ipnat *)); -extern void ap_unload __P((void)); -extern void ap_free __P((aproxy_t *)); -extern void aps_free __P((ap_session_t *)); -extern int ap_check __P((ip_t *, tcphdr_t *, fr_info_t *, struct nat *)); -extern aproxy_t *ap_match __P((u_char, char *)); -extern void ap_expire __P((void)); - -#endif /* __IP_PROXY_H__ */ diff --git a/sys/netinet/ip_state.c b/sys/netinet/ip_state.c deleted file mode 100644 index d5a3637..0000000 --- a/sys/netinet/ip_state.c +++ /dev/null @@ -1,799 +0,0 @@ -/* - * Copyright (C) 1995-1997 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-1995 Darren Reed"; -static const char rcsid[] = "@(#)$FreeBSD$"; -#endif - -#include "opt_ipfilter.h" -#if defined(KERNEL) && !defined(_KERNEL) -#define _KERNEL -#endif -#define __FreeBSD_version 300000 /* it's a hack, but close enough */ - -#if !defined(_KERNEL) && !defined(KERNEL) && !defined(__KERNEL__) -# include <stdlib.h> -# include <string.h> -#else -# ifdef linux -# include <linux/kernel.h> -# include <linux/module.h> -# endif -#endif -#include <sys/errno.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/file.h> -#if defined(KERNEL) && (__FreeBSD_version >= 220000) -# include <sys/filio.h> -# include <sys/fcntl.h> -# include <sys/malloc.h> -#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(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> -# include <sys/dditypes.h> -# include <sys/stream.h> -# include <sys/kmem.h> -#endif - -#include <net/if.h> -#ifdef sun -#include <net/af.h> -#endif -#include <net/route.h> -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <netinet/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" -#ifndef MIN -#define MIN(a,b) (((a)<(b))?(a):(b)) -#endif - -#define TCP_CLOSE (TH_FIN|TH_RST) - -static ipstate_t *ips_table[IPSTATE_SIZE]; -static int ips_num = 0; -static ips_stat_t ips_stats; -#if (SOLARIS || defined(__sgi)) && defined(_KERNEL) -extern kmutex_t ipf_state; -#endif - -static int fr_matchsrcdst __P((ipstate_t *, struct in_addr, struct in_addr, - fr_info_t *, void *, u_short, u_short)); -static int fr_state_flush __P((int)); -static ips_stat_t *fr_statetstats __P((void)); - - -#define FIVE_DAYS (2 * 5 * 86400) /* 5 days: half closed session */ - -u_long fr_tcpidletimeout = FIVE_DAYS, - fr_tcpclosewait = 60, - fr_tcplastack = 20, - fr_tcptimeout = 120, - fr_tcpclosed = 1, - fr_udptimeout = 120, - fr_icmptimeout = 120; - - -static ips_stat_t *fr_statetstats() -{ - ips_stats.iss_active = ips_num; - ips_stats.iss_table = ips_table; - 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 int i; - register ipstate_t *is, **isp; -#if defined(_KERNEL) && !SOLARIS - int s; -#endif - int delete, removed = 0; - - SPL_NET(s); - MUTEX_ENTER(&ipf_state); - for (i = 0; i < IPSTATE_SIZE; i++) - for (isp = &ips_table[i]; (is = *isp); ) { - delete = 0; - - switch (which) - { - case 0 : - delete = 1; - break; - case 1 : - if ((is->is_p == IPPROTO_TCP) && - (((is->is_state[0] <= TCPS_ESTABLISHED) && - (is->is_state[1] > TCPS_ESTABLISHED)) || - ((is->is_state[1] <= TCPS_ESTABLISHED) && - (is->is_state[0] > TCPS_ESTABLISHED)))) - delete = 1; - break; - } - - if (delete) { - *isp = is->is_next; - if (is->is_p == IPPROTO_TCP) - ips_stats.iss_fin++; - else - ips_stats.iss_expire++; -#ifdef IPFILTER_LOG - ipstate_log(is, ISL_FLUSH); -#endif - KFREE(is); - ips_num--; - removed++; - } else - isp = &is->is_next; - } - MUTEX_EXIT(&ipf_state); - SPL_X(s); - return removed; -} - - -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 SIOCIPFFL : - IRCOPY(data, (caddr_t)&arg, sizeof(arg)); - if (arg == 0 || arg == 1) { - ret = fr_state_flush(arg); - IWCOPY((caddr_t)&ret, data, sizeof(ret)); - } else - error = EINVAL; - break; - case SIOCGIPST : - IWCOPY((caddr_t)fr_statetstats(), data, sizeof(ips_stat_t)); - break; - case FIONREAD : -#ifdef IPFILTER_LOG - IWCOPY((caddr_t)&iplused[IPL_LOGSTATE], (caddr_t)data, - sizeof(iplused[IPL_LOGSTATE])); -#endif - break; - default : - return EINVAL; - } - return error; -} - - -/* - * Create a new ipstate structure and hang it off the hash table. - */ -int fr_addstate(ip, fin, pass) -ip_t *ip; -fr_info_t *fin; -u_int pass; -{ - ipstate_t ips; - register ipstate_t *is = &ips; - register u_int hv; - - if ((ip->ip_off & 0x1fff) || (fin->fin_fi.fi_fl & FI_SHORT)) - return -1; - if (ips_num == IPSTATE_MAX) { - ips_stats.iss_max++; - return -1; - } - ips.is_age = 1; - ips.is_state[0] = 0; - ips.is_state[1] = 0; - /* - * Copy and calculate... - */ - hv = (is->is_p = ip->ip_p); - hv += (is->is_src.s_addr = ip->ip_src.s_addr); - hv += (is->is_dst.s_addr = ip->ip_dst.s_addr); - - switch (ip->ip_p) - { - case IPPROTO_ICMP : - { - struct icmp *ic = (struct icmp *)fin->fin_dp; - - switch (ic->icmp_type) - { - case ICMP_ECHO : - is->is_icmp.ics_type = ICMP_ECHOREPLY; /* XXX */ - hv += (is->is_icmp.ics_id = ic->icmp_id); - hv += (is->is_icmp.ics_seq = ic->icmp_seq); - break; - case ICMP_TSTAMP : - case ICMP_IREQ : - case ICMP_MASKREQ : - is->is_icmp.ics_type = ic->icmp_type + 1; - break; - default : - return -1; - } - ips_stats.iss_icmp++; - is->is_age = fr_icmptimeout; - break; - } - case IPPROTO_TCP : - { - register tcphdr_t *tcp = (tcphdr_t *)fin->fin_dp; - - /* - * The endian of the ports doesn't matter, but the ack and - * sequence numbers do as we do mathematics on them later. - */ - hv += (is->is_dport = tcp->th_dport); - hv += (is->is_sport = tcp->th_sport); - is->is_seq = ntohl(tcp->th_seq); - is->is_ack = ntohl(tcp->th_ack); - is->is_swin = ntohs(tcp->th_win); - is->is_dwin = is->is_swin; /* start them the same */ - ips_stats.iss_tcp++; - /* - * If we're creating state for a starting connection, start the - * timer on it as we'll never see an error if it fails to - * connect. - */ - if ((tcp->th_flags & (TH_SYN|TH_ACK)) == TH_SYN) - is->is_ack = 0; /* Trumpet WinSock 'ism */ - fr_tcp_age(&is->is_age, is->is_state, ip, fin, - tcp->th_sport == is->is_sport); - break; - } - case IPPROTO_UDP : - { - register tcphdr_t *tcp = (tcphdr_t *)fin->fin_dp; - - hv += (is->is_dport = tcp->th_dport); - hv += (is->is_sport = tcp->th_sport); - ips_stats.iss_udp++; - is->is_age = fr_udptimeout; - break; - } - default : - return -1; - } - - KMALLOC(is, ipstate_t *, sizeof(*is)); - if (is == NULL) { - ips_stats.iss_nomem++; - return -1; - } - bcopy((char *)&ips, (char *)is, sizeof(*is)); - hv %= IPSTATE_SIZE; - MUTEX_ENTER(&ipf_state); - - is->is_pass = pass; - is->is_pkts = 1; - is->is_bytes = ip->ip_len; - /* - * Copy these from the rule itself. - */ - is->is_opt = fin->fin_fr->fr_ip.fi_optmsk; - is->is_optmsk = fin->fin_fr->fr_mip.fi_optmsk; - is->is_sec = fin->fin_fr->fr_ip.fi_secmsk; - is->is_secmsk = fin->fin_fr->fr_mip.fi_secmsk; - is->is_auth = fin->fin_fr->fr_ip.fi_auth; - is->is_authmsk = fin->fin_fr->fr_mip.fi_auth; - is->is_flags = fin->fin_fr->fr_ip.fi_fl; - is->is_flags |= fin->fin_fr->fr_mip.fi_fl << 4; - /* - * add into table. - */ - is->is_next = ips_table[hv]; - ips_table[hv] = is; - if (fin->fin_out) { - is->is_ifpin = NULL; - is->is_ifpout = fin->fin_ifp; - } else { - is->is_ifpin = fin->fin_ifp; - is->is_ifpout = NULL; - } - if (pass & FR_LOGFIRST) - is->is_pass &= ~(FR_LOGFIRST|FR_LOG); - ips_num++; -#ifdef IPFILTER_LOG - ipstate_log(is, ISL_NEW); -#endif - MUTEX_EXIT(&ipf_state); - if (fin->fin_fi.fi_fl & FI_FRAG) - ipfr_newfrag(ip, fin, pass ^ FR_KEEPSTATE); - return 0; -} - - -/* - * check to see if a packet with TCP headers fits within the TCP window. - * change timeout depending on whether new packet is a SYN-ACK returning for a - * SYN or a RST or FIN which indicate time to close up shop. - */ -int fr_tcpstate(is, fin, ip, tcp) -register ipstate_t *is; -fr_info_t *fin; -ip_t *ip; -tcphdr_t *tcp; -{ - register int seqskew, ackskew; - register u_short swin, dwin; - register tcp_seq seq, ack; - int source; - - /* - * Find difference between last checked packet and this packet. - */ - seq = ntohl(tcp->th_seq); - ack = ntohl(tcp->th_ack); - source = (ip->ip_src.s_addr == is->is_src.s_addr); - - if (!(tcp->th_flags & TH_ACK)) /* Pretend an ack was sent */ - ack = source ? is->is_ack : is->is_seq; - - if (source) { - if (!is->is_seq) - /* - * Must be an outgoing SYN-ACK in reply to a SYN. - */ - is->is_seq = seq; - seqskew = seq - is->is_seq; - ackskew = ack - is->is_ack; - } else { - if (!is->is_ack) - /* - * Must be a SYN-ACK in reply to a SYN. - */ - is->is_ack = seq; - ackskew = seq - is->is_ack; - seqskew = ack - is->is_seq; - } - - /* - * Make skew values absolute - */ - if (seqskew < 0) - seqskew = -seqskew; - if (ackskew < 0) - ackskew = -ackskew; - - /* - * If the difference in sequence and ack numbers is within the - * window size of the connection, store these values and match - * the packet. - */ - if (source) { - swin = is->is_swin; - dwin = is->is_dwin; - } else { - dwin = is->is_swin; - swin = is->is_dwin; - } - - if ((seqskew <= dwin) && (ackskew <= swin)) { - if (source) { - is->is_seq = seq; - is->is_ack = ack; - is->is_swin = ntohs(tcp->th_win); - } else { - is->is_seq = ack; - is->is_ack = seq; - is->is_dwin = ntohs(tcp->th_win); - } - ips_stats.iss_hits++; - is->is_pkts++; - is->is_bytes += ip->ip_len; - /* - * Nearing end of connection, start timeout. - */ - fr_tcp_age(&is->is_age, is->is_state, ip, fin, source); - return 1; - } - return 0; -} - - -static int fr_matchsrcdst(is, src, dst, fin, tcp, sp, dp) -ipstate_t *is; -struct in_addr src, dst; -fr_info_t *fin; -void *tcp; -u_short sp, dp; -{ - int ret = 0, rev, out; - void *ifp; - - rev = (is->is_dst.s_addr != dst.s_addr); - ifp = fin->fin_ifp; - out = fin->fin_out; - - if (!rev) { - if (out) { - if (!is->is_ifpout) - is->is_ifpout = ifp; - } else { - if (!is->is_ifpin) - is->is_ifpin = ifp; - } - } else { - if (out) { - if (!is->is_ifpin) - is->is_ifpin = ifp; - } else { - if (!is->is_ifpout) - is->is_ifpout = ifp; - } - } - - if (!rev) { - if (((out && is->is_ifpout == ifp) || - (!out && is->is_ifpin == ifp)) && - (is->is_dst.s_addr == dst.s_addr) && - (is->is_src.s_addr == src.s_addr) && - (!tcp || ((sp == is->is_sport) && - (dp == is->is_dport)))) { - ret = 1; - } - } else { - if (((out && is->is_ifpin == ifp) || - (!out && is->is_ifpout == ifp)) && - (is->is_dst.s_addr == src.s_addr) && - (is->is_src.s_addr == dst.s_addr) && - (!tcp || ((sp == is->is_dport) && - (dp == is->is_sport)))) { - ret = 1; - } - } - - /* - * Whether or not this should be here, is questionable, but the aim - * is to get this out of the main line. - */ - if (ret) { - if (((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) || - ((fin->fin_fi.fi_fl & (is->is_flags >> 4)) != - (is->is_flags & 0xf))) - ret = 0; - } - return ret; -} - - -/* - * Check if a packet has a registered state. - */ -int fr_checkstate(ip, fin) -ip_t *ip; -fr_info_t *fin; -{ - register struct in_addr dst, src; - register ipstate_t *is, **isp; - register u_char pr; - struct icmp *ic; - tcphdr_t *tcp; - u_int hv, hlen, pass; - - if ((ip->ip_off & 0x1fff) || (fin->fin_fi.fi_fl & FI_SHORT)) - return 0; - - hlen = fin->fin_hlen; - tcp = (tcphdr_t *)((char *)ip + hlen); - ic = (struct icmp *)tcp; - hv = (pr = ip->ip_p); - hv += (src.s_addr = ip->ip_src.s_addr); - hv += (dst.s_addr = ip->ip_dst.s_addr); - - /* - * Search the hash table for matching packet header info. - */ - switch (ip->ip_p) - { - case IPPROTO_ICMP : - hv += ic->icmp_id; - hv += ic->icmp_seq; - hv %= IPSTATE_SIZE; - MUTEX_ENTER(&ipf_state); - for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_next) - if ((is->is_p == pr) && - (ic->icmp_id == is->is_icmp.ics_id) && - (ic->icmp_seq == is->is_icmp.ics_seq) && - fr_matchsrcdst(is, src, dst, fin, NULL, 0, 0)) { - if (is->is_icmp.ics_type != ic->icmp_type) - continue; - is->is_age = fr_icmptimeout; - is->is_pkts++; - is->is_bytes += ip->ip_len; - ips_stats.iss_hits++; - pass = is->is_pass; - MUTEX_EXIT(&ipf_state); - return pass; - } - MUTEX_EXIT(&ipf_state); - break; - case IPPROTO_TCP : - { - register u_short dport = tcp->th_dport, sport = tcp->th_sport; - - hv += dport; - hv += sport; - hv %= IPSTATE_SIZE; - MUTEX_ENTER(&ipf_state); - for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_next) - if ((is->is_p == pr) && - fr_matchsrcdst(is, src, dst, fin, tcp, - sport, dport)) { - if (fr_tcpstate(is, fin, ip, tcp)) { - pass = is->is_pass; -#ifdef _KERNEL - MUTEX_EXIT(&ipf_state); -#else - - if (tcp->th_flags & TCP_CLOSE) { - *isp = is->is_next; - isp = &ips_table[hv]; - KFREE(is); - } -#endif - return pass; - } - } - MUTEX_EXIT(&ipf_state); - break; - } - case IPPROTO_UDP : - { - register u_short dport = tcp->th_dport, sport = tcp->th_sport; - - hv += dport; - hv += sport; - hv %= IPSTATE_SIZE; - /* - * Nothing else to match on but ports. and IP#'s - */ - MUTEX_ENTER(&ipf_state); - for (is = ips_table[hv]; is; is = is->is_next) - if ((is->is_p == pr) && - fr_matchsrcdst(is, src, dst, fin, - tcp, sport, dport)) { - ips_stats.iss_hits++; - is->is_pkts++; - is->is_bytes += ip->ip_len; - is->is_age = fr_udptimeout; - pass = is->is_pass; - MUTEX_EXIT(&ipf_state); - return pass; - } - MUTEX_EXIT(&ipf_state); - break; - } - default : - break; - } - ips_stats.iss_miss++; - return 0; -} - - -/* - * Free memory in use by all state info. kept. - */ -void fr_stateunload() -{ - register int i; - register ipstate_t *is, **isp; - - MUTEX_ENTER(&ipf_state); - for (i = 0; i < IPSTATE_SIZE; i++) - for (isp = &ips_table[i]; (is = *isp); ) { - *isp = is->is_next; - KFREE(is); - } - MUTEX_EXIT(&ipf_state); -} - - -/* - * Slowly expire held state for thingslike UDP and ICMP. Timeouts are set - * in expectation of this being called twice per second. - */ -void fr_timeoutstate() -{ - register int i; - register ipstate_t *is, **isp; -#if defined(_KERNEL) && !SOLARIS - int s; -#endif - - SPL_NET(s); - MUTEX_ENTER(&ipf_state); - for (i = 0; i < IPSTATE_SIZE; i++) - for (isp = &ips_table[i]; (is = *isp); ) - if (is->is_age && !--is->is_age) { - *isp = is->is_next; - if (is->is_p == IPPROTO_TCP) - ips_stats.iss_fin++; - else - ips_stats.iss_expire++; -#ifdef IPFILTER_LOG - ipstate_log(is, ISL_EXPIRE); -#endif - KFREE(is); - ips_num--; - } else - isp = &is->is_next; - MUTEX_EXIT(&ipf_state); - SPL_X(s); -} - - -/* - * Original idea freom Pradeep Krishnan for use primarily with NAT code. - * (pkrishna@netcom.com) - */ -void fr_tcp_age(age, state, ip, fin, dir) -u_long *age; -u_char *state; -ip_t *ip; -fr_info_t *fin; -int dir; -{ - tcphdr_t *tcp = (tcphdr_t *)fin->fin_dp; - u_char flags = tcp->th_flags; - int dlen, ostate; - - ostate = state[1 - dir]; - - dlen = ip->ip_len - fin->fin_hlen - (tcp->th_off << 2); - - if (flags & TH_RST) { - if (!(tcp->th_flags & TH_PUSH) && !dlen) { - *age = fr_tcpclosed; - state[dir] = TCPS_CLOSED; - } else { - *age = fr_tcpclosewait; - state[dir] = TCPS_CLOSE_WAIT; - } - return; - } - - *age = fr_tcptimeout; /* 1 min */ - - switch(state[dir]) - { - case TCPS_FIN_WAIT_2: - case TCPS_CLOSED: - if ((flags & TH_OPENING) == TH_OPENING) - state[dir] = TCPS_SYN_RECEIVED; - else if (flags & TH_SYN) - state[dir] = TCPS_SYN_SENT; - break; - case TCPS_SYN_RECEIVED: - if ((flags & (TH_FIN|TH_ACK)) == TH_ACK) { - state[dir] = TCPS_ESTABLISHED; - *age = fr_tcpidletimeout; - } - break; - case TCPS_SYN_SENT: - if ((flags & (TH_FIN|TH_ACK)) == TH_ACK) { - state[dir] = TCPS_ESTABLISHED; - *age = fr_tcpidletimeout; - } - break; - case TCPS_ESTABLISHED: - if (flags & TH_FIN) { - state[dir] = TCPS_CLOSE_WAIT; - if (!(flags & TH_PUSH) && !dlen && - ostate > TCPS_ESTABLISHED) - *age = fr_tcplastack; - else - *age = fr_tcpclosewait; - } else - *age = fr_tcpidletimeout; - break; - case TCPS_CLOSE_WAIT: - if ((flags & TH_FIN) && !(flags & TH_PUSH) && !dlen && - ostate > TCPS_ESTABLISHED) { - *age = fr_tcplastack; - state[dir] = TCPS_LAST_ACK; - } else - *age = fr_tcpclosewait; - break; - case TCPS_LAST_ACK: - if (flags & TH_ACK) { - state[dir] = TCPS_FIN_WAIT_2; - if (!(flags & TH_PUSH) && !dlen && - ostate > TCPS_ESTABLISHED) - *age = fr_tcplastack; - else { - *age = fr_tcpclosewait; - state[dir] = TCPS_CLOSE_WAIT; - } - } - break; - } -} - - -#ifdef IPFILTER_LOG -void ipstate_log(is, type) -struct ipstate *is; -u_short type; -{ - struct ipslog ipsl; - void *items[1]; - size_t sizes[1]; - int types[1]; - - 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_flags = is->is_flags; - ipsl.isl_type = type; - if (ipsl.isl_p == IPPROTO_TCP || ipsl.isl_p == IPPROTO_UDP) { - ipsl.isl_sport = is->is_sport; - ipsl.isl_dport = is->is_dport; - } 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, 0, items, sizes, types, 1); -} -#endif diff --git a/sys/netinet/ip_state.h b/sys/netinet/ip_state.h deleted file mode 100644 index 2b7e898..0000000 --- a/sys/netinet/ip_state.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 1995-1997 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 - * $FreeBSD$ - */ -#ifndef __IP_STATE_H__ -#define __IP_STATE_H__ - -#define IPSTATE_SIZE 257 -#define IPSTATE_MAX 2048 /* 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 tcpstate { - u_short ts_sport; - u_short ts_dport; - u_long ts_seq; - u_long ts_ack; - u_short ts_swin; - u_short ts_dwin; - u_char ts_state[2]; -} tcpstate_t; - -typedef struct ipstate { - struct ipstate *is_next; - u_long is_age; - u_int is_pass; - U_QUAD_T is_pkts; - U_QUAD_T is_bytes; - void *is_ifpin; - void *is_ifpout; - struct in_addr is_src; - struct in_addr is_dst; - u_char is_p; - u_char is_flags; - u_32_t is_opt; - u_32_t is_optmsk; - u_short is_sec; - u_short is_secmsk; - u_short is_auth; - u_short is_authmsk; - union { - icmpstate_t is_ics; - tcpstate_t is_ts; - udpstate_t is_us; - } is_ps; -} ipstate_t; - -#define is_icmp is_ps.is_ics -#define is_tcp is_ps.is_ts -#define is_udp is_ps.is_us -#define is_seq is_tcp.ts_seq -#define is_ack is_tcp.ts_ack -#define is_dwin is_tcp.ts_dwin -#define is_swin is_tcp.ts_swin -#define is_sport is_tcp.ts_sport -#define is_dport is_tcp.ts_dport -#define is_state is_tcp.ts_state - -#define TH_OPENING (TH_SYN|TH_ACK) - - -typedef struct ipslog { - U_QUAD_T isl_pkts; - U_QUAD_T isl_bytes; - struct in_addr isl_src; - struct in_addr isl_dst; - u_char isl_p; - u_char isl_flags; - u_short isl_type; - union { - u_short isl_filler[2]; - u_short isl_ports[2]; - u_short isl_icmp; - } isl_ps; -} 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 - - -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; - ipstate_t **iss_table; -} 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_udptimeout; -extern u_long fr_icmptimeout; -extern int fr_tcpstate __P((ipstate_t *, fr_info_t *, ip_t *, tcphdr_t *)); -extern int fr_addstate __P((ip_t *, fr_info_t *, u_int)); -extern int fr_checkstate __P((ip_t *, fr_info_t *)); -extern void fr_timeoutstate __P((void)); -extern void fr_tcp_age __P((u_long *, u_char *, ip_t *, fr_info_t *, int)); -extern void fr_stateunload __P((void)); -extern void ipstate_log __P((struct ipstate *, u_short)); -#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/sys/netinet/ipl.h b/sys/netinet/ipl.h deleted file mode 100644 index 0985545..0000000 --- a/sys/netinet/ipl.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) 1993-1997 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 - * $FreeBSD$ - */ - -#ifndef __IPL_H__ -#define __IPL_H__ - -#define IPL_VERSION "IP Filter v3.2.7" - -#endif diff --git a/sys/netinet/mlf_ipl.c b/sys/netinet/mlf_ipl.c deleted file mode 100644 index 2ec0c6b..0000000 --- a/sys/netinet/mlf_ipl.c +++ /dev/null @@ -1,406 +0,0 @@ -/* - * Copyright (C) 1993-1997 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. - * - * $FreeBSD$ - */ -/* - * 29/12/94 Added code from Marc Huber <huber@fzi.de> to allow it to allocate - * its own major char number! Way cool patch! - */ - - -#include <sys/param.h> - -#if defined(__FreeBSD__) && (__FreeBSD__ > 1) -# ifdef IPFILTER_LKM -# include <osreldate.h> -# define ACTUALLY_LKM_NOT_KERNEL -# else -# ifndef __FreeBSD_version -# define __FreeBSD_version 300000 /* this will do as a hack */ -# endif -# endif -#endif -#include <sys/systm.h> -#if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000) -# include "opt_devfs.h" -# include <sys/conf.h> -# include <sys/kernel.h> -# ifdef DEVFS -# include <sys/devfsext.h> -# endif /*DEVFS*/ -#endif -#include <sys/conf.h> -#include <sys/file.h> -#include <sys/lock.h> -#include <sys/stat.h> -#include <sys/proc.h> -#include <sys/uio.h> -#include <sys/kernel.h> -#include <sys/vnode.h> -#include <sys/namei.h> -#include <sys/malloc.h> -#include <sys/socket.h> -#include <sys/exec.h> -#include <sys/mbuf.h> -#if BSD >= 199506 -# include <sys/sysctl.h> -#endif -#if (__FreeBSD_version >= 199511) -#include <net/if.h> -#include <netinet/in_systm.h> -#include <netinet/in.h> -#include <netinet/ip.h> -#include <net/route.h> -#include <netinet/ip_var.h> -#include <netinet/tcp.h> -#include <netinet/tcpip.h> -#endif -#if (__FreeBSD__ > 1) -# include <sys/sysent.h> -#endif -#ifdef IPFILTER_LKM -#include <sys/lkm.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" - - -#if !defined(VOP_LEASE) && defined(LEASE_CHECK) -#define VOP_LEASE LEASE_CHECK -#endif - -#ifndef MIN -#define MIN(a,b) (((a)<(b))?(a):(b)) -#endif - -#if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000) -extern int lkmenodev __P((void)); -#endif -#if defined(__FreeBSD_version) && (__FreeBSD_version < 220000) -int xxxinit __P((struct lkm_table *, int, int)); -#endif - -#ifdef SYSCTL_INT -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_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, ipl_inited, CTLFLAG_RD, - &ipl_inited, 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, ""); -#endif - -#ifdef DEVFS -static void *ipf_devfs[IPL_LOGMAX + 1]; -#endif - -#if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000) -int ipl_major = 0; - -static struct cdevsw ipldevsw -= { - iplopen, /* open */ - iplclose, /* close */ - iplread, /* read */ - (void *)nullop, /* write */ - iplioctl, /* ioctl */ - (void *)nullop, /* stop */ - (void *)nullop, /* reset */ - (void *)NULL, /* tty */ - (void *)nullop, /* select */ - (void *)nullop, /* mmap */ - NULL /* strategy */ -}; - -MOD_DEV(IPL_VERSION, LM_DT_CHAR, -1, &ipldevsw); - -extern struct cdevsw cdevsw[]; -extern int vd_unuseddev __P((void)); -extern int nchrdev; -#else - -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 -}; -#endif - - -static void ipl_drvinit __P((void *)); - -#ifdef ACTUALLY_LKM_NOT_KERNEL -static int if_ipl_unload __P((struct lkm_table *, int)); -static int if_ipl_load __P((struct lkm_table *, int)); -static int if_ipl_remove __P((void)); -static int ipl_major = CDEV_MAJOR; - -static int iplaction __P((struct lkm_table *, int)); -static char *ipf_devfiles[] = { IPL_NAME, IPL_NAT, IPL_STATE, IPL_AUTH, NULL }; -static int iplaction(lkmtp, cmd) -struct lkm_table *lkmtp; -int cmd; -{ -#if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000) - int i = ipl_major; - struct lkm_dev *args = lkmtp->private.lkm_dev; -#endif - int err = 0; - - switch (cmd) - { - case LKM_E_LOAD : - if (lkmexists(lkmtp)) - return EEXIST; - -#if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000) - for (i = 0; i < nchrdev; i++) - if (cdevsw[i].d_open == lkmenodev || - cdevsw[i].d_open == iplopen) - break; - if (i == nchrdev) { - printf("IP Filter: No free cdevsw slots\n"); - return ENODEV; - } - - ipl_major = i; - args->lkm_offset = i; /* slot in cdevsw[] */ -#endif - printf("IP Filter: loaded into slot %d\n", ipl_major); - err = if_ipl_load(lkmtp, cmd); - if (!err) - ipl_drvinit((void *)NULL); - return err; - break; - case LKM_E_UNLOAD : - err = if_ipl_unload(lkmtp, cmd); - if (!err) { - printf("IP Filter: unloaded from slot %d\n", - ipl_major); -# ifdef DEVFS - if (ipf_devfs[IPL_LOGIPF]) - devfs_remove_dev(ipf_devfs[IPL_LOGIPF]); - if (ipf_devfs[IPL_LOGNAT]) - devfs_remove_dev(ipf_devfs[IPL_LOGNAT]); - if (ipf_devfs[IPL_LOGSTATE]) - devfs_remove_dev(ipf_devfs[IPL_LOGSTATE]); - if (ipf_devfs[IPL_LOGAUTH]) - devfs_remove_dev(ipf_devfs[IPL_LOGAUTH]); -# endif - } - return err; - case LKM_E_STAT : - break; - default: - err = EIO; - break; - } - return 0; -} - - -static int if_ipl_remove __P((void)) -{ - char *name; - struct nameidata nd; - int error, i; - - for (i = 0; (name = ipf_devfiles[i]); i++) { - NDINIT(&nd, DELETE, LOCKPARENT, UIO_SYSSPACE, name, curproc); - if ((error = namei(&nd))) - return (error); - VOP_LEASE(nd.ni_vp, curproc, curproc->p_ucred, LEASE_WRITE); - vn_lock(nd.ni_vp, LK_EXCLUSIVE | LK_RETRY, curproc); - VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE); - (void) VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); - if (nd.ni_dvp == nd.ni_vp) - vrele(nd.ni_dvp); - else - vput(nd.ni_dvp); - if (nd.ni_vp != NULLVP) - vput(nd.ni_vp); - } - - return 0; -} - - -static int if_ipl_unload(lkmtp, cmd) -struct lkm_table *lkmtp; -int cmd; -{ - int error = 0; - - error = ipldetach(); - if (!error) - error = if_ipl_remove(); - return error; -} - - -static int if_ipl_load(lkmtp, cmd) -struct lkm_table *lkmtp; -int cmd; -{ - struct nameidata nd; - struct vattr vattr; - int error = 0, fmode = S_IFCHR|0600, i; - char *name; - - error = iplattach(); - if (error) - return error; - (void) if_ipl_remove(); - - for (i = 0; (name = ipf_devfiles[i]); i++) { - NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, name, curproc); - if ((error = namei(&nd))) - return error; - if (nd.ni_vp != NULL) { - VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); - if (nd.ni_dvp == nd.ni_vp) - vrele(nd.ni_dvp); - else - vput(nd.ni_dvp); - vrele(nd.ni_vp); - return (EEXIST); - } - VATTR_NULL(&vattr); - vattr.va_type = VCHR; - vattr.va_mode = (fmode & 07777); - vattr.va_rdev = (ipl_major << 8) | i; - VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE); - error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); - vput(nd.ni_dvp); - if (error) - return error; - } - return 0; -} - -#endif /* actually LKM */ - -#if defined(__FreeBSD_version) && (__FreeBSD_version < 220000) -/* - * strlen isn't present in 2.1.* kernels. - */ -size_t strlen(string) -char *string; -{ - register char *s; - - for (s = string; *s; s++) - ; - return (size_t)(s - string); -} - - -int xxxinit(lkmtp, cmd, ver) -struct lkm_table *lkmtp; -int cmd, ver; -{ - DISPATCH(lkmtp, cmd, ver, iplaction, iplaction, iplaction); -} -#else -# ifdef IPFILTER_LKM -# include <sys/exec.h> - -MOD_DECL(if_ipl); - - -static struct lkm_dev _module = { - LM_DEV, - LKM_VERSION, - IPL_VERSION, - CDEV_MAJOR, - LM_DT_CHAR, - { (void *)&ipl_cdevsw } -}; - - -int if_ipl __P((struct lkm_table *, int, int)); - - -int if_ipl(lkmtp, cmd, ver) -struct lkm_table *lkmtp; -int cmd, ver; -{ - DISPATCH(lkmtp, cmd, ver, iplaction, iplaction, iplaction); -} -# endif -static int ipl_devsw_installed; - -static void ipl_drvinit __P((void *unused)) -{ -# ifdef DEVFS - void **tp = ipf_devfs; -# endif - - if (!ipl_devsw_installed ) { - cdevsw_add(&ipl_cdevsw); - ipl_devsw_installed = 1; - -# ifdef DEVFS - tp[IPL_LOGIPF] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGIPF, - DV_CHR, 0, 0, 0600, "ipf"); - tp[IPL_LOGNAT] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGNAT, - DV_CHR, 0, 0, 0600, "ipnat"); - tp[IPL_LOGSTATE] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGSTATE, - DV_CHR, 0, 0, 0600, - "ipstate"); - tp[IPL_LOGAUTH] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGAUTH, - DV_CHR, 0, 0, 0600, - "ipauth"); -# endif - } -} - -SYSINIT(ipldev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,ipl_drvinit,NULL); -#endif /* _FreeBSD_version */ |