Beispiel #1
0
/*********************************************************************
*
*       _Connect
*
*  Function description
*    This function is called from the FTP server module if the client
*    uses active FTP to establish the data connection.
*/
static FTPS_SOCKET _Connect(FTPS_SOCKET CtrlSocket, U16 Port) {
  int                DataSock;
  struct sockaddr_in Data;
  struct sockaddr_in PeerAddr;
  int                ConnectStatus;
  int                AddrSize;

  DataSock = _socket(AF_INET, SOCK_STREAM, 0);  // Create a new socket for data connection to the client
  if (DataSock != SOCKET_ERROR) {               // Socket created?
    Data.sin_family      = AF_INET;
    Data.sin_port        = _htons(20);
    Data.sin_addr.s_addr = INADDR_ANY;
    _bind(DataSock, (struct sockaddr *)&Data, sizeof(Data));
    //
    //  Get IP address of connected client and connect to listening port
    //
    AddrSize = sizeof(struct sockaddr_in);
    _getpeername((long)CtrlSocket, (struct sockaddr *)&PeerAddr, &AddrSize);
    PeerAddr.sin_port = _htons(Port);
    ConnectStatus  = _connect(DataSock, (struct sockaddr *)&PeerAddr, sizeof(struct sockaddr_in));
    if (ConnectStatus == 0) {
      return (void*)DataSock;
    }
  }
  return NULL;
}
Beispiel #2
0
/*********************************************************************
*
*       _Listen
*
*  Function description
*    This function is called from the FTP server module if the client
*    uses passive FTP. It creates socket and searches for a free port
*    which can be used for the data connection.
*
*  Return value
*    > 0   Socket descriptor
*    NULL  Error
*/
static FTPS_SOCKET _Listen(FTPS_SOCKET CtrlSocket, U16 *pPort, U8 * pIPAddr) {
  struct sockaddr_in addr;
  U16  Port;
  int  DataSock;
  int  AddrSize;

  addr.sin_family = AF_INET;
  addr.sin_port   = 0;                          // Let Stack find a free port
  addr.sin_addr.s_addr = INADDR_ANY;
  DataSock = _socket(AF_INET, SOCK_STREAM, 0);  // Create a new socket for data connection to the client
  if(DataSock == SOCKET_ERROR) {                // Socket created?
    return NULL;
  }
  _bind(DataSock, (struct sockaddr *)&addr, sizeof(addr));
  _listen(DataSock, 1);
  //
  //  Get port number stack has assigned
  //
  AddrSize = sizeof(struct sockaddr_in);
  _getsockname((long)DataSock, (struct sockaddr *)&addr, &AddrSize);
  Port = htons(addr.sin_port);
  *pPort = Port;
  _getsockname((long)CtrlSocket, (struct sockaddr *)&addr, &AddrSize);
  Port = htons(addr.sin_port);
  *pIPAddr++ = addr.sin_addr.s_addr;
  *pIPAddr++ = addr.sin_addr.s_addr >> 8;
  *pIPAddr++ = addr.sin_addr.s_addr >> 16;
  *pIPAddr   = addr.sin_addr.s_addr >> 24;
  return (FTPS_SOCKET)DataSock;
}
Beispiel #3
0
void ping(int argc, char **argv)
{
	int err;

	/* init options */
	init_options();

	/* parse args */
	if ((err = parse_args(argc, argv)) < 0) {
		if (err == -1)
			usage();
		return;
	}

	/* signal install */
	signal(SIGALRM, sigalrm);
	signal(SIGINT, sigint);

	/* address */
	skaddr.dst_addr = ipaddr;
	sock = _socket(AF_INET, SOCK_RAW, IP_P_ICMP);
	/* send request */
	sigalrm(SIGALRM);
	/* receive reply */
	recv_packet();

	alarm(0);
	close_socket();
	if (buf)
		free(buf);
	ping_stat();
}
Beispiel #4
0
static void tcp_start_listen( const int i )
{
	if( l_sockets[i].port ) {
		uint32 iface = l_sockets[i].iface;

		D(bug("[%d] binding to interface 0x%08X\r\n", i, iface));

		l_sockets[i].s = _socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
		if(l_sockets[i].s != INVALID_SOCKET) {
			struct sockaddr_in to;
			memset( &to, 0, sizeof(to) );
			to.sin_family = AF_INET;
			to.sin_port = htons( l_sockets[i].port );
			to.sin_addr.s_addr = htonl( iface );

			if(	_bind ( l_sockets[i].s, (const struct sockaddr *)&to, sizeof(to) ) == 0 )
			{
				D(bug("[%d] socket bound to port %d on interface 0x%08X\r\n", i, l_sockets[i].port, iface));
				if( _listen( l_sockets[i].s, SOMAXCONN ) == SOCKET_ERROR  ) {
					D(bug("[%d] listen() failed with error code %d\r\n", i, _WSAGetLastError()));
				} else {
					D(bug("[%d] listening to port %d\r\n", i, l_sockets[i].port));
					_WSAResetEvent( l_sockets[i].ev );
					if( SOCKET_ERROR == _WSAEventSelect( l_sockets[i].s, l_sockets[i].ev, FD_ACCEPT ) ) {
						D(bug("[%d] WSAEventSelect() failed with error code %d\r\n", i, _WSAGetLastError()));
					}
				}
			} else {
				D(bug("[%d] bind to port %d failed with error code %d\r\n", i, l_sockets[i].port, _WSAGetLastError()));
			}
		} else {
			D(bug("[%d] could not create a socket for port %d, error = %d\r\n", i, l_sockets[i].port, _WSAGetLastError()));
		}
	}
}
Beispiel #5
0
SOCKET WSASocketA(int af, int type, int protocol, LPWSAPROTOCOL_INFOA lpProtocolInfo, GROUP g, DWORD dwFlags)
{
	SOCKET s;

	s = _socket(af, type, protocol);

	return s;
}
Beispiel #6
0
wLogAppender* WLog_UdpAppender_New(wLog* log)
{
	wLogUdpAppender* appender;
	DWORD nSize;
	LPCSTR name;

	appender = (wLogUdpAppender*) calloc(1, sizeof(wLogUdpAppender));
	if (!appender)
		return NULL;

	appender->Type = WLOG_APPENDER_UDP;

	appender->Open = WLog_UdpAppender_Open;
	appender->Close = WLog_UdpAppender_Close;
	appender->WriteMessage = WLog_UdpAppender_WriteMessage;
	appender->WriteDataMessage = WLog_UdpAppender_WriteDataMessage;
	appender->WriteImageMessage = WLog_UdpAppender_WriteImageMessage;
	appender->Free = WLog_UdpAppender_Free;
	appender->Set = WLog_UdpAppender_Set;

	appender->sock = _socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (appender->sock == INVALID_SOCKET)
		goto error_sock;

	name = "WLOG_UDP_TARGET";
	nSize = GetEnvironmentVariableA(name, NULL, 0);
	if (nSize)
	{
		appender->host = (LPSTR) malloc(nSize);
		if (!appender->host)
			goto error_host_alloc;

		GetEnvironmentVariableA(name, appender->host, nSize);

		if (!WLog_UdpAppender_Open(log, (wLogAppender *)appender))
			goto error_open;
	}
	else
	{
		appender->host = _strdup("127.0.0.1:20000");
		if (!appender->host)
			goto error_host_alloc;
	}

	return (wLogAppender*)appender;

error_open:
	free(appender->host);
error_host_alloc:
	closesocket(appender->sock);
error_sock:
	free(appender);
	return NULL;
}
Beispiel #7
0
bool
socket_new (socket_t *socket, const char *ip, int port)
{
	socket->socket.sin_family = AF_INET;
	socket->socket.sin_addr.s_addr = inet_addr (ip);
	socket->socket.sin_port = htons (port);

	socket->connection = _socket (socket->socket.sin_family, SOCK_STREAM, 0);

	final_test (socket->connection);
}
Beispiel #8
0
int
socket(int domain, int type, int protocol)
{
    libc_func(socket, int, int, int, int);
    int fd;

    fd = netlink_socket(domain, type, protocol);
    if (fd != UNHANDLED)
	return fd;

    return _socket(domain, type, protocol);
}
Beispiel #9
0
int
socket(int domain, int type, int protocol)
{
  int fd;

  fd	= _socket(domain, type, protocol);
  DP(("socket(%d,%d,%d) = %d cmp %d %d %d\n", domain, type, protocol, fd, _sock.domain, _sock.type, _sock.proto));
  if (fd<0)
    return fd;
  if (_sock.domain == domain && _sock.type == type && _sock.proto == protocol)
    bind(fd, &_saddr, sizeof _saddr);
  return fd;
}
Beispiel #10
0
/* Should be called with mutex acquired */
static void
connectlog(void)
{
	struct sockaddr_un SyslogAddr;	/* AF_UNIX address of local logger */

	if (LogFile == -1) {
		if ((LogFile = _socket(AF_UNIX, SOCK_DGRAM, 0)) == -1)
			return;
		(void)_fcntl(LogFile, F_SETFD, 1);
	}
	if (LogFile != -1 && status == NOCONN) {
		SyslogAddr.sun_len = sizeof(SyslogAddr);
		SyslogAddr.sun_family = AF_UNIX;

		/*
		 * First try priveleged socket. If no success,
		 * then try default socket.
		 */
		(void)strncpy(SyslogAddr.sun_path, _PATH_LOG_PRIV,
		    sizeof SyslogAddr.sun_path);
		if (_connect(LogFile, (struct sockaddr *)&SyslogAddr,
		    sizeof(SyslogAddr)) != -1)
			status = CONNPRIV;

		if (status == NOCONN) {
			(void)strncpy(SyslogAddr.sun_path, _PATH_LOG,
			    sizeof SyslogAddr.sun_path);
			if (_connect(LogFile, (struct sockaddr *)&SyslogAddr,
			    sizeof(SyslogAddr)) != -1)
				status = CONNDEF;
		}

		if (status == NOCONN) {
			/*
			 * Try the old "/dev/log" path, for backward
			 * compatibility.
			 */
			(void)strncpy(SyslogAddr.sun_path, _PATH_OLDLOG,
			    sizeof SyslogAddr.sun_path);
			if (_connect(LogFile, (struct sockaddr *)&SyslogAddr,
			    sizeof(SyslogAddr)) != -1)
				status = CONNDEF;
		}

		if (status == NOCONN) {
			(void)_close(LogFile);
			LogFile = -1;
		}
	}
}
Beispiel #11
0
int socket_create_server(char *bindaddr, int port)
{
    int s = -1;
    struct addrinfo *p, *servinfo;

    if (_getaddrinfo(bindaddr, port, &servinfo, SOCK_STREAM) == CORVUS_ERR) {
        LOG(ERROR, "socket_create_server: fail to get address info");
        return CORVUS_ERR;
    }

    for (p = servinfo; p != NULL; p = p->ai_next) {
        if ((s = _socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
            continue;
        }
        break;
    }

    if (p == NULL || s == -1) {
        freeaddrinfo(servinfo);
        return CORVUS_ERR;
    }

    if (socket_set_nonblocking(s) == -1) {
        close(s);
        freeaddrinfo(servinfo);
        return CORVUS_ERR;
    }

    if (set_reuseaddr(s) == -1) {
        close(s);
        freeaddrinfo(servinfo);
        return CORVUS_ERR;
    }

    if (set_reuseport(s) == -1) {
        close(s);
        freeaddrinfo(servinfo);
        return CORVUS_ERR;
    }

    if (_listen(s, p->ai_addr, p->ai_addrlen, 1024) == -1) {
        close(s);
        freeaddrinfo(servinfo);
        return CORVUS_ERR;
    }
    freeaddrinfo(servinfo);

    return s;
}
Beispiel #12
0
static int
netlink_socket(int domain, int type, int protocol)
{
    libc_func(socket, int, int, int, int);
    int fd;
    const char *path = getenv("UMOCKDEV_DIR");

    if (domain == AF_NETLINK && protocol == NETLINK_KOBJECT_UEVENT && path != NULL) {
	fd = _socket(AF_UNIX, type, 0);
	fd_map_add(&wrapped_netlink_sockets, fd, NULL);
	DBG(DBG_NETLINK, "testbed wrapped socket: intercepting netlink, fd %i\n", fd);
	return fd;
    }

    return UNHANDLED;
}
Beispiel #13
0
int
rresvport_af(int *alport, int family)
{
	int s;
	struct sockaddr_storage ss;
	u_short *sport;

	memset(&ss, 0, sizeof(ss));
	ss.ss_family = family;
	switch (family) {
	case AF_INET:
		((struct sockaddr *)&ss)->sa_len = sizeof(struct sockaddr_in);
		sport = &((struct sockaddr_in *)&ss)->sin_port;
		((struct sockaddr_in *)&ss)->sin_addr.s_addr = INADDR_ANY;
		break;
#ifdef INET6
	case AF_INET6:
		((struct sockaddr *)&ss)->sa_len = sizeof(struct sockaddr_in6);
		sport = &((struct sockaddr_in6 *)&ss)->sin6_port;
		((struct sockaddr_in6 *)&ss)->sin6_addr = in6addr_any;
		break;
#endif
	default:
		errno = EAFNOSUPPORT;
		return -1;
	}

	s = _socket(ss.ss_family, SOCK_STREAM, 0);
	if (s < 0)
		return (-1);
#if 0 /* compat_exact_traditional_rresvport_semantics */
	sin.sin_port = htons((u_short)*alport);
	if (_bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
		return (s);
	if (errno != EADDRINUSE) {
		_close(s);
		return (-1);
	}
#endif
	*sport = 0;
	if (bindresvport_sa(s, (struct sockaddr *)&ss) == -1) {
		_close(s);
		return (-1);
	}
	*alport = (int)ntohs(*sport);
	return (s);
}
Beispiel #14
0
/*
 * Opens the connection with the specified params. Initializes all kqueues.
 */
struct cached_connection_ *
__open_cached_connection(struct cached_connection_params const *params)
{
	struct cached_connection_ *retval;
	struct kevent eventlist;
	struct sockaddr_un client_address;
	int client_address_len, client_socket;
	int res;

	assert(params != NULL);

	client_socket = _socket(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
	client_address.sun_family = PF_LOCAL;
	strncpy(client_address.sun_path, params->socket_path,
	    sizeof(client_address.sun_path));
	client_address_len = sizeof(client_address.sun_family) +
	    strlen(client_address.sun_path) + 1;

	res = _connect(client_socket, (struct sockaddr *)&client_address,
	    client_address_len);
	if (res == -1) {
		_close(client_socket);
		return (NULL);
	}
	_fcntl(client_socket, F_SETFL, O_NONBLOCK);

	retval = malloc(sizeof(struct cached_connection_));
	assert(retval != NULL);
	memset(retval, 0, sizeof(struct cached_connection_));

	retval->sockfd = client_socket;

	retval->write_queue = kqueue();
	assert(retval->write_queue != -1);

	EV_SET(&eventlist, retval->sockfd, EVFILT_WRITE, EV_ADD, 0, 0, NULL);
	res = _kevent(retval->write_queue, &eventlist, 1, NULL, 0, NULL);

	retval->read_queue = kqueue();
	assert(retval->read_queue != -1);

	EV_SET(&eventlist, retval->sockfd, EVFILT_READ, EV_ADD, 0, 0, NULL);
	res = _kevent(retval->read_queue, &eventlist, 1, NULL, 0, NULL);

	return (retval);
}
Beispiel #15
0
int init_socket(int port) {
	int listenfd, t = 1;
	struct sockaddr_in servaddr;

	listenfd = _socket(PF_INET, SOCK_STREAM, 0);

	memset(&servaddr, sizeof(char), sizeof(servaddr));			

	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port = htons(port);

	_setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(t));	

	_bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));

	return listenfd;	
}
Beispiel #16
0
/*
 * We are intercepting socket() so that we can set the stackname in time.
 * We can't just do this when the stack's name is set; pthread_setname_np
 * allows this to be done from another thread; and onload_set_stackname
 * can only act on the current thread.  So we need to do it here instead.
*/
int socket(int socket_family, int socket_type, int protocol)
{
  int ok, ext_ok;

  /* Set up passthroughs */
  if( ensure_intercepts() < 0 )
    return -EOPNOTSUPP;

  /* Set up stack name based on socket type */
  ext_ok = apply_extname(socket_type);
  /* Actually create the socket */
  ok = _socket(socket_family, socket_type, protocol);

  /* Go back to old stack name, if we changed */
  if( ext_ok )
    onload_stackname_restore();

  LOG("socket returning %d", ok);
  return ok;
}
Beispiel #17
0
/*
 * Create a client handle for a unix connection. Obsoleted by clnt_vc_create()
 */
