--- ./src/ftp.cc 2013-07-13 15:22:32.000000000 +0200
+++ ./src/ftp.cc 2013-12-21 15:39:23.015056228 +0100
@@ -2816,6 +2816,7 @@
}
ftpState->listenForDataChannel(temp, ftpState->entry->url());
+ ftpState->data.listenConn = temp;
}
/// \ingroup ServerProtocolFTPInternal
@@ -2851,14 +2852,19 @@
// pull out the internal IP address bytes to send in PORT command...
// source them from the listen_conn->local
-
+ struct sockaddr_in addr;
+ socklen_t addrlen = sizeof(addr);
+ getsockname(ftpState->data.listenConn->fd, (struct sockaddr *) &addr, &addrlen);
+ unsigned char port_high = ntohs(addr.sin_port) >> 8;
+ unsigned char port_low = ntohs(addr.sin_port) & 0xff;
+
struct addrinfo *AI = NULL;
ftpState->data.listenConn->local.GetAddrInfo(AI, AF_INET);
unsigned char *addrptr = (unsigned char *) &((struct sockaddr_in*)AI->ai_addr)->sin_addr;
- unsigned char *portptr = (unsigned char *) &((struct sockaddr_in*)AI->ai_addr)->sin_port;
+ // unsigned char *portptr = (unsigned char *) &((struct sockaddr_in*)AI->ai_addr)->sin_port;
snprintf(cbuf, CTRL_BUFLEN, "PORT %d,%d,%d,%d,%d,%d\r\n",
addrptr[0], addrptr[1], addrptr[2], addrptr[3],
- portptr[0], portptr[1]);
+ port_high, port_low);
ftpState->writeCommand(cbuf);
ftpState->state = SENT_PORT;
@@ -2907,15 +2913,25 @@
ftpFail(ftpState);
return;
}
-
- char buf[MAX_IPSTRLEN];
-
+ unsigned int port;
+ struct sockaddr_storage addr;
+ socklen_t addrlen = sizeof(addr);
+ getsockname(ftpState->data.listenConn->fd, (struct sockaddr *) &addr, &addrlen);
+ if (addr.ss_family == AF_INET) {
+ struct sockaddr_in *addr4 = (struct sockaddr_in*) &addr;
+ port = ntohs( addr4->sin_port );
+ } else {
+ struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &addr;
+ port = ntohs( addr6->sin6_port );
+ }
+
+ char buf[MAX_IPSTRLEN];
/* RFC 2428 defines EPRT as IPv6 equivalent to IPv4 PORT command. */
/* Which can be used by EITHER protocol. */
- snprintf(cbuf, CTRL_BUFLEN, "EPRT |%d|%s|%d|\r\n",
+ snprintf(cbuf, CTRL_BUFLEN, "EPRT |%d|%s|%u|\r\n",
( ftpState->data.listenConn->local.IsIPv6() ? 2 : 1 ),
ftpState->data.listenConn->local.NtoA(buf,MAX_IPSTRLEN),
- ftpState->data.listenConn->local.GetPort() );
+ port);
ftpState->writeCommand(cbuf);
ftpState->state = SENT_EPRT;