Jan Engelhardt | 0720c12 | 2008-01-20 13:22:42 +0000 | [diff] [blame] | 1 | #include <stdbool.h> |
| 2 | #include <stdint.h> |
| 3 | #include <stdio.h> |
Jan Engelhardt | ef18e81 | 2008-08-04 12:47:48 +0200 | [diff] [blame] | 4 | #include <linux/ip.h> |
Jan Engelhardt | 0720c12 | 2008-01-20 13:22:42 +0000 | [diff] [blame] | 5 | |
| 6 | struct tos_value_mask { |
| 7 | uint8_t value, mask; |
| 8 | }; |
| 9 | |
| 10 | static const struct tos_symbol_info { |
| 11 | unsigned char value; |
| 12 | const char *name; |
| 13 | } tos_symbol_names[] = { |
| 14 | {IPTOS_LOWDELAY, "Minimize-Delay"}, |
| 15 | {IPTOS_THROUGHPUT, "Maximize-Throughput"}, |
| 16 | {IPTOS_RELIABILITY, "Maximize-Reliability"}, |
| 17 | {IPTOS_MINCOST, "Minimize-Cost"}, |
| 18 | {IPTOS_NORMALSVC, "Normal-Service"}, |
Max Kellermann | 9ee386a | 2008-01-29 13:48:05 +0000 | [diff] [blame] | 19 | { .name = NULL } |
Jan Engelhardt | 0720c12 | 2008-01-20 13:22:42 +0000 | [diff] [blame] | 20 | }; |
| 21 | |
| 22 | /* |
| 23 | * tos_parse_numeric - parse sth. like "15/255" |
| 24 | * |
| 25 | * @s: input string |
| 26 | * @info: accompanying structure |
| 27 | * @bits: number of bits that are allowed |
| 28 | * (8 for IPv4 TOS field, 4 for IPv6 Priority Field) |
| 29 | */ |
| 30 | static bool tos_parse_numeric(const char *str, struct tos_value_mask *tvm, |
| 31 | unsigned int bits) |
| 32 | { |
| 33 | const unsigned int max = (1 << bits) - 1; |
| 34 | unsigned int value; |
| 35 | char *end; |
| 36 | |
Jan Engelhardt | 5f2922c | 2009-01-27 18:43:01 +0100 | [diff] [blame] | 37 | xtables_strtoui(str, &end, &value, 0, max); |
Jan Engelhardt | 0720c12 | 2008-01-20 13:22:42 +0000 | [diff] [blame] | 38 | tvm->value = value; |
| 39 | tvm->mask = max; |
| 40 | |
| 41 | if (*end == '/') { |
| 42 | const char *p = end + 1; |
| 43 | |
Jan Engelhardt | 5f2922c | 2009-01-27 18:43:01 +0100 | [diff] [blame] | 44 | if (!xtables_strtoui(p, &end, &value, 0, max)) |
Jan Engelhardt | 0720c12 | 2008-01-20 13:22:42 +0000 | [diff] [blame] | 45 | exit_error(PARAMETER_PROBLEM, "Illegal value: \"%s\"", |
| 46 | str); |
| 47 | tvm->mask = value; |
| 48 | } |
| 49 | |
| 50 | if (*end != '\0') |
| 51 | exit_error(PARAMETER_PROBLEM, "Illegal value: \"%s\"", str); |
| 52 | return true; |
| 53 | } |
| 54 | |
| 55 | static bool tos_parse_symbolic(const char *str, struct tos_value_mask *tvm, |
| 56 | unsigned int def_mask) |
| 57 | { |
Jan Engelhardt | e917bca | 2009-01-27 18:14:21 +0100 | [diff] [blame] | 58 | const unsigned int max = UINT8_MAX; |
Jan Engelhardt | 0720c12 | 2008-01-20 13:22:42 +0000 | [diff] [blame] | 59 | const struct tos_symbol_info *symbol; |
Jan Engelhardt | 4ded0f1 | 2008-06-30 14:57:08 +0200 | [diff] [blame] | 60 | char *tmp; |
Jan Engelhardt | 0720c12 | 2008-01-20 13:22:42 +0000 | [diff] [blame] | 61 | |
Jan Engelhardt | 5f2922c | 2009-01-27 18:43:01 +0100 | [diff] [blame] | 62 | if (xtables_strtoui(str, &tmp, NULL, 0, max)) |
Jan Engelhardt | 0720c12 | 2008-01-20 13:22:42 +0000 | [diff] [blame] | 63 | return tos_parse_numeric(str, tvm, max); |
| 64 | |
| 65 | /* Do not consider ECN bits */ |
| 66 | tvm->mask = def_mask; |
| 67 | for (symbol = tos_symbol_names; symbol->name != NULL; ++symbol) |
| 68 | if (strcasecmp(str, symbol->name) == 0) { |
| 69 | tvm->value = symbol->value; |
| 70 | return true; |
| 71 | } |
| 72 | |
| 73 | exit_error(PARAMETER_PROBLEM, "Symbolic name \"%s\" is unknown", str); |
| 74 | return false; |
| 75 | } |
| 76 | |
| 77 | static bool tos_try_print_symbolic(const char *prefix, |
| 78 | u_int8_t value, u_int8_t mask) |
| 79 | { |
| 80 | const struct tos_symbol_info *symbol; |
| 81 | |
| 82 | if (mask != 0x3F) |
| 83 | return false; |
| 84 | |
| 85 | for (symbol = tos_symbol_names; symbol->name != NULL; ++symbol) |
| 86 | if (value == symbol->value) { |
| 87 | printf("%s%s ", prefix, symbol->name); |
| 88 | return true; |
| 89 | } |
| 90 | |
| 91 | return false; |
| 92 | } |