xref: /csrg-svn/lib/libc/net/gethostnamadr.c (revision 18505)
1*18505Sralph /*	gethostnamadr.c	4.9	85/03/25	*/
215662Sralph 
3*18505Sralph #include <sys/types.h>
4*18505Sralph #include <sys/socket.h>
5*18505Sralph #include <netinet/in.h>
6*18505Sralph #include <netdb.h>
715662Sralph #include <stdio.h>
8*18505Sralph #include <nameser.h>
9*18505Sralph #include <resolv.h>
1015662Sralph 
1115662Sralph #define	MAXALIASES	35
1215662Sralph 
1315662Sralph static struct hostent host;
1415662Sralph static char *host_aliases[MAXALIASES];
1515912Sralph static char hostbuf[BUFSIZ+1];
1615662Sralph 
1715662Sralph static struct hostent *
18*18505Sralph getanswer(msg, msglen, iquery)
19*18505Sralph 	char *msg;
20*18505Sralph 	int msglen, iquery;
2115662Sralph {
22*18505Sralph 	register HEADER *hp;
23*18505Sralph 	register char *cp;
24*18505Sralph 	register int n;
25*18505Sralph 	char answer[PACKETSZ];
26*18505Sralph 	char *eom, *bp, **ap;
27*18505Sralph 	int type, class, ancount, buflen;
2815662Sralph 
29*18505Sralph 	n = sendquery(msg, msglen, answer, sizeof(answer));
30*18505Sralph 	if (n < 0) {
31*18505Sralph 		if (_res.options & RES_DEBUG)
32*18505Sralph 			printf("sendquery failed\n");
33*18505Sralph 		return (NULL);
3415662Sralph 	}
35*18505Sralph 	eom = answer + n;
36*18505Sralph 	/*
37*18505Sralph 	 * find first satisfactory answer
38*18505Sralph 	 */
39*18505Sralph 	hp = (HEADER *) answer;
40*18505Sralph 	ancount = ntohs(hp->ancount);
41*18505Sralph 	if (hp->rcode != NOERROR || ancount == 0) {
42*18505Sralph 		if (_res.options & RES_DEBUG)
43*18505Sralph 			printf("rcode = %d, ancount=%d\n", hp->rcode, ancount);
44*18505Sralph 		return (NULL);
45*18505Sralph 	}
46*18505Sralph 	bp = hostbuf;
47*18505Sralph 	buflen = sizeof(hostbuf);
48*18505Sralph 	ap = host_aliases;
49*18505Sralph 	cp = answer + sizeof(HEADER);
50*18505Sralph 	if (hp->qdcount) {
51*18505Sralph 		if (iquery) {
52*18505Sralph 			if ((n = dn_expand(answer, cp, bp, buflen)) < 0)
53*18505Sralph 				return (NULL);
54*18505Sralph 			cp += n + QFIXEDSZ;
55*18505Sralph 			host.h_name = bp;
56*18505Sralph 			n = strlen(bp) + 1;
57*18505Sralph 			bp += n;
58*18505Sralph 			buflen -= n;
59*18505Sralph 		} else
60*18505Sralph 			cp += dn_skip(cp) + QFIXEDSZ;
61*18505Sralph 	} else if (iquery)
62*18505Sralph 		return (NULL);
63*18505Sralph 	while (--ancount >= 0 && cp < eom) {
64*18505Sralph 		if ((n = dn_expand(answer, cp, bp, buflen)) < 0)
65*18505Sralph 			return (NULL);
66*18505Sralph 		cp += n;
67*18505Sralph 		type = getshort(cp);
68*18505Sralph  		cp += sizeof(u_short);
69*18505Sralph 		class = getshort(cp);
70*18505Sralph  		cp += sizeof(u_short) + sizeof(u_long);
71*18505Sralph 		n = getshort(cp);
72*18505Sralph 		cp += sizeof(u_short);
73*18505Sralph 		if (type == T_CNAME) {
74*18505Sralph 			cp += n;
75*18505Sralph 			if (ap >= &host_aliases[MAXALIASES-1])
76*18505Sralph 				continue;
77*18505Sralph 			*ap++ = bp;
78*18505Sralph 			n = strlen(bp) + 1;
79*18505Sralph 			bp += n;
80*18505Sralph 			buflen -= n;
81*18505Sralph 			continue;
82*18505Sralph 		}
83*18505Sralph 		if (type != T_A || n != 4) {
84*18505Sralph 			if (_res.options & RES_DEBUG)
85*18505Sralph 				printf("unexpected answer type %d, size %d\n",
86*18505Sralph 					type, n);
87*18505Sralph 			continue;
88*18505Sralph 		}
89*18505Sralph 		if (!iquery) {
90*18505Sralph 			host.h_name = bp;
91*18505Sralph 			bp += strlen(bp) + 1;
92*18505Sralph 		}
93*18505Sralph 		*ap = NULL;
94*18505Sralph 		host.h_aliases = host_aliases;
95*18505Sralph 		host.h_addrtype = class == C_IN ? AF_INET : AF_UNSPEC;
96*18505Sralph 		if (bp + n >= &hostbuf[sizeof(hostbuf)]) {
97*18505Sralph 			if (_res.options & RES_DEBUG)
98*18505Sralph 				printf("size (%d) too big\n", n);
99*18505Sralph 			return (NULL);
100*18505Sralph 		}
101*18505Sralph 		bcopy(cp, host.h_addr = bp, host.h_length = n);
102*18505Sralph 		return (&host);
103*18505Sralph 	}
104*18505Sralph 	return (NULL);
10515662Sralph }
10615662Sralph 
10715662Sralph struct hostent *
108*18505Sralph gethostbyname(name)
109*18505Sralph 	char *name;
11015662Sralph {
111*18505Sralph 	int n;
11215662Sralph 
113*18505Sralph 	n = mkquery(QUERY, name, C_ANY, T_A, NULL, 0, NULL, hostbuf, sizeof(hostbuf));
114*18505Sralph 	if (n < 0) {
115*18505Sralph 		if (_res.options & RES_DEBUG)
116*18505Sralph 			printf("mkquery failed\n");
117*18505Sralph 		return (NULL);
11817761Sserge 	}
119*18505Sralph 	return (getanswer(hostbuf, n, 0));
12015662Sralph }
12115662Sralph 
12215662Sralph struct hostent *
123*18505Sralph gethostbyaddr(addr, len, type)
12415662Sralph 	char *addr;
125*18505Sralph 	int len, type;
12615662Sralph {
127*18505Sralph 	int n;
12815662Sralph 
129*18505Sralph 	if (type != AF_INET)
130*18505Sralph 		return (NULL);
131*18505Sralph 	n = mkquery(IQUERY, NULL, C_IN, T_A, addr, len, NULL, hostbuf, sizeof(hostbuf));
132*18505Sralph 	if (n < 0) {
133*18505Sralph 		if (_res.options & RES_DEBUG)
134*18505Sralph 			printf("mkquery failed\n");
135*18505Sralph 		return (NULL);
13617761Sserge 	}
137*18505Sralph 	return (getanswer(hostbuf, n, 1));
13815662Sralph }
139