/* * $Id$ * * resolver related functions */ #ifndef resolve_h #define resolve_h #include <netdb.h> #include <arpa/nameser.h> #define MAX_QUERY_SIZE 8192 #define ANS_SIZE 8192 #define DNS_HDR_SIZE 12 #define MAX_DNS_NAME 256 /* query union*/ union dns_query{ HEADER hdr; unsigned char buff[MAX_QUERY_SIZE]; }; /* rdata struct*/ struct rdata { unsigned short type; unsigned short class; unsigned int ttl; void* rdata; struct rdata* next; }; /* srv rec. struct*/ struct srv_rdata { unsigned short priority; unsigned short weight; unsigned short port; unsigned int name_len; char name[MAX_DNS_NAME]; }; /* A rec. struct */ struct a_rdata { unsigned char ip[4]; }; struct aaaa_rdata { unsigned char ip6[16]; }; /* cname rec. struct*/ struct cname_rdata { char name[MAX_DNS_NAME]; }; struct rdata* get_record(char* name, int type); void free_rdata_list(struct rdata* head); /* gethostbyname wrappers * use this, someday htey will use a local cache */ static inline struct hostent* resolvehost(const char* name) { struct hostent* he; #ifdef DNS_IP_HACK #endif he=gethostbyname(name); /*ipv4*/ #ifdef USE_IPV6 if(he==0){ /*try ipv6*/ he=gethostbyname2(name, AF_INET6); } #endif return he; } struct hostent* sip_resolvehost(char* name, unsigned short* port); #define HEX2I(c) \ ( (((c)>='0') && ((c)<='9'))? (c)-'0' : \ (((c)>='A') && ((c)<='F'))? ((c)-'A')+10 : \ (((c)>='a') && ((c)<='f'))? ((c)-'a')+10 : -1 ) #define rev_resolvehost(ip) gethostbyaddr((ip)->u.addr, (ip)->len, (ip)->af); #if 0 /* returns an ip_addr struct.; on error retunrs 0 and sets err (if !=0) * the ip_addr struct is static, so subsequent calls will destroy its * content */ static /*inline*/ struct ip_addr* str2ip6(unsigned char* str, unsigned int len, int* err) { int i, idx1, rest; int no_colons; int double_colon; int hex; static struct ip_addr ip; unsigned short* addr_start; unsigned short addr_end[8]; unsigned short* addr; unsigned char* limit; unsigned char* init; /* init */ init=str; i=idx1=rest=0; double_colon=0; no_colons=0; ip.af=AF_INET6; ip.len=16; addr_start=ip.u.addr16; addr=addr_start; limit=str+len; memset(addr_start, 0 , 8*sizeof(unsigned short)); memset(addr_end, 0 , 8*sizeof(unsigned short)); for (; str<limit; str++){ if (*str==':'){ no_colons++; if (no_colons>7) goto error_too_many_colons; if (double_colon){ idx1=i; i=0; if (addr==addr_end) goto error_colons; addr=addr_end; }else{ double_colon=1; i++; } }else if ((hex=HEX2I(*str))>=0){ addr[i]=addr[i]*16+hex; double_colon=0; }else{ /* error, unknown char */ goto error_char; } } rest=8-i-idx1; memcpy(addr_start+idx1+rest, addr_end, i*sizeof(unsigned short)); if (err) *err=0; return &ip; error_too_many_colons: DBG("str2ip6: ERROR: too many colons in [%.*s]\n", (int) len, init); if (err) *err=1; return 0; error_colons: DBG("str2ip6: ERROR: too many double colons in [%.*s]\n", (int) len, init); if (err) *err=1; return 0; error_char: DBG("str2ip6: WARNING: unexpected char %c in [%.*s]\n", *str, (int) len, init); if (err) *err=1; return 0; } #endif #endif