diff -cr ip_fil3.3.15/HISTORY ip_fil3.3.16/HISTORY *** ip_fil3.3.15/HISTORY Sat May 20 02:02:58 2000 --- ip_fil3.3.16/HISTORY Mon May 22 17:08:08 2000 *************** *** 20,25 **** --- 20,32 ---- # and especially those who have found the time to port IP Filter to new # platforms. # + 3.3.16 23/05/2000 - Released + + don't add TCP state if it is an RST packet and (attempt) to send out + RST/ICMP packets in a manner that bypasses IP Filter. + + add patch to work with 4.0_STABLE delayed checksums + 3.3.15 20/05/2000 - Released fix destination being 0/32 in NAT map rules diff -cr ip_fil3.3.15/SunOS5/pkginfo ip_fil3.3.16/SunOS5/pkginfo *** ip_fil3.3.15/SunOS5/pkginfo Sat May 20 02:03:02 2000 --- ip_fil3.3.16/SunOS5/pkginfo Mon May 22 17:01:53 2000 *************** *** 5,11 **** PKG=ipf NAME=IP Filter ARCH=sparc,i386 ! VERSION=3.3.15 CATEGORY=system DESC=This package contains tools for building a firewall VENDOR=Darren Reed --- 5,11 ---- PKG=ipf NAME=IP Filter ARCH=sparc,i386 ! VERSION=3.3.16 CATEGORY=system DESC=This package contains tools for building a firewall VENDOR=Darren Reed diff -cr ip_fil3.3.15/fil.c ip_fil3.3.16/fil.c *** ip_fil3.3.15/fil.c Wed May 10 08:40:01 2000 --- ip_fil3.3.16/fil.c Mon May 22 16:57:42 2000 *************** *** 7,13 **** */ #if !defined(lint) static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-1996 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: fil.c,v 2.3.2.19 2000/05/09 22:40:01 darrenr Exp $"; #endif #include --- 7,13 ---- */ #if !defined(lint) static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-1996 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: fil.c,v 2.3.2.20 2000/05/22 06:57:42 darrenr Exp $"; #endif #include *************** *** 97,105 **** second; } # define FR_VERBOSE(verb_pr) verbose verb_pr # define FR_DEBUG(verb_pr) debug verb_pr - # define SEND_RESET(ip, qif, if, m, fin) send_reset(ip, if) # define IPLLOG(a, c, d, e) ipllog() - # define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, ip) #else /* #ifndef _KERNEL */ # define FR_IFVERBOSE(ex,second,verb_pr) ; # define FR_IFDEBUG(ex,second,verb_pr) ; --- 97,103 ---- *************** *** 109,131 **** # if SOLARIS || defined(__sgi) extern KRWLOCK_T ipf_mutex, ipf_auth, ipf_nat; extern kmutex_t ipf_rw; - # endif - # if SOLARIS - # define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, \ - ip, qif) - # define SEND_RESET(ip, qif, if, fin) send_reset(fin, ip, qif) - # define ICMP_ERROR(b, ip, t, c, if, dst) \ - icmp_error(ip, t, c, if, dst) - # else /* SOLARIS */ - # define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, ip) - # ifdef linux - # define SEND_RESET(ip, qif, if, fin) send_reset(ip, ifp) - # define ICMP_ERROR(b, ip, t, c, if, dst) icmp_send(b,t,c,0,if) - # else - # define SEND_RESET(ip, qif, if, fin) send_reset(fin, ip) - # define ICMP_ERROR(b, ip, t, c, if, dst) \ - send_icmp_err(ip, t, c, if, dst) - # endif /* linux */ # endif /* SOLARIS || __sgi */ #endif /* _KERNEL */ --- 107,112 ---- *************** *** 245,256 **** if (!off && (icmp->icmp_type == ICMP_ECHOREPLY || icmp->icmp_type == ICMP_ECHO)) minicmpsz = ICMP_MINLEN; if (!off && (icmp->icmp_type == ICMP_TSTAMP || icmp->icmp_type == ICMP_TSTAMPREPLY)) ! minicmpsz = 20; /* type(1) + code(1) + cksum(2) + id(2) + seq(2) + 3*timestamp(3*4) */ if (!off && (icmp->icmp_type == ICMP_MASKREQ || icmp->icmp_type == ICMP_MASKREPLY)) ! minicmpsz = 12; /* type(1) + code(1) + cksum(2) + id(2) + seq(2) + mask(4) */ if ((!(ip->ip_len >= hlen + minicmpsz) && !off) || (off && off < sizeof(struct icmp))) fi->fi_fl |= FI_SHORT; --- 226,242 ---- if (!off && (icmp->icmp_type == ICMP_ECHOREPLY || icmp->icmp_type == ICMP_ECHO)) minicmpsz = ICMP_MINLEN; + if (!off && (icmp->icmp_type == ICMP_TSTAMP || icmp->icmp_type == ICMP_TSTAMPREPLY)) ! minicmpsz = 20; ! /* type(1) + code(1) + cksum(2) + id(2) + seq(2) + 3*timestamp(3*4) */ ! if (!off && (icmp->icmp_type == ICMP_MASKREQ || icmp->icmp_type == ICMP_MASKREPLY)) ! minicmpsz = 12; ! /* type(1) + code(1) + cksum(2) + id(2) + seq(2) + mask(4) */ ! if ((!(ip->ip_len >= hlen + minicmpsz) && !off) || (off && off < sizeof(struct icmp))) fi->fi_fl |= FI_SHORT; *************** *** 630,635 **** --- 616,631 ---- */ m->m_flags &= ~M_CANFASTFWD; # endif /* M_CANFASTFWD */ + # ifdef CSUM_DELAY_DATA + /* + * disable delayed checksums. + */ + if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { + in_delayed_cksum(m); + m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; + } + # endif /* CSUM_DELAY_DATA */ + if ((ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP || ip->ip_p == IPPROTO_ICMP)) { *************** *** 762,768 **** * then pretend we've dropped it already. */ if ((pass & FR_AUTH)) ! if (FR_NEWAUTH(m, fin, ip, qif) != 0) #ifdef _KERNEL m = *mp = NULL; #else --- 758,764 ---- * then pretend we've dropped it already. */ if ((pass & FR_AUTH)) ! if (fr_newauth((mb_t *)m, fin, ip) != 0) #ifdef _KERNEL m = *mp = NULL; #else *************** *** 892,908 **** dst = ip->ip_dst; else dst.s_addr = 0; ! # if SOLARIS ! ICMP_ERROR(q, ip, ICMP_UNREACH, fin->fin_icode, ! qif, dst); ! # else ! ICMP_ERROR(m, ip, ICMP_UNREACH, fin->fin_icode, ! ifp, dst); ! # endif ATOMIC_INC(frstats[0].fr_ret); } else if (((pass & FR_RETMASK) == FR_RETRST) && !(fin->fin_fi.fi_fl & FI_SHORT)) { ! if (SEND_RESET(ip, qif, ifp, fin) == 0) { ATOMIC_INC(frstats[1].fr_ret); } } --- 888,898 ---- dst = ip->ip_dst; else dst.s_addr = 0; ! send_icmp_err(ip, ICMP_UNREACH, fin, dst); ATOMIC_INC(frstats[0].fr_ret); } else if (((pass & FR_RETMASK) == FR_RETRST) && !(fin->fin_fi.fi_fl & FI_SHORT)) { ! if (send_reset(ip, fin) == 0) { ATOMIC_INC(frstats[1].fr_ret); } } *************** *** 1195,1201 **** * SUCH DAMAGE. * * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 ! * $Id: fil.c,v 2.3.2.19 2000/05/09 22:40:01 darrenr Exp $ */ /* * Copy data from an mbuf chain starting "off" bytes from the beginning, --- 1185,1191 ---- * SUCH DAMAGE. * * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 ! * $Id: fil.c,v 2.3.2.20 2000/05/22 06:57:42 darrenr Exp $ */ /* * Copy data from an mbuf chain starting "off" bytes from the beginning, diff -cr ip_fil3.3.15/ip_auth.c ip_fil3.3.16/ip_auth.c *** ip_fil3.3.15/ip_auth.c Wed Apr 26 02:21:12 2000 --- ip_fil3.3.16/ip_auth.c Mon May 22 16:57:45 2000 *************** *** 6,12 **** * to the original author and the contributors. */ #if !defined(lint) ! static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.1.2.3 2000/04/25 16:21:12 darrenr Exp $"; #endif #include --- 6,12 ---- * to the original author and the contributors. */ #if !defined(lint) ! static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.1.2.4 2000/05/22 06:57:45 darrenr Exp $"; #endif #include *************** *** 196,212 **** * If we do, store it and wake up any user programs which are waiting to * hear about these events. */ ! int fr_newauth(m, fin, ip ! #if defined(_KERNEL) && SOLARIS ! , qif) ! qif_t *qif; ! #else ! ) ! #endif mb_t *m; fr_info_t *fin; ip_t *ip; { int i; WRITE_ENTER(&ipf_auth); --- 196,209 ---- * If we do, store it and wake up any user programs which are waiting to * hear about these events. */ ! int fr_newauth(m, fin, ip) mb_t *m; fr_info_t *fin; ip_t *ip; { + #if defined(_KERNEL) && SOLARIS + qif_t *qif = fin->fin_qif; + #endif int i; WRITE_ENTER(&ipf_auth); diff -cr ip_fil3.3.15/ip_auth.h ip_fil3.3.16/ip_auth.h *** ip_fil3.3.15/ip_auth.h Thu Aug 5 03:29:54 1999 --- ip_fil3.3.16/ip_auth.h Mon May 22 16:57:47 2000 *************** *** 5,11 **** * provided that this notice is preserved and due credit is given * to the original author and the contributors. * ! * $Id: ip_auth.h,v 2.1 1999/08/04 17:29:54 darrenr Exp $ * */ #ifndef __IP_AUTH_H__ --- 5,11 ---- * provided that this notice is preserved and due credit is given * to the original author and the contributors. * ! * $Id: ip_auth.h,v 2.1.2.1 2000/05/22 06:57:47 darrenr Exp $ * */ #ifndef __IP_AUTH_H__ *************** *** 54,64 **** extern void fr_authexpire __P((void)); extern void fr_authunload __P((void)); extern mb_t *fr_authpkts[]; - #if defined(_KERNEL) && SOLARIS - extern int fr_newauth __P((mb_t *, fr_info_t *, ip_t *, qif_t *)); - #else extern int fr_newauth __P((mb_t *, fr_info_t *, ip_t *)); - #endif #if defined(__NetBSD__) || defined(__OpenBSD__) extern int fr_auth_ioctl __P((caddr_t, u_long, frentry_t *, frentry_t **)); #else --- 54,60 ---- diff -cr ip_fil3.3.15/ip_fil.c ip_fil3.3.16/ip_fil.c *** ip_fil3.3.15/ip_fil.c Wed Apr 19 02:31:27 2000 --- ip_fil3.3.16/ip_fil.c Mon May 22 16:57:47 2000 *************** *** 7,13 **** */ #if !defined(lint) static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-1995 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.4.2.20 2000/04/18 16:31:27 darrenr Exp $"; #endif #ifndef SOLARIS --- 7,13 ---- */ #if !defined(lint) static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-1995 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.4.2.21 2000/05/22 06:57:47 darrenr Exp $"; #endif #ifndef SOLARIS *************** *** 137,143 **** #endif #ifdef _KERNEL static int (*fr_savep) __P((ip_t *, int, void *, int, struct mbuf **)); ! static int send_ip __P((struct mbuf *, ip_t *)); # ifdef __sgi extern kmutex_t ipf_rw; extern KRWLOCK_T ipf_mutex; --- 137,143 ---- #endif #ifdef _KERNEL static int (*fr_savep) __P((ip_t *, int, void *, int, struct mbuf **)); ! static int send_ip __P((ip_t *, fr_info_t *, struct mbuf *)); # ifdef __sgi extern kmutex_t ipf_rw; extern KRWLOCK_T ipf_mutex; *************** *** 874,885 **** * send_reset - this could conceivably be a call to tcp_respond(), but that * requires a large amount of setting up and isn't any more efficient. */ ! int send_reset(fin, oip) ! fr_info_t *fin; struct ip *oip; { struct tcphdr *tcp, *tcp2; - struct tcpiphdr *tp; struct mbuf *m; int tlen = 0; ip_t *ip; --- 874,884 ---- * send_reset - this could conceivably be a call to tcp_respond(), but that * requires a large amount of setting up and isn't any more efficient. */ ! int send_reset(oip, fin) struct ip *oip; + fr_info_t *fin; { struct tcphdr *tcp, *tcp2; struct mbuf *m; int tlen = 0; ip_t *ip; *************** *** 902,914 **** m->m_len = sizeof(*tcp2) + sizeof(*ip); # if BSD >= 199306 m->m_data += max_linkhdr; ! m->m_pkthdr.len = m->m_len; m->m_pkthdr.rcvif = (struct ifnet *)0; # endif - bzero(mtod(m, char *), sizeof(struct tcpiphdr)); ip = mtod(m, struct ip *); ! tp = mtod(m, struct tcpiphdr *); ! tcp2 = (struct tcphdr *)((char *)ip + sizeof(*ip)); ip->ip_src.s_addr = oip->ip_dst.s_addr; ip->ip_dst.s_addr = oip->ip_src.s_addr; --- 901,912 ---- m->m_len = sizeof(*tcp2) + sizeof(*ip); # if BSD >= 199306 m->m_data += max_linkhdr; ! m->m_pkthdr.len = sizeof(*tcp2) + sizeof(*ip); m->m_pkthdr.rcvif = (struct ifnet *)0; # endif ip = mtod(m, struct ip *); ! bzero((char *)ip, sizeof(*tcp2) + sizeof(*ip)); ! tcp2 = (struct tcphdr *)(ip + 1); ip->ip_src.s_addr = oip->ip_dst.s_addr; ip->ip_dst.s_addr = oip->ip_src.s_addr; *************** *** 919,945 **** tcp2->th_ack = htonl(tcp2->th_ack); tcp2->th_off = sizeof(*tcp2) >> 2; tcp2->th_flags = TH_RST|TH_ACK; ! tp->ti_pr = oip->ip_p; ! tp->ti_len = htons(sizeof(struct tcphdr)); tcp2->th_sum = in_cksum(m, sizeof(*ip) + sizeof(*tcp2)); ip->ip_tos = oip->ip_tos; - ip->ip_p = oip->ip_p; ip->ip_len = sizeof(*ip) + sizeof(*tcp2); ! return send_ip(m, ip); } ! static int send_ip(m, ip) struct mbuf *m; ip_t *ip; { ! # if (defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)) || \ ! (defined(_BSDI_VERSION) && (_BSDI_VERSION >= 199802)) ! struct route ro; ! # endif ! # if (BSD < 199306) || defined(__sgi) ip->ip_ttl = tcp_ttl; # else --- 917,941 ---- tcp2->th_ack = htonl(tcp2->th_ack); tcp2->th_off = sizeof(*tcp2) >> 2; tcp2->th_flags = TH_RST|TH_ACK; ! ip->ip_p = IPPROTO_TCP; ! ip->ip_len = htons(sizeof(struct tcphdr)); tcp2->th_sum = in_cksum(m, sizeof(*ip) + sizeof(*tcp2)); + ip->ip_id = oip->ip_id; ip->ip_tos = oip->ip_tos; ip->ip_len = sizeof(*ip) + sizeof(*tcp2); ! return send_ip(ip, fin, m); } ! static int send_ip(ip, fin, m) ! fr_info_t *fin; struct mbuf *m; ip_t *ip; { ! ip->ip_v = IPVERSION; ! ip->ip_hl = (sizeof(*ip) >> 2); # if (BSD < 199306) || defined(__sgi) ip->ip_ttl = tcp_ttl; # else *************** *** 949,991 **** # ifdef IPSEC m->m_pkthdr.rcvif = NULL; # endif ! # if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000) ! { ! int err; ! ! bzero((char *)&ro, sizeof(ro)); ! err = ip_output(m, (struct mbuf *)0, &ro, 0, 0); ! if (ro.ro_rt) ! RTFREE(ro.ro_rt); ! return err; ! } ! # else ! /* ! * extra 0 in case of multicast ! */ ! # if _BSDI_VERSION >= 199802 ! return ip_output(m, (struct mbuf *)0, &ro, 0, 0, NULL); ! # else ! # if defined(__OpenBSD__) ! return ip_output(m, (struct mbuf *)0, 0, 0, 0, NULL); ! # else ! return ip_output(m, (struct mbuf *)0, 0, 0, 0); ! # endif ! # endif ! # endif } ! int send_icmp_err(oip, type, code, ifp, dst) ip_t *oip; ! int type, code; ! void *ifp; struct in_addr dst; { struct icmp *icmp; struct mbuf *m; ip_t *nip; # if (BSD < 199306) || defined(__sgi) m = m_get(M_DONTWAIT, MT_HEADER); # else --- 945,978 ---- # ifdef IPSEC m->m_pkthdr.rcvif = NULL; # endif ! return ipfr_fastroute(m, fin, NULL); } ! int send_icmp_err(oip, type, fin, dst) ip_t *oip; ! int type; ! fr_info_t *fin; struct in_addr dst; { struct icmp *icmp; struct mbuf *m; ip_t *nip; + int code; + if ((oip->ip_p == IPPROTO_ICMP) && !(fin->fin_fi.fi_fl & FI_SHORT)) + switch (ntohs(fin->fin_data[0]) >> 8) + { + case ICMP_ECHO : + case ICMP_TSTAMP : + case ICMP_IREQ : + case ICMP_MASKREQ : + break; + default : + return 0; + } + + code = fin->fin_icode; # if (BSD < 199306) || defined(__sgi) m = m_get(M_DONTWAIT, MT_HEADER); # else *************** *** 1004,1011 **** nip = mtod(m, ip_t *); icmp = (struct icmp *)(nip + 1); - nip->ip_v = IPVERSION; - nip->ip_hl = (sizeof(*nip) >> 2); nip->ip_p = IPPROTO_ICMP; nip->ip_id = oip->ip_id; nip->ip_sum = 0; --- 991,996 ---- *************** *** 1013,1019 **** nip->ip_tos = oip->ip_tos; nip->ip_len = sizeof(*nip) + sizeof(*icmp) + 8; if (dst.s_addr == 0) { ! if (fr_ifpaddr(ifp, &dst) == -1) return -1; } nip->ip_src = dst; --- 998,1004 ---- nip->ip_tos = oip->ip_tos; nip->ip_len = sizeof(*nip) + sizeof(*icmp) + 8; if (dst.s_addr == 0) { ! if (fr_ifpaddr(fin->fin_ifp, &dst) == -1) return -1; } nip->ip_src = dst; *************** *** 1037,1043 **** } # endif icmp->icmp_cksum = ipf_cksum((u_short *)icmp, sizeof(*icmp) + 8); ! return send_ip(m, nip); } --- 1022,1028 ---- } # endif icmp->icmp_cksum = ipf_cksum((u_short *)icmp, sizeof(*icmp) + 8); ! return send_ip(nip, fin, m); } *************** *** 1079,1088 **** register struct ip *ip, *mhip; register struct mbuf *m = m0; register struct route *ro; ! int len, off, error = 0, hlen; struct sockaddr_in *dst; struct route iproute; - struct ifnet *ifp; frentry_t *fr; hlen = fin->fin_hlen; --- 1064,1073 ---- register struct ip *ip, *mhip; register struct mbuf *m = m0; register struct route *ro; ! int len, off, error = 0, hlen, code; ! struct ifnet *ifp, *sifp; struct sockaddr_in *dst; struct route iproute; frentry_t *fr; hlen = fin->fin_hlen; *************** *** 1096,1102 **** dst->sin_family = AF_INET; fr = fin->fin_fr; ! ifp = fdp->fd_ifp; /* * In case we're here due to "to " being used with "keep state", * check that we're going in the correct direction. --- 1081,1093 ---- dst->sin_family = AF_INET; fr = fin->fin_fr; ! if (fdp) ! ifp = fdp->fd_ifp; ! else { ! ifp = fin->fin_ifp; ! dst->sin_addr = ip->ip_dst; ! } ! /* * In case we're here due to "to " being used with "keep state", * check that we're going in the correct direction. *************** *** 1105,1113 **** if ((ifp != NULL) && (fdp == &fr->fr_tif)) return -1; dst->sin_addr = ip->ip_dst; ! } else dst->sin_addr = fdp->fd_ip.s_addr ? fdp->fd_ip : ip->ip_dst; ! # ifdef __bsdi__ dst->sin_len = sizeof(*dst); # endif # if (BSD >= 199306) && !defined(__NetBSD__) && !defined(__bsdi__) && \ --- 1096,1105 ---- if ((ifp != NULL) && (fdp == &fr->fr_tif)) return -1; dst->sin_addr = ip->ip_dst; ! } else if (fdp) dst->sin_addr = fdp->fd_ip.s_addr ? fdp->fd_ip : ip->ip_dst; ! ! # if BSD >= 199306 dst->sin_len = sizeof(*dst); # endif # if (BSD >= 199306) && !defined(__NetBSD__) && !defined(__bsdi__) && \ *************** *** 1121,1127 **** rtalloc(ro); # endif if (!ifp) { ! if (!(fin->fin_fr->fr_flags & FR_FASTROUTE)) { error = -2; goto bad; } --- 1113,1119 ---- rtalloc(ro); # endif if (!ifp) { ! if (!fr || !(fr->fr_flags & FR_FASTROUTE)) { error = -2; goto bad; } *************** *** 1151,1158 **** ATOMIC_INC(frstats[1].fr_acct); } fin->fin_fr = NULL; ! (void) fr_checkstate(ip, fin); ! (void) ip_natout(ip, fin); } else ip->ip_sum = 0; /* --- 1143,1152 ---- ATOMIC_INC(frstats[1].fr_acct); } fin->fin_fr = NULL; ! if (!fr || !(fr->fr_flags & FR_RETMASK)) { ! (void) fr_checkstate(ip, fin); ! (void) ip_natout(ip, fin); ! } } else ip->ip_sum = 0; /* *************** *** 1280,1288 **** RTFREE(ro->ro_rt); return 0; bad: ! if (error == EMSGSIZE) ! (void) send_icmp_err(ip, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, ! ifp, ip->ip_dst); m_freem(m); goto done; } --- 1274,1288 ---- RTFREE(ro->ro_rt); return 0; bad: ! if (error == EMSGSIZE) { ! sifp = fin->fin_ifp; ! fin->fin_ifp = ifp; ! code = fin->fin_icode; ! fin->fin_icode = ICMP_UNREACH_NEEDFRAG; ! (void) send_icmp_err(ip, ICMP_UNREACH, fin, ip->ip_dst); ! fin->fin_ifp = sifp; ! fin->fin_icode = code; ! } m_freem(m); goto done; } diff -cr ip_fil3.3.15/ip_fil.h ip_fil3.3.16/ip_fil.h *** ip_fil3.3.15/ip_fil.h Sun May 7 11:49:04 2000 --- ip_fil3.3.16/ip_fil.h Mon May 22 16:57:50 2000 *************** *** 6,12 **** * to the original author and the contributors. * * @(#)ip_fil.h 1.35 6/5/96 ! * $Id: ip_fil.h,v 2.3.2.10 2000/05/07 01:49:04 darrenr Exp $ */ #ifndef __IP_FIL_H__ --- 6,12 ---- * to the original author and the contributors. * * @(#)ip_fil.h 1.35 6/5/96 ! * $Id: ip_fil.h,v 2.3.2.11 2000/05/22 06:57:50 darrenr Exp $ */ #ifndef __IP_FIL_H__ *************** *** 455,465 **** extern int ipflog_read __P((minor_t, struct uio *)); extern int ipflog __P((u_int, ip_t *, fr_info_t *, mb_t *)); extern int ipllog __P((int, fr_info_t *, void **, size_t *, int *, int)); # if SOLARIS extern int fr_check __P((ip_t *, int, void *, int, qif_t *, mb_t **)); extern int (*fr_checkp) __P((ip_t *, int, void *, int, qif_t *, mb_t **)); - extern int icmp_error __P((ip_t *, int, int, qif_t *, struct in_addr)); # if SOLARIS2 >= 7 extern int iplioctl __P((dev_t, int, intptr_t, int, cred_t *, int *)); # else --- 455,466 ---- extern int ipflog_read __P((minor_t, struct uio *)); extern int ipflog __P((u_int, ip_t *, fr_info_t *, mb_t *)); extern int ipllog __P((int, fr_info_t *, void **, size_t *, int *, int)); + extern int send_icmp_err __P((ip_t *, int, fr_info_t *, struct in_addr)); + extern int send_reset __P((ip_t *, fr_info_t *)); # if SOLARIS extern int fr_check __P((ip_t *, int, void *, int, qif_t *, mb_t **)); extern int (*fr_checkp) __P((ip_t *, int, void *, int, qif_t *, mb_t **)); # if SOLARIS2 >= 7 extern int iplioctl __P((dev_t, int, intptr_t, int, cred_t *, int *)); # else *************** *** 468,474 **** extern int iplopen __P((dev_t *, int, int, cred_t *)); extern int iplclose __P((dev_t, int, int, cred_t *)); extern int ipfsync __P((void)); - extern int send_reset __P((fr_info_t *, ip_t *, qif_t *)); extern int ipfr_fastroute __P((qif_t *, ip_t *, mblk_t *, mblk_t **, fr_info_t *, frdest_t *)); extern void copyin_mblk __P((mblk_t *, size_t, size_t, char *)); --- 469,474 ---- *************** *** 481,492 **** # else /* SOLARIS */ extern int fr_check __P((ip_t *, int, void *, int, mb_t **)); extern int (*fr_checkp) __P((ip_t *, int, void *, int, mb_t **)); - # ifdef linux - extern int send_reset __P((tcpiphdr_t *, struct ifnet *)); - # else - extern int send_reset __P((fr_info_t *, struct ip *)); - extern int send_icmp_err __P((ip_t *, int, int, void *, struct in_addr)); - # endif extern int ipfr_fastroute __P((mb_t *, fr_info_t *, frdest_t *)); extern size_t mbufchainlen __P((mb_t *)); # ifdef __sgi --- 481,486 ---- diff -cr ip_fil3.3.15/ip_sfil.c ip_fil3.3.16/ip_sfil.c *** ip_fil3.3.15/ip_sfil.c Wed Apr 19 02:31:30 2000 --- ip_fil3.3.16/ip_sfil.c Mon May 22 16:57:52 2000 *************** *** 9,15 **** */ #if !defined(lint) static const char sccsid[] = "%W% %G% (C) 1993-1995 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.1.2.7 2000/04/18 16:31:30 darrenr Exp $"; #endif #include --- 9,15 ---- */ #if !defined(lint) static const char sccsid[] = "%W% %G% (C) 1993-1995 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.1.2.8 2000/05/22 06:57:52 darrenr Exp $"; #endif #include *************** *** 617,652 **** #endif /* IPFILTER_LOG */ /* * send_reset - this could conceivably be a call to tcp_respond(), but that * requires a large amount of setting up and isn't any more efficient. */ ! int send_reset(fin, iphdr, qif) fr_info_t *fin; - ip_t *iphdr; - qif_t *qif; { tcphdr_t *tcp, *tcp2; int tlen = 0; mblk_t *m; ip_t *ip; tcp = (struct tcphdr *)fin->fin_dp; if (tcp->th_flags & TH_RST) return -1; if (tcp->th_flags & TH_SYN) tlen = 1; ! if ((m = (mblk_t *)allocb(sizeof(*ip) + sizeof(*tcp),BPRI_HI)) == NULL) return -1; ! MTYPE(m) = M_DATA; ! m->b_wptr += sizeof(*ip) + sizeof(*tcp); ! bzero((char *)m->b_rptr, sizeof(*ip) + sizeof(*tcp)); ip = (ip_t *)m->b_rptr; tcp2 = (struct tcphdr *)(m->b_rptr + sizeof(*ip)); ! ip->ip_src.s_addr = iphdr->ip_dst.s_addr; ! ip->ip_dst.s_addr = iphdr->ip_src.s_addr; tcp2->th_dport = tcp->th_sport; tcp2->th_sport = tcp->th_dport; tcp2->th_ack = htonl(ntohl(tcp->th_seq) + tlen); --- 617,655 ---- #endif /* IPFILTER_LOG */ + #define TCPIP_HDRLEN (sizeof(*ip) + sizeof(*tcp)) + /* * send_reset - this could conceivably be a call to tcp_respond(), but that * requires a large amount of setting up and isn't any more efficient. */ ! int send_reset(oip, fin) ! ip_t *oip; fr_info_t *fin; { tcphdr_t *tcp, *tcp2; int tlen = 0; + qif_t *qif; mblk_t *m; ip_t *ip; + qif = fin->fin_qif; tcp = (struct tcphdr *)fin->fin_dp; if (tcp->th_flags & TH_RST) return -1; if (tcp->th_flags & TH_SYN) tlen = 1; ! if ((m = (mblk_t *)allocb(TCPIP_HDRLEN + 16, BPRI_HI)) == NULL) return -1; ! m->b_rptr += 16; ! m->b_wptr = m->b_rptr + TCPIP_HDRLEN; ! bzero((char *)m->b_rptr, TCPIP_HDRLEN); ip = (ip_t *)m->b_rptr; tcp2 = (struct tcphdr *)(m->b_rptr + sizeof(*ip)); ! ip->ip_src.s_addr = oip->ip_dst.s_addr; ! ip->ip_dst.s_addr = oip->ip_src.s_addr; tcp2->th_dport = tcp->th_sport; tcp2->th_sport = tcp->th_dport; tcp2->th_ack = htonl(ntohl(tcp->th_seq) + tlen); *************** *** 657,709 **** * This is to get around a bug in the Solaris 2.4/2.5 TCP checksum * computation that is done by their put routine. */ ! tcp2->th_sum = htons(0x14); ip->ip_hl = sizeof(*ip) >> 2; ip->ip_v = IPVERSION; - ip->ip_p = IPPROTO_TCP; - ip->ip_len = htons(sizeof(*ip) + sizeof(*tcp)); - ip->ip_tos = iphdr->ip_tos; - ip->ip_off = 0; ip->ip_ttl = 60; ! ip->ip_sum = 0; ! RWLOCK_EXIT(&ipfs_mutex); ! RWLOCK_EXIT(&ipf_solaris); ! ip_wput(qif->qf_ill->ill_wq, m); ! READ_ENTER(&ipf_solaris); ! READ_ENTER(&ipfs_mutex); ! return 0; } ! int icmp_error(ip, type, code, qif, dst) ip_t *ip; ! int type, code; ! qif_t *qif; struct in_addr dst; { - mblk_t *mb; struct icmp *icmp; ip_t *nip; ! u_short sz = sizeof(*nip) + sizeof(*icmp) + 8; ! if ((mb = (mblk_t *)allocb((size_t)sz, BPRI_HI)) == NULL) return -1; ! MTYPE(mb) = M_DATA; ! mb->b_wptr += sz; bzero((char *)mb->b_rptr, (size_t)sz); nip = (ip_t *)mb->b_rptr; icmp = (struct icmp *)(nip + 1); - nip->ip_v = IPVERSION; nip->ip_hl = (sizeof(*nip) >> 2); nip->ip_p = IPPROTO_ICMP; nip->ip_id = ip->ip_id; - nip->ip_sum = 0; - nip->ip_ttl = 60; nip->ip_tos = ip->ip_tos; nip->ip_len = (u_short)htons(sz); if (dst.s_addr == 0) { ! if (fr_ifpaddr(qif->qf_ill, &dst) == -1) return -1; } nip->ip_src = dst; --- 660,744 ---- * This is to get around a bug in the Solaris 2.4/2.5 TCP checksum * computation that is done by their put routine. */ ! ip->ip_p = IPPROTO_TCP; ! ip->ip_len = TCPIP_HDRLEN; ip->ip_hl = sizeof(*ip) >> 2; + ip->ip_tos = oip->ip_tos; + ip->ip_id = oip->ip_id; + tcp2->th_sum = fr_tcpsum(m, ip, tcp2); + ip->ip_len = htons(ip->ip_len); + + return send_ip(ip, fin, m); + } + + + int send_ip(ip, fin, m) + ip_t *ip; + fr_info_t *fin; + mb_t *m; + { + u_32_t sum; + void *wp; + ip->ip_v = IPVERSION; ip->ip_ttl = 60; ! ! MTYPE(m) = M_DATA; ! wp = m->b_wptr; ! m->b_wptr = m->b_rptr + sizeof(*ip); ! sum = ip_cksum(m, 0, 0); ! sum = (sum & 0xffff) + (sum >> 16); ! sum = ~sum & 0xffff; ! ip->ip_sum = sum; ! m->b_wptr = wp; ! ip->ip_len = ntohs(ip->ip_len); ! ! return ipfr_fastroute(fin->fin_qif, ip, m, &m, fin, NULL); } ! int send_icmp_err(ip, type, fin, dst) ip_t *ip; ! int type; ! fr_info_t *fin; struct in_addr dst; { struct icmp *icmp; + mblk_t *mb; ip_t *nip; ! int code; ! u_short sz; ! ! sz = sizeof(*nip) + sizeof(*icmp) + 8; ! code = fin->fin_icode; ! if ((mb = (mblk_t *)allocb((size_t)sz + 16, BPRI_HI)) == NULL) return -1; ! mb->b_rptr += 16; ! if ((ip->ip_p == IPPROTO_ICMP) && !(fin->fin_fi.fi_fl & FI_SHORT)) ! switch (ntohs(fin->fin_data[0]) >> 8) ! { ! case ICMP_ECHO : ! case ICMP_TSTAMP : ! case ICMP_IREQ : ! case ICMP_MASKREQ : ! break; ! default : ! return 0; ! } ! ! mb->b_wptr = mb->b_rptr + sz; bzero((char *)mb->b_rptr, (size_t)sz); nip = (ip_t *)mb->b_rptr; icmp = (struct icmp *)(nip + 1); nip->ip_hl = (sizeof(*nip) >> 2); nip->ip_p = IPPROTO_ICMP; nip->ip_id = ip->ip_id; nip->ip_tos = ip->ip_tos; nip->ip_len = (u_short)htons(sz); if (dst.s_addr == 0) { ! if (fr_ifpaddr(((qif_t *)fin->fin_qif)->qf_ill, &dst) == -1) return -1; } nip->ip_src = dst; *************** *** 727,740 **** } #endif icmp->icmp_cksum = ipf_cksum((u_short *)icmp, sizeof(*icmp) + 8); ! /* ! * Need to exit out of these so we don't recursively call rw_enter ! * from fr_qout. ! */ ! RWLOCK_EXIT(&ipfs_mutex); ! RWLOCK_EXIT(&ipf_solaris); ! ip_wput(qif->qf_ill->ill_wq, mb); ! READ_ENTER(&ipf_solaris); ! READ_ENTER(&ipfs_mutex); ! return 0; } --- 762,767 ---- } #endif icmp->icmp_cksum = ipf_cksum((u_short *)icmp, sizeof(*icmp) + 8); ! ! return send_ip(nip, fin, mb); } diff -cr ip_fil3.3.15/ip_state.c ip_fil3.3.16/ip_state.c *** ip_fil3.3.15/ip_state.c Sat May 20 01:53:45 2000 --- ip_fil3.3.16/ip_state.c Mon May 22 16:57:53 2000 *************** *** 7,13 **** */ #if !defined(lint) static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-1995 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.3.2.24 2000/05/19 15:53:45 darrenr Exp $"; #endif #include --- 7,13 ---- */ #if !defined(lint) static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-1995 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.3.2.25 2000/05/22 06:57:53 darrenr Exp $"; #endif #include *************** *** 316,321 **** --- 316,323 ---- { register tcphdr_t *tcp = (tcphdr_t *)fin->fin_dp; + if (tcp->th_flags & TH_RST) + return NULL; /* * The endian of the ports doesn't matter, but the ack and * sequence numbers do as we do mathematics on them later. diff -cr ip_fil3.3.15/ipl.h ip_fil3.3.16/ipl.h *** ip_fil3.3.15/ipl.h Sat May 20 02:03:00 2000 --- ip_fil3.3.16/ipl.h Mon May 22 17:01:52 2000 *************** *** 11,16 **** #ifndef __IPL_H__ #define __IPL_H__ ! #define IPL_VERSION "IP Filter: v3.3.15" #endif --- 11,16 ---- #ifndef __IPL_H__ #define __IPL_H__ ! #define IPL_VERSION "IP Filter: v3.3.16" #endif diff -cr ip_fil3.3.15/solaris.c ip_fil3.3.16/solaris.c *** ip_fil3.3.15/solaris.c Wed Feb 23 22:16:37 2000 --- ip_fil3.3.16/solaris.c Mon May 22 16:57:56 2000 *************** *** 6,12 **** * to the original author and the contributors. */ /* #pragma ident "@(#)solaris.c 1.12 6/5/96 (C) 1995 Darren Reed"*/ ! #pragma ident "@(#)$Id: solaris.c,v 2.1.2.19 2000/02/23 11:16:37 darrenr Exp $" #include #include --- 6,12 ---- * to the original author and the contributors. */ /* #pragma ident "@(#)solaris.c 1.12 6/5/96 (C) 1995 Darren Reed"*/ ! #pragma ident "@(#)$Id: solaris.c,v 2.1.2.20 2000/05/22 06:57:56 darrenr Exp $" #include #include *************** *** 535,540 **** --- 535,542 ---- u_short __iplen, __ipoff; #endif tryagain: + ip = NULL; + m = NULL; /* * If there is only M_DATA for a packet going out, then any header * information (which would otherwise appear in an M_PROTO mblk before *************** *** 552,559 **** dl_unitdata_ind_t *dl = (dl_unitdata_ind_t *)bp; if (dl->dl_primitive != DL_UNITDATA_IND && dl->dl_primitive != DL_UNITDATA_REQ) { ! frstats[out].fr_notdata++; ! return 0; } } --- 554,569 ---- dl_unitdata_ind_t *dl = (dl_unitdata_ind_t *)bp; if (dl->dl_primitive != DL_UNITDATA_IND && dl->dl_primitive != DL_UNITDATA_REQ) { ! ip = (ip_t *)dl; ! if ((ip->ip_v == IPVERSION) && ! (ip->ip_hl == (sizeof(*ip) >> 2)) && ! (ntohs(ip->ip_len) == mt->b_wptr - mt->b_rptr)) { ! off = 0; ! m = mt; ! } else { ! frstats[out].fr_notdata++; ! return 0; ! } } } *************** *** 561,568 **** * Find the first data block, count the data blocks in this chain and * the total amount of data. */ ! for (m = mt; m && (MTYPE(m) != M_DATA); m = m->b_cont) ! off = 0; /* Any non-M_DATA cancels the offset */ if (!m) { frstats[out].fr_nodata++; --- 571,579 ---- * Find the first data block, count the data blocks in this chain and * the total amount of data. */ ! if (ip == NULL) ! for (m = mt; m && (MTYPE(m) != M_DATA); m = m->b_cont) ! off = 0; /* Any non-M_DATA cancels the offset */ if (!m) { frstats[out].fr_nodata++; *************** *** 1461,1467 **** --- 1472,1480 ---- mblk_t *mp = NULL; size_t hlen = 0; frentry_t *fr; + frdest_t fd; ill_t *ifp; + qif_t *qif; u_char *s; #ifndef sparc *************** *** 1488,1493 **** --- 1501,1527 ---- *mpp = mp; } + if (!fdp) { + ipif_t *ipif; + + ifp = fin->fin_ifp; + ipif = ifp->ill_ipif; + if (!ipif) + goto bad_fastroute; + #if SOLARIS2 > 5 + ir = ire_ctable_lookup(ipif->ipif_local_addr, 0, IRE_LOCAL, + NULL, NULL, MATCH_IRE_TYPE); + #else + ir = ire_lookup_myaddr(ipif->ipif_local_addr); + #endif + if (!ir) + ir = (ire_t *)-1; + + fd.fd_ifp = (struct ifnet *)ir; + fd.fd_ip = ip->ip_dst; + fdp = &fd; + } + ir = (ire_t *)fdp->fd_ifp; if (fdp->fd_ip.s_addr) *************** *** 1538,1545 **** ATOMIC_INC(frstats[1].fr_acct); } fin->fin_fr = NULL; ! (void) fr_checkstate(ip, fin); ! (void) ip_natout(ip, fin); } #ifndef sparc __iplen = (u_short)ip->ip_len, --- 1572,1581 ---- ATOMIC_INC(frstats[1].fr_acct); } fin->fin_fr = NULL; ! if (!fr || !(fr->fr_flags & FR_RETMASK)) { ! (void) fr_checkstate(ip, fin); ! (void) ip_natout(ip, fin); ! } } #ifndef sparc __iplen = (u_short)ip->ip_len, *************** *** 1574,1580 **** mp2 = copyb(mp); if (!mp2) goto bad_fastroute; ! mp2->b_cont = mb; mb = mp2; } } --- 1610,1616 ---- mp2 = copyb(mp); if (!mp2) goto bad_fastroute; ! linkb(mp2, mb); mb = mp2; } }