/* reads filename, puts protocol info into layer7_protocol_info, number of protocols to numprotos */ int parse_protocol_file(char * filename, const unsigned char * protoname, struct ipt_layer7_info *info) { FILE * f; char * line = NULL; size_t len = 0; enum { protocol, pattern, done } datatype = protocol; f = fopen(filename, "r"); if(!f) return 0; while(getline(&line, &len, f) != -1) { if(strlen(line) < 2 || line[0] == '#') continue; /* strip the pesky newline... */ if(line[strlen(line) - 1] == '\n') line[strlen(line) - 1] = '\0'; if(datatype == protocol) { /* Ignore everything on the line beginning with the first space or tab . For instance, this allows the protocol line in http.pat to be "http " (or "http I am so cool") instead of just "http". */ if(strchr(line, ' ')){ char * space = strchr(line, ' '); space[0] = '\0'; } if(strchr(line, '\t')){ char * space = strchr(line, '\t'); space[0] = '\0'; } /* sanity check. First non-comment non-blank line must be the same as the file name. */ if(strcmp(line, protoname)) exit_error(OTHER_PROBLEM, "Protocol name (%s) doesn't match file name (%s). Bailing out\n", line, filename); if(strlen(line) >= MAX_PROTOCOL_LEN) exit_error(PARAMETER_PROBLEM, "Protocol name in %s too long!", filename); strncpy(info->protocol, line, MAX_PROTOCOL_LEN); datatype = pattern; } else if(datatype == pattern) { if(strlen(line) >= MAX_PATTERN_LEN) exit_error(PARAMETER_PROBLEM, "Pattern in %s too long!", filename); strncpy(info->pattern, line, MAX_PATTERN_LEN); datatype = done; break; } else exit_error(OTHER_PROBLEM, "Internal error"); } if(datatype != done) exit_error(OTHER_PROBLEM, "Failed to get all needed data from %s", filename); if(line) free(line); fclose(f); return 1; /* fprintf(stderr, "protocol: %s\npattern: %s\n\n", info->protocol, info->pattern); */ }
static void connlimit_check(unsigned int flags) { if (!(flags & 0x1)) exit_error(PARAMETER_PROBLEM, "You must specify \"--connlimit-above\""); }
/* Function which parses command options; returns true if it ate an option */ static int parse(int c, char **argv, int invert, unsigned int *flags, const struct ipt_entry *entry, struct ipt_entry_target **target) { struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) (*target)->data; int group_d; switch (c) { case '!': if (*flags & IPT_LOG_OPT_NLGROUP) exit_error(PARAMETER_PROBLEM, "Can't specify --ulog-nlgroup twice"); if (check_inverse(optarg, &invert, NULL, 0)) exit_error(PARAMETER_PROBLEM, "Unexpected `!' after --ulog-nlgroup"); group_d = atoi(optarg); if (group_d > 32 || group_d < 1) exit_error(PARAMETER_PROBLEM, "--ulog-nlgroup has to be between 1 and 32"); loginfo->nl_group = (1 << (group_d - 1)); *flags |= IPT_LOG_OPT_NLGROUP; break; case '#': if (*flags & IPT_LOG_OPT_PREFIX) exit_error(PARAMETER_PROBLEM, "Can't specify --ulog-prefix twice"); if (check_inverse(optarg, &invert, NULL, 0)) exit_error(PARAMETER_PROBLEM, "Unexpected `!' after --ulog-prefix"); if (strlen(optarg) > sizeof(loginfo->prefix) - 1) exit_error(PARAMETER_PROBLEM, "Maximum prefix length %u for --ulog-prefix", (unsigned int)(sizeof(loginfo->prefix) - 1)); strcpy(loginfo->prefix, optarg); *flags |= IPT_LOG_OPT_PREFIX; break; case 'A': if (*flags & IPT_LOG_OPT_CPRANGE) exit_error(PARAMETER_PROBLEM, "Can't specify --ulog-cprange twice"); if (atoi(optarg) < 0) exit_error(PARAMETER_PROBLEM, "Negative copy range?"); loginfo->copy_range = atoi(optarg); *flags |= IPT_LOG_OPT_CPRANGE; break; case 'B': if (*flags & IPT_LOG_OPT_QTHRESHOLD) exit_error(PARAMETER_PROBLEM, "Can't specify --ulog-qthreshold twice"); if (atoi(optarg) < 1) exit_error(PARAMETER_PROBLEM, "Negative or zero queue threshold ?"); if (atoi(optarg) > ULOG_MAX_QLEN) exit_error(PARAMETER_PROBLEM, "Maximum queue length exceeded"); loginfo->qthreshold = atoi(optarg); *flags |= IPT_LOG_OPT_QTHRESHOLD; break; } return 1; }
static int parse(int c, char **argv, int invert, unsigned int *flags, const struct ipt_entry *entry, unsigned int *nfcache, struct ipt_entry_match **match) { const char *s; char *e, *p; int n; struct ipt_web_info *info; if ((c < '1') || (c > '6')) return 0; if (*flags) exit_error(PARAMETER_PROBLEM, "Multiple modes are not supported"); *flags = 1; info = (struct ipt_web_info *)(*match)->data; switch (c) { case '2': info->mode = IPT_WEB_HOST; break; case '3': info->mode = IPT_WEB_RURI; break; case '4': info->mode = IPT_WEB_PATH; break; case '5': info->mode = IPT_WEB_QUERY; break; case '6': info->mode = IPT_WEB_HORE; break; default: // IPT_WEB_HTTP return 1; } if (entry->ip.proto != IPPROTO_TCP) { exit_error(PARAMETER_PROBLEM, "web match requires -p tcp"); } check_inverse(optarg, &invert, &optind, 0); if (invert) info->invert = 1; // convert arg to text\0text\0\0 s = argv[optind - 1]; if ((p = malloc(strlen(s) + 2)) == NULL) { exit_error(PARAMETER_PROBLEM, "Not enough memory"); } e = p; while (*s) { while ((*s == ' ') || (*s == '\n') || (*s == '\t')) ++s; if (*s == 0) break; while ((*s != 0) && (*s != ' ') && (*s != '\n') && (*s != '\t')) { *e++ = *s++; } *e++ = 0; } n = (e - p); #if 0 *e = 0; e = p; while (*e) { printf("[%s]\n", e); e += strlen(e) + 1; } #endif if (n <= 1) { exit_error(PARAMETER_PROBLEM, "Text is too short"); } if (n >= IPT_WEB_MAXTEXT) { exit_error(PARAMETER_PROBLEM, "Text is too long"); } memcpy(info->text, p, n); memset(info->text + n, 0, IPT_WEB_MAXTEXT - n); // term, need to clear rest for ipt rule cmp free(p); return 1; }
/* Function which parses command options; returns true if it ate an option */ static int parse(int c, char **argv, int invert, unsigned int *flags, const struct ipt_entry *entry, unsigned int *nfcache, struct ipt_entry_match **match) { struct ipt_psd_info *psdinfo = (struct ipt_psd_info *)(*match)->data; unsigned int num; char storage[strlen(optarg) + 2]; /* string_to_number needs a leading space */ storage[0] = ' '; strcpy(&storage[1], optarg); switch (c) { /* PSD-weight-threshold */ case '1': if (*flags & IPT_PSD_OPT_CTRESH) exit_error(PARAMETER_PROBLEM, "Can't specify --psd-weight-threshold " "twice"); if (string_to_number(storage, 0, 10000, &num) == -1) exit_error(PARAMETER_PROBLEM, "bad --psd-weight-threshold `%s'", optarg); psdinfo->weight_threshold = num; *flags |= IPT_PSD_OPT_CTRESH; break; /* PSD-delay-threshold */ case '2': if (*flags & IPT_PSD_OPT_DTRESH) exit_error(PARAMETER_PROBLEM, "Can't specify --psd-delay-threshold twice"); if (string_to_number(storage, 0, 10000, &num) == -1) exit_error(PARAMETER_PROBLEM, "bad --psd-delay-threshold `%s'", optarg); psdinfo->delay_threshold = num; *flags |= IPT_PSD_OPT_DTRESH; break; /* PSD-lo-ports-weight */ case '3': if (*flags & IPT_PSD_OPT_LPWEIGHT) exit_error(PARAMETER_PROBLEM, "Can't specify --psd-lo-ports-weight twice"); if (string_to_number(storage, 0, 10000, &num) == -1) exit_error(PARAMETER_PROBLEM, "bad --psd-lo-ports-weight `%s'", optarg); psdinfo->lo_ports_weight = num; *flags |= IPT_PSD_OPT_LPWEIGHT; break; /* PSD-hi-ports-weight */ case '4': if (*flags & IPT_PSD_OPT_HPWEIGHT) exit_error(PARAMETER_PROBLEM, "Can't specify --psd-hi-ports-weight twice"); if (string_to_number(storage, 0, 10000, &num) == -1) exit_error(PARAMETER_PROBLEM, "bad --psd-hi-ports-weight `%s'", optarg); psdinfo->hi_ports_weight = num; *flags |= IPT_PSD_OPT_HPWEIGHT; break; default: return 0; } return 1; }
static void final_check(unsigned int flags) { if (flags != 7) exit_error(PARAMETER_PROBLEM, "You must specify `--connbytes'" "`--connbytes-dir' and `--connbytes-mode'"); }
static void parse_hex_string(const char *s, struct xt_string_info *info) { int i=0, slen, sindex=0, schar; short hex_f = 0, literal_f = 0; char hextmp[3]; slen = strlen(s); if (slen == 0) { exit_error(PARAMETER_PROBLEM, "STRING must contain at least one char"); } while (i < slen) { if (s[i] == '\\' && !hex_f) { literal_f = 1; } else if (s[i] == '\\') { exit_error(PARAMETER_PROBLEM, "Cannot include literals in hex data"); } else if (s[i] == '|') { if (hex_f) hex_f = 0; else { hex_f = 1; /* get past any initial whitespace just after the '|' */ while (s[i+1] == ' ') i++; } if (i+1 >= slen) break; else i++; /* advance to the next character */ } if (literal_f) { if (i+1 >= slen) { exit_error(PARAMETER_PROBLEM, "Bad literal placement at end of string"); } info->pattern[sindex] = s[i+1]; i += 2; /* skip over literal char */ literal_f = 0; } else if (hex_f) { if (i+1 >= slen) { exit_error(PARAMETER_PROBLEM, "Odd number of hex digits"); } if (i+2 >= slen) { /* must end with a "|" */ exit_error(PARAMETER_PROBLEM, "Invalid hex block"); } if (! isxdigit(s[i])) /* check for valid hex char */ exit_error(PARAMETER_PROBLEM, "Invalid hex char `%c'", s[i]); if (! isxdigit(s[i+1])) /* check for valid hex char */ exit_error(PARAMETER_PROBLEM, "Invalid hex char `%c'", s[i+1]); hextmp[0] = s[i]; hextmp[1] = s[i+1]; hextmp[2] = '\0'; if (! sscanf(hextmp, "%x", &schar)) exit_error(PARAMETER_PROBLEM, "Invalid hex char `%c'", s[i]); info->pattern[sindex] = (char) schar; if (s[i+2] == ' ') i += 3; /* spaces included in the hex block */ else i += 2; } else { /* the char is not part of hex data, so just copy */ info->pattern[sindex] = s[i]; i++; } if (sindex > XT_STRING_MAX_PATTERN_SIZE) exit_error(PARAMETER_PROBLEM, "STRING too long `%s'", s); sindex++; } info->patlen = sindex; }
int main(int argc,char*argv[]) { /*9:*/ #line 220 "./interval.w" int i; int start_pitchclass; int start_accidental; int start_octave; int operator; int interval_quality; char interval_quality_name_in; int interval_dia; /*:9*//*18:*/ #line 342 "./interval.w" int interval_octaves; int interval_steps_dia; /*:18*//*20:*/ #line 398 "./interval.w" int start_abs_pitch_dia; int end_abs_pitch_dia; int end_pitchclass; int end_octave; /*:20*//*22:*/ #line 422 "./interval.w" int end_accidental; int start_abs_pitch_chrom; int end_abs_pitch_chrom; int end_base_pitch_chrom; int interval_chrom; /*:22*//*24:*/ #line 469 "./interval.w" char end_pitchclass_symb; char end_accidental_symb; /*:24*/ #line 119 "./interval.w" /*10:*/ #line 237 "./interval.w" /*11:*/ #line 249 "./interval.w" if(argc!=7){ exit_error(ERROR_ARGNUM,NULL); } /*:11*/ #line 238 "./interval.w" /*12:*/ #line 258 "./interval.w" if(argv[1][1]!='\0'||argv[1][0]<'A'||argv[1][0]> 'G'){ exit_error(ERROR_PITCH,argv[1]); } start_pitchclass= (int)argv[1][0]-'C'; if(start_pitchclass<0){ start_pitchclass+= 7; } /*:12*/ #line 239 "./interval.w" /*13:*/ #line 270 "./interval.w" if(argv[2][1]!='\0'){ exit_error(ERROR_ACCIDENTAL,argv[2]); } for(i= 0,found= FALSE;accidental_name[i]!='\0';++i){ if(argv[2][0]==accidental_name[i]){ found= TRUE; start_accidental= accidental_code[i]; break; } } if(found==FALSE){ exit_error(ERROR_ACCIDENTAL,argv[2]); } /*:13*/ #line 240 "./interval.w" /*14:*/ #line 287 "./interval.w" sscanf(argv[3],"%d",&start_octave); if(start_octave<0||start_octave> 20){ exit_error(ERROR_OCTAVE,argv[3]); } /*:14*/ #line 241 "./interval.w" /*15:*/ #line 295 "./interval.w" if(argv[4][1]!='\0'){ exit_error(ERROR_OPERATOR,argv[4]); }else{ switch(argv[4][0]){ case'-': operator= -1; break; case'+': operator= 1; break; default: exit_error(ERROR_OPERATOR,argv[4]); } } /*:15*/ #line 242 "./interval.w" /*16:*/ #line 314 "./interval.w" if(argv[5][1]!='\0'){ exit_error(ERROR_INTERVAL_QUALITY,argv[5]); } for(i= 0,found= FALSE;interval_quality_name[i]!='\0';++i){ if(argv[5][0]==interval_quality_name[i]){ found= TRUE; interval_quality_name_in= argv[5][0]; interval_quality= interval_quality_code[i]; break; } } if(found==FALSE){ exit_error(ERROR_INTERVAL_QUALITY,argv[5]); } /*:16*/ #line 243 "./interval.w" /*17:*/ #line 333 "./interval.w" sscanf(argv[6],"%d",&interval_dia); if(interval_dia<1||interval_dia> 70){ exit_error(ERROR_INTERVAL_DEGREE,argv[6]); } --interval_dia; /*:17*/ #line 244 "./interval.w" /*19:*/ #line 358 "./interval.w" interval_octaves= interval_steps_dia= 0; convert_from_base_ten(7,interval_dia,&interval_octaves,&interval_steps_dia); switch(interval_steps_dia){ case 0: case 3: case 4: perfect_interval= TRUE; break; default: perfect_interval= FALSE; } if(perfect_interval==TRUE){ switch(interval_quality_name_in){ case'm': case'M': exit_error(ERROR_MISMATCH_INTERVAL_QUALITY,NULL); break; default: ; } }else{ switch(interval_quality_name_in){ case'P': exit_error(ERROR_MISMATCH_INTERVAL_QUALITY,NULL); break; case'd': --interval_quality; break; default: ; } } /*:19*/ #line 245 "./interval.w" /*:10*/ #line 120 "./interval.w" /*21:*/ #line 407 "./interval.w" start_abs_pitch_dia= convert_to_base_ten(7,start_octave,start_pitchclass); end_abs_pitch_dia= start_abs_pitch_dia+operator*interval_dia; end_pitchclass= end_octave= 0; convert_from_base_ten(7,end_abs_pitch_dia,&end_octave,&end_pitchclass); if(end_octave<0){ exit_error(ERROR_OCTAVE_RANGE,NULL); } if(end_pitchclass<0||end_pitchclass> 6){ exit_error(ERROR_ENDPITCH_RANGE,NULL); } /*:21*/ #line 121 "./interval.w" /*23:*/ #line 447 "./interval.w" start_abs_pitch_chrom= convert_to_base_ten(12,start_octave,dia_to_chrom[start_pitchclass]) +start_accidental; interval_chrom= convert_to_base_ten(12,interval_octaves, dia_to_chrom[interval_steps_dia])+interval_quality; end_abs_pitch_chrom= start_abs_pitch_chrom+operator*interval_chrom; end_base_pitch_chrom= convert_to_base_ten(12,end_octave, dia_to_chrom[end_pitchclass]); end_accidental= end_abs_pitch_chrom-end_base_pitch_chrom; /*:23*/ #line 122 "./interval.w" /*25:*/ #line 475 "./interval.w" end_accidental+= 2; if(end_accidental<0||end_accidental> 4){ exit_error(ERROR_ENDACCIDENTAL_RANGE,NULL); } if(end_pitchclass> 4){ end_pitchclass-= 7; } end_pitchclass_symb= (char)(end_pitchclass+'C'); end_accidental_symb= accidental_name[end_accidental]; printf("%c %c %d\n",end_pitchclass_symb,end_accidental_symb,end_octave); /*:25*/ #line 123 "./interval.w" return(0); }
/* Function which parses command options; returns true if it ate an option */ static int parse(int c, char **argv, int invert, unsigned int *flags, const struct ipt_entry *entry, unsigned int *nfcache, struct ipt_entry_match **match) { struct ipt_time_info *timeinfo = (struct ipt_time_info *)(*match)->data; int hours, minutes; time_t temp_date; switch (c) { /* timestart */ case '1': if (invert) exit_error(PARAMETER_PROBLEM, "unexpected '!' with --timestart"); if (*flags & IPT_TIME_START) exit_error(PARAMETER_PROBLEM, "Can't specify --timestart twice"); parse_time_string(&hours, &minutes, optarg); timeinfo->time_start = (hours * 60) + minutes; *flags |= IPT_TIME_START; break; /* timestop */ case '2': if (invert) exit_error(PARAMETER_PROBLEM, "unexpected '!' with --timestop"); if (*flags & IPT_TIME_STOP) exit_error(PARAMETER_PROBLEM, "Can't specify --timestop twice"); parse_time_string(&hours, &minutes, optarg); timeinfo->time_stop = (hours * 60) + minutes; *flags |= IPT_TIME_STOP; break; /* days */ case '3': if (invert) exit_error(PARAMETER_PROBLEM, "unexpected '!' with --days"); if (*flags & IPT_TIME_DAYS) exit_error(PARAMETER_PROBLEM, "Can't specify --days twice"); parse_days_string(&globaldays, optarg); timeinfo->days_match = globaldays; *flags |= IPT_TIME_DAYS; break; /* datestart */ case '4': if (invert) exit_error(PARAMETER_PROBLEM, "unexpected '!' with --datestart"); if (*flags & IPT_DATE_START) exit_error(PARAMETER_PROBLEM, "Can't specify --datestart twice"); temp_date = parse_date_string(optarg); timeinfo->date_start = temp_date; *flags |= IPT_DATE_START; break; /* datestop*/ case '5': if (invert) exit_error(PARAMETER_PROBLEM, "unexpected '!' with --datestop"); if (*flags & IPT_DATE_STOP) exit_error(PARAMETER_PROBLEM, "Can't specify --datestop twice"); temp_date = parse_date_string(optarg); timeinfo->date_stop = temp_date; *flags |= IPT_DATE_STOP; break; default: return 0; } return 1; }
/* Function which parses command options; returns true if it ate an option */ static int parse(int c, char **argv, int invert, unsigned int *flags, const struct ipt_entry *entry, struct ipt_entry_match **match) { struct ipt_ipv4options_info *info = (struct ipt_ipv4options_info *)(*match)->data; switch (c) { /* strict-source-routing */ case '1': if (invert) exit_error(PARAMETER_PROBLEM, "ipv4options: unexpected `!' with --ssrr"); if (*flags & IPT_IPV4OPTION_MATCH_SSRR) exit_error(PARAMETER_PROBLEM, "Can't specify --ssrr twice"); if (*flags & IPT_IPV4OPTION_MATCH_LSRR) exit_error(PARAMETER_PROBLEM, "Can't specify --ssrr with --lsrr"); if (*flags & IPT_IPV4OPTION_DONT_MATCH_SRR) exit_error(PARAMETER_PROBLEM, "Can't specify --ssrr with --no-srr"); info->options |= IPT_IPV4OPTION_MATCH_SSRR; *flags |= IPT_IPV4OPTION_MATCH_SSRR; break; /* loose-source-routing */ case '2': if (invert) exit_error(PARAMETER_PROBLEM, "ipv4options: unexpected `!' with --lsrr"); if (*flags & IPT_IPV4OPTION_MATCH_SSRR) exit_error(PARAMETER_PROBLEM, "Can't specify --lsrr twice"); if (*flags & IPT_IPV4OPTION_MATCH_LSRR) exit_error(PARAMETER_PROBLEM, "Can't specify --lsrr with --ssrr"); if (*flags & IPT_IPV4OPTION_DONT_MATCH_SRR) exit_error(PARAMETER_PROBLEM, "Can't specify --lsrr with --no-srr"); info->options |= IPT_IPV4OPTION_MATCH_LSRR; *flags |= IPT_IPV4OPTION_MATCH_LSRR; break; /* no-source-routing */ case '3': if (invert) exit_error(PARAMETER_PROBLEM, "ipv4options: unexpected `!' with --no-srr"); if (*flags & IPT_IPV4OPTION_DONT_MATCH_SRR) exit_error(PARAMETER_PROBLEM, "Can't specify --no-srr twice"); if (*flags & IPT_IPV4OPTION_MATCH_SSRR) exit_error(PARAMETER_PROBLEM, "Can't specify --no-srr with --ssrr"); if (*flags & IPT_IPV4OPTION_MATCH_LSRR) exit_error(PARAMETER_PROBLEM, "Can't specify --no-srr with --lsrr"); info->options |= IPT_IPV4OPTION_DONT_MATCH_SRR; *flags |= IPT_IPV4OPTION_DONT_MATCH_SRR; break; /* record-route */ case '4': if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_RR)) exit_error(PARAMETER_PROBLEM, "Can't specify --rr twice"); if (invert && (*flags & IPT_IPV4OPTION_DONT_MATCH_RR)) exit_error(PARAMETER_PROBLEM, "Can't specify ! --rr twice"); if ((!invert) && (*flags & IPT_IPV4OPTION_DONT_MATCH_RR)) exit_error(PARAMETER_PROBLEM, "Can't specify --rr with ! --rr"); if (invert && (*flags & IPT_IPV4OPTION_MATCH_RR)) exit_error(PARAMETER_PROBLEM, "Can't specify ! --rr with --rr"); if (invert) { info->options |= IPT_IPV4OPTION_DONT_MATCH_RR; *flags |= IPT_IPV4OPTION_DONT_MATCH_RR; } else { info->options |= IPT_IPV4OPTION_MATCH_RR; *flags |= IPT_IPV4OPTION_MATCH_RR; } break; /* timestamp */ case '5': if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_TIMESTAMP)) exit_error(PARAMETER_PROBLEM, "Can't specify --ts twice"); if (invert && (*flags & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP)) exit_error(PARAMETER_PROBLEM, "Can't specify ! --ts twice"); if ((!invert) && (*flags & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP)) exit_error(PARAMETER_PROBLEM, "Can't specify --ts with ! --ts"); if (invert && (*flags & IPT_IPV4OPTION_MATCH_TIMESTAMP)) exit_error(PARAMETER_PROBLEM, "Can't specify ! --ts with --ts"); if (invert) { info->options |= IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP; *flags |= IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP; } else { info->options |= IPT_IPV4OPTION_MATCH_TIMESTAMP; *flags |= IPT_IPV4OPTION_MATCH_TIMESTAMP; } break; /* router-alert */ case '6': if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_ROUTER_ALERT)) exit_error(PARAMETER_PROBLEM, "Can't specify --ra twice"); if (invert && (*flags & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT)) exit_error(PARAMETER_PROBLEM, "Can't specify ! --rr twice"); if ((!invert) && (*flags & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT)) exit_error(PARAMETER_PROBLEM, "Can't specify --ra with ! --ra"); if (invert && (*flags & IPT_IPV4OPTION_MATCH_ROUTER_ALERT)) exit_error(PARAMETER_PROBLEM, "Can't specify ! --ra with --ra"); if (invert) { info->options |= IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT; *flags |= IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT; } else { info->options |= IPT_IPV4OPTION_MATCH_ROUTER_ALERT; *flags |= IPT_IPV4OPTION_MATCH_ROUTER_ALERT; } break; /* any option */ case '7' : if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_ANY_OPT)) exit_error(PARAMETER_PROBLEM, "Can't specify --any-opt twice"); if (invert && (*flags & IPT_IPV4OPTION_MATCH_ANY_OPT)) exit_error(PARAMETER_PROBLEM, "Can't specify ! --any-opt with --any-opt"); if (invert && (*flags & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT)) exit_error(PARAMETER_PROBLEM, "Can't specify ! --any-opt twice"); if ((!invert) && ((*flags & IPT_IPV4OPTION_DONT_MATCH_SRR) || (*flags & IPT_IPV4OPTION_DONT_MATCH_RR) || (*flags & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) || (*flags & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT))) exit_error(PARAMETER_PROBLEM, "Can't specify --any-opt with any other negative ipv4options match"); if (invert && ((*flags & IPT_IPV4OPTION_MATCH_LSRR) || (*flags & IPT_IPV4OPTION_MATCH_SSRR) || (*flags & IPT_IPV4OPTION_MATCH_RR) || (*flags & IPT_IPV4OPTION_MATCH_TIMESTAMP) || (*flags & IPT_IPV4OPTION_MATCH_ROUTER_ALERT))) exit_error(PARAMETER_PROBLEM, "Can't specify ! --any-opt with any other positive ipv4options match"); if (invert) { info->options |= IPT_IPV4OPTION_DONT_MATCH_ANY_OPT; *flags |= IPT_IPV4OPTION_DONT_MATCH_ANY_OPT; } else { info->options |= IPT_IPV4OPTION_MATCH_ANY_OPT; *flags |= IPT_IPV4OPTION_MATCH_ANY_OPT; } break; default: return 0; } return 1; }
/* Final check; must have specified --srcpool or --dstpool. */ static void final_check(unsigned int flags) { if (!flags) exit_error(PARAMETER_PROBLEM, "You must specify either `--srcpool or --dstpool'"); }
static struct iptables_target * get_target_name(const char *name) { void *handle; char *error; char *new_name, *lname; struct iptables_target *m; char path[strlen(lib_dir) + sizeof ("/libipt_.so") + strlen(name)]; new_name = malloc(strlen(name) + 1); lname = malloc(strlen(name) + 1); if (new_name) memset(new_name, '\0', strlen(name) + 1); else exit_error(PARAMETER_PROBLEM, "get_target_name"); if (lname) memset(lname, '\0', strlen(name) + 1); else exit_error(PARAMETER_PROBLEM, "get_target_name"); strcpy(new_name, name); strcpy(lname, name); if (isupper(lname[0])) { int i; for (i = 0; i < strlen(name); i++) { lname[i] = tolower(lname[i]); } } if (islower(new_name[0])) { int i; for (i = 0; i < strlen(new_name); i++) { new_name[i] = toupper(new_name[i]); } } /* try libxt_xx first */ sprintf(path, "%s/libxt_%s.so", lib_dir, new_name); handle = dlopen(path, RTLD_LAZY); if (!handle) { /* try libipt_xx next */ sprintf(path, "%s/libipt_%s.so", lib_dir, new_name); handle = dlopen(path, RTLD_LAZY); if (!handle) { sprintf(path, "%s/libxt_%s.so", lib_dir , lname); handle = dlopen(path, RTLD_LAZY); } if (!handle) { sprintf(path, "%s/libipt_%s.so", lib_dir , lname); handle = dlopen(path, RTLD_LAZY); } /* ok, lets give up .. */ if (!handle) { fputs(dlerror(), stderr); printf("\n"); return NULL; } } m = dlsym(handle, new_name); if ((error = dlerror()) != NULL) { m = (struct iptables_target *) dlsym(handle, lname); if ((error = dlerror()) != NULL) { m = find_t(new_name); if (NULL == m) { m = find_t(lname); if (NULL == m) { fputs(error, stderr); fprintf(stderr, "\n"); dlclose(handle); return NULL; } } } } return m; }
/* Final check; need --to. */ static void final_check(unsigned int flags) { if (!(flags & IPT_SAME_OPT_TO)) exit_error(PARAMETER_PROBLEM, "SAME needs --to"); }
static int parse(int c, char **argv, int invert, unsigned int *flags, const struct ipt_entry *entry, unsigned int *nfcache, struct ipt_entry_match **match) { struct ipt_dccp_info *einfo = (struct ipt_dccp_info *)(*match)->data; switch (c) { case '1': if (*flags & IPT_DCCP_SRC_PORTS) exit_error(PARAMETER_PROBLEM, "Only one `--source-port' allowed"); einfo->flags |= IPT_DCCP_SRC_PORTS; check_inverse(optarg, &invert, &optind, 0); parse_dccp_ports(argv[optind-1], einfo->spts); if (invert) einfo->invflags |= IPT_DCCP_SRC_PORTS; *flags |= IPT_DCCP_SRC_PORTS; break; case '2': if (*flags & IPT_DCCP_DEST_PORTS) exit_error(PARAMETER_PROBLEM, "Only one `--destination-port' allowed"); einfo->flags |= IPT_DCCP_DEST_PORTS; check_inverse(optarg, &invert, &optind, 0); parse_dccp_ports(argv[optind-1], einfo->dpts); if (invert) einfo->invflags |= IPT_DCCP_DEST_PORTS; *flags |= IPT_DCCP_DEST_PORTS; break; case '3': if (*flags & IPT_DCCP_TYPE) exit_error(PARAMETER_PROBLEM, "Only one `--dccp-types' allowed"); einfo->flags |= IPT_DCCP_TYPE; check_inverse(optarg, &invert, &optind, 0); einfo->typemask = parse_dccp_types(argv[optind-1]); if (invert) einfo->invflags |= IPT_DCCP_TYPE; *flags |= IPT_DCCP_TYPE; break; case '4': if (*flags & IPT_DCCP_OPTION) exit_error(PARAMETER_PROBLEM, "Only one `--dccp-option' allowed"); einfo->flags |= IPT_DCCP_OPTION; check_inverse(optarg, &invert, &optind, 0); einfo->option = parse_dccp_option(argv[optind-1]); if (invert) einfo->invflags |= IPT_DCCP_OPTION; *flags |= IPT_DCCP_OPTION; break; default: return 0; } return 1; }
/* Final check; must have specfied --to-source. */ static void final_check(unsigned int flags) { if (!flags) exit_error(PARAMETER_PROBLEM, "You must specify --to-destination"); }
/* Function which parses command options; returns true if it ate an option */ static int parse(int c, char **argv, int invert, unsigned int *flags, const struct ipt_entry *entry, struct ipt_entry_target **target) { struct ipt_trigger_info *info = (struct ipt_trigger_info *)(*target)->data; switch (c) { case '1': if (!strcasecmp(optarg, "dnat")) info->type = IPT_TRIGGER_DNAT; else if (!strcasecmp(optarg, "in")) info->type = IPT_TRIGGER_IN; else if (!strcasecmp(optarg, "out")) info->type = IPT_TRIGGER_OUT; else exit_error(PARAMETER_PROBLEM, "triggering type can only be one of `%s', '%s' '%s'", "dnat", "in", "out"); return 1; case '2': if (!strcasecmp(optarg, "tcp")) info->proto = IPPROTO_TCP; else if (!strcasecmp(optarg, "udp")) info->proto = IPPROTO_UDP; else if (!strcasecmp(optarg, "all")) info->proto = 0; else exit_error(PARAMETER_PROBLEM, "triggering protocol can only be one of `%s', '%s', '%s'", "tcp", "udp", "all"); return 1; case '3': if (check_inverse(optarg, &invert, &optind, 0)) exit_error(PARAMETER_PROBLEM, "Unexpected `!' after --triggering-port"); parse_ports(optarg, info->ports.mport); return 1; #ifdef ATP_SUPPORT_PRTT_RPROTOCOL case '4': if (!strcasecmp(optarg, "tcp")) info->rproto = IPPROTO_TCP; else if (!strcasecmp(optarg, "udp")) info->rproto = IPPROTO_UDP; else if (!strcasecmp(optarg, "all")) info->rproto = 0; else exit_error(PARAMETER_PROBLEM, "open protocol can only be one of '%s', '%s', '%s'", "tcp", "udp", "all"); return 1; case '5': if (check_inverse(optarg, &invert, &optind, 0)) exit_error(PARAMETER_PROBLEM, "Unexpected `!' after --open-port"); //parse_ports(optarg, info->ports.rport); parse_Openports(optarg, &(info->ports)); *flags |= IP_NAT_RANGE_PROTO_SPECIFIED; return 1; #else #if 0 case '4': if (check_inverse(optarg, &invert, &optind, 0)) exit_error(PARAMETER_PROBLEM, "Unexpected `!' after --open-port"); parse_ports(optarg, info->ports.rport); *flags |= IP_NAT_RANGE_PROTO_SPECIFIED; return 1; #endif #endif default: return 0; } }
/* Ranges expected in network order. */ static struct ipt_entry_target * parse_to(char *arg, int portok, struct ipt_natinfo *info) { struct ip_nat_range range; char *colon, *dash, *error; struct in_addr *ip; memset(&range, 0, sizeof(range)); colon = strchr(arg, ':'); if (colon) { int port; if (!portok) exit_error(PARAMETER_PROBLEM, "Need TCP or UDP with port specification"); range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED; port = atoi(colon+1); if (port <= 0 || port > 65535) exit_error(PARAMETER_PROBLEM, "Port `%s' not valid\n", colon+1); error = strchr(colon+1, ':'); if (error) exit_error(PARAMETER_PROBLEM, "Invalid port:port syntax - use dash\n"); dash = strchr(colon, '-'); if (!dash) { range.min.tcp.port = range.max.tcp.port = htons(port); } else { int maxport; maxport = atoi(dash + 1); if (maxport <= 0 || maxport > 65535) exit_error(PARAMETER_PROBLEM, "Port `%s' not valid\n", dash+1); if (maxport < port) /* People are stupid. */ exit_error(PARAMETER_PROBLEM, "Port range `%s' funky\n", colon+1); range.min.tcp.port = htons(port); range.max.tcp.port = htons(maxport); } /* Starts with a colon? No IP info...*/ if (colon == arg) return &(append_range(info, &range)->t); *colon = '\0'; } range.flags |= IP_NAT_RANGE_MAP_IPS; dash = strchr(arg, '-'); if (colon && dash && dash > colon) dash = NULL; if (dash) *dash = '\0'; ip = dotted_to_addr(arg); if (!ip) exit_error(PARAMETER_PROBLEM, "Bad IP address `%s'\n", arg); range.min_ip = ip->s_addr; if (dash) { ip = dotted_to_addr(dash+1); if (!ip) exit_error(PARAMETER_PROBLEM, "Bad IP address `%s'\n", dash+1); range.max_ip = ip->s_addr; } else range.max_ip = range.min_ip; return &(append_range(info, &range)->t); }
static void parse_Openports(const char *arg, struct ipt_trigger_ports *ports) { const char *dash; int port; char* pcTmp = NULL; char* pcStr1 = NULL; char* pcStr2 = NULL; int index = 0; u_int32_t ulStartPort = 0; u_int32_t ulEndPort = 0; /******************一触发多:内核扩展成用一条规则支持2000-2038,2050-2051,2069,2085,3010-3030格式的模式, 不需要将外部端口号解析并分段,但必须校验保证格式正确*****************************/ memset(ports->stOpenPort,0,PT_OPEN_PORT_RANGE_MAX *sizeof(PT_OPEN_APP_PORT_RANGE)); pcTmp = arg; while (NULL != (pcStr1 = strchr(pcTmp, ','))) { if (index >= PT_OPEN_PORT_RANGE_MAX) { index = 0; } *(pcTmp + (pcStr1 - pcTmp)) = '\0'; if (NULL != (pcStr2 = strchr(pcTmp, '-'))) { *(pcTmp + (pcStr2 - pcTmp)) = '\0'; pcStr2 += 1; ulStartPort = (u_int32_t)atoi(pcTmp); ulEndPort = (u_int32_t)atoi(pcStr2); if (ulEndPort == 0) { ulEndPort = ulStartPort; } // printf("\n ===========startport is %u,endport is %u===========\n",ulStartPort,ulEndPort); } else { ulStartPort = (u_int32_t)atoi(pcTmp); ulEndPort = ulStartPort; // printf("\n =================startport is %u,endport is %u**************\n",ulStartPort,ulEndPort); } ports->stOpenPort[index].ulStartPort = ulStartPort; ports->stOpenPort[index].ulEndPort = ulEndPort; index ++; pcTmp = pcStr1 + 1; } if (index >= PT_OPEN_PORT_RANGE_MAX) { index = 0; } //只有一个"-"或最后一个要进行补充 if (NULL != (pcStr2 = strchr(pcTmp, '-'))) { *(pcTmp + (pcStr2 - pcTmp)) = '\0'; pcStr2 += 1; ulStartPort = (u_int32_t)atoi(pcTmp); ulEndPort = (u_int32_t)atoi(pcStr2); if (ulEndPort == 0) { ulEndPort = ulStartPort; } } else { ulStartPort = (u_int32_t)atoi(pcTmp); ulEndPort = ulStartPort; } //printf("\n 2222222222222startport is %u,endport is %u===========\n",ulStartPort,ulEndPort); //printf("\n 22222222222222startport is %u,endport is %u**************\n",ulStartPort,ulEndPort); ports->stOpenPort[index].ulStartPort = ulStartPort; ports->stOpenPort[index].ulEndPort = ulEndPort; #if 0 port = atoi(arg); if (port == 0 || port > 65535) exit_error(PARAMETER_PROBLEM, "Port range `%s' invalid\n", arg); dash = strchr(arg, '-'); if (!dash) ports[0] = ports[1] = port; else { int maxport; maxport = atoi(dash + 1); if (maxport == 0 || maxport > 65535) exit_error(PARAMETER_PROBLEM, "Port range `%s' invalid\n", dash+1); if (maxport < port) exit_error(PARAMETER_PROBLEM, "Port range `%s' invalid\n", arg); ports[0] = port; ports[1] = maxport; } #endif }
/* Function which parses command options; returns true if it ate an option */ static int parse(int c, char **argv, int invert, unsigned int *flags, const struct ip6t_entry *entry, struct ip6t_entry_target **target) { struct ip6t_route_target_info *route_info = (struct ip6t_route_target_info*)(*target)->data; switch (c) { case '1': if (*flags & IP6T_ROUTE_OPT_OIF) exit_error(PARAMETER_PROBLEM, "Can't specify --oif twice"); if (check_inverse(optarg, &invert, NULL, 0)) exit_error(PARAMETER_PROBLEM, "Unexpected `!' after --oif"); if (strlen(optarg) > sizeof(route_info->oif) - 1) exit_error(PARAMETER_PROBLEM, "Maximum interface name length %u", sizeof(route_info->oif) - 1); strcpy(route_info->oif, optarg); *flags |= IP6T_ROUTE_OPT_OIF; break; case '2': exit_error(PARAMETER_PROBLEM, "--iif option not implemented"); break; case '3': if (*flags & IP6T_ROUTE_OPT_GW) exit_error(PARAMETER_PROBLEM, "Can't specify --gw twice"); if (check_inverse(optarg, &invert, NULL, 0)) exit_error(PARAMETER_PROBLEM, "Unexpected `!' after --gw"); if (!inet_pton(AF_INET6, optarg, (struct in6_addr*)&route_info->gw)) { exit_error(PARAMETER_PROBLEM, "Invalid IPv6 address %s", optarg); } *flags |= IP6T_ROUTE_OPT_GW; break; case '4': if (*flags & IP6T_ROUTE_OPT_CONTINUE) exit_error(PARAMETER_PROBLEM, "Can't specify --continue twice"); if (*flags & IP6T_ROUTE_OPT_TEE) exit_error(PARAMETER_PROBLEM, "Can't specify --continue AND --tee"); route_info->flags |= IP6T_ROUTE_CONTINUE; *flags |= IP6T_ROUTE_OPT_CONTINUE; break; case '5': if (*flags & IP6T_ROUTE_OPT_TEE) exit_error(PARAMETER_PROBLEM, "Can't specify --tee twice"); if (*flags & IP6T_ROUTE_OPT_CONTINUE) exit_error(PARAMETER_PROBLEM, "Can't specify --tee AND --continue"); route_info->flags |= IP6T_ROUTE_TEE; *flags |= IP6T_ROUTE_OPT_TEE; break; default: return 0; } return 1; }
/* Function which parses command options; returns true if it ate an option */ static int parse(int c, char **argv, int invert, unsigned int *flags, const struct ipt_entry *entry, unsigned int *nfcache, struct ipt_entry_match **match) { struct ipt_owner_info *ownerinfo = (struct ipt_owner_info *)(*match)->data; switch (c) { char *end; struct passwd *pwd; struct group *grp; case '1': check_inverse(optarg, &invert, &optind, 0); if ((pwd = getpwnam(optarg))) ownerinfo->uid = pwd->pw_uid; else { ownerinfo->uid = strtoul(optarg, &end, 0); if (*end != '\0' || end == optarg) exit_error(PARAMETER_PROBLEM, "Bad OWNER UID value `%s'", optarg); } if (invert) ownerinfo->invert |= IPT_OWNER_UID; ownerinfo->match |= IPT_OWNER_UID; *flags = 1; break; case '2': check_inverse(optarg, &invert, &optind, 0); if ((grp = getgrnam(optarg))) ownerinfo->gid = grp->gr_gid; else { ownerinfo->gid = strtoul(optarg, &end, 0); if (*end != '\0' || end == optarg) exit_error(PARAMETER_PROBLEM, "Bad OWNER GID value `%s'", optarg); } if (invert) ownerinfo->invert |= IPT_OWNER_GID; ownerinfo->match |= IPT_OWNER_GID; *flags = 1; break; case '3': check_inverse(optarg, &invert, &optind, 0); ownerinfo->pid = strtoul(optarg, &end, 0); if (*end != '\0' || end == optarg) exit_error(PARAMETER_PROBLEM, "Bad OWNER PID value `%s'", optarg); if (invert) ownerinfo->invert |= IPT_OWNER_PID; ownerinfo->match |= IPT_OWNER_PID; *flags = 1; break; case '4': check_inverse(optarg, &invert, &optind, 0); ownerinfo->sid = strtoul(optarg, &end, 0); if (*end != '\0' || end == optarg) exit_error(PARAMETER_PROBLEM, "Bad OWNER SID value `%s'", optarg); if (invert) ownerinfo->invert |= IPT_OWNER_SID; ownerinfo->match |= IPT_OWNER_SID; *flags = 1; break; #ifdef IPT_OWNER_COMM case '5': check_inverse(optarg, &invert, &optind, 0); if(strlen(optarg) > sizeof(ownerinfo->comm)) exit_error(PARAMETER_PROBLEM, "OWNER CMD `%s' too long, max %d characters", optarg, sizeof(ownerinfo->comm)); strncpy(ownerinfo->comm, optarg, sizeof(ownerinfo->comm)); if (invert) ownerinfo->invert |= IPT_OWNER_COMM; ownerinfo->match |= IPT_OWNER_COMM; *flags = 1; break; #endif default: return 0; } return 1; }
/* Function which parses command options; returns true if it ate an option */ static int parse(int c, char **argv, int invert, unsigned int *flags, const struct ipt_entry *entry, unsigned int *nfcache, struct ipt_entry_match **match) { struct ipt_u32 *data = (struct ipt_u32 *)(*match)->data; char *arg = argv[optind-1]; /* the argument string */ char *start = arg; int state=0, testind=0, locind=0, valind=0; if (c != '1') return 0; /* states: 0 = looking for numbers and operations, 1 = looking for ranges */ while (1) { /* read next operand/number or range */ while (isspace(*arg)) arg++; /* skip white space */ if (! *arg) { /* end of argument found */ if (state == 0) exit_error(PARAMETER_PROBLEM, "u32: input ended in location spec"); if (valind == 0) exit_error(PARAMETER_PROBLEM, "u32: test ended with no value spec"); data->tests[testind].nnums = locind; data->tests[testind].nvalues = valind; testind++; data->ntests=testind; if (testind > U32MAXSIZE) exit_error(PARAMETER_PROBLEM, "u32: at char %d too many &&'s", arg-start); /* debugging print_u32(data);printf("\n"); exit_error(PARAMETER_PROBLEM, "debugging output done"); */ return 1; } if (state == 0) { /* reading location: read a number if nothing read yet, otherwise either op number or = to end location spec */ if (*arg == '=') { if (locind == 0) exit_error(PARAMETER_PROBLEM, "u32: at char %d location spec missing", arg-start); else { arg++; state=1; } } else { if (locind) { /* need op before number */ if (*arg == '&') { data->tests[testind].location[locind].nextop = IPT_U32_AND; } else if (*arg == '<') { arg++; if (*arg != '<') exit_error(PARAMETER_PROBLEM, "u32: at char %d a second < expected", arg-start); data->tests[testind].location[locind].nextop = IPT_U32_LEFTSH; } else if (*arg == '>') { arg++; if (*arg != '>') exit_error(PARAMETER_PROBLEM, "u32: at char %d a second > expected", arg-start); data->tests[testind].location[locind].nextop = IPT_U32_RIGHTSH; } else if (*arg == '@') { data->tests[testind].location[locind].nextop = IPT_U32_AT; } else exit_error(PARAMETER_PROBLEM, "u32: at char %d operator expected", arg-start); arg++; } /* now a number; string_to_number skips white space? */ data->tests[testind].location[locind].number = parse_number(&arg, arg-start); locind++; if (locind > U32MAXSIZE) exit_error(PARAMETER_PROBLEM, "u32: at char %d too many operators", arg-start); } } else { /* state 1 - reading values: read a range if nothing read yet, otherwise either ,range or && to end test spec */ if (*arg == '&') { arg++; if (*arg != '&') exit_error(PARAMETER_PROBLEM, "u32: at char %d a second & expected", arg-start); if (valind == 0) exit_error(PARAMETER_PROBLEM, "u32: at char %d value spec missing", arg-start); else { data->tests[testind].nnums = locind; data->tests[testind].nvalues = valind; testind++; if (testind > U32MAXSIZE) exit_error(PARAMETER_PROBLEM, "u32: at char %d too many &&'s", arg-start); arg++; state=0; locind=0; valind=0; } } else { /* read value range */ if (valind) { /* need , before number */ if (*arg != ',') exit_error(PARAMETER_PROBLEM, "u32: at char %d expected , or &&", arg-start); arg++; } data->tests[testind].value[valind].min = parse_number(&arg, arg-start); while (isspace(*arg)) arg++; /* another place white space could be */ if (*arg==':') { arg++; data->tests[testind].value[valind].max = parse_number(&arg, arg-start); } else data->tests[testind].value[valind].max = data->tests[testind].value[valind].min; valind++; if (valind > U32MAXSIZE) exit_error(PARAMETER_PROBLEM, "u32: at char %d too many ,'s", arg-start); } } } }
/* Final check; nothing. */ static void final_check(unsigned int flags) { if (!(flags & IPT_DYNAHELPER_OPT_PROTO)) exit_error(PARAMETER_PROBLEM, "DYNAHELPER: must specify --proto"); }
/* Final check; must specify something. */ static void final_check(unsigned int flags) { if (!flags) exit_error(PARAMETER_PROBLEM, "mport expects an option"); }
static void CONNMARK_check(unsigned int flags) { if (!flags) exit_error(PARAMETER_PROBLEM, "CONNMARK target: No operation specified"); }
/* Function which parses command options; returns true if it ate an option. */ static int tcp_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct xt_tcp *tcpinfo = (struct xt_tcp *)(*match)->data; switch (c) { case '1': if (*flags & TCP_SRC_PORTS) exit_error(PARAMETER_PROBLEM, "Only one `--source-port' allowed"); check_inverse(optarg, &invert, &optind, 0); parse_tcp_ports(argv[optind-1], tcpinfo->spts); if (invert) tcpinfo->invflags |= XT_TCP_INV_SRCPT; *flags |= TCP_SRC_PORTS; break; case '2': if (*flags & TCP_DST_PORTS) exit_error(PARAMETER_PROBLEM, "Only one `--destination-port' allowed"); check_inverse(optarg, &invert, &optind, 0); parse_tcp_ports(argv[optind-1], tcpinfo->dpts); if (invert) tcpinfo->invflags |= XT_TCP_INV_DSTPT; *flags |= TCP_DST_PORTS; break; case '3': if (*flags & TCP_FLAGS) exit_error(PARAMETER_PROBLEM, "Only one of `--syn' or `--tcp-flags' " " allowed"); parse_tcp_flags(tcpinfo, "SYN,RST,ACK,FIN", "SYN", invert); *flags |= TCP_FLAGS; break; case '4': if (*flags & TCP_FLAGS) exit_error(PARAMETER_PROBLEM, "Only one of `--syn' or `--tcp-flags' " " allowed"); check_inverse(optarg, &invert, &optind, 0); if (!argv[optind] || argv[optind][0] == '-' || argv[optind][0] == '!') exit_error(PARAMETER_PROBLEM, "--tcp-flags requires two args."); parse_tcp_flags(tcpinfo, argv[optind-1], argv[optind], invert); optind++; *flags |= TCP_FLAGS; break; case '5': if (*flags & TCP_OPTION) exit_error(PARAMETER_PROBLEM, "Only one `--tcp-option' allowed"); check_inverse(optarg, &invert, &optind, 0); parse_tcp_option(argv[optind-1], &tcpinfo->option); if (invert) tcpinfo->invflags |= XT_TCP_INV_OPTION; *flags |= TCP_OPTION; break; default: return 0; } return 1; }
static void parse_string(const unsigned char *s, struct ipt_string_info *info) { if (strlen(s) <= BM_MAX_NLEN) strcpy(info->string, s); else exit_error(PARAMETER_PROBLEM, "STRING too long `%s'", s); }
/* Function which parses command options; returns true if it ate an option */ static int parse(int c, char **argv, int invert, unsigned int *flags, const struct ip6t_entry *entry, unsigned int *nfcache, struct ip6t_entry_match **match) { struct ip6t_rt *rtinfo = (struct ip6t_rt *)(*match)->data; switch (c) { case '1': if (*flags & IP6T_RT_TYP) exit_error(PARAMETER_PROBLEM, "Only one `--rt-type' allowed"); check_inverse(optarg, &invert, &optind, 0); rtinfo->rt_type = parse_rt_num(argv[optind-1], "type"); if (invert) rtinfo->invflags |= IP6T_RT_INV_TYP; rtinfo->flags |= IP6T_RT_TYP; *flags |= IP6T_RT_TYP; break; case '2': if (*flags & IP6T_RT_SGS) exit_error(PARAMETER_PROBLEM, "Only one `--rt-segsleft' allowed"); check_inverse(optarg, &invert, &optind, 0); parse_rt_segsleft(argv[optind-1], rtinfo->segsleft); if (invert) rtinfo->invflags |= IP6T_RT_INV_SGS; rtinfo->flags |= IP6T_RT_SGS; *flags |= IP6T_RT_SGS; break; case '3': if (*flags & IP6T_RT_LEN) exit_error(PARAMETER_PROBLEM, "Only one `--rt-len' allowed"); check_inverse(optarg, &invert, &optind, 0); rtinfo->hdrlen = parse_rt_num(argv[optind-1], "length"); if (invert) rtinfo->invflags |= IP6T_RT_INV_LEN; rtinfo->flags |= IP6T_RT_LEN; *flags |= IP6T_RT_LEN; break; case '4': if (*flags & IP6T_RT_RES) exit_error(PARAMETER_PROBLEM, "Only one `--rt-0-res' allowed"); if ( !(*flags & IP6T_RT_TYP) || (rtinfo->rt_type != 0) || (rtinfo->invflags & IP6T_RT_INV_TYP) ) exit_error(PARAMETER_PROBLEM, "`--rt-type 0' required before `--rt-0-res'"); rtinfo->flags |= IP6T_RT_RES; *flags |= IP6T_RT_RES; break; case '5': if (*flags & IP6T_RT_FST) exit_error(PARAMETER_PROBLEM, "Only one `--rt-0-addrs' allowed"); if ( !(*flags & IP6T_RT_TYP) || (rtinfo->rt_type != 0) || (rtinfo->invflags & IP6T_RT_INV_TYP) ) exit_error(PARAMETER_PROBLEM, "`--rt-type 0' required before `--rt-0-addrs'"); check_inverse(optarg, &invert, &optind, 0); if (invert) exit_error(PARAMETER_PROBLEM, " '!' not allowed with `--rt-0-addrs'"); rtinfo->addrnr = parse_addresses(argv[optind-1], rtinfo->addrs); rtinfo->flags |= IP6T_RT_FST; *flags |= IP6T_RT_FST; break; case '6': if (*flags & IP6T_RT_FST_NSTRICT) exit_error(PARAMETER_PROBLEM, "Only one `--rt-0-not-strict' allowed"); if ( !(*flags & IP6T_RT_FST) ) exit_error(PARAMETER_PROBLEM, "`--rt-0-addr ...' required before `--rt-0-not-strict'"); rtinfo->flags |= IP6T_RT_FST_NSTRICT; *flags |= IP6T_RT_FST_NSTRICT; break; default: return 0; } return 1; }
static int parse(int c, char **argv, int invert, unsigned int *flags, const struct ipt_entry *entry, unsigned int *nfcache, struct ipt_entry_match **match) { struct ipt_p2p_info *info = (struct ipt_p2p_info *)(*match)->data; switch (c) { case '1': /*cmd: ipp2p*/ if ((*flags & SHORT_HAND_IPP2P) == SHORT_HAND_IPP2P) exit_error(PARAMETER_PROBLEM, "ipp2p: `--ipp2p' may only be " "specified once!"); if ((*flags) != 0) exit_error(PARAMETER_PROBLEM, "ipp2p: `--ipp2p' may only be " "specified alone!"); if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); *flags += SHORT_HAND_IPP2P; info->cmd = *flags; break; case '2': /*cmd: edk*/ if ((*flags & IPP2P_EDK) == IPP2P_EDK) exit_error(PARAMETER_PROBLEM, "ipp2p: `--edk' may only be " "specified once"); if ((*flags & SHORT_HAND_IPP2P) == SHORT_HAND_IPP2P) exit_error(PARAMETER_PROBLEM, "ipp2p: `--ipp2p' may only be " "specified alone!"); if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); *flags += IPP2P_EDK; info->cmd = *flags; break; case '3': /*cmd: pp*/ if ((*flags & IPP2P_PP) == IPP2P_PP) exit_error(PARAMETER_PROBLEM, "ipp2p: `--pp' may only be " "specified once!"); if ((*flags & SHORT_HAND_IPP2P) == SHORT_HAND_IPP2P) exit_error(PARAMETER_PROBLEM, "ipp2p: `--ipp2p' may only be " "specified alone!"); if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); *flags += IPP2P_PP; info->cmd = *flags; break; case '4': if ((*flags & IPP2P_XUNLEI) == IPP2P_XUNLEI) exit_error(PARAMETER_PROBLEM, "ipp2p: `--xunlei' may only be " "specified once!"); if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); *flags += IPP2P_XUNLEI; info->cmd = *flags; break; case '7': /*cmd: dc*/ if ((*flags & IPP2P_DC) == IPP2P_DC) exit_error(PARAMETER_PROBLEM, "ipp2p: `--dc' may only be " "specified once!"); if ((*flags & SHORT_HAND_IPP2P) == SHORT_HAND_IPP2P) exit_error(PARAMETER_PROBLEM, "ipp2p: `--ipp2p' may only be " "specified alone!"); if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); *flags += IPP2P_DC; info->cmd = *flags; break; case '9': /*cmd: gnu*/ if ((*flags & IPP2P_GNU) == IPP2P_GNU) exit_error(PARAMETER_PROBLEM, "ipp2p: `--gnu' may only be " "specified once!"); if ((*flags & SHORT_HAND_IPP2P) == SHORT_HAND_IPP2P) exit_error(PARAMETER_PROBLEM, "ipp2p: `--ipp2p' may only be " "specified alone!"); if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); *flags += IPP2P_GNU; info->cmd = *flags; break; case 'a': /*cmd: kazaa*/ if ((*flags & IPP2P_KAZAA) == IPP2P_KAZAA) exit_error(PARAMETER_PROBLEM, "ipp2p: `--kazaa' may only be " "specified once!"); if ((*flags & SHORT_HAND_IPP2P) == SHORT_HAND_IPP2P) exit_error(PARAMETER_PROBLEM, "ipp2p: `--ipp2p' may only be " "specified alone!"); if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); *flags += IPP2P_KAZAA; info->cmd = *flags; break; case 'b': /*cmd: bit*/ if ((*flags & IPP2P_BIT) == IPP2P_BIT) exit_error(PARAMETER_PROBLEM, "ipp2p: `--bit' may only be " "specified once!"); if ((*flags & SHORT_HAND_IPP2P) == SHORT_HAND_IPP2P) exit_error(PARAMETER_PROBLEM, "ipp2p: `--ipp2p' may only be " "specified alone!"); if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); *flags += IPP2P_BIT; info->cmd = *flags; break; case 'c': /*cmd: apple*/ if ((*flags & IPP2P_APPLE) == IPP2P_APPLE) exit_error(PARAMETER_PROBLEM, "ipp2p: `--apple' may only be " "specified once!"); if ((*flags & SHORT_HAND_IPP2P) == SHORT_HAND_IPP2P) exit_error(PARAMETER_PROBLEM, "ipp2p: `--ipp2p' may only be " "specified alone!"); if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); *flags += IPP2P_APPLE; info->cmd = *flags; break; case 'd': /*cmd: soul*/ if ((*flags & IPP2P_SOUL) == IPP2P_SOUL) exit_error(PARAMETER_PROBLEM, "ipp2p: `--soul' may only be " "specified once!"); if ((*flags & SHORT_HAND_IPP2P) == SHORT_HAND_IPP2P) exit_error(PARAMETER_PROBLEM, "ipp2p: `--ipp2p' may only be " "specified alone!"); if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); *flags += IPP2P_SOUL; info->cmd = *flags; break; case 'e': /*cmd: winmx*/ if ((*flags & IPP2P_WINMX) == IPP2P_WINMX) exit_error(PARAMETER_PROBLEM, "ipp2p: `--winmx' may only be " "specified once!"); if ((*flags & SHORT_HAND_IPP2P) == SHORT_HAND_IPP2P) exit_error(PARAMETER_PROBLEM, "ipp2p: `--ipp2p' may only be " "specified alone!"); if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); *flags += IPP2P_WINMX; info->cmd = *flags; break; case 'f': /*cmd: ares*/ if ((*flags & IPP2P_ARES) == IPP2P_ARES) exit_error(PARAMETER_PROBLEM, "ipp2p: `--ares' may only be " "specified once!"); if ((*flags & SHORT_HAND_IPP2P) == SHORT_HAND_IPP2P) exit_error(PARAMETER_PROBLEM, "ipp2p: `--ipp2p' may only be " "specified alone!"); if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); *flags += IPP2P_ARES; info->cmd = *flags; break; case 'g': /*cmd: mute*/ if ((*flags & IPP2P_MUTE) == IPP2P_MUTE) exit_error(PARAMETER_PROBLEM, "ipp2p: `--mute' may only be " "specified once!"); if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); *flags += IPP2P_MUTE; info->cmd = *flags; break; case 'h': /*cmd: waste*/ if ((*flags & IPP2P_WASTE) == IPP2P_WASTE) exit_error(PARAMETER_PROBLEM, "ipp2p: `--waste' may only be " "specified once!"); if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); *flags += IPP2P_WASTE; info->cmd = *flags; break; case 'i': /*cmd: xdcc*/ if ((*flags & IPP2P_XDCC) == IPP2P_XDCC) exit_error(PARAMETER_PROBLEM, "ipp2p: `--xdcc' may only be " "specified once!"); if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); *flags += IPP2P_XDCC; info->cmd = *flags; break; case 'j': /*cmd: debug*/ if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); info->debug = 1; break; default: // exit_error(PARAMETER_PROBLEM, // "\nipp2p-parameter problem: for ipp2p usage type: iptables -m ipp2p --help\n"); return 0; } return 1; }
static int do_output(const char *tablename) { ip6tc_handle_t h; const char *chain = NULL; if (!tablename) return for_each_table(&do_output); h = ip6tc_init(tablename); if (!h) exit_error(OTHER_PROBLEM, "Can't initialize: %s\n", ip6tc_strerror(errno)); if (!binary) { time_t now = time(NULL); printf("# Generated by ip6tables-save v%s on %s", IPTABLES_VERSION, ctime(&now)); printf("*%s\n", tablename); /* Dump out chain names first, * thereby preventing dependency conflicts */ for (chain = ip6tc_first_chain(&h); chain; chain = ip6tc_next_chain(&h)) { printf(":%s ", chain); if (ip6tc_builtin(chain, h)) { struct ip6t_counters count; printf("%s ", ip6tc_get_policy(chain, &count, &h)); printf("[%llu:%llu]\n", (unsigned long long)count.pcnt, (unsigned long long)count.bcnt); } else { printf("- [0:0]\n"); } } for (chain = ip6tc_first_chain(&h); chain; chain = ip6tc_next_chain(&h)) { const struct ip6t_entry *e; /* Dump out rules */ e = ip6tc_first_rule(chain, &h); while(e) { print_rule(e, &h, chain, counters); e = ip6tc_next_rule(e, &h); } } now = time(NULL); printf("COMMIT\n"); printf("# Completed on %s", ctime(&now)); } else { /* Binary, huh? OK. */ exit_error(OTHER_PROBLEM, "Binary NYI\n"); } ip6tc_free(&h); return 1; }
/* Final check; must have specified --l7proto */ static void final_check(unsigned int flags) { if (!flags) exit_error(PARAMETER_PROBLEM, "LAYER7 match: You must specify --l7proto'"); }