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 25int __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 80static 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 125int 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