⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dns_client.c

📁 DNS 的实现代码
💻 C
📖 第 1 页 / 共 4 页
字号:
            foreground_output_end();            break;        case MSG_N_DNS_GET_RR:            DNSC_DEBUG("MSG_N_DNS_GET_RR\n");            dns_XX_query(pmsg, &dnsdomain);  /* reply sent to sender when */            break;             /* the DNS results become available */        case MSG_N_DNS_FLUSH_XX_CACHE: {            MSG_D_DNS_FLUSH_XX_CACHE(dmsg, pmsg);            DNSC_DEBUG("MSG_N_DNS_FLUSH_XX_CACHE\n");            dns_flush_resolver_XX_cache();            dmsg->error = ESUCCESS;            sendreply(pmsg);            break;        }        case MSG_N_DNS_FLUSH_XX_CACHE_BYNAME: {            MSG_D_DNS_FLUSH_XX_CACHE_BYNAME(dmsg, pmsg);            DNSC_DEBUG("MSG_N_DNS_FLUSH_XX_CACHE_BYNAME\n");            dns_flush_resolver_XX_cache_byname(dmsg->dname);            dmsg->error = ESUCCESS;            sendreply(pmsg);            break;        }        default:            /* verify the R flag is not set */            if ( !(pmsg->code & MSG_REPLY_BIT) ) {                sendreply(pmsg);            }            kprintf("%C: received unexpected message code 0x%x\n", pmsg->code);            break;    }#ifdef DNS_DEBUG    foreground_output_end();#endif} /* dns_message_handler *//* * cmd_ns_list() * * this routine will handle the nameserver command.  this command allows a user * to add or delete an IP address from the list of default nameservers.  the * routine will attempt to verify the command and then perform the necessary * action. */static BOOLcmd_ns_list(PTR context, const char *cmdstr){    char  *tmp, *tok, *tok2;    struct sockaddr_storage ip;    int   i;    UNUSED(context);    tmp = string_cleanup(cmdstr);    /* if the string is empty, just print the help string */    if ( 0 == strlen(tmp) ) {        printf("%s\n", NSLISTSTR);        return FALSE;    }    /*     * if the command string only has one argument, it should be an IP     * address.  we verify that, and then make sure there's still room     * to add another nameserver.  if not we print a message warning the     * user.     */    if (NULL == (tok = strchr(tmp, ' '))) {    /* only one argument */        if (ipstring2sockaddr(tmp, &ip) == NULL)        {            printf("%s invalid IP address: %s\n", tmp, NSLISTSTR);        }        else if ( MAXNS <= dnsdomain.num_svr ) {            printf("too many nameservers\n");        }        else {            for ( i = 0; i < dnsdomain.num_svr; i++ ) {                if (SOCKEQUAL(&dnsdomain.nsaddr[i], &ip))                    return FALSE;            }            memcpy(&dnsdomain.nsaddr[dnsdomain.num_svr++], &ip,                   sizeof(ip));        }    }    /*     * else the command string has more than one argument.  it must be     * "delete IP_address".  so, first we see if the first argument is "delete"     * and if not we print a warning and exit.  if it is we verify there is     * only one other argument.  then we verify the second argument is an IP     * address and attempt to remove it from the nameserver list.     */    else {                                /* we have at least two arguments */        *tok++ = '\0';        if ( 0 != strcmp(tmp, "delete") ) {            printf("%s not a valid option: %s\n", tmp, NSLISTSTR);        }        else if (NULL != (tok2 = strchr(tok, ' '))) {            printf("command has too many arguments: %s\n", NSLISTSTR);        }        else if (ipstring2sockaddr(tok, &ip) == NULL) {            printf("%s not a valid IP address: %s\n", tok, NSLISTSTR);        }        else {            ns_list_delete(&ip);        }    }    return FALSE;}   /* end cmd_ns_list() *//* * cmd_search_list() * * this routine handles the search_list command.  this command allows the user * to update or replace the domain name list.  an example of the command is: * * search local1.somedomain.com local2.somedomain.com somedomain.com * * note that the routine does not attempt to ascertain if the strings are valid * domain names, only verify the strings will fit.  a config save is necessary * to save the data to the file system. */static BOOLcmd_search_list(PTR context, const char *cmdstr){    char  *tmp, *tok;    char  list[MAXDNSRCH][NAMEMAX+1];    int   i, cnt = 0;    UNUSED(context);    tmp = string_cleanup(cmdstr);    /* if the string is empty just print the help string */    if ( 0 == strlen(tmp) ) {        printf("%s\n", SEARCHLISTSTR);        return FALSE;    }    /* otherwise get the names out of the list and create our search list     * from them.     */    do {        if (NULL == (tok = strchr(tmp, ' '))) {            if ( strlen(tmp) == 0 )                break;            /* make sure name is valid */            if ( dns_validate_hostname(tmp) < 0 ) {                printf("error: %s is not a valid domain name\n", tmp);        break;            }            if ( !in_current_list(list, tmp, cnt) )        strcpy(list[cnt++], tmp);            break;        }        *tok++ = '\0';        while ( *tok == ' ' && *tok != '\0' )            tok++;        /* make sure name is valid  */        if ( dns_validate_hostname(tmp) < 0 ) {            printf("error: %s is not a valid domain name\n", tmp);            tmp = tok;            continue;        }        if ( !in_current_list(list, tmp, cnt) )            strcpy(list[cnt++], tmp);        tmp = tok;    } while ( tmp != NULL && cnt < MAXDNSRCH );    if ( cnt > 0 ) {        for ( i = 0; i < cnt; i++ )            strcpy(dnsdomain.search[i], list[i]);        dnsdomain.num_search = cnt;    }    return FALSE;}   /* end cmd_search_list() *//* * in_current_list() * * this routine is used by cmd_search_list() to prevent duplicate domain * names in the search list.  it will compare the passed in test string * to all the current elements in the passed in list. * * return:  TRUE if the test string is in the list, or *          FALSE if not. */static BOOLin_current_list(char list[][NAMEMAX+1], char *test, int lcnt){    int  i;    for ( i = 0; i < lcnt; i++ ) {        if ( strcmp(test, list[i]) == 0 )            return TRUE;    }    return FALSE;}   /* end in_current_list() *//* * cmd_show() * * this routine will print the DNS domain config information. */static BOOLcmd_show(PTR context, const char *cmdstr){    char  ipstr[INET6_ADDRSTRLEN];    int   i;    UNUSED(context);    UNUSED(cmdstr);    printf("search ");    for ( i = 0; i < dnsdomain.num_search; i++ )        printf(" %s", dnsdomain.search[i]);    printf("\n");    for ( i = 0; i < dnsdomain.num_svr; i++ ) {        ip_string(&dnsdomain.nsaddr[i], ipstr, sizeof(ipstr));        printf("nameserver %s\n", ipstr);    }    return FALSE;}   /* end cmd_show() *//* * cmd_nslookup() * * this routine handles the nslookup command.  this command allows a user * to acquire the IP address of a host name or the host name given an IP address. * the command works by attempting to determine whether the entered data is a * host name or an IP address.  depending on which we construct the proper message * and send it off to ourself for solution. */static BOOLcmd_nslookup(PTR context, const char *cmdstr){    U32          ip;    char         *tmp;    ATMOS_MQID   qid;    nslook_t     *hp;    UNUSED(context);    tmp = string_cleanup(cmdstr);    if ( strlen(tmp) == 0 ) {        printf("%s\n", NSLOOKUPSTR);        return FALSE;    }    if ((qid = findqueue(atmos_pcb_current_get_name())) == 0) {        printf("%C: error, could not retrieve queue handle\n");        return FALSE;    }    if ((hp = dns_nslkup_alloc()) == NULL) {        printf("%C: error, could not obtain required resources for nslookup.\n");#ifdef DNS_DEBUG        print_resource_pool();#endif    }    else {        hp->hent.h_numaddrs = ENTADDRS;        if ((ip = ipstring2long(tmp)) == (U32 )-1) {            MSG_D_DNS_GET_ADDRBYNAME(dmsg, &hp->amsg);            if ( dns_validate_hostname(tmp) < 0 ) {                printf("%s not a valid host name or IP address.\n", tmp);        dns_nslkup_free(hp);        return FALSE;            }            strcpy(hp->name, tmp);            dmsg->hostname = hp->name;            dmsg->error = 0;            dmsg->use_cache = TRUE;            dmsg->hptr = &hp->hent;            sendmessage(&hp->amsg, MSG_N_DNS_GET_ADDRBYNAME, qid);        }        else {            MSG_D_DNS_GET_HOSTBYADDR(dmsg, &hp->amsg);            dmsg->ipaddr = ip;            dmsg->error = 0;            dmsg->use_cache = TRUE;            dmsg->hptr = &hp->hent;            sendmessage(&hp->amsg, MSG_N_DNS_GET_HOSTBYADDR, qid);        }    }    return FALSE;}   /* end cmd_nslookup() *//* * cmd_nslookup6 -- *     Performs standard or inverse DNS query for IPv6 address. *     If string parameter is a valid IPv6 address inverse *     name resolution is invoked. Otherwise, standard name *     resolution is invoked. * * PARAMETERS *     context - unused *     cmdStr  - command line string */static BOOLcmd_nslookup6(PTR context, const char *cmdStr){    struct sockaddr_storage  ip;    char                    *tmp;    ATMOS_MQID               qid;    nslook_t                *hp;    UNUSED(context);    tmp = string_cleanup(cmdStr);    if ( strlen(tmp) == 0 ) {        printf("%s\n", NSLOOKUPSTR);        return FALSE;    }    if ((qid = findqueue(atmos_pcb_current_get_name())) == 0) {        printf("%C: error, could not retrieve queue handle\n");        return FALSE;    }    if ((hp = dns_nslkup_alloc()) == NULL) {        printf("%C: error, could not obtain required resources for nslookup.\n");#ifdef DNS_DEBUG        print_resource_pool();#endif    }    else {        if (ipstring2sockaddr(tmp, &ip) == NULL) {            MSG_D_DNS_GET_NODEBYNAME(dmsg, &hp->amsg);            if ( dns_validate_hostname(tmp) < 0 ) {                printf("%s not a valid host name or IP address.\n", tmp);        dns_nslkup_free(hp);        return FALSE;            }            if ((hp->hent6 = dns_alloc_struct_hostent()) == NULL)            {                dns_nslkup_free(hp);                return FALSE;            }            if (dns_alloc_hostname(hp->hent6, tmp) == NULL)            {                hp->hent6 = NULL;                dns_nslkup_free(hp);                return FALSE;            }            strcpy(hp->name, tmp);            dmsg->hostname = hp->name;            dmsg->error = 0;            dmsg->hent = hp->hent6;            sendmessage(&hp->amsg, MSG_N_DNS_GET_NODEBYNAME, qid);        }        else {            MSG_D_DNS_GET_HOSTBYADDR6(dmsg, &hp->amsg);            if ((hp->hent6 = dns_alloc_struct_hostent()) == NULL)            {                dns_nslkup_free(hp);                return FALSE;            }            if (dns_alloc_addrlist(hp->hent6, 1, AF_INET6) == NULL)            {                hp->hent6 = NULL;                dns_nslkup_free(hp);                return FALSE;            }            memcpy(hp->hent6->h_addr_list[0],                   &((struct sockaddr_in6 *)&ip)->sin6_addr,                   sizeof(struct in6_addr));            dmsg->addr = (struct in6_addr *)hp->hent6->h_addr_list[0];            dmsg->error = ESUCCESS;            dmsg->hent = hp->hent6;            sendmessage(&hp->amsg, MSG_N_DNS_GET_HOSTBYADDR6, qid);        }    }    return FALSE;}   /* end cmd_nslookup6() *//* * cmd_cache() * * this routine will handle the cache command.  this command allow the user * to "show" what's in the cache, or "flush" elements of the cache.  see the * functional spec for more details. * * pab note: this routine can be used to remove IPv6 addresses as well *           as IPv4 addresses. */static BOOLcmd_cache(PTR context, const char *cmdstr){    char  *tmp, *tok;    UNUSED(context);    tmp = string_cleanup(cmdstr);    /* if the string is empty just print the help string */    if ( 0 == strlen(tmp) ) {        printf("%s\n", CACHESTR);        return FALSE;    }    /*     * the command requires at least one argument, see what that is.  if no     * space then there's only one argument and that has to be "show" or the     * command is invalid.  if there is more than one argument, then "show"     * is not valid.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -