Unix Technical Forum

SEO

vBulletin Search Engine Optimization


Go Back   Unix Technical Forum > Unix Operating Systems > OpenBSD > lucky.openbsd.tech

Register FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 02-22-2008, 11:20 AM
Ronnel P. Maglasang
 
Posts: n/a
Default Re: upgraded ftp-proxy to support ipv6

apologies, the patch is incorrect, i diff'ed in the wrong direction.
please disregard the previous one.

this is the correct patch file.

thanks

Ronnel P. Maglasang wrote:

> hi, i have here a patch for ftp-proxy to support both ipv4 and ipv6 ftp
> sessions. the codebase was based on OPENBSD_3_6 tag.
>
> any feedbacks greatly appreciated.
>
> thanks
> - ronnel
>
> eric wrote:
>
>> On Fri, 2005-03-18 at 14:10:41 +0800, Ronnel P. Maglasang proclaimed...
>>
>>
>>
>>> Hello everyone, I have upgraded the 3.6 ftp-proxy
>>> implementation to support ipv6. I have it tested
>>> on our local testbed. It now support both ipv4 and
>>> ipv6 ftp sessions. Support for ipv6 can be disabled
>>> during compilation. Does anyone here know how
>>> to contribute my work to the community?
>>>

>>
>>
>> Submit a patch to tech@
>>
>>

