diff --git a/sys/netinet/fil.c b/sys/netinet/fil.c index d51963e5e2b6..dd6dff46d3c9 100644 --- a/sys/netinet/fil.c +++ b/sys/netinet/fil.c @@ -11,14 +11,6 @@ static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-1996 Darren Reed"; static const char rcsid[] = "@(#)$FreeBSD$"; #endif -#if defined(_KERNEL) && defined(__FreeBSD_version) && \ - (__FreeBSD_version >= 400019) -# define CSUM_DELAY_DATA -#endif -#if defined(_KERNEL) && defined(__FreeBSD_version) && \ - (__FreeBSD_version >= 400000) && !defined(KLD_MODULE) -#include "opt_inet6.h" -#endif #include #include #include @@ -30,6 +22,14 @@ static const char rcsid[] = "@(#)$FreeBSD$"; #endif #if (defined(KERNEL) || defined(_KERNEL)) && defined(__FreeBSD_version) && \ (__FreeBSD_version >= 220000) +# if (__FreeBSD_version >= 400000) +# ifndef KLD_MODULE +# include "opt_inet6.h" +# endif +# if (__FreeBSD_version == 400019) +# define CSUM_DELAY_DATA +# endif +# endif # include # include #else @@ -122,10 +122,8 @@ extern kmutex_t ipf_rw; # 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) # else /* SOLARIS */ # define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, ip) -# define SEND_RESET(ip, qif, if, fin) send_reset(fin, ip) # endif /* SOLARIS || __sgi */ #endif /* _KERNEL */ @@ -666,8 +664,11 @@ void *m; * Just log this packet... */ passt = fr->fr_flags; - if ((passt & FR_CALLNOW) && fr->fr_func) - passt = (*fr->fr_func)(passt, ip, fin); +#if (BSD >= 199306) && (defined(_KERNEL) || defined(KERNEL)) + if (securelevel <= 0) +#endif + if ((passt & FR_CALLNOW) && fr->fr_func) + passt = (*fr->fr_func)(passt, ip, fin); fin->fin_fr = fr; #ifdef IPFILTER_LOG if ((passt & FR_LOGMASK) == FR_LOG) { @@ -972,8 +973,11 @@ int out; pass &= ~(FR_LOGFIRST|FR_LOG); } - if (fr && fr->fr_func && !(pass & FR_CALLNOW)) - pass = (*fr->fr_func)(pass, ip, fin); +#if (BSD >= 199306) && (defined(_KERNEL) || defined(KERNEL)) + if (securelevel <= 0) +#endif + if (fr && fr->fr_func && !(pass & FR_CALLNOW)) + pass = (*fr->fr_func)(pass, ip, fin); /* * Only count/translate packets which will be passed on, out the @@ -982,10 +986,10 @@ int out; if (out && (pass & FR_PASS)) { #ifdef USE_INET6 if (v == 6) - list = ipacct6[0][fr_active]; + list = ipacct6[1][fr_active]; else #endif - list = ipacct[0][fr_active]; + list = ipacct[1][fr_active]; if ((fin->fin_fr = list) && (fr_scanlist(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT)) { ATOMIC_INCL(frstats[1].fr_acct); @@ -1130,11 +1134,11 @@ logit: if (((pass & FR_FASTROUTE) && !out) || (fdp->fd_ifp && fdp->fd_ifp != (struct ifnet *)-1)) { - if (ipfr_fastroute(qif, ip, m, mp, fin, fdp) == 0) + if (ipfr_fastroute(ip, m, mp, fin, fdp) == 0) m = *mp = NULL; } if (mc) - ipfr_fastroute(qif, ip, mc, mp, fin, &fr->fr_dif); + ipfr_fastroute(ip, mc, mp, fin, &fr->fr_dif); } # endif /* !SOLARIS */ return (pass & FR_PASS) ? 0 : error; @@ -1366,7 +1370,7 @@ nodata: * SUCH DAMAGE. * * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 - * $Id: fil.c,v 2.35.2.8 2000/05/22 10:26:09 darrenr Exp $ + * $Id: fil.c,v 2.35.2.18 2000/07/19 13:13:40 darrenr Exp $ */ /* * Copy data from an mbuf chain starting "off" bytes from the beginning, @@ -1814,6 +1818,7 @@ void frsync() ip_natsync(ifp); ip_statesync(ifp); } + ip_natsync((struct ifnet *)-1); # endif WRITE_ENTER(&ipf_mutex); diff --git a/sys/netinet/ip_auth.c b/sys/netinet/ip_auth.c index 4df787585ea8..14c4f8208611 100644 --- a/sys/netinet/ip_auth.c +++ b/sys/netinet/ip_auth.c @@ -47,7 +47,7 @@ static const char rcsid[] = "@(#)$FreeBSD$"; # include # include #endif -#if _BSDI_VERSION >= 199802 +#if (_BSDI_VERSION >= 199802) || (__FreeBSD_Version >= 400000) # include #endif #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(bsdi) diff --git a/sys/netinet/ip_fil.c b/sys/netinet/ip_fil.c index 3da5a1fb0817..746df30dabf3 100644 --- a/sys/netinet/ip_fil.c +++ b/sys/netinet/ip_fil.c @@ -7,7 +7,7 @@ */ #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.16 2000/01/16 10:12:42 darrenr Exp $";*/ +/*static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.42.2.14 2000/07/18 13:57:55 darrenr Exp $";*/ static const char rcsid[] = "@(#)$FreeBSD$"; #endif @@ -694,6 +694,10 @@ caddr_t data; if (error) return EFAULT; fp->fr_ref = 0; +#if (BSD >= 199306) && defined(_KERNEL) + if ((securelevel > 0) && (fp->fr_func != NULL)) + return EPERM; +#endif /* * Check that the group number does exist and that if a head group @@ -766,7 +770,7 @@ caddr_t data; * interface pointer in the comparison (fr_next, fr_ifa). */ for (fp->fr_cksum = 0, p = (u_int *)&fp->fr_ip, pp = &fp->fr_cksum; - p != pp; p++) + p < pp; p++) fp->fr_cksum += *p; for (; (f = *ftail); ftail = &f->fr_next) @@ -1090,6 +1094,19 @@ int dst; m = NULL; ifp = fin->fin_ifp; if (fin->fin_v == 4) { + 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; + } + # if (BSD < 199306) || defined(__sgi) avail = MLEN; m = m_get(M_DONTWAIT, MT_HEADER); @@ -1327,10 +1344,9 @@ frdest_t *fdp; ATOMIC_INCL(frstats[1].fr_acct); } fin->fin_fr = NULL; - if (!fr || !(fr->fr_flags & FR_RETMASK)) { + if (!fr || !(fr->fr_flags & FR_RETMASK)) (void) fr_checkstate(ip, fin); - (void) ip_natout(ip, fin); - } + (void) ip_natout(ip, fin); } else ip->ip_sum = 0; /* @@ -1587,15 +1603,29 @@ int v; if (!ifneta) { ifneta = (struct ifnet **)malloc(sizeof(ifp) * 2); + if (!ifneta) + return NULL; ifneta[1] = NULL; ifneta[0] = (struct ifnet *)calloc(1, sizeof(*ifp)); + if (!ifneta[0]) { + free(ifneta); + return NULL; + } nifs = 1; } else { nifs++; ifneta = (struct ifnet **)realloc(ifneta, (nifs + 1) * sizeof(*ifa)); + if (!ifneta) { + nifs = 0; + return NULL; + } ifneta[nifs] = NULL; ifneta[nifs - 1] = (struct ifnet *)malloc(sizeof(*ifp)); + if (!ifneta[nifs - 1]) { + nifs--; + return NULL; + } } ifp = ifneta[nifs - 1]; diff --git a/sys/netinet/ip_fil.h b/sys/netinet/ip_fil.h index eb3154dea09c..0d7ff052fa87 100644 --- a/sys/netinet/ip_fil.h +++ b/sys/netinet/ip_fil.h @@ -6,7 +6,7 @@ * to the original author and the contributors. * * @(#)ip_fil.h 1.35 6/5/96 - * $Id: ip_fil.h,v 2.3.2.7 2000/01/27 08:49:41 darrenr Exp $ + * $Id: ip_fil.h,v 2.29.2.3 2000/06/05 13:12:42 darrenr Exp $ * $FreeBSD$ */ @@ -521,8 +521,8 @@ extern int iplioctl __P((dev_t, int, int *, int, cred_t *, int *)); 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 ipfr_fastroute __P((qif_t *, ip_t *, mblk_t *, mblk_t **, - fr_info_t *, frdest_t *)); +extern int ipfr_fastroute __P((ip_t *, mblk_t *, mblk_t **, + fr_info_t *, frdest_t *)); extern void copyin_mblk __P((mblk_t *, size_t, size_t, char *)); extern void copyout_mblk __P((mblk_t *, size_t, size_t, char *)); extern int fr_qin __P((queue_t *, mblk_t *)); diff --git a/sys/netinet/ip_frag.c b/sys/netinet/ip_frag.c index c99fe3ec456d..8d2bbc5c6787 100644 --- a/sys/netinet/ip_frag.c +++ b/sys/netinet/ip_frag.c @@ -7,7 +7,7 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-1995 Darren Reed"; -/*static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.4.2.4 1999/11/28 04:52:10 darrenr Exp $";*/ +/*static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.10.2.4 2000/06/06 15:49:15 darrenr Exp $";*/ static const char rcsid[] = "@(#)$FreeBSD$"; #endif @@ -145,6 +145,9 @@ ipfr_t *table[]; ipfr_t **fp, *fra, frag; u_int idx; + if (ipfr_inuse >= IPFT_SIZE) + return NULL; + frag.ipfr_p = ip->ip_p; idx = ip->ip_p; frag.ipfr_id = ip->ip_id; diff --git a/sys/netinet/ip_ftp_pxy.c b/sys/netinet/ip_ftp_pxy.c index b6a658360b8a..0eb54c0bb66b 100644 --- a/sys/netinet/ip_ftp_pxy.c +++ b/sys/netinet/ip_ftp_pxy.c @@ -8,7 +8,10 @@ extern kmutex_t ipf_rw; #endif #define isdigit(x) ((x) >= '0' && (x) <= '9') -#define isupper(x) ((unsigned)((x) - 'A') <= 'Z' - 'A') +#define isupper(x) (((unsigned)(x) >= 'A') && ((unsigned)(x) <= 'Z')) +#define islower(x) (((unsigned)(x) >= 'a') && ((unsigned)(x) <= 'z')) +#define isalpha(x) (isupper(x) || islower(x)) +#define toupper(x) (isupper(x) ? (x) : (x) - 'a' + 'A') #define IPF_FTP_PROXY @@ -34,6 +37,7 @@ u_short ippr_ftp_atoi __P((char **)); static frentry_t natfr; int ippr_ftp_pasvonly = 0; +int ippr_ftp_insecure = 0; /* @@ -96,21 +100,12 @@ int dlen; #endif tcp = (tcphdr_t *)fin->fin_dp; - off = f->ftps_seq - ntohl(tcp->th_seq); - if (off < 0) - return 0; /* * Check for client sending out PORT message. */ if (dlen < IPF_MINPORTLEN) return 0; - /* - * Count the number of bytes in the PORT message is. - */ - if (off < 0) - return 0; - - off += fin->fin_hlen + (tcp->th_off << 2); + off = fin->fin_hlen + (tcp->th_off << 2); /* * Skip the PORT command + space */ @@ -200,6 +195,10 @@ int dlen; m_adj(m, inc); /* the mbuf chain will be extended if necessary by m_copyback() */ m_copyback(m, off, nlen, newbuf); +# ifdef M_PKTHDR + if (!(m->m_flags & M_PKTHDR)) + m->m_pkthdr.len += inc; +# endif #endif if (inc != 0) { #if SOLARIS || defined(__sgi) @@ -274,27 +273,39 @@ ftpinfo_t *ftp; ip_t *ip; int dlen; { - char *rptr, *wptr; + char *rptr, *wptr, cmd[6], c; ftpside_t *f; - int inc; + int inc, i; inc = 0; f = &ftp->ftp_side[0]; rptr = f->ftps_rptr; wptr = f->ftps_wptr; - if ((ftp->ftp_passok == 0) && !strncmp(rptr, "USER ", 5)) + for (i = 0; (i < 5) && (i < dlen); i++) { + c = rptr[i]; + if (isalpha(c)) { + cmd[i] = toupper(c); + } else { + cmd[i] = c; + } + } + cmd[i] = '\0'; + + if ((ftp->ftp_passok == 0) && !strncmp(cmd, "USER ", 5)) ftp->ftp_passok = 1; - else if ((ftp->ftp_passok == 2) && !strncmp(rptr, "PASS ", 5)) + else if ((ftp->ftp_passok == 2) && !strncmp(cmd, "PASS ", 5)) ftp->ftp_passok = 3; else if ((ftp->ftp_passok == 4) && !ippr_ftp_pasvonly && - !strncmp(rptr, "PORT ", 5)) { + !strncmp(cmd, "PORT ", 5)) { + inc = ippr_ftp_port(fin, ip, nat, f, dlen); + } else if (ippr_ftp_insecure && !ippr_ftp_pasvonly && + !strncmp(cmd, "PORT ", 5)) { inc = ippr_ftp_port(fin, ip, nat, f, dlen); } while ((*rptr++ != '\n') && (rptr < wptr)) ; - f->ftps_seq += rptr - f->ftps_rptr; f->ftps_rptr = rptr; return inc; } @@ -312,8 +323,8 @@ int dlen; u_short a5, a6, sp, dp; u_int a1, a2, a3, a4; fr_info_t fi; - int inc, off; nat_t *ipn; + int inc; char *s; /* @@ -324,15 +335,8 @@ int dlen; else if (strncmp(f->ftps_rptr, "227 Entering Passive Mode", 25)) return 0; - /* - * Count the number of bytes in the 227 reply is. - */ tcp = (tcphdr_t *)fin->fin_dp; - off = f->ftps_seq - ntohl(tcp->th_seq); - if (off < 0) - return 0; - off += fin->fin_hlen + (tcp->th_off << 2); /* * Skip the PORT command + space */ @@ -416,13 +420,13 @@ int dlen; m1->b_wptr += inc; } /*copyin_mblk(m, off, nlen, newbuf);*/ -#else +#else /* SOLARIS */ m = *((mb_t **)fin->fin_mp); if (inc < 0) m_adj(m, inc); /* the mbuf chain will be extended if necessary by m_copyback() */ /*m_copyback(m, off, nlen, newbuf);*/ -#endif +#endif /* SOLARIS */ if (inc != 0) { #if SOLARIS || defined(__sgi) register u_32_t sum1, sum2; @@ -437,10 +441,10 @@ int dlen; sum2 = (sum2 & 0xffff) + (sum2 >> 16); fix_outcksum(&ip->ip_sum, sum2, 0); -#endif +#endif /* SOLARIS || defined(__sgi) */ ip->ip_len += inc; } -#endif +#endif /* 0 */ /* * Add skeleton NAT entry for connection which will come back the @@ -506,10 +510,11 @@ int dlen; ftp->ftp_passok = 0; else if ((ftp->ftp_passok == 4) && !strncmp(rptr, "227 ", 4)) { inc = ippr_ftp_pasv(fin, ip, nat, f, dlen); + } else if (ippr_ftp_insecure && !strncmp(rptr, "227 ", 4)) { + inc = ippr_ftp_pasv(fin, ip, nat, f, dlen); } while ((*rptr++ != '\n') && (rptr < wptr)) ; - f->ftps_seq += rptr - f->ftps_rptr; f->ftps_rptr = rptr; return inc; } @@ -547,16 +552,16 @@ size_t len; return 1; } else return 1; - } else if (isupper(c)) { + } else if (isalpha(c)) { c = *s++; i--; - if (isupper(c)) { + if (isalpha(c)) { c = *s++; i--; - if (isupper(c)) { + if (isalpha(c)) { c = *s++; i--; - if (isupper(c)) { + if (isalpha(c)) { c = *s++; i--; if ((c != ' ') && (c != '\r')) @@ -585,10 +590,10 @@ nat_t *nat; ftpinfo_t *ftp; int rv; { - int mlen, len, off, inc, i; + int mlen, len, off, inc, i, sel; char *rptr, *wptr; + ftpside_t *f, *t; tcphdr_t *tcp; - ftpside_t *f; mb_t *m; tcp = (tcphdr_t *)fin->fin_dp; @@ -605,23 +610,29 @@ int rv; #else mlen = mbufchainlen(m) - off; #endif - if (!mlen) + t = &ftp->ftp_side[1 - rv]; + if (!mlen) { + t->ftps_seq = ntohl(tcp->th_ack); return 0; + } inc = 0; f = &ftp->ftp_side[rv]; rptr = f->ftps_rptr; wptr = f->ftps_wptr; - if ((wptr == f->ftps_buf) && (f->ftps_seq <= ntohl(tcp->th_seq))) - f->ftps_seq = ntohl(tcp->th_seq); + sel = nat->nat_aps->aps_sel[1 - rv]; + if (rv) + i = nat->nat_aps->aps_ackoff[sel]; + else + i = nat->nat_aps->aps_seqoff[sel]; /* * XXX - Ideally, this packet should get dropped because we now know * that it is out of order (and there is no real danger in doing so * apart from causing packets to go through here ordered). */ - if (ntohl(tcp->th_seq) != f->ftps_seq + (wptr - rptr)) { - return APR_ERR(0); + if (ntohl(tcp->th_seq) + i != f->ftps_seq) { + return APR_ERR(-1); } while (mlen > 0) { @@ -665,7 +676,6 @@ int rv; } else rptr++; } - f->ftps_seq += rptr - f->ftps_rptr; f->ftps_rptr = rptr; } @@ -676,7 +686,6 @@ int rv; i = wptr - rptr; if ((rptr == f->ftps_buf) || (wptr - rptr > FTP_BUFSZ / 2)) { - f->ftps_seq += i; f->ftps_junk = 1; rptr = wptr = f->ftps_buf; } else { @@ -690,6 +699,7 @@ int rv; } } + t->ftps_seq = ntohl(tcp->th_ack); f->ftps_rptr = rptr; f->ftps_wptr = wptr; return inc; diff --git a/sys/netinet/ip_log.c b/sys/netinet/ip_log.c index 7d6f0b158e33..9178c74742ff 100644 --- a/sys/netinet/ip_log.c +++ b/sys/netinet/ip_log.c @@ -5,7 +5,7 @@ * provided that this notice is preserved and due credit is given * to the original author and the contributors. * - * $Id: ip_log.c,v 2.1.2.2 1999/09/21 11:55:44 darrenr Exp $ + * $Id: ip_log.c,v 2.5.2.1 2000/07/19 13:11:47 darrenr Exp $ * $FreeBSD$ */ #include @@ -26,7 +26,11 @@ # endif # endif # else -# include +# ifdef KLD_MODULE +# include +# else +# include +# endif # endif #endif #ifdef IPFILTER_LOG diff --git a/sys/netinet/ip_nat.c b/sys/netinet/ip_nat.c index 34dc99ba28f3..dc0c7f21ae82 100644 --- a/sys/netinet/ip_nat.c +++ b/sys/netinet/ip_nat.c @@ -9,7 +9,7 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed"; -/*static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.2.2.12 2000/01/24 12:43:40 darrenr Exp $";*/ +/*static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.37.2.16 2000/07/18 13:57:40 darrenr Exp $";*/ static const char rcsid[] = "@(#)$FreeBSD$"; #endif @@ -474,10 +474,14 @@ int mode; n->in_next = NULL; *np = n; - if (n->in_redir & NAT_REDIRECT) + if (n->in_redir & NAT_REDIRECT) { + n->in_flags &= ~IPN_NOTDST; nat_addrdr(n); - if (n->in_redir & (NAT_MAP|NAT_MAPBLK)) + } + if (n->in_redir & (NAT_MAP|NAT_MAPBLK)) { + n->in_flags &= ~IPN_NOTSRC; nat_addnat(n); + } n->in_use = 0; if (n->in_redir & NAT_MAPBLK) @@ -1518,6 +1522,8 @@ int dir; ip_t *oip; int flags = 0; + if ((fin->fin_fi.fi_fl & FI_SHORT) || (ip->ip_off & IP_OFFMASK)) + return NULL; if ((ip->ip_v != 4) || !(nat = nat_icmplookup(ip, fin, dir))) return NULL; *nflags = IPN_ICMPERR; @@ -1560,14 +1566,14 @@ int dir; fix_outcksum(&icmp->icmp_cksum, sumd, 0); } else { fix_outcksum(&oip->ip_sum, sumd, 0); - +#if !SOLARIS && !defined(__sgi) sumd += (sumd & 0xffff); while (sumd > 0xffff) sumd = (sumd & 0xffff) + (sumd >> 16); -/* fix_incksum(&icmp->icmp_cksum, sumd, 0); */ + fix_incksum(&icmp->icmp_cksum, sumd, 0); +#endif } - if ((flags & IPN_TCPUDP) != 0) { tcphdr_t *tcp; @@ -1715,19 +1721,28 @@ ip_t *ip; if (np->in_p && ip->ip_p != np->in_p) return 0; if (fin->fin_out) { - if (!(np->in_redir && (NAT_MAP|NAT_MAPBLK))) + if (!(np->in_redir & (NAT_MAP|NAT_MAPBLK))) return 0; - if ((fin->fin_fi.fi_saddr & np->in_inmsk) != np->in_inip) + if (((fin->fin_fi.fi_saddr & np->in_inmsk) != np->in_inip) + ^ ((np->in_flags & IPN_NOTSRC) != 0)) return 0; - if ((fin->fin_fi.fi_daddr & np->in_srcmsk) != np->in_srcip) + if (((fin->fin_fi.fi_daddr & np->in_srcmsk) != np->in_srcip) + ^ ((np->in_flags & IPN_NOTDST) != 0)) return 0; } else { - if (!(np->in_redir && NAT_REDIRECT)) + if (!(np->in_redir & NAT_REDIRECT)) + return 0; + if (((fin->fin_fi.fi_saddr & np->in_srcmsk) != np->in_srcip) + ^ ((np->in_flags & IPN_NOTSRC) != 0)) + return 0; + if (((fin->fin_fi.fi_daddr & np->in_outmsk) != np->in_outip) + ^ ((np->in_flags & IPN_NOTDST) != 0)) return 0; } ft = &np->in_tuc; - if (!(fin->fin_fi.fi_fl & FI_TCPUDP)) { + if (!(fin->fin_fi.fi_fl & FI_TCPUDP) || + (fin->fin_fi.fi_fl & FI_SHORT) || (ip->ip_off & IP_OFFMASK)) { if (ft->ftu_scmp || ft->ftu_dcmp) return 0; return 1; @@ -1864,7 +1879,6 @@ maskloop: np = nat->nat_ptr; if (natadd && fin->fin_fi.fi_fl & FI_FRAG) ipfr_nat_newfrag(ip, fin, 0, nat); - ip->ip_src = nat->nat_outip; MUTEX_ENTER(&nat->nat_lock); nat->nat_age = fr_defnatage; nat->nat_bytes += ip->ip_len; @@ -1875,12 +1889,27 @@ maskloop: * Fix up checksums, not by recalculating them, but * simply computing adjustments. */ + if (nflags == IPN_ICMPERR) { + u_32_t s1, s2, sumd; + + s1 = LONG_SUM(ntohl(ip->ip_src.s_addr)); + s2 = LONG_SUM(ntohl(nat->nat_outip.s_addr)); + CALC_SUMD(s1, s2, sumd); + + if (nat->nat_dir == NAT_OUTBOUND) + fix_incksum(&ip->ip_sum, sumd, 0); + else + fix_outcksum(&ip->ip_sum, sumd, 0); + } #if SOLARIS || defined(__sgi) - if (nat->nat_dir == NAT_OUTBOUND) - fix_outcksum(&ip->ip_sum, nat->nat_ipsumd, 0); - else - fix_incksum(&ip->ip_sum, nat->nat_ipsumd, 0); + else { + if (nat->nat_dir == NAT_OUTBOUND) + fix_outcksum(&ip->ip_sum, nat->nat_ipsumd, 0); + else + fix_incksum(&ip->ip_sum, nat->nat_ipsumd, 0); + } #endif + ip->ip_src = nat->nat_outip; if (!(ip->ip_off & IP_OFFMASK) && !(fin->fin_fi.fi_fl & FI_SHORT)) { @@ -1918,6 +1947,7 @@ maskloop: } else if (ip->ip_p == IPPROTO_ICMP) { nat->nat_age = fr_defnaticmpage; } + if (csump) { if (nat->nat_dir == NAT_OUTBOUND) fix_outcksum(csump, nat->nat_sumd[1], @@ -1987,7 +2017,7 @@ fr_info_t *fin; if ((ip->ip_p == IPPROTO_ICMP) && (nat = nat_icmp(ip, fin, &nflags, NAT_INBOUND))) ; - else if ((ip->ip_off & IP_OFFMASK) && + else if ((ip->ip_off & (IP_OFFMASK|IP_MF)) && (nat = ipfr_nat_knownfrag(ip, fin))) natadd = 0; else if ((nat = nat_inlookup(fin->fin_ifp, nflags, (u_int)ip->ip_p, @@ -2025,7 +2055,7 @@ maskloop: } else if ((in.s_addr & np->in_outmsk) != np->in_outip) continue; if ((np->in_redir & NAT_REDIRECT) && - (!np->in_pmin || + (!np->in_pmin || (np->in_flags & IPN_FILTER) || ((ntohs(np->in_pmax) >= ntohs(dport)) && (ntohs(dport) >= ntohs(np->in_pmin))))) if ((nat = nat_new(np, ip, fin, nflags, diff --git a/sys/netinet/ip_nat.h b/sys/netinet/ip_nat.h index 00d93b0220ce..b5d53e8b8b66 100644 --- a/sys/netinet/ip_nat.h +++ b/sys/netinet/ip_nat.h @@ -6,7 +6,7 @@ * to the original author and the contributors. * * @(#)ip_nat.h 1.5 2/4/96 - * $Id: ip_nat.h,v 2.1.2.3 2000/01/24 12:44:24 darrenr Exp $ + * $Id: ip_nat.h,v 2.17.2.6 2000/07/15 14:50:06 darrenr Exp $ * $FreeBSD$ */ @@ -104,9 +104,10 @@ typedef struct ipnat { u_int in_hits; struct in_addr in_nextip; u_short in_pnext; - u_short in_ppip; /* ports per IP */ u_short in_ippip; /* IP #'s per IP# */ - u_short in_flags; /* From here to in_dport must be reflected */ + u_32_t in_flags; /* From here to in_dport must be reflected */ + u_short in_spare; + u_short in_ppip; /* ports per IP */ u_short in_port[2]; /* correctly in IPN_CMPSIZ */ struct in_addr in_in[2]; struct in_addr in_out[2]; @@ -213,11 +214,13 @@ typedef struct natstat { #define IPN_RF (IPN_TCPUDP|IPN_DELETE|IPN_ICMPERR) #define IPN_AUTOPORTMAP 0x010 #define IPN_IPRANGE 0x020 -#define IPN_USERFLAGS (IPN_TCPUDP|IPN_AUTOPORTMAP|IPN_IPRANGE|\ - IPN_SPLIT|IPN_ROUNDR|IPN_FILTER) +#define IPN_USERFLAGS (IPN_TCPUDP|IPN_AUTOPORTMAP|IPN_IPRANGE|IPN_SPLIT|\ + IPN_ROUNDR|IPN_FILTER|IPN_NOTSRC|IPN_NOTDST) #define IPN_FILTER 0x040 #define IPN_SPLIT 0x080 #define IPN_ROUNDR 0x100 +#define IPN_NOTSRC 0x080000 +#define IPN_NOTDST 0x100000 typedef struct natlog { @@ -237,6 +240,8 @@ typedef struct natlog { #define NL_NEWMAP NAT_MAP #define NL_NEWRDR NAT_REDIRECT +#define NL_NEWBIMAP NAT_BIMAP +#define NL_NEWBLOCK NAT_MAPBLK #define NL_EXPIRE 0xffff #define NAT_HASH_FN(k,l,m) (((k) + ((k) >> 12) + l) % (m)) diff --git a/sys/netinet/ip_rcmd_pxy.c b/sys/netinet/ip_rcmd_pxy.c index ad60752d9a90..112171f815ba 100644 --- a/sys/netinet/ip_rcmd_pxy.c +++ b/sys/netinet/ip_rcmd_pxy.c @@ -1,5 +1,5 @@ /* - * $Id: ip_rcmd_pxy.c,v 1.4.2.1 2000/05/06 11:19:34 darrenr Exp $ + * $Id: ip_rcmd_pxy.c,v 1.4.2.2 2000/07/15 12:38:30 darrenr Exp $ */ /* * Simple RCMD transparent proxy for in-kernel use. For use with the NAT @@ -94,8 +94,17 @@ nat_t *nat; #endif tcp = (tcphdr_t *)fin->fin_dp; + + if (tcp->th_flags & TH_SYN) { + *(u_32_t *)aps->aps_data = htonl(ntohl(tcp->th_seq) + 1); + return 0; + } + + if ((*(u_32_t *)aps->aps_data != 0) && + (tcp->th_seq != *(u_32_t *)aps->aps_data)) + return 0; + off = (ip->ip_hl << 2) + (tcp->th_off << 2); - m = *(mb_t **)fin->fin_mp; #if SOLARIS m = fin->fin_qfm; @@ -104,13 +113,11 @@ nat_t *nat; bzero(portbuf, sizeof(portbuf)); copyout_mblk(m, off, MIN(sizeof(portbuf), dlen), portbuf); #else + m = *(mb_t **)fin->fin_mp; dlen = mbufchainlen(m) - off; bzero(portbuf, sizeof(portbuf)); m_copydata(m, off, MIN(sizeof(portbuf), dlen), portbuf); #endif - if ((*(u_32_t *)aps->aps_data != 0) && - (tcp->th_seq != *(u_32_t *)aps->aps_data)) - return 0; portbuf[sizeof(portbuf) - 1] = '\0'; s = portbuf; diff --git a/sys/netinet/ip_state.c b/sys/netinet/ip_state.c index 3176ea0a9096..e5166d8ae1c4 100644 --- a/sys/netinet/ip_state.c +++ b/sys/netinet/ip_state.c @@ -381,8 +381,8 @@ caddr_t data; { register ipstate_t *is, *isn; ipstate_save_t ips, *ipsp; + int error, out; frentry_t *fr; - int error; error = IRCOPY(data, (caddr_t)&ipsp, sizeof(ipsp)); if (error) @@ -405,8 +405,26 @@ caddr_t data; return ENOMEM; } bcopy((char *)&ips.ips_fr, (char *)fr, sizeof(*fr)); + out = fr->fr_flags & FR_OUTQUE ? 1 : 0; isn->is_rule = fr; ips.ips_is.is_rule = fr; + if (*fr->fr_ifname) { + fr->fr_ifa = GETUNIT(fr->fr_ifname, fr->fr_v); + if (fr->fr_ifa == NULL) + fr->fr_ifa = (void *)-1; +#ifdef _KERNEL + else { + strncpy(isn->is_ifname[out], + IFNAME(fr->fr_ifa), IFNAMSIZ); + isn->is_ifp[out] = fr->fr_ifa; + } +#endif + } else + fr->fr_ifa = NULL; + /* + * send a copy back to userland of what we ended up + * to allow for verification. + */ error = IWCOPY((caddr_t)&ips, ipsp, sizeof(ips)); if (error) { KFREE(isn); @@ -1582,8 +1600,8 @@ fr_info_t *fin; (oic->icmp6_type == ICMP6_ECHO_REQUEST)) || (is->is_type - 1 == oic->icmp6_type )) { ips_stats.iss_hits++; - is->is_pkts++; - is->is_bytes += fin->fin_plen; + is->is_pkts++; + is->is_bytes += fin->fin_plen; return is->is_rule; } } diff --git a/sys/netinet/ip_state.h b/sys/netinet/ip_state.h index 675b50b9d916..2374068b6688 100644 --- a/sys/netinet/ip_state.h +++ b/sys/netinet/ip_state.h @@ -6,7 +6,7 @@ * to the original author and the contributors. * * @(#)ip_state.h 1.3 1/12/96 (C) 1995 Darren Reed - * $Id: ip_state.h,v 2.1.2.2 2000/01/24 13:13:52 darrenr Exp $ + * $Id: ip_state.h,v 2.13.2.1 2000/07/08 02:15:35 darrenr Exp $ * $FreeBSD$ */ #ifndef __IP_STATE_H__ @@ -18,8 +18,8 @@ # define SIOCDELST _IOW(r, 61, struct ipstate *) #endif -#define IPSTATE_SIZE 257 -#define IPSTATE_MAX 2048 /* Maximum number of states held */ +#define IPSTATE_SIZE 5737 +#define IPSTATE_MAX 4013 /* Maximum number of states held */ #define PAIRS(s1,d1,s2,d2) ((((s1) == (s2)) && ((d1) == (d2))) ||\ (((s1) == (d2)) && ((d1) == (s2)))) diff --git a/sys/netinet/ipl.h b/sys/netinet/ipl.h index 6fd97c8922fe..a0f595d4d069 100644 --- a/sys/netinet/ipl.h +++ b/sys/netinet/ipl.h @@ -12,6 +12,6 @@ #ifndef __IPL_H__ #define __IPL_H__ -#define IPL_VERSION "IP Filter: v3.4.4" +#define IPL_VERSION "IP Filter: v3.4.8" #endif