18ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* ans.c - Interface for text2atm and atm2text to ANS */
28ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
38ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* Written 1996-2000 by Werner Almesberger, EPFL-LRC/ICA */
48ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
58ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
68ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
78ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * This stuff is a temporary hack to avoid using gethostbyname_nsap and such
88ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * without doing the "full upgrade" to getaddrinfo/getnameinfo. This also
98ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * serves as an exercise for me to get all the details right before I propose
108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * a patch that would eventually end up in libc (and that should therefore be
118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * as stable as possible).
128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if HAVE_CONFIG_H
158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <config.h>
168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stdlib.h>
198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stdio.h>
208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <string.h>
218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <netinet/in.h>
238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <arpa/nameser.h>
248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <netdb.h>
258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <resolv.h>
268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "atm.h"
288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "atmres.h"
298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define MAX_ANSWER 2048
328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define MAX_NAME   1024
338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define MAX_LINE		2048	/* in /etc/e164_cc */
358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define E164_CC_DEFAULT_LEN	   2
368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define E164_CC_FILE		"/etc/e164_cc"
378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define GET16(pos) (((pos)[0] << 8) | (pos)[1])
398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int ans(const char *text,int wanted,void *result,int res_len)
428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    unsigned char answer[MAX_ANSWER];
448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    unsigned char name[MAX_NAME];
458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    unsigned char *pos,*data,*found;
468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int answer_len,name_len,data_len,found_len;
478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int questions,answers;
488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    found_len = 0; /* gcc wants it */
508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if ((answer_len = res_search(text,C_IN,wanted,answer,MAX_ANSWER)) < 0)
518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return TRY_OTHER;
528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Response header: id, flags, #queries, #answers, #authority,
548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * #additional (all 16 bits)
558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    pos = answer+12;
578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (answer[3] & 15) return TRY_OTHER; /* rcode != 0 */
588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    questions = GET16(answer+4);
598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (questions != 1) return TRY_OTHER; /* trouble ... */
608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    answers = GET16(answer+6);
618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (answers < 1) return TRY_OTHER;
628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Query: name, type (16), class (16)
648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if ((name_len = dn_expand(answer,answer+answer_len,pos,name,MAX_NAME)) < 0)
668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return TRY_OTHER;
678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    pos += name_len;
688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (GET16(pos) != wanted || GET16(pos+2) != C_IN) return TRY_OTHER;
698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    pos += 4;
708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Iterate over answers until we find something we like, giving priority
728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * to ATMA_AESA (until signaling is fixed to work with E.164 too)
738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    found = NULL;
758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    while (answers--) {
768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/*
778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * RR: name, type (16), class (16), TTL (32), resource_len (16),
788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * resource_data ...
798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 */
808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((name_len = dn_expand(answer,answer+answer_len,pos,name,MAX_NAME))
818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	  < 0) return TRY_OTHER;
828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	pos += name_len;
838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	data_len = GET16(pos+8);
848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	data = pos+10;
858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	pos = data+data_len;
868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (GET16(data-10) != wanted || GET16(data-8) != C_IN || !--data_len)
878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	switch (wanted) {
898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project            case T_NSAP:
908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project                data_len++;
918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project                if (data_len != ATM_ESA_LEN) continue;
928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project                memcpy(((struct sockaddr_atmsvc *) result)->
938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project                  sas_addr.prv,data,ATM_ESA_LEN);
948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project                return 0;
958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case T_ATMA:
968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		switch (*data++) {
978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    case ATMA_AESA:
988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (data_len != ATM_ESA_LEN) continue;
998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			memcpy(((struct sockaddr_atmsvc *) result)->
1008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			  sas_addr.prv,data,ATM_ESA_LEN);
1018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			return 0;
1028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    case ATMA_E164:
1038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (data_len > ATM_E164_LEN) continue;
1048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			if (!found) {
1058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    found = data;
1068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    found_len = data_len;
1078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			}
1088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			break;
1098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    default:
1108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			continue;
1118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
1128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case T_PTR:
1138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (dn_expand(answer,answer+answer_len,data,result,
1148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		      res_len) < 0) return FATAL;
1158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    return 0;
1168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		default:
1178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    continue;
1188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
1198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
1208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!found) return TRY_OTHER;
1218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memcpy(((struct sockaddr_atmsvc *) result)->sas_addr.pub,found,
1228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      found_len);
1238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ((struct sockaddr_atmsvc *) result)->sas_addr.pub[found_len] = 0;
1248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 0;
1258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
1268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint ans_byname(const char *text,struct sockaddr_atmsvc *addr,int length,
1298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project  int flags)
1308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
1318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!(flags & T2A_SVC) || length != sizeof(*addr)) return TRY_OTHER;
1328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(addr,0,sizeof(*addr));
1338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    addr->sas_family = AF_ATMSVC;
1348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!ans(text,T_ATMA,addr,length)) return 0;
1358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return ans(text,T_NSAP,addr,length);
1368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
1378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int encode_nsap(char *buf,const unsigned char *addr)
1408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
1418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    static int fmt_dcc[] = { 2,12,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project      4,2,0 };
1438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    static int fmt_e164[] = { 2,12,1,1,1,1,1,1,1,1,16,2,0 };
1448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int *fmt;
1458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int pos,i,j;
1468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    switch (*addr) {
1488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case ATM_AFI_DCC:
1498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case ATM_AFI_ICD:
1508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case ATM_AFI_LOCAL:
1518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case ATM_AFI_DCC_GROUP:
1528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case ATM_AFI_ICD_GROUP:
1538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case ATM_AFI_LOCAL_GROUP:
1548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    fmt = fmt_dcc;
1558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
1568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case ATM_AFI_E164:
1578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case ATM_AFI_E164_GROUP:
1588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    fmt = fmt_e164;
1598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
1608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	default:
1618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return TRY_OTHER;
1628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
1638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    pos = 2*ATM_ESA_LEN;
1648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (i = 0; fmt[i]; i++) {
1658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	pos -= fmt[i];
1668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	for (j = 0; j < fmt[i]; j++)
1678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    sprintf(buf++,"%x",
1688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	      (addr[(pos+j) >> 1] >> 4*(1-((pos+j) & 1))) & 0xf);
1698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	*buf++ = '.';
1708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
1718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strcpy(buf,"AESA.ATMA.INT.");
1728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 0;
1738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
1748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int encode_nsap_new(char *buf,const unsigned char *addr)
1778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
1788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int i;
1798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int digit;
1808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (i = 20; i; ) {
1828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        i--;
1838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        digit = addr[i] & 0x0F;
1848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        *(buf++) = digit + (digit >= 10 ? '7' : '0');
1858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        *(buf++) = '.';
1868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        digit = ((unsigned char) (addr[i])) >> 4;
1878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        *(buf++) = digit + (digit >= 10 ? '7' : '0');
1888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        *(buf++) = '.';
1898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
1908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strcpy (buf, "NSAP.INT.");
1918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 0;
1928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
1938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int cc_len(int p0,int p1)
1968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
1978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    static char *cc_table = NULL;
1988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    FILE *file;
1998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char buffer[MAX_LINE];
2008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *here;
2018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int cc;
2028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!cc_table) {
2048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!(cc_table = malloc(100))) {
2058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    perror("malloc");
2068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return E164_CC_DEFAULT_LEN;
2078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
2088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	memset(cc_table,E164_CC_DEFAULT_LEN,100);
2098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!(file = fopen(E164_CC_FILE,"r")))
2108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    perror(E164_CC_FILE);
2118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	else {
2128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    while (fgets(buffer,MAX_LINE,file)) {
2138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		here = strchr(buffer,'#');
2148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (here) *here = 0;
2158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (sscanf(buffer,"%d",&cc) == 1) {
2168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (cc < 10) cc_table[cc] = 1;
2178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    else if (cc < 100) cc_table[cc] = 2;
2188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			else cc_table[cc/10] = 3;
2198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
2208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
2218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    fclose(file);
2228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
2238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
2248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (cc_table[p0] == 1) return 1;
2258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return cc_table[p0*10+p1];
2268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
2278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int encode_e164(char *buf,const char *addr)
2308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
2318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    const char *prefix,*here;
2328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    prefix = addr+cc_len(addr[0]-48,addr[1]-48);
2348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    here = strchr(addr,0);
2358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    while (here > prefix) {
2368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	*buf++ = *--here;
2378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	*buf++ = '.';
2388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
2398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    while (here > addr) *buf++ = *addr++;
2408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strcpy(buf,".E164.ATMA.INT.");
2418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 0;
2428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
2438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint ans_byaddr(char *buffer,int length,const struct sockaddr_atmsvc *addr,
2468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project  int flags)
2478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
2488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char tmp[MAX_NAME]; /* could be smaller ... */
2498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int res;
2508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (addr->sas_addr.prv) {
2528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        res = encode_nsap(tmp,addr->sas_addr.prv);
2538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        if (!res && !ans(tmp,T_PTR,buffer,length)) return 0;
2548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	res = encode_nsap_new(tmp,addr->sas_addr.prv);
2558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        if (res < 0) return res;
2568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return ans(tmp,T_PTR,buffer,length);
2578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else {
2588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        res = encode_e164(tmp,addr->sas_addr.pub);
2598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        if (res < 0) return res;
2608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        return ans(tmp,T_PTR,buffer,length);
2618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
2628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
263