*** ftp-gw.c.orig Sun Jun 22 16:27:42 1997 --- ftp-gw.c Sun Jun 22 17:02:16 1997 *************** *** 11,31 **** --- 11,41 ---- */ static char RcsId[] = "$Header: /devel/CVS/IP-Filter/FWTK/ftp-gw.diff,v 2.1 1999/08/04 17:30:30 darrenr Exp $"; + /* + * Patches for IP Filter NAT extensions written by Darren Reed, 7/7/96 + * darrenr@cyber.com.au + */ + static char vIpFilter[] = "v3.1.11"; #include #include #include + #include + #include #include #include #include extern int errno; + #ifdef sun extern char *sys_errlist[]; + #endif #include #include #include #include #include #include + #include extern char *rindex(); extern char *index(); *************** *** 36,41 **** --- 46,54 ---- #include "firewall.h" + #include "ip_compat.h" + #include "ip_fil.h" + #include "ip_nat.h" #ifndef BSIZ #define BSIZ 2048 *************** *** 83,88 **** --- 96,103 ---- static int cmd_noop(); static int cmd_abor(); static int cmd_passthru(); + static int nat_destination(); + static int connectdest(); static void saveline(); static void flushsaved(); static void trap_sigurg(); *************** *** 317,323 **** if(authallflg) if(say(0,"220-Proxy first requires authentication")) exit(1); ! sprintf(xuf,"220 %s FTP proxy (Version %s) ready.",huf,FWTK_VERSION_MINOR); if(say(0,xuf)) exit(1); } --- 332,341 ---- if(authallflg) if(say(0,"220-Proxy first requires authentication")) exit(1); ! sprintf(xuf,"220-%s FTP proxy (Version %s) ready.",huf,FWTK_VERSION_MINOR); ! if(say(0,xuf)) ! exit(1); ! sprintf(xuf,"220-%s TIS ftp-gw with IP Filter %s NAT extensions",huf,vIpFilter); if(say(0,xuf)) exit(1); } *************** *** 338,343 **** --- 356,363 ---- exit(1); } + nat_destination(0); + /* main loop */ while(1) { FD_ZERO(&rdy); *************** *** 608,619 **** static char narg[] = "501 Missing or extra username"; static char noad[] = "501 Use user@site to connect via proxy"; char buf[1024]; - char mbuf[512]; char *p; char *dest; char *user; int x; - int msg_int; short port = FTPPORT; /* kludgy but effective. if authorizing everything call auth instead */ --- 628,637 ---- *************** *** 643,648 **** --- 661,687 ---- return(sayn(0,noad,sizeof(noad))); } + if((rfd == -1) && (x = connectdest(dest,port))) + return x; + sprintf(buf,"USER %s",user); + if(say(rfd,buf)) + return(1); + x = getresp(rfd,buf,sizeof(buf),1); + if(sendsaved(0,x)) + return(1); + return(say(0,buf)); + } + + static int + connectdest(dest,port) + char *dest; + short port; + { + char buf[1024]; + char mbuf[512]; + int msg_int; + int x; + if(*dest == '\0') dest = "localhost"; *************** *** 685,693 **** char ebuf[512]; strcpy(ebuf,buf); ! sprintf(buf,"521 %s: %s",dest,ebuf); return(say(0,buf)); } sprintf(buf,"----GATEWAY CONNECTED TO %s----",dest); saveline(buf); --- 724,733 ---- char ebuf[512]; strcpy(ebuf,buf); ! sprintf(buf,"521 %s,%d: %s",dest,ntohs(port),ebuf); return(say(0,buf)); } + sprintf(buf,"----GATEWAY CONNECTED TO %s----",dest); saveline(buf); *************** *** 698,711 **** return(say(0,buf)); } saveline(buf); ! ! sprintf(buf,"USER %s",user); ! if(say(rfd,buf)) ! return(1); ! x = getresp(rfd,buf,sizeof(buf),1); ! if(sendsaved(0,x)) ! return(1); ! return(say(0,buf)); } --- 738,745 ---- return(say(0,buf)); } saveline(buf); ! sendsaved(0,-1); ! return 0; } *************** *** 1591,1593 **** --- 1625,1671 ---- dup(nread); } #endif + + + static int + nat_destination(fd) + int fd; + { + struct sockaddr_in laddr, faddr; + struct natlookup natlookup; + char *dest; + int slen, natfd; + + bzero((char *)&laddr, sizeof(laddr)); + bzero((char *)&faddr, sizeof(faddr)); + slen = sizeof(laddr); + if(getsockname(fd,(struct sockaddr *)&laddr,&slen) < 0) { + perror("getsockname"); + exit(1); + } + slen = sizeof(faddr); + if(getpeername(fd,(struct sockaddr *)&faddr,&slen) < 0) { + perror("getsockname"); + exit(1); + } + + natlookup.nl_inport = laddr.sin_port; + natlookup.nl_outport = faddr.sin_port; + natlookup.nl_inip = laddr.sin_addr; + natlookup.nl_outip = faddr.sin_addr; + natlookup.nl_flags = IPN_TCP; + if((natfd = open(IPL_NAT, O_RDONLY)) < 0) { + perror("open"); + exit(1); + } + if(ioctl(natfd, SIOCGNATL, &natlookup) == -1) { + syslog(LOG_ERR, "SIOCGNATL failed: %m\n"); + close(natfd); + if(say(0,"220 Ready")) + exit(1); + return 0; + } + close(natfd); + return connectdest(inet_ntoa(natlookup.nl_realip), + ntohs(natlookup.nl_realport)); + }