summaryrefslogtreecommitdiffstats
path: root/mdk-stage1/dietlibc/libcruft/dnscruft.c
diff options
context:
space:
mode:
authorGuillaume Cottenceau <gc@mandriva.com>2001-05-14 13:47:49 +0000
committerGuillaume Cottenceau <gc@mandriva.com>2001-05-14 13:47:49 +0000
commitf15aa3a552022743398a652165d76bf912c715e5 (patch)
treeb58f8b4c47fc571fbb498d83a4bd4fca226ac6c4 /mdk-stage1/dietlibc/libcruft/dnscruft.c
parent189b01c358a1181ddc951adba97a0258d5fc2cf1 (diff)
downloaddrakx-backup-do-not-use-f15aa3a552022743398a652165d76bf912c715e5.tar
drakx-backup-do-not-use-f15aa3a552022743398a652165d76bf912c715e5.tar.gz
drakx-backup-do-not-use-f15aa3a552022743398a652165d76bf912c715e5.tar.bz2
drakx-backup-do-not-use-f15aa3a552022743398a652165d76bf912c715e5.tar.xz
drakx-backup-do-not-use-f15aa3a552022743398a652165d76bf912c715e5.zip
Initial revision
Diffstat (limited to 'mdk-stage1/dietlibc/libcruft/dnscruft.c')
-rw-r--r--mdk-stage1/dietlibc/libcruft/dnscruft.c115
1 files changed, 115 insertions, 0 deletions
diff --git a/mdk-stage1/dietlibc/libcruft/dnscruft.c b/mdk-stage1/dietlibc/libcruft/dnscruft.c
new file mode 100644
index 000000000..d7a0efa50
--- /dev/null
+++ b/mdk-stage1/dietlibc/libcruft/dnscruft.c
@@ -0,0 +1,115 @@
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+int __dns_fd=-1;
+
+void __dns_make_fd() {
+ int tmp;
+ struct sockaddr_in si;
+ if (__dns_fd>0) return;
+ tmp=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP);
+ if (tmp<0) {
+ perror("__dns_make_fd!socket");
+ return;
+ }
+ si.sin_family=AF_INET;
+ si.sin_port=0;
+ si.sin_addr.s_addr=INADDR_ANY;
+ if (bind(tmp,(struct sockaddr*)&si,sizeof(si))) {
+ perror("__dns_make_fd!bind");
+ return;
+ }
+ __dns_fd=tmp;
+}
+
+int __dns_servers=0;
+struct sockaddr __dns_server_ips[8];
+
+int __dns_search=0;
+char *__dns_domains[8];
+
+void __dns_readstartfiles() {
+ int fd;
+ char *buf=alloca(4096);
+ int len;
+ if (__dns_servers>0) return;
+ {
+ struct sockaddr_in to;
+ char *cacheip=getenv("DNSCACHEIP");
+ if (cacheip) {
+ to.sin_port=htons(53);
+ to.sin_family=AF_INET;
+ if (inet_aton(cacheip,&to.sin_addr)) {
+ memmove(__dns_server_ips,&to,sizeof(struct sockaddr));
+ ++__dns_servers;
+ }
+ }
+ }
+ if ((fd=open("/etc/resolv.conf",O_RDONLY))<0) return;
+ len=read(fd,buf,4096);
+ close(fd);
+ {
+ char *last=buf+len;
+ for (; buf<last;) {
+ if (!strncmp(buf,"nameserver",10)) {
+ buf+=10;
+ while (buf<last && *buf!='\n') {
+ while (buf<last && isblank(*buf)) ++buf;
+ {
+ char *tmp=buf;
+ struct sockaddr_in i;
+ while (buf<last && !isspace(*buf)) ++buf;
+ if (buf>=last) break;
+ *buf=0;
+ if (inet_aton(tmp,&i.sin_addr)) {
+ i.sin_family=AF_INET;
+ i.sin_port=htons(53);
+ memmove(&__dns_server_ips[__dns_servers],&i,sizeof(struct sockaddr));
+ if (__dns_servers<8) ++__dns_servers;
+ }
+ }
+ }
+ }
+ if (!strncmp(buf,"search",6) || !strncmp(buf,"domain",6)) {
+ buf+=6;
+ }
+ while (buf<last && *buf!='\n') ++buf;
+ while (buf<last && *buf=='\n') ++buf;
+ }
+ }
+}
+
+/* return length of decoded data or -1 */
+int __dns_decodename(unsigned char *packet,int offset,unsigned char *dest,int maxlen) {
+ unsigned char *tmp;
+ unsigned char *max=dest+maxlen;
+ unsigned char *after=packet+offset;
+ int ok=0;
+ for (tmp=after; maxlen>0&&*tmp; ) {
+ if ((*tmp>>6)==3) { /* goofy DNS decompression */
+ unsigned int ofs=((unsigned int)(*tmp&0x3f)<<8)|*(tmp+1);
+ if (ofs>=offset) return -1; /* RFC1035: "pointer to a _prior_ occurrance" */
+ if (after<tmp+2) after=tmp+2;
+ tmp=packet+ofs;
+ ok=0;
+ } else {
+ unsigned int duh;
+ if (dest+*tmp+1>max) return -1;
+ for (duh=*tmp; duh>0; --duh)
+ *dest++=*++tmp;
+ *dest++='.'; ok=1;
+ ++tmp;
+ if (tmp>after) { after=tmp; if (!*tmp) ++after; }
+ }
+ }
+ if (ok) --dest;
+ *dest=0;
+ return after-packet;
+}