vBulletin Search Engine Optimization
| |||||||
| Register | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
| ||||
| Thanks Bob, Btw, do you have any idea when 3.7 be released? - Ronnel Bob Beck wrote: > Thanks ronnel, I'll take a look at this with you after the 3.7 >release > > -Bob > > >* Ronnel P. Maglasang <rmaglasang@infoweapons.com> [2005-03-18 03:16]: > > >>thanks, got that. just learned the convention here is >>diff -urN <orig> <new>. >> >>here's using diff -urN. >> >> >>Dries Schellekens wrote: >> >> >> >>>Ronnel P. Maglasang wrote: >>> >>> >>> >>>>apologies, the patch is incorrect, i diff'ed in the wrong direction. >>>>please disregard the previous one. >>>> >>>>this is the correct patch file. >>>> >>>> >>>OpenBSD developers prefer if you use diff -u >>> >>> >>>Cheers, >>> >>>Dries >>> >>> >> >> > > > >>diff -urN 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,4 +14,7 @@ >> DPADD+= ${LIBWRAP} >> .endif >> >>+# For ipv6 support >>+CFLAGS+= -DIPV6_SUP >>+ >> .include <bsd.prog.mk> >>diff -urN 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 18:04:33 2005 >>@@ -55,6 +55,13 @@ >> * 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,11 +132,24 @@ >> >> 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,18 +166,33 @@ >> 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,16 +281,50 @@ >> * 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 >>+ /* 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,6 +333,21 @@ >> * 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,6 +361,7 @@ >> >> 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,8 +371,12 @@ >> 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,6 +511,12 @@ >> * 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,8 +531,13 @@ >> >> 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,8 +549,13 @@ >> } >> } 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,14 +574,32 @@ >> 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,14 +616,41 @@ >> 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); >>+ 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,14 +662,34 @@ >> 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,6 +701,17 @@ >> 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,9 +722,34 @@ >> * 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); >>+ 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,12 +761,33 @@ >> * 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,8 +802,23 @@ >> } >> } >> >>+#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,9 +834,32 @@ >> 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,11 +932,20 @@ >> 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,9 +954,28 @@ >> 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,13 +983,42 @@ >> 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,6 +1028,11 @@ >> 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,6 +1040,7 @@ >> else >> snprintf(tbuf, sizeof(tbuf), >> "501 Protocol not supported\r\n"); >>+#endif >> sendbuf = NULL; >> out: >> if (line) >>@@ -765,6 +1093,11 @@ >> 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,6 +1122,19 @@ >> } >> } >> >>+#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,6 +1145,7 @@ >> 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,10 +1153,39 @@ >> 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,7 +1193,13 @@ >> ((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,9 +1230,25 @@ >> 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,6 +1285,13 @@ >> 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,6 +1322,32 @@ >> 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,9 +1357,42 @@ >> 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 >>@@ -943,9 +1407,264 @@ >> ((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; >>- } else { >>+ } >>+#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; >> } >>@@ -963,7 +1682,6 @@ >> else if (rv != -1) >> j += rv; >> } while (j >= 0 && j < i); >>- >> } >> >> int >>@@ -979,6 +1697,26 @@ >> #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 >> char *p; >>@@ -986,11 +1724,36 @@ >> 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 */ >>@@ -1024,6 +1787,82 @@ >> 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) >>@@ -1051,12 +1890,34 @@ >> 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); >>@@ -1085,7 +1946,9 @@ >> if (max_port < min_port) >> usage(); >> >>+#ifndef IPV6_SUP >> openlog(__progname, LOG_NDELAY|LOG_PID, LOG_DAEMON); >>+#endif >> >> setlinebuf(stdout); >> setlinebuf(stderr); >>@@ -1118,21 +1981,36 @@ >> 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); >> } >> >>@@ -1143,17 +2021,35 @@ >> >> 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); >> } >> >>@@ -1165,16 +2061,32 @@ >> 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)); >>@@ -1224,6 +2136,12 @@ >> 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) >>@@ -1237,6 +2155,13 @@ >> 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"); >>@@ -1303,12 +2228,25 @@ >> 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(); >>@@ -1320,12 +2258,25 @@ >> 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(); >>diff -urN ftp-proxy/ftp-proxy.cat8 ftp-proxy-new/ftp-proxy.cat8 >>--- ftp-proxy/ftp-proxy.cat8 Thu Jan 1 08:00:00 1970 >>+++ ftp-proxy-new/ftp-proxy.cat8 Fri Mar 18 16:37:40 2005 >>@@ -0,0 +1,170 @@ >>+FTP-PROXY(8) OpenBSD System Manager's Manual FTP-PROXY(8) >>+ >>+NNAAMMEE >>+ ffttpp--pprrooxxyy - Internet File Transfer Protocol proxy server >>+ >>+SSYYNNOOPPSSIISS >>+ ffttpp--pprrooxxyy [--AAnnrrVVww] [--aa _a_d_d_r_e_s_s] [--DD _d_e_b_u_g_l_e_v_e_l] [--gg _g_r_o_u_p] [--MM _m_a_x_p_o_r_t] >>+ [--mm _m_i_n_p_o_r_t] [--RR _a_d_d_r_e_s_s_[_:_p_o_r_t_]] [--SS _a_d_d_r_e_s_s] [--tt _t_i_m_e_o_u_t] [--uu >>+ _u_s_e_r] >>+ >>+DDEESSCCRRIIPPTTIIOONN >>+ ffttpp--pprrooxxyy is a proxy for the Internet File Transfer Protocol. The proxy >>+ uses pf(4) and expects to have the FTP control connection as described in >>+ services(5) redirected to it via a pf(4) _r_d_r command. An example of how >>+ to do that is further down in this document. >>+ >>+ The options are as follows: >>+ >>+ --AA Permit only anonymous FTP connections. The proxy will allow con- >>+ nections to log in to other sites as the user "ftp" or >>+ "anonymous" only. Any attempt to log in as another user will be >>+ blocked by the proxy. >>+ >>+ --aa _a_d_d_r_e_s_s >>+ Specify the local IP address to use in bind(2) as the source for >>+ connections made by ffttpp--pprrooxxyy when connecting to destination FTP >>+ servers. This may be necessary if the interface address of your >>+ default route is not reachable from the destinations ffttpp--pprrooxxyy is >>+ attempting connections to, or this address is different from the >>+ one connections are being NATed to. In the usual case this means >>+ that _a_d_d_r_e_s_s should be a publicly visible IP address assigned to >>+ one of the interfaces on the machine running ffttpp--pprrooxxyy and should >>+ be the same address to which you are translating traffic if you >>+ are using the --nn option. >>+ >>+ --DD _d_e_b_u_g_l_e_v_e_l >>+ Specify a debug level, where the proxy emits verbose debug output >>+ into syslogd(8) at level LOG_DEBUG. Meaningful values of debu- >>+ glevel are 0-3, where 0 is no debug output and 3 is lots of debug >>+ output, the default being 0. >>+ >>+ --gg _g_r_o_u_p >>+ Specify the named group to drop group privileges to, after doing >>+ pf(4) lookups which require root. By default, ffttpp--pprrooxxyy uses the >>+ default group of the user it drops privilege to. >>+ >>+ --MM _m_a_x_p_o_r_t >>+ Specify the upper end of the port range the proxy will use for >>+ the data connections it establishes. The default is >>+ IPPORT_HILASTAUTO defined in <_n_e_t_i_n_e_t_/_i_n_._h> as 65535. >>+ >>+ --mm _m_i_n_p_o_r_t >>+ Specify the lower end of the port range the proxy will use for >>+ all data connections it establishes. The default is >>+ IPPORT_HIFIRSTAUTO defined in <_n_e_t_i_n_e_t_/_i_n_._h> as 49152. >>+ >>+ --nn Activate network address translation (NAT) mode. In this mode, >>+ the proxy will not attempt to proxy passive mode (PASV or EPSV) >>+ data connections. In order for this to work, the machine running >>+ the proxy will need to be forwarding packets and doing network >>+ address translation to allow the outbound passive connections >>+ from the client to reach the server. See pf.conf(5) for more de- >>+ tails on NAT. The proxy only ignores passive mode data connec- >>+ tions when using this flag; it will still proxy PORT and EPRT >>+ mode data connections. Without this flag, ffttpp--pprrooxxyy does not re- >>+ quire any IP forwarding or NAT beyond the _r_d_r necessary to cap- >>+ ture the FTP control connection. >>+ >>+ --rr Use reverse host (reverse DNS) lookups for logging and libwrap >>+ use. By default, the proxy does not look up hostnames for lib- >>+ wrap or logging purposes. >>+ >>+ --RR _a_d_d_r_e_s_s_:_[_p_o_r_t_] >>+ Reverse proxy mode for FTP servers running behind a NAT gateway. >>+ In this mode, no redirection is needed. The proxy is run from >>+ inetd(8) on the port that external clients connect to (usually >>+ 21). Control connections and passive data connections are for- >>+ warded to the server. >>+ >>+ --SS _a_d_d_r_e_s_s >>+ Source address to use for data connections made by the proxy. >>+ Useful when there are multiple addresses (aliases) available to >>+ the proxy. Clients may expect data connections to have the same >>+ source address as the control connections, and reject or drop >>+ other connections. >>+ >>+ --tt _t_i_m_e_o_u_t >>+ Specifies a timeout, in seconds. The proxy will exit and close >>+ open connections if it sees no data for the duration of the time- >>+ out. The default is 0, which means the proxy will not time out. >>+ >>+ --uu _u_s_e_r >>+ Specify the named user to drop privilege to, after doing pf(4) >>+ lookups which require root privilege. By default, ffttpp--pprrooxxyy >>+ drops privilege to the user _p_r_o_x_y. >>+ >>+ Running as root means that the source of data connections the >>+ proxy makes for PORT and EPRT will be the RFC mandated port 20. >>+ When running as a non-root user, the source of the data connec- >>+ tions from ffttpp--pprrooxxyy will be chosen randomly from the range >>+ _m_i_n_p_o_r_t to _m_a_x_p_o_r_t as described above. >>+ >>+ --VV Be verbose. With this option the proxy logs the control commands >>+ sent by clients and the replies sent by the servers to >>+ syslogd(8). >>+ >>+ --ww Use the tcp wrapper access control library hosts_access(3), al- >>+ lowing connections to be allowed or denied based on the tcp wrap- >>+ per's hosts.allow(5) and hosts.deny(5) files. The proxy does >>+ libwrap operations after determining the destination of the cap- >>+ tured control connection, so that tcp wrapper rules may be writ- >>+ ten based on the destination as well as the source of FTP connec- >>+ tions. >>+ >>+ ffttpp--pprrooxxyy is run from inetd(8) and requires that FTP connections are >>+ redirected to it using a _r_d_r rule. A typical way to do this would be to >>+ use a pf.conf(5) rule such as >>+ >>+ int_if = "xl0" >>+ rdr pass on $int_if proto tcp from any to any port 21 -> 127.0.0.1 port 8021 >>+ >>+ inetd(8) must then be configured to run ffttpp--pprrooxxyy on the port from above >>+ using >>+ >>+ 127.0.0.1:8021 stream tcp nowait root /usr/libexec/ftp-proxy ftp-proxy >>+ >>+ in inetd.conf(5). >>+ >>+ ffttpp--pprrooxxyy accepts the redirected control connections and forwards them to >>+ the server. The proxy replaces the address and port number that the >>+ client sends through the control connection to the server with its own >>+ address and proxy port, where it listens for the data connection. When >>+ the server opens the data connection back to this port, the proxy for- >>+ wards it to the client. The pf.conf(5) rules need to let pass connec- >>+ tions to these proxy ports (see options --uu, --mm, and --MM above) in on the >>+ external interface. The following example allows only ports 49152 to >>+ 65535 to pass in statefully: >>+ >>+ block in on $ext_if proto tcp all >>+ pass in on $ext_if inet proto tcp from any to $ext_if \ >>+ port > 49151 keep state >>+ >>+ Alternatively, rules can make use of the fact that by default, ffttpp--pprrooxxyy >>+ runs as user "proxy" to allow the backchannel connections, as in the fol- >>+ lowing example: >>+ >>+ block in on $ext_if proto tcp all >>+ pass in on $ext_if inet proto tcp from any to $ext_if \ >>+ user proxy keep state >>+ >>+ These examples do not cover the connections from the proxy to the foreign >>+ FTP server. If one does not pass outgoing connections by default addi- >>+ tional rules are needed. >>+ >>+SSEEEE AALLSSOO >>+ ftp(1), pf(4), hosts.allow(5), hosts.deny(5), inetd.conf(5), pf.conf(5), >>+ inetd(8), pfctl(8), syslogd(8) >>+ >>+BBUUGGSS >>+ Extended Passive mode (EPSV) is not supported by the proxy and will not >>+ work unless the proxy is run in network address translation mode. When >>+ not in network address translation mode, the proxy returns an error to >>+ the client, hopefully forcing the client to revert to passive mode (PASV) >>+ which is supported. EPSV will work in network address translation mode, >>+ assuming a pf.conf(5) setup which allows the EPSV connections through to >>+ their destinations. >>+ >>+ IPv6 already supported. >>+ >>+OpenBSD 3.6 August 17, 2001 3 >>diff -urN ftp-proxy/util.c ftp-proxy-new/util.c >>--- ftp-proxy/util.c Wed Jul 7 03:49:11 2004 >>+++ ftp-proxy-new/util.c Thu Mar 17 22:37:28 2005 >>@@ -58,9 +58,19 @@ >> >> 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, ...); >> >>@@ -76,12 +86,27 @@ >> } >> >> 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, >>@@ -96,9 +121,96 @@ >> 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 >>@@ -111,6 +223,7 @@ >> 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 >>@@ -123,10 +236,16 @@ >> } >> >> 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); >> } >>@@ -136,11 +255,38 @@ >> * 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); >> } >> >>@@ -151,8 +297,13 @@ >> * 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]; >>@@ -216,15 +367,84 @@ >> } >> } >> >>+ >>+#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 >>@@ -257,9 +477,39 @@ >> } >> >> 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); >>@@ -271,6 +521,7 @@ >> 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 >>@@ -281,13 +532,42 @@ >> 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); >>diff -urN ftp-proxy/util.h ftp-proxy-new/util.h >>--- ftp-proxy/util.h Wed Jul 7 03:49:11 2004 >>+++ ftp-proxy-new/util.h Fri Mar 11 23:30:48 2005 >>@@ -45,7 +45,11 @@ >> 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; >>@@ -54,14 +58,29 @@ >> 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; [demime 1.01d removed an attachment of type application/x-pkcs7-signature which had a name of smime.p7s] |