⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ans.c

📁 linux 下的ppp源码,难得难得,大家快来下吧
💻 C
字号:
/* ans.c - Interface for text2atm and atm2text to ANS *//* Written 1996-2000 by Werner Almesberger, EPFL-LRC/ICA *//* * This stuff is a temporary hack to avoid using gethostbyname_nsap and such * without doing the "full upgrade" to getaddrinfo/getnameinfo. This also * serves as an exercise for me to get all the details right before I propose * a patch that would eventually end up in libc (and that should therefore be * as stable as possible). */#if HAVE_CONFIG_H#include <config.h>#endif#include <stdlib.h>#include <stdio.h>#include <string.h>#include <netinet/in.h>#include <arpa/nameser.h>#include <netdb.h>#include <resolv.h>#include "atm.h"#include "atmres.h"#define MAX_ANSWER 2048#define MAX_NAME   1024#define MAX_LINE		2048	/* in /etc/e164_cc */#define E164_CC_DEFAULT_LEN	   2#define E164_CC_FILE		"/etc/e164_cc"#define GET16(pos) (((pos)[0] << 8) | (pos)[1])static int ans(const char *text,int wanted,void *result,int res_len){    unsigned char answer[MAX_ANSWER];    unsigned char name[MAX_NAME];    unsigned char *pos,*data,*found;    int answer_len,name_len,data_len,found_len;    int questions,answers;    found_len = 0; /* gcc wants it */    if ((answer_len = res_search(text,C_IN,wanted,answer,MAX_ANSWER)) < 0)	return TRY_OTHER;    /*     * Response header: id, flags, #queries, #answers, #authority,     * #additional (all 16 bits)     */    pos = answer+12;    if (answer[3] & 15) return TRY_OTHER; /* rcode != 0 */    questions = GET16(answer+4);    if (questions != 1) return TRY_OTHER; /* trouble ... */    answers = GET16(answer+6);    if (answers < 1) return TRY_OTHER;    /*     * Query: name, type (16), class (16)     */    if ((name_len = dn_expand(answer,answer+answer_len,pos,name,MAX_NAME)) < 0)	return TRY_OTHER;    pos += name_len;    if (GET16(pos) != wanted || GET16(pos+2) != C_IN) return TRY_OTHER;    pos += 4;    /*     * Iterate over answers until we find something we like, giving priority     * to ATMA_AESA (until signaling is fixed to work with E.164 too)     */    found = NULL;    while (answers--) {	/*	 * RR: name, type (16), class (16), TTL (32), resource_len (16),	 * resource_data ...	 */	if ((name_len = dn_expand(answer,answer+answer_len,pos,name,MAX_NAME))	  < 0) return TRY_OTHER;	pos += name_len;	data_len = GET16(pos+8);	data = pos+10;	pos = data+data_len;	if (GET16(data-10) != wanted || GET16(data-8) != C_IN || !--data_len)	    continue;	switch (wanted) {            case T_NSAP:                data_len++;                if (data_len != ATM_ESA_LEN) continue;                memcpy(((struct sockaddr_atmsvc *) result)->                  sas_addr.prv,data,ATM_ESA_LEN);                return 0;	    case T_ATMA:		switch (*data++) {		    case ATMA_AESA:			if (data_len != ATM_ESA_LEN) continue;			memcpy(((struct sockaddr_atmsvc *) result)->			  sas_addr.prv,data,ATM_ESA_LEN);			return 0;		    case ATMA_E164:			if (data_len > ATM_E164_LEN) continue;			if (!found) {			    found = data;			    found_len = data_len;			}			break;		    default:			continue;		}	    case T_PTR:		    if (dn_expand(answer,answer+answer_len,data,result,		      res_len) < 0) return FATAL;		    return 0;		default:		    continue;	}    }    if (!found) return TRY_OTHER;    memcpy(((struct sockaddr_atmsvc *) result)->sas_addr.pub,found,      found_len);    ((struct sockaddr_atmsvc *) result)->sas_addr.pub[found_len] = 0;    return 0;}int ans_byname(const char *text,struct sockaddr_atmsvc *addr,int length,  int flags){    if (!(flags & T2A_SVC) || length != sizeof(*addr)) return TRY_OTHER;     memset(addr,0,sizeof(*addr));    addr->sas_family = AF_ATMSVC;    if (!ans(text,T_ATMA,addr,length)) return 0;    return ans(text,T_NSAP,addr,length);}static int encode_nsap(char *buf,const unsigned char *addr){    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,      4,2,0 };    static int fmt_e164[] = { 2,12,1,1,1,1,1,1,1,1,16,2,0 };    int *fmt;    int pos,i,j;    switch (*addr) {	case ATM_AFI_DCC:	case ATM_AFI_ICD:	case ATM_AFI_LOCAL:	case ATM_AFI_DCC_GROUP:	case ATM_AFI_ICD_GROUP:	case ATM_AFI_LOCAL_GROUP:	    fmt = fmt_dcc;	    break;	case ATM_AFI_E164:	case ATM_AFI_E164_GROUP:	    fmt = fmt_e164;	    break;	default:	    return TRY_OTHER;    }    pos = 2*ATM_ESA_LEN;    for (i = 0; fmt[i]; i++) {	pos -= fmt[i];	for (j = 0; j < fmt[i]; j++)	    sprintf(buf++,"%x",	      (addr[(pos+j) >> 1] >> 4*(1-((pos+j) & 1))) & 0xf);	*buf++ = '.';    }    strcpy(buf,"AESA.ATMA.INT.");    return 0;}static int encode_nsap_new(char *buf,const unsigned char *addr){    int i;    int digit;    for (i = 20; i; ) {        i--;        digit = addr[i] & 0x0F;        *(buf++) = digit + (digit >= 10 ? '7' : '0');        *(buf++) = '.';        digit = ((unsigned char) (addr[i])) >> 4;        *(buf++) = digit + (digit >= 10 ? '7' : '0');        *(buf++) = '.';    }    strcpy (buf, "NSAP.INT.");    return 0;}static int cc_len(int p0,int p1){    static char *cc_table = NULL;    FILE *file;    char buffer[MAX_LINE];    char *here;    int cc;    if (!cc_table) {	if (!(cc_table = malloc(100))) {	    perror("malloc");	    return E164_CC_DEFAULT_LEN;	}	memset(cc_table,E164_CC_DEFAULT_LEN,100);	if (!(file = fopen(E164_CC_FILE,"r")))	    perror(E164_CC_FILE);	else {	    while (fgets(buffer,MAX_LINE,file)) {		here = strchr(buffer,'#');		if (here) *here = 0;		if (sscanf(buffer,"%d",&cc) == 1) {		    if (cc < 10) cc_table[cc] = 1;		    else if (cc < 100) cc_table[cc] = 2;			else cc_table[cc/10] = 3;		}	    }	    fclose(file);	}    }    if (cc_table[p0] == 1) return 1;    return cc_table[p0*10+p1];}static int encode_e164(char *buf,const char *addr){    const char *prefix,*here;    prefix = addr+cc_len(addr[0]-48,addr[1]-48);    here = strchr(addr,0);    while (here > prefix) {	*buf++ = *--here;	*buf++ = '.';    }    while (here > addr) *buf++ = *addr++;    strcpy(buf,".E164.ATMA.INT.");    return 0;}int ans_byaddr(char *buffer,int length,const struct sockaddr_atmsvc *addr,  int flags){    char tmp[MAX_NAME]; /* could be smaller ... */    int res;    if (addr->sas_addr.prv) {        res = encode_nsap(tmp,addr->sas_addr.prv);        if (!res && !ans(tmp,T_PTR,buffer,length)) return 0;	res = encode_nsap_new(tmp,addr->sas_addr.prv);        if (res < 0) return res;	return ans(tmp,T_PTR,buffer,length);    } else {        res = encode_e164(tmp,addr->sas_addr.pub);        if (res < 0) return res;        return ans(tmp,T_PTR,buffer,length);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -