1. when raising windows, let those frozen out know
[unix-history] / usr / src / lib / libc / net / gethostnamadr.c
CommitLineData
8ea4199d 1/*
412fa3e3 2 * Copyright (c) 1983 Regents of the University of California.
8ea4199d
DF
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
7#ifndef lint
22352302 8static char sccsid[] = "@(#)gethostnamadr.c 5.6 (Berkeley) %G%";
8ea4199d 9#endif not lint
b423e985 10
f784656b
RC
11#include <sys/types.h>
12#include <sys/socket.h>
13#include <netinet/in.h>
337257b2 14#include <netdb.h>
f784656b 15#include <stdio.h>
aa678832
JB
16#include <arpa/nameser.h>
17#include <arpa/resolv.h>
337257b2
RC
18
19#define MAXALIASES 35
412fa3e3 20#define MAXADDRS 35
337257b2 21
412fa3e3
JB
22static char *h_addr_ptrs[MAXADDRS + 1];
23
24static struct hostent host;
337257b2 25static char *host_aliases[MAXALIASES];
291cd39e 26static char hostbuf[BUFSIZ+1];
3a87f357 27
6f4c7128 28
337257b2 29static struct hostent *
f784656b
RC
30getanswer(msg, msglen, iquery)
31 char *msg;
32 int msglen, iquery;
337257b2 33{
f784656b
RC
34 register HEADER *hp;
35 register char *cp;
36 register int n;
37 char answer[PACKETSZ];
38 char *eom, *bp, **ap;
39 int type, class, ancount, buflen;
412fa3e3
JB
40 int haveanswer, getclass;
41 char **hap;
337257b2 42
31f0ead0 43 n = res_send(msg, msglen, answer, sizeof(answer));
f784656b
RC
44 if (n < 0) {
45 if (_res.options & RES_DEBUG)
31f0ead0 46 printf("res_send failed\n");
f784656b
RC
47 return (NULL);
48 }
49 eom = answer + n;
50 /*
51 * find first satisfactory answer
52 */
53 hp = (HEADER *) answer;
54 ancount = ntohs(hp->ancount);
55 if (hp->rcode != NOERROR || ancount == 0) {
56 if (_res.options & RES_DEBUG)
57 printf("rcode = %d, ancount=%d\n", hp->rcode, ancount);
58 return (NULL);
337257b2 59 }
f784656b
RC
60 bp = hostbuf;
61 buflen = sizeof(hostbuf);
f784656b
RC
62 cp = answer + sizeof(HEADER);
63 if (hp->qdcount) {
64 if (iquery) {
65 if ((n = dn_expand(answer, cp, bp, buflen)) < 0)
66 return (NULL);
67 cp += n + QFIXEDSZ;
68 host.h_name = bp;
69 n = strlen(bp) + 1;
70 bp += n;
71 buflen -= n;
72 } else
73 cp += dn_skip(cp) + QFIXEDSZ;
74 } else if (iquery)
75 return (NULL);
412fa3e3
JB
76 ap = host_aliases;
77 host.h_aliases = host_aliases;
78 hap = h_addr_ptrs;
79 host.h_addr_list = h_addr_ptrs;
80 haveanswer = 0;
f784656b
RC
81 while (--ancount >= 0 && cp < eom) {
82 if ((n = dn_expand(answer, cp, bp, buflen)) < 0)
412fa3e3 83 break;
f784656b
RC
84 cp += n;
85 type = getshort(cp);
86 cp += sizeof(u_short);
87 class = getshort(cp);
88 cp += sizeof(u_short) + sizeof(u_long);
89 n = getshort(cp);
90 cp += sizeof(u_short);
91 if (type == T_CNAME) {
92 cp += n;
93 if (ap >= &host_aliases[MAXALIASES-1])
94 continue;
95 *ap++ = bp;
96 n = strlen(bp) + 1;
97 bp += n;
98 buflen -= n;
99 continue;
100 }
412fa3e3 101 if (type != T_A) {
f784656b
RC
102 if (_res.options & RES_DEBUG)
103 printf("unexpected answer type %d, size %d\n",
104 type, n);
412fa3e3 105 cp += n;
f784656b
RC
106 continue;
107 }
412fa3e3
JB
108 if (haveanswer) {
109 if (n != host.h_length) {
110 cp += n;
111 continue;
112 }
113 if (class != getclass) {
114 cp += n;
115 continue;
116 }
117 } else {
118 host.h_length = n;
119 getclass = class;
120 host.h_addrtype = C_IN ? AF_INET : AF_UNSPEC;
121 if (!iquery) {
122 host.h_name = bp;
123 bp += strlen(bp) + 1;
124 }
f784656b 125 }
f784656b
RC
126 if (bp + n >= &hostbuf[sizeof(hostbuf)]) {
127 if (_res.options & RES_DEBUG)
128 printf("size (%d) too big\n", n);
412fa3e3 129 break;
f784656b 130 }
412fa3e3
JB
131 bcopy(cp, *hap++ = bp, n);
132 bp +=n;
133 cp += n;
134 haveanswer++;
f784656b 135 }
412fa3e3
JB
136 if (haveanswer) {
137 *ap = NULL;
138 *hap = NULL;
139 return (&host);
140 } else
141 return (NULL);
337257b2
RC
142}
143
144struct hostent *
f784656b
RC
145gethostbyname(name)
146 char *name;
337257b2 147{
f784656b 148 int n;
412fa3e3 149 char buf[BUFSIZ+1];
337257b2 150
412fa3e3 151 n = res_mkquery(QUERY, name, C_ANY, T_A, (char *)NULL, 0, NULL,
22352302 152 buf, sizeof(buf));
f784656b
RC
153 if (n < 0) {
154 if (_res.options & RES_DEBUG)
31f0ead0 155 printf("res_mkquery failed\n");
f784656b 156 return (NULL);
3a87f357 157 }
412fa3e3 158 return(getanswer(buf, n, 0));
337257b2
RC
159}
160
161struct hostent *
f784656b 162gethostbyaddr(addr, len, type)
337257b2 163 char *addr;
f784656b 164 int len, type;
337257b2 165{
f784656b 166 int n;
412fa3e3 167 char buf[BUFSIZ+1];
337257b2 168
f784656b
RC
169 if (type != AF_INET)
170 return (NULL);
412fa3e3 171 n = res_mkquery(IQUERY, (char *)NULL, C_IN, T_A, addr, len, NULL,
22352302 172 buf, sizeof(buf));
f784656b
RC
173 if (n < 0) {
174 if (_res.options & RES_DEBUG)
31f0ead0 175 printf("res_mkquery failed\n");
f784656b 176 return (NULL);
f268b9fa 177 }
412fa3e3 178 return(getanswer(buf, n, 1));
337257b2 179}
6f4c7128 180
6f4c7128 181