X-Git-Url: http://git.archive.openwrt.org/?p=project%2Ffirewall3.git;a=blobdiff_plain;f=options.c;h=ae6bf5dbd89ec0da9462a75ce3ece2567f4cc249;hp=292f5fc322f7d93facb08f8c1a2458708c80bfa3;hb=3d2c18a91bb7cd5f3c0dec7fecf3008934de170b;hpb=bba31cce0521e014109fc805671d4cff7ee9dbf6 diff --git a/options.c b/options.c index 292f5fc..ae6bf5d 100644 --- a/options.c +++ b/options.c @@ -1,7 +1,7 @@ /* * firewall3 - 3rd OpenWrt UCI firewall implementation * - * Copyright (C) 2013-2014 Jo-Philipp Wich + * Copyright (C) 2013-2014 Jo-Philipp Wich * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -268,12 +268,15 @@ fw3_parse_address(void *ptr, const char *val, bool is_list) addr.family = FW3_FAMILY_V6; addr.address.v6 = v6; - if (m && !inet_pton(AF_INET6, m, &addr.mask.v6)) + if (m) { - bits = strtol(m, &e, 10); + if (!inet_pton(AF_INET6, m, &v6)) + { + bits = strtol(m, &e, 10); - if ((*e != 0) || !fw3_bitlen2netmask(addr.family, bits, &v6)) - goto fail; + if ((*e != 0) || !fw3_bitlen2netmask(addr.family, bits, &v6)) + goto fail; + } addr.mask.v6 = v6; } @@ -294,12 +297,15 @@ fw3_parse_address(void *ptr, const char *val, bool is_list) addr.family = FW3_FAMILY_V4; addr.address.v4 = v4; - if (m && !inet_pton(AF_INET, m, &addr.mask.v4)) + if (m) { - bits = strtol(m, &e, 10); + if (!inet_pton(AF_INET, m, &v4)) + { + bits = strtol(m, &e, 10); - if ((*e != 0) || !fw3_bitlen2netmask(addr.family, bits, &v4)) - goto fail; + if ((*e != 0) || !fw3_bitlen2netmask(addr.family, bits, &v4)) + goto fail; + } addr.mask.v4 = v4; } @@ -436,7 +442,7 @@ fw3_parse_port(void *ptr, const char *val, bool is_list) bool fw3_parse_family(void *ptr, const char *val, bool is_list) { - if (!strcmp(val, "any")) + if (!strcmp(val, "any") || !strcmp(val, "*")) *((enum fw3_family *)ptr) = FW3_FAMILY_ANY; else if (!strcmp(val, "inet") || strrchr(val, '4')) *((enum fw3_family *)ptr) = FW3_FAMILY_V4; @@ -537,7 +543,7 @@ fw3_parse_protocol(void *ptr, const char *val, bool is_list) while (isspace(*++val)); } - if (!strcmp(val, "all")) + if (!strcmp(val, "all") || !strcmp(val, "any") || !strcmp(val, "*")) { proto.any = true; put_value(ptr, &proto, sizeof(proto), is_list); @@ -712,7 +718,7 @@ fw3_parse_weekdays(void *ptr, const char *val, bool is_list) if (*val == '!') { - setbit(*(uint8_t *)ptr, 0); + fw3_setbit(*(uint8_t *)ptr, 0); while (isspace(*++val)); } @@ -732,7 +738,7 @@ fw3_parse_weekdays(void *ptr, const char *val, bool is_list) } } - setbit(*(uint8_t *)ptr, w); + fw3_setbit(*(uint8_t *)ptr, w); } free(s); @@ -747,7 +753,7 @@ fw3_parse_monthdays(void *ptr, const char *val, bool is_list) if (*val == '!') { - setbit(*(uint32_t *)ptr, 0); + fw3_setbit(*(uint32_t *)ptr, 0); while (isspace(*++val)); } @@ -764,7 +770,7 @@ fw3_parse_monthdays(void *ptr, const char *val, bool is_list) return false; } - setbit(*(uint32_t *)ptr, d); + fw3_setbit(*(uint32_t *)ptr, d); } free(s); @@ -885,7 +891,7 @@ fw3_parse_options(void *s, const struct fw3_option *opts, struct uci_section *section) { char *p, *v; - bool known; + bool known, inv; struct uci_element *e, *l; struct uci_option *o; const struct fw3_option *opt; @@ -947,10 +953,30 @@ fw3_parse_options(void *s, const struct fw3_option *opts, } else { + inv = false; dest = (struct list_head *)((char *)s + opt->offset); for (p = strtok(v, " \t"); p != NULL; p = strtok(NULL, " \t")) { + /* If we encounter a sole "!" token, assume that it + * is meant to be part of the next token, so silently + * skip it and remember the state... */ + if (!strcmp(p, "!")) + { + inv = true; + continue; + } + + /* The previous token was a sole "!", rewind pointer + * back by one byte to precede the value with an + * exclamation mark which effectively turns + * ("!", "foo") into ("!foo") */ + if (inv) + { + *--p = '!'; + inv = false; + } + if (!opt->parse(dest, p, true)) { warn_elem(e, "has invalid value '%s'", p); @@ -958,6 +984,15 @@ fw3_parse_options(void *s, const struct fw3_option *opts, continue; } } + + /* The last token was a sole "!" without any subsequent + * text, so pass it to the option parser as-is. */ + if (inv && !opt->parse(dest, "!", true)) + { + warn_elem(e, "has invalid value '%s'", p); + valid = false; + continue; + } } } @@ -975,7 +1010,7 @@ fw3_parse_options(void *s, const struct fw3_option *opts, bool fw3_parse_blob_options(void *s, const struct fw3_option *opts, - struct blob_attr *a) + struct blob_attr *a, const char *name) { char *p, *v, buf[16]; bool known; @@ -1001,7 +1036,9 @@ fw3_parse_blob_options(void *s, const struct fw3_option *opts, { if (!opt->elem_size) { - fprintf(stderr, "%s must not be a list\n", opt->name); + fprintf(stderr, "%s: '%s' must not be a list\n", + name, opt->name); + valid = false; } else @@ -1019,7 +1056,8 @@ fw3_parse_blob_options(void *s, const struct fw3_option *opts, if (!opt->parse(dest, v, true)) { - fprintf(stderr, "%s has invalid value '%s'\n", opt->name, v); + fprintf(stderr, "%s: '%s' has invalid value '%s'\n", + name, opt->name, v); valid = false; continue; } @@ -1042,7 +1080,8 @@ fw3_parse_blob_options(void *s, const struct fw3_option *opts, { if (!opt->parse((char *)s + opt->offset, v, false)) { - fprintf(stderr, "%s has invalid value '%s'\n", opt->name, v); + fprintf(stderr, "%s: '%s' has invalid value '%s'\n", + name, opt->name, v); valid = false; } } @@ -1054,7 +1093,8 @@ fw3_parse_blob_options(void *s, const struct fw3_option *opts, { if (!opt->parse(dest, p, true)) { - fprintf(stderr, "%s has invalid value '%s'\n", opt->name, p); + fprintf(stderr, "%s: '%s' has invalid value '%s'\n", + name, opt->name, p); valid = false; continue; } @@ -1066,8 +1106,8 @@ fw3_parse_blob_options(void *s, const struct fw3_option *opts, break; } - if (!known) - fprintf(stderr, "%s is unknown\n", blobmsg_name(o)); + if (!known && strcmp(blobmsg_name(o), "type")) + fprintf(stderr, "%s: '%s' is unknown\n", name, blobmsg_name(o)); } return valid;