예제 #1
0
static int __dns_gethostbyx_r_inner(const char* name, struct hostent* result,
			char *buf, size_t buflen,
			struct hostent **RESULT, int *h_errnop, int lookfor) {
#else
int __dns_gethostbyx_r(const char* name, struct hostent* result,
			char *buf, size_t buflen,
			struct hostent **RESULT, int *h_errnop, int lookfor) {
#endif
  int names,ips;
  unsigned char *cur;
  unsigned char *max;
  unsigned char inpkg[1500];
  char* tmp;
  int size;

  if (lookfor==1) {
    result->h_addrtype=AF_INET;
    result->h_length=4;
  } else {
    result->h_addrtype=AF_INET6;
    result->h_length=16;
  }
  result->h_aliases=(char**)(buf+8*sizeof(char*));
  result->h_addr_list=(char**)buf;
  result->h_aliases[0]=0;

  cur=buf+16*sizeof(char*);
  max=buf+buflen;
  names=ips=0;

  if ((size=res_query(name,C_IN,lookfor,inpkg,512))<0) {
invalidpacket:
    *h_errnop=HOST_NOT_FOUND;
    return -1;
  }
  {
    tmp=inpkg+12;
    {
      char Name[257];
      unsigned short q=((unsigned short)inpkg[4]<<8)+inpkg[5];
      while (q>0) {
	if (tmp>(char*)inpkg+size) goto invalidpacket;
	while (*tmp) { tmp+=*tmp+1; if (tmp>(char*)inpkg+size) goto invalidpacket; }
	tmp+=5;
	--q;
      }
      if (tmp>(char*)inpkg+size) goto invalidpacket;
      q=((unsigned short)inpkg[6]<<8)+inpkg[7];
      if (q<1) goto nodata;
      while (q>0) {
	int decofs=__dns_decodename(inpkg,(size_t)(tmp-(char*)inpkg),Name,256,inpkg+size);
	if (decofs<0) break;
	tmp=inpkg+decofs;
	--q;
	if (tmp[0]!=0 || tmp[1]!=lookfor ||	/* TYPE != A */
	    tmp[2]!=0 || tmp[3]!=1) {		/* CLASS != IN */
	  if (tmp[1]==5) {	/* CNAME */
	    tmp+=10;
	    decofs=__dns_decodename(inpkg,(size_t)(tmp-(char*)inpkg),Name,256,inpkg+size);
	    if (decofs<0) break;
	    tmp=inpkg+decofs;
	  } else
	    break;
	  continue;
	}
	tmp+=10;	/* skip type, class, TTL and length */
	{
	  int slen;
	  if (lookfor==1 || lookfor==28) /* A or AAAA*/ {
	    slen=strlen(Name);
	    if (cur+slen+8+(lookfor==28?12:0)>=max) { *h_errnop=NO_RECOVERY; return -1; }
	  } else if (lookfor==12) /* PTR */ {
	    decofs=__dns_decodename(inpkg,(size_t)(tmp-(char*)inpkg),Name,256,inpkg+size);
	    if (decofs<0) break;
	    tmp=inpkg+decofs;
	    slen=strlen(Name);
	  } else
	    slen=strlen(Name);
	  strcpy(cur,Name);
	  if (names==0)
	    result->h_name=cur;
	  else
	    result->h_aliases[names-1]=cur;
	  result->h_aliases[names]=0;
	  if (names<8) ++names;
/*		cur+=slen+1; */
	  cur+=(slen|3)+1;
	  result->h_addr_list[ips++] = cur;
	  if (lookfor==1) /* A */ {
	    *(int*)cur=*(int*)tmp;
	    cur+=4;
	    result->h_addr_list[ips]=0;
	  } else if (lookfor==28) /* AAAA */ {
	    {
	      int k;
	      for (k=0; k<16; ++k) cur[k]=tmp[k];
	    }
	    cur+=16;
	    result->h_addr_list[ips]=0;
	  }
	}
/*	      puts(Name); */
      }
    }
  }
  if (!names) {
nodata:
    *h_errnop=NO_DATA;
    return -1;
  }
  *h_errnop=0;
  *RESULT=result;
  return 0;
}
예제 #2
0
int dn_expand(unsigned char *msg, unsigned char *eomorig, unsigned char *comp_dn, unsigned char *exp_dn, int length) {
  return __dns_decodename(msg,comp_dn-msg,exp_dn,length,eomorig)-(comp_dn-msg);
}