Home | History | Annotate | Download | only in pppoatm
      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 
     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 
     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 
    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