Exemple #1
0
/* 
	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;
}
Exemple #2
0
/* 
	Receive data into user's buffer.
	return 
		if the max len has been received 
		if a timeout occures
	In p_recv_len the total number of bytes are returned.
	Note:
		if the recv_len is bigger than 0, no error is returned.
*/
RC_TYPE ip_recv(IP_SOCKET *p_self, char *p_buf, int max_recv_len, int *p_recv_len)
{
	RC_TYPE rc = RC_OK;
	int remaining_buf_len = max_recv_len;
	int total_recv_len = 0;
	int recv_len = 0;

	if (p_self == NULL || p_buf == NULL || p_recv_len == NULL)
	{
		return RC_INVALID_POINTER;
	}

	if (!p_self->initialized)
	{
		return RC_IP_OBJECT_NOT_INITIALIZED;
	}

	while (remaining_buf_len > 0)
	{
		int chunk_size = remaining_buf_len > IP_DEFAULT_READ_CHUNK_SIZE ? 
					IP_DEFAULT_READ_CHUNK_SIZE : remaining_buf_len;
		recv_len = recv(p_self->socket, p_buf + total_recv_len, chunk_size, 0);
		if (recv_len < 0)
		{
			
			{
				DBG_PRINTF((LOG_WARNING, MODULE_TAG "Error 0x%x in recv()\n", os_get_socket_error()));
				rc = RC_IP_RECV_ERROR;
			}
			break;
		}

		if (recv_len == 0)			
		{
			if (total_recv_len == 0)
			{
				rc = RC_IP_RECV_ERROR;				
			}
			break;
		}

		total_recv_len += recv_len;
		remaining_buf_len = max_recv_len - total_recv_len;
	}
	

	*p_recv_len = total_recv_len;
	return rc;
}
Exemple #3
0
int ip_send(ip_sock_t *ip, const char *buf, int len)
{
	ASSERT(ip);

	if (!ip->initialized)
		return RC_IP_OBJECT_NOT_INITIALIZED;

	if (send(ip->socket, buf, len, 0) == -1) {
		int code = os_get_socket_error();

		logit(LOG_WARNING, "Network error while sending query/update: %s", strerror(code));
		return RC_IP_SEND_ERROR;
	}

	return 0;
}
Exemple #4
0
/*
  Receive data into user's buffer.
  return
  if the max len has been received
  if a timeout occures
  In p_recv_len the total number of bytes are returned.
  Note:
  if the recv_len is bigger than 0, no error is returned.
*/
int ip_recv(ip_sock_t *p_self, char *p_buf, int max_recv_len, int *p_recv_len)
{
    int rc = 0;
    int remaining_buf_len = max_recv_len;
    int total_recv_len = 0;
    int recv_len = 0;

    if (p_self == NULL || p_buf == NULL || p_recv_len == NULL) {
        return RC_INVALID_POINTER;
    }

    if (!p_self->initialized) {
        return RC_IP_OBJECT_NOT_INITIALIZED;
    }

    while (remaining_buf_len > 0) {
        int chunk_size =
            remaining_buf_len >
            IP_DEFAULT_READ_CHUNK_SIZE ? IP_DEFAULT_READ_CHUNK_SIZE : remaining_buf_len;

        recv_len = recv(p_self->socket, p_buf + total_recv_len, chunk_size, 0);
        if (recv_len < 0) {
            int code = os_get_socket_error();

            logit(LOG_WARNING, "Network error while waiting for reply: %s", strerror(code));
            rc = RC_IP_RECV_ERROR;
            break;
        }

        if (recv_len == 0) {
            if (total_recv_len == 0) {
                rc = RC_IP_RECV_ERROR;
            }
            break;
        }

        total_recv_len += recv_len;
        remaining_buf_len = max_recv_len - total_recv_len;
    }

    *p_recv_len = total_recv_len;

    return rc;
}
Exemple #5
0
/*
  Receive data into user's buffer.
  return
  if the max len has been received
  if a timeout occures
  In p_recv_len the total number of bytes are returned.
  Note:
  if the recv_len is bigger than 0, no error is returned.
*/
int ip_recv(ip_sock_t *ip, char *buf, int len, int *recv_len)
{
	int rc = 0;
	int remaining_bytes = len;
	int total_bytes = 0;

	ASSERT(ip);
	ASSERT(buf);
	ASSERT(recv_len);

	if (!ip->initialized)
		return RC_IP_OBJECT_NOT_INITIALIZED;

	while (remaining_bytes > 0) {
		int bytes;
		int chunk_size = remaining_bytes > IP_DEFAULT_READ_CHUNK_SIZE
			? IP_DEFAULT_READ_CHUNK_SIZE
			: remaining_bytes;

		bytes = recv(ip->socket, buf + total_bytes, chunk_size, 0);
		if (bytes < 0) {
			int code = os_get_socket_error();

			logit(LOG_WARNING, "Network error while waiting for reply: %s",
			      strerror(code));
			rc = RC_IP_RECV_ERROR;
			break;
		}

		if (bytes == 0) {
			if (total_bytes == 0)
				rc = RC_IP_RECV_ERROR;
			break;
		}

		total_bytes    += bytes;
		remaining_bytes = len - total_bytes;
	}

	*recv_len = total_bytes;

	return rc;
}
Exemple #6
0
int ip_send(ip_sock_t *p_self, const char *p_buf, int len)
{
    if (p_self == NULL) {
        return RC_INVALID_POINTER;
    }

    if (!p_self->initialized) {
        return RC_IP_OBJECT_NOT_INITIALIZED;
    }

    if (send(p_self->socket, (char *)p_buf, len, 0) == -1) {
        int code = os_get_socket_error();

        logit(LOG_WARNING, "Network error while sending query/update: %s", strerror(code));
        return RC_IP_SEND_ERROR;
    }

    return 0;
}
Exemple #7
0
RC_TYPE ip_send(IP_SOCKET *p_self, const char *p_buf, int len)
{
	if (p_self == NULL)
	{
		return RC_INVALID_POINTER;
	}

	if (!p_self->initialized)
	{
		return RC_IP_OBJECT_NOT_INITIALIZED;
	}
	
	if( send(p_self->socket, (char*) p_buf, len, 0) == SOCKET_ERROR )
	{
		DBG_PRINTF((LOG_WARNING,MODULE_TAG "Error 0x%x in send()\n", os_get_socket_error()));
		return RC_IP_SEND_ERROR;
	}
	return RC_OK;
}
Exemple #8
0
/*
	Get the IP address from interface
*/
static RC_TYPE do_ip_check_interface(DYN_DNS_CLIENT *p_self)
{
	struct ifreq ifr;
	in_addr_t new_ip;
	char *new_ip_str;
	int i;

	if (p_self == NULL)
	{
		return RC_INVALID_POINTER;
	}

	if (p_self->check_interface)
	{
		logit(LOG_INFO, MODULE_TAG "Checking for IP# change, querying interface %s",
		      p_self->check_interface);

		int sd = socket(PF_INET, SOCK_DGRAM, 0);

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

			logit(LOG_WARNING, MODULE_TAG "Failed opening network socket: %s", strerror(code));
			return RC_IP_OS_SOCKET_INIT_FAILED;
		}

		memset(&ifr, 0, sizeof(struct ifreq));
		ifr.ifr_addr.sa_family = AF_INET;
		snprintf(ifr.ifr_name, IFNAMSIZ, p_self->check_interface);
		if (ioctl(sd, SIOCGIFADDR, &ifr) != -1)
		{	
			new_ip = ntohl(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr);
			new_ip_str = inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr);
		}
		else
		{
			int code = os_get_socket_error();

			logit(LOG_ERR, MODULE_TAG "Failed reading IP address of interface %s: %s",
			      p_self->check_interface, strerror(code));
			return RC_ERROR;
		}
		close(sd);
	}
	else
	{
		return RC_ERROR;
	}

	if (IN_ZERONET(new_ip) ||
	    IN_LOOPBACK(new_ip) ||
	    IN_LINKLOCAL(new_ip) ||
	    IN_MULTICAST(new_ip) ||
	    IN_EXPERIMENTAL(new_ip))
	{
		logit(LOG_WARNING, MODULE_TAG "Interface %s has invalid IP# %s",
		      p_self->check_interface, new_ip_str);
		return RC_ERROR;
	}

	int anychange = 0;

	for (i = 0; i < p_self->info_count; i++)
	{
		DYNDNS_INFO_TYPE *info = &p_self->info[i];

		info->my_ip_has_changed = strcmp(info->my_ip_address.name, new_ip_str) != 0;
		if (info->my_ip_has_changed)
		{
			anychange++;
			strcpy(info->my_ip_address.name, new_ip_str);
		}
	}

	if (!anychange)
	{
		logit(LOG_INFO, MODULE_TAG "No IP# change detected, still at %s", new_ip_str);
	}

	return RC_OK;
}
Exemple #9
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;
}
Exemple #10
0
/*
  Sets up the object.

  - ...
*/
int tcp_initialize(tcp_sock_t *p_self, char *msg)
{
	int rc;
	struct timeval sv;
	int svlen = sizeof(sv);
	char host[NI_MAXHOST];

	do {
		local_set_params(p_self);

		/*call the super */
		rc = ip_initialize(&p_self->super);
		if (rc != 0) {
			break;
		}

		/* local object initalizations */
		if (p_self->super.type == TYPE_TCP) {
			p_self->super.socket = socket(AF_INET, SOCK_STREAM, 0);
			if (p_self->super.socket == -1) {
				int code = os_get_socket_error();

				logit(LOG_ERR, "Error creating client socket: %s", strerror(code));
				rc = RC_IP_SOCKET_CREATE_ERROR;
				break;
			}

			/* Call to socket() OK, allow tcp_shutdown() to run to
			 * prevent socket leak if any of the below calls fail. */
			p_self->initialized = 1;

			if (p_self->super.bound == 1) {
				if (bind
				    (p_self->super.socket,
				     (struct sockaddr *)&p_self->super.local_addr,
				     sizeof(struct sockaddr_in)) < 0) {
					int code = os_get_socket_error();

					logit(LOG_WARNING,
					      "Failed binding client socket to local address: %s",
					      strerror(code));
					rc = RC_IP_SOCKET_BIND_ERROR;
					break;
				}
			}
		} else {
			p_self->initialized = 1;	/* Allow tcp_shutdown() to run. */
			rc = RC_IP_BAD_PARAMETER;
		}

		/* set timeouts */
		sv.tv_sec = p_self->super.timeout / 1000;	/* msec to sec */
		sv.tv_usec = (p_self->super.timeout % 1000) * 1000;	/* reminder to usec */
		setsockopt(p_self->super.socket, SOL_SOCKET, SO_RCVTIMEO, &sv, svlen);
		setsockopt(p_self->super.socket, SOL_SOCKET, SO_SNDTIMEO, &sv, svlen);

		if (!getnameinfo
		    (&p_self->super.remote_addr, p_self->super.remote_len, host,
		     NI_MAXHOST, NULL, 0, NI_NUMERICHOST)) {
			logit(LOG_INFO, "%s, connecting to %s(%s)", msg,
			      p_self->super.p_remote_host_name, host);
		}

		if (0 != connect(p_self->super.socket, &p_self->super.remote_addr, p_self->super.remote_len)) {
			int code = os_get_socket_error();

			logit(LOG_WARNING, "Failed connecting to remote server: %s", strerror(code));
			rc = RC_IP_CONNECT_FAILED;
			break;
		}
	}
	while (0);

	if (rc != 0) {
		tcp_shutdown(p_self);
		return rc;
	}

	return 0;
}