tos_values.c revision e917bca09924435f3fca23c01042543b1826c81e
1#include <stdbool.h>
2#include <stdint.h>
3#include <stdio.h>
4#include <linux/ip.h>
5
6struct tos_value_mask {
7	uint8_t value, mask;
8};
9
10static 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"},
19	{ .name = NULL }
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 */
30static 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
37	strtonum(str, &end, &value, 0, max);
38	tvm->value = value;
39	tvm->mask  = max;
40
41	if (*end == '/') {
42		const char *p = end + 1;
43
44		if (!strtonum(p, &end, &value, 0, max))
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
55static bool tos_parse_symbolic(const char *str, struct tos_value_mask *tvm,
56    unsigned int def_mask)
57{
58	const unsigned int max = UINT8_MAX;
59	const struct tos_symbol_info *symbol;
60	char *tmp;
61
62	if (strtonum(str, &tmp, NULL, 0, max))
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
77static 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}
93