CLIENT *
clntunix_create(struct sockaddr_un *raddr, u_long prog, u_long vers, int *sockp,
    u_int sendsz, u_int recvsz)
{
	struct netbuf *svcaddr;
	CLIENT *cl;
	int len;

	cl = NULL;
	svcaddr = NULL;
	if ((raddr->sun_len == 0) ||
	   ((svcaddr = malloc(sizeof(struct netbuf))) == NULL ) ||
	   ((svcaddr->buf = malloc(sizeof(struct sockaddr_un))) == NULL)) {
		free(svcaddr);
		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
		rpc_createerr.cf_error.re_errno = errno;
		return(cl);
	}
	if (*sockp < 0) {
		*sockp = _socket(AF_LOCAL, SOCK_STREAM, 0);
		len = raddr->sun_len = SUN_LEN(raddr);
		if ((*sockp < 0) || (_connect(*sockp,
		    (struct sockaddr *)raddr, len) < 0)) {
			rpc_createerr.cf_stat = RPC_SYSTEMERROR;
			rpc_createerr.cf_error.re_errno = errno;
			if (*sockp != -1)
				(void)_close(*sockp);
			goto done;
		}
	}
	svcaddr->buf = raddr;
	svcaddr->len = raddr->sun_len;
	svcaddr->maxlen = sizeof (struct sockaddr_un);
	cl = clnt_vc_create(*sockp, svcaddr, prog,
	    vers, sendsz, recvsz);
done:
	free(svcaddr->buf);
	free(svcaddr);
	return(cl);
}
unsigned int
if_nametoindex(const char *ifname)
{
	int s;
	struct ifreq ifr;
	struct ifaddrs *ifaddrs, *ifa;
	unsigned int ni;

	s = _socket(AF_INET, SOCK_DGRAM, 0);
	if (s != -1) {
#ifdef PURIFY
		memset(&ifr, 0, sizeof(ifr));
#endif
		strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
		if (_ioctl(s, SIOCGIFINDEX, &ifr) != -1) {
			_close(s);
			return (ifr.ifr_index);
		}
		_close(s);
	}

	if (getifaddrs(&ifaddrs) < 0)
		return(0);

	ni = 0;

	for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
		if (ifa->ifa_addr &&
		    ifa->ifa_addr->sa_family == AF_LINK &&
		    strcmp(ifa->ifa_name, ifname) == 0) {
			ni = ((struct sockaddr_dl*)ifa->ifa_addr)->sdl_index;
			break;
		}
	}

	freeifaddrs(ifaddrs);
	if (!ni)
		errno = ENXIO;
	return(ni);
}
Beispiel #19
0
static int alloc_new_socket( const uint16 src_port, const uint16 dest_port, const uint32 ip_dest )
{
	int t = alloc_socket();

	if(t >= 0) {
		sockets[t].s = _socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
		if(sockets[t].s == INVALID_SOCKET) {
			free_socket( t );
			t = -1;
		} else {
			sockets[t].src_port = src_port;
			sockets[t].dest_port = dest_port;
			
			sockets[t].from_len = sizeof(sockets[t].from);
			memset( &sockets[t].from, 0, sockets[t].from_len );
			sockets[t].from.sin_family = AF_INET;
			sockets[t].from.sin_port = htons(dest_port);
			sockets[t].from.sin_addr.s_addr = htonl(ip_dest);

			struct sockaddr_in to;
			memset( &to, 0, sizeof(to) );
			to.sin_family = AF_INET;

			if(	_bind ( sockets[t].s, (const struct sockaddr *)&to, sizeof(to) ) == 0 ) {
				D(bug("<%d> socket bound\r\n", t));
			} else {
				if( _WSAGetLastError() == WSAEINPROGRESS ) {
					D(bug("<%d> bind: a blocking call is in progress.\r\n", t));
				} else {
					D(bug("<%d> bind failed with error code %d\r\n", t, _WSAGetLastError()));
				}
				free_socket( t );
				t = -1;
			}
		}
	}
	return t;
}
Beispiel #20
0
/*
********************************************************************************
*              MAKE DNS QUERY AND PARSE THE REPLY
*
* Description : This function makes DNS query message and parses the reply from DNS server.
* Arguments   : name - is a pointer to the domain name.
* Returns     : if succeeds : 1, fails : -1
* Note        :
********************************************************************************
*/
int DNS::query(char *name)
{
    int state;
    static uint32_t dns_wait_time = 0;
    struct dhdr dhp;
    uint8_t ip[4];
    uint16_t len, port;
    uint8_t dns_server_ip[4];
    uint8_t BUFPUB[100];

    get_local_dns(dns_server_ip);
    len = makequery(0, (uint8_t *)name, BUFPUB, MAX_DNS_BUF_SIZE);
    DNS_DBG("ÓòÃû:[%s]\r\n", name);
    DNS_DBG("ÓòÃû½âÎöÖÐ...\r\n");

    while(1)
    {
        state = socket_status(s);
        if(state == SOCK_CLOSED)
        {
            DNS_DBG("dns's socket closed!,socket: %d\r\n", s);
            DNS_DBG("openning dns's socket... !\r\n");
            if(_socket(s, Sn_MR_UDP, port, 0) == 1)
                DNS_DBG("open dns's socket seccusse!\r\n");
        }

        if(state == SOCK_UDP)
        {
            DNS_DBG("sending query cmd...\r\n");
            if(_sendto(s, BUFPUB, len, dns_server_ip, IPPORT_DOMAIN) > 0)
                DNS_DBG("send dns cmd ok!\r\n");

            if ((len = recv_available(s)) > 0)
            {
                if (len > MAX_DNS_BUF_SIZE)
                {
                    len = MAX_DNS_BUF_SIZE;
                }
                len = _recvfrom(s, BUFPUB, len, ip, &port);
                DNS_DBG("receiv dns's date ok!datelen:%d\r\n", len);
                if(parseMSG(&dhp, BUFPUB))
                {
                    _close(s);
                    DNS_DBG("query is ok!\r\n");
                    return 1;
                }
                else
                {
                    DNS_DBG("dns's date is bad!\r\n");
                    return -1;
                }
            }
            else
            {
                DNS_DBG("wait dns's date...!\r\n");
                delay_ms(1000);
                dns_wait_time++;
            }
            if(dns_wait_time >= 3)
            {
                _close(s);
                return -2;
            }
        }
    };
}
Beispiel #21
0
int
rtime(struct sockaddr_in *addrp, struct timeval *timep,
    struct timeval *timeout)
{
	int s;
	fd_set readfds;
	int res;
	unsigned long thetime;
	struct sockaddr_in from;
	socklen_t fromlen;
	int type;
	struct servent *serv;

