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