diff options
Diffstat (limited to 'sys/contrib/ipfilter/netinet/fil.c')
-rw-r--r-- | sys/contrib/ipfilter/netinet/fil.c | 286 |
1 files changed, 163 insertions, 123 deletions
diff --git a/sys/contrib/ipfilter/netinet/fil.c b/sys/contrib/ipfilter/netinet/fil.c index e2b6e92895d9..3183dd1fb852 100644 --- a/sys/contrib/ipfilter/netinet/fil.c +++ b/sys/contrib/ipfilter/netinet/fil.c @@ -80,7 +80,7 @@ struct file; #ifdef sun # include <net/af.h> #endif -#if !defined(_KERNEL) && defined(__FreeBSD__) +#if !defined(_KERNEL) && (defined(__FreeBSD__) || defined(SOLARIS2)) # if (__FreeBSD_version >= 504000) # undef _RADIX_H_ # endif @@ -151,7 +151,7 @@ struct file; #if !defined(lint) static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: fil.c,v 2.243.2.109 2007/05/31 12:27:33 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: fil.c,v 2.243.2.125 2007/10/10 09:27:20 darrenr Exp $"; #endif #ifndef _KERNEL @@ -357,7 +357,7 @@ static INLINE int frpr_hopopts6 __P((fr_info_t *)); static INLINE int frpr_mobility6 __P((fr_info_t *)); static INLINE int frpr_routing6 __P((fr_info_t *)); static INLINE int frpr_dstopts6 __P((fr_info_t *)); -static INLINE void frpr_fragment6 __P((fr_info_t *)); +static INLINE int frpr_fragment6 __P((fr_info_t *)); static INLINE int frpr_ipv6exthdr __P((fr_info_t *, int, int)); @@ -475,8 +475,9 @@ fr_info_t *fin; break; case IPPROTO_FRAGMENT : - frpr_fragment6(fin); - go = 0; + p = frpr_fragment6(fin); + if (fin->fin_off != 0) + go = 0; break; default : @@ -647,7 +648,7 @@ fr_info_t *fin; /* ------------------------------------------------------------------------ */ /* Function: frpr_fragment6 */ -/* Returns: void */ +/* Returns: int - value of the next header or IPPROTO_NONE if error */ /* Parameters: fin(I) - pointer to packet information */ /* */ /* IPv6 Only */ @@ -659,7 +660,7 @@ fr_info_t *fin; /* upper layer header has been seen (or where it ends) and thus we are not */ /* able to continue processing beyond this header with any confidence. */ /* ------------------------------------------------------------------------ */ -static INLINE void frpr_fragment6(fin) +static INLINE int frpr_fragment6(fin) fr_info_t *fin; { struct ip6_frag *frag; @@ -668,12 +669,12 @@ fr_info_t *fin; fin->fin_flx |= FI_FRAG; if (frpr_ipv6exthdr(fin, 0, IPPROTO_FRAGMENT) == IPPROTO_NONE) - return; + return IPPROTO_NONE; extoff = (char *)fin->fin_exthdr - (char *)fin->fin_dp; if (frpr_pullup(fin, sizeof(*frag)) == -1) - return; + return IPPROTO_NONE; fin->fin_exthdr = (char *)fin->fin_dp + extoff; frag = fin->fin_exthdr; @@ -682,16 +683,18 @@ fr_info_t *fin; */ if (frag->ip6f_offlg == 0) { fin->fin_flx |= FI_BAD; - return; + return IPPROTO_NONE; } - fin->fin_off = frag->ip6f_offlg & IP6F_OFF_MASK; + fin->fin_off = ntohs(frag->ip6f_offlg & IP6F_OFF_MASK); fin->fin_off <<= 3; if (fin->fin_off != 0) fin->fin_flx |= FI_FRAGBODY; fin->fin_dp = (char *)fin->fin_dp + sizeof(*frag); fin->fin_dlen -= sizeof(*frag); + + return frag->ip6f_nxt; } @@ -747,26 +750,26 @@ fr_info_t *fin; case ICMP6_TIME_EXCEEDED : case ICMP6_PARAM_PROB : fin->fin_flx |= FI_ICMPERR; - if ((fin->fin_m != NULL) && - (M_LEN(fin->fin_m) < fin->fin_plen)) { + minicmpsz = ICMP6ERR_IPICMPHLEN - sizeof(ip6_t); + if (fin->fin_plen < ICMP6ERR_IPICMPHLEN) + break; + + if (M_LEN(fin->fin_m) < fin->fin_plen) { if (fr_coalesce(fin) != 1) return; } - if (frpr_pullup(fin, ICMP6ERR_MINPKTLEN) == -1) - return; - /* * If the destination of this packet doesn't match the * source of the original packet then this packet is * not correct. */ + icmp6 = fin->fin_dp; ip6 = (ip6_t *)((char *)icmp6 + ICMPERR_ICMPHLEN); if (IP6_NEQ(&fin->fin_fi.fi_dst, (i6addr_t *)&ip6->ip6_src)) fin->fin_flx |= FI_BAD; - minicmpsz = ICMP6ERR_IPICMPHLEN - sizeof(ip6_t); break; default : break; @@ -907,6 +910,14 @@ fr_info_t *fin; /* Short inline function to cut down on code duplication to perform a call */ /* to fr_pullup to ensure there is the required amount of data, */ /* consecutively in the packet buffer. */ +/* */ +/* This function pulls up 'extra' data at the location of fin_dp. fin_dp */ +/* points to the first byte after the complete layer 3 header, which will */ +/* include all of the known extension headers for IPv6 or options for IPv4. */ +/* */ +/* Since fr_pullup() expects the total length of bytes to be pulled up, it */ +/* is necessary to add those we can already assume to be pulled up (fin_dp */ +/* - fin_ip) to what is passed through. */ /* ------------------------------------------------------------------------ */ static INLINE int frpr_pullup(fin, plen) fr_info_t *fin; @@ -995,6 +1006,9 @@ fr_info_t *fin; fin->fin_data[0] = *(u_short *)icmp; + if (fin->fin_dlen >= 6) /* ID field */ + fin->fin_data[1] = icmp->icmp_id; + switch (icmp->icmp_type) { case ICMP_ECHOREPLY : @@ -1065,14 +1079,12 @@ fr_info_t *fin; default : break; } - - if (fin->fin_dlen >= 6) /* ID field */ - fin->fin_data[1] = icmp->icmp_id; } frpr_short(fin, minicmpsz); - fr_checkv4sum(fin); + if ((fin->fin_flx & FI_FRAG) == 0) + fr_checkv4sum(fin); } @@ -1188,6 +1200,7 @@ fr_info_t *fin; return -1; #if 0 + tcp = fin->fin_dp; ip = fin->fin_ip; s = (u_char *)(tcp + 1); off = IP_HL(ip) << 2; @@ -1275,8 +1288,10 @@ fr_info_t *fin; frpr_short(fin, sizeof(tcphdr_t)); - if (frpr_tcpcommon(fin) == 0) - fr_checkv4sum(fin); + if (frpr_tcpcommon(fin) == 0) { + if ((fin->fin_flx & FI_FRAG) == 0) + fr_checkv4sum(fin); + } } @@ -1294,8 +1309,10 @@ fr_info_t *fin; frpr_short(fin, sizeof(udphdr_t)); - if (frpr_udpcommon(fin) == 0) - fr_checkv4sum(fin); + if (frpr_udpcommon(fin) == 0) { + if ((fin->fin_flx & FI_FRAG) == 0) + fr_checkv4sum(fin); + } } @@ -1945,7 +1962,7 @@ int fr_scanlist(fin, pass) fr_info_t *fin; u_32_t pass; { - int rulen, portcmp, off, logged, skip; + int rulen, portcmp, off, skip; struct frentry *fr, *fnext; u_32_t passt, passo; @@ -1964,7 +1981,6 @@ u_32_t pass; return pass; skip = 0; - logged = 0; portcmp = 0; fin->fin_depth++; fin->fin_fr = NULL; @@ -2098,7 +2114,7 @@ u_32_t pass; ATOMIC_INCL(frstats[fin->fin_out].fr_skip); } ATOMIC_INCL(frstats[fin->fin_out].fr_pkl); - logged = 1; + fin->fin_flx |= FI_DONTCACHE; } #endif /* IPFILTER_LOG */ fr->fr_bytes += (U_QUAD_T)fin->fin_plen; @@ -2123,8 +2139,6 @@ u_32_t pass; fin->fin_fr = fr; passt = pass; } - if (fin->fin_flx & FI_DONTCACHE) - logged = 1; pass = passt; } @@ -2152,8 +2166,6 @@ u_32_t pass; break; } } - if (logged) - fin->fin_flx |= FI_DONTCACHE; fin->fin_depth--; return pass; } @@ -2404,8 +2416,10 @@ int out; # ifdef MENTAT qpktinfo_t *qpi = qif; +# if !defined(_INET_IP_STACK_H) if ((u_int)ip & 0x3) return 2; +# endif # else SPL_INT(s); # endif @@ -2558,11 +2572,20 @@ int out; if (!out) (void) fr_acctpkt(fin, NULL); - if (fr == NULL) - if ((fin->fin_flx & (FI_FRAG|FI_BAD)) == FI_FRAG) + if (fr == NULL) { + if ((fin->fin_flx & (FI_FRAG|FI_BAD)) == FI_FRAG) { fr = fr_knownfrag(fin, &pass); - if (fr == NULL) - fr = fr_checkstate(fin, &pass); + /* + * Reset the keep state flag here so that we don't + * try and add a new state entry because of it, leading + * to a blocked packet because the add will fail. + */ + if (fr != NULL) + pass &= ~FR_KEEPSTATE; + } + if (fr == NULL) + fr = fr_checkstate(fin, &pass); + } if ((pass & FR_NOMATCH) || (fr == NULL)) fr = fr_firewall(fin, &pass); @@ -2625,7 +2648,14 @@ filterdone: } if (fin->fin_nat != NULL) { - fr_natderef((nat_t **)&fin->fin_nat); + if (FR_ISBLOCK(pass) && (fin->fin_flx & FI_NEWNAT)) { + WRITE_ENTER(&ipf_nat); + nat_delete((nat_t *)fin->fin_nat, NL_DESTROY); + RWLOCK_EXIT(&ipf_nat); + fin->fin_nat = NULL; + } else { + fr_natderef((nat_t **)&fin->fin_nat); + } } /* @@ -3065,8 +3095,8 @@ void *l4hdr; * 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; + if ((char *)ip != mtod(m, char *)) { + hlen = (char *)sp - (char *)ip; while (hlen) { add = MIN(hlen, m->m_len); sp = (u_short *)(mtod(m, caddr_t) + add); @@ -3089,12 +3119,12 @@ void *l4hdr; goto nodata; while (len > 1) { - if (((caddr_t)sp - mtod(m, caddr_t)) >= m->m_len) { + if (((char *)sp - mtod(m, char *)) >= m->m_len) { m = m->m_next; PANIC((!m),("fr_cksum(2): not enough data")); sp = mtod(m, u_short *); } - if (((caddr_t)(sp + 1) - mtod(m, caddr_t)) > m->m_len) { + if (((char *)(sp + 1) - mtod(m, char *)) > m->m_len) { bytes.c[0] = *(u_char *)sp; m = m->m_next; PANIC((!m),("fr_cksum(3): not enough data")); @@ -3172,7 +3202,7 @@ nodata: * SUCH DAMAGE. * * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 - * $Id: fil.c,v 2.243.2.109 2007/05/31 12:27:33 darrenr Exp $ + * $Id: fil.c,v 2.243.2.125 2007/10/10 09:27:20 darrenr Exp $ */ /* * Copy data from an mbuf chain starting "off" bytes from the beginning, @@ -3478,7 +3508,7 @@ minor_t unit; int *nfreedp; frentry_t **listp; { - int freed = 0, i; + int freed = 0; frentry_t *fp; while ((fp = *listp) != NULL) { @@ -3489,8 +3519,7 @@ frentry_t **listp; } *listp = fp->fr_next; if (fp->fr_grp != NULL) { - i = frflushlist(set, unit, nfreedp, fp->fr_grp); - fp->fr_ref -= i; + (void) frflushlist(set, unit, nfreedp, fp->fr_grp); } if (fp->fr_grhead != NULL) { @@ -3846,7 +3875,7 @@ size_t size; int error; # if SOLARIS - error = COPYIN(src, (caddr_t)&ca, sizeof(ca)); + error = COPYIN(src, &ca, sizeof(ca)); if (error != 0) return error; # else @@ -3888,22 +3917,27 @@ size_t size; /* ------------------------------------------------------------------------ */ /* Function: fr_lock */ -/* Returns: (void) */ +/* Returns: int - 0 = success, else error */ /* Parameters: data(I) - pointer to lock value to set */ /* lockp(O) - pointer to location to store old lock value */ /* */ /* Get the new value for the lock integer, set it and return the old value */ /* in *lockp. */ /* ------------------------------------------------------------------------ */ -void fr_lock(data, lockp) +int fr_lock(data, lockp) caddr_t data; int *lockp; { - int arg; + int arg, err; - BCOPYIN(data, (caddr_t)&arg, sizeof(arg)); - BCOPYOUT((caddr_t)lockp, data, sizeof(*lockp)); + err = BCOPYIN(data, &arg, sizeof(arg)); + if (err != 0) + return EFAULT; + err = BCOPYOUT(lockp, data, sizeof(*lockp)); + if (err != 0) + return EFAULT; *lockp = arg; + return 0; } @@ -4542,7 +4576,7 @@ caddr_t data; /* * Return EBUSY if the rule is being reference by - * something else (eg state information. + * something else (eg state information.) */ if (f->fr_ref > 1) { error = EBUSY; @@ -4553,8 +4587,6 @@ caddr_t data; (f->fr_isc != (struct ipscan *)-1)) ipsc_detachfr(f); #endif - if ((fg != NULL) && (fg->fg_head != NULL)) - fg->fg_head->fr_ref--; if (unit == IPL_LOGAUTH) { error = fr_preauthcmd(req, f, ftail); goto done; @@ -4582,8 +4614,6 @@ caddr_t data; } else f = fp; if (f != NULL) { - if (fg != NULL && fg->fg_head != NULL) - fg->fg_head->fr_ref++; if (fp != f) bcopy((char *)fp, (char *)f, sizeof(*f)); @@ -4683,8 +4713,11 @@ int fr_resolvefunc(data) void *data; { ipfunc_resolve_t res, *ft; + int err; - BCOPYIN(data, &res, sizeof(res)); + err = BCOPYIN(data, &res, sizeof(res)); + if (err != 0) + return EFAULT; if (res.ipfu_addr == NULL && res.ipfu_name[0] != '\0') { for (ft = fr_availfuncs; ft->ipfu_addr != NULL; ft++) @@ -5453,7 +5486,9 @@ int type; if ((type < 0) || (type >= IPFOBJ_COUNT)) return EINVAL; - BCOPYIN((caddr_t)data, (caddr_t)&obj, sizeof(obj)); + error = BCOPYIN(data, &obj, sizeof(obj)); + if (error != 0) + return EFAULT; if (obj.ipfo_type != type) return EINVAL; @@ -5479,11 +5514,9 @@ int type; #endif if ((fr_objbytes[type][0] & 1) != 0) { - error = COPYIN((caddr_t)obj.ipfo_ptr, (caddr_t)ptr, - fr_objbytes[type][1]); + error = COPYIN(obj.ipfo_ptr, ptr, fr_objbytes[type][1]); } else { - error = COPYIN((caddr_t)obj.ipfo_ptr, (caddr_t)ptr, - obj.ipfo_size); + error = COPYIN(obj.ipfo_ptr, ptr, obj.ipfo_size); } if (error != 0) error = EFAULT; @@ -5518,7 +5551,9 @@ int type, sz; if (((fr_objbytes[type][0] & 1) == 0) || (sz < fr_objbytes[type][1])) return EINVAL; - BCOPYIN((caddr_t)data, (caddr_t)&obj, sizeof(obj)); + error = BCOPYIN(data, &obj, sizeof(obj)); + if (error != 0) + return EFAULT; if (obj.ipfo_type != type) return EINVAL; @@ -5535,7 +5570,7 @@ int type, sz; return EINVAL; #endif - error = COPYIN((caddr_t)obj.ipfo_ptr, (caddr_t)ptr, sz); + error = COPYIN(obj.ipfo_ptr, ptr, sz); if (error != 0) error = EFAULT; return error; @@ -5564,12 +5599,14 @@ int type, sz; ipfobj_t obj; int error; - if ((type < 0) || (type > IPFOBJ_COUNT) || + if ((type < 0) || (type >= IPFOBJ_COUNT) || ((fr_objbytes[type][0] & 1) == 0) || (sz < fr_objbytes[type][1])) return EINVAL; - BCOPYIN((caddr_t)data, (caddr_t)&obj, sizeof(obj)); + error = BCOPYIN(data, &obj, sizeof(obj)); + if (error != 0) + return EFAULT; if (obj.ipfo_type != type) return EINVAL; @@ -5586,7 +5623,7 @@ int type, sz; return EINVAL; #endif - error = COPYOUT((caddr_t)ptr, (caddr_t)obj.ipfo_ptr, sz); + error = COPYOUT(ptr, obj.ipfo_ptr, sz); if (error != 0) error = EFAULT; return error; @@ -5612,10 +5649,12 @@ int type; ipfobj_t obj; int error; - if ((type < 0) || (type > IPFOBJ_COUNT)) + if ((type < 0) || (type >= IPFOBJ_COUNT)) return EINVAL; - BCOPYIN((caddr_t)data, (caddr_t)&obj, sizeof(obj)); + error = BCOPYIN(data, &obj, sizeof(obj)); + if (error != 0) + return EFAULT; if (obj.ipfo_type != type) return EINVAL; @@ -5639,7 +5678,7 @@ int type; return EINVAL; #endif - error = COPYOUT((caddr_t)ptr, (caddr_t)obj.ipfo_ptr, obj.ipfo_size); + error = COPYOUT(ptr, obj.ipfo_ptr, obj.ipfo_size); if (error != 0) error = EFAULT; return error; @@ -5665,6 +5704,12 @@ fr_info_t *fin; if ((fin->fin_flx & FI_NOCKSUM) != 0) return 0; + if (fin->fin_cksum == 1) + return 0; + + if (fin->fin_cksum == -1) + return -1; + /* * If the TCP packet isn't a fragment, isn't too short and otherwise * isn't already considered "bad", then validate the checksum. If @@ -5727,8 +5772,11 @@ fr_info_t *fin; FR_DEBUG(("checkl4sum: %hx != %hx\n", sum, hdrsum)); } #endif - if (hdrsum == sum) + if (hdrsum == sum) { + fin->fin_cksum = 1; return 0; + } + fin->fin_cksum = -1; return -1; } @@ -5981,7 +6029,7 @@ ipftuneable_t ipf_tuneables[] = { { { &ipf_hostmap_sz }, "ipf_hostmap_sz", 1, 0x7fffffff, sizeof(ipf_hostmap_sz), IPFT_WRDISABLED, NULL }, { { &fr_nat_maxbucket }, "fr_nat_maxbucket", 1, 0x7fffffff, - sizeof(fr_nat_maxbucket), IPFT_WRDISABLED, NULL }, + sizeof(fr_nat_maxbucket), 0, NULL }, { { &fr_nat_maxbucket_reset }, "fr_nat_maxbucket_reset", 0, 1, sizeof(fr_nat_maxbucket_reset), IPFT_WRDISABLED, NULL }, { { &nat_logging }, "nat_logging", 0, 1, @@ -6424,7 +6472,7 @@ void fr_deinitialise() /* the copyout may result in paging (ie network activity.) */ /* ------------------------------------------------------------------------ */ int fr_zerostats(data) -caddr_t data; +void *data; { friostat_t fio; int error; @@ -6530,15 +6578,12 @@ ipftoken_t *ipftokenhead = NULL, **ipftokentail = &ipftokenhead; void ipf_expiretokens() { ipftoken_t *it; - void *data; WRITE_ENTER(&ipf_tokens); while ((it = ipftokenhead) != NULL) { if (it->ipt_die > fr_ticks) break; - data = it->ipt_data; - ipf_freetoken(it); } RWLOCK_EXIT(&ipf_tokens); @@ -6715,7 +6760,9 @@ ipftoken_t *token; #endif break; case IPFGENITER_HOSTMAP : + WRITE_ENTER(&ipf_nat); fr_hostmapdel((hostmap_t **)datap); + RWLOCK_EXIT(&ipf_nat); break; default : #ifdef IPFILTER_LOOKUP @@ -6794,30 +6841,27 @@ int ipf_getnextrule(ipftoken_t *t, void *ptr) } dst = (char *)it.iri_rule; + count = it.iri_nrules; /* * The ipfruleiter may ask for more than 1 rule at a time to be * copied out, so long as that many exist in the list to start with! */ - for (count = it.iri_nrules; count > 0; count--) { + for (;;) { if (next != NULL) { - MUTEX_ENTER(&next->fr_lock); - next->fr_ref++; - MUTEX_EXIT(&next->fr_lock); - t->ipt_data = next; + if (count == 1) { + MUTEX_ENTER(&next->fr_lock); + next->fr_ref++; + MUTEX_EXIT(&next->fr_lock); + t->ipt_data = next; + } } else { bzero(&zero, sizeof(zero)); next = &zero; - ipf_freetoken(t); - fr = NULL; - t = NULL; count = 1; + t->ipt_data = NULL; } RWLOCK_EXIT(&ipf_mutex); - if (fr != NULL) { - (void) fr_derefrule(&fr); - } - error = COPYOUT(next, dst, sizeof(*next)); if (error != 0) return EFAULT; @@ -6831,12 +6875,17 @@ int ipf_getnextrule(ipftoken_t *t, void *ptr) dst += next->fr_dsize; } - if ((count == 1) || (next->fr_next == NULL) || (error != 0)) + if ((count == 1) || (error != 0)) break; + count--; + READ_ENTER(&ipf_mutex); - fr = next; - next = fr->fr_next; + next = next->fr_next; + } + + if (fr != NULL) { + (void) fr_derefrule(&fr); } return error; @@ -6964,8 +7013,7 @@ void *ctx; if (!(mode & FWRITE)) error = EPERM; else { - error = BCOPYIN((caddr_t)data, (caddr_t)&tmp, - sizeof(tmp)); + error = BCOPYIN(data, &tmp, sizeof(tmp)); if (error != 0) { error = EFAULT; break; @@ -7005,16 +7053,14 @@ void *ctx; if (!(mode & FWRITE)) error = EPERM; else { - error = BCOPYIN((caddr_t)data, (caddr_t)&fr_flags, - sizeof(fr_flags)); + error = BCOPYIN(data, &fr_flags, sizeof(fr_flags)); if (error != 0) error = EFAULT; } break; case SIOCGETFF : - error = BCOPYOUT((caddr_t)&fr_flags, (caddr_t)data, - sizeof(fr_flags)); + error = BCOPYOUT(&fr_flags, data, sizeof(fr_flags)); if (error != 0) error = EFAULT; break; @@ -7030,8 +7076,7 @@ void *ctx; if (!(mode & FWRITE)) error = EPERM; else - error = frrequest(IPL_LOGIPF, cmd, (caddr_t)data, - fr_active, 1); + error = frrequest(IPL_LOGIPF, cmd, data, fr_active, 1); break; case SIOCINIFR : @@ -7040,7 +7085,7 @@ void *ctx; if (!(mode & FWRITE)) error = EPERM; else - error = frrequest(IPL_LOGIPF, cmd, (caddr_t)data, + error = frrequest(IPL_LOGIPF, cmd, data, 1 - fr_active, 1); break; @@ -7050,8 +7095,7 @@ void *ctx; else { WRITE_ENTER(&ipf_mutex); bzero((char *)frcache, sizeof(frcache[0]) * 2); - error = BCOPYOUT((caddr_t)&fr_active, (caddr_t)data, - sizeof(fr_active)); + error = BCOPYOUT(&fr_active, data, sizeof(fr_active)); if (error != 0) error = EFAULT; else @@ -7069,19 +7113,17 @@ void *ctx; if (!(mode & FWRITE)) error = EPERM; else - error = fr_zerostats((caddr_t)data); + error = fr_zerostats(data); break; case SIOCIPFFL : if (!(mode & FWRITE)) error = EPERM; else { - error = BCOPYIN((caddr_t)data, (caddr_t)&tmp, - sizeof(tmp)); + error = BCOPYIN(data, &tmp, sizeof(tmp)); if (!error) { tmp = frflush(IPL_LOGIPF, 4, tmp); - error = BCOPYOUT((caddr_t)&tmp, (caddr_t)data, - sizeof(tmp)); + error = BCOPYOUT(&tmp, data, sizeof(tmp)); if (error != 0) error = EFAULT; } else @@ -7094,12 +7136,10 @@ void *ctx; if (!(mode & FWRITE)) error = EPERM; else { - error = BCOPYIN((caddr_t)data, (caddr_t)&tmp, - sizeof(tmp)); + error = BCOPYIN(data, &tmp, sizeof(tmp)); if (!error) { tmp = frflush(IPL_LOGIPF, 6, tmp); - error = BCOPYOUT((caddr_t)&tmp, (caddr_t)data, - sizeof(tmp)); + error = BCOPYOUT(&tmp, data, sizeof(tmp)); if (error != 0) error = EFAULT; } else @@ -7109,7 +7149,7 @@ void *ctx; #endif case SIOCSTLCK : - error = BCOPYIN((caddr_t)data, (caddr_t)&tmp, sizeof(tmp)); + error = BCOPYIN(data, &tmp, sizeof(tmp)); if (error == 0) { fr_state_lock = tmp; fr_nat_lock = tmp; @@ -7125,8 +7165,7 @@ void *ctx; error = EPERM; else { tmp = ipflog_clear(IPL_LOGIPF); - error = BCOPYOUT((caddr_t)&tmp, (caddr_t)data, - sizeof(tmp)); + error = BCOPYOUT(&tmp, data, sizeof(tmp)); if (error) error = EFAULT; } @@ -7158,7 +7197,7 @@ void *ctx; case FIONREAD : tmp = (int)iplused[IPL_LOGIPF]; - error = BCOPYOUT((caddr_t)&tmp, (caddr_t)data, sizeof(tmp)); + error = BCOPYOUT(&tmp, data, sizeof(tmp)); break; #endif @@ -7173,16 +7212,14 @@ void *ctx; error = ipf_genericiter(data, uid, ctx); SPL_X(s); break; - break; case SIOCIPFDELTOK : SPL_SCHED(s); - error = BCOPYIN((caddr_t)data, (caddr_t)&tmp, sizeof(tmp)); + error = BCOPYIN(data, &tmp, sizeof(tmp)); if (error == 0) error = ipf_deltoken(tmp, uid, ctx); SPL_X(s); break; - break; default : error = EINVAL; @@ -7258,15 +7295,16 @@ ipftq_t *ipfqs, *userqs; return 0; } if (istart > fr_ticks) { - istart = (fr_ticks / interval) * interval; + if (fr_ticks - interval < interval) + istart = interval; + else + istart = (fr_ticks / interval) * interval; } iend = fr_ticks - interval; - if (istart > iend) - istart = iend - interval; removed = 0; - while (removed == 0) { + for (;;) { u_long try; try = fr_ticks - istart; @@ -7293,8 +7331,9 @@ ipftq_t *ipfqs, *userqs; } } - istart -= interval; if (try >= iend) { + if (removed > 0) + break; if (interval == IPF_TTLVAL(43200)) { interval = IPF_TTLVAL(1800); } else if (interval == IPF_TTLVAL(1800)) { @@ -7307,6 +7346,7 @@ ipftq_t *ipfqs, *userqs; iend = fr_ticks - interval; } + istart -= interval; } return removed; |