	if (timeout == NULL) {
		type = SOCK_STREAM;
	} else {
		type = SOCK_DGRAM;
	}
	s = _socket(AF_INET, type, 0);
	if (s < 0) {
		return(-1);
	}
	addrp->sin_family = AF_INET;

	/* TCP and UDP port are the same in this case */
	if ((serv = getservbyname("time", "tcp")) == NULL) {
		return(-1);
	}

	addrp->sin_port = serv->s_port;

	if (type == SOCK_DGRAM) {
		res = _sendto(s, (char *)&thetime, sizeof(thetime), 0,
			     (struct sockaddr *)addrp, sizeof(*addrp));
		if (res < 0) {
			do_close(s);
			return(-1);
		}
		do {
			FD_ZERO(&readfds);
			FD_SET(s, &readfds);
			res = _select(_rpc_dtablesize(), &readfds,
				     (fd_set *)NULL, (fd_set *)NULL, timeout);
		} while (res < 0 && errno == EINTR);
		if (res <= 0) {
			if (res == 0) {
				errno = ETIMEDOUT;
			}
			do_close(s);
			return(-1);
		}
		fromlen = sizeof(from);
		res = _recvfrom(s, (char *)&thetime, sizeof(thetime), 0,
			       (struct sockaddr *)&from, &fromlen);
		do_close(s);
		if (res < 0) {
			return(-1);
		}
	} else {
		if (_connect(s, (struct sockaddr *)addrp, sizeof(*addrp)) < 0) {
			do_close(s);
			return(-1);
		}
		res = _read(s, (char *)&thetime, sizeof(thetime));
		do_close(s);
		if (res < 0) {
			return(-1);
		}
	}
	if (res != sizeof(thetime)) {
		errno = EIO;
		return(-1);
	}
	thetime = ntohl(thetime);
	timep->tv_sec = thetime - TOFFSET;
	timep->tv_usec = 0;
	return(0);
}
Beispiel #22
0
static int freerdp_tcp_connect_multi(rdpContext* context, char** hostnames,
				     UINT32* ports, int count, int port,
				     int timeout)
{
	int index;
	int sindex;
	int status;
	SOCKET sockfd = -1;
	SOCKET* sockfds;
	HANDLE* events;
	DWORD waitStatus;
	char port_str[16];
	struct addrinfo hints;
	struct addrinfo* addr;
	struct addrinfo* result;
	struct addrinfo** addrs;
	struct addrinfo** results;

	sprintf_s(port_str, sizeof(port_str) - 1, "%d", port);

	sockfds = (SOCKET*) calloc(count, sizeof(SOCKET));
	events = (HANDLE*) calloc(count + 1, sizeof(HANDLE));
	addrs = (struct addrinfo**) calloc(count, sizeof(struct addrinfo*));
	results = (struct addrinfo**) calloc(count, sizeof(struct addrinfo*));

	if (!sockfds || !events || !addrs || !results)
	{
		free(sockfds);
		free(events);
		free(addrs);
		free(results);
		return -1;
	}

	for (index = 0; index < count; index++)
	{
		ZeroMemory(&hints, sizeof(hints));
		hints.ai_family = AF_UNSPEC;
		hints.ai_socktype = SOCK_STREAM;

		if (ports)
			sprintf_s(port_str, sizeof(port_str) - 1, "%"PRIu32"", ports[index]);

		status = getaddrinfo(hostnames[index], port_str, &hints, &result);

		if (status)
		{
			continue;
		}

		addr = result;

		if ((addr->ai_family == AF_INET6) && (addr->ai_next != 0))
		{
			while ((addr = addr->ai_next))
			{
				if (addr->ai_family == AF_INET)
					break;
			}

			if (!addr)
				addr = result;
		}

		sockfds[index] = _socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);

		if (sockfds[index] == INVALID_SOCKET)
		{
			freeaddrinfo(result);
			sockfds[index] = 0;
			continue;
		}

		addrs[index] = addr;
		results[index] = result;
	}

	for (index = 0; index < count; index++)
	{
		if (!sockfds[index])
			continue;

		sockfd = sockfds[index];
		addr = addrs[index];

		/* set socket in non-blocking mode */
		events[index] = WSACreateEvent();
		if (!events[index])
		{
			WLog_ERR(TAG, "WSACreateEvent returned 0x%08X", WSAGetLastError());
			continue;
		}

		if (WSAEventSelect(sockfd, events[index], FD_READ | FD_WRITE | FD_CONNECT | FD_CLOSE))
		{
			WLog_ERR(TAG, "WSAEventSelect returned 0x%08X", WSAGetLastError());
			continue;
		}

		/* non-blocking tcp connect */

		status = _connect(sockfd, addr->ai_addr, addr->ai_addrlen);

		if (status >= 0)
		{
			/* connection success */
			break;
		}
	}

	events[count] = context->abortEvent;

	waitStatus = WaitForMultipleObjects(count + 1, events, FALSE, timeout * 1000);

	sindex = waitStatus - WAIT_OBJECT_0;

	for (index = 0; index < count; index++)
	{
		u_long arg = 0;

		if (!sockfds[index])
			continue;

		sockfd = sockfds[index];

		/* set socket in blocking mode */
		if (WSAEventSelect(sockfd, NULL, 0))
		{
			WLog_ERR(TAG, "WSAEventSelect returned 0x%08X", WSAGetLastError());
			continue;
		}

		if (_ioctlsocket(sockfd, FIONBIO, &arg))
		{
			WLog_ERR(TAG, "_ioctlsocket failed");
		}
	}

	if ((sindex >= 0) && (sindex < count))
	{
		sockfd = sockfds[sindex];
	}

	if (sindex == count)
		freerdp_set_last_error(context, FREERDP_ERROR_CONNECT_CANCELLED);

	for (index = 0; index < count; index++)
	{
		if (results[index])
			freeaddrinfo(results[index]);
		CloseHandle(events[index]);
	}

	free(addrs);
	free(results);
	free(sockfds);
	free(events);

	return sockfd;
}
Beispiel #23
0
int socket_create_stream()
{
    return _socket(AF_INET, SOCK_STREAM, 0);
}
Beispiel #24
0
/*
 * __rpc_get_time_offset()
 *
 * This function uses a nis_server structure to contact the a remote
 * machine (as named in that structure) and returns the offset in time
 * between that machine and this one. This offset is returned in seconds
 * and may be positive or negative.
 *
 * The first time through, a lot of fiddling is done with the netconfig
 * stuff to find a suitable transport. The function is very aggressive
 * about choosing UDP or at worst TCP if it can. This is because
 * those transports support both the RCPBIND call and the internet
 * time service.
 *
 * Once through, *uaddr is set to the universal address of
 * the machine and *netid is set to the local netid for the transport
 * that uaddr goes with. On the second call, the netconfig stuff
 * is skipped and the uaddr/netid pair are used to fetch the netconfig
 * structure and to then contact the machine for the time.
 *
 * td = "server" - "client"
 */
int
__rpc_get_time_offset(struct timeval *td,	/* Time difference			*/
		      nis_server *srv,		/* NIS Server description 		*/
		      char *thost,		/* if no server, this is the timehost	*/
		      char **uaddr,		/* known universal address		*/
		      struct sockaddr_in *netid)/* known network identifier		*/
{
	CLIENT			*clnt; 		/* Client handle 	*/
	endpoint		*ep,		/* useful endpoints	*/
				*useep = NULL;	/* endpoint of xp	*/
	char			*useua = NULL;	/* uaddr of selected xp	*/
	int			epl, i;		/* counters		*/
	enum clnt_stat		status;		/* result of clnt_call	*/
	u_long			thetime, delta;
	int			needfree = 0;
	struct timeval		tv;
	int			time_valid;
	int			udp_ep = -1, tcp_ep = -1;
	int			a1, a2, a3, a4;
	char			ut[64], ipuaddr[64];
	endpoint		teps[32];
	nis_server		tsrv;
	void			(*oldsig)() = NULL; /* old alarm handler */
	struct sockaddr_in	sin;
	socklen_t		len;
	int			s = RPC_ANYSOCK;
	int			type = 0;

	td->tv_sec = 0;
	td->tv_usec = 0;

	/*
	 * First check to see if we need to find and address for this
	 * server.
	 */
	if (*uaddr == NULL) {
		if ((srv != NULL) && (thost != NULL)) {
			msg("both timehost and srv pointer used!");
			return (0);
		}
		if (! srv) {
			srv = get_server(netid, thost, &tsrv, teps, 32);
			if (srv == NULL) {
				msg("unable to contruct server data.");
				return (0);
			}
			needfree = 1;	/* need to free data in endpoints */
		}

		ep = srv->ep.ep_val;
		epl = srv->ep.ep_len;

		/* Identify the TCP and UDP endpoints */
		for (i = 0;
			(i < epl) && ((udp_ep == -1) || (tcp_ep == -1)); i++) {
			if (strcasecmp(ep[i].proto, "udp") == 0)
				udp_ep = i;
			if (strcasecmp(ep[i].proto, "tcp") == 0)
				tcp_ep = i;
		}

		/* Check to see if it is UDP or TCP */
		if (tcp_ep > -1) {
			useep = &ep[tcp_ep];
			useua = ep[tcp_ep].uaddr;
			type = SOCK_STREAM;
		} else if (udp_ep > -1) {
			useep = &ep[udp_ep];
			useua = ep[udp_ep].uaddr;
			type = SOCK_DGRAM;
		}

		if (useep == NULL) {
			msg("no acceptable transport endpoints.");
			if (needfree)
				free_eps(teps, tsrv.ep.ep_len);
			return (0);
		}
	}

	/*
	 * Create a sockaddr from the uaddr.
	 */
	if (*uaddr != NULL)
		useua = *uaddr;

	/* Fixup test for NIS+ */
	sscanf(useua, "%d.%d.%d.%d.", &a1, &a2, &a3, &a4);
	sprintf(ipuaddr, "%d.%d.%d.%d.0.111", a1, a2, a3, a4);
	useua = &ipuaddr[0];

	bzero((char *)&sin, sizeof(sin));
	if (uaddr_to_sockaddr(useua, &sin)) {
		msg("unable to translate uaddr to sockaddr.");
		if (needfree)
			free_eps(teps, tsrv.ep.ep_len);
		return (0);
	}

	/*
	 * Create the client handle to rpcbind. Note we always try
	 * version 3 since that is the earliest version that supports
	 * the RPCB_GETTIME call. Also it is the version that comes
	 * standard with SVR4. Since most everyone supports TCP/IP
	 * we could consider trying the rtime call first.
	 */
	clnt = clnttcp_create(&sin, RPCBPROG, RPCBVERS, &s, 0, 0);
	if (clnt == NULL) {
		msg("unable to create client handle to rpcbind.");
		if (needfree)
			free_eps(teps, tsrv.ep.ep_len);
		return (0);
	}

