diff -cr ip_fil3.4.1/HISTORY ip_fil3.4.2/HISTORY *** ip_fil3.4.1/HISTORY Sun Apr 30 15:20:58 2000 --- ip_fil3.4.2/HISTORY Wed May 10 08:47:36 2000 *************** *** 20,25 **** --- 20,37 ---- # and especially those who have found the time to port IP Filter to new # platforms. # + 3.4.2 - 10/5/2000 - Released + + Fix bug in dealing with "hlen == 1 and opt > 1" - Itojun + + ignore previous NAT mappings for 0/0 and 0/32 rules + + bring in a completely new ftp proxy + + allow NAT to cause packets to be dropped. + + add NetBSD callout support for 1.4-current + 3.4.1 - 30/4/2000 - Released add ratoui() and fix parsing of group numbers to allow 0 - UINT_MAX diff -cr ip_fil3.4.1/SunOS5/pkginfo ip_fil3.4.2/SunOS5/pkginfo *** ip_fil3.4.1/SunOS5/pkginfo Sun Apr 30 15:13:55 2000 --- ip_fil3.4.2/SunOS5/pkginfo Wed May 10 08:44:14 2000 *************** *** 5,11 **** PKG=ipf NAME=IP Filter ARCH=ARCH_updated_by_sed_when_package_is_built ! VERSION=3.4.1 CATEGORY=system DESC=This package contains tools for building a firewall VENDOR=Darren Reed --- 5,11 ---- PKG=ipf NAME=IP Filter ARCH=ARCH_updated_by_sed_when_package_is_built ! VERSION=3.4.2 CATEGORY=system DESC=This package contains tools for building a firewall VENDOR=Darren Reed diff -cr ip_fil3.4.1/common.c ip_fil3.4.2/common.c *** ip_fil3.4.1/common.c Sat Apr 29 01:31:02 2000 --- ip_fil3.4.2/common.c Sat May 6 21:20:10 2000 *************** *** 574,576 **** --- 574,595 ---- printf(" port %s %s", pcmp1[frp->frp_cmp], portname(pr, frp->frp_port)); } + + + void printbuf(buf, len, zend) + char *buf; + int len, zend; + { + char *s, c; + int i; + + for (s = buf, i = len; i; i--) { + c = *s++; + if (isprint(c)) + putchar(c); + else + printf("\\%03o", c); + if ((c == '\0') && zend) + break; + } + } diff -cr ip_fil3.4.1/fil.c ip_fil3.4.2/fil.c *** ip_fil3.4.1/fil.c Sat Apr 29 01:38:32 2000 --- ip_fil3.4.2/fil.c Wed May 10 08:42:40 2000 *************** *** 7,13 **** */ #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.35.2.4 2000/04/28 15:38:32 darrenr Exp $"; #endif #if defined(_KERNEL) && defined(__FreeBSD_version) && \ --- 7,13 ---- */ #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.35.2.6 2000/05/09 22:42:40 darrenr Exp $"; #endif #if defined(_KERNEL) && defined(__FreeBSD_version) && \ *************** *** 330,342 **** } #endif ! for (s = (u_char *)(ip + 1), hlen -= (int)sizeof(*ip); hlen; ) { opt = *s; if (opt == '\0') break; ! ol = (opt == IPOPT_NOP) ? 1 : (int)*(s+1); ! if (opt > 1 && (ol < 2 || ol > hlen)) ! break; for (i = 9, mv = 4; mv >= 0; ) { op = ipopts + i; if (opt == (u_char)op->ol_val) { --- 330,348 ---- } #endif ! for (s = (u_char *)(ip + 1), hlen -= (int)sizeof(*ip); hlen > 0; ) { opt = *s; if (opt == '\0') break; ! else if (opt == IPOPT_NOP) ! ol = 1; ! else { ! if (hlen < 2) ! break; ! ol = (int)*(s + 1); ! if (ol < 2 || ol > hlen) ! break; ! } for (i = 9, mv = 4; mv >= 0; ) { op = ipopts + i; if (opt == (u_char)op->ol_val) { *************** *** 1062,1067 **** --- 1068,1077 ---- * Once we're finished return to our caller, freeing the packet if * we are dropping it (* BSD ONLY *). */ + if ((changed == -1) && (pass & FR_PASS)) { + pass &= ~FR_PASS; + pass |= FR_BLOCK; + } #if defined(_KERNEL) # if !SOLARIS # if !defined(linux) *************** *** 1325,1331 **** * SUCH DAMAGE. * * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 ! * $Id: fil.c,v 2.35.2.4 2000/04/28 15:38:32 darrenr Exp $ */ /* * Copy data from an mbuf chain starting "off" bytes from the beginning, --- 1335,1341 ---- * SUCH DAMAGE. * * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 ! * $Id: fil.c,v 2.35.2.6 2000/05/09 22:42:40 darrenr Exp $ */ /* * Copy data from an mbuf chain starting "off" bytes from the beginning, diff -cr ip_fil3.4.1/fils.c ip_fil3.4.2/fils.c *** ip_fil3.4.1/fils.c Sat Apr 29 03:03:11 2000 --- ip_fil3.4.2/fils.c Mon May 8 22:35:51 2000 *************** *** 65,71 **** #if !defined(lint) static const char sccsid[] = "@(#)fils.c 1.21 4/20/96 (C) 1993-2000 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: fils.c,v 2.21.2.1 2000/04/28 17:03:11 darrenr Exp $"; #endif extern char *optarg; --- 65,71 ---- #if !defined(lint) static const char sccsid[] = "@(#)fils.c 1.21 4/20/96 (C) 1993-2000 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: fils.c,v 2.21.2.3 2000/05/08 12:35:51 darrenr Exp $"; #endif extern char *optarg; *************** *** 155,161 **** --- 155,165 ---- static void Usage(name) char *name; { + #ifdef USE_INET6 + fprintf(stderr, "Usage: %s [-6aAfhIinosv] [-d ]\n", name); + #else fprintf(stderr, "Usage: %s [-aAfhIinosv] [-d ]\n", name); + #endif fprintf(stderr, " %s -t [-S source address] [-D destination address] [-P protocol] [-T refreshtime] [-C] [-d ]\n", name); exit(1); } *************** *** 449,463 **** fp->fr_flags |= FR_OUTQUE; if (opts & (OPT_HITS|OPT_VERBOSE)) #ifdef USE_QUAD_T ! PRINTF("%qd ", fp->fr_hits); #else ! PRINTF("%ld ", fp->fr_hits); #endif if (opts & (OPT_ACCNT|OPT_VERBOSE)) #ifdef USE_QUAD_T ! PRINTF("%qd ", fp->fr_bytes); #else ! PRINTF("%ld ", fp->fr_bytes); #endif if (opts & OPT_SHOWLINENO) PRINTF("@%d ", n); --- 453,467 ---- fp->fr_flags |= FR_OUTQUE; if (opts & (OPT_HITS|OPT_VERBOSE)) #ifdef USE_QUAD_T ! PRINTF("%qu ", (unsigned long long) fp->fr_hits); #else ! PRINTF("%lu ", fp->fr_hits); #endif if (opts & (OPT_ACCNT|OPT_VERBOSE)) #ifdef USE_QUAD_T ! PRINTF("%qu ", (unsigned long long) fp->fr_bytes); #else ! PRINTF("%lu ", fp->fr_bytes); #endif if (opts & OPT_SHOWLINENO) PRINTF("@%d ", n); *************** *** 557,563 **** ips.is_age, ips.is_pass, ips.is_p, ips.is_state[0], ips.is_state[1]); #ifdef USE_QUAD_T ! PRINTF("\tpkts %qd bytes %qd", ips.is_pkts, ips.is_bytes); #else PRINTF("\tpkts %ld bytes %ld", ips.is_pkts, ips.is_bytes); #endif --- 561,569 ---- ips.is_age, ips.is_pass, ips.is_p, ips.is_state[0], ips.is_state[1]); #ifdef USE_QUAD_T ! PRINTF("\tpkts %qu bytes %qu", ! (unsigned long long) ips.is_pkts, ! (unsigned long long) ips.is_bytes); #else PRINTF("\tpkts %ld bytes %ld", ips.is_pkts, ips.is_bytes); #endif *************** *** 900,908 **** printw(" %4s", str1); /* print #pkt/#bytes */ #ifdef USE_QUAD_T ! printw(" %7qu %9qu", tp->st_pkts, tp->st_bytes); #else ! printw(" %7ld %9ld", tp->st_pkts, tp->st_bytes); #endif printw(" %9s", ttl_to_string(tp->st_age)); --- 906,915 ---- printw(" %4s", str1); /* print #pkt/#bytes */ #ifdef USE_QUAD_T ! printw(" %7qu %9qu", (unsigned long long) tp->st_pkts, ! (unsigned long long) tp->st_bytes); #else ! printw(" %7lu %9lu", tp->st_pkts, tp->st_bytes); #endif printw(" %9s", ttl_to_string(tp->st_age)); *************** *** 996,1003 **** frauthent_t *frap, fra; #ifdef USE_QUAD_T ! printf("Authorisation hits: %qd\tmisses %qd\n", asp->fas_hits, ! asp->fas_miss); #else printf("Authorisation hits: %ld\tmisses %ld\n", asp->fas_hits, asp->fas_miss); --- 1003,1011 ---- frauthent_t *frap, fra; #ifdef USE_QUAD_T ! printf("Authorisation hits: %qu\tmisses %qu\n", ! (unsigned long long) asp->fas_hits, ! (unsigned long long) asp->fas_miss); #else printf("Authorisation hits: %ld\tmisses %ld\n", asp->fas_hits, asp->fas_miss); diff -cr ip_fil3.4.1/ip_fil.c ip_fil3.4.2/ip_fil.c *** ip_fil3.4.1/ip_fil.c Sat Apr 29 00:56:50 2000 --- ip_fil3.4.2/ip_fil.c Wed May 10 08:43:31 2000 *************** *** 7,13 **** */ #if !defined(lint) static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.42.2.2 2000/04/28 14:56:50 darrenr Exp $"; #endif #ifndef SOLARIS --- 7,13 ---- */ #if !defined(lint) static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.42.2.4 2000/05/09 22:43:31 darrenr Exp $"; #endif #ifndef SOLARIS *************** *** 167,172 **** --- 167,176 ---- #if (__FreeBSD_version >= 300000) && defined(_KERNEL) struct callout_handle ipfr_slowtimer_ch; #endif + #if defined(__NetBSD__) && (__NetBSD_Version__ >= 104230000) + # include + struct callout ipfr_slowtimer_ch; + #endif #if (_BSDI_VERSION >= 199510) && defined(_KERNEL) # include *************** *** 309,319 **** # else "disabled"); # endif ! #ifdef _KERNEL ! # if (__FreeBSD_version >= 300000) && defined(_KERNEL) ! ipfr_slowtimer_ch = timeout(ipfr_slowtimer, NULL, hz/2); # else timeout(ipfr_slowtimer, NULL, hz/2); # endif #endif return 0; --- 313,328 ---- # else "disabled"); # endif ! #ifdef _KERNEL ! # if defined(__NetBSD__) && (__NetBSD_Version__ >= 104230000) ! callout_init(&ipfr_slowtimer_ch); ! callout_reset(&ipfr_slowtimer_ch, hz / 2, ipfr_slowtimer, NULL); # else + # if (__FreeBSD_version >= 300000) && defined(_KERNEL) + ipfr_slowtimer_ch = timeout(ipfr_slowtimer, NULL, hz/2); + # else timeout(ipfr_slowtimer, NULL, hz/2); + # endif # endif #endif return 0; *************** *** 331,346 **** int error = 0; #endif ! #ifdef _KERNEL ! # if (__FreeBSD_version >= 300000) ! untimeout(ipfr_slowtimer, NULL, ipfr_slowtimer_ch); # else # ifdef __sgi untimeout(ipfr_slowtimer); ! # else untimeout(ipfr_slowtimer, NULL); ! # endif ! # endif #endif SPL_NET(s); if (!fr_running) --- 340,359 ---- int error = 0; #endif ! #ifdef _KERNEL ! # if defined(__NetBSD__) && (__NetBSD_Version__ >= 104230000) ! callout_stop(&ipfr_slowtimer_ch); # else + # if (__FreeBSD_version >= 300000) + untimeout(ipfr_slowtimer, NULL, ipfr_slowtimer_ch); + # else # ifdef __sgi untimeout(ipfr_slowtimer); ! # else untimeout(ipfr_slowtimer, NULL); ! # endif ! # endif /* FreeBSD */ ! # endif /* NetBSD */ #endif SPL_NET(s); if (!fr_running) *************** *** 1342,1347 **** --- 1355,1363 ---- * If small enough for interface, can just send directly. */ if (ip->ip_len <= ifp->if_mtu) { + # if BSD >= 199306 + int i = m->m_flags & M_EXT; + # endif # ifndef sparc ip->ip_id = htons(ip->ip_id); ip->ip_len = htons(ip->ip_len); *************** *** 1352,1357 **** --- 1368,1378 ---- # if BSD >= 199306 error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst, ro->ro_rt); + if (i) { + ip->ip_id = ntohs(ip->ip_id); + ip->ip_len = ntohs(ip->ip_len); + ip->ip_off = ntohs(ip->ip_off); + } # else error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst); # endif diff -cr ip_fil3.4.1/ip_frag.c ip_fil3.4.2/ip_frag.c *** ip_fil3.4.1/ip_frag.c Sat Apr 29 00:56:51 2000 --- ip_fil3.4.2/ip_frag.c Sat May 6 01:10:23 2000 *************** *** 7,13 **** */ #if !defined(lint) static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-2000 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.10.2.1 2000/04/28 14:56:51 darrenr Exp $"; #endif #if defined(KERNEL) && !defined(_KERNEL) --- 7,13 ---- */ #if !defined(lint) static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-2000 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.10.2.3 2000/05/05 15:10:23 darrenr Exp $"; #endif #if defined(KERNEL) && !defined(_KERNEL) *************** *** 85,90 **** --- 85,94 ---- extern struct callout_handle ipfr_slowtimer_ch; # endif #endif + #if defined(__NetBSD__) && (__NetBSD_Version__ >= 104230000) + # include + extern struct callout ipfr_slowtimer_ch; + #endif static ipfr_t *ipfr_heads[IPFT_SIZE]; *************** *** 525,544 **** fr_timeoutstate(); ip_natexpire(); fr_authexpire(); ! # if SOLARIS ipfr_timer_id = timeout(ipfr_slowtimer, NULL, drv_usectohz(500000)); # else ! # ifndef linux # if (__FreeBSD_version >= 300000) ipfr_slowtimer_ch = timeout(ipfr_slowtimer, NULL, hz/2); # else timeout(ipfr_slowtimer, NULL, hz/2); # endif ! # endif ! # if (BSD < 199306) && !defined(__sgi) return 0; ! # endif ! # endif ! RWLOCK_EXIT(&ipf_solaris); } #endif /* defined(_KERNEL) */ --- 529,550 ---- fr_timeoutstate(); ip_natexpire(); fr_authexpire(); ! # if SOLARIS ipfr_timer_id = timeout(ipfr_slowtimer, NULL, drv_usectohz(500000)); + RWLOCK_EXIT(&ipf_solaris); # else ! # if defined(__NetBSD__) && (__NetBSD_Version__ >= 104240000) ! callout_reset(&ipfr_slowtimer_ch, hz / 2, ipfr_slowtimer, NULL); ! # else # if (__FreeBSD_version >= 300000) ipfr_slowtimer_ch = timeout(ipfr_slowtimer, NULL, hz/2); # else timeout(ipfr_slowtimer, NULL, hz/2); # endif ! # if (BSD < 199306) && !defined(__sgi) return 0; ! # endif /* FreeBSD */ ! # endif /* NetBSD */ ! # endif /* SOLARIS */ } #endif /* defined(_KERNEL) */ diff -cr ip_fil3.4.1/ip_ftp_pxy.c ip_fil3.4.2/ip_ftp_pxy.c *** ip_fil3.4.1/ip_ftp_pxy.c Sun Apr 30 15:13:05 2000 --- ip_fil3.4.2/ip_ftp_pxy.c Tue May 9 21:41:46 2000 *************** *** 2,8 **** * Simple FTP transparent proxy for in-kernel use. For use with the NAT * code. * ! * $Id: ip_ftp_pxy.c,v 2.7.2.1 2000/04/30 05:13:05 darrenr Exp $ */ #if SOLARIS && defined(_KERNEL) extern kmutex_t ipf_rw; --- 2,8 ---- * Simple FTP transparent proxy for in-kernel use. For use with the NAT * code. * ! * $Id: ip_ftp_pxy.c,v 2.7.2.5 2000/05/09 11:41:46 darrenr Exp $ */ #if SOLARIS && defined(_KERNEL) extern kmutex_t ipf_rw; *************** *** 20,34 **** #define IPF_FTPBUFSZ 96 /* This *MUST* be >= 53! */ int ippr_ftp_init __P((void)); int ippr_ftp_new __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *)); int ippr_ftp_out __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *)); ! int ippr_ftp_in __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *)); ! int ippr_ftp_portmsg __P((fr_info_t *, ip_t *, nat_t *)); ! int ippr_ftp_pasvmsg __P((fr_info_t *, ip_t *, nat_t *)); ! int ippr_ftp_complete __P((char *, size_t)); ! ! u_short ipf_ftp_atoi __P((char **)); static frentry_t natfr; int ippr_ftp_pasvonly = 0; --- 20,37 ---- #define IPF_FTPBUFSZ 96 /* This *MUST* be >= 53! */ + int ippr_ftp_client __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int)); + int ippr_ftp_complete __P((char *, size_t)); + int ippr_ftp_in __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *)); int ippr_ftp_init __P((void)); int ippr_ftp_new __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *)); int ippr_ftp_out __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *)); ! int ippr_ftp_pasv __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *, int)); ! int ippr_ftp_port __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *, int)); ! int ippr_ftp_process __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int)); ! int ippr_ftp_server __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int)); ! int ippr_ftp_valid __P((char *, size_t)); ! u_short ippr_ftp_atoi __P((char **)); static frentry_t natfr; int ippr_ftp_pasvonly = 0; *************** *** 46,122 **** } - int ippr_ftp_complete(buf, len) - char *buf; - size_t len; - { - register char *s, c; - register size_t i = len; - - nextmsg: - if (i < 5) - return 0; - s = buf; - c = *s++; - i = len - 1; - - if (isdigit(c)) { - c = *s++; - i--; - if (isdigit(c)) { - c = *s++; - i--; - if (isdigit(c)) { - c = *s++; - i--; - if (c != '-' && c != ' ') - return 0; - } else - return 0; - } else - return 0; - } else if (isupper(c)) { - c = *s++; - i--; - if (isupper(c)) { - c = *s++; - i--; - if (isupper(c)) { - c = *s++; - i--; - if (isupper(c)) { - c = *s++; - i--; - if (c != ' ' && c != '\r') - return 0; - } else if (c != ' ' && c != '\r') - return 0; - } else - return 0; - } else - return 0; - } else - return 0; - - for (; i && (c = *s); i--, s++) { - if (c == '\r') { - if (i >= 2) - continue; - return 0; - } - if (c == '\n') { - if (i > 1) - goto nextmsg; - } - if ((i == 2) && (c != '\r')) - return 0; - else if ((i == 1) && (c != '\n')) - return 0; - } - return (i == 0); - } - - int ippr_ftp_new(fin, ip, aps, nat) fr_info_t *fin; ip_t *ip; --- 49,54 ---- *************** *** 124,129 **** --- 56,62 ---- nat_t *nat; { ftpinfo_t *ftp; + ftpside_t *f; KMALLOC(ftp, ftpinfo_t *); if (ftp == NULL) *************** *** 132,184 **** aps->aps_psiz = sizeof(ftpinfo_t); bzero((char *)ftp, sizeof(*ftp)); return 0; } ! /* ! * ipf_ftp_atoi - implement a version of atoi which processes numbers in ! * pairs separated by commas (which are expected to be in the range 0 - 255), ! * returning a 16 bit number combining either side of the , as the MSB and ! * LSB. ! */ ! u_short ipf_ftp_atoi(ptr) ! char **ptr; ! { ! register char *s = *ptr, c; ! register u_char i = 0, j = 0; ! ! while ((c = *s++) && isdigit(c)) { ! i *= 10; ! i += c - '0'; ! } ! if (c != ',') { ! *ptr = NULL; ! return 0; ! } ! while ((c = *s++) && isdigit(c)) { ! j *= 10; ! j += c - '0'; ! } ! *ptr = s; ! return (i << 8) | j; ! } ! ! ! int ippr_ftp_portmsg(fin, ip, nat) fr_info_t *fin; ip_t *ip; nat_t *nat; { - char portbuf[IPF_FTPBUFSZ], newbuf[IPF_FTPBUFSZ], *s; tcphdr_t *tcp, tcph, *tcp2 = &tcph; ! size_t nlen = 0, dlen, olen; u_short a5, a6, sp, dp; u_int a1, a2, a3, a4; struct in_addr swip; ! int off, inc = 0; ! ftpinfo_t *ftp; fr_info_t fi; nat_t *ipn; mb_t *m; #if SOLARIS --- 65,95 ---- aps->aps_psiz = sizeof(ftpinfo_t); bzero((char *)ftp, sizeof(*ftp)); + f = &ftp->ftp_side[0]; + f->ftps_rptr = f->ftps_buf; + f->ftps_wptr = f->ftps_buf; + f = &ftp->ftp_side[1]; + f->ftps_rptr = f->ftps_buf; + f->ftps_wptr = f->ftps_buf; return 0; } ! int ippr_ftp_port(fin, ip, nat, f, dlen) fr_info_t *fin; ip_t *ip; nat_t *nat; + ftpside_t *f; + int dlen; { tcphdr_t *tcp, tcph, *tcp2 = &tcph; ! char newbuf[IPF_FTPBUFSZ], *s; u_short a5, a6, sp, dp; u_int a1, a2, a3, a4; struct in_addr swip; ! size_t nlen, olen; fr_info_t fi; + int inc, off; nat_t *ipn; mb_t *m; #if SOLARIS *************** *** 186,264 **** #endif tcp = (tcphdr_t *)fin->fin_dp; ! bzero(portbuf, sizeof(portbuf)); ! off = (ip->ip_hl << 2) + (tcp->th_off << 2); ! ! #if SOLARIS ! m = fin->fin_qfm; ! ! dlen = msgdsize(m) - off; ! if (dlen > 0) ! copyout_mblk(m, off, MIN(sizeof(portbuf), dlen), portbuf); ! #else ! m = *(mb_t **)fin->fin_mp; ! ! dlen = mbufchainlen(m) - off; ! if (dlen > 0) ! m_copydata(m, off, MIN(sizeof(portbuf), dlen), portbuf); ! #endif ! if (dlen == 0) return 0; - portbuf[sizeof(portbuf) - 1] = '\0'; - *newbuf = '\0'; - /* ! * Check that a user is progressing through the login ok. */ ! ftp = nat->nat_aps->aps_data; ! ftp->ftp_eol[1][1] = ftp->ftp_eol[1][0]; ! ftp->ftp_eol[1][0] = ippr_ftp_complete(portbuf, dlen); ! ! ftp->ftp_seq[1][1] = ftp->ftp_seq[1][0]; ! ftp->ftp_seq[1][0] = ntohl(tcp->th_seq) + dlen; ! ! switch (ftp->ftp_passok) ! { ! case 0 : ! if (!strncmp(portbuf, "USER ", 5)) ! ftp->ftp_passok = 1; ! break; ! case 2 : ! if (!strncmp(portbuf, "PASS ", 5)) ! ftp->ftp_passok = 3; ! break; ! } ! ! if (ftp->ftp_eol[1][0] == 0) return 0; - - if ((ftp->ftp_passok != 4) || (ftp->ftp_eol[1][1] == 0) || - (ntohl(tcp->th_ack) != ftp->ftp_seq[0][0])) - return 0; - /* ! * Check for client sending out PORT message. */ ! if (!ippr_ftp_pasvonly && !strncmp(portbuf, "PORT ", 5)) { ! if (dlen < IPF_MINPORTLEN) ! return 0; ! } else return 0; /* * Skip the PORT command + space */ ! s = portbuf + 5; /* * Pick out the address components, two at a time. */ ! a1 = ipf_ftp_atoi(&s); if (!s) return 0; ! a2 = ipf_ftp_atoi(&s); if (!s) return 0; - /* * check that IP address in the PORT/PASV reply is the same as the * sender of the command - prevents using PORT for port scanning. --- 97,130 ---- #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); /* * Skip the PORT command + space */ ! s = f->ftps_rptr + 5; /* * Pick out the address components, two at a time. */ ! a1 = ippr_ftp_atoi(&s); if (!s) return 0; ! a2 = ippr_ftp_atoi(&s); if (!s) return 0; /* * check that IP address in the PORT/PASV reply is the same as the * sender of the command - prevents using PORT for port scanning. *************** *** 268,274 **** if (a1 != ntohl(nat->nat_inip.s_addr)) return 0; ! a5 = ipf_ftp_atoi(&s); if (!s) return 0; if (*s == ')') --- 134,140 ---- if (a1 != ntohl(nat->nat_inip.s_addr)) return 0; ! a5 = ippr_ftp_atoi(&s); if (!s) return 0; if (*s == ')') *************** *** 293,299 **** a3 = (a1 >> 8) & 0xff; a4 = a1 & 0xff; a1 >>= 24; ! olen = s - portbuf; /* DO NOT change this to sprintf! */ (void) sprintf(newbuf, "%s %u,%u,%u,%u,%u,%u\r\n", "PORT", a1, a2, a3, a4, a5, a6); --- 159,165 ---- a3 = (a1 >> 8) & 0xff; a4 = a1 & 0xff; a1 >>= 24; ! olen = s - f->ftps_rptr; /* DO NOT change this to sprintf! */ (void) sprintf(newbuf, "%s %u,%u,%u,%u,%u,%u\r\n", "PORT", a1, a2, a3, a4, a5, a6); *************** *** 304,309 **** --- 170,176 ---- return 0; #if SOLARIS + m = fin->fin_qfm; for (m1 = m; m1->b_cont; m1 = m1->b_cont) ; if ((inc > 0) && (m1->b_datap->db_lim - m1->b_wptr < inc)) { *************** *** 329,334 **** --- 196,202 ---- } copyin_mblk(m, off, nlen, newbuf); #else + m = *((mb_t **)fin->fin_mp); if (inc < 0) m_adj(m, inc); /* the mbuf chain will be extended if necessary by m_copyback() */ *************** *** 372,381 **** --- 240,254 ---- ipn = nat_outlookup(fin->fin_ifp, IPN_TCP, nat->nat_p, nat->nat_inip, ip->ip_dst, (dp << 16) | sp); if (ipn == NULL) { + int slen; + + slen = ip->ip_len; + ip->ip_len = fin->fin_hlen + sizeof(*tcp2); bcopy((char *)fin, (char *)&fi, sizeof(fi)); bzero((char *)tcp2, sizeof(*tcp2)); tcp2->th_win = htons(8192); tcp2->th_sport = sp; + tcp2->th_off = 5; tcp2->th_dport = 0; /* XXX - don't specify remote port */ fi.fin_data[0] = ntohs(sp); fi.fin_data[1] = 0; *************** *** 388,507 **** ipn->nat_age = fr_defnatage; (void) fr_addstate(ip, &fi, FI_W_DPORT); } ip->ip_src = swip; } return inc; } ! int ippr_ftp_out(fin, ip, aps, nat) fr_info_t *fin; - ip_t *ip; - ap_session_t *aps; nat_t *nat; { ! return ippr_ftp_portmsg(fin, ip, nat); } ! int ippr_ftp_pasvmsg(fin, ip, nat) fr_info_t *fin; ip_t *ip; nat_t *nat; { ! char portbuf[IPF_FTPBUFSZ], newbuf[IPF_FTPBUFSZ], *s; ! int off, olen, dlen, nlen = 0, inc = 0; ! tcphdr_t tcph, *tcp2 = &tcph; struct in_addr swip, swip2; ! u_short a5, a6, dp, sp; u_int a1, a2, a3, a4; ! ftpinfo_t *ftp; ! tcphdr_t *tcp; fr_info_t fi; nat_t *ipn; mb_t *m; #if SOLARIS mb_t *m1; #endif ! ! tcp = (tcphdr_t *)fin->fin_dp; ! off = (ip->ip_hl << 2) + (tcp->th_off << 2); ! m = *(mb_t **)fin->fin_mp; ! bzero(portbuf, sizeof(portbuf)); ! ! #if SOLARIS ! m = fin->fin_qfm; ! ! dlen = msgdsize(m) - off; ! if (dlen > 0) ! copyout_mblk(m, off, MIN(sizeof(portbuf), dlen), portbuf); ! #else ! dlen = mbufchainlen(m) - off; ! if (dlen > 0) ! m_copydata(m, off, MIN(sizeof(portbuf), dlen), portbuf); ! #endif ! if (dlen == 0) ! return 0; ! portbuf[sizeof(portbuf) - 1] = '\0'; ! *newbuf = '\0'; ! ! /* ! * Check that a user is progressing through the login ok. ! * Don't put the switch in one common function because one side ! * should only see numeric responses and the other commands. ! */ ! ftp = nat->nat_aps->aps_data; ! ftp->ftp_eol[0][1] = ftp->ftp_eol[0][0]; ! ftp->ftp_eol[0][0] = ippr_ftp_complete(portbuf, dlen); ! ! ftp->ftp_seq[0][1] = ftp->ftp_seq[0][0]; ! ftp->ftp_seq[0][0] = ntohl(tcp->th_seq) + dlen; ! ! switch (ftp->ftp_passok) ! { ! case 1 : ! if (!strncmp(portbuf, "331", 3)) ! ftp->ftp_passok = 2; ! else if (!strncmp(portbuf, "530", 3)) ! ftp->ftp_passok = 0; ! break; ! case 3 : ! if (!strncmp(portbuf, "230", 3)) ! ftp->ftp_passok = 4; ! break; ! default : ! break; ! } ! ! if (ftp->ftp_eol[0][0] == 0) return 0; ! if ((ftp->ftp_passok != 4) || (ftp->ftp_eol[0][1] == 0) || ! (ntohl(tcp->th_ack) != ftp->ftp_seq[1][0])) return 0; /* ! * Check for PASV reply message. */ ! if (!strncmp(portbuf, "227 ", 4)) { ! if (dlen < IPF_MIN227LEN) ! return 0; ! else if (strncmp(portbuf, "227 Entering Passive Mode", 25)) ! return 0; ! } else return 0; /* * Skip the PORT command + space */ ! s = portbuf + 25; while (*s && !isdigit(*s)) s++; /* * Pick out the address components, two at a time. */ ! a1 = ipf_ftp_atoi(&s); if (!s) return 0; ! a2 = ipf_ftp_atoi(&s); if (!s) return 0; --- 261,356 ---- ipn->nat_age = fr_defnatage; (void) fr_addstate(ip, &fi, FI_W_DPORT); } + ip->ip_len = slen; ip->ip_src = swip; } return inc; } ! int ippr_ftp_client(fin, ip, nat, ftp, dlen) fr_info_t *fin; nat_t *nat; + ftpinfo_t *ftp; + ip_t *ip; + int dlen; { ! char *rptr, *wptr; ! ftpside_t *f; ! int inc; ! ! inc = 0; ! f = &ftp->ftp_side[0]; ! rptr = f->ftps_rptr; ! wptr = f->ftps_wptr; ! ! if ((ftp->ftp_passok == 0) && !strncmp(rptr, "USER ", 5)) ! ftp->ftp_passok = 1; ! else if ((ftp->ftp_passok == 2) && !strncmp(rptr, "PASS ", 5)) ! ftp->ftp_passok = 3; ! else if ((ftp->ftp_passok == 4) && !ippr_ftp_pasvonly && ! !strncmp(rptr, "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; } ! int ippr_ftp_pasv(fin, ip, nat, f, dlen) fr_info_t *fin; ip_t *ip; nat_t *nat; + ftpside_t *f; + int dlen; { ! tcphdr_t *tcp, tcph, *tcp2 = &tcph; ! char newbuf[IPF_FTPBUFSZ], *s; struct in_addr swip, swip2; ! u_short a5, a6, sp, dp; u_int a1, a2, a3, a4; ! size_t nlen, olen; fr_info_t fi; + int inc, off; nat_t *ipn; mb_t *m; #if SOLARIS mb_t *m1; #endif ! /* ! * Check for PASV reply message. ! */ ! if (dlen < IPF_MIN227LEN) return 0; ! 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 */ ! s = f->ftps_rptr + 25; while (*s && !isdigit(*s)) s++; /* * Pick out the address components, two at a time. */ ! a1 = ippr_ftp_atoi(&s); if (!s) return 0; ! a2 = ippr_ftp_atoi(&s); if (!s) return 0; *************** *** 514,520 **** if (a1 != ntohl(nat->nat_oip.s_addr)) return 0; ! a5 = ipf_ftp_atoi(&s); if (!s) return 0; --- 363,369 ---- if (a1 != ntohl(nat->nat_oip.s_addr)) return 0; ! a5 = ippr_ftp_atoi(&s); if (!s) return 0; *************** *** 539,554 **** a3 = (a1 >> 8) & 0xff; a4 = a1 & 0xff; a1 >>= 24; ! olen = s - portbuf; (void) sprintf(newbuf, "%s %u,%u,%u,%u,%u,%u\r\n", "227 Entering Passive Mode", a1, a2, a3, a4, a5, a6); - nlen = strlen(newbuf); inc = nlen - olen; if ((inc + ip->ip_len) > 65535) return 0; #if SOLARIS for (m1 = m; m1->b_cont; m1 = m1->b_cont) ; if ((inc > 0) && (m1->b_datap->db_lim - m1->b_wptr < inc)) { --- 388,405 ---- a3 = (a1 >> 8) & 0xff; a4 = a1 & 0xff; a1 >>= 24; ! inc = 0; ! #if 0 ! olen = s - f->ftps_rptr; (void) sprintf(newbuf, "%s %u,%u,%u,%u,%u,%u\r\n", "227 Entering Passive Mode", a1, a2, a3, a4, a5, a6); nlen = strlen(newbuf); inc = nlen - olen; if ((inc + ip->ip_len) > 65535) return 0; #if SOLARIS + m = fin->fin_qfm; for (m1 = m; m1->b_cont; m1 = m1->b_cont) ; if ((inc > 0) && (m1->b_datap->db_lim - m1->b_wptr < inc)) { *************** *** 569,580 **** } else { m1->b_wptr += inc; } ! copyin_mblk(m, off, nlen, newbuf); #else 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 if (inc != 0) { #if SOLARIS || defined(__sgi) --- 420,432 ---- } else { m1->b_wptr += inc; } ! /*copyin_mblk(m, off, nlen, newbuf);*/ #else + 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 if (inc != 0) { #if SOLARIS || defined(__sgi) *************** *** 593,598 **** --- 445,451 ---- #endif ip->ip_len += inc; } + #endif /* * Add skeleton NAT entry for connection which will come back the *************** *** 603,612 **** --- 456,470 ---- ipn = nat_outlookup(fin->fin_ifp, IPN_TCP, nat->nat_p, nat->nat_inip, ip->ip_dst, (dp << 16) | sp); if (ipn == NULL) { + int slen; + + slen = ip->ip_len; + ip->ip_len = fin->fin_hlen + sizeof(*tcp2); bcopy((char *)fin, (char *)&fi, sizeof(fi)); bzero((char *)tcp2, sizeof(*tcp2)); tcp2->th_win = htons(8192); tcp2->th_sport = 0; /* XXX - fake it for nat_new */ + tcp2->th_off = 5; fi.fin_data[0] = a5 << 8 | a6; tcp2->th_dport = htons(fi.fin_data[0]); fi.fin_data[1] = 0; *************** *** 621,626 **** --- 479,485 ---- ipn->nat_age = fr_defnatage; (void) fr_addstate(ip, &fi, FI_W_SPORT); } + ip->ip_len = slen; ip->ip_src = swip; ip->ip_dst = swip2; } *************** *** 628,639 **** } int ippr_ftp_in(fin, ip, aps, nat) fr_info_t *fin; ip_t *ip; ap_session_t *aps; nat_t *nat; { ! return ippr_ftp_pasvmsg(fin, ip, nat); } --- 487,760 ---- } + int ippr_ftp_server(fin, ip, nat, ftp, dlen) + fr_info_t *fin; + ip_t *ip; + nat_t *nat; + ftpinfo_t *ftp; + int dlen; + { + char *rptr, *wptr; + ftpside_t *f; + int inc; + + inc = 0; + f = &ftp->ftp_side[1]; + rptr = f->ftps_rptr; + wptr = f->ftps_wptr; + + if ((ftp->ftp_passok == 1) && !strncmp(rptr, "331", 3)) + ftp->ftp_passok = 2; + else if ((ftp->ftp_passok == 3) && !strncmp(rptr, "230", 3)) + ftp->ftp_passok = 4; + else if ((ftp->ftp_passok == 3) && !strncmp(rptr, "530", 3)) + ftp->ftp_passok = 0; + else if ((ftp->ftp_passok == 4) && !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; + } + + + /* + * Look to see if the buffer starts with something which we recognise as + * being the correct syntax for the FTP protocol. + */ + int ippr_ftp_valid(buf, len) + char *buf; + size_t len; + { + register char *s, c; + register size_t i = len; + + if (i < 5) + return 2; + s = buf; + c = *s++; + i--; + + if (isdigit(c)) { + c = *s++; + i--; + if (isdigit(c)) { + c = *s++; + i--; + if (isdigit(c)) { + c = *s++; + i--; + if ((c != '-') && (c != ' ')) + return 1; + } else + return 1; + } else + return 1; + } else if (isupper(c)) { + c = *s++; + i--; + if (isupper(c)) { + c = *s++; + i--; + if (isupper(c)) { + c = *s++; + i--; + if (isupper(c)) { + c = *s++; + i--; + if ((c != ' ') && (c != '\r')) + return 1; + } else if ((c != ' ') && (c != '\r')) + return 1; + } else + return 1; + } else + return 1; + } else + return 1; + for (; i; i--) { + c = *s++; + if (c == '\n') + return 0; + } + return 2; + } + + + int ippr_ftp_process(fin, ip, nat, ftp, rv) + fr_info_t *fin; + ip_t *ip; + nat_t *nat; + ftpinfo_t *ftp; + int rv; + { + int mlen, len, off, inc, i; + char *rptr, *wptr; + tcphdr_t *tcp; + ftpside_t *f; + mb_t *m; + + tcp = (tcphdr_t *)fin->fin_dp; + off = fin->fin_hlen + (tcp->th_off << 2); + + #if SOLARIS + m = fin->fin_qfm; + #else + m = *((mb_t **)fin->fin_mp); + #endif + + #if SOLARIS + mlen = msgdsize(m) - off; + #else + mlen = mbufchainlen(m) - off; + #endif + if (!mlen) + 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); + + /* + * 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(-1); + } + + while (mlen > 0) { + len = MIN(mlen, FTP_BUFSZ / 2); + + #if SOLARIS + copyout_mblk(m, off, len, wptr); + #else + m_copydata(m, off, len, wptr); + #endif + mlen -= len; + off += len; + wptr += len; + f->ftps_wptr = wptr; + if (f->ftps_junk == 2) + f->ftps_junk = ippr_ftp_valid(rptr, wptr - rptr); + + while ((f->ftps_junk == 0) && (wptr > rptr)) { + f->ftps_junk = ippr_ftp_valid(rptr, wptr - rptr); + if (f->ftps_junk == 0) { + len = wptr - rptr; + f->ftps_rptr = rptr; + if (rv) + inc += ippr_ftp_server(fin, ip, nat, + ftp, len); + else + inc += ippr_ftp_client(fin, ip, nat, + ftp, len); + rptr = f->ftps_rptr; + } + } + + while ((f->ftps_junk == 1) && (rptr < wptr)) { + while ((rptr < wptr) && (*rptr != '\r')) + rptr++; + + if ((*rptr == '\r') && (rptr + 1 < wptr)) { + if (*(rptr + 1) == '\n') { + rptr += 2; + f->ftps_junk = 0; + } else + rptr++; + } + f->ftps_seq += rptr - f->ftps_rptr; + f->ftps_rptr = rptr; + } + + if (rptr == wptr) { + rptr = wptr = f->ftps_buf; + } else { + if ((wptr > f->ftps_buf + FTP_BUFSZ / 2)) { + 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 { + bcopy(rptr, f->ftps_buf, i); + wptr = f->ftps_buf + i; + rptr = f->ftps_buf; + } + } + f->ftps_rptr = rptr; + f->ftps_wptr = wptr; + } + } + + f->ftps_rptr = rptr; + f->ftps_wptr = wptr; + return inc; + } + + + int ippr_ftp_out(fin, ip, aps, nat) + fr_info_t *fin; + ip_t *ip; + ap_session_t *aps; + nat_t *nat; + { + ftpinfo_t *ftp; + + ftp = aps->aps_data; + if (ftp == NULL) + return 0; + return ippr_ftp_process(fin, ip, nat, ftp, 0); + } + + int ippr_ftp_in(fin, ip, aps, nat) fr_info_t *fin; ip_t *ip; ap_session_t *aps; nat_t *nat; { + ftpinfo_t *ftp; + + ftp = aps->aps_data; + if (ftp == NULL) + return 0; + return ippr_ftp_process(fin, ip, nat, ftp, 1); + } + + + /* + * ippr_ftp_atoi - implement a version of atoi which processes numbers in + * pairs separated by commas (which are expected to be in the range 0 - 255), + * returning a 16 bit number combining either side of the , as the MSB and + * LSB. + */ + u_short ippr_ftp_atoi(ptr) + char **ptr; + { + register char *s = *ptr, c; + register u_char i = 0, j = 0; ! while ((c = *s++) && isdigit(c)) { ! i *= 10; ! i += c - '0'; ! } ! if (c != ',') { ! *ptr = NULL; ! return 0; ! } ! while ((c = *s++) && isdigit(c)) { ! j *= 10; ! j += c - '0'; ! } ! *ptr = s; ! return (i << 8) | j; } diff -cr ip_fil3.4.1/ip_nat.c ip_fil3.4.2/ip_nat.c *** ip_fil3.4.1/ip_nat.c Sun Apr 30 15:10:56 2000 --- ip_fil3.4.2/ip_nat.c Sat May 6 22:29:48 2000 *************** *** 9,15 **** */ #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.37.2.2 2000/04/30 05:10:56 darrenr Exp $"; #endif #if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL) --- 9,15 ---- */ #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.37.2.4 2000/05/06 12:29:48 darrenr Exp $"; #endif #if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL) *************** *** 1166,1172 **** port += MAPBLK_MINPORT; port = htons(port); } ! } else if (!in.s_addr && (np->in_outmsk == 0xffffffff)) { /* * 0/32 - use the interface's IP address. --- 1166,1172 ---- port += MAPBLK_MINPORT; port = htons(port); } ! } else if (!np->in_nip && (np->in_outmsk == 0xffffffff)) { /* * 0/32 - use the interface's IP address. *************** *** 1175,1181 **** fr_ifpaddr(4, fin->fin_ifp, &in) == -1) goto badnat; in.s_addr = ntohl(in.s_addr); ! } else if (!in.s_addr && !np->in_outmsk) { /* * 0/0 - use the original source address/port. */ --- 1175,1181 ---- fr_ifpaddr(4, fin->fin_ifp, &in) == -1) goto badnat; in.s_addr = ntohl(in.s_addr); ! } else if (!np->in_nip && !np->in_outmsk) { /* * 0/0 - use the original source address/port. */ *************** *** 1917,1928 **** ip->ip_len); } } if ((np->in_apr != NULL) && (np->in_dport == 0 || ! (tcp != NULL && dport == np->in_dport))) ! (void) appr_check(ip, fin, nat); ATOMIC_INCL(nat_stats.ns_mapped[1]); RWLOCK_EXIT(&ipf_nat); /* READ */ ! return 1; } RWLOCK_EXIT(&ipf_nat); /* READ/WRITE */ return 0; --- 1917,1933 ---- ip->ip_len); } } + if ((np->in_apr != NULL) && (np->in_dport == 0 || ! (tcp != NULL && dport == np->in_dport))) { ! i = appr_check(ip, fin, nat); ! if (i == 0) ! i = 1; ! } else ! i = 1; ATOMIC_INCL(nat_stats.ns_mapped[1]); RWLOCK_EXIT(&ipf_nat); /* READ */ ! return i; } RWLOCK_EXIT(&ipf_nat); /* READ/WRITE */ return 0; *************** *** 2038,2045 **** if (natadd && fin->fin_fi.fi_fl & FI_FRAG) ipfr_nat_newfrag(ip, fin, 0, nat); if ((np->in_apr != NULL) && (np->in_dport == 0 || ! (tcp != NULL && sport == np->in_dport))) ! (void) appr_check(ip, fin, nat); MUTEX_ENTER(&nat->nat_lock); if (nflags != IPN_ICMPERR) --- 2043,2055 ---- if (natadd && fin->fin_fi.fi_fl & FI_FRAG) ipfr_nat_newfrag(ip, fin, 0, nat); if ((np->in_apr != NULL) && (np->in_dport == 0 || ! (tcp != NULL && sport == np->in_dport))) { ! i = appr_check(ip, fin, nat); ! if (i == -1) { ! RWLOCK_EXIT(&ipf_nat); ! return i; ! } ! } MUTEX_ENTER(&nat->nat_lock); if (nflags != IPN_ICMPERR) *************** *** 2100,2108 **** if (csump) { if (nat->nat_dir == NAT_OUTBOUND) ! fix_incksum(csump, nat->nat_sumd[0], 0); else ! fix_outcksum(csump, nat->nat_sumd[0], 0); } } ATOMIC_INCL(nat_stats.ns_mapped[0]); --- 2110,2120 ---- if (csump) { if (nat->nat_dir == NAT_OUTBOUND) ! fix_incksum(csump, nat->nat_sumd[0], ! 0); else ! fix_outcksum(csump, nat->nat_sumd[0], ! 0); } } ATOMIC_INCL(nat_stats.ns_mapped[0]); diff -cr ip_fil3.4.1/ip_proxy.c ip_fil3.4.2/ip_proxy.c *** ip_fil3.4.1/ip_proxy.c Thu Mar 16 12:42:35 2000 --- ip_fil3.4.2/ip_proxy.c Sat May 6 22:30:50 2000 *************** *** 6,12 **** * to the original author and the contributors. */ #if !defined(lint) ! static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.9 2000/03/16 01:42:35 darrenr Exp $"; #endif #if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL) --- 6,12 ---- * to the original author and the contributors. */ #if !defined(lint) ! static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.9.2.1 2000/05/06 12:30:50 darrenr Exp $"; #endif #if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL) *************** *** 220,225 **** --- 220,226 ---- aproxy_t *apr; tcphdr_t *tcp = NULL; u_32_t sum; + short rv; int err; if (nat->nat_aps == NULL) *************** *** 254,261 **** err = (*apr->apr_inpkt)(fin, ip, aps, nat); } if (tcp != NULL) { ! err = appr_fixseqack(fin, ip, aps, err); #if SOLARIS && defined(_KERNEL) tcp->th_sum = fr_tcpsum(fin->fin_qfm, ip, tcp); #else --- 255,266 ---- err = (*apr->apr_inpkt)(fin, ip, aps, nat); } + rv = APR_EXIT(err); + if (rv == -1) + return rv; + if (tcp != NULL) { ! err = appr_fixseqack(fin, ip, aps, APR_INC(err)); #if SOLARIS && defined(_KERNEL) tcp->th_sum = fr_tcpsum(fin->fin_qfm, ip, tcp); #else *************** *** 264,272 **** } aps->aps_bytes += ip->ip_len; aps->aps_pkts++; ! return 2; } ! return -1; } --- 269,277 ---- } aps->aps_bytes += ip->ip_len; aps->aps_pkts++; ! return 1; } ! return 0; } diff -cr ip_fil3.4.1/ip_proxy.h ip_fil3.4.2/ip_proxy.h *** ip_fil3.4.1/ip_proxy.h Fri Apr 7 22:31:01 2000 --- ip_fil3.4.2/ip_proxy.h Sat May 6 22:32:43 2000 *************** *** 5,11 **** * provided that this notice is preserved and due credit is given * to the original author and the contributors. * ! * $Id: ip_proxy.h,v 2.8.2.1 2000/04/07 12:31:01 darrenr Exp $ */ #ifndef __IP_PROXY_H__ --- 5,11 ---- * provided that this notice is preserved and due credit is given * to the original author and the contributors. * ! * $Id: ip_proxy.h,v 2.8.2.3 2000/05/06 12:32:43 darrenr Exp $ */ #ifndef __IP_PROXY_H__ *************** *** 84,97 **** #define APR_DELETE 1 /* * For the ftp proxy. */ typedef struct ftpinfo { ! u_int ftp_passok; ! u_char ftp_eol[2][2]; ! u_32_t ftp_seq[2][2]; } ftpinfo_t; /* --- 84,108 ---- #define APR_DELETE 1 + #define APR_ERR(x) (((x) & 0xffff) << 16) + #define APR_EXIT(x) (((x) >> 16) & 0xffff) + #define APR_INC(x) ((x) & 0xffff) + #define FTP_BUFSZ 160 /* * For the ftp proxy. */ + typedef struct ftpside { + char *ftps_rptr; + char *ftps_wptr; + u_32_t ftps_seq; + int ftps_junk; + char ftps_buf[FTP_BUFSZ]; + } ftpside_t; + typedef struct ftpinfo { ! u_int ftp_passok; ! ftpside_t ftp_side[2]; } ftpinfo_t; /* diff -cr ip_fil3.4.1/ip_raudio_pxy.c ip_fil3.4.2/ip_raudio_pxy.c *** ip_fil3.4.1/ip_raudio_pxy.c Thu Mar 16 12:38:07 2000 --- ip_fil3.4.2/ip_raudio_pxy.c Sat May 6 21:19:33 2000 *************** *** 1,5 **** /* ! * $Id: ip_raudio_pxy.c,v 1.7 2000/03/16 01:38:07 darrenr Exp $ */ #if SOLARIS && defined(_KERNEL) extern kmutex_t ipf_rw; --- 1,5 ---- /* ! * $Id: ip_raudio_pxy.c,v 1.7.2.1 2000/05/06 11:19:33 darrenr Exp $ */ #if SOLARIS && defined(_KERNEL) extern kmutex_t ipf_rw; *************** *** 172,179 **** raudio_t *rap = aps->aps_data; struct in_addr swa, swb; u_int a1, a2, a3, a4; u_short sp, dp; - int off, dlen; fr_info_t fi; tcp_seq seq; nat_t *ipn; --- 172,179 ---- raudio_t *rap = aps->aps_data; struct in_addr swa, swb; u_int a1, a2, a3, a4; + int off, dlen, slen; u_short sp, dp; fr_info_t fi; tcp_seq seq; nat_t *ipn; *************** *** 262,270 **** --- 262,273 ---- bcopy((char *)fin, (char *)&fi, sizeof(fi)); bzero((char *)tcp2, sizeof(*tcp2)); + tcp2->th_off = 5; fi.fin_dp = (char *)tcp2; fi.fin_fr = &raudiofr; tcp2->th_win = htons(8192); + slen = ip->ip_len; + ip->ip_len = fin->fin_hlen + sizeof(*tcp); if (((rap->rap_mode & RAP_M_UDP_ROBUST) == RAP_M_UDP_ROBUST) && (rap->rap_srport != 0)) { *************** *** 275,282 **** fi.fin_data[0] = dp; fi.fin_data[1] = sp; ipn = nat_new(nat->nat_ptr, ip, &fi, ! IPN_UDP | (sp ? 0 : FI_W_SPORT), ! NAT_OUTBOUND); if (ipn != NULL) { ipn->nat_age = fr_defnatage; (void) fr_addstate(ip, &fi, sp ? 0 : FI_W_SPORT); --- 278,284 ---- fi.fin_data[0] = dp; fi.fin_data[1] = sp; ipn = nat_new(nat->nat_ptr, ip, &fi, ! IPN_UDP | (sp ? 0 : FI_W_SPORT), NAT_OUTBOUND); if (ipn != NULL) { ipn->nat_age = fr_defnatage; (void) fr_addstate(ip, &fi, sp ? 0 : FI_W_SPORT); *************** *** 296,303 **** (void) fr_addstate(ip, &fi, FI_W_DPORT); } } ! ip->ip_p = swp; ip->ip_src = swa; ip->ip_dst = swb; return 0; --- 298,306 ---- (void) fr_addstate(ip, &fi, FI_W_DPORT); } } ! ip->ip_p = swp; + ip->ip_len = slen; ip->ip_src = swa; ip->ip_dst = swb; return 0; diff -cr ip_fil3.4.1/ip_rcmd_pxy.c ip_fil3.4.2/ip_rcmd_pxy.c *** ip_fil3.4.1/ip_rcmd_pxy.c Thu Dec 9 01:35:55 1999 --- ip_fil3.4.2/ip_rcmd_pxy.c Sat May 6 21:19:34 2000 *************** *** 1,5 **** /* ! * $Id: ip_rcmd_pxy.c,v 1.4 1999/12/08 14:35:55 darrenr Exp $ */ /* * Simple RCMD transparent proxy for in-kernel use. For use with the NAT --- 1,5 ---- /* ! * $Id: ip_rcmd_pxy.c,v 1.4.2.1 2000/05/06 11:19:34 darrenr Exp $ */ /* * Simple RCMD transparent proxy for in-kernel use. For use with the NAT *************** *** 126,136 **** --- 126,141 ---- ipn = nat_outlookup(fin->fin_ifp, IPN_TCP, nat->nat_p, nat->nat_inip, ip->ip_dst, (dp << 16) | sp); if (ipn == NULL) { + int slen; + + slen = ip->ip_len; + ip->ip_len = fin->fin_hlen + sizeof(*tcp); bcopy((char *)fin, (char *)&fi, sizeof(fi)); bzero((char *)tcp2, sizeof(*tcp2)); tcp2->th_win = htons(8192); tcp2->th_sport = sp; tcp2->th_dport = 0; /* XXX - don't specify remote port */ + tcp2->th_off = 5; fi.fin_data[0] = ntohs(sp); fi.fin_data[1] = 0; fi.fin_dp = (char *)tcp2; *************** *** 143,148 **** --- 148,154 ---- fi.fin_fr = &rcmdfr; (void) fr_addstate(ip, &fi, FI_W_DPORT); } + ip->ip_len = slen; ip->ip_src = swip; } return 0; diff -cr ip_fil3.4.1/ipf.h ip_fil3.4.2/ipf.h *** ip_fil3.4.1/ipf.h Sat Apr 29 01:27:40 2000 --- ip_fil3.4.2/ipf.h Sat May 6 21:20:20 2000 *************** *** 6,12 **** * to the original author and the contributors. * * @(#)ipf.h 1.12 6/5/96 ! * $Id: ipf.h,v 2.9.2.1 2000/04/28 15:27:40 darrenr Exp $ */ #ifndef __IPF_H__ --- 6,12 ---- * to the original author and the contributors. * * @(#)ipf.h 1.12 6/5/96 ! * $Id: ipf.h,v 2.9.2.2 2000/05/06 11:20:20 darrenr Exp $ */ #ifndef __IPF_H__ *************** *** 94,99 **** --- 94,100 ---- extern void printpacket __P((ip_t *)); extern void printportcmp __P((int, struct frpcmp *)); extern void printhostmask __P((int, u_32_t *, u_32_t *)); + extern void printbuf __P((char *, int, int)); #if SOLARIS extern int inet_aton __P((const char *, struct in_addr *)); extern int gethostname __P((char *, int )); diff -cr ip_fil3.4.1/ipfs.c ip_fil3.4.2/ipfs.c *** ip_fil3.4.1/ipfs.c Sat Feb 26 18:42:20 2000 --- ip_fil3.4.2/ipfs.c Sat May 6 10:11:18 2000 *************** *** 41,47 **** #include "ipf.h" #if !defined(lint) ! static const char rcsid[] = "@(#)$Id: ipfs.c,v 2.6 2000/02/26 07:42:20 darrenr Exp $"; #endif #ifndef IPF_SAVEDIR --- 41,47 ---- #include "ipf.h" #if !defined(lint) ! static const char rcsid[] = "@(#)$Id: ipfs.c,v 2.6.2.1 2000/05/06 00:11:18 darrenr Exp $"; #endif #ifndef IPF_SAVEDIR *************** *** 427,433 **** break; if (i != sizeof(ips)) { fprintf(stderr, "incomplete read: %d != %d\n", i, ! sizeof(ips)); close(sfd); return 1; } --- 427,433 ---- break; if (i != sizeof(ips)) { fprintf(stderr, "incomplete read: %d != %d\n", i, ! (int)sizeof(ips)); close(sfd); return 1; } *************** *** 520,526 **** break; if (i != sizeof(ipn)) { fprintf(stderr, "incomplete read: %d != %d\n", i, ! sizeof(ipn)); close(nfd); return 1; } --- 520,526 ---- break; if (i != sizeof(ipn)) { fprintf(stderr, "incomplete read: %d != %d\n", i, ! (int)sizeof(ipn)); close(nfd); return 1; } diff -cr ip_fil3.4.1/ipl.h ip_fil3.4.2/ipl.h *** ip_fil3.4.1/ipl.h Sun Apr 30 15:13:54 2000 --- ip_fil3.4.2/ipl.h Wed May 10 08:44:13 2000 *************** *** 6,17 **** * to the original author and the contributors. * * @(#)ipl.h 1.21 6/5/96 ! * $Id: ipl.h,v 2.15.2.2 2000/04/30 05:13:54 darrenr Exp $ */ #ifndef __IPL_H__ #define __IPL_H__ ! #define IPL_VERSION "IP Filter: v3.4.1" #endif --- 6,17 ---- * to the original author and the contributors. * * @(#)ipl.h 1.21 6/5/96 ! * $Id: ipl.h,v 2.15.2.3 2000/05/09 22:44:13 darrenr Exp $ */ #ifndef __IPL_H__ #define __IPL_H__ ! #define IPL_VERSION "IP Filter: v3.4.2" #endif diff -cr ip_fil3.4.1/ipnat.c ip_fil3.4.2/ipnat.c *** ip_fil3.4.1/ipnat.c Fri Mar 17 14:11:13 2000 --- ip_fil3.4.2/ipnat.c Sat May 6 22:02:53 2000 *************** *** 57,63 **** #if !defined(lint) static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: ipnat.c,v 2.16 2000/03/17 03:11:13 darrenr Exp $"; #endif --- 57,63 ---- #if !defined(lint) static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed"; ! static const char rcsid[] = "@(#)$Id: ipnat.c,v 2.16.2.1 2000/05/06 12:02:53 darrenr Exp $"; #endif *************** *** 230,241 **** return; printf("\tFTP Proxy:\n"); printf("\t\tpassok: %d\n", ftp.ftp_passok); ! printf("\t\teol: %d,%d,%d,%d\n", ! ftp.ftp_eol[0][0], ftp.ftp_eol[0][1], ! ftp.ftp_eol[1][0], ftp.ftp_eol[1][1]); ! printf("\t\tseq: %x,%x,%x,%x\n", ! ftp.ftp_seq[0][0], ftp.ftp_seq[0][1], ! ftp.ftp_seq[1][0], ftp.ftp_seq[1][1]); } } --- 230,250 ---- return; printf("\tFTP Proxy:\n"); printf("\t\tpassok: %d\n", ftp.ftp_passok); ! ftp.ftp_side[0].ftps_buf[FTP_BUFSZ - 1] = '\0'; ! ftp.ftp_side[1].ftps_buf[FTP_BUFSZ - 1] = '\0'; ! printf("\tClient:\n"); ! printf("\t\trptr %p wptr %p seq %x junk %d\n", ! ftp.ftp_side[0].ftps_rptr, ftp.ftp_side[0].ftps_wptr, ! ftp.ftp_side[0].ftps_seq, ftp.ftp_side[0].ftps_junk); ! printf("\t\tbuf ["); ! printbuf(ftp.ftp_side[0].ftps_buf, FTP_BUFSZ, 1); ! printf("]\n\tServer:\n"); ! printf("\t\trptr %p wptr %p seq %x junk %d\n", ! ftp.ftp_side[1].ftps_rptr, ftp.ftp_side[1].ftps_wptr, ! ftp.ftp_side[1].ftps_seq, ftp.ftp_side[1].ftps_junk); ! printf("\t\tbuf ["); ! printbuf(ftp.ftp_side[1].ftps_buf, FTP_BUFSZ, 1); ! printf("]\n"); } } diff -cr ip_fil3.4.1/man/ipmon.8 ip_fil3.4.2/man/ipmon.8 *** ip_fil3.4.1/man/ipmon.8 Sun Feb 20 17:15:01 2000 --- ip_fil3.4.2/man/ipmon.8 Thu May 4 08:47:17 2000 *************** *** 118,127 **** Packet information read in will be sent through syslogd rather than saved to a file. The default facility when compiled and installed is \fBlocal0\fP. The following levels are used: - .TP - .B "\-S " - Set the logfile to be opened for reading state log records from to . - .TP .IP .B LOG_INFO \- packets logged using the "log" keyword as the action rather --- 118,123 ---- *************** *** 136,141 **** --- 132,140 ---- .B LOG_ERR \- packets which have been logged and which can be considered "short". + .TP + .B "\-S " + Set the logfile to be opened for reading state log records from to . .TP .B \-t read the input file/device in a manner akin to tail(1).