Пример #1
0
static int
is_prefix(const char *in)
{
	char buf[INET6_PREFIXSTRLEN], *sep;

	if (strlen(in) >= INET6_PREFIXSTRLEN)
		return 0;

	strcpy(buf, in);
	sep = strchr(buf, '/');
	if (sep) {
		(*sep) = 0;
		if (!is_int(sep + 1))
			return 0;
	}

	return is_address(buf);
}
Пример #2
0
static int
is_domain(const char *in, int strict)
{
	if (!strict && is_address(in))
		return 1;

	while (*in) {
		int c = eat_realm_label(&in);
		if (c == 0)
			return 0;
		if (*in == 0)
			break;
		else if (*in != '.')
			return 0;
	}

	return 1;
}
Пример #3
0
static void
check_arguments(int line, char *args[], int count, mipv6_conf_item_t *item)
{
	int i;

	for (i = 0; i < count; i++) {
		switch (item->params[i]) {
		case MIPV6_PARAM_T_INT:
			check_argument(is_int(args[i + 1]), "integer", args[0],
				       i, line);
			break;
		case MIPV6_PARAM_T_BOOLEAN:
			check_argument(is_boolean(args[i + 1]), "boolean",
				       args[0], i, line);
			break;
		case MIPV6_PARAM_T_ONOFF:
			check_argument(is_onoff(args[i + 1]), "on/off",
				       args[0], i, line);
			break;
		case MIPV6_PARAM_T_IDENTIFIER:
			check_argument(is_identifier(args[i + 1]), "identifier",
				       args[0], i, line);
			break;
		case MIPV6_PARAM_T_ADDRESS:
			check_argument(is_address(args[i + 1]), "address",
				       args[0], i, line);
			break;
		case MIPV6_PARAM_T_PREFIX:
			check_argument(is_prefix(args[i + 1]), "prefix",
				       args[0], i, line);
			break;
		case MIPV6_PARAM_T_DOMAIN:
			check_argument(is_domain(args[i + 1], 0), "domain name"
				       " or address", args[0], i, line);
			break;
		case MIPV6_PARAM_T_NAI:
			check_argument(is_nai(args[i + 1]), "NAI", args[0], i,
				       line);
			break;
		default:
			break;
		}
	}
}
Пример #4
0
/*
 * getaddrinfo().
 */