	tv.tv_sec = 5;
	tv.tv_usec = 0;
	time_valid = 0;
	status = clnt_call(clnt, RPCBPROC_GETTIME, (xdrproc_t)xdr_void, NULL,
					(xdrproc_t)xdr_u_long, &thetime, tv);
	/*
	 * The only error we check for is anything but success. In
	 * fact we could have seen PROGMISMATCH if talking to a 4.1
	 * machine (pmap v2) or TIMEDOUT if the net was busy.
	 */
	if (status == RPC_SUCCESS)
		time_valid = 1;
	else {
		int save;

		/* Blow away possible stale CLNT handle. */
		if (clnt != NULL) {
			clnt_destroy(clnt);
			clnt = NULL;
		}

		/*
		 * Convert PMAP address into timeservice address
		 * We take advantage of the fact that we "know" what
		 * the universal address looks like for inet transports.
		 *
		 * We also know that the internet timeservice is always
		 * listening on port 37.
		 */
		sscanf(useua, "%d.%d.%d.%d.", &a1, &a2, &a3, &a4);
		sprintf(ut, "%d.%d.%d.%d.0.37", a1, a2, a3, a4);

		if (uaddr_to_sockaddr(ut, &sin)) {
			msg("cannot convert timeservice uaddr to sockaddr.");
			goto error;
		}

		s = _socket(AF_INET, type, 0);
		if (s == -1) {
			msg("unable to open fd to network.");
			goto error;
		}

		/*
		 * Now depending on whether or not we're talking to
		 * UDP we set a timeout or not.
		 */
		if (type == SOCK_DGRAM) {
			struct timeval timeout = { 20, 0 };
			struct sockaddr_in from;
			fd_set readfds;
			int res;

			if (_sendto(s, &thetime, sizeof(thetime), 0,
				(struct sockaddr *)&sin, sizeof(sin)) == -1) {
				msg("udp : sendto failed.");
				goto error;
			}
			do {
				FD_ZERO(&readfds);
				FD_SET(s, &readfds);
				res = _select(_rpc_dtablesize(), &readfds,
				     NULL, NULL, &timeout);
			} while (res < 0 && errno == EINTR);
			if (res <= 0)
				goto error;
			len = sizeof(from);
			res = _recvfrom(s, (char *)&thetime, sizeof(thetime), 0,
				       (struct sockaddr *)&from, &len);
			if (res == -1) {
				msg("recvfrom failed on udp transport.");
				goto error;
			}
			time_valid = 1;
		} else {
			int res;

			oldsig = (void (*)())signal(SIGALRM, alarm_hndler);
			saw_alarm = 0; /* global tracking the alarm */
			alarm(20); /* only wait 20 seconds */
			res = _connect(s, (struct sockaddr *)&sin, sizeof(sin));
			if (res == -1) {
				msg("failed to connect to tcp endpoint.");
				goto error;
			}
			if (saw_alarm) {
				msg("alarm caught it, must be unreachable.");
				goto error;
			}
			res = _read(s, (char *)&thetime, sizeof(thetime));
			if (res != sizeof(thetime)) {
				if (saw_alarm)
					msg("timed out TCP call.");
				else
					msg("wrong size of results returned");

				goto error;
			}
			time_valid = 1;
		}
		save = errno;
		_close(s);
		errno = save;
		s = RPC_ANYSOCK;

		if (time_valid) {
			thetime = ntohl(thetime);
			thetime = thetime - TOFFSET; /* adjust to UNIX time */
		} else
			thetime = 0;
	}

	gettimeofday(&tv, 0);

error:
	/*
	 * clean up our allocated data structures.
	 */

	if (s != RPC_ANYSOCK)
		_close(s);

	if (clnt != NULL)
		clnt_destroy(clnt);

	alarm(0);	/* reset that alarm if its outstanding */
	if (oldsig) {
		signal(SIGALRM, oldsig);
	}

	/*
	 * note, don't free uaddr strings until after we've made a
	 * copy of them.
	 */
	if (time_valid) {
		if (*uaddr == NULL)
			*uaddr = strdup(useua);

		/* Round to the nearest second */
		tv.tv_sec += (tv.tv_sec > 500000) ? 1 : 0;
		delta = (thetime > tv.tv_sec) ? thetime - tv.tv_sec :
						tv.tv_sec - thetime;
		td->tv_sec = (thetime < tv.tv_sec) ? - delta : delta;
		td->tv_usec = 0;
	} else {
		msg("unable to get the server's time.");
	}

	if (needfree)
		free_eps(teps, tsrv.ep.ep_len);

	return (time_valid);
}
Beispiel #25
0
int
getifaddrs(struct ifaddrs **pif)
{
	int icnt = 1;
	int dcnt = 0;
	int ncnt = 0;
#ifdef	NET_RT_IFLIST
	int ntry = 0;
	int mib[6];
	size_t needed;
	char *buf;
	char *next;
	struct ifaddrs *cif = 0;
	char *p, *p0;
	struct rt_msghdr *rtm;
	struct if_msghdr *ifm;
	struct ifa_msghdr *ifam;
	struct sockaddr_dl *dl;
	struct sockaddr *sa;
	struct ifaddrs *ifa, *ift;
	u_short idx = 0;
#else	/* NET_RT_IFLIST */
	char buf[1024];
	int m, sock;
	struct ifconf ifc;
	struct ifreq *ifr;
	struct ifreq *lifr;
#endif	/* NET_RT_IFLIST */
	int i;
	size_t len, alen;
	char *data;
	char *names;

#ifdef	NET_RT_IFLIST
	mib[0] = CTL_NET;
	mib[1] = PF_ROUTE;
	mib[2] = 0;             /* protocol */
	mib[3] = 0;             /* wildcard address family */
	mib[4] = NET_RT_IFLIST;
	mib[5] = 0;             /* no flags */
	do {
		/*
		 * We'll try to get addresses several times in case that
		 * the number of addresses is unexpectedly increased during
		 * the two sysctl calls.  This should rarely happen, but we'll
		 * try to do our best for applications that assume success of
		 * this library (which should usually be the case).
		 * Portability note: since FreeBSD does not add margin of
		 * memory at the first sysctl, the possibility of failure on
		 * the second sysctl call is a bit higher.
		 */

		if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
			return (-1);
		if ((buf = malloc(needed)) == NULL)
			return (-1);
		if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
			if (errno != ENOMEM || ++ntry >= MAX_SYSCTL_TRY) {
				free(buf);
				return (-1);
			}
			free(buf);
			buf = NULL;
		} 
	} while (buf == NULL);

	for (next = buf; next < buf + needed; next += rtm->rtm_msglen) {
		rtm = (struct rt_msghdr *)(void *)next;
		if (rtm->rtm_version != RTM_VERSION)
			continue;
		switch (rtm->rtm_type) {
		case RTM_IFINFO:
			ifm = (struct if_msghdr *)(void *)rtm;
			if (ifm->ifm_addrs & RTA_IFP) {
				idx = ifm->ifm_index;
				++icnt;
				dl = (struct sockaddr_dl *)(void *)(ifm + 1);
				dcnt += SA_RLEN((struct sockaddr *)(void*)dl) +
				    ALIGNBYTES;
#ifdef	HAVE_IFM_DATA
				dcnt += sizeof(ifm->ifm_data);
#endif	/* HAVE_IFM_DATA */
				ncnt += dl->sdl_nlen + 1;
			} else
				idx = 0;
			break;

		case RTM_NEWADDR:
			ifam = (struct ifa_msghdr *)(void *)rtm;
			if (idx && ifam->ifam_index != idx)
				abort();	/* this cannot happen */

#define	RTA_MASKS	(RTA_NETMASK | RTA_IFA | RTA_BRD)
			if (idx == 0 || (ifam->ifam_addrs & RTA_MASKS) == 0)
				break;
			p = (char *)(void *)(ifam + 1);
			++icnt;
#ifdef	HAVE_IFAM_DATA
			dcnt += sizeof(ifam->ifam_data) + ALIGNBYTES;
#endif	/* HAVE_IFAM_DATA */
			/* Scan to look for length of address */
			alen = 0;
			for (p0 = p, i = 0; i < RTAX_MAX; i++) {
				if ((RTA_MASKS & ifam->ifam_addrs & (1 << i))
				    == 0)
					continue;
				sa = (struct sockaddr *)(void *)p;
				len = SA_RLEN(sa);
				if (i == RTAX_IFA) {
					alen = len;
					break;
				}
				p += len;
			}
			for (p = p0, i = 0; i < RTAX_MAX; i++) {
				if ((RTA_MASKS & ifam->ifam_addrs & (1 << i))
				    == 0)
					continue;
				sa = (struct sockaddr *)(void *)p;
				len = SA_RLEN(sa);
				if (i == RTAX_NETMASK && SA_LEN(sa) == 0)
					dcnt += alen;
				else
					dcnt += len;
				p += len;
			}
			break;
		}
	}
#else	/* NET_RT_IFLIST */
	ifc.ifc_buf = buf;
	ifc.ifc_len = sizeof(buf);

	if ((sock = _socket(AF_INET, SOCK_STREAM, 0)) < 0)
		return (-1);
	i =  _ioctl(sock, SIOCGIFCONF, (char *)&ifc);
	_close(sock);
	if (i < 0)
		return (-1);

	ifr = ifc.ifc_req;
	lifr = (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len];

	while (ifr < lifr) {
		struct sockaddr *sa;

		sa = &ifr->ifr_addr;
		++icnt;
		dcnt += SA_RLEN(sa);
		ncnt += sizeof(ifr->ifr_name) + 1;
		
		if (SA_LEN(sa) < sizeof(*sa))
			ifr = (struct ifreq *)(((char *)sa) + sizeof(*sa));
		else
			ifr = (struct ifreq *)(((char *)sa) + SA_LEN(sa));
	}
#endif	/* NET_RT_IFLIST */

	if (icnt + dcnt + ncnt == 1) {
		*pif = NULL;
		free(buf);
		return (0);
	}
	data = malloc(sizeof(struct ifaddrs) * icnt + dcnt + ncnt);
	if (data == NULL) {
		free(buf);
		return(-1);
	}

	ifa = (struct ifaddrs *)(void *)data;
	data += sizeof(struct ifaddrs) * icnt;
	names = data + dcnt;

	memset(ifa, 0, sizeof(struct ifaddrs) * icnt);
	ift = ifa;

