static void parse_subnets(struct list_head *head, enum fw3_family family, struct blob_attr *list) { struct blob_attr *cur; struct fw3_address *addr; int rem; if (!list) return; rem = blobmsg_data_len(list); __blob_for_each_attr(cur, blobmsg_data(list), rem) { addr = parse_subnet(family, blobmsg_data(cur), blobmsg_data_len(cur)); if (addr) list_add_tail(&addr->list, head); }
int parse_rule(const char * const line_buf, const int cline) { /* * Eat white-space chars */ char *cursor; char *token = NULL; cursor = line_buf; cursor += strspn(cursor, WHITESPACE_CHARS); if (*cursor == '#') { /* * this is a comment; skip to the next line */ return 1; } token = strtok(cursor, WHITESPACE_CHARS); if (token == NULL) { return 1; } rule_table[rule_cnt] = malloc(sizeof(ipr_rule_t)); if (rule_table[rule_cnt] == NULL) { fprintf(stderr,"Could not allocate memory."); return -1; } if (strcmp(token, "allow") == 0) { rule_table[rule_cnt]->permission = RULE_ALLOW; } else if (strcmp(token, "deny") == 0) { rule_table[rule_cnt]->permission = RULE_DENY; } else { fprintf(stderr, "Syntax error at line %d: '%s'\n", cline, token); return -1; } token = strtok(NULL, WHITESPACE_CHARS); if (token == NULL) { fprintf(stderr, "Syntax error at line %d: more arguments needed.\n", cline); return -1; } /* * Determine the type */ if (strcmp(token, "ip") == 0) { rule_table[rule_cnt]->type = RULE_IP; token = strtok(NULL,WHITESPACE_CHARS); if (parse_ip(token, &rule_table[rule_cnt]->match.ip) != 0) { fprintf(stderr, "Syntax error at line %d: '%s'\n", cline, token); return -2; } } else if (strcmp(token, "subnet") == 0) { rule_table[rule_cnt]->type = RULE_SUBNET; token = strtok(NULL,WHITESPACE_CHARS); if (parse_subnet(token, &rule_table[rule_cnt]->match.subnet) != 0) { fprintf(stderr, "Syntax error at line %d: '%s'\n", cline, token); return -2; } } else if (strcmp(token, "range") == 0) { rule_table[rule_cnt]->type = RULE_RANGE; token = strtok(NULL,WHITESPACE_CHARS); if (parse_range(token, &rule_table[rule_cnt]->match.range) != 0) { fprintf(stderr, "Syntax error at line %d: '%s'\n", cline, token); return -2; } /* * No need to use htonl() anymore to avoid any endianness problems. * Use our own function to do BigEndian comparisson. */ if (ip_val(rule_table[rule_cnt]->match.range.start) > ip_val(rule_table[rule_cnt]->match.range.stop)) { fprintf(stderr, "Syntax error at line %d: '%s'\n", cline, token); return -2; } } else if (strcmp(token, "all") == 0) { rule_table[rule_cnt]->type = RULE_ALL; } else { fprintf(stderr, "Syntax error at line %d: more arguments needed.\n", cline); return -2; } token = strtok(NULL, WHITESPACE_CHARS); if (token != NULL){ fprintf(stderr, "Illegal syntax in configuration file. " "Unknown parameter after the end of rule at line %d.\n", cline); return -2; } return 0; }
const struct token * match_token(int *argc, char **argv[], const struct token table[]) { u_int i, match; const struct token *t = NULL; const char *word = *argv[0]; struct ether_addr *mac; (void) argc; match = 0; for (i = 0; table[i].type != ENDTOKEN; i++) { switch (table[i].type) { case NOTOKEN: if (word == NULL || strlen(word) == 0) { match++; t = &table[i]; } break; case KEYWORD: if (word != NULL && strncmp(word, table[i].keyword, strlen(word)) == 0) { match++; t = &table[i]; if (t->value) res.action = t->value; } break; case INTERFACE: if (strlen(word) > IF_NAMESIZE) { fprintf(stderr, "interface name too long\n"); break; } match++; t = &table[i]; strlcpy(res.interface, word, sizeof res.interface); break; case PARENT: res.flags |= GROUP_WANT_PARENT; /* FALLTHROUGH */ case SYNTAX: if (word != NULL) { match++; t = &table[i]; strlcpy(res.syntax, word, sizeof res.syntax); } break; case STRING: if (word != NULL) { match++; t = &table[i]; strlcpy(res.string, word, sizeof res.string); } break; case FILENAME: if (word != NULL) { match++; t = &table[i]; strlcpy(res.filename, word, BOOTP_FILE); res.flags |= GROUP_WANT_FILENAME; } break; case SNAME: if (word != NULL) { match++; t = &table[i]; strlcpy(res.sname, word, BOOTP_SNAME); res.flags |= GROUP_WANT_SNAME; } break; case GROUP: if (word != NULL) { match++; t = &table[i]; strlcpy(res.group, word, sizeof res.group); } break; case SUBNET: if (word != NULL && parse_subnet(&res, word)) { match++; t = &table[i]; } break; case NEXT_SERVER: res.flags |= GROUP_WANT_NEXT_SERVER; /* FALLTHROUGH */ case IPv4_FIRST: if (word != NULL && inet_aton(word, &res.ipv4_1)) { match++; t = &table[i]; } break; case IPv4_SECOND: if (word != NULL && inet_aton(word, &res.ipv4_2)) { match++; t = &table[i]; } break; case MAC: if (word != NULL && (mac = ether_aton(word))) { match++; t = &table[i]; memcpy(&res.mac, mac, ETHER_ADDR_LEN); } break; case OPT_TYPE: res.opt_type = atoi(word); if (res.opt_type > 0 && res.opt_type < 255) { match++; t = &table[i]; } break; case OPT_LENGTH: res.opt_length = atoi(word); if (res.opt_length > 0 && res.opt_length < 255) { match++; t = &table[i]; } break; case OPT_VALUE: memcpy(res.opt_value, word, res.opt_length); match++; t = &table[i]; break; case ENDTOKEN: break; } } if (match != 1) { if (word == NULL) fprintf(stderr, "missing argument:\n"); else if (match > 1) fprintf(stderr, "ambiguous argument: %s\n", word); else if (match < 1) fprintf(stderr, "unknown argument: %s\n", word); return (NULL); } return (t); }