1/* vi: set sw=4 ts=4: */
2/*
3 * rtm_map.c
4 *
5 *		This program is free software; you can redistribute it and/or
6 *		modify it under the terms of the GNU General Public License
7 *		as published by the Free Software Foundation; either version
8 *		2 of the License, or (at your option) any later version.
9 *
10 * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
11 *
12 */
13
14#include "libbb.h"
15#include "rt_names.h"
16#include "utils.h"
17
18const char *rtnl_rtntype_n2a(int id, char *buf, int len)
19{
20	switch (id) {
21	case RTN_UNSPEC:
22		return "none";
23	case RTN_UNICAST:
24		return "unicast";
25	case RTN_LOCAL:
26		return "local";
27	case RTN_BROADCAST:
28		return "broadcast";
29	case RTN_ANYCAST:
30		return "anycast";
31	case RTN_MULTICAST:
32		return "multicast";
33	case RTN_BLACKHOLE:
34		return "blackhole";
35	case RTN_UNREACHABLE:
36		return "unreachable";
37	case RTN_PROHIBIT:
38		return "prohibit";
39	case RTN_THROW:
40		return "throw";
41	case RTN_NAT:
42		return "nat";
43	case RTN_XRESOLVE:
44		return "xresolve";
45	default:
46		snprintf(buf, len, "%d", id);
47		return buf;
48	}
49}
50
51
52int rtnl_rtntype_a2n(int *id, char *arg)
53{
54	static const char keywords[] ALIGN1 =
55		"local\0""nat\0""broadcast\0""brd\0""anycast\0"
56		"multicast\0""prohibit\0""unreachable\0""blackhole\0"
57		"xresolve\0""unicast\0""throw\0";
58	enum {
59		ARG_local = 1, ARG_nat, ARG_broadcast, ARG_brd, ARG_anycast,
60		ARG_multicast, ARG_prohibit, ARG_unreachable, ARG_blackhole,
61		ARG_xresolve, ARG_unicast, ARG_throw
62	};
63	const smalluint key = index_in_substrings(keywords, arg) + 1;
64	char *end;
65	unsigned long res;
66
67	if (key == ARG_local)
68		res = RTN_LOCAL;
69	else if (key == ARG_nat)
70		res = RTN_NAT;
71	else if (key == ARG_broadcast || key == ARG_brd)
72		res = RTN_BROADCAST;
73	else if (key == ARG_anycast)
74		res = RTN_ANYCAST;
75	else if (key == ARG_multicast)
76		res = RTN_MULTICAST;
77	else if (key == ARG_prohibit)
78		res = RTN_PROHIBIT;
79	else if (key == ARG_unreachable)
80		res = RTN_UNREACHABLE;
81	else if (key == ARG_blackhole)
82		res = RTN_BLACKHOLE;
83	else if (key == ARG_xresolve)
84		res = RTN_XRESOLVE;
85	else if (key == ARG_unicast)
86		res = RTN_UNICAST;
87	else if (key == ARG_throw)
88		res = RTN_THROW;
89	else {
90		res = strtoul(arg, &end, 0);
91		if (!end || end == arg || *end || res > 255)
92			return -1;
93	}
94	*id = res;
95	return 0;
96}
97
98int get_rt_realms(uint32_t *realms, char *arg)
99{
100	uint32_t realm = 0;
101	char *p = strchr(arg, '/');
102
103	*realms = 0;
104	if (p) {
105		*p = 0;
106		if (rtnl_rtrealm_a2n(realms, arg)) {
107			*p = '/';
108			return -1;
109		}
110		*realms <<= 16;
111		*p = '/';
112		arg = p+1;
113	}
114	if (*arg && rtnl_rtrealm_a2n(&realm, arg))
115		return -1;
116	*realms |= realm;
117	return 0;
118}
119