summaryrefslogtreecommitdiffstats
path: root/sys/netinet/fil.c
diff options
context:
space:
mode:
authordarrenr <darrenr@FreeBSD.org>1997-05-25 15:50:46 +0000
committerdarrenr <darrenr@FreeBSD.org>1997-05-25 15:50:46 +0000
commita93925894facc20de4d8d36bcb61fc349047c73f (patch)
tree25de559faf9011589a627f617cbd6ba5d2249232 /sys/netinet/fil.c
parent525015045eb68d4a74c33a475a65fbacb429ca5a (diff)
downloadFreeBSD-src-a93925894facc20de4d8d36bcb61fc349047c73f.zip
FreeBSD-src-a93925894facc20de4d8d36bcb61fc349047c73f.tar.gz
Import version 3.2alpha7
Diffstat (limited to 'sys/netinet/fil.c')
-rw-r--r--sys/netinet/fil.c205
1 files changed, 162 insertions, 43 deletions
diff --git a/sys/netinet/fil.c b/sys/netinet/fil.c
index 118edf2..b40695f 100644
--- a/sys/netinet/fil.c
+++ b/sys/netinet/fil.c
@@ -7,7 +7,7 @@
*/
#if !defined(lint) && defined(LIBC_SCCS)
static char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-1996 Darren Reed";
-static char rcsid[] = "$Id: fil.c,v 1.1.1.3 1997/04/03 10:10:10 darrenr Exp $";
+static char rcsid[] = "$Id: fil.c,v 2.0.2.13 1997/05/24 07:33:37 darrenr Exp $";
#endif
#include <sys/errno.h>
@@ -45,11 +45,12 @@ static char rcsid[] = "$Id: fil.c,v 1.1.1.3 1997/04/03 10:10:10 darrenr Exp $";
#include <netinet/udp.h>
#include <netinet/tcpip.h>
#include <netinet/ip_icmp.h>
-#include "ip_compat.h"
-#include "ip_fil.h"
-#include "ip_nat.h"
-#include "ip_frag.h"
-#include "ip_state.h"
+#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"
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif
@@ -70,7 +71,6 @@ extern int opts;
# define IPLLOG(a, c, d, e) ipllog()
# if SOLARIS
# define ICMP_ERROR(b, ip, t, c, if, src) icmp_error(ip)
-# define bcmp memcmp
# else
# define ICMP_ERROR(b, ip, t, c, if, src) icmp_error(b, ip, if)
# endif
@@ -100,19 +100,12 @@ extern kmutex_t ipf_mutex;
# endif
#endif
-#ifndef IPF_LOGGING
-#define IPF_LOGGING 0
-#endif
-#ifdef IPF_DEFAULT_PASS
-#define IPF_NOMATCH (IPF_DEFAULT_PASS|FR_NOMATCH)
-#else
-#define IPF_NOMATCH (FR_PASS|FR_NOMATCH)
-#endif
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 } };
int fr_flags = IPF_LOGGING, fr_active = 0;
+int fr_pass = (IPF_DEFAULT_PASS|FR_NOMATCH);
fr_info_t frcache[2];
@@ -417,7 +410,7 @@ void *m;
#endif
{
register u_long *ld, *lm, *lip;
- register int i;
+ register int i, j;
lip = (u_long *)fi;
lm = (u_long *)&fr->fr_mip;
@@ -425,10 +418,10 @@ void *m;
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]);
+ 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]);
+ 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]);
@@ -437,6 +430,7 @@ void *m;
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;
}
@@ -557,6 +551,7 @@ int out;
fr_makefrip(hlen, ip, fin);
fin->fin_ifp = ifp;
fin->fin_out = out;
+ fin->fin_mp = mp;
MUTEX_ENTER(&ipf_mutex);
if (!out) {
@@ -566,24 +561,8 @@ int out;
frstats[0].fr_acct++;
}
- if ((pass = ipfr_knownfrag(ip, fin))) {
- if ((pass & FR_KEEPSTATE)) {
- if (fr_addstate(ip, fin, pass) == -1)
- frstats[out].fr_bads++;
- else
- frstats[out].fr_ads++;
- }
- } else if ((pass = fr_checkstate(ip, fin))) {
- 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++;
- }
- } else {
+ if (!(pass = ipfr_knownfrag(ip, fin)) &&
+ !(pass = fr_checkstate(ip, fin))) {
fc = frcache + out;
if (fc->fin_fr && !bcmp((char *)fin, (char *)fc, FI_CSIZE)) {
/*
@@ -594,16 +573,16 @@ int out;
frstats[out].fr_chit++;
pass = fin->fin_fr->fr_flags;
} else {
- pass = IPF_NOMATCH;
+ pass = fr_pass;
if ((fin->fin_fr = ipfilter[out][fr_active]))
- pass = FR_SCANLIST(IPF_NOMATCH, ip, fin, m);
+ pass = FR_SCANLIST(fr_pass, ip, fin, m);
bcopy((char *)fin, (char *)fc, FI_CSIZE);
if (pass & FR_NOMATCH)
frstats[out].fr_nom++;
}
fr = fin->fin_fr;
- if ((pass & FR_KEEPFRAG)) {
+ if (pass & FR_KEEPFRAG) {
if (fin->fin_fi.fi_fl & FI_FRAG) {
if (ipfr_newfrag(ip, fin, pass) == -1)
frstats[out].fr_bnfr++;
@@ -660,6 +639,19 @@ logit:
}
}
#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
+ mc = m_copy(m, 0, M_COPYALL);
+# endif
+#endif
if (pass & FR_PASS)
frstats[out].fr_pass++;
@@ -703,10 +695,16 @@ logit:
#endif
}
}
+
+ /*
+ * 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 *).
+ */
#ifdef _KERNEL
# if !SOLARIS
- if (pass & FR_DUP)
- mc = m_copy(m, 0, M_COPYALL);
if (fr) {
frdest_t *fdp = &fr->fr_tif;
@@ -722,8 +720,6 @@ logit:
m_freem(m);
return (pass & FR_PASS) ? 0 : -1;
# else
- if (pass & FR_DUP)
- mc = dupmsg(m);
if (fr) {
frdest_t *fdp = &fr->fr_tif;
@@ -777,3 +773,126 @@ int len;
return len;
}
#endif
+
+
+u_short ipf_cksum(addr, len)
+register u_short *addr;
+register int len;
+{
+ register u_long 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)
+#if SOLARIS
+mblk_t *m;
+#else
+struct mbuf *m;
+#endif
+ip_t *ip;
+tcphdr_t *tcp;
+{
+ union {
+ u_char c[2];
+ u_short s;
+ } bytes;
+ u_long sum;
+ u_short *sp;
+ int len, add, hlen, ilen;
+
+ /*
+ * Add up IP Header portion
+ */
+ ilen = len = ip->ip_len - (ip->ip_hl << 2);
+ bytes.c[0] = 0;
+ bytes.c[1] = IPPROTO_TCP;
+ 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);
+ if ((hlen -= add))
+ m = m->b_cont;
+ }
+ }
+#endif
+
+ if (!(len -= sizeof(*tcp)))
+ goto nodata;
+ while (len > 1) {
+ sum += *sp++;
+ len -= 2;
+#if SOLARIS
+ if ((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
+# ifdef m_data
+ if ((caddr_t)sp > (m->m_data + m->m_len))
+# else
+ if ((caddr_t)sp > (caddr_t)(m->m_dat + m->m_off + m->m_len))
+# endif
+ {
+ m = m->m_next;
+ PANIC((!m),("fr_tcpsum: not enough data"));
+ sp = mtod(m, u_short *);
+ }
+#endif /* SOLARIS */
+ }
+ 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;
+}
OpenPOWER on IntegriCloud