http://downloads.netgear.com/files/GPL/GPL_Source_V361j_DM111PSP_series_consumer_rele...
[bcm963xx.git] / userapps / opensource / atm2684 / atm / lib / atm2text.c
1 /* atm2text.c - Converts binary encoding of ATM address to textual
2                 representation */
3
4 /* Written 1995-1998 by Werner Almesberger, EPFL-LRC/ICA */
5
6
7 #include <stdio.h>
8 #include <string.h>
9
10 #include "atm.h"
11 #include "atmres.h"
12
13
14 static int put_item(char **buffer,int *length,int value)
15 {
16     char *walk,*scan;
17     char tmp;
18
19     if (!*length) return FATAL;
20     if (value <= 0) {
21         if (!value) *(*buffer)++ = '0';
22         else if (value == ATM_VCI_ANY) *(*buffer)++ = '*';
23             else if (value == ATM_VCI_UNSPEC) *(*buffer)++ = '?';
24                 else return FATAL;
25                         /* ATM_*_ANY and ATM_*_UNSPEC have all the same value,
26                            respectively */
27         (*length)--;
28         return 0;
29     }
30     for (walk = *buffer; value; value /= 10) {
31         if (!(*length)--) return FATAL;
32         *walk++ = '0'+(value % 10);
33     }
34     for (scan = walk-1; scan > *buffer; (*buffer)++) {
35         tmp = *scan;
36         *scan-- = **buffer;
37         **buffer = tmp;
38     }
39     *buffer = walk;
40     return 0;
41 }
42
43
44 static int do_pvc(char *buffer,int length,const struct sockaddr_atmpvc *addr,
45   int flags)
46 {
47     int orig_len;
48
49     orig_len = length;
50     if (put_item(&buffer,&length,addr->sap_addr.itf)) return FATAL;
51     if (!length--) return FATAL;
52     *buffer++ = '.';
53     if (put_item(&buffer,&length,addr->sap_addr.vpi)) return FATAL;
54     if (!length--) return FATAL;
55     *buffer++ = '.';
56     if (put_item(&buffer,&length,addr->sap_addr.vci)) return FATAL;
57     if (!length) return FATAL;
58     *buffer = 0;
59     return orig_len-length;
60 }
61
62
63 static int do_svc(char *buffer,int length,const struct sockaddr_atmsvc *addr,
64   int flags)
65 {
66     static int pure[] = { 20 };
67     static int bin[] = { 1,2,10,6,1 };
68     static int local[] = { 1,12,6,1 };
69     static int e164[] = { 4,6,1 };
70
71     int orig_len,len,i,left,value;
72     int *fmt;
73
74     orig_len = length;
75     if (!*addr->sas_addr.pub && !*addr->sas_addr.prv) return FATAL;
76     if (*addr->sas_addr.pub) {
77         len = strlen(addr->sas_addr.pub);
78         if (!*addr->sas_addr.prv && length >= len+2) {
79             *buffer++ = '+';
80             length--;
81         }
82         if (length < len+1) return FATAL;
83         strcpy(buffer,addr->sas_addr.pub);
84         buffer += len;
85         length -= len;
86         if (*addr->sas_addr.prv) {
87             if (!length--) return FATAL;
88             *buffer++ = '+';
89         }
90     }
91     if (*addr->sas_addr.prv) {
92         fmt = pure;
93         i = 0;
94         if (flags & A2T_PRETTY)
95             switch (*addr->sas_addr.prv) {
96                 case ATM_AFI_DCC:
97                 case ATM_AFI_ICD:
98                 case ATM_AFI_DCC_GROUP:
99                 case ATM_AFI_ICD_GROUP:
100                     fmt = bin;
101                     break;
102                 case ATM_AFI_LOCAL:
103                 case ATM_AFI_LOCAL_GROUP:
104                     fmt = local;
105                     break;
106                 case ATM_AFI_E164:
107                 case ATM_AFI_E164_GROUP:
108                     for (i = 2; i < 17; i++)
109                         if (addr->sas_addr.prv[i >> 1] & (0xf0 >> 4*(i & 1)))
110                             break;
111                     while (i < 17) {
112                         value = (addr->sas_addr.prv[i >> 1] >> 4*(1-(i & 1))) &
113                           0xf;
114                         if (value > 9) return FATAL;
115                         if (!length--) return FATAL;
116                         *buffer++ = '0'+value;
117                         i++;
118                     }
119                     if (!length--) return FATAL;
120                     *buffer++ = ':';
121                     i = 9;
122                     fmt = e164;
123                     break;
124                 default:
125                     break;
126             }
127         for (left = *fmt++; i < ATM_ESA_LEN; i++) {
128             if (!left--) {
129                 if (!length--) return FATAL;
130                 *buffer++ = '.';
131                 left = *fmt++-1;
132             }
133             if (length < 2) return FATAL;
134             sprintf(buffer,"%02X",addr->sas_addr.prv[i]);
135             length -= 2;
136             buffer += 2;
137         }
138     }
139     if (!length) return FATAL;
140     *buffer = 0;
141     return orig_len-length;
142 }
143
144
145 static int search(FILE *file,char *buffer,int length,
146   const struct sockaddr *addr,int flags)
147 {
148     struct sockaddr_atmsvc temp;
149     char line[MAX_ATM_NAME_LEN+1];
150     const char *here;
151  
152     while (fgets(line,MAX_ATM_NAME_LEN,file)) {
153         if (!(here = strtok(line,"\t\n "))) continue;
154         if (text2atm(here,(struct sockaddr *) &temp,sizeof(temp),flags) < 0)
155             continue;
156         if (temp.sas_family != addr->sa_family) continue;
157         if (temp.sas_family == AF_ATMPVC) {
158             if (((const struct sockaddr_atmpvc *) addr)->sap_addr.itf !=
159               ((struct sockaddr_atmpvc *) &temp)->sap_addr.itf ||
160               ((const struct sockaddr_atmpvc *) addr)->sap_addr.vpi !=
161               ((struct sockaddr_atmpvc *) &temp)->sap_addr.vpi ||
162               ((const struct sockaddr_atmpvc *) addr)->sap_addr.vci !=
163               ((struct sockaddr_atmpvc *) &temp)->sap_addr.vci) continue;
164         }
165         else if (!atm_equal(addr,(struct sockaddr *) &temp,0,0)) continue;
166         while ((here = strtok(NULL,"\t\n ")))
167             if (strlen(here) < length) {
168                 strcpy(buffer,here);
169                 return 0;
170             }
171         return FATAL;
172     }
173     return TRY_OTHER;
174 }
175  
176  
177 static int try_name(char *buffer,int length,const struct sockaddr *addr)
178 {
179     FILE *file;
180     int result;
181  
182     if (!(file = fopen(HOSTS_ATM,"r"))) return TRY_OTHER;
183     result = search(file,buffer,length,addr,addr->sa_family == AF_ATMPVC ?
184       T2A_PVC : T2A_SVC);
185     (void) fclose(file);
186     return result;
187 }
188
189
190 int atm2text(char *buffer,int length,const struct sockaddr *addr,int flags)
191 {
192     int result;
193
194     if (addr->sa_family != AF_ATMPVC && addr->sa_family != AF_ATMSVC)
195         return -1;
196     if (!length) return -1;
197     if (flags & A2T_NAME) {
198         result = try_name(buffer,length,addr);
199         if (result == TRY_OTHER && !(flags & A2T_LOCAL))
200             result = ans_byaddr(buffer,length,
201               (const struct sockaddr_atmsvc *) addr,flags);
202         if (result == FATAL) return FATAL;
203         if (result != TRY_OTHER) return strlen(buffer);
204     }
205     if (addr->sa_family == AF_ATMPVC)
206         return do_pvc(buffer,length,(const struct sockaddr_atmpvc *) addr,
207           flags);
208     else return do_svc(buffer,length,(const struct sockaddr_atmsvc *) addr,
209           flags);
210     return -1;
211 }