| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: getnetnamadr.c,v 1.42 2012/03/13 21:13:41 christos Exp $ */ | | 1 | /* $NetBSD: getnetnamadr.c,v 1.42.12.1 2015/11/08 00:35:21 riz Exp $ */ |
2 | | | 2 | |
3 | /* Copyright (c) 1993 Carlos Leandro and Rui Salgueiro | | 3 | /* Copyright (c) 1993 Carlos Leandro and Rui Salgueiro |
4 | * Dep. Matematica Universidade de Coimbra, Portugal, Europe | | 4 | * Dep. Matematica Universidade de Coimbra, Portugal, Europe |
5 | * | | 5 | * |
6 | * Permission to use, copy, modify, and distribute this software for any | | 6 | * Permission to use, copy, modify, and distribute this software for any |
7 | * purpose with or without fee is hereby granted, provided that the above | | 7 | * purpose with or without fee is hereby granted, provided that the above |
8 | * copyright notice and this permission notice appear in all copies. | | 8 | * copyright notice and this permission notice appear in all copies. |
9 | */ | | 9 | */ |
10 | /* | | 10 | /* |
11 | * Copyright (c) 1983, 1993 | | 11 | * Copyright (c) 1983, 1993 |
12 | * The Regents of the University of California. All rights reserved. | | 12 | * The Regents of the University of California. All rights reserved. |
13 | * | | 13 | * |
14 | * Redistribution and use in source and binary forms, with or without | | 14 | * Redistribution and use in source and binary forms, with or without |
| @@ -33,27 +33,27 @@ | | | @@ -33,27 +33,27 @@ |
33 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 33 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
34 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 34 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
35 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 35 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
36 | * SUCH DAMAGE. | | 36 | * SUCH DAMAGE. |
37 | */ | | 37 | */ |
38 | | | 38 | |
39 | #include <sys/cdefs.h> | | 39 | #include <sys/cdefs.h> |
40 | #if defined(LIBC_SCCS) && !defined(lint) | | 40 | #if defined(LIBC_SCCS) && !defined(lint) |
41 | #if 0 | | 41 | #if 0 |
42 | static char sccsid[] = "@(#)getnetbyaddr.c 8.1 (Berkeley) 6/4/93"; | | 42 | static char sccsid[] = "@(#)getnetbyaddr.c 8.1 (Berkeley) 6/4/93"; |
43 | static char sccsid_[] = "from getnetnamadr.c 1.4 (Coimbra) 93/06/03"; | | 43 | static char sccsid_[] = "from getnetnamadr.c 1.4 (Coimbra) 93/06/03"; |
44 | static char rcsid[] = "Id: getnetnamadr.c,v 8.8 1997/06/01 20:34:37 vixie Exp "; | | 44 | static char rcsid[] = "Id: getnetnamadr.c,v 8.8 1997/06/01 20:34:37 vixie Exp "; |
45 | #else | | 45 | #else |
46 | __RCSID("$NetBSD: getnetnamadr.c,v 1.42 2012/03/13 21:13:41 christos Exp $"); | | 46 | __RCSID("$NetBSD: getnetnamadr.c,v 1.42.12.1 2015/11/08 00:35:21 riz Exp $"); |
47 | #endif | | 47 | #endif |
48 | #endif /* LIBC_SCCS and not lint */ | | 48 | #endif /* LIBC_SCCS and not lint */ |
49 | | | 49 | |
50 | #include "namespace.h" | | 50 | #include "namespace.h" |
51 | #include <sys/types.h> | | 51 | #include <sys/types.h> |
52 | #include <sys/param.h> | | 52 | #include <sys/param.h> |
53 | #include <sys/socket.h> | | 53 | #include <sys/socket.h> |
54 | #include <netinet/in.h> | | 54 | #include <netinet/in.h> |
55 | #include <arpa/inet.h> | | 55 | #include <arpa/inet.h> |
56 | #include <arpa/nameser.h> | | 56 | #include <arpa/nameser.h> |
57 | | | 57 | |
58 | #include <assert.h> | | 58 | #include <assert.h> |
59 | #include <ctype.h> | | 59 | #include <ctype.h> |
| @@ -67,26 +67,32 @@ __RCSID("$NetBSD: getnetnamadr.c,v 1.42 | | | @@ -67,26 +67,32 @@ __RCSID("$NetBSD: getnetnamadr.c,v 1.42 |
67 | #include <string.h> | | 67 | #include <string.h> |
68 | | | 68 | |
69 | #ifdef YP | | 69 | #ifdef YP |
70 | #include <rpc/rpc.h> | | 70 | #include <rpc/rpc.h> |
71 | #include <rpcsvc/yp_prot.h> | | 71 | #include <rpcsvc/yp_prot.h> |
72 | #include <rpcsvc/ypclnt.h> | | 72 | #include <rpcsvc/ypclnt.h> |
73 | #endif | | 73 | #endif |
74 | | | 74 | |
75 | #ifdef __weak_alias | | 75 | #ifdef __weak_alias |
76 | __weak_alias(getnetbyaddr,_getnetbyaddr) | | 76 | __weak_alias(getnetbyaddr,_getnetbyaddr) |
77 | __weak_alias(getnetbyname,_getnetbyname) | | 77 | __weak_alias(getnetbyname,_getnetbyname) |
78 | #endif | | 78 | #endif |
79 | | | 79 | |
| | | 80 | #define maybe_ok(res, nm, ok) (((res)->options & RES_NOCHECKNAME) != 0U || \ |
| | | 81 | (ok)(nm) != 0) |
| | | 82 | #define maybe_hnok(res, hn) maybe_ok((res), (hn), res_hnok) |
| | | 83 | #define maybe_dnok(res, dn) maybe_ok((res), (dn), res_dnok) |
| | | 84 | |
| | | 85 | |
80 | extern int _net_stayopen; | | 86 | extern int _net_stayopen; |
81 | | | 87 | |
82 | #define BYADDR 0 | | 88 | #define BYADDR 0 |
83 | #define BYNAME 1 | | 89 | #define BYNAME 1 |
84 | #define MAXALIASES 35 | | 90 | #define MAXALIASES 35 |
85 | | | 91 | |
86 | #define MAXPACKET (64*1024) | | 92 | #define MAXPACKET (64*1024) |
87 | | | 93 | |
88 | typedef union { | | 94 | typedef union { |
89 | HEADER hdr; | | 95 | HEADER hdr; |
90 | u_char buf[MAXPACKET]; | | 96 | u_char buf[MAXPACKET]; |
91 | } querybuf; | | 97 | } querybuf; |
92 | | | 98 | |
| @@ -95,27 +101,27 @@ typedef union { | | | @@ -95,27 +101,27 @@ typedef union { |
95 | char ac; | | 101 | char ac; |
96 | } align; | | 102 | } align; |
97 | | | 103 | |
98 | #ifdef YP | | 104 | #ifdef YP |
99 | static char *__ypdomain; | | 105 | static char *__ypdomain; |
100 | static char *__ypcurrent; | | 106 | static char *__ypcurrent; |
101 | static int __ypcurrentlen; | | 107 | static int __ypcurrentlen; |
102 | #endif | | 108 | #endif |
103 | | | 109 | |
104 | static struct netent net_entry; | | 110 | static struct netent net_entry; |
105 | static char *net_aliases[MAXALIASES]; | | 111 | static char *net_aliases[MAXALIASES]; |
106 | | | 112 | |
107 | static int parse_reversed_addr(const char *, in_addr_t *); | | 113 | static int parse_reversed_addr(const char *, in_addr_t *); |
108 | static struct netent *getnetanswer(querybuf *, int, int); | | 114 | static struct netent *getnetanswer(res_state, querybuf *, int, int); |
109 | static int _files_getnetbyaddr(void *, void *, va_list); | | 115 | static int _files_getnetbyaddr(void *, void *, va_list); |
110 | static int _files_getnetbyname(void *, void *, va_list); | | 116 | static int _files_getnetbyname(void *, void *, va_list); |
111 | static int _dns_getnetbyaddr(void *, void *, va_list); | | 117 | static int _dns_getnetbyaddr(void *, void *, va_list); |
112 | static int _dns_getnetbyname(void *, void *, va_list); | | 118 | static int _dns_getnetbyname(void *, void *, va_list); |
113 | #ifdef YP | | 119 | #ifdef YP |
114 | static int _yp_getnetbyaddr(void *, void *, va_list); | | 120 | static int _yp_getnetbyaddr(void *, void *, va_list); |
115 | static int _yp_getnetbyname(void *, void *, va_list); | | 121 | static int _yp_getnetbyname(void *, void *, va_list); |
116 | static struct netent *_ypnetent(char *); | | 122 | static struct netent *_ypnetent(char *); |
117 | #endif | | 123 | #endif |
118 | | | 124 | |
119 | /* | | 125 | /* |
120 | * parse_reversed_addr -- | | 126 | * parse_reversed_addr -- |
121 | * parse str, which should be of the form 'd.c.b.a.IN-ADDR.ARPA' | | 127 | * parse str, which should be of the form 'd.c.b.a.IN-ADDR.ARPA' |
| @@ -149,39 +155,40 @@ parse_reversed_addr(const char *str, in_ | | | @@ -149,39 +155,40 @@ parse_reversed_addr(const char *str, in_ |
149 | /* ensure trailer is correct */ | | 155 | /* ensure trailer is correct */ |
150 | if (strcasecmp(sp, "IN-ADDR.ARPA") != 0) | | 156 | if (strcasecmp(sp, "IN-ADDR.ARPA") != 0) |
151 | return -1; | | 157 | return -1; |
152 | *result = 0; | | 158 | *result = 0; |
153 | /* build result from octets in reverse */ | | 159 | /* build result from octets in reverse */ |
154 | for (octidx = 3; octidx >= 0; octidx--) { | | 160 | for (octidx = 3; octidx >= 0; octidx--) { |
155 | *result <<= 8; | | 161 | *result <<= 8; |
156 | *result |= (in_addr_t)(octet[octidx] & 0xff); | | 162 | *result |= (in_addr_t)(octet[octidx] & 0xff); |
157 | } | | 163 | } |
158 | return 0; | | 164 | return 0; |
159 | } | | 165 | } |
160 | | | 166 | |
161 | static struct netent * | | 167 | static struct netent * |
162 | getnetanswer(querybuf *answer, int anslen, int net_i) | | 168 | getnetanswer(res_state res, querybuf *answer, int anslen, int net_i) |
163 | { | | 169 | { |
164 | static char n_name[MAXDNAME]; | | 170 | static char n_name[MAXDNAME]; |
165 | static char netbuf[PACKETSZ]; | | 171 | static char netbuf[PACKETSZ]; |
166 | | | 172 | |
167 | HEADER *hp; | | 173 | HEADER *hp; |
168 | u_char *cp; | | 174 | u_char *cp; |
169 | int n; | | 175 | int n; |
170 | u_char *eom; | | 176 | u_char *eom; |
171 | int type, class, ancount, qdcount, haveanswer; | | 177 | int type, class, ancount, qdcount, haveanswer; |
172 | char *in, *bp, **ap, *ep; | | 178 | char *in, *bp, **ap, *ep; |
173 | | | 179 | |
174 | _DIAGASSERT(answer != NULL); | | 180 | _DIAGASSERT(answer != NULL); |
| | | 181 | _DIAGASSERT(res != NULL); |
175 | | | 182 | |
176 | /* | | 183 | /* |
177 | * find first satisfactory answer | | 184 | * find first satisfactory answer |
178 | * | | 185 | * |
179 | * answer --> +------------+ ( MESSAGE ) | | 186 | * answer --> +------------+ ( MESSAGE ) |
180 | * | Header | | | 187 | * | Header | |
181 | * +------------+ | | 188 | * +------------+ |
182 | * | Question | the question for the name server | | 189 | * | Question | the question for the name server |
183 | * +------------+ | | 190 | * +------------+ |
184 | * | Answer | RRs answering the question | | 191 | * | Answer | RRs answering the question |
185 | * +------------+ | | 192 | * +------------+ |
186 | * | Authority | RRs pointing toward an authority | | 193 | * | Authority | RRs pointing toward an authority |
187 | * | Additional | RRs holding additional information | | 194 | * | Additional | RRs holding additional information |
| @@ -206,37 +213,37 @@ getnetanswer(querybuf *answer, int ansle | | | @@ -206,37 +213,37 @@ getnetanswer(querybuf *answer, int ansle |
206 | if (n < 0 || (cp + n + QFIXEDSZ) > eom) { | | 213 | if (n < 0 || (cp + n + QFIXEDSZ) > eom) { |
207 | h_errno = NO_RECOVERY; | | 214 | h_errno = NO_RECOVERY; |
208 | return(NULL); | | 215 | return(NULL); |
209 | } | | 216 | } |
210 | cp += n + QFIXEDSZ; | | 217 | cp += n + QFIXEDSZ; |
211 | } | | 218 | } |
212 | ap = net_aliases; | | 219 | ap = net_aliases; |
213 | *ap = NULL; | | 220 | *ap = NULL; |
214 | net_entry.n_aliases = net_aliases; | | 221 | net_entry.n_aliases = net_aliases; |
215 | haveanswer = 0; | | 222 | haveanswer = 0; |
216 | n_name[0] = '\0'; | | 223 | n_name[0] = '\0'; |
217 | while (--ancount >= 0 && cp < eom) { | | 224 | while (--ancount >= 0 && cp < eom) { |
218 | n = dn_expand(answer->buf, eom, cp, bp, (int)(ep - bp)); | | 225 | n = dn_expand(answer->buf, eom, cp, bp, (int)(ep - bp)); |
219 | if ((n < 0) || !res_dnok(bp)) | | 226 | if ((n < 0) || !maybe_dnok(res, bp)) |
220 | break; | | 227 | break; |
221 | cp += n; | | 228 | cp += n; |
222 | (void)strlcpy(n_name, bp, sizeof(n_name)); | | 229 | (void)strlcpy(n_name, bp, sizeof(n_name)); |
223 | GETSHORT(type, cp); | | 230 | GETSHORT(type, cp); |
224 | GETSHORT(class, cp); | | 231 | GETSHORT(class, cp); |
225 | cp += INT32SZ; /* TTL */ | | 232 | cp += INT32SZ; /* TTL */ |
226 | GETSHORT(n, cp); | | 233 | GETSHORT(n, cp); |
227 | if (class == C_IN && type == T_PTR) { | | 234 | if (class == C_IN && type == T_PTR) { |
228 | n = dn_expand(answer->buf, eom, cp, bp, (int)(ep - bp)); | | 235 | n = dn_expand(answer->buf, eom, cp, bp, (int)(ep - bp)); |
229 | if ((n < 0) || !res_hnok(bp)) { | | 236 | if ((n < 0) || !maybe_hnok(res, bp)) { |
230 | cp += n; | | 237 | cp += n; |
231 | return NULL; | | 238 | return NULL; |
232 | } | | 239 | } |
233 | cp += n; | | 240 | cp += n; |
234 | *ap++ = bp; | | 241 | *ap++ = bp; |
235 | bp += strlen(bp) + 1; | | 242 | bp += strlen(bp) + 1; |
236 | net_entry.n_addrtype = | | 243 | net_entry.n_addrtype = |
237 | (class == C_IN) ? AF_INET : AF_UNSPEC; | | 244 | (class == C_IN) ? AF_INET : AF_UNSPEC; |
238 | haveanswer++; | | 245 | haveanswer++; |
239 | } | | 246 | } |
240 | } | | 247 | } |
241 | if (haveanswer) { | | 248 | if (haveanswer) { |
242 | *ap = NULL; | | 249 | *ap = NULL; |
| @@ -348,28 +355,28 @@ _dns_getnetbyaddr(void *cbrv, void *cbda | | | @@ -348,28 +355,28 @@ _dns_getnetbyaddr(void *cbrv, void *cbda |
348 | return NS_NOTFOUND; | | 355 | return NS_NOTFOUND; |
349 | } | | 356 | } |
350 | anslen = res_nquery(res, qbuf, C_IN, T_PTR, buf->buf, | | 357 | anslen = res_nquery(res, qbuf, C_IN, T_PTR, buf->buf, |
351 | (int)sizeof(buf->buf)); | | 358 | (int)sizeof(buf->buf)); |
352 | if (anslen < 0) { | | 359 | if (anslen < 0) { |
353 | free(buf); | | 360 | free(buf); |
354 | #ifdef DEBUG | | 361 | #ifdef DEBUG |
355 | if (res->options & RES_DEBUG) | | 362 | if (res->options & RES_DEBUG) |
356 | printf("res_query failed\n"); | | 363 | printf("res_query failed\n"); |
357 | #endif | | 364 | #endif |
358 | __res_put_state(res); | | 365 | __res_put_state(res); |
359 | return NS_NOTFOUND; | | 366 | return NS_NOTFOUND; |
360 | } | | 367 | } |
| | | 368 | np = getnetanswer(res, buf, anslen, BYADDR); |
361 | __res_put_state(res); | | 369 | __res_put_state(res); |
362 | np = getnetanswer(buf, anslen, BYADDR); | | | |
363 | free(buf); | | 370 | free(buf); |
364 | if (np) { | | 371 | if (np) { |
365 | /* maybe net should be unsigned? */ | | 372 | /* maybe net should be unsigned? */ |
366 | uint32_t u_net = net; | | 373 | uint32_t u_net = net; |
367 | | | 374 | |
368 | /* Strip trailing zeros */ | | 375 | /* Strip trailing zeros */ |
369 | while ((u_net & 0xff) == 0 && u_net != 0) | | 376 | while ((u_net & 0xff) == 0 && u_net != 0) |
370 | u_net >>= 8; | | 377 | u_net >>= 8; |
371 | np->n_net = u_net; | | 378 | np->n_net = u_net; |
372 | } | | 379 | } |
373 | | | 380 | |
374 | if (np != NULL) { | | 381 | if (np != NULL) { |
375 | *retval = np; | | 382 | *retval = np; |
| @@ -460,28 +467,28 @@ _dns_getnetbyname(void *cbrv, void *cbda | | | @@ -460,28 +467,28 @@ _dns_getnetbyname(void *cbrv, void *cbda |
460 | return NS_NOTFOUND; | | 467 | return NS_NOTFOUND; |
461 | } | | 468 | } |
462 | anslen = res_nsearch(res, qbuf, C_IN, T_PTR, buf->buf, | | 469 | anslen = res_nsearch(res, qbuf, C_IN, T_PTR, buf->buf, |
463 | (int)sizeof(buf->buf)); | | 470 | (int)sizeof(buf->buf)); |
464 | if (anslen < 0) { | | 471 | if (anslen < 0) { |
465 | free(buf); | | 472 | free(buf); |
466 | #ifdef DEBUG | | 473 | #ifdef DEBUG |
467 | if (res->options & RES_DEBUG) | | 474 | if (res->options & RES_DEBUG) |
468 | printf("res_search failed\n"); | | 475 | printf("res_search failed\n"); |
469 | #endif | | 476 | #endif |
470 | __res_put_state(res); | | 477 | __res_put_state(res); |
471 | return NS_NOTFOUND; | | 478 | return NS_NOTFOUND; |
472 | } | | 479 | } |
| | | 480 | np = getnetanswer(res, buf, anslen, BYNAME); |
473 | __res_put_state(res); | | 481 | __res_put_state(res); |
474 | np = getnetanswer(buf, anslen, BYNAME); | | | |
475 | free(buf); | | 482 | free(buf); |
476 | | | 483 | |
477 | if (np != NULL) { | | 484 | if (np != NULL) { |
478 | *retval = np; | | 485 | *retval = np; |
479 | return NS_SUCCESS; | | 486 | return NS_SUCCESS; |
480 | } else { | | 487 | } else { |
481 | h_errno = HOST_NOT_FOUND; | | 488 | h_errno = HOST_NOT_FOUND; |
482 | return NS_NOTFOUND; | | 489 | return NS_NOTFOUND; |
483 | } | | 490 | } |
484 | } | | 491 | } |
485 | | | 492 | |
486 | struct netent * | | 493 | struct netent * |
487 | getnetbyname(const char *name) | | 494 | getnetbyname(const char *name) |