📄 dns_client.c
字号:
*/ 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 + -