Ejemplo n.º 1
0
Archivo: ip.c Proyecto: ebichu/dd-wrt
/* 
	Sets up the object.
	
	- ...
*/
RC_TYPE ip_initialize(IP_SOCKET *p_self)
{
	RC_TYPE rc = RC_OK; 

	if (p_self->initialized == TRUE)
	{
		return RC_OK;
	}

	do
	{
//		res_init();
		rc = os_ip_support_startup();
		if (rc != RC_OK)
		{
			break;
		}

		/*remote addres */
		if (p_self->p_remote_host_name != NULL)
		{
        		unsigned long addr = 0;
			HOSTENT* p_remotehost = (HOSTENT*) gethostbyname(p_self->p_remote_host_name);
			
			if (p_remotehost == NULL)
			{                
                rc = os_convert_ip_to_inet_addr(&addr, p_self->p_remote_host_name);
                if (rc != RC_OK)
                {
				    DBG_PRINTF((LOG_WARNING,MODULE_TAG "Error '0x%x' resolving host name '%s'\n", 
							    os_get_socket_error(),
							    p_self->p_remote_host_name));
				    rc = RC_IP_INVALID_REMOTE_ADDR;
				    break;
                }
			}
			
			p_self->remote_addr.sin_family = AF_INET;
			p_self->remote_addr.sin_port = htons(p_self->port); 
			p_self->remote_addr.sin_addr.s_addr = (addr == 0) ?
                    *((unsigned long *)p_remotehost->h_addr_list[0]) : addr; 
		}
	}
	while(0);

	if (rc != RC_OK)
	{
		ip_shutdown(p_self);		
	}
	else
	{
		p_self->initialized = TRUE;
	}
			
	return rc;
}
Ejemplo n.º 2
0
/* Sets up the object. */
int ip_init(ip_sock_t *ip)
{
	int rc = 0;
	struct ifreq ifr;
	struct sockaddr_in *addrp = NULL;

	ASSERT(ip);

	if (ip->initialized == 1)
		return 0;

	do {
		TRY(os_ip_support_startup());

		/* local bind, to interface */
		if (ip->ifname) {
			int sd = socket(PF_INET, SOCK_DGRAM, 0);

			if (sd < 0) {
				int code = os_get_socket_error();

				logit(LOG_WARNING, "Failed opening network socket: %s", strerror(code));
				rc = RC_IP_OS_SOCKET_INIT_FAILED;
				break;
			}

			memset(&ifr, 0, sizeof(struct ifreq));
			strlcpy(ifr.ifr_name, ip->ifname, IFNAMSIZ);
			if (ioctl(sd, SIOCGIFADDR, &ifr) != -1) {
				ip->local_addr.sin_family = AF_INET;
				ip->local_addr.sin_port = htons(0);
				addrp = (struct sockaddr_in *)&(ifr.ifr_addr);
				ip->local_addr.sin_addr.s_addr = addrp->sin_addr.s_addr;
				ip->bound = 1;

				logit(LOG_INFO, "Bound to interface %s (IP# %s)",
				      ip->ifname, inet_ntoa(ip->local_addr.sin_addr));
			} else {
				int code = os_get_socket_error();

				logit(LOG_ERR, "Failed reading IP address of interface %s: %s",
				      ip->ifname, strerror(code));
				ip->bound = 0;
			}
			close(sd);
		}

		/* remote address */
		if (ip->p_remote_host_name) {
			int s;
			char port[10];
			struct addrinfo hints, *result;

			/* Clear DNS cache before calling getaddrinfo(). */
			res_init();

			/* Obtain address(es) matching host/port */
			memset(&hints, 0, sizeof(struct addrinfo));
			hints.ai_family = AF_INET;	/* Use AF_UNSPEC to allow IPv4 or IPv6 */
			hints.ai_socktype = SOCK_DGRAM;	/* Datagram socket */
			snprintf(port, sizeof(port), "%d", ip->port);

			s = getaddrinfo(ip->p_remote_host_name, port, &hints, &result);
			if (s != 0 || !result) {
				logit(LOG_WARNING, "Failed resolving hostname %s: %s",
				      ip->p_remote_host_name, gai_strerror(s));
				rc = RC_IP_INVALID_REMOTE_ADDR;
				break;
			}

			/* XXX: Here we should iterate over all of the records returned by
			 * getaddrinfo(), but with this code here in ip.c and connect() being
			 * in tcp.c that's hardly feasible.  Needs refactoring!  --Troglobit */
			ip->remote_addr = *result->ai_addr;
			ip->remote_len = result->ai_addrlen;

			freeaddrinfo(result);	/* No longer needed */
		}
	}
	while (0);

	if (rc) {
		ip_exit(ip);
		return rc;
	}

	ip->initialized = 1;

	return 0;
}