2 * Copyright (C) 1993-1998 by Darren Reed.
4 * Redistribution and use in source and binary forms are permitted
5 * provided that this notice is preserved and due credit is given
6 * to the original author and the contributors.
9 static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-1996 Darren Reed";
10 /*static const char rcsid[] = "@(#)$Id: fil.c,v 2.3.2.7 1999/10/21 14:21:40 darrenr Exp $";*/
11 static const char rcsid[] = "@(#)$FreeBSD$";
14 #include <sys/errno.h>
15 #include <sys/types.h>
16 #include <sys/param.h>
19 #if defined(__NetBSD__) && (NetBSD >= 199905) && !defined(IPFILTER_LKM) && \
21 # include "opt_ipfilter_log.h"
23 #if defined(KERNEL) && defined(__FreeBSD_version) && \
24 (__FreeBSD_version >= 220000)
25 # include <sys/filio.h>
26 # include <sys/fcntl.h>
28 # include <sys/ioctl.h>
30 #if (defined(_KERNEL) || defined(KERNEL)) && !defined(linux)
31 # include <sys/systm.h>
38 #if !defined(__SVR4) && !defined(__svr4__)
40 # include <sys/mbuf.h>
43 # include <sys/byteorder.h>
45 # include <sys/dditypes.h>
47 # include <sys/stream.h>
50 # include <sys/protosw.h>
51 # include <sys/socket.h>
57 #include <net/route.h>
58 #include <netinet/in.h>
59 #include <netinet/in_systm.h>
60 #include <netinet/ip.h>
62 # include <netinet/ip_var.h>
64 #if defined(__sgi) && defined(IFF_DRVRLOCK) /* IRIX 6 */
65 # include <sys/hashing.h>
66 # include <netinet/in_var.h>
68 #include <netinet/tcp.h>
69 #include <netinet/udp.h>
70 #include <netinet/ip_icmp.h>
71 #include "netinet/ip_compat.h"
72 #include <netinet/tcpip.h>
73 #include "netinet/ip_fil.h"
74 #include "netinet/ip_proxy.h"
75 #include "netinet/ip_nat.h"
76 #include "netinet/ip_frag.h"
77 #include "netinet/ip_state.h"
78 #include "netinet/ip_auth.h"
79 # if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
80 # include <sys/malloc.h>
81 # if defined(_KERNEL) && !defined(IPFILTER_LKM)
82 # include "opt_ipfilter.h"
86 # define MIN(a,b) (((a)<(b))?(a):(b))
88 #include "netinet/ipl.h"
95 # define FR_IFVERBOSE(ex,second,verb_pr) if (ex) { verbose verb_pr; \
97 # define FR_IFDEBUG(ex,second,verb_pr) if (ex) { debug verb_pr; \
99 # define FR_VERBOSE(verb_pr) verbose verb_pr
100 # define FR_DEBUG(verb_pr) debug verb_pr
101 # define SEND_RESET(ip, qif, if, m, fin) send_reset(ip, if)
102 # define IPLLOG(a, c, d, e) ipllog()
103 # define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, ip)
104 #else /* #ifndef _KERNEL */
105 # define FR_IFVERBOSE(ex,second,verb_pr) ;
106 # define FR_IFDEBUG(ex,second,verb_pr) ;
107 # define FR_VERBOSE(verb_pr)
108 # define FR_DEBUG(verb_pr)
109 # define IPLLOG(a, c, d, e) ipflog(a, c, d, e)
110 # if SOLARIS || defined(__sgi)
111 extern KRWLOCK_T ipf_mutex, ipf_auth, ipf_nat;
112 extern kmutex_t ipf_rw;
115 # define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, \
117 # define SEND_RESET(ip, qif, if, fin) send_reset(fin, ip, qif)
118 # define ICMP_ERROR(b, ip, t, c, if, dst) \
119 icmp_error(ip, t, c, if, dst)
121 # define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, ip)
123 # define SEND_RESET(ip, qif, if, fin) send_reset(ip, ifp)
124 # define ICMP_ERROR(b, ip, t, c, if, dst) icmp_send(b,t,c,0,if)
126 # define SEND_RESET(ip, qif, if, fin) send_reset(fin, ip)
127 # define ICMP_ERROR(b, ip, t, c, if, dst) \
128 send_icmp_err(ip, t, c, if, dst)
130 # endif /* SOLARIS || __sgi */
134 struct filterstats frstats[2] = {{0,0,0,0,0},{0,0,0,0,0}};
135 struct frentry *ipfilter[2][2] = { { NULL, NULL }, { NULL, NULL } },
136 *ipacct[2][2] = { { NULL, NULL }, { NULL, NULL } };
137 struct frgroup *ipfgroups[3][2];
138 int fr_flags = IPF_LOGGING, fr_active = 0;
139 #if defined(IPFILTER_DEFAULT_BLOCK)
140 int fr_pass = FR_NOMATCH|FR_BLOCK;
142 int fr_pass = (IPF_DEFAULT_PASS|FR_NOMATCH);
144 char ipfilter_version[] = IPL_VERSION;
146 fr_info_t frcache[2];
148 static int fr_tcpudpchk __P((frentry_t *, fr_info_t *));
149 static int frflushlist __P((int, minor_t, int *, frentry_t **));
153 * bit values for identifying presence of individual IP options
155 struct optlist ipopts[20] = {
156 { IPOPT_NOP, 0x000001 },
157 { IPOPT_RR, 0x000002 },
158 { IPOPT_ZSU, 0x000004 },
159 { IPOPT_MTUP, 0x000008 },
160 { IPOPT_MTUR, 0x000010 },
161 { IPOPT_ENCODE, 0x000020 },
162 { IPOPT_TS, 0x000040 },
163 { IPOPT_TR, 0x000080 },
164 { IPOPT_SECURITY, 0x000100 },
165 { IPOPT_LSRR, 0x000200 },
166 { IPOPT_E_SEC, 0x000400 },
167 { IPOPT_CIPSO, 0x000800 },
168 { IPOPT_SATID, 0x001000 },
169 { IPOPT_SSRR, 0x002000 },
170 { IPOPT_ADDEXT, 0x004000 },
171 { IPOPT_VISA, 0x008000 },
172 { IPOPT_IMITD, 0x010000 },
173 { IPOPT_EIP, 0x020000 },
174 { IPOPT_FINN, 0x040000 },
179 * bit values for identifying presence of individual IP security options
181 struct optlist secopt[8] = {
182 { IPSO_CLASS_RES4, 0x01 },
183 { IPSO_CLASS_TOPS, 0x02 },
184 { IPSO_CLASS_SECR, 0x04 },
185 { IPSO_CLASS_RES3, 0x08 },
186 { IPSO_CLASS_CONF, 0x10 },
187 { IPSO_CLASS_UNCL, 0x20 },
188 { IPSO_CLASS_RES2, 0x40 },
189 { IPSO_CLASS_RES1, 0x80 }
194 * compact the IP header into a structure which contains just the info.
195 * which is useful for comparing IP headers with.
197 void fr_makefrip(hlen, ip, fin)
204 fr_ip_t *fi = &fin->fin_fi;
205 u_short optmsk = 0, secmsk = 0, auth = 0;
212 fin->fin_data[0] = 0;
213 fin->fin_data[1] = 0;
216 fin->fin_id = ip->ip_id;
218 fin->fin_icode = ipl_unreach;
221 fi->fi_tos = ip->ip_tos;
222 fin->fin_hlen = hlen;
223 fin->fin_dlen = ip->ip_len - hlen;
224 tcp = (tcphdr_t *)((char *)ip + hlen);
225 fin->fin_dp = (void *)tcp;
226 (*(((u_short *)fi) + 1)) = (*(((u_short *)ip) + 4));
227 fi->fi_src.s_addr = ip->ip_src.s_addr;
228 fi->fi_dst.s_addr = ip->ip_dst.s_addr;
230 fi->fi_fl = (hlen > sizeof(ip_t)) ? FI_OPTIONS : 0;
231 off = (ip->ip_off & IP_OFFMASK) << 3;
232 if (ip->ip_off & 0x3fff)
233 fi->fi_fl |= FI_FRAG;
238 int minicmpsz = sizeof(struct icmp);
241 icmp = (icmphdr_t *)tcp;
243 if (!off && (icmp->icmp_type == ICMP_ECHOREPLY ||
244 icmp->icmp_type == ICMP_ECHO))
245 minicmpsz = ICMP_MINLEN;
246 if ((!(ip->ip_len >= hlen + minicmpsz) && !off) ||
247 (off && off < sizeof(struct icmp)))
248 fi->fi_fl |= FI_SHORT;
249 if (fin->fin_dlen > 1)
250 fin->fin_data[0] = *(u_short *)tcp;
254 fi->fi_fl |= FI_TCPUDP;
255 if ((!IPMINLEN(ip, tcphdr) && !off) ||
256 (off && off < sizeof(struct tcphdr)))
257 fi->fi_fl |= FI_SHORT;
258 if (!(fi->fi_fl & FI_SHORT) && !off)
259 fin->fin_tcpf = tcp->th_flags;
262 fi->fi_fl |= FI_TCPUDP;
263 if ((!IPMINLEN(ip, udphdr) && !off) ||
264 (off && off < sizeof(struct udphdr)))
265 fi->fi_fl |= FI_SHORT;
267 if (!off && (fin->fin_dlen > 3)) {
268 fin->fin_data[0] = ntohs(tcp->th_sport);
269 fin->fin_data[1] = ntohs(tcp->th_dport);
277 for (s = (u_char *)(ip + 1), hlen -= (int)sizeof(*ip); hlen; ) {
281 ol = (opt == IPOPT_NOP) ? 1 : (int)*(s+1);
282 if (opt > 1 && (ol < 2 || ol > hlen))
284 for (i = 9, mv = 4; mv >= 0; ) {
286 if (opt == (u_char)op->ol_val) {
287 optmsk |= op->ol_bit;
288 if (opt == IPOPT_SECURITY) {
293 sec = *(s + 2); /* classification */
294 for (j = 3, m = 2; m >= 0; ) {
296 if (sec == sp->ol_val) {
297 secmsk |= sp->ol_bit;
303 if (sec < sp->ol_val)
311 if (opt < op->ol_val)
319 if (auth && !(auth & 0x0100))
321 fi->fi_optmsk = optmsk;
322 fi->fi_secmsk = secmsk;
328 * check an IP packet for TCP/UDP characteristics such as ports and flags.
330 static int fr_tcpudpchk(fr, fin)
334 register u_short po, tup;
336 register int err = 1;
339 * Both ports should *always* be in the first fragment.
340 * So far, I cannot find any cases where they can not be.
342 * compare destination ports
344 if ((i = (int)fr->fr_dcmp)) {
346 tup = fin->fin_data[1];
348 * Do opposite test to that required and
349 * continue if that succeeds.
351 if (!--i && tup != po) /* EQUAL */
353 else if (!--i && tup == po) /* NOTEQUAL */
355 else if (!--i && tup >= po) /* LESSTHAN */
357 else if (!--i && tup <= po) /* GREATERTHAN */
359 else if (!--i && tup > po) /* LT or EQ */
361 else if (!--i && tup < po) /* GT or EQ */
363 else if (!--i && /* Out of range */
364 (tup >= po && tup <= fr->fr_dtop))
366 else if (!--i && /* In range */
367 (tup <= po || tup >= fr->fr_dtop))
371 * compare source ports
373 if (err && (i = (int)fr->fr_scmp)) {
375 tup = fin->fin_data[0];
376 if (!--i && tup != po)
378 else if (!--i && tup == po)
380 else if (!--i && tup >= po)
382 else if (!--i && tup <= po)
384 else if (!--i && tup > po)
386 else if (!--i && tup < po)
388 else if (!--i && /* Out of range */
389 (tup >= po && tup <= fr->fr_stop))
391 else if (!--i && /* In range */
392 (tup <= po || tup >= fr->fr_stop))
397 * If we don't have all the TCP/UDP header, then how can we
398 * expect to do any sort of match on it ? If we were looking for
399 * TCP flags, then NO match. If not, then match (which should
400 * satisfy the "short" class too).
402 if (err && (fin->fin_fi.fi_p == IPPROTO_TCP)) {
403 if (fin->fin_fi.fi_fl & FI_SHORT)
404 return !(fr->fr_tcpf | fr->fr_tcpfm);
406 * Match the flags ? If not, abort this match.
409 fr->fr_tcpf != (fin->fin_tcpf & fr->fr_tcpfm)) {
410 FR_DEBUG(("f. %#x & %#x != %#x\n", fin->fin_tcpf,
411 fr->fr_tcpfm, fr->fr_tcpf));
419 * Check the input/output list of rules for a match and result.
420 * Could be per interface, but this gets real nasty when you don't have
423 int fr_scanlist(pass, ip, fin, m)
426 register fr_info_t *fin;
429 register struct frentry *fr;
430 register fr_ip_t *fi = &fin->fin_fi;
431 int rulen, portcmp = 0, off, skip = 0, logged = 0;
438 off = ip->ip_off & IP_OFFMASK;
439 pass |= (fi->fi_fl << 24);
441 if ((fi->fi_fl & FI_TCPUDP) && (fin->fin_dlen > 3) && !off)
444 for (rulen = 0; fr; fr = fr->fr_next, rulen++) {
450 * In all checks below, a null (zero) value in the
451 * filter struture is taken to mean a wildcard.
453 * check that we are working for the right interface
457 if (fin->fin_out != 0) {
459 fr->fr_oifa != ((mb_t *)m)->m_pkthdr.rcvif) ||
460 (fr->fr_ifa && fr->fr_ifa != fin->fin_ifp))
464 if (fr->fr_ifa && fr->fr_ifa != fin->fin_ifp)
467 if (opts & (OPT_VERBOSE|OPT_DEBUG))
469 FR_VERBOSE(("%c", (pass & FR_PASS) ? 'p' :
470 (pass & FR_AUTH) ? 'a' : 'b'));
471 if (fr->fr_ifa && fr->fr_ifa != fin->fin_ifp)
476 register u_32_t *ld, *lm, *lip;
480 lm = (u_32_t *)&fr->fr_mip;
481 ld = (u_32_t *)&fr->fr_ip;
482 i = ((lip[0] & lm[0]) != ld[0]);
483 FR_IFDEBUG(i,continue,("0. %#08x & %#08x != %#08x\n",
484 lip[0], lm[0], ld[0]));
485 i |= ((lip[1] & lm[1]) != ld[1]) << 19;
486 i ^= (fr->fr_flags & FR_NOTSRCIP);
487 FR_IFDEBUG(i,continue,("1. %#08x & %#08x != %#08x\n",
488 lip[1], lm[1], ld[1]));
489 i |= ((lip[2] & lm[2]) != ld[2]) << 20;
490 i ^= (fr->fr_flags & FR_NOTDSTIP);
491 FR_IFDEBUG(i,continue,("2. %#08x & %#08x != %#08x\n",
492 lip[2], lm[2], ld[2]));
493 i |= ((lip[3] & lm[3]) != ld[3]);
494 FR_IFDEBUG(i,continue,("3. %#08x & %#08x != %#08x\n",
495 lip[3], lm[3], ld[3]));
496 i |= ((lip[4] & lm[4]) != ld[4]);
497 FR_IFDEBUG(i,continue,("4. %#08x & %#08x != %#08x\n",
498 lip[4], lm[4], ld[4]));
504 * If a fragment, then only the first has what we're looking
507 if (!portcmp && (fr->fr_dcmp || fr->fr_scmp || fr->fr_tcpf ||
510 if (fi->fi_fl & FI_TCPUDP) {
511 if (!fr_tcpudpchk(fr, fin))
513 } else if (fr->fr_icmpm || fr->fr_icmp) {
514 if ((fi->fi_p != IPPROTO_ICMP) || off ||
517 if ((fin->fin_data[0] & fr->fr_icmpm) != fr->fr_icmp) {
518 FR_DEBUG(("i. %#x & %#x != %#x\n",
519 fin->fin_data[0], fr->fr_icmpm,
526 * Just log this packet...
528 passt = fr->fr_flags;
529 if ((passt & FR_CALLNOW) && fr->fr_func)
530 passt = (*fr->fr_func)(passt, ip, fin);
533 if ((passt & FR_LOGMASK) == FR_LOG) {
534 if (!IPLLOG(passt, ip, fin, m)) {
535 ATOMIC_INC(frstats[fin->fin_out].fr_skip);
537 ATOMIC_INC(frstats[fin->fin_out].fr_pkl);
540 #endif /* IPFILTER_LOG */
541 if (!(skip = fr->fr_skip) && (passt & FR_LOGMASK) != FR_LOG)
543 FR_DEBUG(("pass %#x\n", pass));
544 ATOMIC_INC(fr->fr_hits);
545 if (pass & FR_ACCOUNT)
546 fr->fr_bytes += (U_QUAD_T)ip->ip_len;
548 fin->fin_icode = fr->fr_icode;
549 fin->fin_rule = rulen;
550 fin->fin_group = fr->fr_group;
552 fin->fin_fr = fr->fr_grp;
553 pass = fr_scanlist(pass, ip, fin, m);
554 if (fin->fin_fr == NULL) {
555 fin->fin_rule = rulen;
556 fin->fin_group = fr->fr_group;
559 if (pass & FR_DONTCACHE)
566 pass |= FR_DONTCACHE;
572 * frcheck - filter check
573 * check using source and destination addresses/ports in a packet whether
574 * or not to pass it on or not.
576 int fr_check(ip, hlen, ifp, out
577 #if defined(_KERNEL) && SOLARIS
590 * The above really sucks, but short of writing a diff
592 fr_info_t frinfo, *fc;
593 register fr_info_t *fin = &frinfo;
594 frentry_t *fr = NULL;
595 int changed, error = EHOSTUNREACH;
597 #if !SOLARIS || !defined(_KERNEL)
598 register mb_t *m = *mp;
603 # if !defined(__SVR4) && !defined(__svr4__)
605 char hbuf[(0xf << 2) + sizeof(struct icmp) + sizeof(ip_t) + 8];
611 * XXX For now, IP Filter and fast-forwarding of cached flows
612 * XXX are mutually exclusive. Eventually, IP Filter should
613 * XXX get a "can-fast-forward" filter rule.
615 m->m_flags &= ~M_CANFASTFWD;
616 # endif /* M_CANFASTFWD */
618 if ((ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP ||
619 ip->ip_p == IPPROTO_ICMP)) {
622 if ((ip->ip_off & IP_OFFMASK) == 0)
626 plen = sizeof(tcphdr_t);
629 plen = sizeof(udphdr_t);
631 /* 96 - enough for complete ICMP error IP header */
633 plen = ICMPERR_MAXPKTLEN - sizeof(ip_t);
636 up = MIN(hlen + plen, ip->ip_len);
640 /* Under IRIX, avoid m_pullup as it makes ping <hostname> panic */
641 if ((up > sizeof(hbuf)) || (m_length(m) < up)) {
642 ATOMIC_INC(frstats[out].fr_pull[1]);
645 m_copydata(m, 0, up, hbuf);
646 ATOMIC_INC(frstats[out].fr_pull[0]);
650 if ((*mp = m_pullup(m, up)) == 0) {
651 ATOMIC_INC(frstats[out].fr_pull[1]);
654 ATOMIC_INC(frstats[out].fr_pull[0]);
656 ip = mtod(m, ip_t *);
664 # endif /* !defined(__SVR4) && !defined(__svr4__) */
674 fr_makefrip(hlen, ip, fin);
680 READ_ENTER(&ipf_mutex);
683 * Check auth now. This, combined with the check below to see if apass
684 * is 0 is to ensure that we don't count the packet twice, which can
685 * otherwise occur when we reprocess it. As it is, we only count it
686 * after it has no auth. table matchup. This also stops NAT from
687 * occuring until after the packet has been auth'd.
689 apass = fr_checkauth(ip, fin);
692 changed = ip_natin(ip, fin);
693 if (!apass && (fin->fin_fr = ipacct[0][fr_active]) &&
694 (fr_scanlist(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT)) {
695 ATOMIC_INC(frstats[0].fr_acct);
699 if (apass || (!(fr = ipfr_knownfrag(ip, fin)) &&
700 !(fr = fr_checkstate(ip, fin)))) {
702 * If a packet is found in the auth table, then skip checking
703 * the access lists for permission but we do need to consider
704 * the result as if it were from the ACL's.
708 if (!bcmp((char *)fin, (char *)fc, FI_CSIZE)) {
710 * copy cached data so we can unlock the mutex
713 bcopy((char *)fc, (char *)fin, FI_COPYSIZE);
714 ATOMIC_INC(frstats[out].fr_chit);
715 if ((fr = fin->fin_fr)) {
716 ATOMIC_INC(fr->fr_hits);
720 if ((fin->fin_fr = ipfilter[out][fr_active]))
721 pass = fr_scanlist(fr_pass, ip, fin, m);
722 if (!(pass & (FR_KEEPSTATE|FR_DONTCACHE)))
723 bcopy((char *)fin, (char *)fc,
725 if (pass & FR_NOMATCH) {
726 ATOMIC_INC(frstats[out].fr_nom);
734 * If we fail to add a packet to the authorization queue,
735 * then we drop the packet later. However, if it was added
736 * then pretend we've dropped it already.
738 if ((pass & FR_AUTH))
739 if (FR_NEWAUTH(m, fin, ip, qif) != 0)
746 if (pass & FR_PREAUTH) {
747 READ_ENTER(&ipf_auth);
748 if ((fin->fin_fr = ipauth) &&
749 (pass = fr_scanlist(0, ip, fin, m))) {
750 ATOMIC_INC(fr_authstats.fas_hits);
752 ATOMIC_INC(fr_authstats.fas_miss);
754 RWLOCK_EXIT(&ipf_auth);
758 if ((pass & (FR_KEEPFRAG|FR_KEEPSTATE)) == FR_KEEPFRAG) {
759 if (fin->fin_fi.fi_fl & FI_FRAG) {
760 if (ipfr_newfrag(ip, fin, pass) == -1) {
761 ATOMIC_INC(frstats[out].fr_bnfr);
763 ATOMIC_INC(frstats[out].fr_nfr);
766 ATOMIC_INC(frstats[out].fr_cfr);
769 if (pass & FR_KEEPSTATE) {
770 if (fr_addstate(ip, fin, 0) == NULL) {
771 ATOMIC_INC(frstats[out].fr_bads);
773 ATOMIC_INC(frstats[out].fr_ads);
776 } else if (fr != NULL) {
778 if (pass & FR_LOGFIRST)
779 pass &= ~(FR_LOGFIRST|FR_LOG);
782 if (fr && fr->fr_func && !(pass & FR_CALLNOW))
783 pass = (*fr->fr_func)(pass, ip, fin);
786 * Only count/translate packets which will be passed on, out the
789 if (out && (pass & FR_PASS)) {
790 if ((fin->fin_fr = ipacct[1][fr_active]) &&
791 (fr_scanlist(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT)) {
792 ATOMIC_INC(frstats[1].fr_acct);
795 changed = ip_natout(ip, fin);
798 RWLOCK_EXIT(&ipf_mutex);
801 if ((fr_flags & FF_LOGGING) || (pass & FR_LOGMASK)) {
802 if ((fr_flags & FF_LOGNOMATCH) && (pass & FR_NOMATCH)) {
803 pass |= FF_LOGNOMATCH;
804 ATOMIC_INC(frstats[out].fr_npkl);
806 } else if (((pass & FR_LOGMASK) == FR_LOGP) ||
807 ((pass & FR_PASS) && (fr_flags & FF_LOGPASS))) {
808 if ((pass & FR_LOGMASK) != FR_LOGP)
810 ATOMIC_INC(frstats[out].fr_ppkl);
812 } else if (((pass & FR_LOGMASK) == FR_LOGB) ||
813 ((pass & FR_BLOCK) && (fr_flags & FF_LOGBLOCK))) {
814 if ((pass & FR_LOGMASK) != FR_LOGB)
816 ATOMIC_INC(frstats[out].fr_bpkl);
818 if (!IPLLOG(pass, ip, fin, m)) {
819 ATOMIC_INC(frstats[out].fr_skip);
820 if ((pass & (FR_PASS|FR_LOGORBLOCK)) ==
821 (FR_PASS|FR_LOGORBLOCK))
822 pass ^= FR_PASS|FR_BLOCK;
826 #endif /* IPFILTER_LOG */
829 * Only allow FR_DUP to work if a rule matched - it makes no sense to
830 * set FR_DUP as a "default" as there are no instructions about where
831 * to send the packet.
833 if (fr && (pass & FR_DUP))
838 mc = m_copy(m, 0, M_COPYALL);
844 if (pass & FR_PASS) {
845 ATOMIC_INC(frstats[out].fr_pass);
846 } else if (pass & FR_BLOCK) {
847 ATOMIC_INC(frstats[out].fr_block);
849 * Should we return an ICMP packet to indicate error
850 * status passing through the packet filter ?
851 * WARNING: ICMP error packets AND TCP RST packets should
852 * ONLY be sent in repsonse to incoming packets. Sending them
853 * in response to outbound packets can result in a panic on
854 * some operating systems.
858 if (pass & FR_RETICMP) {
861 if ((pass & FR_RETMASK) == FR_FAKEICMP)
866 ICMP_ERROR(q, ip, ICMP_UNREACH, fin->fin_icode,
869 ICMP_ERROR(m, ip, ICMP_UNREACH, fin->fin_icode,
872 ATOMIC_INC(frstats[0].fr_ret);
873 } else if (((pass & FR_RETMASK) == FR_RETRST) &&
874 !(fin->fin_fi.fi_fl & FI_SHORT)) {
875 if (SEND_RESET(ip, qif, ifp, fin) == 0) {
876 ATOMIC_INC(frstats[1].fr_ret);
880 if ((pass & FR_RETMASK) == FR_RETICMP) {
881 verbose("- ICMP unreachable sent\n");
882 ATOMIC_INC(frstats[0].fr_ret);
883 } else if ((pass & FR_RETMASK) == FR_FAKEICMP) {
884 verbose("- forged ICMP unreachable sent\n");
885 ATOMIC_INC(frstats[0].fr_ret);
886 } else if (((pass & FR_RETMASK) == FR_RETRST) &&
887 !(fin->fin_fi.fi_fl & FI_SHORT)) {
888 verbose("- TCP RST sent\n");
889 ATOMIC_INC(frstats[1].fr_ret);
893 if (pass & FR_RETRST)
899 * If we didn't drop off the bottom of the list of rules (and thus
900 * the 'current' rule fr is not NULL), then we may have some extra
901 * instructions about what to do with a packet.
902 * Once we're finished return to our caller, freeing the packet if
903 * we are dropping it (* BSD ONLY *).
909 frdest_t *fdp = &fr->fr_tif;
911 if (((pass & FR_FASTROUTE) && !out) ||
912 (fdp->fd_ifp && fdp->fd_ifp != (struct ifnet *)-1)) {
913 if (ipfr_fastroute(m, fin, fdp) == 0)
917 ipfr_fastroute(mc, fin, &fr->fr_dif);
919 if (!(pass & FR_PASS) && m)
922 else if (changed && up && m)
923 m_copyback(m, 0, up, hbuf);
926 # else /* !SOLARIS */
928 frdest_t *fdp = &fr->fr_tif;
930 if (((pass & FR_FASTROUTE) && !out) ||
931 (fdp->fd_ifp && fdp->fd_ifp != (struct ifnet *)-1)) {
932 if (ipfr_fastroute(qif, ip, m, mp, fin, fdp) == 0)
936 ipfr_fastroute(qif, ip, mc, mp, fin, &fr->fr_dif);
938 # endif /* !SOLARIS */
939 return (pass & FR_PASS) ? 0 : error;
941 if (pass & FR_NOMATCH)
954 * addr should be 16bit aligned and len is in bytes.
957 u_short ipf_cksum(addr, len)
958 register u_short *addr;
961 register u_32_t sum = 0;
963 for (sum = 0; len > 1; len -= 2)
966 /* mop up an odd byte, if necessary */
968 sum += *(u_char *)addr;
971 * add back carry outs from top 16 bits to low 16 bits
973 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
974 sum += (sum >> 16); /* add carry */
975 return (u_short)(~sum);
980 * NB: This function assumes we've pullup'd enough for all of the IP header
981 * and the TCP header. We also assume that data blocks aren't allocated in
984 u_short fr_tcpsum(m, ip, tcp)
989 u_short *sp, slen, ts;
994 * Add up IP Header portion
996 hlen = ip->ip_hl << 2;
997 slen = ip->ip_len - hlen;
998 sum = htons((u_short)ip->ip_p);
1000 sp = (u_short *)&ip->ip_src;
1001 sum += *sp++; /* ip_src */
1003 sum += *sp++; /* ip_dst */
1009 sum2 = ip_cksum(m, hlen, sum); /* hlen == offset */
1010 sum2 = (sum2 & 0xffff) + (sum2 >> 16);
1011 sum2 = ~sum2 & 0xffff;
1012 # else /* SOLARIS */
1013 # if defined(BSD) || defined(sun)
1020 sum2 = in_cksum(m, slen);
1028 * Both sum and sum2 are partial sums, so combine them together.
1030 sum = (sum & 0xffff) + (sum >> 16);
1031 sum = ~sum & 0xffff;
1033 sum2 = (sum2 & 0xffff) + (sum2 >> 16);
1034 # else /* defined(BSD) || defined(sun) */
1040 u_short len = ip->ip_len;
1046 * Add up IP Header portion
1048 sp = (u_short *)&ip->ip_src;
1049 len -= (ip->ip_hl << 2);
1050 sum = ntohs(IPPROTO_TCP);
1052 sum += *sp++; /* ip_src */
1054 sum += *sp++; /* ip_dst */
1056 if (sp != (u_short *)tcp)
1057 sp = (u_short *)tcp;
1058 sum += *sp++; /* sport */
1059 sum += *sp++; /* dport */
1060 sum += *sp++; /* seq */
1062 sum += *sp++; /* ack */
1064 sum += *sp++; /* off */
1065 sum += *sp++; /* win */
1066 sum += *sp++; /* Skip over checksum */
1067 sum += *sp++; /* urp */
1071 * In case we had to copy the IP & TCP header out of mbufs,
1072 * skip over the mbuf bits which are the header
1074 if ((caddr_t)ip != mtod(m, caddr_t)) {
1075 hlen = (caddr_t)sp - (caddr_t)ip;
1077 add = MIN(hlen, m->m_len);
1078 sp = (u_short *)(mtod(m, caddr_t) + add);
1080 if (add == m->m_len) {
1085 sp = mtod(m, u_short *);
1087 PANIC((!m),("fr_tcpsum(1): not enough data"));
1093 if (!(len -= sizeof(*tcp)))
1096 if (((caddr_t)sp - mtod(m, caddr_t)) >= m->m_len) {
1098 PANIC((!m),("fr_tcpsum(2): not enough data"));
1099 sp = mtod(m, u_short *);
1101 if (((caddr_t)(sp + 1) - mtod(m, caddr_t)) > m->m_len) {
1102 bytes.c[0] = *(u_char *)sp;
1104 PANIC((!m),("fr_tcpsum(3): not enough data"));
1105 sp = mtod(m, u_short *);
1106 bytes.c[1] = *(u_char *)sp;
1108 sp = (u_short *)((u_char *)sp + 1);
1110 if ((u_long)sp & 1) {
1111 bcopy((char *)sp++, (char *)&bytes.s, sizeof(bytes.s));
1118 sum += ntohs(*(u_char *)sp << 8);
1120 while (sum > 0xffff)
1121 sum = (sum & 0xffff) + (sum >> 16);
1122 sum2 = (u_short)(~sum & 0xffff);
1124 # endif /* defined(BSD) || defined(sun) */
1125 # endif /* SOLARIS */
1134 #if defined(_KERNEL) && ( ((BSD < 199306) && !SOLARIS) || defined(__sgi) )
1136 * Copyright (c) 1982, 1986, 1988, 1991, 1993
1137 * The Regents of the University of California. All rights reserved.
1139 * Redistribution and use in source and binary forms, with or without
1140 * modification, are permitted provided that the following conditions
1142 * 1. Redistributions of source code must retain the above copyright
1143 * notice, this list of conditions and the following disclaimer.
1144 * 2. Redistributions in binary form must reproduce the above copyright
1145 * notice, this list of conditions and the following disclaimer in the
1146 * documentation and/or other materials provided with the distribution.
1147 * 3. All advertising materials mentioning features or use of this software
1148 * must display the following acknowledgement:
1149 * This product includes software developed by the University of
1150 * California, Berkeley and its contributors.
1151 * 4. Neither the name of the University nor the names of its contributors
1152 * may be used to endorse or promote products derived from this software
1153 * without specific prior written permission.
1155 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1156 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1157 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1158 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1159 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1160 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1161 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1162 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1163 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1164 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1167 * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
1168 * $Id: fil.c,v 2.3.2.7 1999/10/21 14:21:40 darrenr Exp $
1171 * Copy data from an mbuf chain starting "off" bytes from the beginning,
1172 * continuing for "len" bytes, into the indicated buffer.
1175 m_copydata(m, off, len, cp)
1181 register unsigned count;
1183 if (off < 0 || len < 0)
1184 panic("m_copydata");
1187 panic("m_copydata");
1195 panic("m_copydata");
1196 count = MIN(m->m_len - off, len);
1197 bcopy(mtod(m, caddr_t) + off, cp, count);
1208 * Copy data from a buffer back into the indicated mbuf chain,
1209 * starting "off" bytes from the beginning, extending the mbuf
1210 * chain if necessary.
1213 m_copyback(m0, off, len, cp)
1220 register struct mbuf *m = m0, *n;
1225 while (off > (mlen = m->m_len)) {
1228 if (m->m_next == 0) {
1229 n = m_getclr(M_DONTWAIT, m->m_type);
1232 n->m_len = min(MLEN, len + off);
1238 mlen = min (m->m_len - off, len);
1239 bcopy(cp, off + mtod(m, caddr_t), (unsigned)mlen);
1247 if (m->m_next == 0) {
1248 n = m_get(M_DONTWAIT, m->m_type);
1251 n->m_len = min(MLEN, len);
1258 if (((m = m0)->m_flags & M_PKTHDR) && (m->m_pkthdr.len < totlen))
1259 m->m_pkthdr.len = totlen;
1264 #endif /* (_KERNEL) && ( ((BSD < 199306) && !SOLARIS) || __sgi) */
1267 frgroup_t *fr_findgroup(num, flags, which, set, fgpp)
1274 frgroup_t *fg, **fgp;
1276 if (which == IPL_LOGAUTH)
1277 fgp = &ipfgroups[2][set];
1278 else if (flags & FR_ACCOUNT)
1279 fgp = &ipfgroups[1][set];
1280 else if (flags & (FR_OUTQUE|FR_INQUE))
1281 fgp = &ipfgroups[0][set];
1287 if (fg->fg_num == num)
1297 frgroup_t *fr_addgroup(num, fp, which, set)
1303 frgroup_t *fg, **fgp;
1305 if ((fg = fr_findgroup(num, fp->fr_flags, which, set, &fgp)))
1308 KMALLOC(fg, frgroup_t *);
1310 fg->fg_num = num & 0xffff;
1313 fg->fg_start = &fp->fr_grp;
1320 void fr_delgroup(num, flags, which, set)
1326 frgroup_t *fg, **fgp;
1328 if (!(fg = fr_findgroup(num, flags, which, set, &fgp)))
1338 * recursively flush rules from the list, descending groups as they are
1339 * encountered. if a rule is the head of a group and it has lost all its
1340 * group members, then also delete the group reference.
1342 static int frflushlist(set, unit, nfreedp, listp)
1348 register int freed = 0, i;
1349 register frentry_t *fp;
1351 while ((fp = *listp)) {
1352 *listp = fp->fr_next;
1354 i = frflushlist(set, unit, nfreedp, &fp->fr_grp);
1355 MUTEX_ENTER(&ipf_rw);
1357 MUTEX_EXIT(&ipf_rw);
1360 ATOMIC_DEC(fp->fr_ref);
1361 if (fp->fr_ref == 0) {
1363 fr_delgroup((u_int)fp->fr_grhead, fp->fr_flags,
1375 int frflush(unit, flags)
1379 int flushed = 0, set;
1381 if (unit != IPL_LOGIPF)
1383 WRITE_ENTER(&ipf_mutex);
1384 bzero((char *)frcache, sizeof(frcache[0]) * 2);
1387 if (flags & FR_INACTIVE)
1390 if (flags & FR_OUTQUE) {
1391 (void) frflushlist(set, unit, &flushed, &ipfilter[1][set]);
1392 (void) frflushlist(set, unit, &flushed, &ipacct[1][set]);
1394 if (flags & FR_INQUE) {
1395 (void) frflushlist(set, unit, &flushed, &ipfilter[0][set]);
1396 (void) frflushlist(set, unit, &flushed, &ipacct[0][set]);
1398 RWLOCK_EXIT(&ipf_mutex);
1403 char *memstr(src, dst, slen, dlen)
1409 while (dlen >= slen) {
1410 if (bcmp(src, dst, slen) == 0) {
1421 void fixskip(listp, rp, addremove)
1422 frentry_t **listp, *rp;
1426 int rules = 0, rn = 0;
1428 for (fp = *listp; fp && (fp != rp); fp = fp->fr_next, rules++)
1434 for (fp = *listp; fp && (fp != rp); fp = fp->fr_next, rn++)
1435 if (fp->fr_skip && (rn + fp->fr_skip >= rules))
1436 fp->fr_skip += addremove;
1442 * count consecutive 1's in bit mask. If the mask generated by counting
1443 * consecutive 1's is different to that passed, return -1, else return #
1452 ip = ipn = ntohl(ip);
1453 for (i = 32; i; i--, ipn *= 2)
1454 if (ipn & 0x80000000)
1459 for (i = 32, j = cnt; i; i--, j--) {
1471 * return the first IP Address associated with an interface
1473 int fr_ifpaddr(ifptr, inp)
1475 struct in_addr *inp;
1480 struct ifnet *ifp = ifptr;
1485 in.s_addr = ill->ill_ipif->ipif_local_addr;
1486 # else /* SOLARIS */
1491 struct sockaddr_in *sin;
1493 # if (__FreeBSD_version >= 300000)
1494 ifa = TAILQ_FIRST(&ifp->if_addrhead);
1496 # if defined(__NetBSD__) || defined(__OpenBSD__)
1497 ifa = ifp->if_addrlist.tqh_first;
1499 # if defined(__sgi) && defined(IFF_DRVRLOCK) /* IRIX 6 */
1500 ifa = &((struct in_ifaddr *)ifp->in_ifaddr)->ia_ifa;
1502 ifa = ifp->if_addrlist;
1504 # endif /* __NetBSD__ || __OpenBSD__ */
1505 # endif /* __FreeBSD_version >= 300000 */
1506 # if (BSD < 199306) && !(/*IRIX6*/defined(__sgi) && defined(IFF_DRVRLOCK))
1507 sin = (struct sockaddr_in *)&ifa->ifa_addr;
1509 sin = (struct sockaddr_in *)ifa->ifa_addr;
1510 while (sin && ifa &&
1511 sin->sin_family != AF_INET) {
1512 # if (__FreeBSD_version >= 300000)
1513 ifa = TAILQ_NEXT(ifa, ifa_link);
1515 # if defined(__NetBSD__) || defined(__OpenBSD__)
1516 ifa = ifa->ifa_list.tqe_next;
1518 ifa = ifa->ifa_next;
1520 # endif /* __FreeBSD_version >= 300000 */
1522 sin = (struct sockaddr_in *)ifa->ifa_addr;
1528 # endif /* (BSD < 199306) && (!__sgi && IFF_DRVLOCK) */
1531 # endif /* SOLARIS */
1532 in.s_addr = ntohl(in.s_addr);
1540 * return the first IP Address associated with an interface
1542 int fr_ifpaddr(ifptr, inp)
1544 struct in_addr *inp;