1 /* dscp lookup routines lifted wholesale from openssh */
2
3 /*
4 * Copyright (c) 2000 Markus Friedl. All rights reserved.
5 * Copyright (c) 2005,2006 Damien Miller. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #if HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31
32 #include <stdio.h>
33 #if HAVE_STRING_H
34 #include <string.h>
35 #endif
36 #if HAVE_STDLIB_H
37 #include <stdlib.h>
38 #endif
39
40 #if HAVE_INTTYPES_H
41 #include <inttypes.h>
42 #endif
43
44 #ifdef WIN32
45 #define strcasecmp(a,b) _stricmp(a,b)
46 #define snprintf _snprintf
47 #endif
48
49 int parse_ipqos(const char *cp);
50 const char * iptos2str(int iptos);
51
52 /*
53 * Definitions for IP type of service (ip_tos)
54 */
55
56 #if HAVE_NETINET_IN_SYSTM_H
57 #include <netinet/in_systm.h>
58 #endif
59 #if HAVE_NETINET_IP_H
60 #include <netinet/ip.h>
61 #endif
62
63 #ifndef IPTOS_LOWDELAY
64 # define IPTOS_LOWDELAY 0x10
65 # define IPTOS_THROUGHPUT 0x08
66 # define IPTOS_RELIABILITY 0x04
67 # define IPTOS_LOWCOST 0x02
68 # define IPTOS_MINCOST IPTOS_LOWCOST
69 #endif /* IPTOS_LOWDELAY */
70
71 /*
72 * Definitions for DiffServ Codepoints as per RFC2474
73 */
74 #ifndef IPTOS_DSCP_AF11
75 # define IPTOS_DSCP_AF11 0x28
76 # define IPTOS_DSCP_AF12 0x30
77 # define IPTOS_DSCP_AF13 0x38
78 # define IPTOS_DSCP_AF21 0x48
79 # define IPTOS_DSCP_AF22 0x50
80 # define IPTOS_DSCP_AF23 0x58
81 # define IPTOS_DSCP_AF31 0x68
82 # define IPTOS_DSCP_AF32 0x70
83 # define IPTOS_DSCP_AF33 0x78
84 # define IPTOS_DSCP_AF41 0x88
85 # define IPTOS_DSCP_AF42 0x90
86 # define IPTOS_DSCP_AF43 0x98
87 # define IPTOS_DSCP_EF 0xb8
88 #endif /* IPTOS_DSCP_AF11 */
89
90 #ifndef IPTOS_DSCP_CS0
91 # define IPTOS_DSCP_CS0 0x00
92 # define IPTOS_DSCP_CS1 0x20
93 # define IPTOS_DSCP_CS2 0x40
94 # define IPTOS_DSCP_CS3 0x60
95 # define IPTOS_DSCP_CS4 0x80
96 # define IPTOS_DSCP_CS5 0xa0
97 # define IPTOS_DSCP_CS6 0xc0
98 # define IPTOS_DSCP_CS7 0xe0
99 #endif /* IPTOS_DSCP_CS0 */
100 #ifndef IPTOS_DSCP_EF
101 # define IPTOS_DSCP_EF 0xb8
102 #endif /* IPTOS_DSCP_EF */
103
104 static const struct {
105 const char *name;
106 int value;
107 } ipqos[] = {
108 { "af11", IPTOS_DSCP_AF11 },
109 { "af12", IPTOS_DSCP_AF12 },
110 { "af13", IPTOS_DSCP_AF13 },
111 { "af21", IPTOS_DSCP_AF21 },
112 { "af22", IPTOS_DSCP_AF22 },
113 { "af23", IPTOS_DSCP_AF23 },
114 { "af31", IPTOS_DSCP_AF31 },
115 { "af32", IPTOS_DSCP_AF32 },
116 { "af33", IPTOS_DSCP_AF33 },
117 { "af41", IPTOS_DSCP_AF41 },
118 { "af42", IPTOS_DSCP_AF42 },
119 { "af43", IPTOS_DSCP_AF43 },
120 { "cs0", IPTOS_DSCP_CS0 },
121 { "cs1", IPTOS_DSCP_CS1 },
122 { "cs2", IPTOS_DSCP_CS2 },
123 { "cs3", IPTOS_DSCP_CS3 },
124 { "cs4", IPTOS_DSCP_CS4 },
125 { "cs5", IPTOS_DSCP_CS5 },
126 { "cs6", IPTOS_DSCP_CS6 },
127 { "cs7", IPTOS_DSCP_CS7 },
128 { "ef", IPTOS_DSCP_EF },
129 { "lowdelay", IPTOS_LOWDELAY },
130 { "throughput", IPTOS_THROUGHPUT },
131 { "reliability", IPTOS_RELIABILITY },
132 { NULL, -1 }
133 };
134
135 int
parse_ipqos(const char * cp)136 parse_ipqos(const char *cp)
137 {
138 unsigned int i;
139 char *ep = NULL;
140 long val;
141
142 if (cp == NULL)
143 return -1;
144 for (i = 0; ipqos[i].name != NULL; i++) {
145 if (strcasecmp(cp, ipqos[i].name) == 0)
146 return ipqos[i].value;
147 }
148 /* Try parsing as an integer */
149 val = strtol(cp, &ep, 0);
150 if (*cp == '\0' || *ep != '\0' || val < 0 || val > 255)
151 return -1;
152 return val;
153 }
154
155 const char *
iptos2str(int iptos)156 iptos2str(int iptos)
157 {
158 int i;
159 static char iptos_str[sizeof "0xff"];
160 if (iptos < 0 || iptos > 64) iptos = 0;
161 for (i = 0; ipqos[i].name != NULL; i++) {
162 if (ipqos[i].value == iptos)
163 return ipqos[i].name;
164 }
165 snprintf(iptos_str, sizeof iptos_str, "0x%02x", iptos);
166 return iptos_str;
167 }
168