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);
}
Beispiel #3
0
/*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.*/
				}
            }
        }
    }