Print this page
1926 libresolv evades compiler warnings
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libresolv/res_gethost.c
+++ new/usr/src/lib/libresolv/res_gethost.c
1 1 /*
2 + * Copyright 2015 Gary Mills
2 3 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
3 4 * Use is subject to license terms.
4 5 */
5 6
6 7 /*
7 8 * Copyright (c) 1985, 1988 Regents of the University of California.
8 9 * All rights reserved.
9 10 *
10 11 * Redistribution and use in source and binary forms are permitted
11 12 * provided that this notice is preserved and that due credit is given
12 13 * to the University of California at Berkeley. The name of the University
13 14 * may not be used to endorse or promote products derived from this
14 15 * software without specific prior written permission. This software
15 16 * is provided ``as is'' without express or implied warranty.
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
16 17 *
17 18 */
18 19
19 20 #include <sys/param.h>
20 21 #include <sys/socket.h>
21 22 #include <netinet/in.h>
22 23 #include <ctype.h>
23 24 #include <netdb.h>
24 25 #include <stdio.h>
25 26 #include <errno.h>
27 +#include <string.h>
26 28 #include <arpa/inet.h>
27 29 #include <arpa/nameser.h>
28 30 #include <resolv.h>
29 31 #include <syslog.h>
32 +#include "crossl.h"
30 33
31 34 /*
32 35 * When the name service switch calls libresolv, it doesn't want fallback
33 36 * to /etc/hosts, so we provide a method to turn it off.
34 37 */
35 38 static int no_hosts_fallback = 0;
36 39
37 40 void
38 41 __res_set_no_hosts_fallback(void) {
39 42 no_hosts_fallback = 1;
40 43 }
41 44
42 45 static int
43 46 __res_no_hosts_fallback(void) {
44 47 return(no_hosts_fallback);
45 48 }
46 49
47 50 static char *h_addr_ptrs[MAXADDRS + 1];
48 51
49 52 static struct hostent host;
50 53 static char *host_aliases[MAXALIASES];
51 54 static char hostbuf[BUFSIZ+1];
52 55 static struct in_addr host_addr;
53 56 static char HOSTDB[] = "/etc/hosts";
54 57 static FILE *hostf = NULL;
55 58 static char hostaddr[MAXADDRS];
56 59 static char *host_addrs[2];
57 60 static int stayopen = 0;
58 61 static char *any();
59 62
60 63 #if PACKETSZ > 1024
61 64 #define MAXPACKET PACKETSZ
62 65 #else
63 66 #define MAXPACKET 1024
64 67 #endif
65 68
66 69 typedef union {
67 70 HEADER hdr;
68 71 u_char buf[MAXPACKET];
69 72 } querybuf;
70 73
71 74 static union {
72 75 long al;
73 76 char ac;
74 77 } align;
75 78
76 79
77 80 int h_errno;
78 81
79 82 static struct hostent *
80 83 getanswer(answer, anslen, iquery)
81 84 querybuf *answer;
82 85 int anslen;
83 86 int iquery;
84 87 {
85 88 register HEADER *hp;
86 89 register u_char *cp;
87 90 register int n;
88 91 u_char *eom;
89 92 char *bp, **ap;
90 93 int type, class, buflen, ancount, qdcount;
91 94 int haveanswer, getclass = C_ANY;
92 95 char **hap;
93 96
94 97 eom = answer->buf + anslen;
95 98 /*
↓ open down ↓ |
56 lines elided |
↑ open up ↑ |
96 99 * find first satisfactory answer
97 100 */
98 101 hp = &answer->hdr;
99 102 ancount = ntohs(hp->ancount);
100 103 qdcount = ntohs(hp->qdcount);
101 104 bp = hostbuf;
102 105 buflen = sizeof (hostbuf);
103 106 cp = answer->buf + sizeof (HEADER);
104 107 if (qdcount) {
105 108 if (iquery) {
106 - if ((n = dn_expand((char *)answer->buf, eom,
107 - cp, bp, buflen)) < 0) {
109 + if ((n = dn_expand(answer->buf, eom,
110 + cp, (u_char *)bp, buflen)) < 0) {
108 111 h_errno = NO_RECOVERY;
109 112 return ((struct hostent *) NULL);
110 113 }
111 114 cp += n + QFIXEDSZ;
112 115 host.h_name = bp;
113 116 n = strlen(bp) + 1;
114 117 bp += n;
115 118 buflen -= n;
116 119 } else
117 120 cp += dn_skipname(cp, eom) + QFIXEDSZ;
118 121 while (--qdcount > 0)
119 122 cp += dn_skipname(cp, eom) + QFIXEDSZ;
120 123 } else if (iquery) {
121 124 if (hp->aa)
122 125 h_errno = HOST_NOT_FOUND;
123 126 else
124 127 h_errno = TRY_AGAIN;
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
125 128 return ((struct hostent *) NULL);
126 129 }
127 130 ap = host_aliases;
128 131 host.h_aliases = host_aliases;
129 132 hap = h_addr_ptrs;
130 133 #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
131 134 host.h_addr_list = h_addr_ptrs;
132 135 #endif
133 136 haveanswer = 0;
134 137 while (--ancount >= 0 && cp < eom && haveanswer < MAXADDRS) {
135 - if ((n = dn_expand((char *)answer->buf, eom,
136 - cp, bp, buflen)) < 0)
138 + if ((n = dn_expand(answer->buf, eom,
139 + cp, (u_char *)bp, buflen)) < 0)
137 140 break;
138 141 cp += n;
139 142 type = _getshort(cp);
140 143 cp += sizeof (u_short);
141 144 class = _getshort(cp);
142 145 cp += sizeof (u_short) + sizeof (u_long);
143 146 n = _getshort(cp);
144 147 cp += sizeof (u_short);
145 148 if (type == T_CNAME) {
146 149 cp += n;
147 150 if (ap >= &host_aliases[MAXALIASES-1])
148 151 continue;
149 152 *ap++ = bp;
150 153 n = strlen(bp) + 1;
151 154 bp += n;
152 155 buflen -= n;
153 156 continue;
154 157 }
155 158 if (iquery && type == T_PTR) {
156 - if ((n = dn_expand((char *)answer->buf, eom,
157 - cp, bp, buflen)) < 0) {
159 + if ((n = dn_expand(answer->buf, eom,
160 + cp, (u_char *)bp, buflen)) < 0) {
158 161 cp += n;
159 162 continue;
160 163 }
161 164 cp += n;
162 165 host.h_name = bp;
163 166 return (&host);
164 167 }
165 168 if (iquery || type != T_A) {
166 169 #ifdef DEBUG
167 170 if (_res.options & RES_DEBUG)
168 171 printf("unexpected answer type %d, size %d\n",
169 172 type, n);
170 173 #endif
171 174 cp += n;
172 175 continue;
173 176 }
174 177 if (haveanswer) {
175 178 if (n != host.h_length) {
176 179 cp += n;
177 180 continue;
178 181 }
179 182 if (class != getclass) {
180 183 cp += n;
181 184 continue;
182 185 }
183 186 } else {
184 187 host.h_length = n;
185 188 getclass = class;
186 189 host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC;
187 190 if (!iquery) {
188 191 host.h_name = bp;
189 192 bp += strlen(bp) + 1;
190 193 }
191 194 }
192 195
193 196 bp += sizeof (align) - ((u_long)bp % sizeof (align));
194 197
195 198 if (bp + n >= &hostbuf[sizeof (hostbuf)]) {
196 199 #ifdef DEBUG
197 200 if (_res.options & RES_DEBUG)
198 201 printf("size (%d) too big\n", n);
199 202 #endif
200 203 break;
201 204 }
202 205 #ifdef SYSV
203 206 memcpy((void *)(*hap++ = bp), (void *)cp, n);
204 207 #else
205 208 bcopy(cp, *hap++ = bp, n);
206 209 #endif
207 210 bp += n;
208 211 cp += n;
209 212 haveanswer++;
210 213 }
211 214 if (haveanswer) {
212 215 *ap = NULL;
213 216 #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
214 217 *hap = NULL;
215 218 #else
216 219 host.h_addr = h_addr_ptrs[0];
217 220 #endif
218 221 return (&host);
219 222 } else {
220 223 h_errno = TRY_AGAIN;
221 224 return ((struct hostent *) NULL);
222 225 }
223 226 }
↓ open down ↓ |
56 lines elided |
↑ open up ↑ |
224 227
225 228 static struct hostent *_gethtbyname();
226 229
227 230 struct hostent *
228 231 res_gethostbyname(name)
229 232 char *name;
230 233 {
231 234 querybuf buf;
232 235 register char *cp;
233 236 int n;
234 - struct hostent *hp, *gethostdomain();
235 237
236 238 /*
237 239 * disallow names consisting only of digits/dots, unless
238 240 * they end in a dot.
239 241 */
240 242 if (isdigit(name[0]))
241 243 for (cp = name; /*EMPTY*/; ++cp) {
242 244 if (!*cp) {
243 245 if (*--cp == '.')
244 246 break;
245 247 h_errno = HOST_NOT_FOUND;
246 248 return ((struct hostent *) NULL);
247 249 }
248 250 if (!isdigit(*cp) && *cp != '.')
249 251 break;
250 252 }
251 253
252 254 if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof (buf))) < 0) {
253 255 #ifdef DEBUG
254 256 if (_res.options & RES_DEBUG)
255 257 printf("res_search failed\n");
256 258 #endif
257 259 if (errno == ECONNREFUSED)
258 260 return (_gethtbyname(name));
259 261 else
260 262 return ((struct hostent *) NULL);
261 263 }
262 264 return (getanswer(&buf, n, 0));
263 265 }
264 266
265 267 static struct hostent *_gethtbyaddr();
266 268
267 269 static struct hostent *
268 270 _getrhbyaddr(addr, len, type)
269 271 char *addr;
270 272 int len, type;
271 273 {
272 274 int n;
273 275 querybuf buf;
↓ open down ↓ |
29 lines elided |
↑ open up ↑ |
274 276 register struct hostent *hp;
275 277 char qbuf[MAXDNAME];
276 278
277 279 if (type != AF_INET)
278 280 return ((struct hostent *) NULL);
279 281 (void) sprintf(qbuf, "%d.%d.%d.%d.in-addr.arpa",
280 282 ((unsigned)addr[3] & 0xff),
281 283 ((unsigned)addr[2] & 0xff),
282 284 ((unsigned)addr[1] & 0xff),
283 285 ((unsigned)addr[0] & 0xff));
284 - n = res_query(qbuf, C_IN, T_PTR, (char *)&buf, sizeof (buf));
286 + n = res_query(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof (buf));
285 287 if (n < 0) {
286 288 #ifdef DEBUG
287 289 if (_res.options & RES_DEBUG)
288 290 printf("res_query failed\n");
289 291 #endif
290 292 if (errno == ECONNREFUSED)
291 293 return (_gethtbyaddr(addr, len, type));
292 294 return ((struct hostent *) NULL);
293 295 }
294 296 hp = getanswer(&buf, n, 1);
295 297 if (hp == NULL)
296 298 return ((struct hostent *) NULL);
297 299 hp->h_addrtype = type;
298 300 hp->h_length = len;
299 301 h_addr_ptrs[0] = (char *)&host_addr;
300 302 h_addr_ptrs[1] = (char *)0;
301 303 host_addr = *(struct in_addr *)addr;
302 304 return (hp);
303 305 }
304 306
305 307 /*
306 308 * First we get what the PTR record says, but do an extra call
307 309 * to gethostbyname() to make sure that someone is not trying to
308 310 * spoof us. Hopefully this is not done that often, so good
309 311 * performance is not really an issue.
310 312 */
311 313 struct hostent *
312 314 res_gethostbyaddr(addr, len, type)
313 315 char *addr;
314 316 int len;
315 317 int type;
316 318 {
317 319 char **a, hbuf[MAXHOSTNAMELEN];
318 320 struct hostent *hp, *hp2;
319 321
320 322 if ((hp = _getrhbyaddr(addr, len, type)) == (struct hostent *)NULL)
321 323 return ((struct hostent *)NULL);
322 324
323 325 /* hang on to what we got as an answer */
324 326 (void) strcpy(hbuf, hp->h_name);
325 327
326 328 /* check to make sure by doing a forward query */
327 329 if ((hp2 = res_gethostbyname(hbuf)) != (struct hostent *)NULL)
328 330 for (a = hp2->h_addr_list; *a; a++)
329 331 #ifdef SYSV
330 332 if (memcmp(*a, addr, hp2->h_length) == 0)
331 333 #else
332 334 if (bcmp(*a, addr, hp2->h_length) == 0)
333 335 #endif
334 336 return (hp2);
335 337
336 338 /*
337 339 * we've been spoofed, make sure to log it.
338 340 * XXX - syslog needs a security priority level.
339 341 */
340 342 syslog(LOG_NOTICE, "gethostbyaddr: %s != %s", hbuf,
341 343 inet_ntoa(*(struct in_addr *)addr));
342 344 return ((struct hostent *)NULL);
343 345 }
344 346
345 347 static void
346 348 _sethtent(int f)
347 349 {
348 350 if (__res_no_hosts_fallback()) return;
349 351
350 352 if (hostf == NULL)
351 353 hostf = fopen(HOSTDB, "r");
352 354 else
353 355 rewind(hostf);
354 356 stayopen |= f;
355 357 }
356 358
357 359 static void
358 360 _endhtent(void)
359 361 {
360 362 if (__res_no_hosts_fallback()) return;
361 363
362 364 if (hostf && !stayopen) {
363 365 (void) fclose(hostf);
364 366 hostf = NULL;
365 367 }
366 368 }
367 369
368 370 static struct hostent *
369 371 _gethtent()
370 372 {
371 373 char *p;
372 374 register char *cp, **q;
373 375
374 376 if (__res_no_hosts_fallback()) return(NULL);
375 377
376 378 if (hostf == NULL && (hostf = fopen(HOSTDB, "r")) == NULL)
377 379 return (NULL);
378 380 again:
379 381 if ((p = fgets(hostbuf, BUFSIZ, hostf)) == NULL)
380 382 return (NULL);
381 383 if (*p == '#')
382 384 goto again;
383 385 cp = any(p, "#\n");
384 386 if (cp == NULL)
385 387 goto again;
386 388 *cp = '\0';
387 389 cp = any(p, " \t");
388 390 if (cp == NULL)
389 391 goto again;
390 392 *cp++ = '\0';
391 393 /* THIS STUFF IS INTERNET SPECIFIC */
392 394 #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
393 395 host.h_addr_list = host_addrs;
394 396 #endif
395 397 host.h_addr = hostaddr;
396 398 *((u_long *)host.h_addr) = inet_addr(p);
397 399 host.h_length = sizeof (u_long);
398 400 host.h_addrtype = AF_INET;
399 401 while (*cp == ' ' || *cp == '\t')
400 402 cp++;
401 403 host.h_name = cp;
402 404 q = host.h_aliases = host_aliases;
403 405 cp = any(cp, " \t");
404 406 if (cp != NULL)
405 407 *cp++ = '\0';
406 408 while (cp && *cp) {
407 409 if (*cp == ' ' || *cp == '\t') {
408 410 cp++;
409 411 continue;
410 412 }
411 413 if (q < &host_aliases[MAXALIASES - 1])
412 414 *q++ = cp;
413 415 cp = any(cp, " \t");
414 416 if (cp != NULL)
415 417 *cp++ = '\0';
416 418 }
417 419 *q = NULL;
418 420 return (&host);
419 421 }
420 422
421 423 static char *
422 424 any(cp, match)
423 425 register char *cp;
424 426 char *match;
425 427 {
426 428 register char *mp, c;
427 429
428 430 while (c = *cp) {
429 431 for (mp = match; *mp; mp++)
430 432 if (*mp == c)
431 433 return (cp);
432 434 cp++;
433 435 }
434 436 return ((char *)0);
435 437 }
436 438
437 439 static struct hostent *
438 440 _gethtbyname(name)
439 441 char *name;
440 442 {
441 443 register struct hostent *p;
442 444 register char **cp;
443 445
444 446 _sethtent(0);
445 447 while (p = _gethtent()) {
446 448 if (strcasecmp(p->h_name, name) == 0)
447 449 break;
448 450 for (cp = p->h_aliases; *cp != 0; cp++)
449 451 if (strcasecmp(*cp, name) == 0)
450 452 goto found;
451 453 }
452 454 found:
453 455 _endhtent();
454 456 return (p);
455 457 }
456 458
457 459 static struct hostent *
458 460 _gethtbyaddr(addr, len, type)
459 461 char *addr;
460 462 int len, type;
461 463 {
462 464 register struct hostent *p;
463 465
464 466 _sethtent(0);
465 467 while (p = _gethtent())
466 468 #ifdef SYSV
467 469 if (p->h_addrtype == type && !memcmp(p->h_addr, addr, len))
468 470 #else
469 471 if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len))
470 472 #endif
471 473 break;
472 474 _endhtent();
473 475 return (p);
474 476 }
↓ open down ↓ |
180 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX