Deleted Added
full compact
0a1,2
> /* $FreeBSD: head/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c 145522 2005-04-25 18:43:14Z darrenr $ */
>
1a4,7
> * Copyright (C) 1997-2003 by Darren Reed
> *
> * See the IPFILTER.LICENCE file for details on licencing.
> *
5c11,12
< * $FreeBSD: head/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c 130886 2004-06-21 22:46:36Z darrenr $
---
> * $FreeBSD: head/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c 145522 2005-04-25 18:43:14Z darrenr $
> * Id: ip_ftp_pxy.c,v 2.88.2.15 2005/03/19 19:38:10 darrenr Exp
7,9d13
< #if SOLARIS && defined(_KERNEL)
< extern kmutex_t ipf_rw;
< #endif
11,16d14
< #define isdigit(x) ((x) >= '0' && (x) <= '9')
< #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')
<
23c21,22
< #define IPF_FTPBUFSZ 96 /* This *MUST* be >= 53! */
---
> #define IPF_MIN229LEN 47
> #define IPF_MAX229LEN 51
49c48
< int ippr_ftp_in __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
---
> int ippr_ftp_in __P((fr_info_t *, ap_session_t *, nat_t *));
51,52c50,52
< 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 *));
---
> void ippr_ftp_fini __P((void));
> int ippr_ftp_new __P((fr_info_t *, ap_session_t *, nat_t *));
> int ippr_ftp_out __P((fr_info_t *, ap_session_t *, nat_t *));
53a54
> int ippr_ftp_epsv __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *, int));
55c56
< int ippr_ftp_process __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int));
---
> int ippr_ftp_process __P((fr_info_t *, nat_t *, ftpinfo_t *, int));
60a62,63
> int ippr_ftp_pasvreply __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *,
> u_int, char *, char *, u_int));
62c65,66
< static frentry_t ftppxyfr;
---
>
> int ftp_proxy_init = 0;
64,65c68,83
< int ippr_ftp_insecure = 0;
< int ippr_ftp_forcepasv = 0;
---
> int ippr_ftp_insecure = 0; /* Do not require logins before transfers */
> int ippr_ftp_pasvrdr = 0;
> int ippr_ftp_forcepasv = 0; /* PASV must be last command prior to 227 */
> #if defined(_KERNEL)
> int ippr_ftp_debug = 0;
> #else
> int ippr_ftp_debug = 2;
> #endif
> /*
> * 1 - security
> * 2 - errors
> * 3 - error debugging
> * 4 - parsing errors
> * 5 - parsing info
> * 6 - parsing debug
> */
66a85,94
> static frentry_t ftppxyfr;
> static ipftuneable_t ftptune = {
> { &ippr_ftp_debug },
> "ippr_ftp_debug",
> 0,
> 10,
> sizeof(ippr_ftp_debug),
> 0,
> NULL
> };
67a96
>
75a105,108
> MUTEX_INIT(&ftppxyfr.fr_lock, "FTP Proxy Mutex");
> ftp_proxy_init = 1;
> (void) fr_addipftune(&ftptune);
>
80c113,124
< int ippr_ftp_new(fin, ip, aps, nat)
---
> void ippr_ftp_fini()
> {
> (void) fr_delipftune(&ftptune);
>
> if (ftp_proxy_init == 1) {
> MUTEX_DESTROY(&ftppxyfr.fr_lock);
> ftp_proxy_init = 0;
> }
> }
>
>
> int ippr_ftp_new(fin, aps, nat)
82d125
< ip_t *ip;
91a135,138
>
> fin = fin; /* LINT */
> nat = nat; /* LINT */
>
102a150
> ftp->ftp_incok = 0;
115a164
> struct in_addr swip, swip2;
117c166
< struct in_addr swip;
---
> int inc, off, flags;
121,122c170
< int inc, off;
< nat_t *ipn;
---
> nat_t *nat2;
124,126d171
< #if SOLARIS && defined(_KERNEL)
< mb_t *m1;
< #endif
127a173
> m = fin->fin_m;
128a175,176
> off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff;
>
133,136c181,183
< #if !defined(_KERNEL) && !defined(KERNEL)
< fprintf(stdout,
< "ippr_ftp_port:dlen(%d) < IPF_MINPORTLEN\n", dlen);
< #endif
---
> if (ippr_ftp_debug > 1)
> printf("ippr_ftp_port:dlen(%d) < IPF_MINPORTLEN\n",
> dlen);
139d185
< off = fin->fin_hlen + (tcp->th_off << 2);
149,151c195,196
< #if !defined(_KERNEL) && !defined(KERNEL)
< fprintf(stdout, "ippr_ftp_port:ippr_ftp_atoi(1) failed\n");
< #endif
---
> if (ippr_ftp_debug > 1)
> printf("ippr_ftp_port:ippr_ftp_atoi(%d) failed\n", 1);
156,158c201,202
< #if !defined(_KERNEL) && !defined(KERNEL)
< fprintf(stdout, "ippr_ftp_port:ippr_ftp_atoi(2) failed\n");
< #endif
---
> if (ippr_ftp_debug > 1)
> printf("ippr_ftp_port:ippr_ftp_atoi(%d) failed\n", 2);
160a205
>
162c207
< * check that IP address in the PORT/PASV reply is the same as the
---
> * Check that IP address in the PORT/PASV reply is the same as the
167,171c212,218
< if (a1 != ntohl(nat->nat_inip.s_addr)) {
< #if !defined(_KERNEL) && !defined(KERNEL)
< fprintf(stdout, "ippr_ftp_port:a1 != nat->nat_inip\n");
< #endif
< return 0;
---
> if (((nat->nat_dir == NAT_OUTBOUND) &&
> (a1 != ntohl(nat->nat_inip.s_addr))) ||
> ((nat->nat_dir == NAT_INBOUND) &&
> (a1 != ntohl(nat->nat_oip.s_addr)))) {
> if (ippr_ftp_debug > 0)
> printf("ippr_ftp_port:%s != nat->nat_inip\n", "a1");
> return APR_ERR(1);
176,178c223,224
< #if !defined(_KERNEL) && !defined(KERNEL)
< fprintf(stdout, "ippr_ftp_port:ippr_ftp_atoi(3) failed\n");
< #endif
---
> if (ippr_ftp_debug > 1)
> printf("ippr_ftp_port:ippr_ftp_atoi(%d) failed\n", 3);
193,195c239,240
< #if !defined(_KERNEL) && !defined(KERNEL)
< fprintf(stdout, "ippr_ftp_port:missing cr-lf\n");
< #endif
---
> if (ippr_ftp_debug > 1)
> printf("ippr_ftp_port:missing %s\n", "cr-lf");
197a243
>
199a246
> sp = a5 << 8 | a6;
200a248,256
> * Don't allow the PORT command to specify a port < 1024 due to
> * security crap.
> */
> if (sp < 1024) {
> if (ippr_ftp_debug > 0)
> printf("ippr_ftp_port:sp(%d) < 1024\n", sp);
> return 0;
> }
> /*
203c259,262
< a1 = ntohl(ip->ip_src.s_addr);
---
> if (nat->nat_dir == NAT_INBOUND)
> a1 = ntohl(nat->nat_oip.s_addr);
> else
> a1 = ntohl(ip->ip_src.s_addr);
210,212c269,271
< #if defined(OpenBSD) && (200311 >= 200311)
< (void) snprintf(newbuf, sizeof(newbuf), "%s %u,%u,%u,%u,%u,%u\r\n",
< "PORT", a1, a2, a3, a4, a5, a6);
---
> #if defined(SNPRINTF) && defined(_KERNEL)
> SNPRINTF(newbuf, sizeof(newbuf), "%s %u,%u,%u,%u,%u,%u\r\n",
> "PORT", a1, a2, a3, a4, a5, a6);
221,224c280,282
< #if !defined(_KERNEL) && !defined(KERNEL)
< fprintf(stdout,
< "ippr_ftp_port:inc(%d) + ip->ip_len > 65535\n", inc);
< #endif
---
> if (ippr_ftp_debug > 0)
> printf("ippr_ftp_port:inc(%d) + ip->ip_len > 65535\n",
> inc);
229,230c287
< m = *fin->fin_mp;
< bcopy(newbuf, (char *)m + off, nlen);
---
> bcopy(newbuf, MTOD(m, char *) + off, nlen);
232,259c289
< # 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)) {
< mblk_t *nm;
<
< /* alloc enough to keep same trailer space for lower driver */
< nm = allocb(nlen, BPRI_MED);
< PANIC((!nm),("ippr_ftp_out: allocb failed"));
<
< nm->b_band = m1->b_band;
< nm->b_wptr += nlen;
<
< m1->b_wptr -= olen;
< PANIC((m1->b_wptr < m1->b_rptr),
< ("ippr_ftp_out: cannot handle fragmented data block"));
<
< linkb(m1, nm);
< } else {
< if (m1->b_datap->db_struiolim == m1->b_wptr)
< m1->b_datap->db_struiolim += inc;
< m1->b_datap->db_struioflag &= ~STRUIO_IP;
< m1->b_wptr += inc;
< }
< copyin_mblk(m, off, nlen, newbuf);
< # else
< m = *fin->fin_mp;
---
> # if defined(MENTAT)
260a291,298
> (void)adjmsg(m, inc);
> # else /* defined(MENTAT) */
> /*
> * m_adj takes care of pkthdr.len, if required and treats inc<0 to
> * mean remove -len bytes from the end of the packet.
> * The mbuf chain will be extended if necessary by m_copyback().
> */
> if (inc < 0)
262,272c300,302
< /* 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
< #endif
< if (inc != 0) {
< #if ((SOLARIS || defined(__sgi)) && defined(_KERNEL)) || !defined(_KERNEL)
< register u_32_t sum1, sum2;
---
> # endif /* defined(MENTAT) */
> #endif /* !defined(_KERNEL) */
> COPYBACK(m, off, nlen, newbuf);
274,284c304
< sum1 = ip->ip_len;
< sum2 = ip->ip_len + inc;
<
< /* Because ~1 == -2, We really need ~1 == -1 */
< if (sum1 > sum2)
< sum2--;
< sum2 -= sum1;
< sum2 = (sum2 & 0xffff) + (sum2 >> 16);
<
< fix_outcksum(fin, &ip->ip_sum, sum2);
< #endif
---
> if (inc != 0) {
285a306,307
> fin->fin_dlen += inc;
> fin->fin_plen += inc;
289,304d310
< * Add skeleton NAT entry for connection which will come back the
< * other way.
< */
< sp = (a5 << 8 | a6);
< /*
< * Don't allow the PORT command to specify a port < 1024 due to
< * security crap.
< */
< if (sp < 1024) {
< #if !defined(_KERNEL) && !defined(KERNEL)
< fprintf(stdout, "ippr_ftp_port:sp(%d) < 1024\n", sp);
< #endif
< return 0;
< }
<
< /*
309a316,318
> fi.fin_state = NULL;
> fi.fin_nat = NULL;
> fi.fin_flx |= FI_IGNORE;
312,314c321,331
< ipn = nat_outlookup(&fi, IPN_TCP, nat->nat_p, nat->nat_inip,
< ip->ip_dst, 0);
< if (ipn == NULL) {
---
> /*
> * Add skeleton NAT entry for connection which will come back the
> * other way.
> */
> if (nat->nat_dir == NAT_OUTBOUND)
> nat2 = nat_outlookup(&fi, NAT_SEARCH|IPN_TCP, nat->nat_p,
> nat->nat_inip, nat->nat_oip);
> else
> nat2 = nat_inlookup(&fi, NAT_SEARCH|IPN_TCP, nat->nat_p,
> nat->nat_inip, nat->nat_oip);
> if (nat2 == NULL) {
322c339
< tcp2->th_off = 5;
---
> TCP_OFF_A(tcp2, 5);
326a344
> fi.fin_plen = fi.fin_hlen + sizeof(*tcp2);
329c347,348
< fi.fin_out = 1;
---
> fi.fin_out = nat->nat_dir;
> fi.fin_flx &= FI_LOWTTL|FI_FRAG|FI_TCPUDP|FI_OPTIONS|FI_IGNORE;
331,338c350,356
< fi.fin_fi.fi_saddr = nat->nat_inip.s_addr;
< ip->ip_src = nat->nat_inip;
< ipn = nat_new(&fi, ip, nat->nat_ptr, NULL, IPN_TCP|FI_W_DPORT,
< NAT_OUTBOUND);
< if (ipn != NULL) {
< ipn->nat_age = fr_defnatage;
< (void) fr_addstate(ip, &fi, NULL,
< FI_W_DPORT|FI_IGNOREPKT);
---
> swip2 = ip->ip_dst;
> if (nat->nat_dir == NAT_OUTBOUND) {
> fi.fin_fi.fi_saddr = nat->nat_inip.s_addr;
> ip->ip_src = nat->nat_inip;
> } else if (nat->nat_dir == NAT_INBOUND) {
> fi.fin_fi.fi_saddr = nat->nat_oip.s_addr;
> ip->ip_src = nat->nat_oip;
339a358,375
>
> flags = NAT_SLAVE|IPN_TCP|SI_W_DPORT;
> if (nat->nat_dir == NAT_INBOUND)
> flags |= NAT_NOTRULEPORT;
> nat2 = nat_new(&fi, nat->nat_ptr, NULL, flags, nat->nat_dir);
>
> if (nat2 != NULL) {
> (void) nat_proto(&fi, nat2, IPN_TCP);
> nat_update(&fi, nat2, nat->nat_ptr);
> fi.fin_ifp = NULL;
> if (nat->nat_dir == NAT_INBOUND) {
> fi.fin_fi.fi_daddr = nat->nat_inip.s_addr;
> ip->ip_dst = nat->nat_inip;
> }
> (void) fr_addstate(&fi, &nat2->nat_state, SI_W_DPORT);
> if (fi.fin_state != NULL)
> fr_statederef(&fi, (ipstate_t **)&fi.fin_state);
> }
341a378,391
> ip->ip_dst = swip2;
> } else {
> ipstate_t *is;
>
> nat_update(&fi, nat2, nat->nat_ptr);
> READ_ENTER(&ipf_state);
> is = nat2->nat_state;
> if (is != NULL) {
> MUTEX_ENTER(&is->is_lock);
> (void)fr_tcp_age(&is->is_sti, &fi, ips_tqtqb,
> is->is_flags);
> MUTEX_EXIT(&is->is_lock);
> }
> RWLOCK_EXIT(&ipf_state);
343c393
< return inc;
---
> return APR_INC(inc);
365,366c415,416
< if (isalpha(c)) {
< cmd[i] = toupper(c);
---
> if (ISALPHA(c)) {
> cmd[i] = TOUPPER(c);
425,429c475,478
< tcphdr_t *tcp, tcph, *tcp2 = &tcph;
< struct in_addr swip, swip2;
< u_int a1, a2, a3, a4;
< u_short a5, a6, dp;
< fr_info_t fi;
---
> u_int a1, a2, a3, a4, data_ip;
> char newbuf[IPF_FTPBUFSZ];
> char *s, *brackets[2];
> u_short a5, a6;
431,433d479
< nat_t *ipn;
< int inc;
< char *s;
437,441c483,485
< #if !defined(_KERNEL) && !defined(KERNEL)
< fprintf(stdout,
< "ippr_ftp_pasv:ftps_cmds(%d) != FTPXY_C_PASV\n",
< ftp->ftp_side[0].ftps_cmds);
< #endif
---
> if (ippr_ftp_debug > 0)
> printf("ippr_ftp_pasv:ftps_cmds(%d) != FTPXY_C_PASV\n",
> ftp->ftp_side[0].ftps_cmds);
452,455c496,498
< #if !defined(_KERNEL) && !defined(KERNEL)
< fprintf(stdout,
< "ippr_ftp_pasv:dlen(%d) < IPF_MIN227LEN\n", dlen);
< #endif
---
> if (ippr_ftp_debug > 1)
> printf("ippr_ftp_pasv:dlen(%d) < IPF_MIN227LEN\n",
> dlen);
459,461c502,503
< #if !defined(_KERNEL) && !defined(KERNEL)
< fprintf(stdout, "ippr_ftp_pasv:227 reply wrong\n");
< #endif
---
> if (ippr_ftp_debug > 0)
> printf("ippr_ftp_pasv:%d reply wrong\n", 227);
465,466c507,508
< tcp = (tcphdr_t *)fin->fin_dp;
<
---
> brackets[0] = "";
> brackets[1] = "";
471c513,517
< while (*s && !isdigit(*s))
---
> while (*s && !ISDIGIT(*s)) {
> if (*s == '(') {
> brackets[0] = "(";
> brackets[1] = ")";
> }
472a519,520
> }
>
478,480c526,527
< #if !defined(_KERNEL) && !defined(KERNEL)
< fprintf(stdout, "ippr_ftp_pasv:ippr_ftp_atoi(1) failed\n");
< #endif
---
> if (ippr_ftp_debug > 1)
> printf("ippr_ftp_pasv:ippr_ftp_atoi(%d) failed\n", 1);
485,487c532,533
< #if !defined(_KERNEL) && !defined(KERNEL)
< fprintf(stdout, "ippr_ftp_pasv:ippr_ftp_atoi(2) failed\n");
< #endif
---
> if (ippr_ftp_debug > 1)
> printf("ippr_ftp_pasv:ippr_ftp_atoi(%d) failed\n", 2);
492,493c538,539
< * check that IP address in the PORT/PASV reply is the same as the
< * sender of the command - prevents using PORT for port scanning.
---
> * check that IP address in the PASV reply is the same as the
> * sender of the command - prevents using PASV for port scanning.
497,500c543,549
< if (a1 != ntohl(nat->nat_oip.s_addr)) {
< #if !defined(_KERNEL) && !defined(KERNEL)
< fprintf(stdout, "ippr_ftp_pasv:a1 != nat->nat_oip\n");
< #endif
---
>
> if (((nat->nat_dir == NAT_INBOUND) &&
> (a1 != ntohl(nat->nat_inip.s_addr))) ||
> ((nat->nat_dir == NAT_OUTBOUND) &&
> (a1 != ntohl(nat->nat_oip.s_addr)))) {
> if (ippr_ftp_debug > 0)
> printf("ippr_ftp_pasv:%s != nat->nat_oip\n", "a1");
506,508c555,556
< #if !defined(_KERNEL) && !defined(KERNEL)
< fprintf(stdout, "ippr_ftp_pasv:ippr_ftp_atoi(3) failed\n");
< #endif
---
> if (ippr_ftp_debug > 1)
> printf("ippr_ftp_pasv:ippr_ftp_atoi(%d) failed\n", 3);
523d570
< a6 = a5 & 0xff;
525,527c572,573
< #if !defined(_KERNEL) && !defined(KERNEL)
< fprintf(stdout, "ippr_ftp_pasv:missing cr-lf\n");
< #endif
---
> if (ippr_ftp_debug > 1)
> printf("ippr_ftp_pasv:missing %s", "cr-lf\n");
529a576,577
>
> a6 = a5 & 0xff;
534c582,587
< a1 = ntohl(ip->ip_src.s_addr);
---
> if (nat->nat_dir == NAT_INBOUND) {
> data_ip = nat->nat_outip.s_addr;
> a1 = ntohl(data_ip);
> } else
> data_ip = htonl(a1);
>
539,547d591
< 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;
549,551c593,596
< #if !defined(_KERNEL)
< m = *fin->fin_mp;
< m_copyback(m, off, nlen, newbuf);
---
> #if defined(SNPRINTF) && defined(_KERNEL)
> SNPRINTF(newbuf, sizeof(newbuf), "%s %s%u,%u,%u,%u,%u,%u%s\r\n",
> "227 Entering Passive Mode", brackets[0], a1, a2, a3, a4,
> a5, a6, brackets[1]);
553,558c598,604
< # 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)) {
< mblk_t *nm;
---
> (void) sprintf(newbuf, "%s %s%u,%u,%u,%u,%u,%u%s\r\n",
> "227 Entering Passive Mode", brackets[0], a1, a2, a3, a4,
> a5, a6, brackets[1]);
> #endif
> return ippr_ftp_pasvreply(fin, ip, nat, f, (a5 << 8 | a6),
> newbuf, s, data_ip);
> }
560,562c606,623
< /* alloc enough to keep same trailer space for lower driver */
< nm = allocb(nlen, BPRI_MED);
< PANIC((!nm),("ippr_ftp_out: allocb failed"));
---
> int ippr_ftp_pasvreply(fin, ip, nat, f, port, newmsg, s, data_ip)
> fr_info_t *fin;
> ip_t *ip;
> nat_t *nat;
> ftpside_t *f;
> u_int port;
> char *newmsg;
> char *s;
> u_int data_ip;
> {
> int inc, off, nflags, sflags;
> tcphdr_t *tcp, tcph, *tcp2;
> struct in_addr swip, swip2;
> struct in_addr data_addr;
> size_t nlen, olen;
> fr_info_t fi;
> nat_t *nat2;
> mb_t *m;
564,565c625,627
< nm->b_band = m1->b_band;
< nm->b_wptr += nlen;
---
> m = fin->fin_m;
> tcp = (tcphdr_t *)fin->fin_dp;
> off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff;
567,569c629,631
< m1->b_wptr -= olen;
< PANIC((m1->b_wptr < m1->b_rptr),
< ("ippr_ftp_out: cannot handle fragmented data block"));
---
> data_addr.s_addr = data_ip;
> tcp2 = &tcph;
> inc = 0;
571,573c633,641
< linkb(m1, nm);
< } else {
< m1->b_wptr += inc;
---
>
> olen = s - f->ftps_rptr;
> nlen = strlen(newmsg);
> inc = nlen - olen;
> if ((inc + ip->ip_len) > 65535) {
> if (ippr_ftp_debug > 0)
> printf("ippr_ftp_pasv:inc(%d) + ip->ip_len > 65535\n",
> inc);
> return 0;
575,577c643,647
< /*copyin_mblk(m, off, nlen, newbuf);*/
< # else /* SOLARIS */
< m = *fin->fin_mp;
---
>
> #if !defined(_KERNEL)
> bcopy(newmsg, MTOD(m, char *) + off, nlen);
> #else
> # if defined(MENTAT)
578a649,656
> (void)adjmsg(m, inc);
> # else /* defined(MENTAT) */
> /*
> * m_adj takes care of pkthdr.len, if required and treats inc<0 to
> * mean remove -len bytes from the end of the packet.
> * The mbuf chain will be extended if necessary by m_copyback().
> */
> if (inc < 0)
580,586c658,660
< /* the mbuf chain will be extended if necessary by m_copyback() */
< /*m_copyback(m, off, nlen, newbuf);*/
< # endif /* SOLARIS */
< #endif /* _KERNEL */
< if (inc != 0) {
< #if ((SOLARIS || defined(__sgi)) && defined(_KERNEL)) || !defined(_KERNEL)
< register u_32_t sum1, sum2;
---
> # endif /* defined(MENTAT) */
> #endif /* !defined(_KERNEL) */
> COPYBACK(m, off, nlen, newmsg);
588,598c662
< sum1 = ip->ip_len;
< sum2 = ip->ip_len + inc;
<
< /* Because ~1 == -2, We really need ~1 == -1 */
< if (sum1 > sum2)
< sum2--;
< sum2 -= sum1;
< sum2 = (sum2 & 0xffff) + (sum2 >> 16);
<
< fix_outcksum(fin, &ip->ip_sum, sum2);
< #endif /* SOLARIS || defined(__sgi) */
---
> if (inc != 0) {
599a664,665
> fin->fin_dlen += inc;
> fin->fin_plen += inc;
601d666
< #endif /* 0 */
607a673,675
> fi.fin_state = NULL;
> fi.fin_nat = NULL;
> fi.fin_flx |= FI_IGNORE;
609,613c677,687
< dp = htons(fin->fin_data[1] - 1);
< fi.fin_data[1] = ntohs(dp);
< ipn = nat_outlookup(&fi, IPN_TCP, nat->nat_p, nat->nat_inip,
< ip->ip_dst, 0);
< if (ipn == NULL) {
---
> fi.fin_data[1] = port;
> nflags = IPN_TCP|SI_W_SPORT;
> if (ippr_ftp_pasvrdr && f->ftps_ifp)
> nflags |= SI_W_DPORT;
> if (nat->nat_dir == NAT_OUTBOUND)
> nat2 = nat_outlookup(&fi, nflags|NAT_SEARCH,
> nat->nat_p, nat->nat_inip, nat->nat_oip);
> else
> nat2 = nat_inlookup(&fi, nflags|NAT_SEARCH,
> nat->nat_p, nat->nat_inip, nat->nat_oip);
> if (nat2 == NULL) {
621c695
< tcp2->th_off = 5;
---
> TCP_OFF_A(tcp2, 5);
623c697
< fi.fin_data[1] = a5 << 8 | a6;
---
> fi.fin_data[1] = port;
625c699
< tcp2->th_dport = htons(fi.fin_data[1]);
---
> tcp2->th_dport = htons(port);
627a702
> fi.fin_plen = fi.fin_hlen + sizeof(*tcp);
629c704,705
< fi.fin_out = 1;
---
> fi.fin_out = nat->nat_dir;
> fi.fin_flx &= FI_LOWTTL|FI_FRAG|FI_TCPUDP|FI_OPTIONS|FI_IGNORE;
632,641c708,717
< fi.fin_fi.fi_daddr = ip->ip_src.s_addr;
< fi.fin_fi.fi_saddr = nat->nat_inip.s_addr;
< ip->ip_dst = ip->ip_src;
< ip->ip_src = nat->nat_inip;
< ipn = nat_new(&fi, ip, nat->nat_ptr, NULL, IPN_TCP|FI_W_SPORT,
< NAT_OUTBOUND);
< if (ipn != NULL) {
< ipn->nat_age = fr_defnatage;
< (void) fr_addstate(ip, &fi, NULL,
< FI_W_SPORT|FI_IGNOREPKT);
---
> if (nat->nat_dir == NAT_OUTBOUND) {
> fi.fin_fi.fi_daddr = data_addr.s_addr;
> fi.fin_fi.fi_saddr = nat->nat_inip.s_addr;
> ip->ip_dst = data_addr;
> ip->ip_src = nat->nat_inip;
> } else if (nat->nat_dir == NAT_INBOUND) {
> fi.fin_fi.fi_saddr = nat->nat_oip.s_addr;
> fi.fin_fi.fi_daddr = nat->nat_outip.s_addr;
> ip->ip_src = nat->nat_oip;
> ip->ip_dst = nat->nat_outip;
642a719,737
>
> sflags = nflags;
> nflags |= NAT_SLAVE;
> if (nat->nat_dir == NAT_INBOUND)
> nflags |= NAT_NOTRULEPORT;
> nat2 = nat_new(&fi, nat->nat_ptr, NULL, nflags, nat->nat_dir);
> if (nat2 != NULL) {
> (void) nat_proto(&fi, nat2, IPN_TCP);
> nat_update(&fi, nat2, nat->nat_ptr);
> fi.fin_ifp = NULL;
> if (nat->nat_dir == NAT_INBOUND) {
> fi.fin_fi.fi_daddr = nat->nat_inip.s_addr;
> ip->ip_dst = nat->nat_inip;
> }
> (void) fr_addstate(&fi, &nat2->nat_state, sflags);
> if (fi.fin_state != NULL)
> fr_statederef(&fi, (ipstate_t **)&fi.fin_state);
> }
>
645a741,753
> } else {
> ipstate_t *is;
>
> nat_update(&fi, nat2, nat->nat_ptr);
> READ_ENTER(&ipf_state);
> is = nat2->nat_state;
> if (is != NULL) {
> MUTEX_ENTER(&is->is_lock);
> (void)fr_tcp_age(&is->is_sti, &fi, ips_tqtqb,
> is->is_flags);
> MUTEX_EXIT(&is->is_lock);
> }
> RWLOCK_EXIT(&ipf_state);
667c775,777
< if (!isdigit(*rptr) || !isdigit(*(rptr + 1)) || !isdigit(*(rptr + 2)))
---
> if (*rptr == ' ')
> goto server_cmd_ok;
> if (!ISDIGIT(*rptr) || !ISDIGIT(*(rptr + 1)) || !ISDIGIT(*(rptr + 2)))
671a782,783
> else if (!strncmp(rptr, "229 ", 4))
> inc = ippr_ftp_epsv(fin, ip, nat, f, dlen);
673a786,787
> } else if (ippr_ftp_insecure && !strncmp(rptr, "229 ", 4)) {
> inc = ippr_ftp_epsv(fin, ip, nat, f, dlen);
697a812
> server_cmd_ok:
716c831
< register char *s, c;
---
> register char *s, c, pc;
719a835,839
> s = buf;
>
> if (ftps->ftps_junk == 1)
> return 1;
>
721,724c841,842
< #if !defined(_KERNEL) && !defined(KERNEL)
< fprintf(stdout, "ippr_ftp_client_valid:i(%lu) < 5\n",
< (u_long)i);
< #endif
---
> if (ippr_ftp_debug > 3)
> printf("ippr_ftp_client_valid:i(%d) < 5\n", (int)i);
727,728c845
< s = buf;
< c = *s++;
---
>
729a847
> c = *s++;
731,732c849,850
< if (isalpha(c)) {
< cmd[0] = toupper(c);
---
> if (ISALPHA(c)) {
> cmd[0] = TOUPPER(c);
735,736c853,854
< if (isalpha(c)) {
< cmd[1] = toupper(c);
---
> if (ISALPHA(c)) {
> cmd[1] = TOUPPER(c);
739,740c857,858
< if (isalpha(c)) {
< cmd[2] = toupper(c);
---
> if (ISALPHA(c)) {
> cmd[2] = TOUPPER(c);
743,744c861,862
< if (isalpha(c)) {
< cmd[3] = toupper(c);
---
> if (ISALPHA(c)) {
> cmd[3] = TOUPPER(c);
757,761c875,879
< #if !defined(_KERNEL) && !defined(KERNEL)
< fprintf(stdout,
< "ippr_ftp_client_valid:bad cmd:len %lu i %lu c 0x%x\n",
< (u_long)i, (u_long)len, c);
< #endif
---
> if (ippr_ftp_debug > 3)
> printf("%s:bad:junk %d len %d/%d c 0x%x buf [%*.*s]\n",
> "ippr_ftp_client_valid",
> ftps->ftps_junk, (int)len, (int)i, c,
> (int)len, (int)len, buf);
765a884
> pc = c;
767c886
< if (c == '\n') {
---
> if ((pc == '\r') && (c == '\n')) {
776,777c895,897
< #if !defined(_KERNEL) && !defined(KERNEL)
< fprintf(stdout, "ippr_ftp_client_valid:junk after cmd[%s]\n", buf);
---
> #if !defined(_KERNEL)
> printf("ippr_ftp_client_valid:junk after cmd[%*.*s]\n",
> (int)len, (int)len, buf);
788c908
< register char *s, c;
---
> register char *s, c, pc;
792,793d911
< if (i < 5)
< return 2;
795d912
< c = *s++;
796a914,924
>
> if (ftps->ftps_junk == 1)
> return 1;
>
> if (i < 5) {
> if (ippr_ftp_debug > 3)
> printf("ippr_ftp_servert_valid:i(%d) < 5\n", (int)i);
> return 2;
> }
>
> c = *s++;
797a926,927
> if (c == ' ')
> goto search_eol;
799c929
< if (isdigit(c)) {
---
> if (ISDIGIT(c)) {
803c933
< if (isdigit(c)) {
---
> if (ISDIGIT(c)) {
807c937
< if (isdigit(c)) {
---
> if (ISDIGIT(c)) {
819,823c949,953
< #if !defined(_KERNEL) && !defined(KERNEL)
< fprintf(stdout,
< "ippr_ftp_server_valid:bad cmd:len %lu i %lu c 0x%x\n",
< (u_long)i, (u_long)len, c);
< #endif
---
> if (ippr_ftp_debug > 3)
> printf("%s:bad:junk %d len %d/%d c 0x%x buf [%*.*s]\n",
> "ippr_ftp_server_valid",
> ftps->ftps_junk, (int)len, (int)i,
> c, (int)len, (int)len, buf);
826c956
<
---
> search_eol:
827a958
> pc = c;
829c960
< if (c == '\n') {
---
> if ((pc == '\r') && (c == '\n')) {
834,836c965,967
< #if !defined(_KERNEL) && !defined(KERNEL)
< fprintf(stdout, "ippr_ftp_server_valid:junk after cmd[%s]\n", buf);
< #endif
---
> if (ippr_ftp_debug > 3)
> printf("ippr_ftp_server_valid:junk after cmd[%*.*s]\n",
> (int)len, (int)len, buf);
860a992
> * For map rules, the following applies:
862a995,997
> * For rdr rules, the following applies:
> * rv == 0 for inbound processing,
> * rv == 1 for outbound processing.
864c999
< int ippr_ftp_process(fin, ip, nat, ftp, rv)
---
> int ippr_ftp_process(fin, nat, ftp, rv)
866d1000
< ip_t *ip;
871a1006
> char *rptr, *wptr, *s;
873d1007
< char *rptr, *wptr;
876a1011
> ip_t *ip;
878a1014,1015
> m = fin->fin_m;
> ip = fin->fin_ip;
880,885c1017
< off = fin->fin_hlen + (tcp->th_off << 2);
< #if SOLARIS && defined(_KERNEL)
< m = fin->fin_qfm;
< #else
< m = *fin->fin_mp;
< #endif
---
> off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff;
887,888c1019,1025
< #ifndef _KERNEL
< mlen = mbuflen(m);
---
> f = &ftp->ftp_side[rv];
> t = &ftp->ftp_side[1 - rv];
> thseq = ntohl(tcp->th_seq);
> thack = ntohl(tcp->th_ack);
>
> #ifdef __sgi
> mlen = fin->fin_plen - off;
890,894c1027
< # if SOLARIS
< mlen = msgdsize(m);
< # else
< mlen = mbufchainlen(m);
< # endif
---
> mlen = MSGDSIZE(m) - off;
896c1029,1030
< mlen -= off;
---
> if (ippr_ftp_debug > 4)
> printf("ippr_ftp_process: mlen %d\n", mlen);
897a1032,1038
> if (mlen <= 0) {
> if ((tcp->th_flags & TH_OPENING) == TH_OPENING) {
> f->ftps_seq[0] = thseq + 1;
> t->ftps_seq[0] = thack;
> }
> return 0;
> }
899,902d1039
< t = &ftp->ftp_side[1 - rv];
< f = &ftp->ftp_side[rv];
< thseq = ntohl(tcp->th_seq);
< thack = ntohl(tcp->th_ack);
914,917d1050
< #if PROXY_DEBUG
< printf("seqoff %d thseq %x ackmin %x\n", seqoff, thseq,
< aps->aps_ackmin[sel]);
< #endif
918a1052,1054
> if (ippr_ftp_debug > 2)
> printf("seqoff %d thseq %x ackmin %x\n", seqoff, thseq,
> aps->aps_ackmin[sel]);
922,925d1057
< #if PROXY_DEBUG
< printf("ackoff %d thack %x seqmin %x\n", ackoff, thack,
< aps->aps_seqmin[sel2]);
< #endif
926a1059,1061
> if (ippr_ftp_debug > 2)
> printf("ackoff %d thack %x seqmin %x\n", ackoff, thack,
> aps->aps_seqmin[sel2]);
935,944c1070,1080
< #if PROXY_DEBUG
< printf("%s: %x seq %x/%d ack %x/%d len %d\n", rv ? "IN" : "OUT",
< tcp->th_flags, thseq, seqoff, thack, ackoff, mlen);
< printf("sel %d seqmin %x/%x offset %d/%d\n", sel,
< aps->aps_seqmin[sel], aps->aps_seqmin[sel2],
< aps->aps_seqoff[sel], aps->aps_seqoff[sel2]);
< printf("sel %d ackmin %x/%x offset %d/%d\n", sel2,
< aps->aps_ackmin[sel], aps->aps_ackmin[sel2],
< aps->aps_ackoff[sel], aps->aps_ackoff[sel2]);
< #endif
---
> if (ippr_ftp_debug > 2) {
> printf("%s: %x seq %x/%d ack %x/%d len %d/%d off %d\n",
> rv ? "IN" : "OUT", tcp->th_flags, thseq, seqoff,
> thack, ackoff, mlen, fin->fin_plen, off);
> printf("sel %d seqmin %x/%x offset %d/%d\n", sel,
> aps->aps_seqmin[sel], aps->aps_seqmin[sel2],
> aps->aps_seqoff[sel], aps->aps_seqoff[sel2]);
> printf("sel %d ackmin %x/%x offset %d/%d\n", sel2,
> aps->aps_ackmin[sel], aps->aps_ackmin[sel2],
> aps->aps_ackoff[sel], aps->aps_ackoff[sel2]);
> }
951,954c1087,1090
< #if PROXY_DEBUG
< printf("rv %d t:seq[0] %x seq[1] %x %d/%d\n",
< rv, t->ftps_seq[0], t->ftps_seq[1], seqoff, ackoff);
< #endif
---
> if (ippr_ftp_debug > 2) {
> printf("rv %d t:seq[0] %x seq[1] %x %d/%d\n",
> rv, t->ftps_seq[0], t->ftps_seq[1], seqoff, ackoff);
> }
983,986c1119,1122
< #if PROXY_DEBUG
< if (!ok)
< printf("not ok\n");
< #endif
---
> if (ippr_ftp_debug > 2) {
> if (!ok)
> printf("%s ok\n", "not");
> }
990,994c1126,1130
< #if !defined(_KERNEL) && !defined(KERNEL)
< fprintf(stdout,
< "ippr_ftp_process:seq[0](%x) + ackoff(%x) != thack(%x)\n",
< t->ftps_seq[0], ackoff, thack);
< #endif
---
> if (ippr_ftp_debug > 1) {
> printf("%s:seq[0](%x) + (%x) != (%x)\n",
> "ippr_ftp_process", t->ftps_seq[0],
> ackoff, thack);
> }
998,1000c1134,1138
< #if PROXY_DEBUG
< printf("f:seq[0] %x seq[1] %x\n", f->ftps_seq[0], f->ftps_seq[1]);
< #endif
---
> if (ippr_ftp_debug > 2) {
> printf("ippr_ftp_process:f:seq[0] %x seq[1] %x\n",
> f->ftps_seq[0], f->ftps_seq[1]);
> }
>
1006,1009c1144,1147
< #if PROXY_DEBUG || (!defined(_KERNEL) && !defined(KERNEL))
< printf("FIN: thseq %x seqoff %d ftps_seq %x\n",
< thseq, seqoff, f->ftps_seq[0]);
< #endif
---
> if (ippr_ftp_debug > 1) {
> printf("FIN: thseq %x seqoff %d ftps_seq %x\n",
> thseq, seqoff, f->ftps_seq[0]);
> }
1030,1038c1168,1176
< #if PROXY_DEBUG || (!defined(_KERNEL) && !defined(KERNEL))
< printf("inc %d sel %d rv %d\n", inc, sel, rv);
< printf("th_seq %x ftps_seq %x/%x\n", thseq, f->ftps_seq[0],
< f->ftps_seq[1]);
< printf("ackmin %x ackoff %d\n", (u_int)aps->aps_ackmin[sel],
< aps->aps_ackoff[sel]);
< printf("seqmin %x seqoff %d\n", (u_int)aps->aps_seqmin[sel],
< aps->aps_seqoff[sel]);
< #endif
---
> if (ippr_ftp_debug > 1) {
> printf("inc %d sel %d rv %d\n", inc, sel, rv);
> printf("th_seq %x ftps_seq %x/%x\n",
> thseq, f->ftps_seq[0], f->ftps_seq[1]);
> printf("ackmin %x ackoff %d\n", aps->aps_ackmin[sel],
> aps->aps_ackoff[sel]);
> printf("seqmin %x seqoff %d\n", aps->aps_seqmin[sel],
> aps->aps_seqoff[sel]);
> }
1051,1061c1189,1190
< len = MIN(mlen, FTP_BUFSZ / 2);
<
< #if !defined(_KERNEL)
< bcopy((char *)m + off, wptr, len);
< #else
< # if SOLARIS
< copyout_mblk(m, off, len, wptr);
< # else
< m_copydata(m, off, len, wptr);
< # endif
< #endif
---
> len = MIN(mlen, sizeof(f->ftps_buf) - (wptr - rptr));
> COPYDATA(m, off, len, wptr);
1064a1194,1200
>
> if (ippr_ftp_debug > 3)
> printf("%s:len %d/%d off %d wptr %lx junk %d [%*.*s]\n",
> "ippr_ftp_process",
> len, mlen, off, (u_long)wptr, f->ftps_junk,
> len, len, rptr);
>
1066c1202,1203
< if (f->ftps_junk == 2)
---
> if (f->ftps_junk != 0) {
> i = f->ftps_junk;
1069a1207,1231
> if (ippr_ftp_debug > 5)
> printf("%s:junk %d -> %d\n",
> "ippr_ftp_process", i, f->ftps_junk);
>
> if (f->ftps_junk != 0) {
> if (wptr - rptr == sizeof(f->ftps_buf)) {
> if (ippr_ftp_debug > 4)
> printf("%s:full buffer\n",
> "ippr_ftp_process");
> f->ftps_rptr = f->ftps_buf;
> f->ftps_wptr = f->ftps_buf;
> rptr = f->ftps_rptr;
> wptr = f->ftps_wptr;
> /*
> * Because we throw away data here that
> * we would otherwise parse, set the
> * junk flag to indicate just ignore
> * any data upto the next CRLF.
> */
> f->ftps_junk = 1;
> continue;
> }
> }
> }
>
1071,1072c1233,1243
< f->ftps_junk = ippr_ftp_valid(ftp, rv, rptr,
< wptr - rptr);
---
> len = wptr - rptr;
> f->ftps_junk = ippr_ftp_valid(ftp, rv, rptr, len);
>
> if (ippr_ftp_debug > 3) {
> printf("%s=%d len %d rv %d ptr %lx/%lx ",
> "ippr_ftp_valid",
> f->ftps_junk, len, rv, (u_long)rptr,
> (u_long)wptr);
> printf("buf [%*.*s]\n", len, len, rptr);
> }
>
1074,1075d1244
< f->ftps_cmds++;
< len = wptr - rptr;
1094,1097c1263,1266
< #if !defined(_KERNEL) && !defined(KERNEL)
< fprintf(stdout,
< "ippr_ftp_process:cmds == 0 junk == 1\n");
< #endif
---
>
> if (ippr_ftp_debug > 1)
> printf("%s:cmds == 0 junk == 1\n",
> "ippr_ftp_process");
1101,1112c1270,1275
< while ((f->ftps_junk == 1) && (rptr < wptr)) {
< while ((rptr < wptr) && (*rptr != '\r'))
< rptr++;
<
< if (*rptr == '\r') {
< if (rptr + 1 < wptr) {
< if (*(rptr + 1) == '\n') {
< rptr += 2;
< f->ftps_junk = 0;
< } else
< rptr++;
< } else
---
> if ((f->ftps_junk != 0) && (rptr < wptr)) {
> for (s = rptr; s < wptr; s++) {
> if ((*s == '\r') && (s + 1 < wptr) &&
> (*(s + 1) == '\n')) {
> rptr = s + 2;
> f->ftps_junk = 0;
1113a1277
> }
1116d1279
< f->ftps_rptr = rptr;
1121,1131c1284,1293
< if ((wptr > f->ftps_buf + FTP_BUFSZ / 2)) {
< i = wptr - rptr;
< if ((rptr == f->ftps_buf) ||
< (wptr - rptr > FTP_BUFSZ / 2)) {
< 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;
< }
---
> /*
> * Compact the buffer back to the start. The junk
> * flag should already be set and because we're not
> * throwing away any data, it is preserved from its
> * current state.
> */
> if (rptr > f->ftps_buf) {
> bcopy(rptr, f->ftps_buf, len);
> wptr -= rptr - f->ftps_buf;
> rptr = f->ftps_buf;
1133,1134d1294
< f->ftps_rptr = rptr;
< f->ftps_wptr = wptr;
1135a1296,1297
> f->ftps_rptr = rptr;
> f->ftps_wptr = wptr;
1141,1152c1303,1307
< #if PROXY_DEBUG
< # ifndef _KERNEL
< mlen = mbuflen(m);
< # else
< # if SOLARIS
< mlen = msgdsize(m);
< # else
< mlen = mbufchainlen(m);
< # endif
< # endif
< mlen -= off;
< printf("ftps_seq[1] = %x inc %d len %d\n", f->ftps_seq[1], inc, mlen);
---
> if (ippr_ftp_debug > 3) {
> #ifdef __sgi
> mlen = fin->fin_plen;
> #else
> mlen = MSGDSIZE(m);
1153a1309,1312
> mlen -= off;
> printf("ftps_seq[1] = %x inc %d len %d\n",
> f->ftps_seq[1], inc, mlen);
> }
1161c1320
< int ippr_ftp_out(fin, ip, aps, nat)
---
> int ippr_ftp_out(fin, aps, nat)
1163d1321
< ip_t *ip;
1167a1326
> int rev;
1172c1331,1336
< return ippr_ftp_process(fin, ip, nat, ftp, 0);
---
>
> rev = (nat->nat_dir == NAT_OUTBOUND) ? 0 : 1;
> if (ftp->ftp_side[1 - rev].ftps_ifp == NULL)
> ftp->ftp_side[1 - rev].ftps_ifp = fin->fin_ifp;
>
> return ippr_ftp_process(fin, nat, ftp, rev);
1176c1340
< int ippr_ftp_in(fin, ip, aps, nat)
---
> int ippr_ftp_in(fin, aps, nat)
1178d1341
< ip_t *ip;
1182a1346
> int rev;
1187c1351,1356
< return ippr_ftp_process(fin, ip, nat, ftp, 1);
---
>
> rev = (nat->nat_dir == NAT_OUTBOUND) ? 0 : 1;
> if (ftp->ftp_side[rev].ftps_ifp == NULL)
> ftp->ftp_side[rev].ftps_ifp = fin->fin_ifp;
>
> return ippr_ftp_process(fin, nat, ftp, 1 - rev);
1203c1372
< while ((c = *s++) && isdigit(c)) {
---
> while (((c = *s++) != '\0') && ISDIGIT(c)) {
1211c1380
< while ((c = *s++) && isdigit(c)) {
---
> while (((c = *s++) != '\0') && ISDIGIT(c)) {
1219a1389,1455
>
>
> int ippr_ftp_epsv(fin, ip, nat, f, dlen)
> fr_info_t *fin;
> ip_t *ip;
> nat_t *nat;
> ftpside_t *f;
> int dlen;
> {
> char newbuf[IPF_FTPBUFSZ];
> char *s;
> u_short ap = 0;
>
> #define EPSV_REPLEN 33
> /*
> * Check for EPSV reply message.
> */
> if (dlen < IPF_MIN229LEN)
> return (0);
> else if (strncmp(f->ftps_rptr,
> "229 Entering Extended Passive Mode", EPSV_REPLEN))
> return (0);
>
> /*
> * Skip the EPSV command + space
> */
> s = f->ftps_rptr + 33;
> while (*s && !ISDIGIT(*s))
> s++;
>
> /*
> * As per RFC 2428, there are no addres components in the EPSV
> * response. So we'll go straight to getting the port.
> */
> while (*s && ISDIGIT(*s)) {
> ap *= 10;
> ap += *s++ - '0';
> }
>
> if (!s)
> return 0;
>
> if (*s == '|')
> s++;
> if (*s == ')')
> s++;
> if (*s == '\n')
> s--;
> /*
> * check for CR-LF at the end.
> */
> if ((*s == '\r') && (*(s + 1) == '\n')) {
> s += 2;
> } else
> return 0;
>
> #if defined(SNPRINTF) && defined(_KERNEL)
> SNPRINTF(newbuf, sizeof(newbuf), "%s (|||%u|)\r\n",
> "229 Entering Extended Passive Mode", ap);
> #else
> (void) sprintf(newbuf, "%s (|||%u|)\r\n",
> "229 Entering Extended Passive Mode", ap);
> #endif
>
> return ippr_ftp_pasvreply(fin, ip, nat, f, (u_int)ap, newbuf, s,
> ip->ip_src.s_addr);
> }