>
>------------------------------------------------------------------------
>
>diff -C 3 -r ftp-proxy-new/Makefile ftp-proxy/Makefile
>*** ftp-proxy-new/Makefile Fri Mar 18 16:34:47 2005
>--- ftp-proxy/Makefile Fri Nov 21 07:23:09 2003
>***************
>*** 14,20 ****
> DPADD+= ${LIBWRAP}
> .endif
>
>- # For ipv6 support
>- CFLAGS+= -DIPV6_SUP
>-
> .include <bsd.prog.mk>
>--- 14,17 ----
>diff -C 3 -r ftp-proxy-new/ftp-proxy.c ftp-proxy/ftp-proxy.c
>*** ftp-proxy-new/ftp-proxy.c Fri Mar 18 16:34:13 2005
>--- ftp-proxy/ftp-proxy.c Sun Jul 11 09:54:36 2004
>***************
>*** 55,67 ****
> * the real destination address - the tcp wrapper stuff is done after
> * the real destination address is retrieved from pf
> *
>- * Added support for IPv6.
>- * Changed all address structures to accomodate IPv4 and IPv6 addresses.
>- * Modified processing of EPRT. Added support for processing the response
>- * of LPRT to support IPv6 ftp session.
>- *
>- * - Ronnel Maglasang(rmaglasang@infoweapons.com)
>- * www.infoweapons.com
> */
>
> /*
>--- 55,60 ----
>***************
>*** 132,155 ****
>
> double xfer_start_time;
>
>- #ifdef IPV6_SUP
>- struct sockaddr_storage real_server_sa;
>- struct sockaddr_storage client_listen_sa;
>- struct sockaddr_storage server_listen_sa;
>- struct sockaddr_storage proxy_sa;
>- int address_family;
>- #else
> struct sockaddr_in real_server_sa;
> struct sockaddr_in client_listen_sa;
> struct sockaddr_in server_listen_sa;
> struct sockaddr_in proxy_sa;
>- #endif
>-
>- #ifdef IPV6_SUP
>- struct sockaddr_storage src_addr;
>- #else
> struct in_addr src_addr;
>- #endif
>
> int client_listen_socket = -1; /* Only used in PASV mode */
> int client_data_socket = -1; /* Connected socket to real client */
>--- 125,135 ----
>***************
>*** 166,198 ****
> char RealServerName[NI_MAXHOST];
> char OurName[NI_MAXHOST];
>
>- #ifdef IPV6_SUP
>- char ClientPortName[NI_MAXHOST];
>- char RealServerPortName[NI_MAXHOST];
>- char OurPortName[NI_MAXHOST];
>- #endif
>-
> char *User = "proxy";
> char *Group;
>
> extern int Debug_Level;
> extern int Use_Rdns;
>- #ifdef IPV6_SUP
>- extern int Bind_Addr_Flag;
>- extern struct sockaddr_storage Bind_Addr;
>- #else
> extern in_addr_t Bind_Addr;
>- #endif
> extern char *__progname;
>
> typedef enum {
> UNKNOWN_MODE,
> PORT_MODE,
> PASV_MODE,
>- #ifdef IPV6_SUP
>- LPRT_MODE,
>- LPSV_MODE,
>- #endif
> EPRT_MODE,
> EPSV_MODE
> } connection_mode_t;
>--- 146,163 ----
>***************
>*** 281,336 ****
> * if we are set to do reverse DNS, otherwise no.
> */
> static int
>- #ifdef IPV6_SUP
>- check_host(struct sockaddr_storage *client_sin, struct sockaddr_storage *server_sin)
>- #else
> check_host(struct sockaddr_in *client_sin, struct sockaddr_in *server_sin)
>- #endif
> {
> char cname[NI_MAXHOST];
> char sname[NI_MAXHOST];
>- #ifdef IPV6_SUP
>- char caddr[NI_MAXHOST];
>- char saddr[NI_MAXHOST];
>- #endif
> struct request_info request;
> int i;
>
>- #ifdef IPV6_SUP
>- #ifdef DEBUG_LOG
>- syslog(LOG_INFO, "entering check_host()\n");
>- #endif
>- #endif
>-
>- #ifdef IPV6_SUP
>- /* retrieve client address */
>- i = getnameinfo((struct sockaddr *)client_sin,
>- client_sin->ss_len, caddr, sizeof(caddr),
>- NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV);
>-
>- if (i != 0 && i != EAI_NONAME && i != EAI_AGAIN) {
>- syslog(LOG_NOTICE, "1 getnameinfo() failed!\n");
>- return(0);
>- }
>-
>- /* retrieve server address */
>- i = getnameinfo((struct sockaddr *)server_sin,
>- server_sin->ss_len, saddr, sizeof(saddr),
>- NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV);
>-
>- if (i != 0 && i != EAI_NONAME && i != EAI_AGAIN) {
>- syslog(LOG_NOTICE, "2 getnameinfo() failed!\n");
>- return(0);
>- }
>-
>- request_init(&request, RQ_DAEMON, __progname, RQ_CLIENT_SIN,
>- client_sin, RQ_SERVER_SIN, server_sin, RQ_CLIENT_ADDR,
>- caddr, 0);
>- #else
> request_init(&request, RQ_DAEMON, __progname, RQ_CLIENT_SIN,
> client_sin, RQ_SERVER_SIN, server_sin, RQ_CLIENT_ADDR,
> inet_ntoa(client_sin->sin_addr), 0);
>- #endif
>
> if (Use_Rdns) {
> /*
>--- 246,261 ----
>***************
>*** 339,359 ****
> * the tcp wrapper cares about these things, and we don't
> * want to pass in a printed address as a name.
> */
>- #ifdef IPV6_SUP
>- i = getnameinfo((struct sockaddr *)client_sin,
>- client_sin->ss_len, cname, sizeof(cname),
>- NULL, 0, NI_NAMEREQD);
>-
>- if (i != 0 && i != EAI_NONAME && i != EAI_AGAIN)
>- strlcpy(cname, STRING_UNKNOWN, sizeof(cname));
>-
>- i = getnameinfo((struct sockaddr *)server_sin,
>- server_sin->ss_len, sname, sizeof(sname),
>- NULL, 0, NI_NAMEREQD);
>-
>- if (i != 0 && i != EAI_NONAME && i != EAI_AGAIN)
>- strlcpy(sname, STRING_UNKNOWN, sizeof(sname));
>- #else
> i = getnameinfo((struct sockaddr *) &client_sin->sin_addr,
> sizeof(&client_sin->sin_addr), cname, sizeof(cname),
> NULL, 0, NI_NAMEREQD);
>--- 264,269 ----
>***************
>*** 367,373 ****
>
> if (i != 0 && i != EAI_NONAME && i != EAI_AGAIN)
> strlcpy(sname, STRING_UNKNOWN, sizeof(sname));
>- #endif
> } else {
> /*
> * ensure the TCP wrapper doesn't start doing
>--- 277,282 ----
>***************
>*** 377,388 ****
> strlcpy(sname, STRING_UNKNOWN, sizeof(sname));
> }
>
>- #ifdef IPV6_SUP
>- request_set(&request, RQ_SERVER_ADDR, saddr, 0);
>- #else
> request_set(&request, RQ_SERVER_ADDR, inet_ntoa(server_sin->sin_addr),
> 0);
>- #endif
> request_set(&request, RQ_CLIENT_NAME, cname, RQ_SERVER_NAME, sname, 0);
>
> if (!hosts_access(&request)) {
>--- 286,293 ----
>***************
>*** 517,528 ****
> * Close existing data conn.
> */
>
>- #ifdef IPV6_SUP
>- #ifdef DEBUG_LOG
>- syslog(LOG_INFO, "new_dataconn() server: [%d]\n", server);
>- #endif
>- #endif
>-
> if (client_listen_socket != -1) {
> close(client_listen_socket);
> client_listen_socket = -1;
>--- 422,427 ----
>***************
>*** 537,549 ****
>
> if (server) {
> bzero(&server_listen_sa, sizeof(server_listen_sa));
>- #ifdef IPV6_SUP
>- server_listen_socket = get_backchannel_socket(address_family,
>- SOCK_STREAM, min_port, max_port, -1, 1, &server_listen_sa);
>- #else
> server_listen_socket = get_backchannel_socket(SOCK_STREAM,
> min_port, max_port, -1, 1, &server_listen_sa);
>- #endif
>
> if (server_listen_socket == -1) {
> syslog(LOG_INFO, "server socket bind() failed (%m)");
>--- 436,443 ----
>***************
>*** 555,567 ****
> }
> } else {
> bzero(&client_listen_sa, sizeof(client_listen_sa));
>- #ifdef IPV6_SUP
>- client_listen_socket = get_backchannel_socket(address_family,
>- SOCK_STREAM, min_port, max_port, -1, 1, &client_listen_sa);
>- #else
> client_listen_socket = get_backchannel_socket(SOCK_STREAM,
> min_port, max_port, -1, 1, &client_listen_sa);
>- #endif
>
> if (client_listen_socket == -1) {
> syslog(LOG_NOTICE,
>--- 449,456 ----
>***************
>*** 580,611 ****
> static void
> connect_pasv_backchannel(void)
> {
>- #ifdef IPV6_SUP
>- struct sockaddr_storage listen_sa;
>- #else
> struct sockaddr_in listen_sa;
>- #endif
> socklen_t salen;
>- #ifdef IPV6_SUP
>- #ifdef DEBUG_LOG
>- char host[NI_MAXHOST];
>- char port[NI_MAXHOST];
>- #endif
>- #endif
>
> /*
> * We are about to accept a connection from the client.
> * This is a PASV data connection.
> */
>- #ifdef IPV6_SUP
>- #ifdef DEBUG_LOG
>- syslog(LOG_INFO, "client listen socket ready");
>- #endif
>-
>- debuglog(2, "client listen socket ready");
>- #else
> debuglog(2, "client listen socket ready");
>- #endif
>
> close_server_data();
> close_client_data();
>--- 469,482 ----
>***************
>*** 622,662 ****
> client_listen_socket = -1;
> memset(&listen_sa, 0, sizeof(listen_sa));
>
>- #ifdef IPV6_SUP
>- server_data_socket = get_backchannel_socket(address_family, SOCK_STREAM, min_port,
>- max_port, -1, 1, (struct sockaddr_storage *)&listen_sa);
>- #else
> server_data_socket = get_backchannel_socket(SOCK_STREAM, min_port,
>! max_port, -1, 1, &listen_sa);
>! #endif
> if (server_data_socket < 0) {
> syslog(LOG_NOTICE, "get_backchannel_socket() failed (%m)");
> exit(EX_OSERR);
> }
>- #ifdef IPV6_SUP
>- #ifdef DEBUG_LOG
>- getnameinfo((struct sockaddr *)&server_listen_sa,
>- server_listen_sa.ss_len,
>- host, sizeof(host),
>- port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV);
>-
>- syslog(LOG_INFO, "1 server_data_socket: [%d], host: [%s], port: [%s]\n",
>- server_data_socket, host, port);
>-
>- getnameinfo((struct sockaddr *)&listen_sa,
>- listen_sa.ss_len,
>- host, sizeof(host),
>- port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV);
>-
>- syslog(LOG_INFO, "2 host: [%s], port: [%s]\n", host, port);
>- #endif
>-
>- if (connect(server_data_socket, (struct sockaddr *) &server_listen_sa,
>- server_listen_sa.ss_len) != 0) {
>- #else
> if (connect(server_data_socket, (struct sockaddr *) &server_listen_sa,
> sizeof(server_listen_sa)) != 0) {
>- #endif
> syslog(LOG_NOTICE, "connect() failed (%m)");
> exit(EX_NOHOST);
> }
>--- 493,506 ----
> client_listen_socket = -1;
> memset(&listen_sa, 0, sizeof(listen_sa));
>
> server_data_socket = get_backchannel_socket(SOCK_STREAM, min_port,
>! max_port, -1, 1, &listen_sa);
> if (server_data_socket < 0) {
> syslog(LOG_NOTICE, "get_backchannel_socket() failed (%m)");
> exit(EX_OSERR);
> }
> if (connect(server_data_socket, (struct sockaddr *) &server_listen_sa,
> sizeof(server_listen_sa)) != 0) {
> syslog(LOG_NOTICE, "connect() failed (%m)");
> exit(EX_NOHOST);
> }
>***************
>*** 668,701 ****
> static void
> connect_port_backchannel(void)
> {
>- #ifdef IPV6_SUP
>- struct sockaddr_storage listen_sa;
>- struct sockaddr_in *sockaddr4;
>- struct sockaddr_in6 *sockaddr6;
>- #else
> struct sockaddr_in listen_sa;
>- #endif
> socklen_t salen;
>- #ifdef IPV6_SUP
>- #ifdef DEBUG_LOG
>- char host[NI_MAXHOST];
>- char port[NI_MAXHOST];
>- #endif
>- #endif
>
> /*
> * We are about to accept a connection from the server.
> * This is a PORT or EPRT data connection.
> */
>- #ifdef IPV6_SUP
>- #ifdef DEBUG_LOG
>- syslog(LOG_INFO, "server listen socket ready");
>- #endif
>-
> debuglog(2, "server listen socket ready");
>- #else
>- debuglog(2, "server listen socket ready");
>- #endif
>
> close_server_data();
> close_client_data();
>--- 512,525 ----
>***************
>*** 707,723 ****
> syslog(LOG_NOTICE, "accept() failed (%m)");
> exit(EX_OSERR);
> }
>- #ifdef IPV6_SUP
>- #ifdef DEBUG_LOG
>- getnameinfo((struct sockaddr *)&listen_sa,
>- listen_sa.ss_len,
>- host, sizeof(host),
>- port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV);
>-
>- syslog(LOG_INFO, "server_listen_socket: [%d], host: [%s], port: [%s]\n",
>- server_listen_socket, host, port);
>- #endif
>- #endif
> close(server_listen_socket);
> server_listen_socket = -1;
>
>--- 531,536 ----
>***************
>*** 728,761 ****
> * getting one bound to port 20 - This is deliberately
> * not RFC compliant.
> */
>- #ifdef IPV6_SUP
>- #ifdef DEBUG_LOG
>- syslog(LOG_INFO, "running as non-root\n");
>- syslog(LOG_INFO, "address_family: [%d]\n", address_family);
>- #endif
>- #endif
>-
>- #ifdef IPV6_SUP
>- /* clear address based on address family */
>- if (address_family == AF_INET) {
>- sockaddr4 = (struct sockaddr_in *)&listen_sa;
>- bzero(&sockaddr4->sin_addr, sizeof(struct in_addr));
>- }
>- else {
>- sockaddr6 = (struct sockaddr_in6 *)&listen_sa;
>- bzero(&sockaddr6->sin6_addr, sizeof(struct in6_addr));
>- }
>- #else
> bzero(&listen_sa.sin_addr, sizeof(struct in_addr));
>- #endif
>-
>- #ifdef IPV6_SUP
>- client_data_socket = get_backchannel_socket(address_family, SOCK_STREAM,
>- min_port, max_port, -1, 1, (struct sockaddr_storage *)&listen_sa);
>- #else
> client_data_socket = get_backchannel_socket(SOCK_STREAM,
>! min_port, max_port, -1, 1, &listen_sa);
>! #endif
> if (client_data_socket < 0) {
> syslog(LOG_NOTICE, "get_backchannel_socket() failed (%m)");
> exit(EX_OSERR);
>--- 541,549 ----
> * getting one bound to port 20 - This is deliberately
> * not RFC compliant.
> */
> bzero(&listen_sa.sin_addr, sizeof(struct in_addr));
> client_data_socket = get_backchannel_socket(SOCK_STREAM,
>! min_port, max_port, -1, 1, &listen_sa);
> if (client_data_socket < 0) {
> syslog(LOG_NOTICE, "get_backchannel_socket() failed (%m)");
> exit(EX_OSERR);
>***************
>*** 767,799 ****
> * We're root, get our backchannel socket bound to port
> * 20 here, so we're fully RFC compliant.
> */
>- #ifdef IPV6_SUP
>- #ifdef DEBUG_LOG
>- syslog(LOG_INFO, "running as root\n");
>- #endif
>- #endif
>-
>- #ifdef IPV6_SUP
>- client_data_socket = socket(address_family, SOCK_STREAM, 0);
>-
>- salen = 1;
>- if (address_family == AF_INET) {
>- sockaddr4 = (struct sockaddr_in *)&listen_sa;
>- sockaddr4->sin_family = AF_INET;
>- bcopy(&((struct sockaddr_in *)&src_addr)->sin_addr,
>- &sockaddr4->sin_addr, sizeof(struct in_addr));
>- sockaddr4->sin_port = htons(20);
>- }
>- else {
>- }
>- #else
> client_data_socket = socket(AF_INET, SOCK_STREAM, 0);
>
> salen = 1;
> listen_sa.sin_family = AF_INET;
> bcopy(&src_addr, &listen_sa.sin_addr, sizeof(struct in_addr));
> listen_sa.sin_port = htons(20);
>- #endif
>
> if (setsockopt(client_data_socket, SOL_SOCKET, SO_REUSEADDR,
> &salen, sizeof(salen)) == -1) {
>--- 555,566 ----
>***************
>*** 808,830 ****
> }
> }
>
>- #ifdef IPV6_SUP
>- #ifdef DEBUG_LOG
>- getnameinfo((struct sockaddr *)&client_listen_sa,
>- client_listen_sa.ss_len,
>- host, sizeof(host),
>- port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV);
>-
>- syslog(LOG_INFO, "client_data_socket: [%d], host: [%s], port: [%s]\n",
>- client_data_socket, host, port);
>- #endif
>-
>- if (connect(client_data_socket, (struct sockaddr *) &client_listen_sa,
>- client_listen_sa.ss_len) != 0) {
>- #else
> if (connect(client_data_socket, (struct sockaddr *) &client_listen_sa,
> sizeof(client_listen_sa)) != 0) {
>- #endif
> syslog(LOG_INFO, "cannot connect data channel (%m)");
> exit(EX_NOHOST);
> }
>--- 575,582 ----
>***************
>*** 840,871 ****
> int i, j, rv;
> char tbuf[100];
> char *sendbuf = NULL;
>- #ifdef IPV6_SUP
>- char c_addr_str[NI_MAXHOST];
>- char c_port_str[NI_MAXHOST];
>- char s_addr_str[NI_MAXHOST];
>- char s_port_str[NI_MAXHOST];
>- int ret;
>- #endif
>
> log_control_command((char *)client->line_buffer, 1);
>
>- #ifdef IPV6_SUP
>- #ifdef DEBUG_LOG
>- syslog(LOG_INFO, "client->line_buffer: [%s]\n", (char *)client->line_buffer);
>- #endif
>- #endif
>-
>- #ifdef IPV6_SUP
>- ret = getnameinfo((struct sockaddr *)&server->sa, server->sa.ss_len, s_addr_str,
>- sizeof(s_addr_str), NULL, 0,
>- NI_NUMERICHOST | NI_NUMERICSERV);
>-
>- if (ret != 0) {
>- strcpy(s_addr_str, "unknown server address");
>- }
>- #endif
>-
> /* client->line_buffer is an ftp control command.
> * There is no reason for these to be very long.
> * In the interest of limiting buffer overrun attempts,
>--- 592,600 ----
>***************
>*** 938,957 ****
> goto protounsupp;
>
> memset(&hints, 0, sizeof(hints));
>- #ifdef IPV6_SUP
>- /* Support for both IPV4 and IPV6 */
>- if ((proto != 1) && (proto != 2))
>- goto protounsupp;
>- hints.ai_family = AF_UNSPEC;
>- hints.ai_socktype = SOCK_STREAM;
>- hints.ai_flags = AI_NUMERICHOST; /*no DNS*/
>- #else
> if (proto != 1) /* 1 == AF_INET - all we support for now */
> goto protounsupp;
> hints.ai_family = AF_INET;
> hints.ai_socktype = SOCK_STREAM;
> hints.ai_flags = AI_NUMERICHOST; /*no DNS*/
>- #endif
> if (getaddrinfo(result[1], result[2], &hints, &res))
> goto parsefail;
> if (res->ai_next)
>--- 667,677 ----
>***************
>*** 960,987 ****
> goto parsefail;
> memcpy(&client_listen_sa, res->ai_addr, res->ai_addrlen);
>
>- #ifdef IPV6_SUP
>- ret = getnameinfo(res->ai_addr, res->ai_addrlen, c_addr_str,
>- sizeof(c_addr_str), c_port_str, sizeof(c_port_str),
>- NI_NUMERICHOST | NI_NUMERICSERV);
>-
>- if (ret != 0) {
>- strcpy(c_addr_str, "unknown client address");
>- strcpy(c_port_str, "unknown client port");
>- }
>-
>- #ifdef DEBUG_LOG
>- syslog(LOG_INFO, "client wants us to use %s:%s",
>- c_addr_str, c_port_str);
>- #endif
>-
>- debuglog(1, "client wants us to use %s:%s",
>- c_addr_str, c_port_str);
>- #else
> debuglog(1, "client wants us to use %s:%u",
> inet_ntoa(client_listen_sa.sin_addr),
> htons(client_listen_sa.sin_port));
>- #endif
>
> /*
> * Configure our own listen socket and tell the server about it
>--- 680,688 ----
>***************
>*** 989,1030 ****
> new_dataconn(1);
> connection_mode = EPRT_MODE;
>
>- #ifdef IPV6_SUP
>- i = getnameinfo((struct sockaddr *)&server_listen_sa, server_listen_sa.ss_len, NULL,
>- 0, s_port_str, sizeof(s_port_str),
>- NI_NUMERICHOST | NI_NUMERICSERV);
>-
>- if (ret != 0) {
>- strcpy(s_port_str, "unknown server port");
>- }
>-
>- #ifdef DEBUG_LOG
>- syslog(LOG_INFO, "we want server to use %s:%s",
>- s_addr_str, s_port_str);
>- #endif
>-
>- debuglog(1, "we want server to use %s:%s",
>- s_addr_str, s_port_str);
>- #else
> debuglog(1, "we want server to use %s:%u",
> inet_ntoa(server->sa.sin_addr),
> ntohs(server_listen_sa.sin_port));
>- #endif
>
>- #ifdef IPV6_SUP
>- snprintf(tbuf, sizeof(tbuf), "EPRT |%u|%s|%s|\r\n", (unsigned int)proto,
>- s_addr_str, s_port_str);
>- #else
> snprintf(tbuf, sizeof(tbuf), "EPRT |%d|%s|%u|\r\n", 1,
> inet_ntoa(server->sa.sin_addr),
> ntohs(server_listen_sa.sin_port));
>- #endif
>-
>- #ifdef IPV6_SUP
>- #ifdef DEBUG_LOG
>- syslog(LOG_INFO, "to server (modified): %s", tbuf);
>- #endif
>- #endif
> debuglog(1, "to server (modified): %s", tbuf);
> sendbuf = tbuf;
> goto out;
>--- 690,702 ----
>***************
>*** 1034,1044 ****
> sendbuf = NULL;
> goto out;
> protounsupp:
>- #ifdef IPV6_SUP
>- /* we support AF_INET and AF_INET6 now */
>- snprintf(tbuf, sizeof(tbuf),
>- "501 Protocol not supported\r\n");
>- #else
> /* we only support AF_INET for now */
> if (proto == 2)
> snprintf(tbuf, sizeof(tbuf),
>--- 706,711 ----
>***************
>*** 1046,1052 ****
> else
> snprintf(tbuf, sizeof(tbuf),
> "501 Protocol not supported\r\n");
>- #endif
> sendbuf = NULL;
> out:
> if (line)
>--- 713,718 ----
>***************
>*** 1099,1109 ****
> strlen("port ")) == 0) {
> unsigned int values[6];
> char *tailptr;
>- #ifdef IPV6_SUP
>- struct sockaddr_in *client_sockaddr_in;
>- struct sockaddr_in *server_sockaddr_in;
>- struct sockaddr_in *server_listen_sockaddr_in;
>- #endif
>
> debuglog(1, "Got a PORT command");
>
>--- 765,770 ----
>***************
>*** 1128,1146 ****
> }
> }
>
>- #ifdef IPV6_SUP
>- client_sockaddr_in = (struct sockaddr_in *)&client_listen_sa;
>- client_sockaddr_in->sin_family = AF_INET;
>- client_sockaddr_in->sin_addr.s_addr = htonl((values[0] << 24) |
>- (values[1] << 16) | (values[2] << 8) |
>- (values[3] << 0));
>-
>- client_sockaddr_in->sin_port = htons((values[4] << 8) |
>- values[5]);
>- debuglog(1, "client wants us to use %u.%u.%u.%u:%u",
>- values[0], values[1], values[2], values[3],
>- (values[4] << 8) | values[5]);
>- #else
> client_listen_sa.sin_family = AF_INET;
> client_listen_sa.sin_addr.s_addr = htonl((values[0] << 24) |
> (values[1] << 16) | (values[2] << 8) |
>--- 789,794 ----
>***************
>*** 1151,1157 ****
> debuglog(1, "client wants us to use %u.%u.%u.%u:%u",
> values[0], values[1], values[2], values[3],
> (values[4] << 8) | values[5]);
>- #endif
>
> /*
> * Configure our own listen socket and tell the server about it
>--- 799,804 ----
>***************
>*** 1159,1197 ****
> new_dataconn(1);
> connection_mode = PORT_MODE;
>
>- #ifdef IPV6_SUP
>- i = getnameinfo((struct sockaddr *)&server_listen_sa, server_listen_sa.ss_len, NULL,
>- 0, s_port_str, sizeof(s_port_str),
>- NI_NUMERICHOST | NI_NUMERICSERV);
>-
>- if (ret != 0) {
>- strcpy(s_port_str, "unknown server port");
>- }
>-
>- #ifdef DEBUG_LOG
>- syslog(LOG_INFO, "we want server to use %s:%s",
>- s_addr_str, s_port_str);
>- #endif
>-
>- debuglog(1, "we want server to use %s:%s",
>- s_addr_str, s_port_str);
>- #else
> debuglog(1, "we want server to use %s:%u",
> inet_ntoa(server->sa.sin_addr),
> ntohs(server_listen_sa.sin_port));
>- #endif
>
>- #ifdef IPV6_SUP
>- server_sockaddr_in = (struct sockaddr_in *)&server->sa;
>- server_listen_sockaddr_in = (struct sockaddr_in *)&server_listen_sa;
>- snprintf(tbuf, sizeof(tbuf), "PORT %u,%u,%u,%u,%u,%u\r\n",
>- ((u_char *)&server_sockaddr_in->sin_addr.s_addr)[0],
>- ((u_char *)&server_sockaddr_in->sin_addr.s_addr)[1],
>- ((u_char *)&server_sockaddr_in->sin_addr.s_addr)[2],
>- ((u_char *)&server_sockaddr_in->sin_addr.s_addr)[3],
>- ((u_char *)&server_listen_sockaddr_in->sin_port)[0],
>- ((u_char *)&server_listen_sockaddr_in->sin_port)[1]);
>- #else
> snprintf(tbuf, sizeof(tbuf), "PORT %u,%u,%u,%u,%u,%u\r\n",
> ((u_char *)&server->sa.sin_addr.s_addr)[0],
> ((u_char *)&server->sa.sin_addr.s_addr)[1],
>--- 806,815 ----
>***************
>*** 1199,1211 ****
> ((u_char *)&server->sa.sin_addr.s_addr)[3],
> ((u_char *)&server_listen_sa.sin_port)[0],
> ((u_char *)&server_listen_sa.sin_port)[1]);
>- #endif
>
>- #ifdef IPV6_SUP
>- #ifdef DEBUG_LOG
>- syslog(LOG_INFO, "to server (modified): %s", tbuf);
>- #endif
>- #endif
> debuglog(1, "to server (modified): %s", tbuf);
>
> sendbuf = tbuf;
>--- 817,823 ----
>***************
>*** 1236,1260 ****
> struct in_addr *iap;
> static int continuing = 0;
> char tbuf[100], *sendbuf, *p;
>- #ifdef IPV6_SUP
>- struct sockaddr_in *client_sockaddr_in;
>- struct sockaddr_in *server_sockaddr_in;
>- struct sockaddr_in *proxy_sockaddr_in;
>- struct sockaddr_in6 *client_sockaddr_in6;
>- struct sockaddr_in6 *server_sockaddr_in6;
>- struct sockaddr_in6 *use_sockaddr_in6;
>- char host[NI_MAXHOST];
>- char port[NI_MAXHOST];
>- #endif
>
> log_control_command((char *)server->line_buffer, 0);
>
>- #ifdef IPV6_SUP
>- #ifdef DEBUG_LOG
>- syslog(LOG_INFO, "server->line_buffer: [%s]\n", (char *)server->line_buffer);
>- #endif
>- #endif
>-
> if (strlen((char *)server->line_buffer) > 512) {
> /*
> * someone's playing games. Have a cow in the syslogs and
>--- 848,856 ----
>***************
>*** 1291,1303 ****
> unsigned int values[6];
> char *tailptr;
>
>- #ifdef IPV6_SUP
>- #ifdef DEBUG_LOG
>- syslog(LOG_INFO, "PASV reply\n");
>- syslog(LOG_INFO, "address_family: [%d]\n", address_family);
>- #endif
>- #endif
>-
> debuglog(1, "Got a PASV reply");
> debuglog(1, "{%s}", (char *)server->line_buffer);
>
>--- 887,892 ----
>***************
>*** 1328,1359 ****
> exit(EX_DATAERR);
> }
>
>- #ifdef IPV6_SUP
>- if (address_family == AF_INET) {
>- server_sockaddr_in = (struct sockaddr_in *)&server_listen_sa;
>- server_sockaddr_in->sin_family = AF_INET;
>- server_sockaddr_in->sin_len = sizeof(struct sockaddr_in);
>- server_sockaddr_in->sin_addr.s_addr = htonl((values[0] << 24) |
>- (values[1] << 16) | (values[2] << 8) | (values[3] << 0));
>- server_sockaddr_in->sin_port = htons((values[4] << 8) |
>- values[5]);
>-
>- #ifdef DEBUG_LOG
>- syslog(LOG_INFO, "server wants us to use %s:%u",
>- inet_ntoa(server_sockaddr_in->sin_addr), (values[4] << 8) |
>- values[5]);
>- #endif
>-
>- debuglog(1, "server wants us to use %s:%u",
>- inet_ntoa(server_sockaddr_in->sin_addr), (values[4] << 8) |
>- values[5]);
>- }
>- else {
>- syslog(LOG_NOTICE, "failed in do_server_reply(), unknown af: [%d]\n",
>- address_family);
>- exit(EX_DATAERR);
>- }
>- #else
> server_listen_sa.sin_family = AF_INET;
> server_listen_sa.sin_addr.s_addr = htonl((values[0] << 24) |
> (values[1] << 16) | (values[2] << 8) | (values[3] << 0));
>--- 917,922 ----
>***************
>*** 1363,1404 ****
> debuglog(1, "server wants us to use %s:%u",
> inet_ntoa(server_listen_sa.sin_addr), (values[4] << 8) |
> values[5]);
>- #endif
>
> new_dataconn(0);
> connection_mode = PASV_MODE;
>-
>- #ifdef IPV6_SUP
>- if (ReverseMode) {
>- if (address_family == AF_INET) {
>- proxy_sockaddr_in = (struct sockaddr_in *)&proxy_sa;
>- iap = &(proxy_sockaddr_in->sin_addr);
>- }
>- }
>- else {
>- if (address_family == AF_INET) {
>- server_sockaddr_in = (struct sockaddr_in *)&server->sa;
>- iap = &(server_sockaddr_in->sin_addr);
>- }
>- }
>-
>- if (address_family == AF_INET) {
>- client_sockaddr_in = (struct sockaddr_in *)&client_listen_sa;
>- #ifdef DEBUG_LOG
>- syslog(LOG_INFO, "we want client to use %s:%u", inet_ntoa(*iap),
>- htons(client_sockaddr_in->sin_port));
>- #endif
>- debuglog(1, "we want client to use %s:%u", inet_ntoa(*iap),
>- htons(client_sockaddr_in->sin_port));
>-
>- snprintf(tbuf, sizeof(tbuf),
>- "227 Entering Passive Mode (%u,%u,%u,%u,%u,%u)\r\n",
>- ((u_char *)iap)[0], ((u_char *)iap)[1],
>- ((u_char *)iap)[2], ((u_char *)iap)[3],
>- ((u_char *)&client_sockaddr_in->sin_port)[0],
>- ((u_char *)&client_sockaddr_in->sin_port)[1]);
>- }
>- #else
> if (ReverseMode)
> iap = &(proxy_sa.sin_addr);
> else
>--- 926,934 ----
>***************
>*** 1413,1676 ****
> ((u_char *)iap)[2], ((u_char *)iap)[3],
> ((u_char *)&client_listen_sa.sin_port)[0],
> ((u_char *)&client_listen_sa.sin_port)[1]);
>- #endif
>-
> debuglog(1, "to client (modified): %s", tbuf);
> sendbuf = tbuf;
>! }
>! #ifdef IPV6_SUP
>! /*
>! * Hack to support IPV6.
>! * Process LPSV response which includes IPV6 packets.
>! * Basically same processing with PASV.
>! */
>! else if (code == 228 && !NatMode) {
>!
>! unsigned int af = 0;
>! unsigned int hal = 0;
>! unsigned int pal = 0;
>! unsigned int h_values[16];
>! unsigned int p_values[2];
>! char *tailptr;
>! int x;
>!
>! #ifdef DEBUG_LOG
>! syslog(LOG_INFO, "LPSV reply\n");
>! syslog(LOG_INFO, "address_family: [%d]\n", address_family);
>! #endif
>!
>! /* support only IPV6 */
>! if (address_family != AF_INET6) {
>! syslog(LOG_NOTICE, "for LPSV only IPv6 is supported");
>! exit(EX_DATAERR);
>! }
>!
>! debuglog(1, "Got a LPSV reply");
>! debuglog(1, "{%s}", (char *)server->line_buffer);
>!
>! tailptr = (char *)strchr((char *)server->line_buffer, '(');
>! if (tailptr == NULL) {
>! tailptr = strrchr((char *)server->line_buffer, ' ');
>! if (tailptr == NULL) {
>! syslog(LOG_NOTICE, "malformed 228 reply");
>! exit(EX_DATAERR);
>! }
>! }
>!
>! tailptr++; /* skip past space or ( */
>!
>! /* read af */
>! i = sscanf(tailptr, "%u", &af);
>! if (i != 1) {
>! syslog(LOG_INFO, "1 malformed LPSV reply (%s)",
>! client->line_buffer);
>! exit(EX_DATAERR);
>! }
>!
>! #ifdef DEBUG_LOG
>! syslog(LOG_INFO, "af: [%d]\n", af);
>! #endif
>!
>! /* move past af */
>! tailptr = (char *)strchr(tailptr, ',');
>! if (tailptr == NULL) {
>! syslog(LOG_NOTICE, "malformed 228 reply, af not found");
>! exit(EX_DATAERR);
>! }
>!
>! tailptr++;
>!
>! /* read address length */
>! i = sscanf(tailptr, "%u", &hal);
>! if (i != 1) {
>! syslog(LOG_INFO, "2 malformed LPSV reply (%s)",
>! client->line_buffer);
>! exit(EX_DATAERR);
>! }
>!
>! #ifdef DEBUG_LOG
>! syslog(LOG_INFO, "hal: [%d]\n", hal);
>! #endif
>! /* we only support a hack for IPV6 for now */
>! if (hal != 16) {
>! syslog(LOG_NOTICE, "malformed 228 reply, address length not supported");
>! exit(EX_DATAERR);
>! }
>!
>! /* move past hal */
>! tailptr = (char *)strchr(tailptr, ',');
>! if (tailptr == NULL) {
>! syslog(LOG_NOTICE, "malformed 228 reply, hal not found");
>! exit(EX_DATAERR);
>! }
>!
>! tailptr++;
>!
>! /* read address */
>! bzero(&h_values, sizeof(h_values));
>! i = sscanf(tailptr, "%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u, %u",
>! &h_values[0], &h_values[1], &h_values[2], &h_values[3],
>! &h_values[4], &h_values[5], &h_values[6], &h_values[7],
>! &h_values[8], &h_values[9], &h_values[10], &h_values[11],
>! &h_values[12], &h_values[13], &h_values[14], &h_values[15]);
>! if (i != 16) {
>! syslog(LOG_INFO, "3 malformed LPSV reply (%s)",
>! client->line_buffer);
>! exit(EX_DATAERR);
>! }
>!
>! /* move past address */
>! #ifdef DEBUG_LOG
>! syslog(LOG_INFO, "h_values: ");
>! #endif
>! for (x = 0; x < i; x++) {
>! #ifdef DEBUG_LOG
>! syslog(LOG_INFO, "h_values[%d]: %d\n", x, h_values[x]);
>! #endif
>! if (tailptr != NULL) {
>! tailptr = (char *)strchr(tailptr, ',');
>! if (tailptr != NULL)
>! tailptr++;
>! }
>! }
>!
>! if (tailptr == NULL) {
>! syslog(LOG_NOTICE, "malformed 228 reply, adderess not found");
>! exit(EX_DATAERR);
>! }
>!
>! /* read port length */
>! i = sscanf(tailptr, "%u", &pal);
>! if (i != 1) {
>! syslog(LOG_INFO, "4 malformed LPSV reply (%s)",
>! client->line_buffer);
>! exit(EX_DATAERR);
>! }
>!
>! #ifdef DEBUG_LOG
>! syslog(LOG_INFO, "pal: [%d]\n", pal);
>! #endif
>! /* we only support a hack for IPV6 for now */
>! if (pal != 2) {
>! syslog(LOG_NOTICE, "malformed 228 reply, port length not supported");
>! exit(EX_DATAERR);
>! }
>!
>! /* move past pal */
>! tailptr = (char *)strchr(tailptr, ',');
>! if (tailptr == NULL) {
>! syslog(LOG_NOTICE, "malformed 228 reply, pal not found");
>! exit(EX_DATAERR);
>! }
>! tailptr++;
>!
>! /* read port */
>! bzero(&p_values, sizeof(p_values));
>! i = sscanf(tailptr, "%u,%u", &p_values[0], &p_values[1]);
>! if (i != 2) {
>! syslog(LOG_INFO, "5 malformed LPSV reply (%s)",
>! client->line_buffer);
>! exit(EX_DATAERR);
>! }
>!
>! #ifdef DEBUG_LOG
>! syslog(LOG_INFO, "p_values: ");
>! #endif
>! for (x = 0; x < i; x++) {
>! #ifdef DEBUG_LOG
>! syslog(LOG_INFO, "p_values[%d]: %d\n", x, p_values[x]);
>! #endif
>!
>! if (tailptr != NULL)
>! tailptr = (char *)strchr(tailptr, ',');
>! }
>!
>! if (address_family == AF_INET6) {
>! bzero(&server_listen_sa, sizeof(server_listen_sa));
>! server_sockaddr_in6 = (struct sockaddr_in6 *)&server_listen_sa;
>! server_sockaddr_in6->sin6_family = AF_INET6;
>! server_sockaddr_in6->sin6_len = sizeof(struct sockaddr_in6);
>! server_sockaddr_in6->sin6_port = htons((p_values[0] << 8) | p_values[1]);
>! server_sockaddr_in6->sin6_addr.s6_addr[0] = h_values[0];
>! server_sockaddr_in6->sin6_addr.s6_addr[1] = h_values[1];
>! server_sockaddr_in6->sin6_addr.s6_addr[2] = h_values[2];
>! server_sockaddr_in6->sin6_addr.s6_addr[3] = h_values[3];
>! server_sockaddr_in6->sin6_addr.s6_addr[4] = h_values[4];
>! server_sockaddr_in6->sin6_addr.s6_addr[5] = h_values[5];
>! server_sockaddr_in6->sin6_addr.s6_addr[6] = h_values[6];
>! server_sockaddr_in6->sin6_addr.s6_addr[7] = h_values[7];
>! server_sockaddr_in6->sin6_addr.s6_addr[8] = h_values[8];
>! server_sockaddr_in6->sin6_addr.s6_addr[9] = h_values[9];
>! server_sockaddr_in6->sin6_addr.s6_addr[10] = h_values[10];
>! server_sockaddr_in6->sin6_addr.s6_addr[11] = h_values[11];
>! server_sockaddr_in6->sin6_addr.s6_addr[12] = h_values[12];
>! server_sockaddr_in6->sin6_addr.s6_addr[13] = h_values[13];
>! server_sockaddr_in6->sin6_addr.s6_addr[14] = h_values[14];
>! server_sockaddr_in6->sin6_addr.s6_addr[15] = h_values[15];
>!
>! getnameinfo((struct sockaddr *)&server_listen_sa, server_listen_sa.ss_len,
>! host, sizeof(host), port, sizeof(port),
>! NI_NUMERICHOST | NI_NUMERICSERV);
>!
>! #ifdef DEBUG_LOG
>! syslog(LOG_INFO, "server wants us to use %s:%s\n", host, port);
>! #endif
>! }
>!
>! new_dataconn(0);
>!
>! connection_mode = LPSV_MODE;
>!
>! if (ReverseMode) {
>! if (address_family == AF_INET6) {
>! use_sockaddr_in6 = (struct sockaddr_in6 *)&proxy_sa;
>! }
>! }
>! else {
>! if (address_family == AF_INET6) {
>! use_sockaddr_in6 = (struct sockaddr_in6 *)&server->sa;
>! }
>! }
>!
>! if (address_family == AF_INET6) {
>! client_sockaddr_in6 = (struct sockaddr_in6 *)&client_listen_sa;
>! #ifdef DEBUG_LOG
>! getnameinfo((struct sockaddr *)&use_sockaddr_in6, use_sockaddr_in6->sin6_len,
>! host, sizeof(host), NULL, 0,
>! NI_NUMERICHOST | NI_NUMERICSERV);
>! syslog(LOG_INFO, "we want client to use %s:%u", host,
>! htons(client_sockaddr_in6->sin6_port));
>! #endif
>! snprintf(tbuf, sizeof(tbuf),
>! "228 Entering Long Passive Mode (%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,% u,%u,%u,%u,%u)\r\n",
>! 6, 16, use_sockaddr_in6->sin6_addr.s6_addr[0],
>! use_sockaddr_in6->sin6_addr.s6_addr[1],
>! use_sockaddr_in6->sin6_addr.s6_addr[2],
>! use_sockaddr_in6->sin6_addr.s6_addr[3],
>! use_sockaddr_in6->sin6_addr.s6_addr[4],
>! use_sockaddr_in6->sin6_addr.s6_addr[5],
>! use_sockaddr_in6->sin6_addr.s6_addr[6],
>! use_sockaddr_in6->sin6_addr.s6_addr[7],
>! use_sockaddr_in6->sin6_addr.s6_addr[8],
>! use_sockaddr_in6->sin6_addr.s6_addr[9],
>! use_sockaddr_in6->sin6_addr.s6_addr[10],
>! use_sockaddr_in6->sin6_addr.s6_addr[11],
>! use_sockaddr_in6->sin6_addr.s6_addr[12],
>! use_sockaddr_in6->sin6_addr.s6_addr[13],
>! use_sockaddr_in6->sin6_addr.s6_addr[14],
>! use_sockaddr_in6->sin6_addr.s6_addr[15],
>! 2, ((u_char *)&client_sockaddr_in6->sin6_port)[0],
>! ((u_char *)&client_sockaddr_in6->sin6_port)[1]);
>! }
>!
>! #ifdef DEBUG_LOG
>! syslog(LOG_INFO, "to client (modified): %s", tbuf);
>! #endif
>! debuglog(1, "to client (modified): %s", tbuf);
>! sendbuf = tbuf;
>! }
>! #endif
>! else {
> sendit:
> sendbuf = (char *)server->line_buffer;
> }
>--- 943,951 ----
> ((u_char *)iap)[2], ((u_char *)iap)[3],
> ((u_char *)&client_listen_sa.sin_port)[0],
> ((u_char *)&client_listen_sa.sin_port)[1]);
> debuglog(1, "to client (modified): %s", tbuf);
> sendbuf = tbuf;
>! } else {
> sendit:
> sendbuf = (char *)server->line_buffer;
> }
>***************
>*** 1688,1693 ****
>--- 963,969 ----
> else if (rv != -1)
> j += rv;
> } while (j >= 0 && j < i);
>+
> }
>
> int
>***************
>*** 1703,1728 ****
> #ifdef LIBWRAP
> int use_tcpwrapper = 0;
> #endif /* LIBWRAP */
>- #ifdef IPV6_SUP
>- struct addrinfo hints;
>- struct addrinfo *res;
>- #ifdef DEBUG_LOG
>- char addr_str[NI_MAXHOST];
>- char port_str[NI_MAXHOST];
>- #endif
>- #endif
>-
>- #ifdef IPV6_SUP
>- openlog(__progname, LOG_NDELAY|LOG_PID, LOG_DAEMON);
>- #ifdef DEBUG_LOG
>- syslog(LOG_INFO, "Starting ftp-proxy... argc: [%d]\n", argc);
>-
>- for (i=0; i< argc; i++)
>- {
>- syslog(LOG_INFO, " argv[%d]: [%s]\n", i, argv[i]);
>- }
>- #endif
>- #endif
>
> while ((ch = getopt(argc, argv, "a:g:m:M:R:S:t:u:AnVwr")) != -1) {
> char *p;
>--- 979,984 ----
>***************
>*** 1730,1765 ****
> case 'a':
> if (!*optarg)
> usage();
>- #ifdef IPV6_SUP
>- Bind_Addr_Flag = 1;
>-
>- bzero(&hints, sizeof(hints));
>- hints.ai_family = PF_UNSPEC;
>- hints.ai_socktype = SOCK_STREAM;
>- hints.ai_flags = AI_NUMERICHOST;
>- if (getaddrinfo(optarg, NULL, &hints, &res) != 0) {
>- syslog(LOG_NOTICE,
>- "%s: invalid address", optarg);
>- usage();
>- }
>-
>- memcpy(&Bind_Addr, res->ai_addr, res->ai_addrlen);
>-
>- #ifdef DEBUG_LOG
>- getnameinfo((struct sockaddr *)&Bind_Addr,
>- Bind_Addr.ss_len, addr_str, sizeof(addr_str),
>- NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV);
>-
>- syslog(LOG_INFO, "Bind Address: [%s]\n", addr_str);
>- #endif
>- freeaddrinfo(res);
>- #else
> if ((Bind_Addr = inet_addr(optarg)) == INADDR_NONE) {
> syslog(LOG_NOTICE,
> "%s: invalid address", optarg);
> usage();
> }
>- #endif
> break;
> case 'A':
> AnonFtpOnly = 1; /* restrict to anon usernames only */
>--- 986,996 ----
>***************
>*** 1793,1874 ****
> Use_Rdns = 1; /* look up hostnames */
> break;
> case 'R': {
>- #ifdef IPV6_SUP
>- char *s, *t, *b, *a, *p;
>-
>- if (!*optarg)
>- usage();
>-
>- if ((s = strdup(optarg)) == NULL) {
>- syslog (LOG_NOTICE,
>- "Insufficient memory (malloc failed)");
>- exit(EX_UNAVAILABLE);
>- }
>-
>- a = strchr(s, '[');
>- if (a != NULL) {
>- /* IPV6 address */
>- a++;
>-
>- if (a == NULL) {
>- syslog(LOG_NOTICE,
>- "%s: invalid address or port", optarg);
>- usage();
>- }
>-
>- p = strchr(a, ']');
>- if (p == NULL) {
>- syslog(LOG_NOTICE,
>- "%s: invalid address or port", optarg);
>- usage();
>- }
>-
>- b = p;
>-
>- p = strchr(p, ':');
>- if (p == NULL) {
>- p = "21";
>- }
>- else {
>- p++;
>- }
>-
>- *b = 0;
>- }
>- else {
>- /* IPV6 address */
>- a = s;
>- t = strchr(s, ':');
>- if (t == NULL)
>- p = "21";
>- else {
>- p = t+1;
>- *t = 0;
>- }
>- }
>-
>- bzero(&hints, sizeof(hints));
>- hints.ai_family = PF_UNSPEC;
>- hints.ai_socktype = SOCK_STREAM;
>- hints.ai_flags = AI_NUMERICHOST;
>- if (getaddrinfo(a, p, &hints, &res) != 0) {
>- syslog(LOG_NOTICE,
>- "%s: invalid address or port", optarg);
>- usage();
>- }
>-
>- memcpy(&real_server_sa, res->ai_addr, res->ai_addrlen);
>-
>- #ifdef DEBUG_LOG
>- getnameinfo((struct sockaddr *)&real_server_sa,
>- real_server_sa.ss_len, addr_str, sizeof(addr_str),
>- port_str, sizeof(port_str), NI_NUMERICHOST | NI_NUMERICSERV);
>-
>- syslog(LOG_INFO, "Reverse Address: [%s]/[%s]\n", addr_str, port_str);
>- #endif
>- freeaddrinfo(res);
>- free(s);
>- #else
> char *s, *t;
>
> if (!*optarg)
>--- 1024,1029 ----
>***************
>*** 1896,1929 ****
> if (real_server_sa.sin_addr.s_addr == INADDR_NONE)
> usage();
> free(s);
>- #endif
> ReverseMode = 1;
> break;
> }
> case 'S':
>- #ifdef IPV6_SUP
>- bzero(&hints, sizeof(hints));
>- hints.ai_family = PF_UNSPEC;
>- hints.ai_socktype = SOCK_STREAM;
>- hints.ai_flags = AI_NUMERICHOST;
>- if (getaddrinfo(optarg, NULL, &hints, &res) != 0) {
>- usage();
>- }
>-
>- memcpy(&src_addr, res->ai_addr, res->ai_addrlen);
>-
>- #ifdef DEBUG_LOG
>- getnameinfo((struct sockaddr *)&src_addr,
>- src_addr.ss_len, addr_str, sizeof(addr_str),
>- NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV);
>-
>- syslog(LOG_INFO, "Source Address: [%s]\n", addr_str);
>- #endif
>- freeaddrinfo(res);
>- #else
> if (!inet_aton(optarg, &src_addr))
> usage();
>- #endif
> break;
> case 't':
> timeout_seconds = strtol(optarg, &p, 10);
>--- 1051,1062 ----
>***************
>*** 1952,1960 ****
> if (max_port < min_port)
> usage();
>
>- #ifndef IPV6_SUP
> openlog(__progname, LOG_NDELAY|LOG_PID, LOG_DAEMON);
>- #endif
>
> setlinebuf(stdout);
> setlinebuf(stderr);
>--- 1085,1091 ----
>***************
>*** 1987,2022 ****
> else
> flags = NI_NUMERICHOST | NI_NUMERICSERV;
>
>- #ifdef IPV6_SUP
>- i = getnameinfo((struct sockaddr *)&client_iob.sa,
>- client_iob.sa.ss_len, ClientName, sizeof(ClientName),
>- ClientPortName, sizeof(ClientPortName),
>- flags);
>- #else
> i = getnameinfo((struct sockaddr *)&client_iob.sa,
> sizeof(client_iob.sa), ClientName, sizeof(ClientName), NULL, 0,
> flags);
>- #endif
>
> if (i != 0 && i != EAI_NONAME && i != EAI_AGAIN) {
> debuglog(2, "name resolution failure (client)");
>- syslog(LOG_INFO, "1 name resolution failure: [%d]\n", i);
> exit(EX_OSERR);
> }
>
>- #ifdef IPV6_SUP
>- i = getnameinfo((struct sockaddr *)&real_server_sa,
>- real_server_sa.ss_len, RealServerName, sizeof(RealServerName),
>- RealServerPortName, sizeof(RealServerPortName), flags);
>- #else
> i = getnameinfo((struct sockaddr *)&real_server_sa,
> sizeof(real_server_sa), RealServerName, sizeof(RealServerName),
> NULL, 0, flags);
>- #endif
>
> if (i != 0 && i != EAI_NONAME && i != EAI_AGAIN) {
> debuglog(2, "name resolution failure (server)");
>- syslog(LOG_INFO, "2 name resolution failure: [%d]\n", i);
> exit(EX_OSERR);
> }
>
>--- 1118,1138 ----
>***************
>*** 2027,2061 ****
>
> client_iob.fd = 0;
>
>- #ifdef IPV6_SUP
>- syslog(LOG_INFO, "accepted connection from %s:%s to %s:%s", ClientName,
>- ClientPortName, RealServerName, RealServerPortName);
>- #else
> syslog(LOG_INFO, "accepted connection from %s:%u to %s:%u", ClientName,
> ntohs(client_iob.sa.sin_port), RealServerName,
> ntohs(real_server_sa.sin_port));
>- #endif
>
>- #ifdef IPV6_SUP
>- server_iob.fd = get_backchannel_socket(real_server_sa.ss_family,
>- SOCK_STREAM, min_port, max_port,
>- -1, 1, &server_iob.sa);
>- #else
> server_iob.fd = get_backchannel_socket(SOCK_STREAM, min_port, max_port,
> -1, 1, &server_iob.sa);
>- #endif
>
>- #ifdef IPV6_SUP
>- if (connect(server_iob.fd, (struct sockaddr *)&real_server_sa,
>- real_server_sa.ss_len) != 0) {
>- syslog(LOG_INFO, "cannot connect to %s:%s (%m)", RealServerName,
>- RealServerPortName);
>- #else
> if (connect(server_iob.fd, (struct sockaddr *)&real_server_sa,
> sizeof(real_server_sa)) != 0) {
> syslog(LOG_INFO, "cannot connect to %s:%u (%m)", RealServerName,
> ntohs(real_server_sa.sin_port));
>- #endif
> exit(EX_NOHOST);
> }
>
>--- 1143,1159 ----
>***************
>*** 2067,2098 ****
> salen = sizeof(server_iob.sa);
> getsockname(server_iob.fd, (struct sockaddr *)&server_iob.sa, &salen);
>
>- #ifdef IPV6_SUP
>- i = getnameinfo((struct sockaddr *)&server_iob.sa,
>- server_iob.sa.ss_len, OurName, sizeof(OurName),
>- OurPortName, sizeof(OurPortName), flags);
>- #else
> i = getnameinfo((struct sockaddr *)&server_iob.sa,
> sizeof(server_iob.sa), OurName, sizeof(OurName), NULL, 0, flags);
>- #endif
>
> if (i != 0 && i != EAI_NONAME && i != EAI_AGAIN) {
> debuglog(2, "name resolution failure (local)");
> exit(EX_OSERR);
> }
>
>- #ifdef IPV6_SUP
>- #ifdef DEBUG_LOG
>- syslog(LOG_INFO, "local socket is %s:%s", OurName,
>- OurPortName);
>- #endif
>-
>- debuglog(1, "local socket is %s:%s", OurName,
>- OurPortName);
>- #else
> debuglog(1, "local socket is %s:%u", OurName,
> ntohs(server_iob.sa.sin_port));
>- #endif
>
> /* ignore SIGPIPE */
> bzero(&new_sa, sizeof(new_sa));
>--- 1165,1180 ----
>***************
>*** 2142,2153 ****
> int maxfd = 0;
> fd_set *fdsp;
>
>- #ifdef IPV6_SUP
>- #ifdef DEBUG_LOG
>- syslog(LOG_INFO, "main loop\n");
>- #endif
>- #endif
>-
> if (client_iob.fd > maxfd)
> maxfd = client_iob.fd;
> if (client_listen_socket > maxfd)
>--- 1224,1229 ----
>***************
>*** 2161,2173 ****
> if (server_data_socket > maxfd)
> maxfd = server_data_socket;
>
>- #ifdef IPV6_SUP
>- #ifdef DEBUG_LOG
>- syslog(LOG_INFO, "client is %s; server is %s",
>- client_iob.alive ? "alive" : "dead",
>- server_iob.alive ? "alive" : "dead");
>- #endif
>- #endif
> debuglog(3, "client is %s; server is %s",
> client_iob.alive ? "alive" : "dead",
> server_iob.alive ? "alive" : "dead");
>--- 1237,1242 ----
>***************
>*** 2234,2258 ****
> FD_ISSET(client_data_socket, fdsp)) {
> int rval;
>
>- #ifdef IPV6_SUP
>- #ifdef DEBUG_LOG
>- syslog(LOG_INFO, "transfer: client to server");
>- #endif
>- #endif
> debuglog(3, "transfer: client to server");
>- #ifdef IPV6_SUP
>- rval = xfer_data("client to server",
>- client_data_socket,
>- server_data_socket,
>- &client_iob.sa,
>- &real_server_sa);
>- #else
> rval = xfer_data("client to server",
> client_data_socket,
> server_data_socket,
> client_iob.sa.sin_addr,
> real_server_sa.sin_addr);
>- #endif
> if (rval <= 0) {
> close_client_data();
> close_server_data();
>--- 1303,1314 ----
>***************
>*** 2264,2288 ****
> FD_ISSET(server_data_socket, fdsp)) {
> int rval;
>
>- #ifdef IPV6_SUP
>- #ifdef DEBUG_LOG
>- syslog(LOG_INFO, "transfer: server to client");
>- #endif
>- #endif
> debuglog(3, "transfer: server to client");
>- #ifdef IPV6_SUP
>- rval = xfer_data("server to client",
>- server_data_socket,
>- client_data_socket,
>- &real_server_sa,
>- &client_iob.sa);
>- #else
> rval = xfer_data("server to client",
> server_data_socket,
> client_data_socket,
> real_server_sa.sin_addr,
> client_iob.sa.sin_addr);
>- #endif
> if (rval <= 0) {
> close_client_data();
> close_server_data();
>--- 1320,1331 ----
>Only in ftp-proxy-new: ftp-proxy.cat8
>diff -C 3 -r ftp-proxy-new/util.c ftp-proxy/util.c
>*** ftp-proxy-new/util.c Thu Mar 17 22:37:28 2005
>--- ftp-proxy/util.c Wed Jul 7 03:49:11 2004
>***************
>*** 58,76 ****
>
> extern int ReverseMode;
>
>- #ifdef IPV6_SUP
>- /* address family type (AF_INET|AF_INET6) */
>- extern int address_family;
>- #endif
>-
> int Debug_Level;
> int Use_Rdns;
>- #ifdef IPV6_SUP
>- int Bind_Addr_Flag = 0;
>- struct sockaddr_storage Bind_Addr;
>- #else
> in_addr_t Bind_Addr = INADDR_NONE;
>- #endif
>
> void debuglog(int debug_level, const char *fmt, ...);
>
>--- 58,66 ----
>***************
>*** 86,112 ****
> }
>
> int
>- #ifdef IPV6_SUP
>- get_proxy_env(int connected_fd, struct sockaddr_storage *real_server_sa_ptr,
>- struct sockaddr_storage *client_sa_ptr, struct sockaddr_storage *proxy_sa_ptr)
>- #else
> get_proxy_env(int connected_fd, struct sockaddr_in *real_server_sa_ptr,
> struct sockaddr_in *client_sa_ptr, struct sockaddr_in *proxy_sa_ptr)
>- #endif
> {
> struct pfioc_natlook natlook;
> socklen_t slen;
> int fd;
>- #ifdef IPV6_SUP
>- struct sockaddr_in *ipv4;
>- struct sockaddr_in6 *ipv6;
>- char client_host[NI_MAXHOST];
>- char client_port[NI_MAXHOST];
>- char proxy_host[NI_MAXHOST];
>- char proxy_port[NI_MAXHOST];
>- int ret;
>- char af;
>- #endif
>
> slen = sizeof(*proxy_sa_ptr);
> if (getsockname(connected_fd, (struct sockaddr *)proxy_sa_ptr,
>--- 76,87 ----
>***************
>*** 121,216 ****
> return(-1);
> }
>
>- #ifdef IPV6_SUP
>- ret = getnameinfo((struct sockaddr *)proxy_sa_ptr,
>- ((struct sockaddr *)proxy_sa_ptr)->sa_len,
>- proxy_host, sizeof(proxy_host),
>- proxy_port, sizeof(proxy_port), NI_NUMERICHOST | NI_NUMERICSERV);
>-
>- if (ret != 0)
>- {
>- syslog(LOG_INFO, "getnameinfo() failed: [%d]\n", ret);
>- return(-1);
>- }
>-
>- #ifdef DEBUG_LOG
>- syslog(LOG_INFO, "proxy_host: [%s], proxy_port: [%s]\n",
>- proxy_host, proxy_port);
>- #endif
>-
>- /* updated global address family variable */
>- af = ((struct sockaddr *)proxy_sa_ptr)->sa_family;
>- switch (af)
>- {
>- case AF_INET:
>- /* set adderss family to AF_INET */
>- address_family = AF_INET;
>- break;
>-
>- case AF_INET6:
>- /* set adderss family to AF_INET */
>- address_family = AF_INET6;
>- break;
>-
>- default:
>- syslog(LOG_ERR, "unsupported address family: [%d]\n", af);
>- return(-1);
>- break;
>- }
>-
>- ret = getnameinfo((struct sockaddr *)client_sa_ptr,
>- ((struct sockaddr *)client_sa_ptr)->sa_len,
>- client_host, sizeof(client_host),
>- client_port, sizeof(client_port), NI_NUMERICHOST | NI_NUMERICSERV);
>-
>- if (ret != 0)
>- {
>- syslog(LOG_INFO, "getnameinfo() failed: [%d]\n", ret);
>- return(-1);
>- }
>-
>- #ifdef DEBUG_LOG
>- syslog(LOG_INFO, "client_host: [%s], client_port: [%s]\n",
>- client_host, client_port);
>- #endif
>- #endif
>-
> if (ReverseMode)
> return(0);
>
>- #ifdef IPV6_SUP
>- /*
>- * Build up the pf natlook structure.
>- * Support only IPV4 and IPV6.
>- */
>- memset((void *)&natlook, 0, sizeof(natlook));
>- switch (af)
>- {
>- case AF_INET:
>- natlook.af = AF_INET;
>- ipv4 = (struct sockaddr_in *)client_sa_ptr;
>- natlook.saddr.addr32[0] = ipv4->sin_addr.s_addr;
>- natlook.sport = ipv4->sin_port;
>- ipv4 = (struct sockaddr_in *)proxy_sa_ptr;
>- natlook.daddr.addr32[0] = ipv4->sin_addr.s_addr;
>- natlook.dport = ipv4->sin_port;
>- natlook.proto = IPPROTO_TCP;
>- natlook.direction = PF_OUT;
>- break;
>-
>- case AF_INET6:
>- natlook.af = AF_INET6;
>- ipv6 = (struct sockaddr_in6 *)client_sa_ptr;
>- natlook.saddr.v6 = ipv6->sin6_addr;
>- natlook.sport = ipv6->sin6_port;
>- ipv6 = (struct sockaddr_in6 *)proxy_sa_ptr;
>- natlook.daddr.v6 = ipv6->sin6_addr;
>- natlook.dport = ipv6->sin6_port;
>- natlook.proto = IPPROTO_TCP;
>- natlook.direction = PF_OUT;
>- break;
>- }
>- #else
> /*
> * Build up the pf natlook structure.
> * Just for IPv4 right now
>--- 96,104 ----
>***************
>*** 223,229 ****
> natlook.sport = client_sa_ptr->sin_port;
> natlook.dport = proxy_sa_ptr->sin_port;
> natlook.direction = PF_OUT;
>- #endif
>
> /*
> * Open the pf device and lookup the mapping pair to find
>--- 111,116 ----
>***************
>*** 236,251 ****
> }
>
> if (ioctl(fd, DIOCNATLOOK, &natlook) == -1) {
>- #ifdef IPV6_SUP
>- syslog(LOG_INFO,
>- "pf nat lookup failed %s:%s (%m)",
>- client_host, client_port);
>- #else
> syslog(LOG_INFO,
> "pf nat lookup failed %s:%hu (%m)",
> inet_ntoa(client_sa_ptr->sin_addr),
> ntohs(client_sa_ptr->sin_port));
>- #endif
> close(fd);
> return(-1);
> }
>--- 123,132 ----
>***************
>*** 255,292 ****
> * Now jam the original address and port back into the into
> * destination sockaddr_in for the proxy to deal with.
> */
>- #ifdef IPV6_SUP
>- memset((void *)real_server_sa_ptr, 0, sizeof(struct sockaddr_storage));
>- switch (af)
>- {
>- case AF_INET:
>- ipv4 = (struct sockaddr_in *)real_server_sa_ptr;
>- ipv4->sin_port = natlook.rdport;
>- ipv4->sin_addr.s_addr = natlook.rdaddr.addr32[0];
>- ipv4->sin_len = sizeof(struct sockaddr_in);
>- ipv4->sin_family = AF_INET;
>- break;
>-
>- case AF_INET6:
>- ipv6 = (struct sockaddr_in6 *)real_server_sa_ptr;
>- ipv6->sin6_port = natlook.rdport;
>- ipv6->sin6_addr = natlook.rdaddr.v6;
>- ipv6->sin6_len = sizeof(struct sockaddr_in6);
>- ipv6->sin6_family = AF_INET6;
>- break;
>-
>- default:
>- syslog(LOG_ERR, "unsupported address family returned by pf: [%d]\n", af);
>- return(-1);
>- }
>- #else
> memset((void *)real_server_sa_ptr, 0, sizeof(struct sockaddr_in));
> real_server_sa_ptr->sin_port = natlook.rdport;
> real_server_sa_ptr->sin_addr.s_addr = natlook.rdaddr.addr32[0];
> real_server_sa_ptr->sin_len = sizeof(struct sockaddr_in);
> real_server_sa_ptr->sin_family = AF_INET;
>- #endif
>-
> return(0);
> }
>
>--- 136,146 ----
>***************
>*** 297,309 ****
> * A unit of data is as much as we get with a single read(2) call.
> */
> int
>- #ifdef IPV6_SUP
>- xfer_data(const char *what_read,int from_fd, int to_fd, struct sockaddr_storage *from,
>- struct sockaddr_storage *to)
>- #else
> xfer_data(const char *what_read,int from_fd, int to_fd, struct in_addr from,
> struct in_addr to)
>- #endif
> {
> int rlen, offset, xerrno, mark, flags = 0;
> char tbuf[4096];
>--- 151,158 ----
>***************
>*** 367,450 ****
> }
> }
>
>-
>- #ifdef IPV6_SUP
>- /*
>- * create sockaddr_storage structure for the INADDR_ANY for both
>- * IPV4 and IPV6 address family.
>- */
>- int
>- create_sockaddr_any(int af, int type, int port, struct sockaddr_storage *sa)
>- {
>- struct addrinfo hints;
>- struct addrinfo *res;
>- char port_str[NI_MAXHOST];
>- int ret;
>-
>- #ifdef DEBUG_LOG
>- char addr_buf[NI_MAXHOST];
>- char port_buf[NI_MAXHOST];
>- #endif
>-
>- bzero(&hints, sizeof(hints));
>- hints.ai_family = af;
>- hints.ai_socktype = type;
>- hints.ai_flags = AI_NUMERICHOST;
>-
>- /* convert port into string */
>- snprintf(port_str, NI_MAXHOST, "%d", port);
>-
>- /* create based on address family type */
>- if (af == AF_INET)
>- ret = getaddrinfo("0.0.0.0", port_str, &hints, &res);
>- else if (af == AF_INET6)
>- ret = getaddrinfo("::", port_str, &hints, &res);
>- else {
>- syslog(LOG_INFO, "unknown af: [%d]\n", af);
>- return(-1);
>- }
>-
>- if (ret != 0) {
>- syslog(LOG_INFO, "getaddrinfo() failed: [%d]\n", ret);
>- }
>-
>- /* copy resulting address to our ouput argument */
>- memcpy(sa, res->ai_addr, res->ai_addrlen);
>-
>- #ifdef DEBUG_LOG
>- getnameinfo(res->ai_addr, res->ai_addrlen, addr_buf,
>- sizeof(addr_buf), port_buf, sizeof(port_buf),
>- NI_NUMERICHOST | NI_NUMERICSERV);
>-
>- syslog(LOG_INFO, "addr_buf: [%s], port_buf: [%s]\n", addr_buf, port_buf);
>- #endif
>- freeaddrinfo(res);
>-
>- return(0);
>- }
>- #endif
>-
>-
> /*
> * get_backchannel_socket gets us a socket bound somewhere in a
> * particular range of ports
> */
> int
>- #ifdef IPV6_SUP
>- get_backchannel_socket(int af, int type, int min_port, int max_port, int start_port,
>- int direction, struct sockaddr_storage *sap)
>- #else
> get_backchannel_socket(int type, int min_port, int max_port, int start_port,
> int direction, struct sockaddr_in *sap)
>- #endif
> {
> int count;
>- #ifdef IPV6_SUP
>- #ifdef DEBUG_LOG
>- char host[NI_MAXHOST];
>- char port[NI_MAXHOST];
>- #endif
>- #endif
>
> /*
> * Make sure that direction is 'defined' and that min_port is not
>--- 216,230 ----
>***************
>*** 477,515 ****
> }
>
> while (count-- > 0) {
>- #ifdef IPV6_SUP
>- struct sockaddr_storage sa;
>- struct sockaddr_in *sockaddr4;
>- struct sockaddr_in6 *sockaddr6;
>- #else
> struct sockaddr_in sa;
>- #endif
> int one, fd;
>
>- #ifdef IPV6_SUP
>- fd = socket(af, type, 0);
>-
>- bzero(&sa, sizeof(sa));
>- if (Bind_Addr_Flag == 0) {
>- if (sap == NULL) {
>- if (create_sockaddr_any(af, type, start_port, &sa) != 0)
>- return(-1);
>- }
>- else {
>- if ((sap->ss_family == AF_INET) ||
>- (sap->ss_family == AF_INET6)) {
>- memcpy(&sa, sap, sap->ss_len);
>- }
>- else {
>- if (create_sockaddr_any(af, type, start_port, &sa) != 0)
>- return(-1);
>- }
>- }
>- }
>- else {
>- memcpy(&sa, &Bind_Addr, sizeof(sa));
>- }
>- #else
> fd = socket(AF_INET, type, 0);
>
> bzero(&sa, sizeof sa);
>--- 257,265 ----
>***************
>*** 521,527 ****
> sa.sin_addr.s_addr = sap->sin_addr.s_addr;
> else
> sa.sin_addr.s_addr = Bind_Addr;
>- #endif
>
> /*
> * Indicate that we want to reuse a port if it happens that the
>--- 271,276 ----
>***************
>*** 532,573 ****
> sizeof(one)) == -1)
> return(-1);
>
>- #ifdef IPV6_SUP
>- /* update port */
>- if (af == AF_INET) {
>- sockaddr4 = (struct sockaddr_in *)&sa;
>- sockaddr4->sin_port = htons(start_port);
>- }
>- else {
>- sockaddr6 = (struct sockaddr_in6 *)&sa;
>- sockaddr6->sin6_port = htons(start_port);
>- }
>- #else
> sa.sin_port = htons(start_port);
>- #endif
>
>- #ifdef IPV6_SUP
>- #ifdef DEBUG_LOG
>- getnameinfo((struct sockaddr *)&sa,
>- sa.ss_len,
>- host, sizeof(host),
>- port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV);
>-
>- syslog(LOG_INFO, "binding to host: [%s], port: [%s]\n",
>- host, port);
>- #endif
>- if (bind(fd, (struct sockaddr *)&sa, sa.ss_len) == 0) {
>- #else
> if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) == 0) {
>- #endif
> if (sap != NULL)
> *sap = sa;
> return(fd);
> }
>-
>- #ifdef IPV6_SUP
>- syslog(LOG_INFO, "bind() failed\n");
>- #endif
>
> if (errno != EADDRINUSE)
> return(-1);
>--- 281,293 ----
>diff -C 3 -r ftp-proxy-new/util.h ftp-proxy/util.h
>*** ftp-proxy-new/util.h Fri Mar 11 23:30:48 2005
>--- ftp-proxy/util.h Wed Jul 7 03:49:11 2004
>***************
>*** 45,55 ****
> int fd;
> int line_buffer_size, io_buffer_size, io_buffer_len, next_byte;
> unsigned char *io_buffer, *line_buffer;
>- #ifdef IPV6_SUP
>- struct sockaddr_storage sa, real_sa;
>- #else
> struct sockaddr_in sa, real_sa;
>- #endif
> char *who;
> char alive, got_eof, data_available;
> int send_oob_flags;
>--- 45,51 ----
>***************
>*** 58,86 ****
> extern int telnet_getline(struct csiob *iobp,
> struct csiob *telnet_passthrough);
>
>- #ifdef IPV6_SUP
>- extern int get_proxy_env(int fd, struct sockaddr_storage *server_sa_ptr,
>- struct sockaddr_storage *client_sa_ptr, struct sockaddr_storage *proxy_sa_ptr);
>- #else
> extern int get_proxy_env(int fd, struct sockaddr_in *server_sa_ptr,
> struct sockaddr_in *client_sa_ptr, struct sockaddr_in *proxy_sa_ptr);
>- #endif
>
>- #ifdef IPV6_SUP
>- extern int get_backchannel_socket(int af, int type, int min_port, int max_port,
>- int start_port, int direction, struct sockaddr_storage *sap);
>- #else
> extern int get_backchannel_socket(int type, int min_port, int max_port,
> int start_port, int direction, struct sockaddr_in *sap);
>- #endif
>
>- #ifdef IPV6_SUP
>- extern int xfer_data(const char *what_read, int from_fd, int to_fd,
>- struct sockaddr_storage *from, struct sockaddr_storage *to);
>- #else
> extern int xfer_data(const char *what_read, int from_fd, int to_fd,
> struct in_addr from, struct in_addr to);
>- #endif
>
> extern char *ProgName;
>
>--- 54,67 ----
>
>



diff -C 3 -r ftp-proxy/Makefile ftp-proxy-new/Makefile
*** ftp-proxy/Makefile Fri Nov 21 07:23:09 2003
--- ftp-proxy-new/Makefile Fri Mar 18 16:34:47 2005
***************
*** 14,17 ****
--- 14,20 ----
DPADD+= ${LIBWRAP}
.endif

+ # For ipv6 support
+ CFLAGS+= -DIPV6_SUP
+
.include <bsd.prog.mk>
diff -C 3 -r ftp-proxy/ftp-proxy.c ftp-proxy-new/ftp-proxy.c
*** ftp-proxy/ftp-proxy.c Sun Jul 11 09:54:36 2004
--- ftp-proxy-new/ftp-proxy.c Fri Mar 18 16:34:13 2005
***************
*** 55,60 ****
--- 55,67 ----
* the real destination address - the tcp wrapper stuff is done after
* the real destination address is retrieved from pf
*
+ * Added support for IPv6.
+ * Changed all address structures to accomodate IPv4 and IPv6 addresses.
+ * Modified processing of EPRT. Added support for processing the response
+ * of LPRT to support IPv6 ftp session.
+ *
+ * - Ronnel Maglasang(rmaglasang@infoweapons.com)
+ * www.infoweapons.com
*/

/*
***************
*** 125,135 ****
--- 132,155 ----

double xfer_start_time;

+ #ifdef IPV6_SUP
+ struct sockaddr_storage real_server_sa;
+ struct sockaddr_storage client_listen_sa;
+ struct sockaddr_storage server_listen_sa;
+ struct sockaddr_storage proxy_sa;
+ int address_family;
+ #else
struct sockaddr_in real_server_sa;
struct sockaddr_in client_listen_sa;
struct sockaddr_in server_listen_sa;
struct sockaddr_in proxy_sa;
+ #endif
+
+ #ifdef IPV6_SUP
+ struct sockaddr_storage src_addr;
+ #else
struct in_addr src_addr;
+ #endif

int client_listen_socket = -1; /* Only used in PASV mode */
int client_data_socket = -1; /* Connected socket to real client */
***************
*** 146,163 ****
--- 166,198 ----
char RealServerName[NI_MAXHOST];
char OurName[NI_MAXHOST];

+ #ifdef IPV6_SUP
+ char ClientPortName[NI_MAXHOST];
+ char RealServerPortName[NI_MAXHOST];
+ char OurPortName[NI_MAXHOST];
+ #endif
+
char *User = "proxy";
char *Group;

extern int Debug_Level;
extern int Use_Rdns;
+ #ifdef IPV6_SUP
+ extern int Bind_Addr_Flag;
+ extern struct sockaddr_storage Bind_Addr;
+ #else
extern in_addr_t Bind_Addr;
+ #endif
extern char *__progname;

typedef enum {
UNKNOWN_MODE,
PORT_MODE,
PASV_MODE,
+ #ifdef IPV6_SUP
+ LPRT_MODE,
+ LPSV_MODE,
+ #endif
EPRT_MODE,
EPSV_MODE
} connection_mode_t;
***************
*** 246,261 ****
--- 281,336 ----
* if we are set to do reverse DNS, otherwise no.
*/
static int
+ #ifdef IPV6_SUP
+ check_host(struct sockaddr_storage *client_sin, struct sockaddr_storage *server_sin)
+ #else
check_host(struct sockaddr_in *client_sin, struct sockaddr_in *server_sin)
+ #endif
{
char cname[NI_MAXHOST];
char sname[NI_MAXHOST];
+ #ifdef IPV6_SUP
+ char caddr[NI_MAXHOST];
+ char saddr[NI_MAXHOST];
+ #endif
struct request_info request;
int i;

+ #ifdef IPV6_SUP
+ #ifdef DEBUG_LOG
+ syslog(LOG_INFO, "entering check_host()\n");
+ #endif
+ #endif
+
+ #ifdef IPV6_SUP
+ /* retrieve client address */
+ i = getnameinfo((struct sockaddr *)client_sin,
+ client_sin->ss_len, caddr, sizeof(caddr),
+ NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV);
+
+ if (i != 0 && i != EAI_NONAME && i != EAI_AGAIN) {
+ syslog(LOG_NOTICE, "1 getnameinfo() failed!\n");
+ return(0);
+ }
+
+ /* retrieve server address */
+ i = getnameinfo((struct sockaddr *)server_sin,
+ server_sin->ss_len, saddr, sizeof(saddr),
+ NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV);
+
+ if (i != 0 && i != EAI_NONAME && i != EAI_AGAIN) {
+ syslog(LOG_NOTICE, "2 getnameinfo() failed!\n");
+ return(0);
+ }
+
+ request_init(&request, RQ_DAEMON, __progname, RQ_CLIENT_SIN,
+ client_sin, RQ_SERVER_SIN, server_sin, RQ_CLIENT_ADDR,
+ caddr, 0);
+ #else
request_init(&request, RQ_DAEMON, __progname, RQ_CLIENT_SIN,
client_sin, RQ_SERVER_SIN, server_sin, RQ_CLIENT_ADDR,
inet_ntoa(client_sin->sin_addr), 0);
+ #endif

if (Use_Rdns) {
/*
***************
*** 264,269 ****
--- 339,359 ----
* the tcp wrapper cares about these things, and we don't
* want to pass in a printed address as a name.
*/
+ #ifdef IPV6_SUP
+ i = getnameinfo((struct sockaddr *)client_sin,
+ client_sin->ss_len, cname, sizeof(cname),
+ NULL, 0, NI_NAMEREQD);
+
+ if (i != 0 && i != EAI_NONAME && i != EAI_AGAIN)
+ strlcpy(cname, STRING_UNKNOWN, sizeof(cname));
+
+ i = getnameinfo((struct sockaddr *)server_sin,
+ server_sin->ss_len, sname, sizeof(sname),
+ NULL, 0, NI_NAMEREQD);
+
+ if (i != 0 && i != EAI_NONAME && i != EAI_AGAIN)
+ strlcpy(sname, STRING_UNKNOWN, sizeof(sname));
+ #else
i = getnameinfo((struct sockaddr *) &client_sin->sin_addr,
sizeof(&client_sin->sin_addr), cname, sizeof(cname),
NULL, 0, NI_NAMEREQD);
***************
*** 277,282 ****
--- 367,373 ----

if (i != 0 && i != EAI_NONAME && i != EAI_AGAIN)
strlcpy(sname, STRING_UNKNOWN, sizeof(sname));
+ #endif
} else {
/*
* ensure the TCP wrapper doesn't start doing
***************
*** 286,293 ****
--- 377,388 ----
strlcpy(sname, STRING_UNKNOWN, sizeof(sname));
}

+ #ifdef IPV6_SUP
+ request_set(&request, RQ_SERVER_ADDR, saddr, 0);
+ #else
request_set(&request, RQ_SERVER_ADDR, inet_ntoa(server_sin->sin_addr),
0);
+ #endif
request_set(&request, RQ_CLIENT_NAME, cname, RQ_SERVER_NAME, sname, 0);

if (!hosts_access(&request)) {
***************
*** 422,427 ****
--- 517,528 ----
* Close existing data conn.
*/

+ #ifdef IPV6_SUP
+ #ifdef DEBUG_LOG
+ syslog(LOG_INFO, "new_dataconn() server: [%d]\n", server);
+ #endif
+ #endif
+
if (client_listen_socket != -1) {
close(client_listen_socket);
client_listen_socket = -1;
***************
*** 436,443 ****
--- 537,549 ----

if (server) {
bzero(&server_listen_sa, sizeof(server_listen_sa));
+ #ifdef IPV6_SUP
+ server_listen_socket = get_backchannel_socket(address_family,
+ SOCK_STREAM, min_port, max_port, -1, 1, &server_listen_sa);
+ #else
server_listen_socket = get_backchannel_socket(SOCK_STREAM,
min_port, max_port, -1, 1, &server_listen_sa);
+ #endif

if (server_listen_socket == -1) {
syslog(LOG_INFO, "server socket bind() failed (%m)");
***************
*** 449,456 ****
--- 555,567 ----
}
} else {
bzero(&client_listen_sa, sizeof(client_listen_sa));
+ #ifdef IPV6_SUP
+ client_listen_socket = get_backchannel_socket(address_family,
+ SOCK_STREAM, min_port, max_port, -1, 1, &client_listen_sa);
+ #else
client_listen_socket = get_backchannel_socket(SOCK_STREAM,
min_port, max_port, -1, 1, &client_listen_sa);
+ #endif

if (client_listen_socket == -1) {
syslog(LOG_NOTICE,
***************
*** 469,482 ****
--- 580,611 ----
static void
connect_pasv_backchannel(void)
{
+ #ifdef IPV6_SUP
+ struct sockaddr_storage listen_sa;
+ #else
struct sockaddr_in listen_sa;
+ #endif
socklen_t salen;
+ #ifdef IPV6_SUP
+ #ifdef DEBUG_LOG
+ char host[NI_MAXHOST];
+ char port[NI_MAXHOST];
+ #endif
+ #endif

/*
* We are about to accept a connection from the client.
* This is a PASV data connection.
*/
+ #ifdef IPV6_SUP
+ #ifdef DEBUG_LOG
+ syslog(LOG_INFO, "client listen socket ready");
+ #endif
+
+ debuglog(2, "client listen socket ready");
+ #else
debuglog(2, "client listen socket ready");
+ #endif

close_server_data();
close_client_data();
***************
*** 493,506 ****
client_listen_socket = -1;
memset(&listen_sa, 0, sizeof(listen_sa));

server_data_socket = get_backchannel_socket(SOCK_STREAM, min_port,
! max_port, -1, 1, &listen_sa);
if (server_data_socket < 0) {
syslog(LOG_NOTICE, "get_backchannel_socket() failed (%m)");
exit(EX_OSERR);
}
if (connect(server_data_socket, (struct sockaddr *) &server_listen_sa,
sizeof(server_listen_sa)) != 0) {
syslog(LOG_NOTICE, "connect() failed (%m)");
exit(EX_NOHOST);
}
--- 622,662 ----
client_listen_socket = -1;
memset(&listen_sa, 0, sizeof(listen_sa));

+ #ifdef IPV6_SUP
+ server_data_socket = get_backchannel_socket(address_family, SOCK_STREAM, min_port,
+ max_port, -1, 1, (struct sockaddr_storage *)&listen_sa);
+ #else
server_data_socket = get_backchannel_socket(SOCK_STREAM, min_port,
! max_port, -1, 1, &listen_sa);
! #endif
if (server_data_socket < 0) {
syslog(LOG_NOTICE, "get_backchannel_socket() failed (%m)");
exit(EX_OSERR);
}
+ #ifdef IPV6_SUP
+ #ifdef DEBUG_LOG
+ getnameinfo((struct sockaddr *)&server_listen_sa,
+ server_listen_sa.ss_len,
+ host, sizeof(host),
+ port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV);
+
+ syslog(LOG_INFO, "1 server_data_socket: [%d], host: [%s], port: [%s]\n",
+ server_data_socket, host, port);
+
+ getnameinfo((struct sockaddr *)&listen_sa,
+ listen_sa.ss_len,
+ host, sizeof(host),
+ port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV);
+
+ syslog(LOG_INFO, "2 host: [%s], port: [%s]\n", host, port);
+ #endif
+
+ if (connect(server_data_socket, (struct sockaddr *) &server_listen_sa,
+ server_listen_sa.ss_len) != 0) {
+ #else
if (connect(server_data_socket, (struct sockaddr *) &server_listen_sa,
sizeof(server_listen_sa)) != 0) {
+ #endif
syslog(LOG_NOTICE, "connect() failed (%m)");
exit(EX_NOHOST);
}
***************
*** 512,525 ****
--- 668,701 ----
static void
connect_port_backchannel(void)
{
+ #ifdef IPV6_SUP
+ struct sockaddr_storage listen_sa;
+ struct sockaddr_in *sockaddr4;
+ struct sockaddr_in6 *sockaddr6;
+ #else
struct sockaddr_in listen_sa;
+ #endif
socklen_t salen;
+ #ifdef IPV6_SUP
+ #ifdef DEBUG_LOG
+ char host[NI_MAXHOST];
+ char port[NI_MAXHOST];
+ #endif
+ #endif

/*
* We are about to accept a connection from the server.
* This is a PORT or EPRT data connection.
*/
+ #ifdef IPV6_SUP
+ #ifdef DEBUG_LOG
+ syslog(LOG_INFO, "server listen socket ready");
+ #endif
+
debuglog(2, "server listen socket ready");
+ #else
+ debuglog(2, "server listen socket ready");
+ #endif

close_server_data();
close_client_data();
***************
*** 531,536 ****
--- 707,723 ----
syslog(LOG_NOTICE, "accept() failed (%m)");
exit(EX_OSERR);
}
+ #ifdef IPV6_SUP
+ #ifdef DEBUG_LOG
+ getnameinfo((struct sockaddr *)&listen_sa,
+ listen_sa.ss_len,
+ host, sizeof(host),
+ port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV);
+
+ syslog(LOG_INFO, "server_listen_socket: [%d], host: [%s], port: [%s]\n",
+ server_listen_socket, host, port);
+ #endif
+ #endif
close(server_listen_socket);
server_listen_socket = -1;

***************
*** 541,549 ****
* getting one bound to port 20 - This is deliberately
* not RFC compliant.
*/
bzero(&listen_sa.sin_addr, sizeof(struct in_addr));
client_data_socket = get_backchannel_socket(SOCK_STREAM,
! min_port, max_port, -1, 1, &listen_sa);
if (client_data_socket < 0) {
syslog(LOG_NOTICE, "get_backchannel_socket() failed (%m)");
exit(EX_OSERR);
--- 728,761 ----
* getting one bound to port 20 - This is deliberately
* not RFC compliant.
*/
+ #ifdef IPV6_SUP
+ #ifdef DEBUG_LOG
+ syslog(LOG_INFO, "running as non-root\n");
+ syslog(LOG_INFO, "address_family: [%d]\n", address_family);
+ #endif
+ #endif
+
+ #ifdef IPV6_SUP
+ /* clear address based on address family */
+ if (address_family == AF_INET) {
+ sockaddr4 = (struct sockaddr_in *)&listen_sa;
+ bzero(&sockaddr4->sin_addr, sizeof(struct in_addr));
+ }
+ else {
+ sockaddr6 = (struct sockaddr_in6 *)&listen_sa;
+ bzero(&sockaddr6->sin6_addr, sizeof(struct in6_addr));
+ }
+ #else
bzero(&listen_sa.sin_addr, sizeof(struct in_addr));
+ #endif
+
+ #ifdef IPV6_SUP
+ client_data_socket = get_backchannel_socket(address_family, SOCK_STREAM,
+ min_port, max_port, -1, 1, (struct sockaddr_storage *)&listen_sa);
+ #else
client_data_socket = get_backchannel_socket(SOCK_STREAM,
! min_port, max_port, -1, 1, &listen_sa);
! #endif
if (client_data_socket < 0) {
syslog(LOG_NOTICE, "get_backchannel_socket() failed (%m)");
exit(EX_OSERR);
***************
*** 555,566 ****
--- 767,799 ----
* We're root, get our backchannel socket bound to port
* 20 here, so we're fully RFC compliant.
*/
+ #ifdef IPV6_SUP
+ #ifdef DEBUG_LOG
+ syslog(LOG_INFO, "running as root\n");
+ #endif
+ #endif
+
+ #ifdef IPV6_SUP
+ client_data_socket = socket(address_family, SOCK_STREAM, 0);
+
+ salen = 1;
+ if (address_family == AF_INET) {
+ sockaddr4 = (struct sockaddr_in *)&listen_sa;
+ sockaddr4->sin_family = AF_INET;
+ bcopy(&((struct sockaddr_in *)&src_addr)->sin_addr,
+ &sockaddr4->sin_addr, sizeof(struct in_addr));
+ sockaddr4->sin_port = htons(20);
+ }
+ else {
+ }
+ #else
client_data_socket = socket(AF_INET, SOCK_STREAM, 0);

salen = 1;
listen_sa.sin_family = AF_INET;
bcopy(&src_addr, &listen_sa.sin_addr, sizeof(struct in_addr));
listen_sa.sin_port = htons(20);
+ #endif

if (setsockopt(client_data_socket, SOL_SOCKET, SO_REUSEADDR,
&salen, sizeof(salen)) == -1) {
***************
*** 575,582 ****
--- 808,830 ----
}
}

+ #ifdef IPV6_SUP
+ #ifdef DEBUG_LOG
+ getnameinfo((struct sockaddr *)&client_listen_sa,
+ client_listen_sa.ss_len,
+ host, sizeof(host),
+ port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV);
+
+ syslog(LOG_INFO, "client_data_socket: [%d], host: [%s], port: [%s]\n",
+ client_data_socket, host, port);
+ #endif
+
+ if (connect(client_data_socket, (struct sockaddr *) &client_listen_sa,
+ client_listen_sa.ss_len) != 0) {
+ #else
if (connect(client_data_socket, (struct sockaddr *) &client_listen_sa,
sizeof(client_listen_sa)) != 0) {
+ #endif
syslog(LOG_INFO, "cannot connect data channel (%m)");
exit(EX_NOHOST);
}
***************
*** 592,600 ****
--- 840,871 ----
int i, j, rv;
char tbuf[100];
char *sendbuf = NULL;
+ #ifdef IPV6_SUP
+ char c_addr_str[NI_MAXHOST];
+ char c_port_str[NI_MAXHOST];
+ char s_addr_str[NI_MAXHOST];
+ char s_port_str[NI_MAXHOST];
+ int ret;
+ #endif

log_control_command((char *)client->line_buffer, 1);

+ #ifdef IPV6_SUP
+ #ifdef DEBUG_LOG
+ syslog(LOG_INFO, "client->line_buffer: [%s]\n", (char *)client->line_buffer);
+ #endif
+ #endif
+
+ #ifdef IPV6_SUP
+ ret = getnameinfo((struct sockaddr *)&server->sa, server->sa.ss_len, s_addr_str,
+ sizeof(s_addr_str), NULL, 0,
+ NI_NUMERICHOST | NI_NUMERICSERV);
+
+ if (ret != 0) {
+ strcpy(s_addr_str, "unknown server address");
+ }
+ #endif
+
/* client->line_buffer is an ftp control command.
* There is no reason for these to be very long.
* In the interest of limiting buffer overrun attempts,
***************
*** 667,677 ****
--- 938,957 ----
goto protounsupp;

memset(&hints, 0, sizeof(hints));
+ #ifdef IPV6_SUP
+ /* Support for both IPV4 and IPV6 */
+ if ((proto != 1) && (proto != 2))
+ goto protounsupp;
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_NUMERICHOST; /*no DNS*/
+ #else
if (proto != 1) /* 1 == AF_INET - all we support for now */
goto protounsupp;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_NUMERICHOST; /*no DNS*/
+ #endif
if (getaddrinfo(result[1], result[2], &hints, &res))
goto parsefail;
if (res->ai_next)
***************
*** 680,688 ****
--- 960,987 ----
goto parsefail;
memcpy(&client_listen_sa, res->ai_addr, res->ai_addrlen);

+ #ifdef IPV6_SUP
+ ret = getnameinfo(res->ai_addr, res->ai_addrlen, c_addr_str,
+ sizeof(c_addr_str), c_port_str, sizeof(c_port_str),
+ NI_NUMERICHOST | NI_NUMERICSERV);
+
+ if (ret != 0) {
+ strcpy(c_addr_str, "unknown client address");
+ strcpy(c_port_str, "unknown client port");
+ }
+
+ #ifdef DEBUG_LOG
+ syslog(LOG_INFO, "client wants us to use %s:%s",
+ c_addr_str, c_port_str);
+ #endif
+
+ debuglog(1, "client wants us to use %s:%s",
+ c_addr_str, c_port_str);
+ #else
debuglog(1, "client wants us to use %s:%u",
inet_ntoa(client_listen_sa.sin_addr),
htons(client_listen_sa.sin_port));
+ #endif

/*
* Configure our own listen socket and tell the server about it
***************
*** 690,702 ****
--- 989,1030 ----
new_dataconn(1);
connection_mode = EPRT_MODE;

+ #ifdef IPV6_SUP
+ i = getnameinfo((struct sockaddr *)&server_listen_sa, server_listen_sa.ss_len, NULL,
+ 0, s_port_str, sizeof(s_port_str),
+ NI_NUMERICHOST | NI_NUMERICSERV);
+
+ if (ret != 0) {
+ strcpy(s_port_str, "unknown server port");
+ }
+
+ #ifdef DEBUG_LOG
+ syslog(LOG_INFO, "we want server to use %s:%s",
+ s_addr_str, s_port_str);
+ #endif
+
+ debuglog(1, "we want server to use %s:%s",
+ s_addr_str, s_port_str);
+ #else
debuglog(1, "we want server to use %s:%u",
inet_ntoa(server->sa.sin_addr),
ntohs(server_listen_sa.sin_port));
+ #endif

+ #ifdef IPV6_SUP
+ snprintf(tbuf, sizeof(tbuf), "EPRT |%u|%s|%s|\r\n", (unsigned int)proto,
+ s_addr_str, s_port_str);
+ #else
snprintf(tbuf, sizeof(tbuf), "EPRT |%d|%s|%u|\r\n", 1,
inet_ntoa(server->sa.sin_addr),
ntohs(server_listen_sa.sin_port));
+ #endif
+
+ #ifdef IPV6_SUP
+ #ifdef DEBUG_LOG
+ syslog(LOG_INFO, "to server (modified): %s", tbuf);
+ #endif
+ #endif
debuglog(1, "to server (modified): %s", tbuf);
sendbuf = tbuf;
goto out;
***************
*** 706,711 ****
--- 1034,1044 ----
sendbuf = NULL;
goto out;
protounsupp:
+ #ifdef IPV6_SUP
+ /* we support AF_INET and AF_INET6 now */
+ snprintf(tbuf, sizeof(tbuf),
+ "501 Protocol not supported\r\n");
+ #else
/* we only support AF_INET for now */
if (proto == 2)
snprintf(tbuf, sizeof(tbuf),
***************
*** 713,718 ****
--- 1046,1052 ----
else
snprintf(tbuf, sizeof(tbuf),
"501 Protocol not supported\r\n");
+ #endif
sendbuf = NULL;
out:
if (line)
***************
*** 765,770 ****
--- 1099,1109 ----
strlen("port ")) == 0) {
unsigned int values[6];
char *tailptr;
+ #ifdef IPV6_SUP
+ struct sockaddr_in *client_sockaddr_in;
+ struct sockaddr_in *server_sockaddr_in;
+ struct sockaddr_in *server_listen_sockaddr_in;
+ #endif

debuglog(1, "Got a PORT command");

***************
*** 789,794 ****
--- 1128,1146 ----
}
}

+ #ifdef IPV6_SUP
+ client_sockaddr_in = (struct sockaddr_in *)&client_listen_sa;
+ client_sockaddr_in->sin_family = AF_INET;
+ client_sockaddr_in->sin_addr.s_addr = htonl((values[0] << 24) |
+ (values[1] << 16) | (values[2] << 8) |
+ (values[3] << 0));
+
+ client_sockaddr_in->sin_port = htons((values[4] << 8) |
+ values[5]);
+ debuglog(1, "client wants us to use %u.%u.%u.%u:%u",
+ values[0], values[1], values[2], values[3],
+ (values[4] << 8) | values[5]);
+ #else
client_listen_sa.sin_family = AF_INET;
client_listen_sa.sin_addr.s_addr = htonl((values[0] << 24) |
(values[1] << 16) | (values[2] << 8) |
***************
*** 799,804 ****
--- 1151,1157 ----
debuglog(1, "client wants us to use %u.%u.%u.%u:%u",
values[0], values[1], values[2], values[3],
(values[4] << 8) | values[5]);
+ #endif

/*
* Configure our own listen socket and tell the server about it
***************
*** 806,815 ****
--- 1159,1197 ----
new_dataconn(1);
connection_mode = PORT_MODE;

+ #ifdef IPV6_SUP
+ i = getnameinfo((struct sockaddr *)&server_listen_sa, server_listen_sa.ss_len, NULL,
+ 0, s_port_str, sizeof(s_port_str),
+ NI_NUMERICHOST | NI_NUMERICSERV);
+
+ if (ret != 0) {
+ strcpy(s_port_str, "unknown server port");
+ }
+
+ #ifdef DEBUG_LOG
+ syslog(LOG_INFO, "we want server to use %s:%s",
+ s_addr_str, s_port_str);
+ #endif
+
+ debuglog(1, "we want server to use %s:%s",
+ s_addr_str, s_port_str);
+ #else
debuglog(1, "we want server to use %s:%u",
inet_ntoa(server->sa.sin_addr),
ntohs(server_listen_sa.sin_port));
+ #endif

+ #ifdef IPV6_SUP
+ server_sockaddr_in = (struct sockaddr_in *)&server->sa;
+ server_listen_sockaddr_in = (struct sockaddr_in *)&server_listen_sa;
+ snprintf(tbuf, sizeof(tbuf), "PORT %u,%u,%u,%u,%u,%u\r\n",
+ ((u_char *)&server_sockaddr_in->sin_addr.s_addr)[0],
+ ((u_char *)&server_sockaddr_in->sin_addr.s_addr)[1],
+ ((u_char *)&server_sockaddr_in->sin_addr.s_addr)[2],
+ ((u_char *)&server_sockaddr_in->sin_addr.s_addr)[3],
+ ((u_char *)&server_listen_sockaddr_in->sin_port)[0],
+ ((u_char *)&server_listen_sockaddr_in->sin_port)[1]);
+ #else
snprintf(tbuf, sizeof(tbuf), "PORT %u,%u,%u,%u,%u,%u\r\n",
((u_char *)&server->sa.sin_addr.s_addr)[0],
((u_char *)&server->sa.sin_addr.s_addr)[1],
***************
*** 817,823 ****
--- 1199,1211 ----
((u_char *)&server->sa.sin_addr.s_addr)[3],
((u_char *)&server_listen_sa.sin_port)[0],
((u_char *)&server_listen_sa.sin_port)[1]);
+ #endif

+ #ifdef IPV6_SUP
+ #ifdef DEBUG_LOG
+ syslog(LOG_INFO, "to server (modified): %s", tbuf);
+ #endif
+ #endif
debuglog(1, "to server (modified): %s", tbuf);

sendbuf = tbuf;
***************
*** 848,856 ****
--- 1236,1260 ----
struct in_addr *iap;
static int continuing = 0;
char tbuf[100], *sendbuf, *p;
+ #ifdef IPV6_SUP
+ struct sockaddr_in *client_sockaddr_in;
+ struct sockaddr_in *server_sockaddr_in;
+ struct sockaddr_in *proxy_sockaddr_in;
+ struct sockaddr_in6 *client_sockaddr_in6;
+ struct sockaddr_in6 *server_sockaddr_in6;
+ struct sockaddr_in6 *use_sockaddr_in6;
+ char host[NI_MAXHOST];
+ char port[NI_MAXHOST];
+ #endif

log_control_command((char *)server->line_buffer, 0);

+ #ifdef IPV6_SUP
+ #ifdef DEBUG_LOG
+ syslog(LOG_INFO, "server->line_buffer: [%s]\n", (char *)server->line_buffer);
+ #endif
+ #endif
+
if (strlen((char *)server->line_buffer) > 512) {
/*
* someone's playing games. Have a cow in the syslogs and
***************
*** 887,892 ****
--- 1291,1303 ----
unsigned int values[6];
char *tailptr;

+ #ifdef IPV6_SUP
+ #ifdef DEBUG_LOG
+ syslog(LOG_INFO, "PASV reply\n");
+ syslog(LOG_INFO, "address_family: [%d]\n", address_family);
+ #endif
+ #endif
+
debuglog(1, "Got a PASV reply");
debuglog(1, "{%s}", (char *)server->line_buffer);

***************
*** 917,922 ****
--- 1328,1359 ----
exit(EX_DATAERR);
}

+ #ifdef IPV6_SUP
+ if (address_family == AF_INET) {
+ server_sockaddr_in = (struct sockaddr_in *)&server_listen_sa;
+ server_sockaddr_in->sin_family = AF_INET;
+ server_sockaddr_in->sin_len = sizeof(struct sockaddr_in);
+ server_sockaddr_in->sin_addr.s_addr = htonl((values[0] << 24) |
+ (values[1] << 16) | (values[2] << 8) | (values[3] << 0));
+ server_sockaddr_in->sin_port = htons((values[4] << 8) |
+ values[5]);
+
+ #ifdef DEBUG_LOG
+ syslog(LOG_INFO, "server wants us to use %s:%u",
+ inet_ntoa(server_sockaddr_in->sin_addr), (values[4] << 8) |
+ values[5]);
+ #endif
+
+ debuglog(1, "server wants us to use %s:%u",
+ inet_ntoa(server_sockaddr_in->sin_addr), (values[4] << 8) |
+ values[5]);
+ }
+ else {
+ syslog(LOG_NOTICE, "failed in do_server_reply(), unknown af: [%d]\n",
+ address_family);
+ exit(EX_DATAERR);
+ }
+ #else
server_listen_sa.sin_family = AF_INET;
server_listen_sa.sin_addr.s_addr = htonl((values[0] << 24) |
(values[1] << 16) | (values[2] << 8) | (values[3] << 0));
***************
*** 926,934 ****
--- 1363,1404 ----
debuglog(1, "server wants us to use %s:%u",
inet_ntoa(server_listen_sa.sin_addr), (values[4]