1 /* atm2text.c - Converts binary encoding of ATM address to textual
4 /* Written 1995-1998 by Werner Almesberger, EPFL-LRC/ICA */
14 static int put_item(char **buffer,int *length,int value)
19 if (!*length) return FATAL;
21 if (!value) *(*buffer)++ = '0';
22 else if (value == ATM_VCI_ANY) *(*buffer)++ = '*';
23 else if (value == ATM_VCI_UNSPEC) *(*buffer)++ = '?';
25 /* ATM_*_ANY and ATM_*_UNSPEC have all the same value,
30 for (walk = *buffer; value; value /= 10) {
31 if (!(*length)--) return FATAL;
32 *walk++ = '0'+(value % 10);
34 for (scan = walk-1; scan > *buffer; (*buffer)++) {
44 static int do_pvc(char *buffer,int length,const struct sockaddr_atmpvc *addr,
50 if (put_item(&buffer,&length,addr->sap_addr.itf)) return FATAL;
51 if (!length--) return FATAL;
53 if (put_item(&buffer,&length,addr->sap_addr.vpi)) return FATAL;
54 if (!length--) return FATAL;
56 if (put_item(&buffer,&length,addr->sap_addr.vci)) return FATAL;
57 if (!length) return FATAL;
59 return orig_len-length;
63 static int do_svc(char *buffer,int length,const struct sockaddr_atmsvc *addr,
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 };
71 int orig_len,len,i,left,value;
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) {
82 if (length < len+1) return FATAL;
83 strcpy(buffer,addr->sas_addr.pub);
86 if (*addr->sas_addr.prv) {
87 if (!length--) return FATAL;
91 if (*addr->sas_addr.prv) {
94 if (flags & A2T_PRETTY)
95 switch (*addr->sas_addr.prv) {
98 case ATM_AFI_DCC_GROUP:
99 case ATM_AFI_ICD_GROUP:
103 case ATM_AFI_LOCAL_GROUP:
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)))
112 value = (addr->sas_addr.prv[i >> 1] >> 4*(1-(i & 1))) &
114 if (value > 9) return FATAL;
115 if (!length--) return FATAL;
116 *buffer++ = '0'+value;
119 if (!length--) return FATAL;
127 for (left = *fmt++; i < ATM_ESA_LEN; i++) {
129 if (!length--) return FATAL;
133 if (length < 2) return FATAL;
134 sprintf(buffer,"%02X",addr->sas_addr.prv[i]);
139 if (!length) return FATAL;
141 return orig_len-length;
145 static int search(FILE *file,char *buffer,int length,
146 const struct sockaddr *addr,int flags)
148 struct sockaddr_atmsvc temp;
149 char line[MAX_ATM_NAME_LEN+1];
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)
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;
165 else if (!atm_equal(addr,(struct sockaddr *) &temp,0,0)) continue;
166 while ((here = strtok(NULL,"\t\n ")))
167 if (strlen(here) < length) {
177 static int try_name(char *buffer,int length,const struct sockaddr *addr)
182 if (!(file = fopen(HOSTS_ATM,"r"))) return TRY_OTHER;
183 result = search(file,buffer,length,addr,addr->sa_family == AF_ATMPVC ?
190 int atm2text(char *buffer,int length,const struct sockaddr *addr,int flags)
194 if (addr->sa_family != AF_ATMPVC && addr->sa_family != AF_ATMSVC)
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);
205 if (addr->sa_family == AF_ATMPVC)
206 return do_pvc(buffer,length,(const struct sockaddr_atmpvc *) addr,
208 else return do_svc(buffer,length,(const struct sockaddr_atmsvc *) addr,