Example #1
0
const char* DLLCALL inet_addrtop(union xp_sockaddr *addr, char *dest, size_t size)
{
#ifdef _WIN32
	if(getnameinfo(&addr->addr, xp_sockaddr_len(addr), dest, size, NULL, 0, NI_NUMERICHOST))
		safe_snprintf(dest, size, "<Error %u converting address, family=%u>", WSAGetLastError(), addr->addr.sa_family);
	return dest;
#else
	switch(addr->addr.sa_family) {
		case AF_INET:
			return inet_ntop(addr->in.sin_family, &addr->in.sin_addr, dest, size);
		case AF_INET6:
			return inet_ntop(addr->in6.sin6_family, &addr->in6.sin6_addr, dest, size);
		case AF_UNIX:
			strncpy(dest, addr->un.sun_path, size);
			dest[size-1]=0;
			return dest;
		default:
			safe_snprintf(dest, size, "<unknown address family: %u>", addr->addr.sa_family);
			return NULL;
	}
#endif
}
Example #2
0
SOCKET sbbs_t::ftp_data_sock(csi_t* csi, SOCKET ctrl_sock, SOCKADDR_IN* addr)
{
	char		cmd[512];
	char		rsp[512];
	char*		p;
	socklen_t	addr_len;
	SOCKET		data_sock;
	int			ip_b[4];
	int			port_b[2];
	union {
		DWORD	dw;
		BYTE	b[sizeof(DWORD)];
	} ip_addr;
	union {
		WORD	w;
		BYTE	b[sizeof(WORD)];
	} port;

	if(csi->ftp_mode&CS_FTP_ASCII)
		strcpy(cmd,"TYPE A");
	else	/* BINARY */
		strcpy(cmd,"TYPE I");
	if(!ftp_cmd(csi,ctrl_sock,cmd,rsp) 
		|| atoi(rsp)!=200) {
		return(INVALID_SOCKET);
	}

	if((data_sock=open_socket(SOCK_STREAM, "ftp"))==INVALID_SOCKET) {
		csi->socket_error=ERROR_VALUE;
		return(INVALID_SOCKET);
	}

	memset(addr,0,sizeof(SOCKADDR_IN));
	addr->sin_addr.s_addr = htonl(startup->outgoing4.s_addr);
	addr->sin_family = AF_INET;

	if(bind(data_sock, (struct sockaddr *)addr,xp_sockaddr_len(addr))!= 0) {
		csi->socket_error=ERROR_VALUE;
		close_socket(data_sock);
		return(INVALID_SOCKET);
	}
	
	if(csi->ftp_mode&CS_FTP_PASV) {

		if(!ftp_cmd(csi,ctrl_sock,"PASV",rsp) 
			|| atoi(rsp)!=227 /* PASV response */) {
			bprintf("ftp: failure, line %d",__LINE__);
			close_socket(data_sock);
			return(INVALID_SOCKET);
		}

		p=strchr(rsp,'(');
		if(p==NULL) {
			bprintf("ftp: failure, line %d",__LINE__);
			close_socket(data_sock);
			return(INVALID_SOCKET);
		}
		p++;
		if(sscanf(p,"%u,%u,%u,%u,%u,%u"
			,&ip_b[0],&ip_b[1],&ip_b[2],&ip_b[3]
			,&port_b[0],&port_b[1])!=6) {
			bprintf("ftp: failure, line %d",__LINE__);
			close_socket(data_sock);
			return(INVALID_SOCKET);
		}

		ip_addr.b[0]=ip_b[0];	ip_addr.b[1]=ip_b[1];
		ip_addr.b[2]=ip_b[2];	ip_addr.b[3]=ip_b[3];
		port.b[0]=port_b[0];	port.b[1]=port_b[1];

		addr->sin_addr.s_addr=ip_addr.dw;
		addr->sin_port=port.w;

	} else {	/* Normal (Active) FTP */

		addr_len=sizeof(SOCKADDR_IN);
		if(getsockname(data_sock, (struct sockaddr *)addr,&addr_len)!=0) {
			csi->socket_error=ERROR_VALUE;
			close_socket(data_sock);
			return(INVALID_SOCKET);
		} 

		SOCKADDR_IN ctrl_addr;
		addr_len=sizeof(ctrl_addr);
		if(getsockname(ctrl_sock, (struct sockaddr *)&ctrl_addr,&addr_len)!=0) {
			csi->socket_error=ERROR_VALUE;
			close_socket(data_sock);
			return(INVALID_SOCKET);
		} 

		if(listen(data_sock, 1)!= 0) {
			csi->socket_error=ERROR_VALUE;
			close_socket(data_sock);
			return(INVALID_SOCKET);
		}

		ip_addr.dw=ntohl(ctrl_addr.sin_addr.s_addr);
		port.w=ntohs(addr->sin_port);
		sprintf(cmd,"PORT %u,%u,%u,%u,%u,%u"
			,ip_addr.b[3]
			,ip_addr.b[2]
			,ip_addr.b[1]
			,ip_addr.b[0]
			,port.b[1]
			,port.b[0]
			);

		if(!ftp_cmd(csi,ctrl_sock,cmd,rsp) 
			|| atoi(rsp)!=200 /* PORT response */) {
			close_socket(data_sock);
			return(INVALID_SOCKET);
		}

	}

	return(data_sock);
}