miniupnpd 1.9 (20160113)
[tomato.git] / release / src / router / miniupnpd / pcplearndscp.c
blobc1b3e22e579d409ab9d3cb799aec7248857e272c
1 /* $Id: pcplearndscp.c,v 1.2 2016/01/13 16:02:08 nanard Exp $ */
2 /* MiniUPnP project
3 * Website : http://miniupnp.free.fr/
4 * Author : Miroslav Bagljas
6 Copyright (c) 2013 by Cisco Systems, Inc.
7 All rights reserved.
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are met:
12 * Redistributions of source code must retain the above copyright notice,
13 this list of conditions and the following disclaimer.
14 * Redistributions in binary form must reproduce the above copyright notice,
15 this list of conditions and the following disclaimer in the documentation
16 and/or other materials provided with the distribution.
17 * The name of the author may not be used to endorse or promote products
18 derived from this software without specific prior written permission.
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 POSSIBILITY OF SUCH DAMAGE.
33 #include "config.h"
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <ctype.h>
39 #include <syslog.h>
41 #include "upnpglobalvars.h"
42 #include "pcplearndscp.h"
44 #ifdef PCP_SADSCP
46 void
47 print_dscp(void) {
48 unsigned int i;
50 for (i=0; i < num_dscp_values; i++){
51 syslog(LOG_DEBUG, "Appname %*.s, del %d, loss %d, jitter %d, dscp %d",
52 dscp_values_list[i].app_name_len,
53 dscp_values_list[i].app_name, dscp_values_list[i].delay,
54 dscp_values_list[i].loss, dscp_values_list[i].jitter,
55 dscp_values_list[i].dscp_value
60 int
61 read_learn_dscp_line(struct dscp_values *dscpvalues, char *p)
63 char * q;
64 size_t len;
65 unsigned int sizeof_first_token = sizeof("set_learn_dscp") - 1;
66 int af_value;
67 int cs_value;
69 /* first token: (set_learn_dscp) skip it */
70 while(isspace(*p))
71 p++;
72 if(0 == memcmp(p, "set_learn_dscp", sizeof_first_token))
74 p += sizeof_first_token;
76 else
78 return -1;
80 while(isspace(*p))
81 p++;
83 /* second token: name of the application */
84 // if
85 if(!(*p == '"'))
86 return -1;
87 p++;
88 for(q = p; !(*q == '"'); q++);
89 len = q - p;
90 if (len != 0) {
91 dscpvalues->app_name = strndup(p, len);
92 } else {
93 dscpvalues->app_name = NULL;
95 dscpvalues->app_name_len = len;
96 p = q + 1;
98 /* third token: delay */
99 while(isspace(*p))
100 p++;
101 if(!isdigit(*p))
102 goto exit_err_and_cleanup;
103 for(q = p; isdigit(*q); q++);
104 if(isspace(*q))
106 *q = '\0';
107 dscpvalues->delay = (unsigned char)atoi(p);
108 if (dscpvalues->delay >= 3) {
109 fprintf(stderr, "Wrong delay value %d in \n", dscpvalues->delay);
110 fprintf(stderr, "Delay can be from set {0,1,2} 0=low delay, 1=medium delay, 2=high delay\n");
111 goto exit_err_and_cleanup;
114 else
116 goto exit_err_and_cleanup;
118 p = q + 1;
120 /* fourth token: loss */
121 while(isspace(*p))
122 p++;
123 if(!isdigit(*p))
124 goto exit_err_and_cleanup;
126 for(q = p; isdigit(*q); q++);
127 if(isspace(*q))
129 *q = '\0';
130 dscpvalues->loss = (unsigned char)atoi(p);
131 if (dscpvalues->loss >= 3) {
132 fprintf(stderr, "Wrong loss value %d \n", dscpvalues->loss);
133 fprintf(stderr, "Delay can be from set {0,1,2} 0=low loss, 1=medium loss, 2=high loss\n");
134 goto exit_err_and_cleanup;
137 else
139 goto exit_err_and_cleanup;
141 p = q + 1;
143 /* fifth token: jitter */
144 while(isspace(*p))
145 p++;
146 if(!isdigit(*p))
147 goto exit_err_and_cleanup;
148 for(q = p; isdigit(*q); q++);
149 if(isspace(*q))
151 *q = '\0';
152 dscpvalues->jitter = (unsigned char)atoi(p);
153 if (dscpvalues->jitter >= 3) {
154 fprintf(stderr, "Wrong jitter value %d \n", dscpvalues->jitter);
155 fprintf(stderr, "Delay can be from set {0,1,2} 0=low jitter, 1=medium jitter, 2=high jitter \n");
156 goto exit_err_and_cleanup;
159 else
161 goto exit_err_and_cleanup;
163 p = q + 1;
164 while(isspace(*p))
165 p++;
168 p = q + 1;
170 /* sixth token: DSCP value */
171 while(isspace(*p))
172 p++;
173 if(!isdigit(*p) && !( toupper(*p) == 'A' && toupper(*(p+1)) == 'F') &&
174 !( toupper(*p) == 'C' && toupper(*(p+1)) == 'S') &&
175 !( toupper(*p) == 'E' && toupper(*(p+1)) == 'F')
177 goto exit_err_and_cleanup;
178 // for(q = p; isdigit(*q) || (toupper(*q) == 'A') || (toupper(*q) == 'F'); q++);
179 for(q = p; isdigit(*q) || isalpha(*q); q++);
180 if(isspace(*q) || *q == '\0')
182 *q = '\0';
183 if (toupper(*p) == 'A' && toupper(*(p+1)) == 'F'){
184 p = p+2;
185 if (*p == '\0') {
186 dscpvalues->dscp_value = 0;
188 else if (!isdigit(*p)) {
189 goto exit_err_and_cleanup;
191 else {
192 af_value = atoi(p);
193 switch(af_value) {
194 case 11:
195 dscpvalues->dscp_value = 10;
196 break;
197 case 12:
198 dscpvalues->dscp_value = 12;
199 break;
200 case 13:
201 dscpvalues->dscp_value = 14;
202 break;
203 case 21:
204 dscpvalues->dscp_value = 18;
205 break;
206 case 22:
207 dscpvalues->dscp_value = 20;
208 break;
209 case 23:
210 dscpvalues->dscp_value = 22;
211 break;
212 case 31:
213 dscpvalues->dscp_value = 26;
214 break;
215 case 32:
216 dscpvalues->dscp_value = 28;
217 break;
218 case 33:
219 dscpvalues->dscp_value = 30;
220 break;
221 case 41:
222 dscpvalues->dscp_value = 34;
223 break;
224 case 42:
225 dscpvalues->dscp_value = 36;
226 break;
227 case 43:
228 dscpvalues->dscp_value = 38;
229 break;
230 default:
231 fprintf(stderr, "Unknown AF value %d \n", af_value);
232 goto exit_err_and_cleanup;
236 else if (toupper(*p) == 'C' && toupper(*(p+1)) == 'S'){
237 p=p+2;
238 if (*p == '\0') {
239 dscpvalues->dscp_value = 0;
241 else if (!isdigit(*p)) {
242 fprintf(stderr, "Not digit after CS but %c \n", *p);
243 goto exit_err_and_cleanup;
245 else {
246 cs_value = atoi(p);
247 switch(cs_value) {
248 case 1:
249 dscpvalues->dscp_value = 8;
250 break;
251 case 2:
252 dscpvalues->dscp_value = 16;
253 break;
254 case 3:
255 dscpvalues->dscp_value = 24;
256 break;
257 case 4:
258 dscpvalues->dscp_value = 32;
259 break;
260 case 5:
261 dscpvalues->dscp_value = 40;
262 break;
263 case 6:
264 dscpvalues->dscp_value = 48;
265 break;
266 case 7:
267 dscpvalues->dscp_value = 56;
268 break;
269 default:
270 fprintf(stderr, "Unknown CS value %d \n", cs_value);
271 goto exit_err_and_cleanup;
275 else if (toupper(*p) == 'E' && toupper(*(p+1)) == 'F'){
276 dscpvalues->dscp_value = 46;
278 else {
279 dscpvalues->dscp_value = (unsigned char)atoi(p);
282 else
284 goto exit_err_and_cleanup;
287 return 0;
289 exit_err_and_cleanup:
290 free(dscpvalues->app_name);
291 dscpvalues->app_name = NULL;
292 dscpvalues->app_name_len = 0;
293 return -1;
298 #endif