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

📄 dns_client.c

📁 DNS 的实现代码
💻 C
📖 第 1 页 / 共 4 页
字号:
     */    if ((tok = strchr(tmp, ' ')) == NULL) {        if ( 0 == strcmp(tmp, "show") )            dns_list_cache();        else            printf("%s\n", CACHESTR);        return FALSE;    }    *tok++ = '\0';    if ( 0 == strcmp(tmp, "show") ) {        printf("%s\n", CACHESTR);        return FALSE;    }    /* see if the command was "flush".  if so we expect another argument.     * if the argument is all the entire cache is flushed, if not the argument     * is either a host name or an IP address     */    if ( 0 == strcmp(tmp, "flush") ) {        if ((tmp = strchr(tok, ' ')) != NULL) {            printf("too many arguments to flush command\n");            return FALSE;        }        if ( 0 == strcmp(tok, "all") )            dns_flush_resolver_cache();        else {            struct sockaddr_storage ip;            if (ipstring2sockaddr(tok, &ip) == NULL)                dns_flush_resolver_entry(tok);            else            {                if (ip.__ss_family == AF_INET)                    dns_flush_resolver_entry_ip(                        ((struct sockaddr_in *)&ip)->sin_addr.s_addr);                else                    dns_flush_resolver_entry_ip6(                        &((struct sockaddr_in6 *)&ip)->sin6_addr);            }        }    }    else        printf("%s\n", CACHESTR);    return FALSE;}   /* end cmd_cache() */#ifdef DNS_DEBUGstatic BOOLcmd_pool_stats(PTR context, const char *cmdstr){    UNUSED(context);    UNUSED(cmdstr);    print_resource_pool();    return FALSE;}static BOOLcmd_toggle(PTR context, const char *cmdstr){    UNUSED(context);    UNUSED(cmdstr);    if ( ++dns_verbosity > 2 )        dns_verbosity = 0;    printf("verbosity level = %d\n", dns_verbosity);    return FALSE;}#endif/* * config_reset() * * this routine will read in the config information from the config file. and * set the current domain data to what's in the config file.  note that this could * zero the current data. */static voidconfig_reset(){    char  *tok, buffer[CONFIGBUFFER];    FILE  *fptr;    /*     * first construct the config file name.  the file is named "//isfs/init"     * concatenated with the name of the process.     */    strcpy(buffer, CONFIGFILE);    strcat(buffer, atmos_pcb_current_get_name());    /*     * open the file for reading.  we have a large buffer size because the     * domain names can potentially be just under 255 characters and we can have     * up to MAXDNSRCH of them.     */    if ((fptr = fopen(buffer, "r")) != NULL ) {        memset(buffer, 0, sizeof(buffer));        /*         * fgets() reads up to the number bytes asked for or a newline or         * end of file marker.  the first line should be the search list.         */        if ( fgets(buffer, sizeof(buffer) - 1, fptr) == NULL ) {            printf("dns_client: search list, error resetting config data\n");            fclose(fptr);            return;        }        if ((tok = strstr(buffer, CNG_SEARCH)) == NULL) {            printf("dns_client: error, config string %s bad\n", buffer);            fclose(fptr);            return;        }        buffer[strlen(buffer)-1] = '\0';   /* lose the newline */        tok = buffer + strlen(CNG_SEARCH);        dnsdomain.num_search = 0;          /* zero out the current search list */        cmd_search_list(NULL, tok);        /* now get the name server list */        dnsdomain.num_svr = 0;             /* zero the nameserver list */        while ((fgets(buffer, sizeof(buffer) - 1, fptr)) != NULL) {            buffer[strlen(buffer)-1] = '\0';   /* loose the newline */            if ((tok = strstr(buffer, CNG_NS)) == NULL) {        printf("dns_client: error, config string %s bad\n", buffer);        fclose(fptr);        return;            }            tok = buffer + strlen(CNG_NS);            cmd_ns_list(NULL, tok);        }        fclose(fptr);    }    else {        printf("could not open config file\n");    }}   /* end config_reset() *//* * config_save() * * this routine will write the current config data to the config file.  its * possible for there to be no data. */static voidconfig_save(){    int   i;    char  ipstr[INET6_ADDRSTRLEN];    FILE  *fptr = CreateConfigFile(atmos_pcb_current_get_name());    if ( NULL != fptr ) {        fprintf(fptr, "search ");        for ( i = 0; i < (dnsdomain.num_search - 1); i++ )            fprintf(fptr, "%s ", dnsdomain.search[i]);        if ( dnsdomain.num_search > 0 )            fprintf(fptr, "%s", dnsdomain.search[dnsdomain.num_search - 1]);        fprintf(fptr, "\n");        for ( i = 0; i < dnsdomain.num_svr; i++ ) {            ip_string(&dnsdomain.nsaddr[i], ipstr, sizeof(ipstr));            fprintf(fptr, "nameserver %s\n", ipstr);        }        fclose(fptr);    }}   /* end config_save() *//* * config_print() * * this routine will print out the config information.  we just make use * of the cmd_show() routine that prints the current information. */static voidconfig_print(int detail){    UNUSED(detail);    cmd_show(NULL, NULL);}   /* end config_print() *//* * ns_list_delete() * * this routine will delete an IP address from the default nameserver list if * the address is present in the list. */static voidns_list_delete(struct sockaddr_storage *ip){    struct sockaddr_storage iplist[MAXNS];    int  i, j, match = 0;    DNSC_DEBUG("entry\n");    if ( 0 == dnsdomain.num_svr )     /* nothing in the list */    {        DNSC_DEBUG("exit - nothing in the list\n");        return;    }    DNSC_DEBUG("Address to delete: (%d) %s\n",               ((struct sockaddr *)ip)->sa_family, dns_client_inetaddr(ip));    DNSC_DEBUG("number of servers in the list = %d\n", dnsdomain.num_svr);    for ( i = 0, j = 0; i < dnsdomain.num_svr; i++ ) {        if (!SOCKEQUAL(&dnsdomain.nsaddr[i], ip))        {            DNSC_DEBUG("Address in the list: (%d) %s\n",                       ((struct sockaddr *)&dnsdomain.nsaddr[i])->sa_family,                       dns_client_inetaddr(&dnsdomain.nsaddr[i]));            memcpy(&iplist[j++], &dnsdomain.nsaddr[i],                   sizeof(struct sockaddr_storage));        }        else        {            DNSC_DEBUG("find match\n");            match = 1;        }    }    if ( match == 1 ) {        dnsdomain.num_svr--;        for ( i = 0; i < dnsdomain.num_svr; i++ )            memcpy(&dnsdomain.nsaddr[i], &iplist[i],                   sizeof(struct sockaddr_storage));    }    DNSC_DEBUG("exit\n");}   /* end ns_list_delete() *//* * string_cleanup() * * this routine will strip tabs from the input string.  it removes leading * spaces and trailing spaces. */static char *string_cleanup(const char *string){    char  *tok, *end;    tok = (char *)string;    end = (char *)&string[strlen(string)-1];    while ( *tok != '\0' ) {        if ( *tok == '\t' )            *tok = ' ';        tok++;    }    while ( *end == ' ' && *end != '\0' )        end--;    *++end = '\0';    tok = (char *)string;    while ( *tok == ' ' && *tok != '\0' )        tok++;    return tok;}   /* end string_cleanup() *//* * ipstring2long() * * convert an IP in the form of a string to a long. */U32ipstring2long(const char *ipstr){    int  ip[4];    int  matches;    U32  tmp;    U8   *p = (U8 *)&tmp;    if ( validate_ipaddr_str(ipstr) != 0 )        return (U32 )-1;    matches = sscanf(ipstr, "%u.%u.%u.%u", &ip[0], &ip[1], &ip[2], &ip[3]);    if ( matches != 4 )        return (U32 )-1;    else {        p[0] = ip[0];        p[1] = ip[1];        p[2] = ip[2];        p[3] = ip[3];        return tmp;    }}   /* end ipstring2long() *//* ipstring2sockaddr -- *     Converts an IP in the form of a string to a sockaddr_storage. *     Here it is assumed an IPv6 address must contain a colon, while *     IPv4 address CANNOT contain a colon. * * PARAMETERS *     ipstr  - source string with address *     dest   - destination sockaddr_storage structure * * RETURNS *     dest  on success, *     NULL  on failure */static struct sockaddr_storage *ipstring2sockaddr(IN const char *ipStr, OUT struct sockaddr_storage *dest){    /* for AF_INET6 there must be at least one colon */    if (strstr(ipStr, COLON) == NULL)    {        struct in_addr addr;        /* try AF_INET */        if (inet_pton(AF_INET, ipStr, &addr) <= 0)            return NULL;        else        {            struct sockaddr_in *tmp = (struct sockaddr_in *)dest;            memset(tmp, 0, sizeof(struct sockaddr_storage));            tmp->sin_family = AF_INET;            memcpy(&tmp->sin_addr, &addr, sizeof(addr));            return dest;        }    }    else    {        struct in6_addr addr;        /* try AF_INET6 */        if (inet_pton(AF_INET6, ipStr, &addr) <= 0)            return NULL;        else        {            struct sockaddr_in6 *tmp = (struct sockaddr_in6 *)dest;            memset(tmp, 0, sizeof(struct sockaddr_storage));            tmp->sin6_family = AF_INET6;            memcpy(&tmp->sin6_addr, &addr, sizeof(addr));            return dest;        }    }}/* * validate_ipaddr_str() * * we want to validate IP address string coming from the command line.  this * routine will check for some simple things to verify that the user didn't * make any obvious mistakes. * * return:  0 if valid, and *         -1 if not. */static intvalidate_ipaddr_str(const char *ipstr){    char  *tok, *dup, ipdup[MAXIPSTRLEN+1];    int   cnt = 0;    if ( strlen(ipstr) > MAXIPSTRLEN )        return -1;    strcpy(ipdup, ipstr);    dup = ipdup;    while ((tok = strchr(dup, '.')) != NULL) {        cnt++;        *tok++ = '\0';        if ( dns_ipsection_test(dup) < 0 )            return -1;        dup = tok;    }    if ( cnt > 3 || dns_ipsection_test(dup) < 0 )   /* check the last section */        return -1;    return 0;}   /* end validate_ipaddr_str() *//* * dns_ipsection_test() * * this routine will test a section of an IP address string.  that is if * the string is 111.222.33.45 then 222 would be a section.  the string is * expected to be NULL terminated. * * return:  0 if its a valid section, or *         -1 if it isn't. */static intdns_ipsection_test(const char *ipsec){    char  num[4];    int   len, cnt = 0;    len = strlen(ipsec);    if ( len > MAXIPSECTION || len <= 0 )        return -1;    memset(num, 0, sizeof(num));    while ( *ipsec != '\0' ) {        if ( !isdigit(*ipsec) )            return -1;        num[cnt++] = *ipsec++;    }

⌨️ 快捷键说明

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