static int32_t Shell_ipconfig_dns (uint32_t enet_device, uint32_t index, int32_t argc, char *argv[]) { uint32_t i; bool res; #if RTCSCFG_ENABLE_IP4 _ip_address dns_addr; #endif #if RTCSCFG_ENABLE_IP6 in6_addr dns6_addr; #endif if (argc > ++index) { if (strcmp (argv[index], "add") == 0) { if (argc > ++index) { #if RTCSCFG_ENABLE_IP4 if(inet_pton(AF_INET, argv[index], &dns_addr, sizeof(dns_addr)) == RTCS_OK) { res = ipcfg_add_dns_ip(enet_device, dns_addr); } else #endif #if RTCSCFG_ENABLE_IP6 if(inet_pton(AF_INET6, argv[index], &dns6_addr, sizeof(dns6_addr)) == RTCS_OK) { res = ipcfg6_add_dns_ip(enet_device, &dns6_addr); } else #endif { printf ("Error in dns command, invalid ip address!\n"); return SHELL_EXIT_ERROR; } if(res == TRUE) { printf ("Add dns ip successful.\n"); } else { printf ("Add dns ip failed!\n"); return SHELL_EXIT_ERROR; } } else { printf ("Error in dns command, missing ip parameter!\n"); return SHELL_EXIT_ERROR; } } else if (strcmp (argv[index], "del") == 0) { if (argc > ++index) { #if RTCSCFG_ENABLE_IP4 if(inet_pton(AF_INET, argv[index], &dns_addr, sizeof(dns_addr)) == RTCS_OK) { res = ipcfg_del_dns_ip(enet_device, dns_addr); } else #endif #if RTCSCFG_ENABLE_IP6 if(inet_pton(AF_INET6, argv[index], &dns6_addr, sizeof(dns6_addr)) == RTCS_OK) { res = ipcfg6_del_dns_ip(enet_device, &dns6_addr); } else #endif { printf ("Error in dns command, invalid ip address!\n"); return SHELL_EXIT_ERROR; } if(res == TRUE) { printf ("Del dns ip successful.\n"); } else { printf ("Del dns ip failed!\n"); return SHELL_EXIT_ERROR; } } else { printf ("Error in dns command, missing ip parameter!\n"); return SHELL_EXIT_ERROR; } } else { printf ("Error in dns command, unknown parameter!\n"); return SHELL_EXIT_ERROR; } } else { char addr_str[RTCS_IP_ADDR_STR_SIZE]; int i; sockaddr dns_server; /* Print server address list.*/ for(i=0;; i++) { if(DNSCLN_get_dns_addr(ipcfg_get_ihandle(enet_device), i, &dns_server) == TRUE) { printf ("[%d] %s\n", i + 1, inet_ntop(dns_server.sa_family, &RTCS_SOCKADDR_ADDR(&dns_server), addr_str, sizeof(addr_str))); } else { break; } } } return SHELL_EXIT_SUCCESS; }
/************************************************************************ * NAME: add_ip * RETURNS: 0 if OK. * DESCRIPTION: Try to Resolve IP address using DNS Client. *************************************************************************/ static int add_ip(int family, const char *hostname, int flags, struct addrinfo **aip, int socktype, int port) { struct addrinfo *ai; int result; char *ip_loop; _mem_size ip_length; DNSCLN_TYPE dns_type; DNSCLN_RECORD_STRUCT *dns_record_list = NULL; DNSCLN_PARAM_STRUCT dns_params; int i; #if RTCSCFG_ENABLE_IP4 if(family == AF_INET) { ip_loop = v4_loop; ip_length = sizeof(in_addr); dns_type = DNSCLN_TYPE_A; } else #endif #if RTCSCFG_ENABLE_IP6 if(family == AF_INET6) { ip_loop = v6_loop; ip_length = sizeof(in6_addr); dns_type = DNSCLN_TYPE_AAAA; } else #endif {}; if (hostname == NULL && (flags & AI_PASSIVE) == 0) { /* In this case to get connection * inside host using LOOPBACK interface . */ ai = ai_clone(*aip, AF_INET); if (ai == NULL) { freeaddrinfo(*aip); GAI_EXIT(EAI_MEMORY); } *aip = ai; ai->ai_socktype = socktype; SIN(ai->ai_addr)->sin_port = port; _mem_copy(ip_loop, &SIN(ai->ai_addr)->sin_addr, ip_length); result = EAI_OK; } else { /* If the hostname is not NULL,lets try to resolve it * here we are using RTCS DNS Client to get addr by name. */ for(i=0; (DNSCLN_get_dns_addr(NULL, i, &dns_params.dns_server) == TRUE); i++) { dns_params.name_to_resolve = (char*)hostname; /* Host name to resolve (null-terminated string). */ dns_params.type = dns_type; /* DNS Resource Record Type that is queried. */ /* Send DNS Query.*/ dns_record_list = DNSCLN_query(&dns_params); /* Process DNS result.*/ if(dns_record_list) { /* Resolved.*/ DNSCLN_RECORD_STRUCT *dns_record = dns_record_list; do { ai = ai_clone(*aip, family); if (ai == NULL) { freeaddrinfo(*aip); GAI_EXIT(EAI_MEMORY); } *aip = ai; ai->ai_socktype = socktype; ((struct sockaddr_in *)(ai->ai_addr))->sin_port = port; /* Special case for AF_INET. From network to host endian.*/ if(family == AF_INET) { ((struct sockaddr_in *)(ai->ai_addr))->sin_addr.s_addr = mqx_ntohl(dns_record->data); } else _mem_copy(dns_record->data, &((struct sockaddr_in *)(ai->ai_addr))->sin_addr, ip_length); if (flags & AI_CANONNAME) { if(dns_record->name) { ai->ai_canonname = strdup(dns_record->name); if (ai->ai_canonname == NULL) { GAI_EXIT(EAI_NONAME); } } } dns_record = dns_record->next; } while(dns_record); GAI_EXIT(EAI_OK); } } /* Not resolved.*/ GAI_EXIT(EAI_FAIL); }/* end of (hostname == NULL && (flags & AI_PASSIVE) == 0) */ cleanup: if(dns_record_list) DNSCLN_record_list_free(dns_record_list); return (result); }
/*FUNCTION*------------------------------------------------------------- * * Function Name : getnameinfo() * Returned Value : RTCS_OK or error code * Comment: Name resolution can be by the Domain Name System (DNS), * a local hosts file, or by other naming mechanisms. *END*-----------------------------------------------------------------*/ int32_t getnameinfo( const struct sockaddr *sa, unsigned int salen, char *host, unsigned int hostlen, char *serv, unsigned int servlen, int flags) { unsigned short port; int family; unsigned int socklen; int i; const void *addr; char numserv[sizeof("65000")]; char numaddr[RTCS_IP6_ADDR_STR_SIZE + RTCS_SCOPEID_STR_SIZE]; int result; const char *host_name = NULL; DNSCLN_RECORD_STRUCT *dns_record_list = NULL; DNSCLN_PARAM_STRUCT dns_params; if (sa == NULL) { ENI_EXIT(EAI_BADFLAGS); } family = sa->sa_family; switch (family) { case AF_INET: port = ((const struct sockaddr_in *)sa)->sin_port; addr = &((const struct sockaddr_in *)sa)->sin_addr.s_addr; socklen = sizeof(struct sockaddr_in); break; case AF_INET6: port = ((const struct sockaddr_in6 *)sa)->sin6_port; addr = ((const struct sockaddr_in6 *)sa)->sin6_addr.s6_addr; socklen = sizeof(struct sockaddr_in6); break; default: ENI_EXIT(EAI_FAMILY); } if (salen != socklen) { ENI_EXIT(EAI_FAMILY); } /* Port number.*/ #if 0 /*We do not support getservbyport function */ proto = (flags & NI_DGRAM) ? "udp" : "tcp"; #endif if((serv == NULL) || (servlen == 0)) { /* Caller does not want service. */ } else #if 0 /*We do not support getservbyport function */ if ((flags & NI_NUMERICSERV) != 0 ||(sp = getservbyport(port, proto)) == NULL) #endif { snprintf(numserv, sizeof(numserv), "%d", ntohs(port)); if ((strlen(numserv) + 1) > servlen) { ENI_EXIT(EAI_MEMORY); } strcpy(serv, numserv); } #if 0 /*We do not support getservbyport function */ else { if ((strlen(sp->s_name) + 1) > servlen) { ENI_EXIT(EAI_MEMORY); } strcpy(serv, sp->s_name); } #endif if((host == NULL) || (hostlen == 0)) { ENI_EXIT(EAI_BADFLAGS); } else if(flags & NI_NUMERICHOST) /* Numeric.*/ { /* If NI_NUMERICHOST set, then the numeric form of the hostname is returned. * (When not set, this will still happen in case the node's name cannot be determined.) */ NUMERICHOST: if (inet_ntop(family, addr, numaddr, sizeof(numaddr)) == NULL) { ENI_EXIT(EAI_SYSTEM); } /* Scope ID.*/ if ((family == AF_INET6) && ((const struct sockaddr_in6 *)sa)->sin6_scope_id) { char *p = numaddr + strlen(numaddr); sprintf(p,"%%%u",((const struct sockaddr_in6 *)sa)->sin6_scope_id); } if ((strlen(numaddr) + 1) > hostlen) { ENI_EXIT(EAI_MEMORY); } strcpy(host, numaddr); } else /* Host name */ { if( (host_name = RTCS_hosts_get_name(sa)) == NULL) /* Check Local Hosts table.*/ { /* Resolve address using DNS */ char addr_str[sizeof("0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa")]; unsigned char *addr_ptr; /* Prepare request.*/ if(family == AF_INET) { _ip_address ip4_addr = htonl(((sockaddr_in*)sa)->sin_addr.s_addr); addr_ptr = (unsigned char *)&ip4_addr; snprintf(addr_str, sizeof(addr_str), "%ld.%ld.%ld.%ld.in-addr.arpa", (uint32_t)addr_ptr[3], (uint32_t)addr_ptr[2], (uint32_t)addr_ptr[1], (uint32_t)addr_ptr[0]); } else /* AF_INET6 */ { addr_ptr = (unsigned char *)&(((sockaddr_in6*)sa)->sin6_addr.s6_addr); snprintf(addr_str, sizeof(addr_str), "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa", addr_ptr[15]&0xf, (addr_ptr[15]>>4)&0xf, addr_ptr[14]&0xf, (addr_ptr[14]>>4)&0xf, addr_ptr[13]&0xf, (addr_ptr[13]>>4)&0xf, addr_ptr[12]&0xf, (addr_ptr[12]>>4)&0xf, addr_ptr[11]&0xf, (addr_ptr[11]>>4)&0xf, addr_ptr[10]&0xf, (addr_ptr[10]>>4)&0xf, addr_ptr[9]&0xf, (addr_ptr[9]>>4)&0xf, addr_ptr[8]&0xf, (addr_ptr[8]>>4)&0xf, addr_ptr[7]&0xf, (addr_ptr[7]>>4)&0xf, addr_ptr[6]&0xf, (addr_ptr[6]>>4)&0xf, addr_ptr[5]&0xf, (addr_ptr[5]>>4)&0xf, addr_ptr[4]&0xf, (addr_ptr[4]>>4)&0xf, addr_ptr[3]&0xf, (addr_ptr[3]>>4)&0xf, addr_ptr[2]&0xf, (addr_ptr[2]>>4)&0xf, addr_ptr[1]&0xf, (addr_ptr[1]>>4)&0xf, addr_ptr[0]&0xf, (addr_ptr[0]>>4)&0xf); } dns_params.name_to_resolve = addr_str; /* Address string to resolve (null-terminated string). */ dns_params.type = DNS_RR_TYPE_PTR; /* Domain name pointer is queried. */ /* Get DNS server address.*/ for(i=0; (DNSCLN_get_dns_addr(NULL, i, &dns_params.dns_server) == TRUE); i++) { /* Send DNS Query.*/ dns_record_list = DNSCLN_query(&dns_params); /* Process DNS result.*/ if((dns_record_list != NULL) && (dns_record_list->data_length > 0)) { /* Resolved.*/ dns_record_list->data[dns_record_list->data_length-1] = '\0'; /* Put end of line, just inj case.*/ host_name = dns_record_list->data; break; } } } if(host_name == NULL) { /* NOT resolved.*/ if (flags & NI_NAMEREQD) { /* If NI_NAMEREQD set, then an error is returned if the hostname cannot be determined. */ ENI_EXIT(EAI_NONAME); } else { /* The numeric form of the hostname is returned.*/ goto NUMERICHOST; } } else /* Resolved.*/ { if((strlen(host_name) + 1) > hostlen) { ENI_EXIT(EAI_MEMORY); } strcpy(host, host_name); if (flags & NI_NOFQDN) { /* If NI_NOFQDN set, return only the hostname part of the fully * qualified domain name.*/ char *chr; if ( (chr = strchr(host, '.')) != NULL) { *chr = 0; /* Limit by first dot.*/ } } } }