summaryrefslogtreecommitdiffstats
path: root/mdk-stage1/dietlibc/libcruft/dnscruft2.c
diff options
context:
space:
mode:
Diffstat (limited to 'mdk-stage1/dietlibc/libcruft/dnscruft2.c')
-rw-r--r--mdk-stage1/dietlibc/libcruft/dnscruft2.c264
1 files changed, 126 insertions, 138 deletions
diff --git a/mdk-stage1/dietlibc/libcruft/dnscruft2.c b/mdk-stage1/dietlibc/libcruft/dnscruft2.c
index b59207072..d4e132e42 100644
--- a/mdk-stage1/dietlibc/libcruft/dnscruft2.c
+++ b/mdk-stage1/dietlibc/libcruft/dnscruft2.c
@@ -8,178 +8,166 @@
#include <sys/poll.h>
#include <unistd.h>
#include <errno.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+#include "dietfeatures.h"
+#include "dietdns.h"
-#include <stdio.h>
+extern void __dns_readstartfiles(void);
-extern int h_errno;
-
-static char dnspacket[]="\xfe\xfe\001\000\000\001\000\000\000\000\000\000";
-
-extern void __dns_make_fd();
-extern int __dns_fd;
-
-extern int __dns_servers;
-extern struct sockaddr __dns_server_ips[];
-
-extern void __dns_readstartfiles();
-
-extern int __dns_decodename(unsigned char *packet,int offset,unsigned char *dest,int maxlen);
+extern int __dns_decodename(unsigned char *packet,unsigned int offset,unsigned char *dest,
+ unsigned int maxlen,unsigned char* behindpacket);
/* Oh boy, this interface sucks so badly, there are no words for it.
* Not one, not two, but _three_ error signalling methods! (*h_errnop
* nonzero? return value nonzero? *RESULT zero?) The glibc goons
* really outdid themselves with this one. */
+#ifdef WANT_FULL_RESOLV_CONF
+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);
+
+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 packet[512];
- __dns_make_fd();
+ unsigned char inpkg[1500];
+ char* tmp;
+ int size;
if (lookfor==1) {
- result->h_aliases=(char**)(buf+8*4);
result->h_addrtype=AF_INET;
result->h_length=4;
- result->h_addr_list=(char**)buf;
} else {
- result->h_aliases=(char**)(buf+8*16);
result->h_addrtype=AF_INET6;
result->h_length=16;
- result->h_addr_list=(char**)buf;
}
+ 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;
- memmove(packet,dnspacket,12);
- *(unsigned short*)packet=rand();
+ if ((size=res_query(name,C_IN,lookfor,inpkg,512))<0) {
+invalidpacket:
+ *h_errnop=HOST_NOT_FOUND;
+ return -1;
+ }
{
- unsigned char* x;
- const char* y,* tmp;
- x=packet+12; y=name;
- while (*y) {
- while (*y=='.') ++y;
- for (tmp=y; *tmp && *tmp!='.'; ++tmp) ;
- *x=tmp-y;
- if (!(tmp-y)) break;
- ++x;
- if (x>=packet+510-(tmp-y)) { *h_errnop=ERANGE; return 1; }
- memmove(x,y,tmp-y);
- x+=tmp-y;
- if (!*tmp) {
- *x=0;
- break;
- }
- y=tmp;
- }
- *++x= 0; *++x= lookfor; /* A */
- *++x= 0; *++x= 1; /* IN */
- ++x;
+ tmp=inpkg+12;
{
- int i; /* current server */
- int j; /* timeout count down */
- struct pollfd duh;
- i=0; j=30;
- __dns_readstartfiles();
- duh.fd=__dns_fd;
- duh.events=POLLIN;
- for (j=30; j>0; --j) {
- sendto(__dns_fd,packet,x-packet,0,(struct sockaddr*)&(__dns_server_ips[i]),sizeof(struct sockaddr));
- if (++i > __dns_servers) i=0;
- if (poll(&duh,1,1) == 1) {
- /* read and parse answer */
- unsigned char inpkg[1500];
- /*int len=*/ read(__dns_fd,inpkg,1500);
-#if 0
- {
- int tft=open("duh",0);
- read(tft,inpkg,1500);
- close(tft);
- }
-#endif
- /* header, question, answer, authority, additional */
- if (inpkg[0]!=packet[0] || inpkg[1]!=packet[1]) continue; /* wrong ID */
- if ((inpkg[2]&0xf9) != 0x81) continue; /* not answer */
- if ((inpkg[3]&0x0f) != 0) break; /* error */
- tmp=inpkg+12;
- {
- char name[257];
- unsigned short q=((unsigned short)inpkg[4]<<8)+inpkg[5];
- while (q>0) {
- while (*tmp) tmp+=*tmp+1;
- tmp+=5;
- --q;
- }
- q=((unsigned short)inpkg[6]<<8)+inpkg[7];
- if (q<1) break;
- while (q>0) {
- int decofs=__dns_decodename(inpkg,tmp-(char*)inpkg,name,256);
- 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,tmp-(char*)inpkg,name,256);
- 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,tmp-(char*)inpkg,name,256);
- 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;
- ++names;
+ 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 i;
- for (i=0; i<16; ++i) cur[i]=tmp[i];
- }
- cur+=16;
- result->h_addr_list[ips]=0;
- }
- }
-/* puts(name); */
+ 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;
}
-/* printf("%d answers\n",((unsigned short)inpkg[6]<<8)+inpkg[7]);
- printf("ok\n");*/
- *h_errnop=0;
- *RESULT=result;
- return 0;
}
-/*kaputt:*/
+/* puts(Name); */
}
}
}
- return 1;
+ if (!names) {
+nodata:
+ *h_errnop=NO_DATA;
+ return -1;
+ }
+ *h_errnop=0;
+ *RESULT=result;
+ return 0;
+}
+
+#ifdef WANT_FULL_RESOLV_CONF
+extern int __dns_search;
+extern char *__dns_domains[];
+
+int __dns_gethostbyx_r(const char* name, struct hostent* result,
+ char *buf, size_t buflen,
+ struct hostent **RESULT, int *h_errnop, int lookfor) {
+ const char *tmp=name;
+ char Buf[MAXDNAME+1];
+ int res;
+ size_t len=strlen(name);
+ int count=0;
+ __dns_readstartfiles();
+ memmove(Buf,name,len);
+ Buf[len]=Buf[MAXDNAME]=0;
+// printf("appending %d: %p\n",count,__dns_domains[count]);
+ while ((res=__dns_gethostbyx_r_inner(tmp,result,buf,buflen,RESULT,h_errnop,lookfor))) {
+ if (res==-1 && *h_errnop!=HOST_NOT_FOUND) break;
+ if (count==__dns_search) break;
+ Buf[len]='.';
+// printf("appending %d: %p (%s)\n",count,__dns_domains[count],__dns_domains[count]);
+ memccpy(Buf+len+1,__dns_domains[count],0,MAXDNAME-len-1);
+ tmp=Buf;
+ ++count;
+ }
+ return res;
}
+#endif
+