#ifdef	NET_RT_IFLIST
	idx = 0;
	for (next = buf; next < buf + needed; next += rtm->rtm_msglen) {
		rtm = (struct rt_msghdr *)(void *)next;
		if (rtm->rtm_version != RTM_VERSION)
			continue;
		switch (rtm->rtm_type) {
		case RTM_IFINFO:
			ifm = (struct if_msghdr *)(void *)rtm;
			if (ifm->ifm_addrs & RTA_IFP) {
				idx = ifm->ifm_index;
				dl = (struct sockaddr_dl *)(void *)(ifm + 1);

				cif = ift;
				ift->ifa_name = names;
				ift->ifa_flags = (int)ifm->ifm_flags;
				memcpy(names, dl->sdl_data,
				    (size_t)dl->sdl_nlen);
				names[dl->sdl_nlen] = 0;
				names += dl->sdl_nlen + 1;

				ift->ifa_addr = (struct sockaddr *)(void *)data;
				memcpy(data, dl,
				    (size_t)SA_LEN((struct sockaddr *)
				    (void *)dl));
				data += SA_RLEN((struct sockaddr *)(void *)dl);

#ifdef	HAVE_IFM_DATA
				/* ifm_data needs to be aligned */
				ift->ifa_data = data = (void *)ALIGN(data);
				memcpy(data, &ifm->ifm_data, sizeof(ifm->ifm_data));
 				data += sizeof(ifm->ifm_data);
#else	/* HAVE_IFM_DATA */
				ift->ifa_data = NULL;
#endif	/* HAVE_IFM_DATA */

				ift = (ift->ifa_next = ift + 1);
			} else
				idx = 0;
			break;

		case RTM_NEWADDR:
			ifam = (struct ifa_msghdr *)(void *)rtm;
			if (idx && ifam->ifam_index != idx)
				abort();	/* this cannot happen */

			if (idx == 0 || (ifam->ifam_addrs & RTA_MASKS) == 0)
				break;
			ift->ifa_name = cif->ifa_name;
			ift->ifa_flags = cif->ifa_flags;
			ift->ifa_data = NULL;
			p = (char *)(void *)(ifam + 1);
			/* Scan to look for length of address */
			alen = 0;
			for (p0 = p, i = 0; i < RTAX_MAX; i++) {
				if ((RTA_MASKS & ifam->ifam_addrs & (1 << i))
				    == 0)
					continue;
				sa = (struct sockaddr *)(void *)p;
				len = SA_RLEN(sa);
				if (i == RTAX_IFA) {
					alen = len;
					break;
				}
				p += len;
			}
			for (p = p0, i = 0; i < RTAX_MAX; i++) {
				if ((RTA_MASKS & ifam->ifam_addrs & (1 << i))
				    == 0)
					continue;
				sa = (struct sockaddr *)(void *)p;
				len = SA_RLEN(sa);
				switch (i) {
				case RTAX_IFA:
					ift->ifa_addr =
					    (struct sockaddr *)(void *)data;
					memcpy(data, p, len);
					data += len;
					break;

				case RTAX_NETMASK:
					ift->ifa_netmask =
					    (struct sockaddr *)(void *)data;
					if (SA_LEN(sa) == 0) {
						memset(data, 0, alen);
						data += alen;
						break;
					}
					memcpy(data, p, len);
					data += len;
					break;

				case RTAX_BRD:
					ift->ifa_broadaddr =
					    (struct sockaddr *)(void *)data;
					memcpy(data, p, len);
					data += len;
					break;
				}
				p += len;
			}

#ifdef	HAVE_IFAM_DATA
			/* ifam_data needs to be aligned */
			ift->ifa_data = data = (void *)ALIGN(data);
			memcpy(data, &ifam->ifam_data, sizeof(ifam->ifam_data));
			data += sizeof(ifam->ifam_data);
#endif	/* HAVE_IFAM_DATA */

			ift = (ift->ifa_next = ift + 1);
			break;
		}
	}

	free(buf);
#else	/* NET_RT_IFLIST */
	ifr = ifc.ifc_req;
	lifr = (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len];

	while (ifr < lifr) {
		struct sockaddr *sa;

		ift->ifa_name = names;
		names[sizeof(ifr->ifr_name)] = 0;
		strncpy(names, ifr->ifr_name, sizeof(ifr->ifr_name));
		while (*names++)
			;

		ift->ifa_addr = (struct sockaddr *)data;
		sa = &ifr->ifr_addr;
		memcpy(data, sa, SA_LEN(sa));
		data += SA_RLEN(sa);
		
		ifr = (struct ifreq *)(((char *)sa) + SA_LEN(sa));
		ift = (ift->ifa_next = ift + 1);
	}
#endif	/* NET_RT_IFLIST */
	if (--ift >= ifa) {
		ift->ifa_next = NULL;
		*pif = ifa;
	} else {
		*pif = NULL;
		free(ifa);
	}
	return (0);
}
/** @brief Filters the socket system call received from the applications. Redirect the calls
 * to the right destination which is either the fins_socket function or sending it to the
 * original corresponding function in the GNU C library
 *  @param domain
 *  @param type
 *  @param protocol
 */
int socket(int domain, int type, int protocol)
{

	/**TODO These static vars are not thread safe
		 * we either find another way to keep tracking or
		 * protect them with multi-processes semaphore
		 */
	// static int numberOfcalls=0;
// Define a locker object to protect the static variable
	static int numberOfSockets=0;
	int retval;
	struct socket *sock;
	int flags;
	int fins_sock;
	char *errormsg;


	/** with the first interception takes place , we initialize the socket channel */
	if (numberOfSockets == 0)
	{
		init_socketChannel();
	}

	PRINT_DEBUG("#Sockets = %d \n",numberOfSockets);
	print_protocol(domain, type, protocol);


	_socket = (int (*)(int domain, int type, int protocol)) dlsym(RTLD_NEXT, "socket");

	errormsg = dlerror();
	if (errormsg != NULL)
	{
		PRINT_DEBUG("\n failed to load the original symbol %s", errormsg);
	}

		if( (domain == AF_UNIX) | (domain == AF_INET6 ) | (domain == AF_NETLINK )
				| (domain == AF_PACKET) )
		{

			retval = _socket(domain, type, protocol);
			return (retval);
		}
		else if ( domain == AF_INET )

		{
			if (type == SOCK_DGRAM ) /** Handle UDP sockets */
				{
				 PRINT_DEBUG("123");

				retval = fins_socket(domain,type, protocol);
					if (retval != -1)
						{
				// TODO lock the locker protect the static variable
						numberOfSockets = numberOfSockets +1;
				// TODO unlock the locker protect the static variable

						}
				return(retval);
				}
			else					/** Handle sockets other than UDP  */
				{
				PRINT_DEBUG("original socket will be called, not a udp socket");
				PRINT_DEBUG("domain = %d,type = %d",domain, type);
				retval = _socket(domain, type, protocol);
				return(retval);
				}

		}

		else
			{
				printf("UNKNOWN SOCKET FAMILY !!!!! \n");
				PRINT_DEBUG("domain = %d,type = %d",domain, type);
				return (-1);
			}

}
Beispiel #27
0
/*
 * sysconf --
 *	get configurable system variables.
 *
 * XXX
 * POSIX 1003.1 (ISO/IEC 9945-1, 4.8.1.3) states that the variable values
 * not change during the lifetime of the calling process.  This would seem
 * to require that any change to system limits kill all running processes.
 * A workaround might be to cache the values when they are first retrieved
 * and then simply return the cached value on subsequent calls.  This is
 * less useful than returning up-to-date values, however.
 */
