17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * Copyright (C) 1997-2003 by Darren Reed. 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * See the IPFILTER.LICENCE file for details on licencing. 57c478bd9Sstevel@tonic-gate * 6ab25eeb5Syz * $Id: ip_log.c,v 2.75.2.7 2005/06/11 07:47:44 darrenr Exp $ 77c478bd9Sstevel@tonic-gate * 87ddc9b1aSDarren Reed * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 97c478bd9Sstevel@tonic-gate * Use is subject to license terms. 1094bdecd9SRob Gulewich * 1194bdecd9SRob Gulewich * Copyright (c) 2014, Joyent, Inc. All rights reserved. 127c478bd9Sstevel@tonic-gate */ 137c478bd9Sstevel@tonic-gate 147c478bd9Sstevel@tonic-gate #include <sys/param.h> 157c478bd9Sstevel@tonic-gate #if defined(KERNEL) || defined(_KERNEL) 167c478bd9Sstevel@tonic-gate # undef KERNEL 177c478bd9Sstevel@tonic-gate # undef _KERNEL 187c478bd9Sstevel@tonic-gate # define KERNEL 1 197c478bd9Sstevel@tonic-gate # define _KERNEL 1 207c478bd9Sstevel@tonic-gate #endif 217c478bd9Sstevel@tonic-gate #if defined(__NetBSD__) && (NetBSD >= 199905) && !defined(IPFILTER_LKM) && \ 227c478bd9Sstevel@tonic-gate defined(_KERNEL) 237c478bd9Sstevel@tonic-gate # include "opt_ipfilter_log.h" 247c478bd9Sstevel@tonic-gate #endif 25ab25eeb5Syz #if defined(__FreeBSD__) && !defined(IPFILTER_LKM) 26ab25eeb5Syz # if defined(_KERNEL) 27ab25eeb5Syz # if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) 28ab25eeb5Syz # include "opt_ipfilter.h" 297c478bd9Sstevel@tonic-gate # endif 30ab25eeb5Syz # else 31ab25eeb5Syz # include <osreldate.h> 327c478bd9Sstevel@tonic-gate # endif 337c478bd9Sstevel@tonic-gate #endif 34ab25eeb5Syz #ifndef SOLARIS 35ab25eeb5Syz # define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4))) 36ab25eeb5Syz #endif 37ab25eeb5Syz #include <sys/errno.h> 38ab25eeb5Syz #include <sys/types.h> 39ab25eeb5Syz #include <sys/file.h> 40ab25eeb5Syz #ifndef _KERNEL 41ab25eeb5Syz # include <stdio.h> 42ab25eeb5Syz # include <string.h> 43ab25eeb5Syz # include <stdlib.h> 44ab25eeb5Syz # include <ctype.h> 45ab25eeb5Syz # define _KERNEL 46ab25eeb5Syz # define KERNEL 477c478bd9Sstevel@tonic-gate # ifdef __OpenBSD__ 487c478bd9Sstevel@tonic-gate struct file; 497c478bd9Sstevel@tonic-gate # endif 50ab25eeb5Syz # include <sys/uio.h> 51ab25eeb5Syz # undef _KERNEL 52ab25eeb5Syz # undef KERNEL 53ab25eeb5Syz #endif 54ab25eeb5Syz #if __FreeBSD_version >= 220000 && defined(_KERNEL) 55ab25eeb5Syz # include <sys/fcntl.h> 56ab25eeb5Syz # include <sys/filio.h> 57ab25eeb5Syz #else 58ab25eeb5Syz # include <sys/ioctl.h> 59ab25eeb5Syz #endif 60ab25eeb5Syz #include <sys/time.h> 61ab25eeb5Syz #if defined(_KERNEL) 62ab25eeb5Syz # include <sys/systm.h> 63ab25eeb5Syz # if defined(NetBSD) && (__NetBSD_Version__ >= 104000000) 64ab25eeb5Syz # include <sys/proc.h> 657c478bd9Sstevel@tonic-gate # endif 66ab25eeb5Syz #endif /* _KERNEL */ 67*af5f29ddSToomas Soome #if !defined(SOLARIS) && !defined(__hpux) && !defined(linux) 68ab25eeb5Syz # if (NetBSD > 199609) || (OpenBSD > 199603) || (__FreeBSD_version >= 300000) 69ab25eeb5Syz # include <sys/dirent.h> 707c478bd9Sstevel@tonic-gate # else 71ab25eeb5Syz # include <sys/dir.h> 727c478bd9Sstevel@tonic-gate # endif 73ab25eeb5Syz # include <sys/mbuf.h> 74ab25eeb5Syz #else 75ab25eeb5Syz # if !defined(__hpux) && defined(_KERNEL) 76ab25eeb5Syz # include <sys/filio.h> 77ab25eeb5Syz # include <sys/cred.h> 78ab25eeb5Syz # include <sys/ddi.h> 79ab25eeb5Syz # include <sys/sunddi.h> 80ab25eeb5Syz # include <sys/ksynch.h> 81ab25eeb5Syz # include <sys/kmem.h> 82ab25eeb5Syz # include <sys/mkdev.h> 83ab25eeb5Syz # include <sys/dditypes.h> 84ab25eeb5Syz # include <sys/cmn_err.h> 85ab25eeb5Syz # endif /* !__hpux */ 86ab25eeb5Syz #endif /* !SOLARIS && !__hpux */ 87ab25eeb5Syz #if !defined(linux) 887c478bd9Sstevel@tonic-gate # include <sys/protosw.h> 89ab25eeb5Syz #endif 90ab25eeb5Syz #include <sys/socket.h> 917c478bd9Sstevel@tonic-gate 92ab25eeb5Syz #include <net/if.h> 93ab25eeb5Syz #ifdef sun 94ab25eeb5Syz # include <net/af.h> 95ab25eeb5Syz #endif 96ab25eeb5Syz #if __FreeBSD_version >= 300000 97ab25eeb5Syz # include <net/if_var.h> 98ab25eeb5Syz #endif 99ab25eeb5Syz #include <net/route.h> 100ab25eeb5Syz #include <netinet/in.h> 101ab25eeb5Syz #ifdef __sgi 102ab25eeb5Syz # include <sys/ddi.h> 103ab25eeb5Syz # ifdef IFF_DRVRLOCK /* IRIX6 */ 104ab25eeb5Syz # include <sys/hashing.h> 1057c478bd9Sstevel@tonic-gate # endif 106ab25eeb5Syz #endif 107ab25eeb5Syz #if !defined(__hpux) && !defined(linux) && \ 108ab25eeb5Syz !(defined(__sgi) && !defined(IFF_DRVRLOCK)) /*IRIX<6*/ 109ab25eeb5Syz # include <netinet/in_var.h> 110ab25eeb5Syz #endif 111ab25eeb5Syz #include <netinet/in_systm.h> 112ab25eeb5Syz #include <netinet/ip.h> 113ab25eeb5Syz #include <netinet/tcp.h> 114ab25eeb5Syz #include <netinet/udp.h> 115ab25eeb5Syz #include <netinet/ip_icmp.h> 116ab25eeb5Syz #ifdef USE_INET6 117ab25eeb5Syz # include <netinet/icmp6.h> 118ab25eeb5Syz #endif 119ab25eeb5Syz #if !defined(linux) 1207c478bd9Sstevel@tonic-gate # include <netinet/ip_var.h> 1217c478bd9Sstevel@tonic-gate #endif 122ab25eeb5Syz #ifndef _KERNEL 123ab25eeb5Syz # include <syslog.h> 124ab25eeb5Syz #endif 125ab25eeb5Syz #include "netinet/ip_compat.h" 126ab25eeb5Syz #include <netinet/tcpip.h> 127ab25eeb5Syz #include "netinet/ip_fil.h" 128ab25eeb5Syz #include "netinet/ip_nat.h" 129ab25eeb5Syz #include "netinet/ip_frag.h" 130ab25eeb5Syz #include "netinet/ip_state.h" 131ab25eeb5Syz #include "netinet/ip_auth.h" 132f4b3ec61Sdh #include "netinet/ipf_stack.h" 133ab25eeb5Syz #if (__FreeBSD_version >= 300000) || defined(__NetBSD__) 134ab25eeb5Syz # include <sys/malloc.h> 135ab25eeb5Syz #endif 136ab25eeb5Syz /* END OF INCLUDES */ 1377c478bd9Sstevel@tonic-gate 138ab25eeb5Syz #ifdef IPFILTER_LOG 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate # if defined(IPL_SELECT) 141ab25eeb5Syz # include <machine/sys/user.h> 142ab25eeb5Syz # include <sys/kthread_iface.h> 143ab25eeb5Syz # define READ_COLLISION 0x001 1447c478bd9Sstevel@tonic-gate 145ab25eeb5Syz iplog_select_t iplog_ss[IPL_LOGMAX+1]; 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate extern int selwait; 1487c478bd9Sstevel@tonic-gate # endif /* IPL_SELECT */ 1497c478bd9Sstevel@tonic-gate 150f4b3ec61Sdh /* ipl_magic never changes */ 151ab25eeb5Syz int ipl_magic[IPL_LOGSIZE] = { IPL_MAGIC, IPL_MAGIC_NAT, IPL_MAGIC_STATE, 152ab25eeb5Syz IPL_MAGIC, IPL_MAGIC, IPL_MAGIC, 153ab25eeb5Syz IPL_MAGIC, IPL_MAGIC }; 1547c478bd9Sstevel@tonic-gate 1557c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 1567c478bd9Sstevel@tonic-gate /* Function: fr_loginit */ 1577c478bd9Sstevel@tonic-gate /* Returns: int - 0 == success (always returned) */ 1587c478bd9Sstevel@tonic-gate /* Parameters: Nil */ 1597c478bd9Sstevel@tonic-gate /* */ 1607c478bd9Sstevel@tonic-gate /* Initialise log buffers & pointers. Also iniialised the CRC to a local */ 1617c478bd9Sstevel@tonic-gate /* secret for use in calculating the "last log checksum". */ 1627c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 163f4b3ec61Sdh int fr_loginit(ifs) 164f4b3ec61Sdh ipf_stack_t *ifs; 1657c478bd9Sstevel@tonic-gate { 1667c478bd9Sstevel@tonic-gate int i; 167f4b3ec61Sdh 1687c478bd9Sstevel@tonic-gate for (i = IPL_LOGMAX; i >= 0; i--) { 169f4b3ec61Sdh ifs->ifs_iplt[i] = NULL; 170f4b3ec61Sdh ifs->ifs_ipll[i] = NULL; 171f4b3ec61Sdh ifs->ifs_iplh[i] = &ifs->ifs_iplt[i]; 172f4b3ec61Sdh ifs->ifs_iplused[i] = 0; 173f4b3ec61Sdh bzero((char *)&ifs->ifs_iplcrc[i], sizeof(ifs->ifs_iplcrc[i])); 1747c478bd9Sstevel@tonic-gate # ifdef IPL_SELECT 1757c478bd9Sstevel@tonic-gate iplog_ss[i].read_waiter = 0; 1767c478bd9Sstevel@tonic-gate iplog_ss[i].state = 0; 177ab25eeb5Syz # endif 178ab25eeb5Syz # if defined(linux) && defined(_KERNEL) 179ab25eeb5Syz init_waitqueue_head(iplh_linux + i); 1807c478bd9Sstevel@tonic-gate # endif 1817c478bd9Sstevel@tonic-gate } 1827c478bd9Sstevel@tonic-gate 183*af5f29ddSToomas Soome # if defined(SOLARIS) && defined(_KERNEL) 184f4b3ec61Sdh cv_init(&ifs->ifs_iplwait, "ipl condvar", CV_DRIVER, NULL); 1857c478bd9Sstevel@tonic-gate # endif 186f4b3ec61Sdh MUTEX_INIT(&ifs->ifs_ipl_mutex, "ipf log mutex"); 1877c478bd9Sstevel@tonic-gate 188f4b3ec61Sdh ifs->ifs_ipl_log_init = 1; 1897c478bd9Sstevel@tonic-gate 1907c478bd9Sstevel@tonic-gate return 0; 1917c478bd9Sstevel@tonic-gate } 1927c478bd9Sstevel@tonic-gate 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 1957c478bd9Sstevel@tonic-gate /* Function: fr_logunload */ 1967c478bd9Sstevel@tonic-gate /* Returns: Nil */ 1977c478bd9Sstevel@tonic-gate /* Parameters: Nil */ 1987c478bd9Sstevel@tonic-gate /* */ 1997c478bd9Sstevel@tonic-gate /* Clean up any log data that has accumulated without being read. */ 2007c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 201f4b3ec61Sdh void fr_logunload(ifs) 202f4b3ec61Sdh ipf_stack_t *ifs; 2037c478bd9Sstevel@tonic-gate { 2047c478bd9Sstevel@tonic-gate int i; 2057c478bd9Sstevel@tonic-gate 206f4b3ec61Sdh if (ifs->ifs_ipl_log_init == 0) 2077c478bd9Sstevel@tonic-gate return; 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate for (i = IPL_LOGMAX; i >= 0; i--) 210f4b3ec61Sdh (void) ipflog_clear(i, ifs); 2117c478bd9Sstevel@tonic-gate 212*af5f29ddSToomas Soome # if defined(SOLARIS) && defined(_KERNEL) 213f4b3ec61Sdh cv_destroy(&ifs->ifs_iplwait); 2147c478bd9Sstevel@tonic-gate # endif 215f4b3ec61Sdh MUTEX_DESTROY(&ifs->ifs_ipl_mutex); 2167c478bd9Sstevel@tonic-gate 217f4b3ec61Sdh ifs->ifs_ipl_log_init = 0; 2187c478bd9Sstevel@tonic-gate } 2197c478bd9Sstevel@tonic-gate 2207c478bd9Sstevel@tonic-gate 2217c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 2227c478bd9Sstevel@tonic-gate /* Function: ipflog */ 2237c478bd9Sstevel@tonic-gate /* Returns: int - 0 == success, -1 == failure */ 2247c478bd9Sstevel@tonic-gate /* Parameters: fin(I) - pointer to packet information */ 2257c478bd9Sstevel@tonic-gate /* flags(I) - flags from filter rules */ 2267c478bd9Sstevel@tonic-gate /* */ 2277c478bd9Sstevel@tonic-gate /* Create a log record for a packet given that it has been triggered by a */ 2287c478bd9Sstevel@tonic-gate /* rule (or the default setting). Calculate the transport protocol header */ 2297c478bd9Sstevel@tonic-gate /* size using predetermined size of a couple of popular protocols and thus */ 2307c478bd9Sstevel@tonic-gate /* how much data to copy into the log, including part of the data body if */ 2317c478bd9Sstevel@tonic-gate /* requested. */ 2327c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 2337c478bd9Sstevel@tonic-gate int ipflog(fin, flags) 2347c478bd9Sstevel@tonic-gate fr_info_t *fin; 2357c478bd9Sstevel@tonic-gate u_int flags; 2367c478bd9Sstevel@tonic-gate { 2377c478bd9Sstevel@tonic-gate register size_t hlen; 2387c478bd9Sstevel@tonic-gate int types[2], mlen; 2397c478bd9Sstevel@tonic-gate size_t sizes[2]; 2407c478bd9Sstevel@tonic-gate void *ptrs[2]; 2417c478bd9Sstevel@tonic-gate ipflog_t ipfl; 2427c478bd9Sstevel@tonic-gate u_char p; 2437c478bd9Sstevel@tonic-gate mb_t *m; 244*af5f29ddSToomas Soome # if defined(SOLARIS) && defined(_KERNEL) 2457ddc9b1aSDarren Reed net_handle_t nif; 246381a2a9aSdr void *ifp; 247381a2a9aSdr # else 248381a2a9aSdr # if defined(__hpux) && defined(_KERNEL) 249ab25eeb5Syz qif_t *ifp; 2507c478bd9Sstevel@tonic-gate # else 2517c478bd9Sstevel@tonic-gate struct ifnet *ifp; 252381a2a9aSdr # endif 253381a2a9aSdr # endif /* SOLARIS */ 254f4b3ec61Sdh ipf_stack_t *ifs = fin->fin_ifs; 2557c478bd9Sstevel@tonic-gate 256ab25eeb5Syz ipfl.fl_nattag.ipt_num[0] = 0; 2577c478bd9Sstevel@tonic-gate m = fin->fin_m; 2587c478bd9Sstevel@tonic-gate ifp = fin->fin_ifp; 2597c478bd9Sstevel@tonic-gate hlen = fin->fin_hlen; 2607c478bd9Sstevel@tonic-gate /* 2617c478bd9Sstevel@tonic-gate * calculate header size. 2627c478bd9Sstevel@tonic-gate */ 2637c478bd9Sstevel@tonic-gate if (fin->fin_off == 0) { 2647c478bd9Sstevel@tonic-gate p = fin->fin_fi.fi_p; 2657c478bd9Sstevel@tonic-gate if (p == IPPROTO_TCP) 2667c478bd9Sstevel@tonic-gate hlen += MIN(sizeof(tcphdr_t), fin->fin_dlen); 2677c478bd9Sstevel@tonic-gate else if (p == IPPROTO_UDP) 2687c478bd9Sstevel@tonic-gate hlen += MIN(sizeof(udphdr_t), fin->fin_dlen); 2697c478bd9Sstevel@tonic-gate else if (p == IPPROTO_ICMP) { 2707c478bd9Sstevel@tonic-gate struct icmp *icmp; 2717c478bd9Sstevel@tonic-gate 2727c478bd9Sstevel@tonic-gate icmp = (struct icmp *)fin->fin_dp; 273ab25eeb5Syz 2747c478bd9Sstevel@tonic-gate /* 2757c478bd9Sstevel@tonic-gate * For ICMP, if the packet is an error packet, also 2767c478bd9Sstevel@tonic-gate * include the information about the packet which 2777c478bd9Sstevel@tonic-gate * caused the error. 2787c478bd9Sstevel@tonic-gate */ 2797c478bd9Sstevel@tonic-gate switch (icmp->icmp_type) 2807c478bd9Sstevel@tonic-gate { 2817c478bd9Sstevel@tonic-gate case ICMP_UNREACH : 2827c478bd9Sstevel@tonic-gate case ICMP_SOURCEQUENCH : 2837c478bd9Sstevel@tonic-gate case ICMP_REDIRECT : 2847c478bd9Sstevel@tonic-gate case ICMP_TIMXCEED : 2857c478bd9Sstevel@tonic-gate case ICMP_PARAMPROB : 2867c478bd9Sstevel@tonic-gate hlen += MIN(sizeof(struct icmp) + 8, 2877c478bd9Sstevel@tonic-gate fin->fin_dlen); 2887c478bd9Sstevel@tonic-gate break; 2897c478bd9Sstevel@tonic-gate default : 2907c478bd9Sstevel@tonic-gate hlen += MIN(sizeof(struct icmp), 2917c478bd9Sstevel@tonic-gate fin->fin_dlen); 2927c478bd9Sstevel@tonic-gate break; 2937c478bd9Sstevel@tonic-gate } 2947c478bd9Sstevel@tonic-gate } 2957c478bd9Sstevel@tonic-gate # ifdef USE_INET6 2967c478bd9Sstevel@tonic-gate else if (p == IPPROTO_ICMPV6) { 2977c478bd9Sstevel@tonic-gate struct icmp6_hdr *icmp; 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate icmp = (struct icmp6_hdr *)fin->fin_dp; 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gate /* 3027c478bd9Sstevel@tonic-gate * For ICMPV6, if the packet is an error packet, also 3037c478bd9Sstevel@tonic-gate * include the information about the packet which 3047c478bd9Sstevel@tonic-gate * caused the error. 3057c478bd9Sstevel@tonic-gate */ 3067c478bd9Sstevel@tonic-gate if (icmp->icmp6_type < 128) { 3077c478bd9Sstevel@tonic-gate hlen += MIN(sizeof(struct icmp6_hdr) + 8, 3087c478bd9Sstevel@tonic-gate fin->fin_dlen); 3097c478bd9Sstevel@tonic-gate } else { 3107c478bd9Sstevel@tonic-gate hlen += MIN(sizeof(struct icmp6_hdr), 3117c478bd9Sstevel@tonic-gate fin->fin_dlen); 3127c478bd9Sstevel@tonic-gate } 3137c478bd9Sstevel@tonic-gate } 3147c478bd9Sstevel@tonic-gate # endif 3157c478bd9Sstevel@tonic-gate } 3167c478bd9Sstevel@tonic-gate /* 3177c478bd9Sstevel@tonic-gate * Get the interface number and name to which this packet is 3187c478bd9Sstevel@tonic-gate * currently associated. 3197c478bd9Sstevel@tonic-gate */ 320*af5f29ddSToomas Soome # if defined(SOLARIS) && defined(_KERNEL) 321ab25eeb5Syz ipfl.fl_unit = (u_int)0; 322381a2a9aSdr nif = NULL; 323381a2a9aSdr if (fin->fin_fi.fi_v == 4) 324f4b3ec61Sdh nif = ifs->ifs_ipf_ipv4; 325381a2a9aSdr else if (fin->fin_fi.fi_v == 6) 326f4b3ec61Sdh nif = ifs->ifs_ipf_ipv6; 327381a2a9aSdr if (nif != NULL) { 328381a2a9aSdr if (net_getifname(nif, (phy_if_t)ifp, 329381a2a9aSdr ipfl.fl_ifname, sizeof(ipfl.fl_ifname)) != 0) 330381a2a9aSdr return (-1); 331381a2a9aSdr } 332381a2a9aSdr 3337c478bd9Sstevel@tonic-gate # else 334381a2a9aSdr # if defined(__hpux) && defined(_KERNEL) 335381a2a9aSdr ipfl.fl_unit = (u_int)0; 336381a2a9aSdr (void) strncpy(ipfl.fl_ifname, IFNAME(ifp), sizeof(ipfl.fl_ifname)); 3377c478bd9Sstevel@tonic-gate # else 338381a2a9aSdr # if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \ 339381a2a9aSdr (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \ 340381a2a9aSdr (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) 341381a2a9aSdr COPYIFNAME(ifp, ipfl.fl_ifname); 342381a2a9aSdr # else 343ab25eeb5Syz ipfl.fl_unit = (u_int)ifp->if_unit; 344381a2a9aSdr # if defined(_KERNEL) 3457c478bd9Sstevel@tonic-gate if ((ipfl.fl_ifname[0] = ifp->if_name[0])) 3467c478bd9Sstevel@tonic-gate if ((ipfl.fl_ifname[1] = ifp->if_name[1])) 3477c478bd9Sstevel@tonic-gate if ((ipfl.fl_ifname[2] = ifp->if_name[2])) 3487c478bd9Sstevel@tonic-gate ipfl.fl_ifname[3] = ifp->if_name[3]; 349381a2a9aSdr # else 350ab25eeb5Syz (void) strncpy(ipfl.fl_ifname, IFNAME(ifp), sizeof(ipfl.fl_ifname)); 351ab25eeb5Syz ipfl.fl_ifname[sizeof(ipfl.fl_ifname) - 1] = '\0'; 352381a2a9aSdr # endif 3537c478bd9Sstevel@tonic-gate # endif 354381a2a9aSdr # endif /* __hpux */ 355381a2a9aSdr # endif /* SOLARIS */ 3567c478bd9Sstevel@tonic-gate mlen = fin->fin_plen - hlen; 357f4b3ec61Sdh if (!ifs->ifs_ipl_logall) { 3587c478bd9Sstevel@tonic-gate mlen = (flags & FR_LOGBODY) ? MIN(mlen, 128) : 0; 3597c478bd9Sstevel@tonic-gate } else if ((flags & FR_LOGBODY) == 0) { 3607c478bd9Sstevel@tonic-gate mlen = 0; 3617c478bd9Sstevel@tonic-gate } 3627c478bd9Sstevel@tonic-gate if (mlen < 0) 3637c478bd9Sstevel@tonic-gate mlen = 0; 3647c478bd9Sstevel@tonic-gate ipfl.fl_plen = (u_char)mlen; 3657c478bd9Sstevel@tonic-gate ipfl.fl_hlen = (u_char)hlen; 3667c478bd9Sstevel@tonic-gate ipfl.fl_rule = fin->fin_rule; 3677c478bd9Sstevel@tonic-gate (void) strncpy(ipfl.fl_group, fin->fin_group, FR_GROUPLEN); 3687c478bd9Sstevel@tonic-gate if (fin->fin_fr != NULL) { 3697c478bd9Sstevel@tonic-gate ipfl.fl_loglevel = fin->fin_fr->fr_loglevel; 370ab25eeb5Syz ipfl.fl_logtag = fin->fin_fr->fr_logtag; 3717c478bd9Sstevel@tonic-gate } else { 3727c478bd9Sstevel@tonic-gate ipfl.fl_loglevel = 0xffff; 373ab25eeb5Syz ipfl.fl_logtag = FR_NOLOGTAG; 3747c478bd9Sstevel@tonic-gate } 375ab25eeb5Syz if (fin->fin_nattag != NULL) 376ab25eeb5Syz bcopy(fin->fin_nattag, (void *)&ipfl.fl_nattag, 377ab25eeb5Syz sizeof(ipfl.fl_nattag)); 3787c478bd9Sstevel@tonic-gate ipfl.fl_flags = flags; 3797c478bd9Sstevel@tonic-gate ipfl.fl_dir = fin->fin_out; 3807c478bd9Sstevel@tonic-gate ipfl.fl_lflags = fin->fin_flx; 3817c478bd9Sstevel@tonic-gate ptrs[0] = (void *)&ipfl; 3827c478bd9Sstevel@tonic-gate sizes[0] = sizeof(ipfl); 3837c478bd9Sstevel@tonic-gate types[0] = 0; 3847c478bd9Sstevel@tonic-gate # if defined(MENTAT) && defined(_KERNEL) 3857c478bd9Sstevel@tonic-gate /* 3867c478bd9Sstevel@tonic-gate * Are we copied from the mblk or an aligned array ? 3877c478bd9Sstevel@tonic-gate */ 3887c478bd9Sstevel@tonic-gate if (fin->fin_ip == (ip_t *)m->b_rptr) { 3897c478bd9Sstevel@tonic-gate ptrs[1] = m; 3907c478bd9Sstevel@tonic-gate sizes[1] = hlen + mlen; 3917c478bd9Sstevel@tonic-gate types[1] = 1; 3927c478bd9Sstevel@tonic-gate } else { 3937c478bd9Sstevel@tonic-gate ptrs[1] = fin->fin_ip; 3947c478bd9Sstevel@tonic-gate sizes[1] = hlen + mlen; 3957c478bd9Sstevel@tonic-gate types[1] = 0; 3967c478bd9Sstevel@tonic-gate } 3977c478bd9Sstevel@tonic-gate # else 3987c478bd9Sstevel@tonic-gate ptrs[1] = m; 3997c478bd9Sstevel@tonic-gate sizes[1] = hlen + mlen; 4007c478bd9Sstevel@tonic-gate types[1] = 1; 4017c478bd9Sstevel@tonic-gate # endif /* MENTAT */ 402f4b3ec61Sdh return ipllog(IPL_LOGIPF, fin, ptrs, sizes, types, 2, fin->fin_ifs); 4037c478bd9Sstevel@tonic-gate } 4047c478bd9Sstevel@tonic-gate 4057c478bd9Sstevel@tonic-gate 4067c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 4077c478bd9Sstevel@tonic-gate /* Function: ipllog */ 4087c478bd9Sstevel@tonic-gate /* Returns: int - 0 == success, -1 == failure */ 4097c478bd9Sstevel@tonic-gate /* Parameters: dev(I) - device that owns this log record */ 4107c478bd9Sstevel@tonic-gate /* fin(I) - pointer to packet information */ 4117c478bd9Sstevel@tonic-gate /* items(I) - array of pointers to log data */ 4127c478bd9Sstevel@tonic-gate /* itemsz(I) - array of size of valid memory pointed to */ 4137c478bd9Sstevel@tonic-gate /* types(I) - type of data pointed to by items pointers */ 4147c478bd9Sstevel@tonic-gate /* cnt(I) - number of elements in arrays items/itemsz/types */ 4157c478bd9Sstevel@tonic-gate /* */ 4167c478bd9Sstevel@tonic-gate /* Takes an array of parameters and constructs one record to include the */ 4177c478bd9Sstevel@tonic-gate /* miscellaneous packet information, as well as packet data, for reading */ 4187c478bd9Sstevel@tonic-gate /* from the log device. */ 4197c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 420f4b3ec61Sdh int ipllog(dev, fin, items, itemsz, types, cnt, ifs) 4217c478bd9Sstevel@tonic-gate int dev; 4227c478bd9Sstevel@tonic-gate fr_info_t *fin; 4237c478bd9Sstevel@tonic-gate void **items; 4247c478bd9Sstevel@tonic-gate size_t *itemsz; 4257c478bd9Sstevel@tonic-gate int *types, cnt; 426f4b3ec61Sdh ipf_stack_t *ifs; 4277c478bd9Sstevel@tonic-gate { 428ab25eeb5Syz caddr_t buf, ptr; 4297c478bd9Sstevel@tonic-gate iplog_t *ipl; 4307c478bd9Sstevel@tonic-gate size_t len; 4317c478bd9Sstevel@tonic-gate int i; 432ab25eeb5Syz SPL_INT(s); 433ab25eeb5Syz 4347c478bd9Sstevel@tonic-gate /* 4357c478bd9Sstevel@tonic-gate * Check to see if this log record has a CRC which matches the last 4367c478bd9Sstevel@tonic-gate * record logged. If it does, just up the count on the previous one 4377c478bd9Sstevel@tonic-gate * rather than create a new one. 4387c478bd9Sstevel@tonic-gate */ 439f4b3ec61Sdh if (ifs->ifs_ipl_suppress) { 440f4b3ec61Sdh MUTEX_ENTER(&ifs->ifs_ipl_mutex); 441ab25eeb5Syz if ((fin != NULL) && (fin->fin_off == 0)) { 442f4b3ec61Sdh if ((ifs->ifs_ipll[dev] != NULL) && 443f4b3ec61Sdh bcmp((char *)fin, (char *)&ifs->ifs_iplcrc[dev], 4447c478bd9Sstevel@tonic-gate FI_LCSIZE) == 0) { 445f4b3ec61Sdh ifs->ifs_ipll[dev]->ipl_count++; 446f4b3ec61Sdh MUTEX_EXIT(&ifs->ifs_ipl_mutex); 4477c478bd9Sstevel@tonic-gate return 0; 4487c478bd9Sstevel@tonic-gate } 449f4b3ec61Sdh bcopy((char *)fin, (char *)&ifs->ifs_iplcrc[dev], 450f4b3ec61Sdh FI_LCSIZE); 4517c478bd9Sstevel@tonic-gate } else 452f4b3ec61Sdh bzero((char *)&ifs->ifs_iplcrc[dev], FI_CSIZE); 453f4b3ec61Sdh MUTEX_EXIT(&ifs->ifs_ipl_mutex); 4547c478bd9Sstevel@tonic-gate } 4557c478bd9Sstevel@tonic-gate 4567c478bd9Sstevel@tonic-gate /* 4577c478bd9Sstevel@tonic-gate * Get the total amount of data to be logged. 4587c478bd9Sstevel@tonic-gate */ 4597c478bd9Sstevel@tonic-gate for (i = 0, len = sizeof(iplog_t); i < cnt; i++) 4607c478bd9Sstevel@tonic-gate len += itemsz[i]; 4617c478bd9Sstevel@tonic-gate 4627c478bd9Sstevel@tonic-gate /* 4637c478bd9Sstevel@tonic-gate * check that we have space to record this information and can 4647c478bd9Sstevel@tonic-gate * allocate that much. 4657c478bd9Sstevel@tonic-gate */ 466ab25eeb5Syz KMALLOCS(buf, caddr_t, len); 467ab25eeb5Syz if (buf == NULL) 468ab25eeb5Syz return -1; 469ab25eeb5Syz SPL_NET(s); 470f4b3ec61Sdh MUTEX_ENTER(&ifs->ifs_ipl_mutex); 471f4b3ec61Sdh if ((ifs->ifs_iplused[dev] + len) > IPFILTER_LOGSIZE) { 472f4b3ec61Sdh MUTEX_EXIT(&ifs->ifs_ipl_mutex); 473ab25eeb5Syz SPL_X(s); 474ab25eeb5Syz KFREES(buf, len); 475ab25eeb5Syz return -1; 4767c478bd9Sstevel@tonic-gate } 477f4b3ec61Sdh ifs->ifs_iplused[dev] += len; 478f4b3ec61Sdh MUTEX_EXIT(&ifs->ifs_ipl_mutex); 479ab25eeb5Syz SPL_X(s); 4807c478bd9Sstevel@tonic-gate 4817c478bd9Sstevel@tonic-gate /* 4827c478bd9Sstevel@tonic-gate * advance the log pointer to the next empty record and deduct the 4837c478bd9Sstevel@tonic-gate * amount of space we're going to use. 4847c478bd9Sstevel@tonic-gate */ 4857c478bd9Sstevel@tonic-gate ipl = (iplog_t *)buf; 486ab25eeb5Syz ipl->ipl_magic = ipl_magic[dev]; 4877c478bd9Sstevel@tonic-gate ipl->ipl_count = 1; 4887c478bd9Sstevel@tonic-gate ipl->ipl_next = NULL; 4897c478bd9Sstevel@tonic-gate ipl->ipl_dsize = len; 4907c478bd9Sstevel@tonic-gate #ifdef _KERNEL 4917c478bd9Sstevel@tonic-gate GETKTIME(&ipl->ipl_sec); 4927c478bd9Sstevel@tonic-gate #else 4937c478bd9Sstevel@tonic-gate ipl->ipl_sec = 0; 4947c478bd9Sstevel@tonic-gate ipl->ipl_usec = 0; 4957c478bd9Sstevel@tonic-gate #endif 4967c478bd9Sstevel@tonic-gate 4977c478bd9Sstevel@tonic-gate /* 4987c478bd9Sstevel@tonic-gate * Loop through all the items to be logged, copying each one to the 4997c478bd9Sstevel@tonic-gate * buffer. Use bcopy for normal data or the mb_t copyout routine. 5007c478bd9Sstevel@tonic-gate */ 501ab25eeb5Syz for (i = 0, ptr = buf + sizeof(*ipl); i < cnt; i++) { 5027c478bd9Sstevel@tonic-gate if (types[i] == 0) { 503ab25eeb5Syz bcopy(items[i], ptr, itemsz[i]); 5047c478bd9Sstevel@tonic-gate } else if (types[i] == 1) { 505ab25eeb5Syz COPYDATA(items[i], 0, itemsz[i], ptr); 5067c478bd9Sstevel@tonic-gate } 507ab25eeb5Syz ptr += itemsz[i]; 5087c478bd9Sstevel@tonic-gate } 509ab25eeb5Syz SPL_NET(s); 510f4b3ec61Sdh MUTEX_ENTER(&ifs->ifs_ipl_mutex); 511f4b3ec61Sdh ifs->ifs_ipll[dev] = ipl; 512f4b3ec61Sdh *ifs->ifs_iplh[dev] = ipl; 513f4b3ec61Sdh ifs->ifs_iplh[dev] = &ipl->ipl_next; 5147c478bd9Sstevel@tonic-gate 5157c478bd9Sstevel@tonic-gate /* 5167c478bd9Sstevel@tonic-gate * Now that the log record has been completed and added to the queue, 5177c478bd9Sstevel@tonic-gate * wake up any listeners who may want to read it. 5187c478bd9Sstevel@tonic-gate */ 519*af5f29ddSToomas Soome # if defined(SOLARIS) && defined(_KERNEL) 520f4b3ec61Sdh cv_signal(&ifs->ifs_iplwait); 521f4b3ec61Sdh MUTEX_EXIT(&ifs->ifs_ipl_mutex); 5227c478bd9Sstevel@tonic-gate # else 523f4b3ec61Sdh MUTEX_EXIT(&ifs->ifs_ipl_mutex); 524f4b3ec61Sdh WAKEUP(&ifs->ifs_iplh, dev); 5257c478bd9Sstevel@tonic-gate # endif 526ab25eeb5Syz SPL_X(s); 5277c478bd9Sstevel@tonic-gate # ifdef IPL_SELECT 5287c478bd9Sstevel@tonic-gate iplog_input_ready(dev); 5297c478bd9Sstevel@tonic-gate # endif 530ab25eeb5Syz return 0; 5317c478bd9Sstevel@tonic-gate } 5327c478bd9Sstevel@tonic-gate 5337c478bd9Sstevel@tonic-gate 5347c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 5357c478bd9Sstevel@tonic-gate /* Function: ipflog_read */ 5367c478bd9Sstevel@tonic-gate /* Returns: int - 0 == success, else error value. */ 5377c478bd9Sstevel@tonic-gate /* Parameters: unit(I) - device we are reading from */ 5387c478bd9Sstevel@tonic-gate /* uio(O) - pointer to information about where to store data */ 5397c478bd9Sstevel@tonic-gate /* */ 5407c478bd9Sstevel@tonic-gate /* Called to handle a read on an IPFilter device. Returns only complete */ 5417c478bd9Sstevel@tonic-gate /* log messages - will not partially copy a log record out to userland. */ 5427c478bd9Sstevel@tonic-gate /* */ 5437c478bd9Sstevel@tonic-gate /* NOTE: This function will block and wait for a signal to return data if */ 5447c478bd9Sstevel@tonic-gate /* there is none present. Asynchronous I/O is not implemented. */ 5457c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 546f4b3ec61Sdh int ipflog_read(unit, uio, ifs) 5477c478bd9Sstevel@tonic-gate minor_t unit; 5487c478bd9Sstevel@tonic-gate struct uio *uio; 549f4b3ec61Sdh ipf_stack_t *ifs; 5507c478bd9Sstevel@tonic-gate { 5517c478bd9Sstevel@tonic-gate size_t dlen, copied; 5527c478bd9Sstevel@tonic-gate int error = 0; 5537c478bd9Sstevel@tonic-gate iplog_t *ipl; 554ab25eeb5Syz SPL_INT(s); 5557c478bd9Sstevel@tonic-gate 5567c478bd9Sstevel@tonic-gate /* 5577c478bd9Sstevel@tonic-gate * Sanity checks. Make sure the minor # is valid and we're copying 5587c478bd9Sstevel@tonic-gate * a valid chunk of data. 5597c478bd9Sstevel@tonic-gate */ 5607c478bd9Sstevel@tonic-gate if (IPL_LOGMAX < unit) 5617c478bd9Sstevel@tonic-gate return ENXIO; 5627c478bd9Sstevel@tonic-gate if (uio->uio_resid == 0) 5637c478bd9Sstevel@tonic-gate return 0; 5647c478bd9Sstevel@tonic-gate if ((uio->uio_resid < sizeof(iplog_t)) || 565f4b3ec61Sdh (uio->uio_resid > ifs->ifs_ipl_logsize)) 5667c478bd9Sstevel@tonic-gate return EINVAL; 567ab25eeb5Syz 5687c478bd9Sstevel@tonic-gate /* 5697c478bd9Sstevel@tonic-gate * Lock the log so we can snapshot the variables. Wait for a signal 5707c478bd9Sstevel@tonic-gate * if the log is empty. 5717c478bd9Sstevel@tonic-gate */ 5727c478bd9Sstevel@tonic-gate SPL_NET(s); 573f4b3ec61Sdh MUTEX_ENTER(&ifs->ifs_ipl_mutex); 5747c478bd9Sstevel@tonic-gate 575f4b3ec61Sdh while (ifs->ifs_iplt[unit] == NULL) { 576*af5f29ddSToomas Soome # if defined(SOLARIS) && defined(_KERNEL) 57794bdecd9SRob Gulewich /* 57894bdecd9SRob Gulewich * Prevent a deadlock with ipldetach() - see the "ipfilter 57994bdecd9SRob Gulewich * kernel module mutexes and locking" comment block in solaris.c 58094bdecd9SRob Gulewich * for details. 58194bdecd9SRob Gulewich */ 58294bdecd9SRob Gulewich RWLOCK_EXIT(&ifs->ifs_ipf_global); 583f4b3ec61Sdh if (!cv_wait_sig(&ifs->ifs_iplwait, &ifs->ifs_ipl_mutex.ipf_lk)) { 58494bdecd9SRob Gulewich READ_ENTER(&ifs->ifs_ipf_global); 585f4b3ec61Sdh MUTEX_EXIT(&ifs->ifs_ipl_mutex); 5867c478bd9Sstevel@tonic-gate return EINTR; 5877c478bd9Sstevel@tonic-gate } 58894bdecd9SRob Gulewich READ_ENTER(&ifs->ifs_ipf_global); 5897c478bd9Sstevel@tonic-gate # else 5907c478bd9Sstevel@tonic-gate # if defined(__hpux) && defined(_KERNEL) 5917c478bd9Sstevel@tonic-gate lock_t *l; 5927c478bd9Sstevel@tonic-gate 5937c478bd9Sstevel@tonic-gate # ifdef IPL_SELECT 5947c478bd9Sstevel@tonic-gate if (uio->uio_fpflags & (FNBLOCK|FNDELAY)) { 5957c478bd9Sstevel@tonic-gate /* this is no blocking system call */ 596f4b3ec61Sdh MUTEX_EXIT(&ifs->ifs_ipl_mutex); 5977c478bd9Sstevel@tonic-gate return 0; 5987c478bd9Sstevel@tonic-gate } 5997c478bd9Sstevel@tonic-gate # endif 6007c478bd9Sstevel@tonic-gate 601f4b3ec61Sdh MUTEX_EXIT(&ifs->ifs_ipl_mutex); 602f4b3ec61Sdh l = get_sleep_lock(&ifs->ifs_iplh[unit]); 603f4b3ec61Sdh error = sleep(&ifs->ifs_iplh[unit], PZERO+1); 6047c478bd9Sstevel@tonic-gate spinunlock(l); 6057c478bd9Sstevel@tonic-gate # else 6067c478bd9Sstevel@tonic-gate # if defined(__osf__) && defined(_KERNEL) 607f4b3ec61Sdh error = mpsleep(&ifs->ifs_iplh[unit], PSUSP|PCATCH, "iplread", 0, 608f4b3ec61Sdh &ifs->ifs_ipl_mutex, MS_LOCK_SIMPLE); 6097c478bd9Sstevel@tonic-gate # else 610f4b3ec61Sdh MUTEX_EXIT(&ifs->ifs_ipl_mutex); 6117c478bd9Sstevel@tonic-gate SPL_X(s); 612f4b3ec61Sdh error = SLEEP(&ifs->ifs_iplh[unit], "ipl sleep"); 6137c478bd9Sstevel@tonic-gate # endif /* __osf__ */ 6147c478bd9Sstevel@tonic-gate # endif /* __hpux */ 6157c478bd9Sstevel@tonic-gate if (error) 6167c478bd9Sstevel@tonic-gate return error; 6177c478bd9Sstevel@tonic-gate SPL_NET(s); 618f4b3ec61Sdh MUTEX_ENTER(&ifs->ifs_ipl_mutex); 6197c478bd9Sstevel@tonic-gate # endif /* SOLARIS */ 6207c478bd9Sstevel@tonic-gate } 6217c478bd9Sstevel@tonic-gate 6227c478bd9Sstevel@tonic-gate # if (BSD >= 199101) || defined(__FreeBSD__) || defined(__osf__) 6237c478bd9Sstevel@tonic-gate uio->uio_rw = UIO_READ; 6247c478bd9Sstevel@tonic-gate # endif 6257c478bd9Sstevel@tonic-gate 626f4b3ec61Sdh for (copied = 0; ((ipl = ifs->ifs_iplt[unit]) != NULL); copied += dlen) { 6277c478bd9Sstevel@tonic-gate dlen = ipl->ipl_dsize; 6287c478bd9Sstevel@tonic-gate if (dlen > uio->uio_resid) 6297c478bd9Sstevel@tonic-gate break; 6307c478bd9Sstevel@tonic-gate /* 6317c478bd9Sstevel@tonic-gate * Don't hold the mutex over the uiomove call. 6327c478bd9Sstevel@tonic-gate */ 633f4b3ec61Sdh ifs->ifs_iplt[unit] = ipl->ipl_next; 634f4b3ec61Sdh ifs->ifs_iplused[unit] -= dlen; 635f4b3ec61Sdh if (ifs->ifs_iplt[unit] == NULL) { 636f4b3ec61Sdh ifs->ifs_iplh[unit] = &ifs->ifs_iplt[unit]; 637f4b3ec61Sdh ifs->ifs_ipll[unit] = NULL; 638381a2a9aSdr } 639f4b3ec61Sdh MUTEX_EXIT(&ifs->ifs_ipl_mutex); 6407c478bd9Sstevel@tonic-gate SPL_X(s); 6417c478bd9Sstevel@tonic-gate error = UIOMOVE((caddr_t)ipl, dlen, UIO_READ, uio); 6427c478bd9Sstevel@tonic-gate if (error) { 6437c478bd9Sstevel@tonic-gate SPL_NET(s); 644f4b3ec61Sdh MUTEX_ENTER(&ifs->ifs_ipl_mutex); 645f4b3ec61Sdh ifs->ifs_iplused[unit] += dlen; 646f4b3ec61Sdh ipl->ipl_next = ifs->ifs_iplt[unit]; 647f4b3ec61Sdh ifs->ifs_iplt[unit] = ipl; 648f4b3ec61Sdh ifs->ifs_ipll[unit] = ipl; 649f4b3ec61Sdh if (ifs->ifs_iplh[unit] == &ifs->ifs_iplt[unit]) { 650f4b3ec61Sdh *ifs->ifs_iplh[unit] = ipl; 651f4b3ec61Sdh ifs->ifs_iplh[unit] = &ipl->ipl_next; 652381a2a9aSdr } 6537c478bd9Sstevel@tonic-gate break; 6547c478bd9Sstevel@tonic-gate } 655f4b3ec61Sdh MUTEX_ENTER(&ifs->ifs_ipl_mutex); 6567c478bd9Sstevel@tonic-gate KFREES((caddr_t)ipl, dlen); 6577c478bd9Sstevel@tonic-gate SPL_NET(s); 6587c478bd9Sstevel@tonic-gate } 659ab25eeb5Syz 660f4b3ec61Sdh MUTEX_EXIT(&ifs->ifs_ipl_mutex); 6617c478bd9Sstevel@tonic-gate SPL_X(s); 6627c478bd9Sstevel@tonic-gate return error; 6637c478bd9Sstevel@tonic-gate } 6647c478bd9Sstevel@tonic-gate 6657c478bd9Sstevel@tonic-gate 6667c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 6677c478bd9Sstevel@tonic-gate /* Function: ipflog_clear */ 6687c478bd9Sstevel@tonic-gate /* Returns: int - number of log bytes cleared. */ 6697c478bd9Sstevel@tonic-gate /* Parameters: unit(I) - device we are reading from */ 6707c478bd9Sstevel@tonic-gate /* */ 6717c478bd9Sstevel@tonic-gate /* Deletes all queued up log records for a given output device. */ 6727c478bd9Sstevel@tonic-gate /* ------------------------------------------------------------------------ */ 673f4b3ec61Sdh int ipflog_clear(unit, ifs) 6747c478bd9Sstevel@tonic-gate minor_t unit; 675f4b3ec61Sdh ipf_stack_t *ifs; 6767c478bd9Sstevel@tonic-gate { 6777c478bd9Sstevel@tonic-gate iplog_t *ipl; 6787c478bd9Sstevel@tonic-gate int used; 679ab25eeb5Syz SPL_INT(s); 6807c478bd9Sstevel@tonic-gate 681ab25eeb5Syz SPL_NET(s); 682f4b3ec61Sdh MUTEX_ENTER(&ifs->ifs_ipl_mutex); 683f4b3ec61Sdh while ((ipl = ifs->ifs_iplt[unit]) != NULL) { 684f4b3ec61Sdh ifs->ifs_iplt[unit] = ipl->ipl_next; 6857c478bd9Sstevel@tonic-gate KFREES((caddr_t)ipl, ipl->ipl_dsize); 6867c478bd9Sstevel@tonic-gate } 687f4b3ec61Sdh ifs->ifs_iplh[unit] = &ifs->ifs_iplt[unit]; 688f4b3ec61Sdh ifs->ifs_ipll[unit] = NULL; 689f4b3ec61Sdh used = ifs->ifs_iplused[unit]; 690f4b3ec61Sdh ifs->ifs_iplused[unit] = 0; 691f4b3ec61Sdh bzero((char *)&ifs->ifs_iplcrc[unit], FI_CSIZE); 692f4b3ec61Sdh MUTEX_EXIT(&ifs->ifs_ipl_mutex); 693ab25eeb5Syz SPL_X(s); 6947c478bd9Sstevel@tonic-gate return used; 6957c478bd9Sstevel@tonic-gate } 6967c478bd9Sstevel@tonic-gate #endif /* IPFILTER_LOG */ 697