1 /* text2qos.c - Converts textual representation of QOS parameters to binary
2 encoding */
3
4 /* Written 1996-2000 by Werner Almesberger, EPFL-LRC/ICA */
5
6 #if HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9
10 #include <stdlib.h>
11 #include <stdarg.h>
12 #include <string.h>
13 #include <ctype.h>
14 #include <limits.h>
15
16 #include "atm.h"
17
18
19 #define fetch __atmlib_fetch
20
21
22 #define RATE_ERROR -2
23
24
__t2q_get_rate(const char ** text,int up)25 int __t2q_get_rate(const char **text,int up)
26 {
27 const char mult[] = "kKmMgGg";
28 const char *multiplier;
29 char *end;
30 unsigned int rate,fract;
31 int power;
32
33 if (!strncmp(*text,"max",3)) {
34 *text += 3;
35 return ATM_MAX_PCR;
36 }
37 rate = strtoul(*text,&end,10);
38 power = fract = 0;
39 if (*end == '.')
40 for (end++; *end && isdigit(*end); end++) {
41 fract = fract*10+*end-48;
42 if (--power == -9) break;
43 }
44 multiplier = NULL;
45 if (*end && (multiplier = strchr(mult,*end))) {
46 while (multiplier >= mult) {
47 if (rate > UINT_MAX/1000) return RATE_ERROR;
48 rate *= 1000;
49 power += 3;
50 multiplier -= 2;
51 }
52 end++;
53 }
54 while (power && fract)
55 if (power < 0) {
56 fract /= 10;
57 power++;
58 }
59 else {
60 fract *= 10;
61 power--;
62 }
63 rate += fract;
64 if (strlen(end) < 3) {
65 if (multiplier) return RATE_ERROR;
66 }
67 else if (!strncmp(end,"cps",3)) end += 3;
68 else if (!strncmp(end,"bps",3)) {
69 rate = (rate+(up ? 8*ATM_CELL_PAYLOAD-1 : 0))/8/
70 ATM_CELL_PAYLOAD;
71 end += 3;
72 }
73 else if (multiplier) return RATE_ERROR;
74 if (rate > INT_MAX) return RATE_ERROR;
75 *text = end;
76 return rate;
77 }
78
79
params(const char ** text,struct atm_trafprm * a,struct atm_trafprm * b)80 static int params(const char **text,struct atm_trafprm *a,
81 struct atm_trafprm *b)
82 {
83 int value;
84 char *end;
85
86 if (*(*text)++ != ':') return -1;
87 while (1) {
88 if (!**text) return -1;
89 switch (fetch(text,"max_pcr=","pcr=","min_pcr=","max_sdu=","sdu=",
90 NULL)) {
91 case 0:
92 if ((value = __t2q_get_rate(text,0)) == RATE_ERROR) return -1;
93 if (a) a->max_pcr = value;
94 if (b) b->max_pcr = value;
95 break;
96 case 1:
97 if ((value = __t2q_get_rate(text,0)) == RATE_ERROR) return -1;
98 if (a) a->pcr = value;
99 if (b) b->pcr = value;
100 break;
101 case 2:
102 if ((value = __t2q_get_rate(text,1)) == RATE_ERROR) return -1;
103 if (value == ATM_MAX_PCR) return -1;
104 if (a) a->min_pcr = value;
105 if (b) b->min_pcr = value;
106 break;
107 case 3:
108 case 4:
109 value = strtol(*text,&end,10);
110 if (value < 0) return -1;
111 *text = end;
112 if (a) a->max_sdu = value;
113 if (b) b->max_sdu = value;
114 break;
115 default:
116 return 0;
117 }
118 if (!**text) break;
119 if (*(*text)++ != ',') return -1;
120 }
121 return 0;
122 }
123
124
text2qos(const char * text,struct atm_qos * qos,int flags)125 int text2qos(const char *text,struct atm_qos *qos,int flags)
126 {
127 int traffic_class,aal;
128
129 traffic_class = ATM_NONE;
130 aal = ATM_NO_AAL;
131 do {
132 static const unsigned char aal_number[] = { ATM_AAL0, ATM_AAL5 };
133 int item;
134
135 item = fetch(&text,"!none","ubr","cbr","vbr","abr","aal0","aal5",NULL);
136 switch (item) {
137 case 1:
138 case 2:
139 /* we don't support VBR yet */
140 case 4:
141 traffic_class = item;
142 break;
143 case 5:
144 case 6:
145 aal = aal_number[item-5];
146 break;
147 default:
148 return -1;
149 }
150 }
151 while (*text == ',' ? text++ : 0);
152 if (!traffic_class) return -1;
153 if (qos && !(flags & T2Q_DEFAULTS)) memset(qos,0,sizeof(*qos));
154 if (qos) qos->txtp.traffic_class = qos->rxtp.traffic_class = traffic_class;
155 if (qos && aal) qos->aal = aal;
156 if (!*text) return 0;
157 if (params(&text,qos ? &qos->txtp : NULL,qos ? &qos->rxtp : NULL))
158 return -1;
159 if (!*text) return 0;
160 switch (fetch(&text,"tx","rx",NULL)) {
161 case 0:
162 if (!fetch(&text,":none",NULL)) {
163 if (qos) qos->txtp.traffic_class = ATM_NONE;
164 if (*text == ',') text++;
165 break;
166 }
167 if (params(&text,qos ? &qos->txtp : NULL,NULL)) return -1;
168 break;
169 case 1:
170 text -= 2;
171 break;
172 default:
173 return -1;
174 }
175 if (!*text) return 0;
176 if (fetch(&text,"rx",NULL)) return -1;
177 if (!fetch(&text,":none",NULL) && qos) qos->rxtp.traffic_class = ATM_NONE;
178 else if (params(&text,qos ? &qos->rxtp : NULL,NULL)) return -1;
179 return *text ? -1 : 0;
180 }
181