long
sysconf(int name)
{
	struct rlimit rl;
	size_t len;
	int mib[2], sverrno, value;
	long lvalue, defaultresult;
	const char *path;

	defaultresult = -1;

	switch (name) {
	case _SC_ARG_MAX:
		mib[0] = CTL_KERN;
		mib[1] = KERN_ARGMAX;
		break;
	case _SC_CHILD_MAX:
		if (getrlimit(RLIMIT_NPROC, &rl) != 0)
			return (-1);
		if (rl.rlim_cur == RLIM_INFINITY)
			return (-1);
		if (rl.rlim_cur > LONG_MAX) {
			errno = EOVERFLOW;
			return (-1);
		}
		return ((long)rl.rlim_cur);
	case _SC_CLK_TCK:
		return (CLK_TCK);
	case _SC_NGROUPS_MAX:
		mib[0] = CTL_KERN;
		mib[1] = KERN_NGROUPS;
		break;
	case _SC_OPEN_MAX:
		if (getrlimit(RLIMIT_NOFILE, &rl) != 0)
			return (-1);
		if (rl.rlim_cur == RLIM_INFINITY)
			return (-1);
		if (rl.rlim_cur > LONG_MAX) {
			errno = EOVERFLOW;
			return (-1);
		}
		return ((long)rl.rlim_cur);
	case _SC_STREAM_MAX:
		if (getrlimit(RLIMIT_NOFILE, &rl) != 0)
			return (-1);
		if (rl.rlim_cur == RLIM_INFINITY)
			return (-1);
		if (rl.rlim_cur > LONG_MAX) {
			errno = EOVERFLOW;
			return (-1);
		}
		/*
		 * struct __sFILE currently has a limitation that
		 * file descriptors must fit in a signed short.
		 * This doesn't precisely capture the letter of POSIX
		 * but approximates the spirit.
		 */
		if (rl.rlim_cur > SHRT_MAX)
			return (SHRT_MAX);

		return ((long)rl.rlim_cur);
	case _SC_JOB_CONTROL:
		return (_POSIX_JOB_CONTROL);
	case _SC_SAVED_IDS:
		/* XXX - must be 1 */
		mib[0] = CTL_KERN;
		mib[1] = KERN_SAVED_IDS;
		goto yesno;
	case _SC_VERSION:
		mib[0] = CTL_KERN;
		mib[1] = KERN_POSIX1;
		break;
	case _SC_BC_BASE_MAX:
		return (BC_BASE_MAX);
	case _SC_BC_DIM_MAX:
		return (BC_DIM_MAX);
	case _SC_BC_SCALE_MAX:
		return (BC_SCALE_MAX);
	case _SC_BC_STRING_MAX:
		return (BC_STRING_MAX);
	case _SC_COLL_WEIGHTS_MAX:
		return (COLL_WEIGHTS_MAX);
	case _SC_EXPR_NEST_MAX:
		return (EXPR_NEST_MAX);
	case _SC_LINE_MAX:
		return (LINE_MAX);
	case _SC_RE_DUP_MAX:
		return (RE_DUP_MAX);
	case _SC_2_VERSION:
		/*
		 * This is something of a lie, but it would be silly at
		 * this point to try to deduce this from the contents
		 * of the filesystem.
		 */
		return (_POSIX2_VERSION);
	case _SC_2_C_BIND:
		return (_POSIX2_C_BIND);
	case _SC_2_C_DEV:
		return (_POSIX2_C_DEV);
	case _SC_2_CHAR_TERM:
		return (_POSIX2_CHAR_TERM);
	case _SC_2_FORT_DEV:
		return (_POSIX2_FORT_DEV);
	case _SC_2_FORT_RUN:
		return (_POSIX2_FORT_RUN);
	case _SC_2_LOCALEDEF:
		return (_POSIX2_LOCALEDEF);
	case _SC_2_SW_DEV:
		return (_POSIX2_SW_DEV);
	case _SC_2_UPE:
		return (_POSIX2_UPE);
	case _SC_TZNAME_MAX:
		path = _PATH_ZONEINFO;
do_NAME_MAX:
		sverrno = errno;
		errno = 0;
		lvalue = pathconf(path, _PC_NAME_MAX);
		if (lvalue == -1 && errno != 0)
			return (-1);
		errno = sverrno;
		return (lvalue);

	case _SC_ASYNCHRONOUS_IO:
#if _POSIX_ASYNCHRONOUS_IO == 0
		mib[0] = CTL_P1003_1B;
		mib[1] = CTL_P1003_1B_ASYNCHRONOUS_IO;
		break;
#else
		return (_POSIX_ASYNCHRONOUS_IO);
#endif
	case _SC_MAPPED_FILES:
		return (_POSIX_MAPPED_FILES);
	case _SC_MEMLOCK:
		return (_POSIX_MEMLOCK);
	case _SC_MEMLOCK_RANGE:
		return (_POSIX_MEMLOCK_RANGE);
	case _SC_MEMORY_PROTECTION:
		return (_POSIX_MEMORY_PROTECTION);
	case _SC_MESSAGE_PASSING:
#if _POSIX_MESSAGE_PASSING == 0
		mib[0] = CTL_P1003_1B;
		mib[1] = CTL_P1003_1B_MESSAGE_PASSING;
		goto yesno;
#else
		return (_POSIX_MESSAGE_PASSING);
#endif
	case _SC_PRIORITIZED_IO:
#if _POSIX_PRIORITIZED_IO == 0
		mib[0] = CTL_P1003_1B;
		mib[1] = CTL_P1003_1B_PRIORITIZED_IO;
		goto yesno;
#else
		return (_POSIX_PRIORITIZED_IO);
#endif
	case _SC_PRIORITY_SCHEDULING:
#if _POSIX_PRIORITY_SCHEDULING == 0
		mib[0] = CTL_P1003_1B;
		mib[1] = CTL_P1003_1B_PRIORITY_SCHEDULING;
		goto yesno;
#else
		return (_POSIX_PRIORITY_SCHEDULING);
#endif
	case _SC_REALTIME_SIGNALS:
#if _POSIX_REALTIME_SIGNALS == 0
		mib[0] = CTL_P1003_1B;
		mib[1] = CTL_P1003_1B_REALTIME_SIGNALS;
		goto yesno;
#else
		return (_POSIX_REALTIME_SIGNALS);
#endif
	case _SC_SEMAPHORES:
#if _POSIX_SEMAPHORES == 0
		mib[0] = CTL_P1003_1B;
		mib[1] = CTL_P1003_1B_SEMAPHORES;
		goto yesno;
#else
		return (_POSIX_SEMAPHORES);
#endif
	case _SC_FSYNC:
		return (_POSIX_FSYNC);

	case _SC_SHARED_MEMORY_OBJECTS:
		return (_POSIX_SHARED_MEMORY_OBJECTS);
	case _SC_SYNCHRONIZED_IO:
#if _POSIX_SYNCHRONIZED_IO == 0
		mib[0] = CTL_P1003_1B;
		mib[1] = CTL_P1003_1B_SYNCHRONIZED_IO;
		goto yesno;
#else
		return (_POSIX_SYNCHRONIZED_IO);
#endif
	case _SC_TIMERS:
#if _POSIX_TIMERS == 0
		mib[0] = CTL_P1003_1B;
		mib[1] = CTL_P1003_1B_TIMERS;
		goto yesno;
#else
		return (_POSIX_TIMERS);
#endif
	case _SC_AIO_LISTIO_MAX:
		mib[0] = CTL_P1003_1B;
		mib[1] = CTL_P1003_1B_AIO_LISTIO_MAX;
		break;
	case _SC_AIO_MAX:
		mib[0] = CTL_P1003_1B;
		mib[1] = CTL_P1003_1B_AIO_MAX;
		break;
	case _SC_AIO_PRIO_DELTA_MAX:
		mib[0] = CTL_P1003_1B;
		mib[1] = CTL_P1003_1B_AIO_PRIO_DELTA_MAX;
		break;
	case _SC_DELAYTIMER_MAX:
		mib[0] = CTL_P1003_1B;
		mib[1] = CTL_P1003_1B_DELAYTIMER_MAX;
		goto yesno;
	case _SC_MQ_OPEN_MAX:
		mib[0] = CTL_P1003_1B;
		mib[1] = CTL_P1003_1B_MQ_OPEN_MAX;
		goto yesno;
	case _SC_PAGESIZE:
		defaultresult = getpagesize();
		mib[0] = CTL_P1003_1B;
		mib[1] = CTL_P1003_1B_PAGESIZE;
		goto yesno;
	case _SC_RTSIG_MAX:
		mib[0] = CTL_P1003_1B;
		mib[1] = CTL_P1003_1B_RTSIG_MAX;
		goto yesno;
	case _SC_SEM_NSEMS_MAX:
		mib[0] = CTL_P1003_1B;
		mib[1] = CTL_P1003_1B_SEM_NSEMS_MAX;
		goto yesno;
	case _SC_SEM_VALUE_MAX:
		mib[0] = CTL_P1003_1B;
		mib[1] = CTL_P1003_1B_SEM_VALUE_MAX;
		goto yesno;
	case _SC_SIGQUEUE_MAX:
		mib[0] = CTL_P1003_1B;
		mib[1] = CTL_P1003_1B_SIGQUEUE_MAX;
		goto yesno;
	case _SC_TIMER_MAX:
		mib[0] = CTL_P1003_1B;
		mib[1] = CTL_P1003_1B_TIMER_MAX;
yesno:
		len = sizeof(value);
		if (sysctl(mib, 2, &value, &len, NULL, 0) == -1)
			return (-1);
		if (value == 0)
			return (defaultresult);
		return ((long)value);

	case _SC_2_PBS:
	case _SC_2_PBS_ACCOUNTING:
	case _SC_2_PBS_CHECKPOINT:
	case _SC_2_PBS_LOCATE:
	case _SC_2_PBS_MESSAGE:
	case _SC_2_PBS_TRACK:
#if _POSIX2_PBS == 0
#error "don't know how to determine _SC_2_PBS"
		/*
		 * This probably requires digging through the filesystem
		 * to see if the appropriate package has been installed.
		 * Since we don't currently support this option at all,
		 * it's not worth the effort to write the code now.
		 * Figuring out which of the sub-options are supported
		 * would be even more difficult, so it's probably easier
		 * to always say ``no''.
		 */
#else
		return (_POSIX2_PBS);
#endif
	case _SC_ADVISORY_INFO:
#if _POSIX_ADVISORY_INFO == 0
#error "_POSIX_ADVISORY_INFO"
#else
		return (_POSIX_ADVISORY_INFO);
#endif
	case _SC_BARRIERS:
#if _POSIX_BARRIERS == 0
#error "_POSIX_BARRIERS"
#else
		return (_POSIX_BARRIERS);
#endif
	case _SC_CLOCK_SELECTION:
#if _POSIX_CLOCK_SELECTION == 0
#error "_POSIX_CLOCK_SELECTION"
#else
		return (_POSIX_CLOCK_SELECTION);
#endif
	case _SC_CPUTIME:
		return (_POSIX_CPUTIME);
#ifdef notdef
	case _SC_FILE_LOCKING:
		/*
		 * XXX - The standard doesn't tell us how to define
		 * _POSIX_FILE_LOCKING, so we can't answer this one.
		 */
#endif

	/*
	 * SUSv4tc1 says the following about _SC_GETGR_R_SIZE_MAX and
	 * _SC_GETPW_R_SIZE_MAX:
	 * Note that sysconf(_SC_GETGR_R_SIZE_MAX) may return -1 if
	 * there is no hard limit on the size of the buffer needed to
	 * store all the groups returned.
	 */
	case _SC_GETGR_R_SIZE_MAX:
	case _SC_GETPW_R_SIZE_MAX:
		return (-1);
	case _SC_HOST_NAME_MAX:
		return (MAXHOSTNAMELEN - 1); /* does not include \0 */
	case _SC_LOGIN_NAME_MAX:
		return (MAXLOGNAME);
	case _SC_MONOTONIC_CLOCK:
#if _POSIX_MONOTONIC_CLOCK == 0
#error "_POSIX_MONOTONIC_CLOCK"
#else
		return (_POSIX_MONOTONIC_CLOCK);
#endif
#if _POSIX_MESSAGE_PASSING > -1
	case _SC_MQ_PRIO_MAX:
		return (MQ_PRIO_MAX);
#endif
	case _SC_READER_WRITER_LOCKS:
		return (_POSIX_READER_WRITER_LOCKS);
	case _SC_REGEXP:
		return (_POSIX_REGEXP);
	case _SC_SHELL:
		return (_POSIX_SHELL);
	case _SC_SPAWN:
		return (_POSIX_SPAWN);
	case _SC_SPIN_LOCKS:
		return (_POSIX_SPIN_LOCKS);
	case _SC_SPORADIC_SERVER:
#if _POSIX_SPORADIC_SERVER == 0
#error "_POSIX_SPORADIC_SERVER"
#else
		return (_POSIX_SPORADIC_SERVER);
#endif
	case _SC_THREAD_ATTR_STACKADDR:
		return (_POSIX_THREAD_ATTR_STACKADDR);
	case _SC_THREAD_ATTR_STACKSIZE:
		return (_POSIX_THREAD_ATTR_STACKSIZE);
	case _SC_THREAD_CPUTIME:
		return (_POSIX_THREAD_CPUTIME);
	case _SC_THREAD_DESTRUCTOR_ITERATIONS:
		return (PTHREAD_DESTRUCTOR_ITERATIONS);
	case _SC_THREAD_KEYS_MAX:
		return (PTHREAD_KEYS_MAX);
	case _SC_THREAD_PRIO_INHERIT:
		return (_POSIX_THREAD_PRIO_INHERIT);
	case _SC_THREAD_PRIO_PROTECT:
		return (_POSIX_THREAD_PRIO_PROTECT);
	case _SC_THREAD_PRIORITY_SCHEDULING:
		return (_POSIX_THREAD_PRIORITY_SCHEDULING);
	case _SC_THREAD_PROCESS_SHARED:
		return (_POSIX_THREAD_PROCESS_SHARED);
	case _SC_THREAD_SAFE_FUNCTIONS:
		return (_POSIX_THREAD_SAFE_FUNCTIONS);
	case _SC_THREAD_STACK_MIN:
		return (PTHREAD_STACK_MIN);
	case _SC_THREAD_THREADS_MAX:
		return (PTHREAD_THREADS_MAX); /* XXX wrong type! */
	case _SC_TIMEOUTS:
		return (_POSIX_TIMEOUTS);
	case _SC_THREADS:
		return (_POSIX_THREADS);
	case _SC_TRACE:
#if _POSIX_TRACE == 0
#error "_POSIX_TRACE"
		/* While you're implementing this, also do the ones below. */
#else
		return (_POSIX_TRACE);
#endif
#if _POSIX_TRACE > -1
	case _SC_TRACE_EVENT_FILTER:
		return (_POSIX_TRACE_EVENT_FILTER);
	case _SC_TRACE_INHERIT:
		return (_POSIX_TRACE_INHERIT);
	case _SC_TRACE_LOG:
		return (_POSIX_TRACE_LOG);
#endif
	case _SC_TTY_NAME_MAX:
		path = _PATH_DEV;
		goto do_NAME_MAX;
	case _SC_TYPED_MEMORY_OBJECTS:
#if _POSIX_TYPED_MEMORY_OBJECTS == 0
#error "_POSIX_TYPED_MEMORY_OBJECTS"
#else
		return (_POSIX_TYPED_MEMORY_OBJECTS);
#endif
	case _SC_V6_ILP32_OFF32:
#if _V6_ILP32_OFF32 == 0
		if (sizeof(int) * CHAR_BIT == 32 &&
		    sizeof(int) == sizeof(long) &&
		    sizeof(long) == sizeof(void *) &&
		    sizeof(void *) == sizeof(off_t))
			return 1;
		else
			return -1;
#else
		return (_V6_ILP32_OFF32);
#endif
	case _SC_V6_ILP32_OFFBIG:
#if _V6_ILP32_OFFBIG == 0
		if (sizeof(int) * CHAR_BIT == 32 &&
		    sizeof(int) == sizeof(long) &&
		    sizeof(long) == sizeof(void *) &&
		    sizeof(off_t) * CHAR_BIT >= 64)
			return 1;
		else
			return -1;
#else
		return (_V6_ILP32_OFFBIG);
#endif
	case _SC_V6_LP64_OFF64:
#if _V6_LP64_OFF64 == 0
		if (sizeof(int) * CHAR_BIT == 32 &&
		    sizeof(long) * CHAR_BIT == 64 &&
		    sizeof(long) == sizeof(void *) &&
		    sizeof(void *) == sizeof(off_t))
			return 1;
		else
			return -1;
#else
		return (_V6_LP64_OFF64);
#endif
	case _SC_V6_LPBIG_OFFBIG:
#if _V6_LPBIG_OFFBIG == 0
		if (sizeof(int) * CHAR_BIT >= 32 &&
		    sizeof(long) * CHAR_BIT >= 64 &&
		    sizeof(void *) * CHAR_BIT >= 64 &&
		    sizeof(off_t) * CHAR_BIT >= 64)
			return 1;
		else
			return -1;
#else
		return (_V6_LPBIG_OFFBIG);
#endif
	case _SC_ATEXIT_MAX:
		return (ATEXIT_SIZE);
	case _SC_IOV_MAX:
		mib[0] = CTL_KERN;
		mib[1] = KERN_IOV_MAX;
		break;
	case _SC_XOPEN_CRYPT:
		return (_XOPEN_CRYPT);
	case _SC_XOPEN_ENH_I18N:
		return (_XOPEN_ENH_I18N);
	case _SC_XOPEN_LEGACY:
		return (_XOPEN_LEGACY);
	case _SC_XOPEN_REALTIME:
#if _XOPEN_REALTIME == 0
		sverrno = errno;
		value = sysconf(_SC_ASYNCHRONOUS_IO) > 0 &&
			sysconf(_SC_MEMLOCK) > 0 &&
			sysconf(_SC_MEMLOCK_RANGE) > 0 &&
			sysconf(_SC_MESSAGE_PASSING) > 0 &&
			sysconf(_SC_PRIORITY_SCHEDULING) > 0 &&
			sysconf(_SC_REALTIME_SIGNALS) > 0 &&
			sysconf(_SC_SEMAPHORES) > 0 &&
			sysconf(_SC_SHARED_MEMORY_OBJECTS) > 0 &&
			sysconf(_SC_SYNCHRONIZED_IO) > 0 &&
			sysconf(_SC_TIMERS) > 0;
		errno = sverrno;
		if (value)
			return (200112L);
		else
			return (-1);
#else
		return (_XOPEN_REALTIME);
#endif
	case _SC_XOPEN_REALTIME_THREADS:
#if _XOPEN_REALTIME_THREADS == 0
#error "_XOPEN_REALTIME_THREADS"
#else
		return (_XOPEN_REALTIME_THREADS);
#endif
	case _SC_XOPEN_SHM:
		len = sizeof(lvalue);
		sverrno = errno;
		if (sysctlbyname("kern.ipc.shmmin", &lvalue, &len, NULL,
		    0) == -1) {
			errno = sverrno;
			return (-1);
		}
		errno = sverrno;
		return (1);
	case _SC_XOPEN_STREAMS:
		return (_XOPEN_STREAMS);
	case _SC_XOPEN_UNIX:
		return (_XOPEN_UNIX);
#ifdef _XOPEN_VERSION
	case _SC_XOPEN_VERSION:
		return (_XOPEN_VERSION);
#endif
#ifdef _XOPEN_XCU_VERSION
	case _SC_XOPEN_XCU_VERSION:
		return (_XOPEN_XCU_VERSION);
#endif
	case _SC_SYMLOOP_MAX:
		return (MAXSYMLINKS);
	case _SC_RAW_SOCKETS:
		return (_POSIX_RAW_SOCKETS);
	case _SC_IPV6:
#if _POSIX_IPV6 == 0
		sverrno = errno;
		value = _socket(PF_INET6, SOCK_DGRAM, 0);
		errno = sverrno;
		if (value >= 0) {
			_close(value);
			return (200112L);
		} else
			return (0);
#else
		return (_POSIX_IPV6);
#endif

	case _SC_NPROCESSORS_CONF:
	case _SC_NPROCESSORS_ONLN:
		if (_elf_aux_info(AT_NCPUS, &value, sizeof(value)) == 0)
			return ((long)value);
		mib[0] = CTL_HW;
		mib[1] = HW_NCPU;
		break;

#ifdef _SC_PHYS_PAGES
	case _SC_PHYS_PAGES:
		len = sizeof(lvalue);
		if (sysctlbyname("hw.availpages", &lvalue, &len, NULL, 0) == -1)
			return (-1);
		return (lvalue);
#endif

#ifdef _SC_CPUSET_SIZE
	case _SC_CPUSET_SIZE:
		len = sizeof(value);
		if (sysctlbyname("kern.sched.cpusetsize", &value, &len, NULL,
		    0) == -1)
			return (-1);
		return ((long)value);
#endif

	default:
		errno = EINVAL;
		return (-1);
	}
	len = sizeof(value);
	if (sysctl(mib, 2, &value, &len, NULL, 0) == -1)
		value = -1;
	return ((long)value);
}
Beispiel #28
0
/*
 * rpc_broadcast_exp()
 *
 * prog      - program number
 * vers      - version number
 * proc      - procedure number
 * xargs     - xdr routine for args
 * argsp     - pointer to args
 * xresults  - xdr routine for results
 * resultsp  - pointer to results
 * eachresult - call with each result obtained
 * inittime  - how long to wait initially
 * waittime  - maximum time to wait
 * nettype   - transport type
 */
