X-Git-Url: http://git.openwrt.org/?a=blobdiff_plain;f=options.c;h=2f419a3a9b45b63e88f1a739050fe3ba82841967;hb=HEAD;hp=b5d5c02ff2fa24f0c1f6bc057b56dd1c64451cb8;hpb=41c2ab5e5cf62a4c04707145c65d37e27d82d63f;p=project%2Ffirewall3.git diff --git a/options.c b/options.c index b5d5c02..2f419a3 100644 --- a/options.c +++ b/options.c @@ -77,6 +77,7 @@ const char *fw3_flag_names[__FW3_FLAG_MAX] = { "NOTRACK", "HELPER", "MARK", + "DSCP", "DNAT", "SNAT", "MASQUERADE", @@ -86,6 +87,12 @@ const char *fw3_flag_names[__FW3_FLAG_MAX] = { "DROP", }; +const char *fw3_reject_code_names[__FW3_REJECT_CODE_MAX] = { + "tcp-reset", + "port-unreach", + "adm-prohibited", +}; + const char *fw3_limit_units[__FW3_LIMIT_UNIT_MAX] = { "second", "minute", @@ -129,6 +136,32 @@ static const char *reflection_sources[] = { "external", }; +static const struct { const char *name; uint8_t dscp; } dscp_classes[] = { + { "CS0", 0x00 }, + { "CS1", 0x08 }, + { "CS2", 0x10 }, + { "CS3", 0x18 }, + { "CS4", 0x20 }, + { "CS5", 0x28 }, + { "CS6", 0x30 }, + { "CS7", 0x38 }, + { "BE", 0x00 }, + { "LE", 0x01 }, + { "AF11", 0x0a }, + { "AF12", 0x0c }, + { "AF13", 0x0e }, + { "AF21", 0x12 }, + { "AF22", 0x14 }, + { "AF23", 0x16 }, + { "AF31", 0x1a }, + { "AF32", 0x1c }, + { "AF33", 0x1e }, + { "AF41", 0x22 }, + { "AF42", 0x24 }, + { "AF43", 0x26 }, + { "EF", 0x2e } +}; + bool fw3_parse_bool(void *ptr, const char *val, bool is_list) @@ -169,6 +202,13 @@ fw3_parse_target(void *ptr, const char *val, bool is_list) FW3_FLAG_ACCEPT, FW3_FLAG_MASQUERADE); } +bool +fw3_parse_reject_code(void *ptr, const char *val, bool is_list) +{ + return parse_enum(ptr, val, &fw3_reject_code_names[FW3_REJECT_CODE_TCP_RESET], + FW3_REJECT_CODE_TCP_RESET, FW3_REJECT_CODE_ADM_PROHIBITED); +} + bool fw3_parse_limit(void *ptr, const char *val, bool is_list) { @@ -529,7 +569,7 @@ fw3_parse_icmptype(void *ptr, const char *val, bool is_list) } icmp.type6 = icmp.type; - icmp.code6_min = icmp.code_max; + icmp.code6_min = icmp.code_min; icmp.code6_max = icmp.code_max; v4 = true; @@ -641,6 +681,7 @@ fw3_parse_date(void *ptr, const char *val, bool is_list) { unsigned int year = 1970, mon = 1, day = 1, hour = 0, min = 0, sec = 0; struct tm tm = { 0 }; + time_t ts; char *p; year = strtoul(val, &p, 10); @@ -685,9 +726,11 @@ ret: tm.tm_min = min; tm.tm_sec = sec; - if (mktime(&tm) >= 0) + ts = mktime(&tm) - timezone; + + if (ts >= 0) { - *((struct tm *)ptr) = tm; + gmtime_r(&ts, (struct tm *)ptr); return true; } @@ -842,6 +885,39 @@ fw3_parse_mark(void *ptr, const char *val, bool is_list) return true; } +bool +fw3_parse_dscp(void *ptr, const char *val, bool is_list) +{ + uint32_t n; + char *e; + struct fw3_dscp *d = ptr; + + if (*val == '!') + { + d->invert = true; + while (isspace(*++val)); + } + + for (n = 0; n < sizeof(dscp_classes) / sizeof(dscp_classes[0]); n++) + { + if (strcmp(dscp_classes[n].name, val)) + continue; + + d->set = true; + d->dscp = dscp_classes[n].dscp; + return true; + } + + n = strtoul(val, &e, 0); + + if (e == val || *e || n > 0x3F) + return false; + + d->set = true; + d->dscp = n; + return true; +} + bool fw3_parse_setmatch(void *ptr, const char *val, bool is_list) { @@ -864,7 +940,7 @@ fw3_parse_setmatch(void *ptr, const char *val, bool is_list) return false; } - strncpy(m->name, p, sizeof(m->name)); + snprintf(m->name, sizeof(m->name), "%s", p); for (i = 0, p = strtok(NULL, " \t,"); i < 3 && p != NULL; @@ -912,7 +988,7 @@ fw3_parse_cthelper(void *ptr, const char *val, bool is_list) if (*val) { m.set = true; - strncpy(m.name, val, sizeof(m.name) - 1); + snprintf(m.name, sizeof(m.name), "%s", val); put_value(ptr, &m, sizeof(m), is_list); return true; } @@ -1095,6 +1171,9 @@ fw3_parse_blob_options(void *s, const struct fw3_option *opts, if (blobmsg_type(e) == BLOBMSG_TYPE_INT32) { snprintf(buf, sizeof(buf), "%d", blobmsg_get_u32(e)); v = buf; + } else if (blobmsg_type(o) == BLOBMSG_TYPE_BOOL) { + snprintf(buf, sizeof(buf), "%d", blobmsg_get_bool(o)); + v = buf; } else { v = blobmsg_get_string(e); } @@ -1114,6 +1193,9 @@ fw3_parse_blob_options(void *s, const struct fw3_option *opts, if (blobmsg_type(o) == BLOBMSG_TYPE_INT32) { snprintf(buf, sizeof(buf), "%d", blobmsg_get_u32(o)); v = buf; + } else if (blobmsg_type(o) == BLOBMSG_TYPE_BOOL) { + snprintf(buf, sizeof(buf), "%d", blobmsg_get_bool(o)); + v = buf; } else { v = blobmsg_get_string(o); } @@ -1164,35 +1246,46 @@ fw3_address_to_string(struct fw3_address *address, bool allow_invert, bool as_ci { char *p, ip[INET6_ADDRSTRLEN]; static char buf[INET6_ADDRSTRLEN * 2 + 2]; + size_t rem = sizeof(buf); + int len; p = buf; - if (address->invert && allow_invert) - p += sprintf(p, "!"); + if (address->invert && allow_invert) { + *p++ = '!'; + *p = 0; + rem--; + } inet_ntop(address->family == FW3_FAMILY_V4 ? AF_INET : AF_INET6, &address->address.v4, ip, sizeof(ip)); - p += sprintf(p, "%s", ip); + len = snprintf(p, rem, "%s", ip); + + if (len < 0 || len >= rem) + return buf; + + rem -= len; + p += len; if (address->range) { inet_ntop(address->family == FW3_FAMILY_V4 ? AF_INET : AF_INET6, &address->mask.v4, ip, sizeof(ip)); - p += sprintf(p, "-%s", ip); + snprintf(p, rem, "-%s", ip); } else if (!as_cidr) { inet_ntop(address->family == FW3_FAMILY_V4 ? AF_INET : AF_INET6, &address->mask.v4, ip, sizeof(ip)); - p += sprintf(p, "/%s", ip); + snprintf(p, rem, "/%s", ip); } else { - p += sprintf(p, "/%u", fw3_netmask2bitlen(address->family, - &address->mask.v6)); + snprintf(p, rem, "/%u", + fw3_netmask2bitlen(address->family, &address->mask.v6)); } return buf;