/* Filter vector by command character with index. */ static enum match_type cmd_filter_by_string (char *command, vector v, unsigned int index) { unsigned int i; const char *str; struct cmd_element *cmd_element; enum match_type match_type; vector descvec; struct desc * desc; match_type = no_match; /* If command and cmd_element string does not match set NULL to vector */ for (i = 0; i < vector_active (v); i++) if ((cmd_element = vector_slot (v, i)) != NULL) { /* If given index is bigger than max string vector of command, set NULL */ if (index >= vector_active (cmd_element->strvec)) vector_slot (v, i) = NULL; else { unsigned int j; int matched = 0; descvec = vector_slot (cmd_element->strvec, index); for (j = 0; j < vector_active (descvec); j++) if ((desc = vector_slot (descvec, j))) { str = desc->cmd; if (CMD_VARARG (str)) { if (match_type < vararg_match) match_type = vararg_match; matched++; } else if (CMD_IPV4 (str)) { if (cmd_ipv4_match (command) == exact_match) { if (match_type < ipv4_match) match_type = ipv4_match; matched++; } } else if (CMD_IPV4_PREFIX (str)) { if (cmd_ipv4_prefix_match (command) == exact_match) { if (match_type < ipv4_prefix_match) match_type = ipv4_prefix_match; matched++; } } else if (CMD_OPTION (str) || CMD_VARIABLE (str)) { if (match_type < extend_match) match_type = extend_match; matched++; } else { if (strcmp (command, str) == 0) { match_type = exact_match; matched++; } } } if(!matched) vector_slot(v,i) = NULL; } } return match_type; }
int tracert_opt_parse(char* option, struct tracert_info* tracert_info, char *info) { char* saveptr1 = NULL, *saveptr2 = NULL; char* str1, *str2; char* token, *subtoken; char ch; int j = 0; int flag = 0; //int i = 0; /*设置tracert命令参数的默认值*/ tracert_info->hop = 1; tracert_info->max_hops = 10; tracert_info->wait_time = 3; tracert_info->max_tries = 3; tracert_info->host_addr = NULL; tracert_info->port = TRACE_UDP_PORT; for(str1 = option; ; str1 = NULL) { if(NULL != (token = strtok_r(str1, "-", &saveptr1))) { switch(ch = token[0]) { case ' ': if(NULL != (subtoken = strtok_r(token, " ", &saveptr2))) { //参数如- q 5 这种'-'与'q'之间还有空格隔开的格式错误 sprintf(info, "Parameter format error."); return -1; } break; case 'm'://指定tracert将要探测的最大跳数 if(0 != tracert_parameters_parse('m', token, 255, 1, info, &(tracert_info->max_hops))) { return -1; } break; case 'f'://指定第一个包ttl的的数值 if(0 != tracert_parameters_parse('f', token, 255, 1, info, &(tracert_info->hop))) { return -1; } break; case 'p'://指定端口 if(0 != tracert_parameters_parse('p', token, 65535, 0, info, &(tracert_info->port))) { return -1; } break; case 'q'://指定发送包的数量 if(0 != tracert_parameters_parse('q', token, 65535, 1, info, &(tracert_info->max_tries))) { return -1; } break; case 's'://指定地址发送 for(str2 = token, j = 0; ; j++, str2 = NULL) { if(NULL != (subtoken = strtok_r(str2, " ", &saveptr2))) { if(j == 0) { //适用于当用户输入-q20这种中间没有空格的情况 if(strlen(subtoken) != 1) { //参数超出范围提示 if(exact_match != cmd_ipv4_match(subtoken)) { sprintf(info, "The IP address format is incorrect."); return -1; } tracert_info->host_addr = strdup(subtoken + 1); break; } else { flag = 1; continue; } } if(j == 1) { if(exact_match != cmd_ipv4_match(subtoken)) { sprintf(info, "The IP address format is incorrect."); return -1; } tracert_info->host_addr = strdup(subtoken); continue; } if(j > 1) { sprintf(info, "Parameter format error."); return -1; } break; } else { if((1 == j) && (1 == flag)) { //参数格式如-q -w 5 这种"-q"后面没有具体数值的格式错误 sprintf(info, "Parameter format error."); return -1; } } break; } break; case 'w'://指定等待时间 if(0 != tracert_parameters_parse( 'w', token, 65535, 0, info, &(tracert_info->wait_time))) { return -1; } break; default: sprintf(info, "Parameters are as follows:-p -q -m -f -w -s."); return -1; } } else { break; } } //参数全部处理成功返回0 return 0; }