static int ftp_init_transfer(void) { struct sockaddr_in sa; unsigned char *a, *p; unsigned char pac[6]; if(!ftp_connected()) goto err0; if (!(ftp->data = sock_create())) { goto err0; } sock_copy(ftp->data, ftp->ctrl); if(ftp_is_passive()) { if(ftp_pasv(pac) != 0) { goto err1; } sock_getsockname(ftp->ctrl, &sa); memcpy(&sa.sin_addr, pac, (size_t)4); memcpy(&sa.sin_port, pac+4, (size_t)2); if(sock_connect_addr(ftp->data, &sa) == -1) goto err1; } else { sock_listen(ftp->data); a = (unsigned char *)&ftp->data->local_addr.sin_addr; p = (unsigned char *)&ftp->data->local_addr.sin_port; ftp_set_tmp_verbosity(vbError); ftp_cmd("PORT %d,%d,%d,%d,%d,%d", a[0], a[1], a[2], a[3], p[0], p[1]); if(ftp->code != ctComplete) goto err1; } sock_throughput(ftp->data); return 0; err1: sock_destroy(ftp->data); err0: return -1; }
static int ftp_init_transfer(void) { if (!ftp_connected()) return -1; if (!sock_dup(ftp->ctrl, &ftp->data)) return -1; if (ftp_is_passive()) { ftp_trace("Initializing passive connection.\n"); struct sockaddr_storage sa; memcpy(&sa, sock_remote_addr(ftp->ctrl), sizeof(struct sockaddr_storage)); unsigned char pac[6] = { 0 }; unsigned short ipv6_port = { 0 }; if (!ftp_pasv(sa.ss_family != AF_INET, pac, &ipv6_port)) { ftp_trace("PASV/EPSV failed.\n"); sock_destroy(ftp->data); ftp->data = NULL; return -1; } socklen_t len = sizeof(struct sockaddr_in); if (sa.ss_family == AF_INET) { memcpy(&((struct sockaddr_in*)&sa)->sin_addr, pac, (size_t)4); memcpy(&((struct sockaddr_in*)&sa)->sin_port, pac+4, (size_t)2); } #ifdef HAVE_IPV6 else if (sa.ss_family == AF_INET6) { ((struct sockaddr_in6*)&sa)->sin6_port = htons(ipv6_port); len = sizeof(struct sockaddr_in6); } #endif else { ftp_trace("Do not know how to handle family %d.\n", sa.ss_family); sock_destroy(ftp->data); ftp->data = NULL; return -1; } struct sockaddr_storage tmp; memcpy(&tmp, sock_remote_addr(ftp->ctrl), sizeof(struct sockaddr_storage)); if (is_reserved((struct sockaddr*) &sa) || is_multicast((struct sockaddr*) &sa) || (is_private((struct sockaddr*) &sa) != is_private((struct sockaddr*) &tmp)) || (is_loopback((struct sockaddr*) &sa) != is_loopback((struct sockaddr*) &tmp))) { // Invalid address returned by PASV. Replace with address from control // socket. ftp_err(_("Address returned by PASV seems to be incorrect.\n")); ((struct sockaddr_in*)&sa)->sin_addr = ((struct sockaddr_in*)&tmp)->sin_addr; } if (!sock_connect_addr(ftp->data, (struct sockaddr*) &sa, len)) { ftp_trace("Could not connect to address from PASV/EPSV.\n"); perror("connect()"); sock_destroy(ftp->data); ftp->data = NULL; return -1; } } else { ftp_trace("Initializing active connection.\n"); const struct sockaddr* local = sock_local_addr(ftp->data); sock_listen(ftp->data, local->sa_family); if (local->sa_family == AF_INET) { struct sockaddr_in* tmp = (struct sockaddr_in*)local; unsigned char* a = (unsigned char *)&tmp->sin_addr; unsigned char* p = (unsigned char *)&tmp->sin_port; ftp_set_tmp_verbosity(vbError); ftp_cmd("PORT %d,%d,%d,%d,%d,%d", a[0], a[1], a[2], a[3], p[0], p[1]); } #ifdef HAVE_IPV6 else if (local->sa_family == AF_INET6) { char* addr = printable_address(local); ftp_set_tmp_verbosity(vbError); ftp_cmd("EPRT |2|%s|%u|", addr, ntohs(((struct sockaddr_in6*)local)->sin6_port)); free(addr); } #endif else { ftp_trace("Do not know how to handle family %d.\n", local->sa_family); sock_destroy(ftp->data); ftp->data = NULL; return -1; } if(ftp->code != ctComplete) { ftp_trace("PORT/EPRT not successful\n"); sock_destroy(ftp->data); ftp->data = NULL; return -1; } } sock_throughput(ftp->data); return 0; }
static int ftp_init_transfer(void) { struct sockaddr_storage sa; unsigned char *a, *p; if(!ftp_connected()) return -1; if (!(ftp->data = sock_create())) { return -1; } sock_copy(ftp->data, ftp->ctrl); if (ftp_is_passive()) { memcpy(&sa, sock_remote_addr(ftp->ctrl), sizeof(struct sockaddr_storage)); unsigned char pac[6]; unsigned short ipv6_port; if (!ftp_pasv(sa.ss_family != AF_INET, pac, &ipv6_port)) goto err1; socklen_t len = sizeof(struct sockaddr_in); if (sa.ss_family == AF_INET) { memcpy(&((struct sockaddr_in*)&sa)->sin_addr, pac, (size_t)4); memcpy(&((struct sockaddr_in*)&sa)->sin_port, pac+4, (size_t)2); } #ifdef HAVE_IPV6 else if (sa.ss_family == AF_INET6) { ((struct sockaddr_in6*)&sa)->sin6_port = htons(ipv6_port); len = sizeof(struct sockaddr_in6); } #endif else return -1; struct sockaddr_storage tmp; memcpy(&tmp, sock_remote_addr(ftp->ctrl), sizeof(struct sockaddr_storage)); if (is_reserved((struct sockaddr*) &sa) || is_multicast((struct sockaddr*) &sa) || (is_private((struct sockaddr*) &sa) != is_private((struct sockaddr*) &tmp)) || (is_loopback((struct sockaddr*) &sa) != is_loopback((struct sockaddr*) &tmp))) { // Invalid address returned by PASV. Replace with address from control // socket. ftp_err(_("Address returned by PASV seems to be incorrect.\n")); ((struct sockaddr_in*)&sa)->sin_addr = ((struct sockaddr_in*)&tmp)->sin_addr; } if (!sock_connect_addr(ftp->data, (struct sockaddr*) &sa, len)) { perror("connect()"); goto err1; } } else { const struct sockaddr* local = sock_local_addr(ftp->data); sock_listen(ftp->data, local->sa_family); if (local->sa_family == AF_INET) { struct sockaddr_in* tmp = (struct sockaddr_in*)local; a = (unsigned char *)&tmp->sin_addr; p = (unsigned char *)&tmp->sin_port; ftp_set_tmp_verbosity(vbError); ftp_cmd("PORT %d,%d,%d,%d,%d,%d", a[0], a[1], a[2], a[3], p[0], p[1]); } #ifdef HAVE_IPV6 else if (local->sa_family == AF_INET6) { char* addr = printable_address(local); ftp_set_tmp_verbosity(vbError); ftp_cmd("EPRT |2|%s|%u", addr, ntohs(((struct sockaddr_in6*)local)->sin6_port)); free(addr); } #endif else goto err1; if(ftp->code != ctComplete) goto err1; } sock_throughput(ftp->data); return 0; err1: sock_destroy(ftp->data); ftp->data = 0; return -1; }