int
getaddrinfo(const char *nodename, const char *servname,
    const struct addrinfo *hints, struct addrinfo **res)
{
    struct addrinfo *head_res = NULL;
    struct addrinfo *tail_res = NULL;
    struct addrinfo *new_res;
    struct sockaddr_in *sa_in;
    struct in_addr **addr_list;
    struct in_addr *addr_list_buf[2];
    struct in_addr addr_buf;
    struct in_addr **ap;
    struct servent *servent;
    struct hostent *hostent;
    const char *canonname = NULL;
    in_port_t port;
    int saved_h_errno;
    int result = 0;

#ifdef ENABLE_PTHREAD
    pthread_mutex_lock(&gai_mutex);
#endif

    saved_h_errno = h_errno;

    if (nodename == NULL && servname == NULL) {
	result = EAI_NONAME;
	goto end;
    }

    if (hints != NULL) {
	if (hints->ai_family != PF_INET && hints->ai_family != PF_UNSPEC) {
	    result = EAI_FAMILY;
	    goto end;
	}
	if (hints->ai_socktype != SOCK_DGRAM
	    && hints->ai_socktype != SOCK_STREAM
	    && hints->ai_socktype != 0) {
	    result = EAI_SOCKTYPE;
	    goto end;
	}
    } else {
	hints = &default_hints;
    }

    if (servname != NULL) {
	if (is_integer(servname))
	    port = htons(atoi(servname));
	else  {
	    if (hints->ai_flags & AI_NUMERICSERV) {
		result = EAI_NONAME;
		goto end;
	    }

	    if (hints->ai_socktype == SOCK_DGRAM)
		servent = getservbyname(servname, "udp");
	    else if (hints->ai_socktype == SOCK_STREAM)
		servent = getservbyname(servname, "tcp");
	    else if (hints->ai_socktype == 0)
		servent = getservbyname(servname, "tcp");
	    else {
		result = EAI_SOCKTYPE;
		goto end;
	    }

	    if (servent == NULL) {
		result = EAI_SERVICE;
		goto end;
	    }
	    port = servent->s_port;
	}
    } else {
	port = htons(0);
    }

    if (nodename != NULL) {
	if (is_address(nodename)) {
	    addr_buf.s_addr = inet_addr(nodename);
	    addr_list_buf[0] = &addr_buf;
	    addr_list_buf[1] = NULL;
	    addr_list = addr_list_buf;

	    if (hints->ai_flags & AI_CANONNAME
		&& !(hints->ai_flags & AI_NUMERICHOST)) {
		hostent = gethostbyaddr((char *)&addr_buf,
		    sizeof(struct in_addr), AF_INET);
		if (hostent != NULL)
		    canonname = hostent->h_name;
		else
		    canonname = nodename;
	    }
	} else {
	    if (hints->ai_flags & AI_NUMERICHOST) {
		result = EAI_NONAME;
		goto end;
	    }

	    hostent = gethostbyname(nodename);
	    if (hostent == NULL) {
		switch (h_errno) {
		case HOST_NOT_FOUND:
		case NO_DATA:
		    result = EAI_NONAME;
		    goto end;
		case TRY_AGAIN:
		    result = EAI_AGAIN;
		    goto end;
		default:
		    result = EAI_FAIL;
		    goto end;
                }
	    }
	    addr_list = (struct in_addr **)hostent->h_addr_list;

	    if (hints->ai_flags & AI_CANONNAME)
		canonname = hostent->h_name;
	}
    } else {
	if (hints->ai_flags & AI_PASSIVE)
	    addr_buf.s_addr = htonl(INADDR_ANY);
	else
	    addr_buf.s_addr = htonl(0x7F000001);
	addr_list_buf[0] = &addr_buf;
	addr_list_buf[1] = NULL;
	addr_list = addr_list_buf;
    }

    for (ap = addr_list; *ap != NULL; ap++) {
	new_res = (struct addrinfo *)malloc(sizeof(struct addrinfo));
	if (new_res == NULL) {
	    if (head_res != NULL)
		freeaddrinfo(head_res);
	    result = EAI_MEMORY;
	    goto end;
	}

	new_res->ai_family = PF_INET;
	new_res->ai_socktype = hints->ai_socktype;
	new_res->ai_protocol = hints->ai_protocol;
	new_res->ai_addr = NULL;
	new_res->ai_addrlen = sizeof(struct sockaddr_in);
	new_res->ai_canonname = NULL;
	new_res->ai_next = NULL;

	new_res->ai_addr = (struct sockaddr *)
	    malloc(sizeof(struct sockaddr_in));
	if (new_res->ai_addr == NULL) {
	    free(new_res);
	    if (head_res != NULL)
		freeaddrinfo(head_res);
	    result = EAI_MEMORY;
	    goto end;
	}

	sa_in = (struct sockaddr_in *)new_res->ai_addr;
	memset(sa_in, 0, sizeof(struct sockaddr_in));
	sa_in->sin_family = PF_INET;
	sa_in->sin_port = port;
	memcpy(&sa_in->sin_addr, *ap, sizeof(struct in_addr));

	if (head_res == NULL)
	    head_res = new_res;
	else
	    tail_res->ai_next = new_res;
	tail_res = new_res;
    }

    if (canonname != NULL && head_res != NULL) {
	head_res->ai_canonname = (char *)malloc(strlen(canonname) + 1);
	if (head_res->ai_canonname != NULL)
	    strcpy(head_res->ai_canonname, canonname);
    }

    *res = head_res;

  end:
#ifndef WINSOCK
    h_errno = saved_h_errno;
#else
    WSASetLastError(saved_h_errno);
#endif
#ifdef ENABLE_PTHREAD
    pthread_mutex_unlock(&gai_mutex);
#endif
    return result;
}