diff options
author | pst <pst@FreeBSD.org> | 1995-08-05 19:12:05 +0000 |
---|---|---|
committer | pst <pst@FreeBSD.org> | 1995-08-05 19:12:05 +0000 |
commit | 0e79ca4d900784f6fb111f73eee3ea92efdc87be (patch) | |
tree | 0bb9b657884348aa946f639d6e015b17af89ad79 /usr.bin/ftp/ftp.c | |
parent | f87a14f2ec9b2da3dd881d031cc3eb22beded92e (diff) | |
download | FreeBSD-src-0e79ca4d900784f6fb111f73eee3ea92efdc87be.zip FreeBSD-src-0e79ca4d900784f6fb111f73eee3ea92efdc87be.tar.gz |
Use data ports in the range 40000..44999 by default to enhance FTP usability
in a firewall environment. Original idea by Mark Tracy (?).
Reviewed by: wollman
Submitted by: pst
Diffstat (limited to 'usr.bin/ftp/ftp.c')
-rw-r--r-- | usr.bin/ftp/ftp.c | 55 |
1 files changed, 46 insertions, 9 deletions
diff --git a/usr.bin/ftp/ftp.c b/usr.bin/ftp/ftp.c index 10327c5..137e8c2 100644 --- a/usr.bin/ftp/ftp.c +++ b/usr.bin/ftp/ftp.c @@ -1000,7 +1000,9 @@ initconn() char *p, *a; int result, len, tmpno = 0; int on = 1; + int count; u_long a1,a2,a3,a4,p1,p2; + static u_short last_port = FTP_DATA_BOTTOM; if (passivemode) { data = socket(AF_INET, SOCK_STREAM, 0); @@ -1051,9 +1053,6 @@ initconn() } noport: - data_addr = myctladdr; - if (sendport) - data_addr.sin_port = 0; /* let system pick one */ if (data != -1) (void) close(data); data = socket(AF_INET, SOCK_STREAM, 0); @@ -1063,15 +1062,53 @@ noport: sendport = 1; return (1); } - if (!sendport) - if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)) < 0) { + data_addr = myctladdr; + if (sendport) { + if (restricted_data_ports) { + for (count = 0; + count < FTP_DATA_TOP-FTP_DATA_BOTTOM; count++) { + last_port++; + if (last_port < FTP_DATA_BOTTOM || + last_port > FTP_DATA_TOP) + last_port = FTP_DATA_BOTTOM; + + data_addr.sin_port = htons(last_port); + if (bind(data, (struct sockaddr *)&data_addr, + sizeof(data_addr)) < 0) { + if (errno == EADDRINUSE) + continue; + else { + warn("bind"); + goto bad; + } + } + break; + } + if (count >= FTP_DATA_TOP-FTP_DATA_BOTTOM) { + perror("ftp: all data ports in use"); + goto bad; + } + } else { + data_addr.sin_port = 0; /* use any port */ + if (bind(data, (struct sockaddr *)&data_addr, + sizeof(data_addr)) < 0) { + warn("bind"); + goto bad; + } + } + } else { + if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, + (char *)&on, sizeof (on)) < 0) { warn("setsockopt (reuse address)"); goto bad; } - if (bind(data, (struct sockaddr *)&data_addr, sizeof (data_addr)) < 0) { - warn("bind"); - goto bad; - } + if (bind(data, (struct sockaddr *)&data_addr, + sizeof (data_addr)) < 0) { + warn("bind"); + goto bad; + } + } + if (options & SO_DEBUG && setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) < 0) warn("setsockopt (ignored)"); |