示例#1
0
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;
}
示例#2
0
文件: ftpsend.c 项目: sebastinas/yafc
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;
}
示例#3
0
文件: ftpsend.c 项目: casualuser/yafc
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;
}