enum clnt_stat
rpc_broadcast_exp(rpcprog_t prog, rpcvers_t vers, rpcproc_t proc,
    xdrproc_t xargs, caddr_t argsp, xdrproc_t xresults, caddr_t resultsp,
    resultproc_t eachresult, int inittime, int waittime,
    const char *nettype)
{
	enum clnt_stat	stat = RPC_SUCCESS; /* Return status */
	XDR 		xdr_stream; /* XDR stream */
	XDR 		*xdrs = &xdr_stream;
	struct rpc_msg	msg;	/* RPC message */
	struct timeval	t;
	char 		*outbuf = NULL;	/* Broadcast msg buffer */
	char		*inbuf = NULL; /* Reply buf */
	int		inlen;
	u_int 		maxbufsize = 0;
	AUTH 		*sys_auth = authunix_create_default();
	u_int		i;
	void		*handle;
	char		uaddress[1024];	/* A self imposed limit */
	char		*uaddrp = uaddress;
	int 		pmap_reply_flag; /* reply recvd from PORTMAP */
	/* An array of all the suitable broadcast transports */
	struct {
		int fd;		/* File descriptor */
		int af;
		int proto;
		struct netconfig *nconf; /* Netconfig structure */
		u_int asize;	/* Size of the addr buf */
		u_int dsize;	/* Size of the data buf */
		struct sockaddr_storage raddr; /* Remote address */
		broadlist_t nal;
	} fdlist[MAXBCAST];
	struct pollfd pfd[MAXBCAST];
	size_t fdlistno = 0;
	struct r_rpcb_rmtcallargs barg;	/* Remote arguments */
	struct r_rpcb_rmtcallres bres; /* Remote results */
	size_t outlen;
	struct netconfig *nconf;
	int msec;
	int pollretval;
	int fds_found;

#ifdef PORTMAP
	size_t outlen_pmap = 0;
	u_long port;		/* Remote port number */
	int pmap_flag = 0;	/* UDP exists ? */
	char *outbuf_pmap = NULL;
	struct rmtcallargs barg_pmap;	/* Remote arguments */
	struct rmtcallres bres_pmap; /* Remote results */
	u_int udpbufsz = 0;
#endif				/* PORTMAP */

	if (sys_auth == NULL) {
		return (RPC_SYSTEMERROR);
	}
	/*
	 * initialization: create a fd, a broadcast address, and send the
	 * request on the broadcast transport.
	 * Listen on all of them and on replies, call the user supplied
	 * function.
	 */

	if (nettype == NULL)
		nettype = "datagram_n";
	if ((handle = __rpc_setconf(nettype)) == NULL) {
		AUTH_DESTROY(sys_auth);
		return (RPC_UNKNOWNPROTO);
	}
	while ((nconf = __rpc_getconf(handle)) != NULL) {
		int fd;
		struct __rpc_sockinfo si;

		if (nconf->nc_semantics != NC_TPI_CLTS)
			continue;
		if (fdlistno >= MAXBCAST)
			break;	/* No more slots available */
		if (!__rpc_nconf2sockinfo(nconf, &si))
			continue;

		TAILQ_INIT(&fdlist[fdlistno].nal);
		if (__rpc_getbroadifs(si.si_af, si.si_proto, si.si_socktype, 
		    &fdlist[fdlistno].nal) == 0)
			continue;

		fd = _socket(si.si_af, si.si_socktype, si.si_proto);
		if (fd < 0) {
			stat = RPC_CANTSEND;
			continue;
		}
		fdlist[fdlistno].af = si.si_af;
		fdlist[fdlistno].proto = si.si_proto;
		fdlist[fdlistno].fd = fd;
		fdlist[fdlistno].nconf = nconf;
		fdlist[fdlistno].asize = __rpc_get_a_size(si.si_af);
		pfd[fdlistno].events = POLLIN | POLLPRI |
			POLLRDNORM | POLLRDBAND;
		pfd[fdlistno].fd = fdlist[fdlistno].fd = fd;
		fdlist[fdlistno].dsize = __rpc_get_t_size(si.si_af, si.si_proto,
							  0);

		if (maxbufsize <= fdlist[fdlistno].dsize)
			maxbufsize = fdlist[fdlistno].dsize;

#ifdef PORTMAP
		if (si.si_af == AF_INET && si.si_proto == IPPROTO_UDP) {
			udpbufsz = fdlist[fdlistno].dsize;
			if ((outbuf_pmap = malloc(udpbufsz)) == NULL) {
				_close(fd);
				stat = RPC_SYSTEMERROR;
				goto done_broad;
			}
			pmap_flag = 1;
		}
#endif				/* PORTMAP */
		fdlistno++;
	}

	if (fdlistno == 0) {
		if (stat == RPC_SUCCESS)
			stat = RPC_UNKNOWNPROTO;
		goto done_broad;
	}
	if (maxbufsize == 0) {
		if (stat == RPC_SUCCESS)
			stat = RPC_CANTSEND;
		goto done_broad;
	}
	inbuf = malloc(maxbufsize);
	outbuf = malloc(maxbufsize);
	if ((inbuf == NULL) || (outbuf == NULL)) {
		stat = RPC_SYSTEMERROR;
		goto done_broad;
	}

	/* Serialize all the arguments which have to be sent */
	(void) gettimeofday(&t, NULL);
	msg.rm_xid = __RPC_GETXID(&t);
	msg.rm_direction = CALL;
	msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
	msg.rm_call.cb_prog = RPCBPROG;
	msg.rm_call.cb_vers = RPCBVERS;
	msg.rm_call.cb_proc = RPCBPROC_CALLIT;
	barg.prog = prog;
	barg.vers = vers;
	barg.proc = proc;
	barg.args.args_val = argsp;
	barg.xdr_args = xargs;
	bres.addr = uaddrp;
	bres.results.results_val = resultsp;
	bres.xdr_res = xresults;
	msg.rm_call.cb_cred = sys_auth->ah_cred;
	msg.rm_call.cb_verf = sys_auth->ah_verf;
	xdrmem_create(xdrs, outbuf, maxbufsize, XDR_ENCODE);
	if ((!xdr_callmsg(xdrs, &msg)) ||
	    (!xdr_rpcb_rmtcallargs(xdrs,
	    (struct rpcb_rmtcallargs *)(void *)&barg))) {
		stat = RPC_CANTENCODEARGS;
		goto done_broad;
	}
	outlen = xdr_getpos(xdrs);
	xdr_destroy(xdrs);

#ifdef PORTMAP
	/* Prepare the packet for version 2 PORTMAP */
	if (pmap_flag) {
		msg.rm_xid++;	/* One way to distinguish */
		msg.rm_call.cb_prog = PMAPPROG;
		msg.rm_call.cb_vers = PMAPVERS;
		msg.rm_call.cb_proc = PMAPPROC_CALLIT;
		barg_pmap.prog = prog;
		barg_pmap.vers = vers;
		barg_pmap.proc = proc;
		barg_pmap.args_ptr = argsp;
		barg_pmap.xdr_args = xargs;
		bres_pmap.port_ptr = &port;
		bres_pmap.xdr_results = xresults;
		bres_pmap.results_ptr = resultsp;
		xdrmem_create(xdrs, outbuf_pmap, udpbufsz, XDR_ENCODE);
		if ((! xdr_callmsg(xdrs, &msg)) ||
		    (! xdr_rmtcall_args(xdrs, &barg_pmap))) {
			stat = RPC_CANTENCODEARGS;
			goto done_broad;
		}
		outlen_pmap = xdr_getpos(xdrs);
		xdr_destroy(xdrs);
	}
#endif				/* PORTMAP */

	/*
	 * Basic loop: broadcast the packets to transports which
	 * support data packets of size such that one can encode
	 * all the arguments.
	 * Wait a while for response(s).
	 * The response timeout grows larger per iteration.
	 */
	for (msec = inittime; msec <= waittime; msec += msec) {
		struct broadif *bip;

		/* Broadcast all the packets now */
		for (i = 0; i < fdlistno; i++) {
			if (fdlist[i].dsize < outlen) {
				stat = RPC_CANTSEND;
				continue;
			}
			for (bip = TAILQ_FIRST(&fdlist[i].nal); bip != NULL;
			     bip = TAILQ_NEXT(bip, link)) {
				void *addr;

				addr = &bip->broadaddr;

				__rpc_broadenable(fdlist[i].af, fdlist[i].fd,
				    bip);

				/*
				 * Only use version 3 if lowvers is not set
				 */

				if (!__rpc_lowvers)
					if (_sendto(fdlist[i].fd, outbuf,
					    outlen, 0, (struct sockaddr*)addr,
					    (size_t)fdlist[i].asize) !=
					    outlen) {
#ifdef RPC_DEBUG
						perror("sendto");
#endif
						warnx("clnt_bcast: cannot send "
						      "broadcast packet");
						stat = RPC_CANTSEND;
						continue;
					}
#ifdef RPC_DEBUG
				if (!__rpc_lowvers)
					fprintf(stderr, "Broadcast packet sent "
						"for %s\n",
						 fdlist[i].nconf->nc_netid);
#endif
#ifdef PORTMAP
				/*
				 * Send the version 2 packet also
				 * for UDP/IP
				 */
				if (pmap_flag &&
				    fdlist[i].proto == IPPROTO_UDP) {
					if (_sendto(fdlist[i].fd, outbuf_pmap,
					    outlen_pmap, 0, addr,
					    (size_t)fdlist[i].asize) !=
						outlen_pmap) {
						warnx("clnt_bcast: "
						    "Cannot send broadcast packet");
						stat = RPC_CANTSEND;
						continue;
					}
				}
#ifdef RPC_DEBUG
				fprintf(stderr, "PMAP Broadcast packet "
					"sent for %s\n",
					fdlist[i].nconf->nc_netid);
#endif
#endif				/* PORTMAP */
			}
			/* End for sending all packets on this transport */
		}	/* End for sending on all transports */

		if (eachresult == NULL) {
			stat = RPC_SUCCESS;
			goto done_broad;
		}

		/*
		 * Get all the replies from these broadcast requests
		 */
	recv_again:

		switch (pollretval = _poll(pfd, fdlistno, msec)) {
		case 0:		/* timed out */
			stat = RPC_TIMEDOUT;
			continue;
		case -1:	/* some kind of error - we ignore it */
			goto recv_again;
		}		/* end of poll results switch */

		for (i = fds_found = 0;
		     i < fdlistno && fds_found < pollretval; i++) {
			bool_t done = FALSE;

			if (pfd[i].revents == 0)
				continue;
			else if (pfd[i].revents & POLLNVAL) {
				/*
				 * Something bad has happened to this descri-
				 * ptor. We can cause _poll() to ignore
				 * it simply by using a negative fd.  We do that
				 * rather than compacting the pfd[] and fdlist[]
				 * arrays.
				 */
				pfd[i].fd = -1;
				fds_found++;
				continue;
			} else
				fds_found++;
#ifdef RPC_DEBUG
			fprintf(stderr, "response for %s\n",
				fdlist[i].nconf->nc_netid);
#endif
		try_again:
			inlen = _recvfrom(fdlist[i].fd, inbuf, fdlist[i].dsize,
			    0, (struct sockaddr *)(void *)&fdlist[i].raddr,
			    &fdlist[i].asize);
			if (inlen < 0) {
				if (errno == EINTR)
					goto try_again;
				warnx("clnt_bcast: Cannot receive reply to "
					"broadcast");
				stat = RPC_CANTRECV;
				continue;
			}
			if (inlen < sizeof (u_int32_t))
				continue; /* Drop that and go ahead */
			/*
			 * see if reply transaction id matches sent id.
			 * If so, decode the results. If return id is xid + 1
			 * it was a PORTMAP reply
			 */
			if (*((u_int32_t *)(void *)(inbuf)) ==
			    *((u_int32_t *)(void *)(outbuf))) {
				pmap_reply_flag = 0;
				msg.acpted_rply.ar_verf = _null_auth;
				msg.acpted_rply.ar_results.where =
					(caddr_t)(void *)&bres;
				msg.acpted_rply.ar_results.proc =
					(xdrproc_t)xdr_rpcb_rmtcallres;
#ifdef PORTMAP
			} else if (pmap_flag &&
				*((u_int32_t *)(void *)(inbuf)) ==
				*((u_int32_t *)(void *)(outbuf_pmap))) {
				pmap_reply_flag = 1;
				msg.acpted_rply.ar_verf = _null_auth;
				msg.acpted_rply.ar_results.where =
					(caddr_t)(void *)&bres_pmap;
				msg.acpted_rply.ar_results.proc =
					(xdrproc_t)xdr_rmtcallres;
#endif				/* PORTMAP */
			} else
				continue;
			xdrmem_create(xdrs, inbuf, (u_int)inlen, XDR_DECODE);
			if (xdr_replymsg(xdrs, &msg)) {
				if ((msg.rm_reply.rp_stat == MSG_ACCEPTED) &&
				    (msg.acpted_rply.ar_stat == SUCCESS)) {
					struct netbuf taddr, *np;
					struct sockaddr_in *sin;

#ifdef PORTMAP
					if (pmap_flag && pmap_reply_flag) {
						sin = (struct sockaddr_in *)
						    (void *)&fdlist[i].raddr;
						sin->sin_port =
						    htons((u_short)port);
						taddr.len = taddr.maxlen = 
						    fdlist[i].raddr.ss_len;
						taddr.buf = &fdlist[i].raddr;
						done = (*eachresult)(resultsp,
						    &taddr, fdlist[i].nconf);
					} else {
#endif				/* PORTMAP */
#ifdef RPC_DEBUG
						fprintf(stderr, "uaddr %s\n",
						    uaddrp);
#endif
						np = uaddr2taddr(
						    fdlist[i].nconf, uaddrp);
						done = (*eachresult)(resultsp,
						    np, fdlist[i].nconf);
						free(np);
#ifdef PORTMAP
					}
#endif				/* PORTMAP */
				}
				/* otherwise, we just ignore the errors ... */
			}
			/* else some kind of deserialization problem ... */

			xdrs->x_op = XDR_FREE;
			msg.acpted_rply.ar_results.proc = (xdrproc_t) xdr_void;
			(void) xdr_replymsg(xdrs, &msg);
			(void) (*xresults)(xdrs, resultsp);
			XDR_DESTROY(xdrs);
			if (done) {
				stat = RPC_SUCCESS;
				goto done_broad;
			} else {
				goto recv_again;
			}
		}		/* The recv for loop */
	}			/* The giant for loop */

done_broad:
	free(inbuf);
	free(outbuf);
#ifdef PORTMAP
	free(outbuf_pmap);
#endif				/* PORTMAP */
	for (i = 0; i < fdlistno; i++) {
		(void)_close(fdlist[i].fd);
		__rpc_freebroadifs(&fdlist[i].nal);
	}
	AUTH_DESTROY(sys_auth);
	(void) __rpc_endconf(handle);

	return (stat);
}
Beispiel #29
0
int socket_create_udp_client()
{
    return _socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
}
Beispiel #30
0
int freerdp_tcp_connect_multi(char** hostnames, UINT32* ports, int count, int port, int timeout)
{
	int index;
	int sindex;
	int status;
	SOCKET sockfd;
	SOCKET* sockfds;
	HANDLE* events;
	DWORD waitStatus;
	char port_str[16];
	struct addrinfo hints;
	struct addrinfo* addr;
	struct addrinfo* result;
	struct addrinfo** addrs;
	struct addrinfo** results;

	sindex = -1;

	sprintf_s(port_str, sizeof(port_str) - 1, "%u", port);

	sockfds = (SOCKET*) calloc(count, sizeof(SOCKET));
	events = (HANDLE*) calloc(count, sizeof(HANDLE));
	addrs = (struct addrinfo**) calloc(count, sizeof(struct addrinfo*));
	results = (struct addrinfo**) calloc(count, sizeof(struct addrinfo*));

	if (!sockfds || !events || !addrs || !results)
	{
		free(sockfds);
		free(events);
		free(addrs);
		free(results);
		return -1;
	}

	for (index = 0; index < count; index++)
	{
		ZeroMemory(&hints, sizeof(hints));
		hints.ai_family = AF_UNSPEC;
		hints.ai_socktype = SOCK_STREAM;

		if (ports)
			sprintf_s(port_str, sizeof(port_str) - 1, "%u", ports[index]);

		status = getaddrinfo(hostnames[index], port_str, &hints, &result);

		if (status)
		{
			continue;
		}

		addr = result;

		if ((addr->ai_family == AF_INET6) && (addr->ai_next != 0))
		{
			while ((addr = addr->ai_next))
			{
				if (addr->ai_family == AF_INET)
					break;
			}

			if (!addr)
				addr = result;
		}

		sockfds[index] = _socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);

		if (sockfds[index] < 0)
		{
			freeaddrinfo(result);
			sockfds[index] = 0;
			continue;
		}

		addrs[index] = addr;
		results[index] = result;
	}

	for (index = 0; index < count; index++)
	{
		if (!sockfds[index])
			continue;

		sockfd = sockfds[index];
		addr = addrs[index];

		/* set socket in non-blocking mode */

		WSAEventSelect(sockfd, events[index], FD_READ | FD_WRITE | FD_CONNECT | FD_CLOSE);

		/* non-blocking tcp connect */

		status = _connect(sockfd, addr->ai_addr, addr->ai_addrlen);

		if (status >= 0)
		{
			/* connection success */
			break;
		}
	}

	waitStatus = WaitForMultipleObjects(count, events, FALSE, timeout * 1000);

	sindex = waitStatus - WAIT_OBJECT_0;

	for (index = 0; index < count; index++)
	{
		if (!sockfds[index])
			continue;

		sockfd = sockfds[index];

		/* set socket in blocking mode */

		WSAEventSelect(sockfd, NULL, 0);
	}

	if (sindex >= 0)
	{
		sockfd = sockfds[sindex];
	}

	for (index = 0; index < count; index++)
	{
		if (results[index])
			freeaddrinfo(results[index]);
	}

	free(addrs);
	free(results);
	free(sockfds);
	free(events);

	return sockfd;
}