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); }
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; }
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; } } }
/* * 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; }