| #include <stdbool.h> |
| #include <stdint.h> |
| #include <stdio.h> |
| #include <linux/ip.h> |
| |
| struct tos_value_mask { |
| uint8_t value, mask; |
| }; |
| |
| static const struct tos_symbol_info { |
| unsigned char value; |
| const char *name; |
| } tos_symbol_names[] = { |
| {IPTOS_LOWDELAY, "Minimize-Delay"}, |
| {IPTOS_THROUGHPUT, "Maximize-Throughput"}, |
| {IPTOS_RELIABILITY, "Maximize-Reliability"}, |
| {IPTOS_MINCOST, "Minimize-Cost"}, |
| {IPTOS_NORMALSVC, "Normal-Service"}, |
| { .name = NULL } |
| }; |
| |
| /* |
| * tos_parse_numeric - parse sth. like "15/255" |
| * |
| * @s: input string |
| * @info: accompanying structure |
| * @bits: number of bits that are allowed |
| * (8 for IPv4 TOS field, 4 for IPv6 Priority Field) |
| */ |
| static bool tos_parse_numeric(const char *str, struct tos_value_mask *tvm, |
| unsigned int bits) |
| { |
| const unsigned int max = (1 << bits) - 1; |
| unsigned int value; |
| char *end; |
| |
| xtables_strtoui(str, &end, &value, 0, max); |
| tvm->value = value; |
| tvm->mask = max; |
| |
| if (*end == '/') { |
| const char *p = end + 1; |
| |
| if (!xtables_strtoui(p, &end, &value, 0, max)) |
| xtables_error(PARAMETER_PROBLEM, "Illegal value: \"%s\"", |
| str); |
| tvm->mask = value; |
| } |
| |
| if (*end != '\0') |
| xtables_error(PARAMETER_PROBLEM, "Illegal value: \"%s\"", str); |
| return true; |
| } |
| |
| static bool tos_parse_symbolic(const char *str, struct tos_value_mask *tvm, |
| unsigned int def_mask) |
| { |
| const unsigned int max = UINT8_MAX; |
| const struct tos_symbol_info *symbol; |
| char *tmp; |
| |
| if (xtables_strtoui(str, &tmp, NULL, 0, max)) |
| return tos_parse_numeric(str, tvm, max); |
| |
| /* Do not consider ECN bits */ |
| tvm->mask = def_mask; |
| for (symbol = tos_symbol_names; symbol->name != NULL; ++symbol) |
| if (strcasecmp(str, symbol->name) == 0) { |
| tvm->value = symbol->value; |
| return true; |
| } |
| |
| xtables_error(PARAMETER_PROBLEM, "Symbolic name \"%s\" is unknown", str); |
| return false; |
| } |
| |
| static bool tos_try_print_symbolic(const char *prefix, |
| u_int8_t value, u_int8_t mask) |
| { |
| const struct tos_symbol_info *symbol; |
| |
| if (mask != 0x3F) |
| return false; |
| |
| for (symbol = tos_symbol_names; symbol->name != NULL; ++symbol) |
| if (value == symbol->value) { |
| printf("%s%s ", prefix, symbol->name); |
| return true; |
| } |
| |
| return false; |
| } |