home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <netdb.h>
- #include <sys/types.h>
- #include <sys/syslog.h>
- #include <sys/errno.h>
- #include <netinet/in.h>
- #include <arpa/nameser.h>
-
- #include <exec/nodes.h>
- #include <exec/lists.h>
-
- #include <proto/exec.h>
-
- char VersionTag[]="\0$VER: JoranNameserver 0.3 (14.12.93)";
-
- struct hostinfo {
- struct MinNode Node;
- char name[MAXDNAME];
- LONG netnumber;
- };
- struct MinList hostlist;
- char Line[1024];
- char hostname[MAXHOSTNAMELEN];
- char *curnet="";
-
- void readnamedhosts(void)
- {
- FILE *f;
-
- f=fopen("AmiTCP:db/named.hosts","r");
- if(!f)
- {
- perror("AmiTCP:db/named.hosts");
- exit(1);
- }
- NewList((struct List *)&hostlist);
-
- while(fgets(Line,sizeof(Line),f))
- {
- char *p,*a[6];
- char curdname[MAXDNAME];
- LONG netnumber;
- int i;
-
- if(p=strchr(Line,';')) *p='\0'; // Verwijderen commentaar
- a[0]=strtok(Line,"\t\n ");
- for(i=1;i<6;i++) a[i]=strtok(NULL,"\t\n ");
- netnumber=-1;
- for(i=0;i<6;i++) if(!a[i] || !strcmp(a[i],"IN")) break;
- if(i>0) strcpy(curdname,a[0]);
- if(i<4 && a[i+1] && !strcmp(a[i+1],"A")) netnumber=inet_addr(a[i+2]);
-
- if(netnumber!=-1)
- {
- struct hostinfo *hi;
-
- if(hi=malloc(sizeof(struct hostinfo)))
- {
- strcpy(hi->name,curdname);
- if(hi->name[strlen(hi->name)-1]!='.') strcat(hi->name,curnet);
- else hi->name[strlen(hi->name)-1]='\0';
- hi->netnumber=netnumber;
- #ifdef DEBUG
- printf("add: %s(%s)\n",hi->name,Inet_NtoA(hi->netnumber));
- #endif
- AddTail((struct List *)&hostlist,(struct Node *)hi);
- }
- }
- }
-
- fclose(f);
- }
-
- void send_err(int s,char *msg,int msglen,struct sockaddr_in *to,LONG tolen,short rcode)
- {
- HEADER *h;
-
- h=(HEADER *)msg+sizeof(HEADER);
- h->qr=1;
- h->rcode=rcode;
- sendto(s,msg,msglen,0,(struct sockaddr *)to,tolen);
-
- #ifdef DEBUG
- switch(rcode)
- {
- case FORMERR: puts("FORMERR send");break;
- case SERVFAIL: puts("FORMFAIL send");break;
- case NXDOMAIN: puts("NXDOMAIN send");break;
- default: puts("UNKNOWN ERROR send");break;
- }
- #endif
- }
-
- main()
- {
- struct servent *sp;
- struct sockaddr_in sin;
- struct sockaddr_in from;
- struct hostinfo *hp,*hi;
- LONG fromlen;
- char msg[PACKETSZ];
- char *lmsg;
- char dnbuf[MAXDNAME];
- char *cp,*eom;
- int msglen;
- int s,n;
- short type,class;
-
- sp=getservbyname("domain","udp");
- if(!sp)
- {
- fprintf(stderr,"nameserver: tcp/nameserver: unknown service\n");
- exit(1);
- }
-
- s=socket(AF_INET,SOCK_DGRAM,0);
- if(s==-1)
- {
- perror("nameserver: create socket");
- exit(1);
- }
-
- bzero(&sin,sizeof(sin));
- sin.sin_port=sp->s_port;
-
- if(bind(s,(struct sockaddr *)&sin,sizeof(sin))==-1)
- {
- perror("nameserver: bind");
- exit(1);
- }
-
- if(gethostname(hostname,sizeof(hostname))==-1)
- {
- perror("nameserver: gethostname");
- exit(1);
- }
- if(cp=strchr(hostname,'.')) curnet=cp;
-
- readnamedhosts();
-
- #ifdef DEBUG
- printf("nameserver started\n");
- #endif
- for(;;)
- {
- fromlen=sizeof(from);
- if((msglen=recvfrom(s,msg,sizeof(msg),0,(struct sockaddr *)&from,&fromlen))==-1)
- {
- perror("nameserver: recvfrom");
- }
- else
- {
- HEADER *h;
- h=(HEADER *)msg;
- cp=msg+sizeof(HEADER);
- eom=msg+msglen;
- #ifdef DEBUG
- printf( "datagram received:\n"
- " from : %s\n"
- " opcode : %d\n"
- " qdqount: %d\n"
- ,inet_ntoa(from.sin_addr)
- ,h->opcode
- ,h->qdcount
- );
- #endif
- switch(h->opcode)
- {
- case QUERY:
- if(h->qdcount!=1 || h->ancount || h->nscount || h->arcount)
- {
- h->qdcount=0;
- h->ancount=0;
- h->nscount=0;
- h->arcount=0;
- send_err(s,msg,msglen,&from,fromlen,FORMERR);
- continue;
- }
- if((n=dn_expand(msg,eom,cp,dnbuf,sizeof(dnbuf)))<0)
- {
- send_err(s,msg,msglen,&from,fromlen,FORMERR);
- continue;
- }
- cp+=n;
- GETSHORT(type, cp);
- GETSHORT(class, cp);
- if(cp>eom)
- {
- send_err(s,msg,msglen,&from,fromlen,FORMERR);
- continue;
- }
- #ifdef DEBUG
- printf(" host : %s\n",dnbuf);
- printf(" type : %d\n",type);
- printf(" class : %d\n",class);
- #endif
- if(type!=T_A || class!=C_IN)
- {
- send_err(s,msg,msglen,&from,fromlen,NOTIMP);
- continue;
- }
-
- hp=NULL;
- for(hi=(struct hostinfo *)hostlist.mlh_Head;hi!=(struct hostinfo *)&hostlist.mlh_Tail;hi=(struct hostinfo *)hi->Node.mln_Succ)
- {
- if(!strcmp(hi->name,dnbuf))
- {
- hp=hi;
- break;
- }
- }
-
- if(!hp)
- {
- send_err(s,msg,msglen,&from,fromlen,NXDOMAIN);
- continue;
- }
-
- lmsg=msg+sizeof(msg);
- if((n=dn_comp(dnbuf,cp,lmsg-cp,NULL,NULL))<0)
- {
- send_err(s,msg,msglen,&from,fromlen,SERVFAIL);
- continue;
- }
- cp+=n;
- if(cp+14>lmsg)
- {
- send_err(s,msg,msglen,&from,fromlen,SERVFAIL);
- continue;
- }
-
- PUTSHORT(type, cp);
- PUTSHORT(class, cp);
- PUTLONG(100000,cp);
- PUTSHORT(sizeof(LONG),cp);
- PUTLONG(hi->netnumber,cp);
-
- h->qr=1;
- h->rcode=NOERROR;
- h->ancount=1;
- sendto(s,msg,cp-msg,0,(struct sockaddr *)&from,fromlen);
- #ifdef DEBUG
- printf("answer: %s(%s) send\n",dnbuf,Inet_NtoA(hi->netnumber));
- #endif
- break;
- default:
- send_err(s,msg,msglen,&from,fromlen,NOTIMP);
- }
- }
- }
- }
-