# /* name_user.c */ /* EMACS_MODES: c !fill */ /* This file contains the routines to deal with the Internet name * servers for resolving Internet names. Presently the addresses * of the available Internet name servers are compiled in; the * routine udpname () goes out to all the available Internet * name servers to try to resolve the name. * This file containst the following routines: * udpname resolve a name by asking Internet name servers */ #include #include #include "name_user.h" #define TIMEOUT 15 /* response timeout */ /* Table of all known nameservers */ static struct nstab { int ns_sock; /* foreign socket */ in_name ns_name; /* host address */ } nameservers[] = { { 14, 0x000A0600 }, /* mit-multics */ { 14, 0x02128000 }, /* mit-spooler */ { 42, 0x000A4900 }, /* sri-nic */ { 42, 0x030A0500 }, /* bbna */ { 14, 0x000A2C00 }, /* mit-xx */ }; static int nnsrv = sizeof(nameservers)/(sizeof(struct nstab)); in_name udpname (name) /* Try to resolve the specified name by asking other udp nameservers. * Build nameserver requests for each of the nameservers we presently * know about, send them all out, then wait for responses. Returns * the internet address, or 0 if unknown. * * Arguments: */ char *name; /* name to be resolved */ { register struct nstab *pn; /* pointer to current ns */ register struct udp *pup; /* ptr. to udp header */ register struct ip *pip; /* ptr. to internet header */ struct nmitem *pnm; /* ptr. to packet data area */ unshort locsoc; /* local socket number */ int len; /* length of nameserver request */ int done; /* no. of nameservers responded */ union { char bytes[4]; in_name name; } res; /* result */ caddr_t inpkt; /* received packet */ caddr_t outpkt; /* output packet */ int udpfd; /* udp file descriptor */ long now; /* current time */ long donetime; /* time to finish */ int rcvlen; /* len of received packet */ int i; /* temp index */ len = strlen (name) + sizeof (struct nmitem); locsoc = udp_socket (); if ((udpfd = udp_open (0L, 0, locsoc)) < 0) return (0L); if ((inpkt = udp_alloc (INPKTSIZ, 0)) == NULL) return (0L); if ((outpkt = udp_alloc (len+1, 0)) == NULL) { udp_free (inpkt); return (0L); } done = 0; pip = in_head(outpkt); /* get headers */ pup = udp_head(pip); pnm = (struct nmitem *)udp_data(pup); pnm->nm_type = NI_NAME; /* build common part of request */ pnm->nm_len = len - 2; strcpy (&pnm->nm_item, name); for (pn = &nameservers[0]; pn < &nameservers[nnsrv]; pn++) { pip->ip_dest = pn->ns_name; /* set up headers */ pip->ip_id = 0; /* kernel fills id */ pup->ud_srcp = locsoc; /* udp headers must be built here */ pup->ud_dstp = pn->ns_sock; /* they're byteswapped in pkt */ if (udp_write (udpfd, outpkt, len) <= 0) done++; #ifdef DEBUG else in_logpkt (outpkt,len+sizeof(struct udp),OUTPKT); #endif } time (&now); donetime = now + TIMEOUT; while (now < donetime && done < nnsrv) { if ((rcvlen = udp_bread (udpfd, inpkt, INPKTSIZ, (int)(donetime - now))) > 0) { pip = in_head(inpkt); pup = udp_head(pip); pnm = (struct nmitem *)udp_data(pup); /* Get to second item in the message - the response */ pnm = (struct nmitem *)(&pnm->nm_item[pnm->nm_len]); #ifdef DEBUG in_logpkt (inpkt,pup->ud_len,INPKT); #endif if (pnm->nm_type == NI_ADDR) { /* success! */ for (i = 0; i < sizeof (in_name); i++) res.bytes[i] = pnm->nm_item[i]; udp_close (udpfd); udp_free (outpkt); udp_free (inpkt); return (res.name); } /* must be error; ignore */ done++; time (&now); } else /* timeout; give up */ break; } udp_close (udpfd); udp_free (outpkt); udp_free (inpkt); return (0L); }