diff options
| author | downsj <> | 1997-03-13 19:07:41 +0000 |
|---|---|---|
| committer | downsj <> | 1997-03-13 19:07:41 +0000 |
| commit | 05882f672fb3bf8797e68cc2d68f8406e1cb7b07 (patch) | |
| tree | f9cdfe48f1a2f821eb8d11d33976f3f19cd834db /src/lib/libc | |
| parent | b0e0ca363d82adf8768f67857659b9590e0e6954 (diff) | |
| download | openbsd-05882f672fb3bf8797e68cc2d68f8406e1cb7b07.tar.gz openbsd-05882f672fb3bf8797e68cc2d68f8406e1cb7b07.tar.bz2 openbsd-05882f672fb3bf8797e68cc2d68f8406e1cb7b07.zip | |
Integrate BIND 4.9.5 resolver and associated routines.
Includes the DNS aware getnetby*() routines and IPv6 support.
Diffstat (limited to 'src/lib/libc')
| -rw-r--r-- | src/lib/libc/net/Makefile.inc | 15 | ||||
| -rw-r--r-- | src/lib/libc/net/base64.c | 319 | ||||
| -rw-r--r-- | src/lib/libc/net/gethostbyname.3 | 48 | ||||
| -rw-r--r-- | src/lib/libc/net/gethostnamadr.c | 775 | ||||
| -rw-r--r-- | src/lib/libc/net/getnetbyaddr.c | 6 | ||||
| -rw-r--r-- | src/lib/libc/net/getnetbyname.c | 4 | ||||
| -rw-r--r-- | src/lib/libc/net/getnetent.3 | 23 | ||||
| -rw-r--r-- | src/lib/libc/net/getnetnamadr.c | 291 | ||||
| -rw-r--r-- | src/lib/libc/net/herror.c | 26 | ||||
| -rw-r--r-- | src/lib/libc/net/inet_addr.c | 82 | ||||
| -rw-r--r-- | src/lib/libc/net/inet_net_ntop.c | 139 | ||||
| -rw-r--r-- | src/lib/libc/net/inet_net_pton.c | 207 | ||||
| -rw-r--r-- | src/lib/libc/net/inet_neta.c | 82 | ||||
| -rw-r--r-- | src/lib/libc/net/inet_ntop.c | 194 | ||||
| -rw-r--r-- | src/lib/libc/net/inet_pton.c | 220 | ||||
| -rw-r--r-- | src/lib/libc/net/nsap_addr.c | 55 | ||||
| -rw-r--r-- | src/lib/libc/net/res_comp.c | 174 | ||||
| -rw-r--r-- | src/lib/libc/net/res_data.c | 117 | ||||
| -rw-r--r-- | src/lib/libc/net/res_debug.c | 1055 | ||||
| -rw-r--r-- | src/lib/libc/net/res_init.c | 259 | ||||
| -rw-r--r-- | src/lib/libc/net/res_mkquery.c | 139 | ||||
| -rw-r--r-- | src/lib/libc/net/res_query.c | 116 | ||||
| -rw-r--r-- | src/lib/libc/net/res_send.c | 111 |
23 files changed, 3665 insertions, 792 deletions
diff --git a/src/lib/libc/net/Makefile.inc b/src/lib/libc/net/Makefile.inc index 04831f4f2d..03f7349e5e 100644 --- a/src/lib/libc/net/Makefile.inc +++ b/src/lib/libc/net/Makefile.inc | |||
| @@ -1,15 +1,16 @@ | |||
| 1 | # $OpenBSD: Makefile.inc,v 1.8 1996/09/01 21:25:34 millert Exp $ | 1 | # $OpenBSD: Makefile.inc,v 1.9 1997/03/13 19:07:21 downsj Exp $ |
| 2 | 2 | ||
| 3 | # net sources | 3 | # net sources |
| 4 | .PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/net ${.CURDIR}/net | 4 | .PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/net ${.CURDIR}/net |
| 5 | 5 | ||
| 6 | SRCS+= gethostnamadr.c getnetbyaddr.c getnetbyname.c getnetent.c \ | 6 | SRCS+= base64.c gethostnamadr.c getnetbyaddr.c getnetbyname.c getnetent.c \ |
| 7 | getproto.c getprotoent.c getprotoname.c getservbyname.c \ | 7 | getnetnamadr.c getproto.c getprotoent.c getprotoname.c getservbyname.c \ |
| 8 | getservbyport.c getservent.c herror.c inet_addr.c inet_lnaof.c \ | 8 | getservbyport.c getservent.c herror.c inet_addr.c inet_lnaof.c \ |
| 9 | inet_makeaddr.c inet_netof.c inet_network.c inet_ntoa.c \ | 9 | inet_makeaddr.c inet_neta.c inet_netof.c inet_network.c \ |
| 10 | ipx_addr.c ipx_ntoa.c \ | 10 | inet_net_ntop.c inet_net_pton.c inet_ntoa.c inet_ntop.c \ |
| 11 | inet_pton.c ipx_addr.c ipx_ntoa.c \ | ||
| 11 | iso_addr.c linkaddr.c ns_addr.c ns_ntoa.c nsap_addr.c rcmd.c recv.c \ | 12 | iso_addr.c linkaddr.c ns_addr.c ns_ntoa.c nsap_addr.c rcmd.c recv.c \ |
| 12 | res_comp.c res_debug.c res_init.c res_mkquery.c res_query.c \ | 13 | res_comp.c res_data.c res_debug.c res_init.c res_mkquery.c res_query.c \ |
| 13 | res_send.c send.c sethostent.c ethers.c rcmdsh.c | 14 | res_send.c send.c sethostent.c ethers.c rcmdsh.c |
| 14 | 15 | ||
| 15 | # machine-dependent net sources | 16 | # machine-dependent net sources |
| @@ -28,7 +29,7 @@ MLINKS+=ethers.3 ether_aton.3 ethers.3 ether_hostton.3 ethers.3 ether_line.3 \ | |||
| 28 | ethers.3 ether_ntoa.3 ethers.3 ether_ntohost.3 | 29 | ethers.3 ether_ntoa.3 ethers.3 ether_ntohost.3 |
| 29 | MLINKS+=gethostbyname.3 endhostent.3 gethostbyname.3 gethostbyaddr.3 \ | 30 | MLINKS+=gethostbyname.3 endhostent.3 gethostbyname.3 gethostbyaddr.3 \ |
| 30 | gethostbyname.3 sethostent.3 gethostbyname.3 gethostent.3 \ | 31 | gethostbyname.3 sethostent.3 gethostbyname.3 gethostent.3 \ |
| 31 | gethostbyname.3 herror.3 | 32 | gethostbyname.3 herror.3 gethostbyname.3 gethostbyname2.3 |
| 32 | MLINKS+=getnetent.3 endnetent.3 getnetent.3 getnetbyaddr.3 \ | 33 | MLINKS+=getnetent.3 endnetent.3 getnetent.3 getnetbyaddr.3 \ |
| 33 | getnetent.3 getnetbyname.3 getnetent.3 setnetent.3 | 34 | getnetent.3 getnetbyname.3 getnetent.3 setnetent.3 |
| 34 | MLINKS+=getprotoent.3 endprotoent.3 getprotoent.3 getprotobyname.3 \ | 35 | MLINKS+=getprotoent.3 endprotoent.3 getprotoent.3 getprotobyname.3 \ |
diff --git a/src/lib/libc/net/base64.c b/src/lib/libc/net/base64.c new file mode 100644 index 0000000000..59788bee1b --- /dev/null +++ b/src/lib/libc/net/base64.c | |||
| @@ -0,0 +1,319 @@ | |||
| 1 | /* $OpenBSD: base64.c,v 1.1 1997/03/13 19:07:22 downsj Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 1996 by Internet Software Consortium. | ||
| 5 | * | ||
| 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 | ||
| 8 | * copyright notice and this permission notice appear in all copies. | ||
| 9 | * | ||
| 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS | ||
| 11 | * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES | ||
| 12 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE | ||
| 13 | * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | ||
| 14 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | ||
| 15 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | ||
| 16 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | ||
| 17 | * SOFTWARE. | ||
| 18 | */ | ||
| 19 | |||
| 20 | /* | ||
| 21 | * Portions Copyright (c) 1995 by International Business Machines, Inc. | ||
| 22 | * | ||
| 23 | * International Business Machines, Inc. (hereinafter called IBM) grants | ||
| 24 | * permission under its copyrights to use, copy, modify, and distribute this | ||
| 25 | * Software with or without fee, provided that the above copyright notice and | ||
| 26 | * all paragraphs of this notice appear in all copies, and that the name of IBM | ||
| 27 | * not be used in connection with the marketing of any product incorporating | ||
| 28 | * the Software or modifications thereof, without specific, written prior | ||
| 29 | * permission. | ||
| 30 | * | ||
| 31 | * To the extent it has a right to do so, IBM grants an immunity from suit | ||
| 32 | * under its patents, if any, for the use, sale or manufacture of products to | ||
| 33 | * the extent that such products are used for performing Domain Name System | ||
| 34 | * dynamic updates in TCP/IP networks by means of the Software. No immunity is | ||
| 35 | * granted for any product per se or for any other function of any product. | ||
| 36 | * | ||
| 37 | * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, | ||
| 38 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | ||
| 39 | * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, | ||
| 40 | * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING | ||
| 41 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN | ||
| 42 | * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. | ||
| 43 | */ | ||
| 44 | |||
| 45 | #include <sys/types.h> | ||
| 46 | #include <sys/param.h> | ||
| 47 | #include <sys/socket.h> | ||
| 48 | #include <netinet/in.h> | ||
| 49 | #include <arpa/inet.h> | ||
| 50 | #include <arpa/nameser.h> | ||
| 51 | |||
| 52 | #include <ctype.h> | ||
| 53 | #include <resolv.h> | ||
| 54 | #include <stdio.h> | ||
| 55 | |||
| 56 | #include <stdlib.h> | ||
| 57 | #include <string.h> | ||
| 58 | |||
| 59 | #define Assert(Cond) if (!(Cond)) abort() | ||
| 60 | |||
| 61 | static const char Base64[] = | ||
| 62 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | ||
| 63 | static const char Pad64 = '='; | ||
| 64 | |||
| 65 | /* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) | ||
| 66 | The following encoding technique is taken from RFC 1521 by Borenstein | ||
| 67 | and Freed. It is reproduced here in a slightly edited form for | ||
| 68 | convenience. | ||
| 69 | |||
| 70 | A 65-character subset of US-ASCII is used, enabling 6 bits to be | ||
| 71 | represented per printable character. (The extra 65th character, "=", | ||
| 72 | is used to signify a special processing function.) | ||
| 73 | |||
| 74 | The encoding process represents 24-bit groups of input bits as output | ||
| 75 | strings of 4 encoded characters. Proceeding from left to right, a | ||
| 76 | 24-bit input group is formed by concatenating 3 8-bit input groups. | ||
| 77 | These 24 bits are then treated as 4 concatenated 6-bit groups, each | ||
| 78 | of which is translated into a single digit in the base64 alphabet. | ||
| 79 | |||
| 80 | Each 6-bit group is used as an index into an array of 64 printable | ||
| 81 | characters. The character referenced by the index is placed in the | ||
| 82 | output string. | ||
| 83 | |||
| 84 | Table 1: The Base64 Alphabet | ||
| 85 | |||
| 86 | Value Encoding Value Encoding Value Encoding Value Encoding | ||
| 87 | 0 A 17 R 34 i 51 z | ||
| 88 | 1 B 18 S 35 j 52 0 | ||
| 89 | 2 C 19 T 36 k 53 1 | ||
| 90 | 3 D 20 U 37 l 54 2 | ||
| 91 | 4 E 21 V 38 m 55 3 | ||
| 92 | 5 F 22 W 39 n 56 4 | ||
| 93 | 6 G 23 X 40 o 57 5 | ||
| 94 | 7 H 24 Y 41 p 58 6 | ||
| 95 | 8 I 25 Z 42 q 59 7 | ||
| 96 | 9 J 26 a 43 r 60 8 | ||
| 97 | 10 K 27 b 44 s 61 9 | ||
| 98 | 11 L 28 c 45 t 62 + | ||
| 99 | 12 M 29 d 46 u 63 / | ||
| 100 | 13 N 30 e 47 v | ||
| 101 | 14 O 31 f 48 w (pad) = | ||
| 102 | 15 P 32 g 49 x | ||
| 103 | 16 Q 33 h 50 y | ||
| 104 | |||
| 105 | Special processing is performed if fewer than 24 bits are available | ||
| 106 | at the end of the data being encoded. A full encoding quantum is | ||
| 107 | always completed at the end of a quantity. When fewer than 24 input | ||
| 108 | bits are available in an input group, zero bits are added (on the | ||
| 109 | right) to form an integral number of 6-bit groups. Padding at the | ||
| 110 | end of the data is performed using the '=' character. | ||
| 111 | |||
| 112 | Since all base64 input is an integral number of octets, only the | ||
| 113 | ------------------------------------------------- | ||
| 114 | following cases can arise: | ||
| 115 | |||
| 116 | (1) the final quantum of encoding input is an integral | ||
| 117 | multiple of 24 bits; here, the final unit of encoded | ||
| 118 | output will be an integral multiple of 4 characters | ||
| 119 | with no "=" padding, | ||
| 120 | (2) the final quantum of encoding input is exactly 8 bits; | ||
| 121 | here, the final unit of encoded output will be two | ||
| 122 | characters followed by two "=" padding characters, or | ||
| 123 | (3) the final quantum of encoding input is exactly 16 bits; | ||
| 124 | here, the final unit of encoded output will be three | ||
| 125 | characters followed by one "=" padding character. | ||
| 126 | */ | ||
| 127 | |||
| 128 | int | ||
| 129 | b64_ntop(src, srclength, target, targsize) | ||
| 130 | u_char const *src; | ||
| 131 | size_t srclength; | ||
| 132 | char *target; | ||
| 133 | size_t targsize; | ||
| 134 | { | ||
| 135 | size_t datalength = 0; | ||
| 136 | u_char input[3]; | ||
| 137 | u_char output[4]; | ||
| 138 | int i; | ||
| 139 | |||
| 140 | while (2 < srclength) { | ||
| 141 | input[0] = *src++; | ||
| 142 | input[1] = *src++; | ||
| 143 | input[2] = *src++; | ||
| 144 | srclength -= 3; | ||
| 145 | |||
| 146 | output[0] = input[0] >> 2; | ||
| 147 | output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); | ||
| 148 | output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); | ||
| 149 | output[3] = input[2] & 0x3f; | ||
| 150 | Assert(output[0] < 64); | ||
| 151 | Assert(output[1] < 64); | ||
| 152 | Assert(output[2] < 64); | ||
| 153 | Assert(output[3] < 64); | ||
| 154 | |||
| 155 | if (datalength + 4 > targsize) | ||
| 156 | return (-1); | ||
| 157 | target[datalength++] = Base64[output[0]]; | ||
| 158 | target[datalength++] = Base64[output[1]]; | ||
| 159 | target[datalength++] = Base64[output[2]]; | ||
| 160 | target[datalength++] = Base64[output[3]]; | ||
| 161 | } | ||
| 162 | |||
| 163 | /* Now we worry about padding. */ | ||
| 164 | if (0 != srclength) { | ||
| 165 | /* Get what's left. */ | ||
| 166 | input[0] = input[1] = input[2] = '\0'; | ||
| 167 | for (i = 0; i < srclength; i++) | ||
| 168 | input[i] = *src++; | ||
| 169 | |||
| 170 | output[0] = input[0] >> 2; | ||
| 171 | output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); | ||
| 172 | output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); | ||
| 173 | Assert(output[0] < 64); | ||
| 174 | Assert(output[1] < 64); | ||
| 175 | Assert(output[2] < 64); | ||
| 176 | |||
| 177 | if (datalength + 4 > targsize) | ||
| 178 | return (-1); | ||
| 179 | target[datalength++] = Base64[output[0]]; | ||
| 180 | target[datalength++] = Base64[output[1]]; | ||
| 181 | if (srclength == 1) | ||
| 182 | target[datalength++] = Pad64; | ||
| 183 | else | ||
| 184 | target[datalength++] = Base64[output[2]]; | ||
| 185 | target[datalength++] = Pad64; | ||
| 186 | } | ||
| 187 | if (datalength >= targsize) | ||
| 188 | return (-1); | ||
| 189 | target[datalength] = '\0'; /* Returned value doesn't count \0. */ | ||
| 190 | return (datalength); | ||
| 191 | } | ||
| 192 | |||
| 193 | /* skips all whitespace anywhere. | ||
| 194 | converts characters, four at a time, starting at (or after) | ||
| 195 | src from base - 64 numbers into three 8 bit bytes in the target area. | ||
| 196 | it returns the number of data bytes stored at the target, or -1 on error. | ||
| 197 | */ | ||
| 198 | |||
| 199 | int | ||
| 200 | b64_pton(src, target, targsize) | ||
| 201 | char const *src; | ||
| 202 | u_char *target; | ||
| 203 | size_t targsize; | ||
| 204 | { | ||
| 205 | int tarindex, state, ch; | ||
| 206 | char *pos; | ||
| 207 | |||
| 208 | state = 0; | ||
| 209 | tarindex = 0; | ||
| 210 | |||
| 211 | while ((ch = *src++) != '\0') { | ||
| 212 | if (isspace(ch)) /* Skip whitespace anywhere. */ | ||
| 213 | continue; | ||
| 214 | |||
| 215 | if (ch == Pad64) | ||
| 216 | break; | ||
| 217 | |||
| 218 | pos = strchr(Base64, ch); | ||
| 219 | if (pos == 0) /* A non-base64 character. */ | ||
| 220 | return (-1); | ||
| 221 | |||
| 222 | switch (state) { | ||
| 223 | case 0: | ||
| 224 | if (target) { | ||
| 225 | if (tarindex >= targsize) | ||
| 226 | return (-1); | ||
| 227 | target[tarindex] = (pos - Base64) << 2; | ||
| 228 | } | ||
| 229 | state = 1; | ||
| 230 | break; | ||
| 231 | case 1: | ||
| 232 | if (target) { | ||
| 233 | if (tarindex + 1 >= targsize) | ||
| 234 | return (-1); | ||
| 235 | target[tarindex] |= (pos - Base64) >> 4; | ||
| 236 | target[tarindex+1] = ((pos - Base64) & 0x0f) | ||
| 237 | << 4 ; | ||
| 238 | } | ||
| 239 | tarindex++; | ||
| 240 | state = 2; | ||
| 241 | break; | ||
| 242 | case 2: | ||
| 243 | if (target) { | ||
| 244 | if (tarindex + 1 >= targsize) | ||
| 245 | return (-1); | ||
| 246 | target[tarindex] |= (pos - Base64) >> 2; | ||
| 247 | target[tarindex+1] = ((pos - Base64) & 0x03) | ||
| 248 | << 6; | ||
| 249 | } | ||
| 250 | tarindex++; | ||
| 251 | state = 3; | ||
| 252 | break; | ||
| 253 | case 3: | ||
| 254 | if (target) { | ||
| 255 | if (tarindex >= targsize) | ||
| 256 | return (-1); | ||
| 257 | target[tarindex] |= (pos - Base64); | ||
| 258 | } | ||
| 259 | tarindex++; | ||
| 260 | state = 0; | ||
| 261 | break; | ||
| 262 | default: | ||
| 263 | abort(); | ||
| 264 | } | ||
| 265 | } | ||
| 266 | |||
| 267 | /* | ||
| 268 | * We are done decoding Base-64 chars. Let's see if we ended | ||
| 269 | * on a byte boundary, and/or with erroneous trailing characters. | ||
| 270 | */ | ||
| 271 | |||
| 272 | if (ch == Pad64) { /* We got a pad char. */ | ||
| 273 | ch = *src++; /* Skip it, get next. */ | ||
| 274 | switch (state) { | ||
| 275 | case 0: /* Invalid = in first position */ | ||
| 276 | case 1: /* Invalid = in second position */ | ||
| 277 | return (-1); | ||
| 278 | |||
| 279 | case 2: /* Valid, means one byte of info */ | ||
| 280 | /* Skip any number of spaces. */ | ||
| 281 | for (NULL; ch != '\0'; ch = *src++) | ||
| 282 | if (!isspace(ch)) | ||
| 283 | break; | ||
| 284 | /* Make sure there is another trailing = sign. */ | ||
| 285 | if (ch != Pad64) | ||
| 286 | return (-1); | ||
| 287 | ch = *src++; /* Skip the = */ | ||
| 288 | /* Fall through to "single trailing =" case. */ | ||
| 289 | /* FALLTHROUGH */ | ||
| 290 | |||
| 291 | case 3: /* Valid, means two bytes of info */ | ||
| 292 | /* | ||
| 293 | * We know this char is an =. Is there anything but | ||
| 294 | * whitespace after it? | ||
| 295 | */ | ||
| 296 | for (NULL; ch != '\0'; ch = *src++) | ||
| 297 | if (!isspace(ch)) | ||
| 298 | return (-1); | ||
| 299 | |||
| 300 | /* | ||
| 301 | * Now make sure for cases 2 and 3 that the "extra" | ||
| 302 | * bits that slopped past the last full byte were | ||
| 303 | * zeros. If we don't check them, they become a | ||
| 304 | * subliminal channel. | ||
| 305 | */ | ||
| 306 | if (target && target[tarindex] != 0) | ||
| 307 | return (-1); | ||
| 308 | } | ||
| 309 | } else { | ||
| 310 | /* | ||
| 311 | * We ended by seeing the end of the string. Make sure we | ||
| 312 | * have no partial bytes lying around. | ||
| 313 | */ | ||
| 314 | if (state != 0) | ||
| 315 | return (-1); | ||
| 316 | } | ||
| 317 | |||
| 318 | return (tarindex); | ||
| 319 | } | ||
diff --git a/src/lib/libc/net/gethostbyname.3 b/src/lib/libc/net/gethostbyname.3 index 8dfdb88cf0..1394fa3467 100644 --- a/src/lib/libc/net/gethostbyname.3 +++ b/src/lib/libc/net/gethostbyname.3 | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | .\" $OpenBSD: gethostbyname.3,v 1.3 1996/08/19 08:28:38 tholo Exp $ | 1 | .\" $OpenBSD: gethostbyname.3,v 1.4 1997/03/13 19:07:23 downsj Exp $ |
| 2 | .\" | 2 | .\" |
| 3 | .\" Copyright (c) 1983, 1987, 1991, 1993 | 3 | .\" Copyright (c) 1983, 1987, 1991, 1993 |
| 4 | .\" The Regents of the University of California. All rights reserved. | 4 | .\" The Regents of the University of California. All rights reserved. |
| @@ -31,11 +31,12 @@ | |||
| 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 32 | .\" SUCH DAMAGE. | 32 | .\" SUCH DAMAGE. |
| 33 | .\" | 33 | .\" |
| 34 | .Dd April 19, 1994 | 34 | .Dd March 13, 1997 |
| 35 | .Dt GETHOSTBYNAME 3 | 35 | .Dt GETHOSTBYNAME 3 |
| 36 | .Os BSD 4.2 | 36 | .Os |
| 37 | .Sh NAME | 37 | .Sh NAME |
| 38 | .Nm gethostbyname , | 38 | .Nm gethostbyname , |
| 39 | .Nm gethostbyname2 , | ||
| 39 | .Nm gethostbyaddr , | 40 | .Nm gethostbyaddr , |
| 40 | .Nm gethostent , | 41 | .Nm gethostent , |
| 41 | .Nm sethostent , | 42 | .Nm sethostent , |
| @@ -48,6 +49,8 @@ | |||
| 48 | .Ft struct hostent * | 49 | .Ft struct hostent * |
| 49 | .Fn gethostbyname "const char *name" | 50 | .Fn gethostbyname "const char *name" |
| 50 | .Ft struct hostent * | 51 | .Ft struct hostent * |
| 52 | .Fn gethostbyname2 "const char *name" "int af" | ||
| 53 | .Ft struct hostent * | ||
| 51 | .Fn gethostbyaddr "const char *addr" "int len" "int type" | 54 | .Fn gethostbyaddr "const char *addr" "int len" "int type" |
| 52 | .Ft struct hostent * | 55 | .Ft struct hostent * |
| 53 | .Fn gethostent void | 56 | .Fn gethostent void |
| @@ -93,8 +96,7 @@ Official name of the host. | |||
| 93 | .It Fa h_aliases | 96 | .It Fa h_aliases |
| 94 | A zero terminated array of alternate names for the host. | 97 | A zero terminated array of alternate names for the host. |
| 95 | .It Fa h_addrtype | 98 | .It Fa h_addrtype |
| 96 | The type of address being returned; currently always | 99 | The type of address being returned. |
| 97 | .Dv AF_INET . | ||
| 98 | .It Fa h_length | 100 | .It Fa h_length |
| 99 | The length, in bytes, of the address. | 101 | The length, in bytes, of the address. |
| 100 | .It Fa h_addr_list | 102 | .It Fa h_addr_list |
| @@ -104,6 +106,7 @@ Host addresses are returned in network byte order. | |||
| 104 | The first address in | 106 | The first address in |
| 105 | .Fa h_addr_list ; | 107 | .Fa h_addr_list ; |
| 106 | this is for backward compatibility. | 108 | this is for backward compatibility. |
| 109 | .El | ||
| 107 | .Pp | 110 | .Pp |
| 108 | When using the nameserver, | 111 | When using the nameserver, |
| 109 | .Fn gethostbyname | 112 | .Fn gethostbyname |
| @@ -117,6 +120,14 @@ See | |||
| 117 | .Xr hostname 7 | 120 | .Xr hostname 7 |
| 118 | for the domain search procedure and the alias file format. | 121 | for the domain search procedure and the alias file format. |
| 119 | .Pp | 122 | .Pp |
| 123 | .Fn Gethostbyname2 | ||
| 124 | is an advanced form of | ||
| 125 | .Fn gethostbyname | ||
| 126 | which allows lookups in address families other than | ||
| 127 | .Dv AF_INET , | ||
| 128 | for example | ||
| 129 | .Dv AF_INET6 . | ||
| 130 | .Pp | ||
| 120 | The | 131 | The |
| 121 | .Fn sethostent | 132 | .Fn sethostent |
| 122 | function | 133 | function |
| @@ -148,7 +159,8 @@ connection. | |||
| 148 | .El | 159 | .El |
| 149 | .Sh DIAGNOSTICS | 160 | .Sh DIAGNOSTICS |
| 150 | Error return status from | 161 | Error return status from |
| 151 | .Fn gethostbyname | 162 | .Fn gethostbyname , |
| 163 | .Fn gethostbyname2 , | ||
| 152 | and | 164 | and |
| 153 | .Fn gethostbyaddr | 165 | .Fn gethostbyaddr |
| 154 | is indicated by return of a null pointer. | 166 | is indicated by return of a null pointer. |
| @@ -198,20 +210,6 @@ for example, a mail-forwarder may be registered for this domain. | |||
| 198 | The | 210 | The |
| 199 | .Fn gethostent | 211 | .Fn gethostent |
| 200 | function | 212 | function |
| 201 | is defined, and | ||
| 202 | .Fn sethostent | ||
| 203 | and | ||
| 204 | .Fn endhostent | ||
| 205 | are redefined, | ||
| 206 | when | ||
| 207 | .Xr libc 3 | ||
| 208 | is built to use only the routines to lookup in | ||
| 209 | .Pa /etc/hosts | ||
| 210 | and not the name server. | ||
| 211 | .Pp | ||
| 212 | The | ||
| 213 | .Fn gethostent | ||
| 214 | function | ||
| 215 | reads the next line of | 213 | reads the next line of |
| 216 | .Pa /etc/hosts , | 214 | .Pa /etc/hosts , |
| 217 | opening the file if necessary. | 215 | opening the file if necessary. |
| @@ -225,7 +223,8 @@ If the | |||
| 225 | .Fa stayopen | 223 | .Fa stayopen |
| 226 | argument is non-zero, | 224 | argument is non-zero, |
| 227 | the file will not be closed after each call to | 225 | the file will not be closed after each call to |
| 228 | .Fn gethostbyname | 226 | .Fn gethostbyname , |
| 227 | .Fn gethostbyname2 , | ||
| 229 | or | 228 | or |
| 230 | .Fn gethostbyaddr . | 229 | .Fn gethostbyaddr . |
| 231 | .Pp | 230 | .Pp |
| @@ -252,4 +251,9 @@ These functions use static data storage; | |||
| 252 | if the data is needed for future use, it should be | 251 | if the data is needed for future use, it should be |
| 253 | copied before any subsequent calls overwrite it. | 252 | copied before any subsequent calls overwrite it. |
| 254 | Only the Internet | 253 | Only the Internet |
| 255 | address format is currently understood. | 254 | address formats are currently understood. |
| 255 | .Pp | ||
| 256 | YP does not support any address families other than | ||
| 257 | .Dv AF_INET | ||
| 258 | and uses | ||
| 259 | the traditional database format. | ||
diff --git a/src/lib/libc/net/gethostnamadr.c b/src/lib/libc/net/gethostnamadr.c index 83e0225a65..9826b46805 100644 --- a/src/lib/libc/net/gethostnamadr.c +++ b/src/lib/libc/net/gethostnamadr.c | |||
| @@ -52,7 +52,7 @@ | |||
| 52 | */ | 52 | */ |
| 53 | 53 | ||
| 54 | #if defined(LIBC_SCCS) && !defined(lint) | 54 | #if defined(LIBC_SCCS) && !defined(lint) |
| 55 | static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.13 1997/01/30 05:56:06 deraadt Exp $"; | 55 | static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.14 1997/03/13 19:07:24 downsj Exp $"; |
| 56 | #endif /* LIBC_SCCS and not lint */ | 56 | #endif /* LIBC_SCCS and not lint */ |
| 57 | 57 | ||
| 58 | #include <sys/param.h> | 58 | #include <sys/param.h> |
| @@ -66,6 +66,7 @@ static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.13 1997/01/30 05:56:06 dera | |||
| 66 | #include <ctype.h> | 66 | #include <ctype.h> |
| 67 | #include <errno.h> | 67 | #include <errno.h> |
| 68 | #include <string.h> | 68 | #include <string.h> |
| 69 | #include <syslog.h> | ||
| 69 | #ifdef YP | 70 | #ifdef YP |
| 70 | #include <rpc/rpc.h> | 71 | #include <rpc/rpc.h> |
| 71 | #include <rpcsvc/yp.h> | 72 | #include <rpcsvc/yp.h> |
| @@ -73,6 +74,8 @@ static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.13 1997/01/30 05:56:06 dera | |||
| 73 | #include "ypinternal.h" | 74 | #include "ypinternal.h" |
| 74 | #endif | 75 | #endif |
| 75 | 76 | ||
| 77 | #define MULTI_PTRS_ARE_ALIASES 1 /* XXX - experimental */ | ||
| 78 | |||
| 76 | #define MAXALIASES 35 | 79 | #define MAXALIASES 35 |
| 77 | #define MAXADDRS 35 | 80 | #define MAXADDRS 35 |
| 78 | 81 | ||
| @@ -85,10 +88,22 @@ static char *__ypdomain; | |||
| 85 | static struct hostent host; | 88 | static struct hostent host; |
| 86 | static char *host_aliases[MAXALIASES]; | 89 | static char *host_aliases[MAXALIASES]; |
| 87 | static char hostbuf[BUFSIZ+1]; | 90 | static char hostbuf[BUFSIZ+1]; |
| 88 | static struct in_addr host_addr; | 91 | static u_char host_addr[16]; /* IPv4 or IPv6 */ |
| 89 | static FILE *hostf = NULL; | 92 | static FILE *hostf = NULL; |
| 90 | static int stayopen = 0; | 93 | static int stayopen = 0; |
| 91 | 94 | ||
| 95 | static void map_v4v6_address __P((const char *src, char *dst)); | ||
| 96 | static void map_v4v6_hostent __P((struct hostent *hp, char **bp, int *len)); | ||
| 97 | |||
| 98 | #ifdef RESOLVSORT | ||
| 99 | static void addrsort __P((char **, int)); | ||
| 100 | #endif | ||
| 101 | |||
| 102 | static int hokchar __P((const char *)); | ||
| 103 | |||
| 104 | static const char AskedForGot[] = | ||
| 105 | "gethostby*.getanswer: asked for \"%s\", got \"%s\""; | ||
| 106 | |||
| 92 | #if PACKETSZ > 1024 | 107 | #if PACKETSZ > 1024 |
| 93 | #define MAXPACKET PACKETSZ | 108 | #define MAXPACKET PACKETSZ |
| 94 | #else | 109 | #else |
| @@ -105,15 +120,14 @@ typedef union { | |||
| 105 | char ac; | 120 | char ac; |
| 106 | } align; | 121 | } align; |
| 107 | 122 | ||
| 108 | static int qcomp __P((struct in_addr **, struct in_addr **)); | 123 | static struct hostent *getanswer __P((const querybuf *, int, const char *, |
| 109 | static struct hostent *getanswer __P((querybuf *, int, int)); | 124 | int)); |
| 110 | static int hbadchar __P((char *)); | ||
| 111 | 125 | ||
| 112 | extern int h_errno; | 126 | extern int h_errno; |
| 113 | 127 | ||
| 114 | static int | 128 | static int |
| 115 | hbadchar(p) | 129 | hokchar(p) |
| 116 | char *p; | 130 | const char *p; |
| 117 | { | 131 | { |
| 118 | char c; | 132 | char c; |
| 119 | 133 | ||
| @@ -121,7 +135,7 @@ hbadchar(p) | |||
| 121 | * Many people do not obey RFC 822 and 1035. The valid | 135 | * Many people do not obey RFC 822 and 1035. The valid |
| 122 | * characters are a-z, A-Z, 0-9, '-' and . But the others | 136 | * characters are a-z, A-Z, 0-9, '-' and . But the others |
| 123 | * tested for below can happen, and we must be more permissive | 137 | * tested for below can happen, and we must be more permissive |
| 124 | * until those idiots clean up their act. | 138 | * than the resolver until those idiots clean up their act. |
| 125 | */ | 139 | */ |
| 126 | while ((c = *p++)) { | 140 | while ((c = *p++)) { |
| 127 | if (('a' >= c && c <= 'z') || | 141 | if (('a' >= c && c <= 'z') || |
| @@ -130,28 +144,50 @@ hbadchar(p) | |||
| 130 | continue; | 144 | continue; |
| 131 | if (strchr("-_/.[]\\", c) || | 145 | if (strchr("-_/.[]\\", c) || |
| 132 | (c == '.' && p[1] == '.')) | 146 | (c == '.' && p[1] == '.')) |
| 133 | return 1; | 147 | return 0; |
| 134 | } | 148 | } |
| 135 | return 0; | 149 | return 1; |
| 136 | } | 150 | } |
| 137 | 151 | ||
| 138 | static struct hostent * | 152 | static struct hostent * |
| 139 | getanswer(answer, anslen, iquery) | 153 | getanswer(answer, anslen, qname, qtype) |
| 140 | querybuf *answer; | 154 | const querybuf *answer; |
| 141 | int anslen; | 155 | int anslen; |
| 142 | int iquery; | 156 | const char *qname; |
| 157 | int qtype; | ||
| 143 | { | 158 | { |
| 144 | register HEADER *hp; | 159 | register const HEADER *hp; |
| 145 | register u_char *cp; | 160 | register const u_char *cp; |
| 146 | register int n; | 161 | register int n; |
| 147 | u_char *eom; | 162 | const u_char *eom; |
| 148 | char *bp, **ap; | 163 | char *bp, **ap, **hap; |
| 149 | int type, class, buflen, ancount, qdcount; | 164 | int type, class, buflen, ancount, qdcount; |
| 150 | int haveanswer, getclass = C_ANY; | 165 | int haveanswer, had_error; |
| 151 | char **hap; | 166 | int toobig = 0; |
| 152 | int good = 1; | 167 | char tbuf[MAXDNAME]; |
| 168 | const char *tname; | ||
| 169 | int (*name_ok) __P((const char *)); | ||
| 153 | 170 | ||
| 171 | tname = qname; | ||
| 172 | host.h_name = NULL; | ||
| 154 | eom = answer->buf + anslen; | 173 | eom = answer->buf + anslen; |
| 174 | switch (qtype) { | ||
| 175 | case T_A: | ||
| 176 | case T_AAAA: | ||
| 177 | #ifdef USE_RESOLV_NAME_OK | ||
| 178 | name_ok = res_hnok; | ||
| 179 | break; | ||
| 180 | #endif | ||
| 181 | case T_PTR: | ||
| 182 | #ifdef USE_RESOLV_NAME_OK | ||
| 183 | name_ok = res_dnok; | ||
| 184 | #else | ||
| 185 | name_ok = hokchar; | ||
| 186 | #endif | ||
| 187 | break; | ||
| 188 | default: | ||
| 189 | return (NULL); /* XXX should be abort(); */ | ||
| 190 | } | ||
| 155 | /* | 191 | /* |
| 156 | * find first satisfactory answer | 192 | * find first satisfactory answer |
| 157 | */ | 193 | */ |
| @@ -159,34 +195,29 @@ getanswer(answer, anslen, iquery) | |||
| 159 | ancount = ntohs(hp->ancount); | 195 | ancount = ntohs(hp->ancount); |
| 160 | qdcount = ntohs(hp->qdcount); | 196 | qdcount = ntohs(hp->qdcount); |
| 161 | bp = hostbuf; | 197 | bp = hostbuf; |
| 162 | buflen = sizeof(hostbuf); | 198 | buflen = sizeof hostbuf; |
| 163 | cp = answer->buf + sizeof(HEADER); | 199 | cp = answer->buf + HFIXEDSZ; |
| 164 | if (qdcount) { | 200 | if (qdcount != 1) { |
| 165 | if (iquery) { | 201 | h_errno = NO_RECOVERY; |
| 166 | if ((n = dn_expand((u_char *)answer->buf, | 202 | return (NULL); |
| 167 | (u_char *)eom, (u_char *)cp, bp, | 203 | } |
| 168 | buflen)) < 0) { | 204 | n = dn_expand(answer->buf, eom, cp, bp, buflen); |
| 169 | h_errno = NO_RECOVERY; | 205 | if ((n < 0) || !(*name_ok)(bp)) { |
| 170 | return ((struct hostent *) NULL); | 206 | h_errno = NO_RECOVERY; |
| 171 | } | 207 | return (NULL); |
| 172 | cp += n + QFIXEDSZ; | 208 | } |
| 173 | host.h_name = bp; | 209 | cp += n + QFIXEDSZ; |
| 174 | n = strlen(bp); | 210 | if (qtype == T_A || qtype == T_AAAA) { |
| 175 | if (n >= MAXHOSTNAMELEN) | 211 | /* res_send() has already verified that the query name is the |
| 176 | host.h_name[MAXHOSTNAMELEN-1] = '\0'; | 212 | * same as the one we sent; this just gets the expanded name |
| 177 | n++; | 213 | * (i.e., with the succeeding search-domain tacked on). |
| 178 | bp += n; | 214 | */ |
| 179 | buflen -= n; | 215 | n = strlen(bp) + 1; /* for the \0 */ |
| 180 | } else | 216 | host.h_name = bp; |
| 181 | cp += __dn_skipname(cp, eom) + QFIXEDSZ; | 217 | bp += n; |
| 182 | while (--qdcount > 0) | 218 | buflen -= n; |
| 183 | cp += __dn_skipname(cp, eom) + QFIXEDSZ; | 219 | /* The qname can be abbreviated, but h_name is now absolute. */ |
| 184 | } else if (iquery) { | 220 | qname = host.h_name; |
| 185 | if (hp->aa) | ||
| 186 | h_errno = HOST_NOT_FOUND; | ||
| 187 | else | ||
| 188 | h_errno = TRY_AGAIN; | ||
| 189 | return ((struct hostent *) NULL); | ||
| 190 | } | 221 | } |
| 191 | ap = host_aliases; | 222 | ap = host_aliases; |
| 192 | *ap = NULL; | 223 | *ap = NULL; |
| @@ -195,124 +226,258 @@ getanswer(answer, anslen, iquery) | |||
| 195 | *hap = NULL; | 226 | *hap = NULL; |
| 196 | host.h_addr_list = h_addr_ptrs; | 227 | host.h_addr_list = h_addr_ptrs; |
| 197 | haveanswer = 0; | 228 | haveanswer = 0; |
| 198 | if (ancount > MAXADDRS) | 229 | had_error = 0; |
| 199 | ancount = MAXADDRS; | 230 | while (ancount-- > 0 && cp < eom && !had_error) { |
| 200 | while (--ancount >= 0 && cp < eom) { | 231 | n = dn_expand(answer->buf, eom, cp, bp, buflen); |
| 201 | if ((n = dn_expand((u_char *)answer->buf, (u_char *)eom, | 232 | if ((n < 0) || !(*name_ok)(bp)) { |
| 202 | (u_char *)cp, bp, buflen)) < 0) | 233 | had_error++; |
| 203 | break; | 234 | continue; |
| 204 | cp += n; | 235 | } |
| 236 | cp += n; /* name */ | ||
| 205 | type = _getshort(cp); | 237 | type = _getshort(cp); |
| 206 | cp += sizeof(u_int16_t); | 238 | cp += INT16SZ; /* type */ |
| 207 | class = _getshort(cp); | 239 | class = _getshort(cp); |
| 208 | cp += sizeof(u_int16_t) + sizeof(u_int32_t); | 240 | cp += INT16SZ + INT32SZ; /* class, TTL */ |
| 209 | n = _getshort(cp); | 241 | n = _getshort(cp); |
| 210 | cp += sizeof(u_int16_t); | 242 | cp += INT16SZ; /* len */ |
| 211 | if (type == T_CNAME) { | 243 | if (class != C_IN) { |
| 244 | /* XXX - debug? syslog? */ | ||
| 212 | cp += n; | 245 | cp += n; |
| 246 | continue; /* XXX - had_error++ ? */ | ||
| 247 | } | ||
| 248 | if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) { | ||
| 213 | if (ap >= &host_aliases[MAXALIASES-1]) | 249 | if (ap >= &host_aliases[MAXALIASES-1]) |
| 214 | continue; | 250 | continue; |
| 251 | n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); | ||
| 252 | if ((n < 0) || !(*name_ok)(tbuf)) { | ||
| 253 | had_error++; | ||
| 254 | continue; | ||
| 255 | } | ||
| 256 | cp += n; | ||
| 257 | /* Store alias. */ | ||
| 215 | *ap++ = bp; | 258 | *ap++ = bp; |
| 216 | n = strlen(bp) + 1; | 259 | n = strlen(bp) + 1; /* for the \0 */ |
| 217 | if (n > MAXHOSTNAMELEN) | 260 | bp += n; |
| 218 | bp[MAXHOSTNAMELEN-1] = '\0'; | 261 | buflen -= n; |
| 262 | /* Get canonical name. */ | ||
| 263 | n = strlen(tbuf) + 1; /* for the \0 */ | ||
| 264 | if (n > buflen) { | ||
| 265 | had_error++; | ||
| 266 | continue; | ||
| 267 | } | ||
| 268 | strcpy(bp, tbuf); | ||
| 269 | host.h_name = bp; | ||
| 219 | bp += n; | 270 | bp += n; |
| 220 | buflen -= n; | 271 | buflen -= n; |
| 221 | continue; | 272 | continue; |
| 222 | } | 273 | } |
| 223 | if (iquery && type == T_PTR) { | 274 | if (qtype == T_PTR && type == T_CNAME) { |
| 224 | if ((n = dn_expand((u_char *)answer->buf, | 275 | n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); |
| 225 | (u_char *)eom, (u_char *)cp, bp, | 276 | if ((n < 0) || !res_hnok(tbuf)) { |
| 226 | buflen)) < 0) | 277 | had_error++; |
| 227 | break; | 278 | continue; |
| 279 | } | ||
| 228 | cp += n; | 280 | cp += n; |
| 229 | host.h_name = bp; | 281 | /* Get canonical name. */ |
| 230 | n = strlen(host.h_name); | 282 | n = strlen(tbuf) + 1; /* for the \0 */ |
| 231 | if (n >= MAXHOSTNAMELEN) | 283 | if (n > buflen) { |
| 232 | host.h_name[MAXHOSTNAMELEN-1] = '\0'; | 284 | had_error++; |
| 233 | goto gotent; | 285 | continue; |
| 286 | } | ||
| 287 | strcpy(bp, tbuf); | ||
| 288 | tname = bp; | ||
| 289 | bp += n; | ||
| 290 | buflen -= n; | ||
| 291 | continue; | ||
| 234 | } | 292 | } |
| 235 | if (iquery || type != T_A) { | 293 | if (type != qtype) { |
| 236 | #ifdef DEBUG | 294 | syslog(LOG_NOTICE|LOG_AUTH, |
| 237 | if (_res.options & RES_DEBUG) | 295 | "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"", |
| 238 | printf("unexpected answer type %d, size %d\n", | 296 | qname, p_class(C_IN), p_type(qtype), |
| 239 | type, n); | 297 | p_type(type)); |
| 240 | #endif | ||
| 241 | cp += n; | 298 | cp += n; |
| 242 | continue; | 299 | continue; /* XXX - had_error++ ? */ |
| 243 | } | 300 | } |
| 244 | 301 | switch (type) { | |
| 245 | if (haveanswer) { | 302 | case T_PTR: |
| 246 | if (n != host.h_length) { | 303 | if (strcasecmp(tname, bp) != 0) { |
| 304 | syslog(LOG_NOTICE|LOG_AUTH, | ||
| 305 | AskedForGot, qname, bp); | ||
| 247 | cp += n; | 306 | cp += n; |
| 248 | continue; | 307 | continue; /* XXX - had_error++ ? */ |
| 249 | } | 308 | } |
| 250 | if (class != getclass) { | 309 | n = dn_expand(answer->buf, eom, cp, bp, buflen); |
| 310 | if ((n < 0) || !res_hnok(bp)) { | ||
| 311 | had_error++; | ||
| 312 | break; | ||
| 313 | } | ||
| 314 | #if MULTI_PTRS_ARE_ALIASES | ||
| 315 | cp += n; | ||
| 316 | if (!haveanswer) | ||
| 317 | host.h_name = bp; | ||
| 318 | else if (ap < &host_aliases[MAXALIASES-1]) | ||
| 319 | *ap++ = bp; | ||
| 320 | else | ||
| 321 | n = -1; | ||
| 322 | if (n != -1) { | ||
| 323 | n = strlen(bp) + 1; /* for the \0 */ | ||
| 324 | bp += n; | ||
| 325 | buflen -= n; | ||
| 326 | } | ||
| 327 | break; | ||
| 328 | #else | ||
| 329 | host.h_name = bp; | ||
| 330 | if (_res.options & RES_USE_INET6) { | ||
| 331 | n = strlen(bp) + 1; /* for the \0 */ | ||
| 332 | bp += n; | ||
| 333 | buflen -= n; | ||
| 334 | map_v4v6_hostent(&host, &bp, &buflen); | ||
| 335 | } | ||
| 336 | h_errno = NETDB_SUCCESS; | ||
| 337 | return (&host); | ||
| 338 | #endif | ||
| 339 | case T_A: | ||
| 340 | case T_AAAA: | ||
| 341 | if (strcasecmp(host.h_name, bp) != 0) { | ||
| 342 | syslog(LOG_NOTICE|LOG_AUTH, | ||
| 343 | AskedForGot, host.h_name, bp); | ||
| 344 | cp += n; | ||
| 345 | continue; /* XXX - had_error++ ? */ | ||
| 346 | } | ||
| 347 | if (n != host.h_length) { | ||
| 251 | cp += n; | 348 | cp += n; |
| 252 | continue; | 349 | continue; |
| 253 | } | 350 | } |
| 254 | } else { | 351 | if (!haveanswer) { |
| 255 | host.h_length = n; | 352 | register int nn; |
| 256 | getclass = class; | 353 | |
| 257 | host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC; | ||
| 258 | if (host.h_addrtype == AF_INET) | ||
| 259 | host.h_length = INADDRSZ; | ||
| 260 | if (!iquery) { | ||
| 261 | host.h_name = bp; | 354 | host.h_name = bp; |
| 262 | bp += strlen(bp) + 1; | 355 | nn = strlen(bp) + 1; /* for the \0 */ |
| 263 | if (strlen(host.h_name) >= MAXHOSTNAMELEN) | 356 | bp += nn; |
| 264 | host.h_name[MAXHOSTNAMELEN-1] = '\0'; | 357 | buflen -= nn; |
| 265 | } | 358 | } |
| 266 | } | ||
| 267 | 359 | ||
| 268 | bp += sizeof(align) - ((u_long)bp % sizeof(align)); | 360 | bp += sizeof(align) - ((u_long)bp % sizeof(align)); |
| 269 | 361 | ||
| 270 | if (bp + n >= &hostbuf[sizeof(hostbuf)]) { | 362 | if (bp + n >= &hostbuf[sizeof hostbuf]) { |
| 363 | #ifdef DEBUG | ||
| 364 | if (_res.options & RES_DEBUG) | ||
| 365 | printf("size (%d) too big\n", n); | ||
| 366 | #endif | ||
| 367 | had_error++; | ||
| 368 | continue; | ||
| 369 | } | ||
| 370 | if (hap >= &h_addr_ptrs[MAXADDRS-1]) { | ||
| 371 | if (!toobig++) | ||
| 271 | #ifdef DEBUG | 372 | #ifdef DEBUG |
| 272 | if (_res.options & RES_DEBUG) | 373 | if (_res.options & RES_DEBUG) |
| 273 | printf("size (%d) too big\n", n); | 374 | printf("Too many addresses (%d)\n", MAXADDRS); |
| 274 | #endif | 375 | #endif |
| 376 | cp += n; | ||
| 377 | continue; | ||
| 378 | } | ||
| 379 | bcopy(cp, *hap++ = bp, n); | ||
| 380 | bp += n; | ||
| 381 | buflen -= n; | ||
| 382 | cp += n; | ||
| 275 | break; | 383 | break; |
| 384 | default: | ||
| 385 | abort(); | ||
| 276 | } | 386 | } |
| 277 | bcopy(cp, *hap++ = bp, n); | 387 | if (!had_error) |
| 278 | bp +=n; | 388 | haveanswer++; |
| 279 | cp += n; | ||
| 280 | haveanswer++; | ||
| 281 | } | ||
| 282 | if (!haveanswer) { | ||
| 283 | h_errno = TRY_AGAIN; | ||
| 284 | return ((struct hostent *) NULL); | ||
| 285 | } | ||
| 286 | *ap = NULL; | ||
| 287 | *hap = NULL; | ||
| 288 | if (_res.nsort) { | ||
| 289 | qsort(host.h_addr_list, haveanswer, | ||
| 290 | sizeof(struct in_addr), | ||
| 291 | (int (*)__P((const void *, const void *)))qcomp); | ||
| 292 | } | 389 | } |
| 293 | gotent: | 390 | if (haveanswer) { |
| 294 | if (hbadchar(host.h_name)) | 391 | *ap = NULL; |
| 295 | good = 0; | 392 | *hap = NULL; |
| 296 | for (ap = host_aliases; good && *ap; ap++) | 393 | # if defined(RESOLVSORT) |
| 297 | if (hbadchar(*ap)) | 394 | /* |
| 298 | good = 0; | 395 | * Note: we sort even if host can take only one address |
| 299 | if (good) | 396 | * in its return structures - should give it the "best" |
| 397 | * address in that case, not some random one | ||
| 398 | */ | ||
| 399 | if (_res.nsort && haveanswer > 1 && qtype == T_A) | ||
| 400 | addrsort(h_addr_ptrs, haveanswer); | ||
| 401 | # endif /*RESOLVSORT*/ | ||
| 402 | if (!host.h_name) { | ||
| 403 | n = strlen(qname) + 1; /* for the \0 */ | ||
| 404 | if (n > buflen) | ||
| 405 | goto try_again; | ||
| 406 | strcpy(bp, qname); | ||
| 407 | host.h_name = bp; | ||
| 408 | bp += n; | ||
| 409 | buflen -= n; | ||
| 410 | } | ||
| 411 | if (_res.options & RES_USE_INET6) | ||
| 412 | map_v4v6_hostent(&host, &bp, &buflen); | ||
| 413 | h_errno = NETDB_SUCCESS; | ||
| 300 | return (&host); | 414 | return (&host); |
| 301 | h_errno = NO_RECOVERY; | 415 | } |
| 302 | return ((struct hostent *) NULL); | 416 | try_again: |
| 417 | h_errno = TRY_AGAIN; | ||
| 418 | return (NULL); | ||
| 303 | } | 419 | } |
| 304 | 420 | ||
| 305 | struct hostent * | 421 | struct hostent * |
| 306 | gethostbyname(name) | 422 | gethostbyname(name) |
| 307 | const char *name; | 423 | const char *name; |
| 308 | { | 424 | { |
| 425 | struct hostent *hp; | ||
| 426 | extern struct hostent *_gethtbyname2(); | ||
| 427 | |||
| 428 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) | ||
| 429 | return (_gethtbyname2(name, AF_INET)); | ||
| 430 | |||
| 431 | if (_res.options & RES_USE_INET6) { | ||
| 432 | hp = gethostbyname2(name, AF_INET6); | ||
| 433 | if (hp) | ||
| 434 | return (hp); | ||
| 435 | } | ||
| 436 | return (gethostbyname2(name, AF_INET)); | ||
| 437 | } | ||
| 438 | |||
| 439 | struct hostent * | ||
| 440 | gethostbyname2(name, af) | ||
| 441 | const char *name; | ||
| 442 | int af; | ||
| 443 | { | ||
| 309 | querybuf buf; | 444 | querybuf buf; |
| 310 | register const char *cp; | 445 | register const char *cp; |
| 311 | int n, i; | 446 | char *bp; |
| 312 | extern struct hostent *_gethtbyname(), *_yp_gethtbyname(); | 447 | int n, size, type, len, i; |
| 448 | extern struct hostent *_gethtbyname2(), *_yp_gethtbyname(); | ||
| 313 | register struct hostent *hp; | 449 | register struct hostent *hp; |
| 314 | char lookups[MAXDNSLUS]; | 450 | char lookups[MAXDNSLUS]; |
| 315 | 451 | ||
| 452 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) | ||
| 453 | return (_gethtbyname2(name, af)); | ||
| 454 | |||
| 455 | switch (af) { | ||
| 456 | case AF_INET: | ||
| 457 | size = INADDRSZ; | ||
| 458 | type = T_A; | ||
| 459 | break; | ||
| 460 | case AF_INET6: | ||
| 461 | size = IN6ADDRSZ; | ||
| 462 | type = T_AAAA; | ||
| 463 | break; | ||
| 464 | default: | ||
| 465 | h_errno = NETDB_INTERNAL; | ||
| 466 | errno = EAFNOSUPPORT; | ||
| 467 | return (NULL); | ||
| 468 | } | ||
| 469 | |||
| 470 | host.h_addrtype = af; | ||
| 471 | host.h_length = size; | ||
| 472 | |||
| 473 | /* | ||
| 474 | * if there aren't any dots, it could be a user-level alias. | ||
| 475 | * this is also done in res_query() since we are not the only | ||
| 476 | * function that looks up host names. | ||
| 477 | */ | ||
| 478 | if (!strchr(name, '.') && (cp = __hostalias(name))) | ||
| 479 | name = cp; | ||
| 480 | |||
| 316 | /* | 481 | /* |
| 317 | * disallow names consisting only of digits/dots, unless | 482 | * disallow names consisting only of digits/dots, unless |
| 318 | * they end in a dot. | 483 | * they end in a dot. |
| @@ -327,26 +492,58 @@ gethostbyname(name) | |||
| 327 | * Fake up a hostent as if we'd actually | 492 | * Fake up a hostent as if we'd actually |
| 328 | * done a lookup. | 493 | * done a lookup. |
| 329 | */ | 494 | */ |
| 330 | if (!inet_aton(name, &host_addr)) { | 495 | if (inet_pton(af, name, host_addr) <= 0) { |
| 331 | h_errno = HOST_NOT_FOUND; | 496 | h_errno = HOST_NOT_FOUND; |
| 332 | return((struct hostent *) NULL); | 497 | return (NULL); |
| 333 | } | 498 | } |
| 334 | host.h_name = (char *)name; | 499 | strncpy(hostbuf, name, MAXDNAME); |
| 500 | hostbuf[MAXDNAME] = '\0'; | ||
| 501 | bp = hostbuf + MAXDNAME; | ||
| 502 | len = sizeof hostbuf - MAXDNAME; | ||
| 503 | host.h_name = hostbuf; | ||
| 335 | host.h_aliases = host_aliases; | 504 | host.h_aliases = host_aliases; |
| 336 | host_aliases[0] = NULL; | 505 | host_aliases[0] = NULL; |
| 337 | host.h_addrtype = AF_INET; | 506 | h_addr_ptrs[0] = (char *)host_addr; |
| 338 | host.h_length = sizeof(u_int32_t); | ||
| 339 | h_addr_ptrs[0] = (char *)&host_addr; | ||
| 340 | h_addr_ptrs[1] = NULL; | 507 | h_addr_ptrs[1] = NULL; |
| 341 | host.h_addr_list = h_addr_ptrs; | 508 | host.h_addr_list = h_addr_ptrs; |
| 509 | if (_res.options & RES_USE_INET6) | ||
| 510 | map_v4v6_hostent(&host, &bp, &len); | ||
| 511 | h_errno = NETDB_SUCCESS; | ||
| 342 | return (&host); | 512 | return (&host); |
| 343 | } | 513 | } |
| 344 | if (!isdigit(*cp) && *cp != '.') | 514 | if (!isdigit(*cp) && *cp != '.') |
| 345 | break; | 515 | break; |
| 346 | } | 516 | } |
| 347 | 517 | if (isxdigit(name[0]) || name[0] == ':') | |
| 348 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) | 518 | for (cp = name;; ++cp) { |
| 349 | return (_gethtbyname(name)); | 519 | if (!*cp) { |
| 520 | if (*--cp == '.') | ||
| 521 | break; | ||
| 522 | /* | ||
| 523 | * All-IPv6-legal, no dot at the end. | ||
| 524 | * Fake up a hostent as if we'd actually | ||
| 525 | * done a lookup. | ||
| 526 | */ | ||
| 527 | if (inet_pton(af, name, host_addr) <= 0) { | ||
| 528 | h_errno = HOST_NOT_FOUND; | ||
| 529 | return (NULL); | ||
| 530 | } | ||
| 531 | strncpy(hostbuf, name, MAXDNAME); | ||
| 532 | hostbuf[MAXDNAME] = '\0'; | ||
| 533 | bp = hostbuf + MAXDNAME; | ||
| 534 | len = sizeof hostbuf - MAXDNAME; | ||
| 535 | host.h_name = hostbuf; | ||
| 536 | host.h_aliases = host_aliases; | ||
| 537 | host_aliases[0] = NULL; | ||
| 538 | h_addr_ptrs[0] = (char *)host_addr; | ||
| 539 | h_addr_ptrs[1] = NULL; | ||
| 540 | host.h_addr_list = h_addr_ptrs; | ||
| 541 | h_errno = NETDB_SUCCESS; | ||
| 542 | return (&host); | ||
| 543 | } | ||
| 544 | if (!isxdigit(*cp) && *cp != ':' && *cp != '.') | ||
| 545 | break; | ||
| 546 | } | ||
| 350 | 547 | ||
| 351 | bcopy(_res.lookups, lookups, sizeof lookups); | 548 | bcopy(_res.lookups, lookups, sizeof lookups); |
| 352 | if (lookups[0] == '\0') | 549 | if (lookups[0] == '\0') |
| @@ -357,11 +554,13 @@ gethostbyname(name) | |||
| 357 | switch (lookups[i]) { | 554 | switch (lookups[i]) { |
| 358 | #ifdef YP | 555 | #ifdef YP |
| 359 | case 'y': | 556 | case 'y': |
| 360 | hp = _yp_gethtbyname(name); | 557 | /* YP only suports AF_INET. */ |
| 558 | if (af == AF_INET) | ||
| 559 | hp = _yp_gethtbyname(name); | ||
| 361 | break; | 560 | break; |
| 362 | #endif | 561 | #endif |
| 363 | case 'b': | 562 | case 'b': |
| 364 | if ((n = res_search(name, C_IN, T_A, buf.buf, | 563 | if ((n = res_search(name, C_IN, type, buf.buf, |
| 365 | sizeof(buf))) < 0) { | 564 | sizeof(buf))) < 0) { |
| 366 | #ifdef DEBUG | 565 | #ifdef DEBUG |
| 367 | if (_res.options & RES_DEBUG) | 566 | if (_res.options & RES_DEBUG) |
| @@ -369,10 +568,10 @@ gethostbyname(name) | |||
| 369 | #endif | 568 | #endif |
| 370 | break; | 569 | break; |
| 371 | } | 570 | } |
| 372 | hp = getanswer(&buf, n, 0); | 571 | hp = getanswer(&buf, n, name, type); |
| 373 | break; | 572 | break; |
| 374 | case 'f': | 573 | case 'f': |
| 375 | hp = _gethtbyname(name); | 574 | hp = _gethtbyname2(name, af); |
| 376 | break; | 575 | break; |
| 377 | } | 576 | } |
| 378 | } | 577 | } |
| @@ -380,27 +579,69 @@ gethostbyname(name) | |||
| 380 | } | 579 | } |
| 381 | 580 | ||
| 382 | struct hostent * | 581 | struct hostent * |
| 383 | gethostbyaddr(addr, len, type) | 582 | gethostbyaddr(addr, len, af) |
| 384 | const char *addr; | 583 | const char *addr; /* XXX should have been def'd as u_char! */ |
| 385 | int len, type; | 584 | int len, af; |
| 386 | { | 585 | { |
| 387 | int n, i; | 586 | const u_char *uaddr = (const u_char *)addr; |
| 587 | static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff }; | ||
| 588 | static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 }; | ||
| 589 | int n, size, i; | ||
| 388 | querybuf buf; | 590 | querybuf buf; |
| 389 | register struct hostent *hp; | 591 | register struct hostent *hp; |
| 390 | char qbuf[MAXDNAME]; | 592 | char qbuf[MAXDNAME+1], *qp; |
| 391 | extern struct hostent *_gethtbyaddr(), *_yp_gethtbyaddr(); | 593 | extern struct hostent *_gethtbyaddr(), *_yp_gethtbyaddr(); |
| 392 | char lookups[MAXDNSLUS]; | 594 | char lookups[MAXDNSLUS]; |
| 393 | 595 | ||
| 394 | if (type != AF_INET) | ||
| 395 | return ((struct hostent *) NULL); | ||
| 396 | (void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", | ||
| 397 | ((unsigned)addr[3] & 0xff), | ||
| 398 | ((unsigned)addr[2] & 0xff), | ||
| 399 | ((unsigned)addr[1] & 0xff), | ||
| 400 | ((unsigned)addr[0] & 0xff)); | ||
| 401 | |||
| 402 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) | 596 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) |
| 403 | return (_gethtbyaddr(addr, len, type)); | 597 | return (_gethtbyaddr(addr, len, af)); |
| 598 | |||
| 599 | if (af == AF_INET6 && len == IN6ADDRSZ && | ||
| 600 | (!bcmp(uaddr, mapped, sizeof mapped) || | ||
| 601 | !bcmp(uaddr, tunnelled, sizeof tunnelled))) { | ||
| 602 | /* Unmap. */ | ||
| 603 | addr += sizeof mapped; | ||
| 604 | uaddr += sizeof mapped; | ||
| 605 | af = AF_INET; | ||
| 606 | len = INADDRSZ; | ||
| 607 | } | ||
| 608 | switch (af) { | ||
| 609 | case AF_INET: | ||
| 610 | size = INADDRSZ; | ||
| 611 | break; | ||
| 612 | case AF_INET6: | ||
| 613 | size = IN6ADDRSZ; | ||
| 614 | break; | ||
| 615 | default: | ||
| 616 | errno = EAFNOSUPPORT; | ||
| 617 | h_errno = NETDB_INTERNAL; | ||
| 618 | return (NULL); | ||
| 619 | } | ||
| 620 | if (size != len) { | ||
| 621 | errno = EINVAL; | ||
| 622 | h_errno = NETDB_INTERNAL; | ||
| 623 | return (NULL); | ||
| 624 | } | ||
| 625 | switch (af) { | ||
| 626 | case AF_INET: | ||
| 627 | (void) sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", | ||
| 628 | (uaddr[3] & 0xff), | ||
| 629 | (uaddr[2] & 0xff), | ||
| 630 | (uaddr[1] & 0xff), | ||
| 631 | (uaddr[0] & 0xff)); | ||
| 632 | break; | ||
| 633 | case AF_INET6: | ||
| 634 | qp = qbuf; | ||
| 635 | for (n = IN6ADDRSZ - 1; n >= 0; n--) { | ||
| 636 | qp += sprintf(qp, "%x.%x.", | ||
| 637 | uaddr[n] & 0xf, | ||
| 638 | (uaddr[n] >> 4) & 0xf); | ||
| 639 | } | ||
| 640 | strcpy(qp, "ip6.int"); | ||
| 641 | break; | ||
| 642 | default: | ||
| 643 | abort(); | ||
| 644 | } | ||
| 404 | 645 | ||
| 405 | bcopy(_res.lookups, lookups, sizeof lookups); | 646 | bcopy(_res.lookups, lookups, sizeof lookups); |
| 406 | if (lookups[0] == '\0') | 647 | if (lookups[0] == '\0') |
| @@ -411,29 +652,38 @@ gethostbyaddr(addr, len, type) | |||
| 411 | switch (lookups[i]) { | 652 | switch (lookups[i]) { |
| 412 | #ifdef YP | 653 | #ifdef YP |
| 413 | case 'y': | 654 | case 'y': |
| 414 | hp = _yp_gethtbyaddr(addr); | 655 | /* YP only supports AF_INET. */ |
| 656 | if (af == AF_INET) | ||
| 657 | hp = _yp_gethtbyaddr(addr); | ||
| 415 | break; | 658 | break; |
| 416 | #endif | 659 | #endif |
| 417 | case 'b': | 660 | case 'b': |
| 418 | n = res_query(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf)); | 661 | n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, |
| 662 | sizeof buf.buf); | ||
| 419 | if (n < 0) { | 663 | if (n < 0) { |
| 420 | #ifdef DEBUG | 664 | #ifdef DEBUG |
| 421 | if (_res.options & RES_DEBUG) | 665 | if (_res.options & RES_DEBUG) |
| 422 | printf("res_query failed\n"); | 666 | printf("res_query failed\n"); |
| 423 | #endif | 667 | #endif |
| 424 | break; | 668 | return (NULL); |
| 425 | } | 669 | } |
| 426 | hp = getanswer(&buf, n, 1); | 670 | if (!(hp = getanswer(&buf, n, qbuf, T_PTR))) |
| 427 | if (hp == NULL) | 671 | return (NULL); /* h_errno was set by getanswer() */ |
| 428 | break; | 672 | hp->h_addrtype = af; |
| 429 | hp->h_addrtype = type; | ||
| 430 | hp->h_length = len; | 673 | hp->h_length = len; |
| 431 | h_addr_ptrs[0] = (char *)&host_addr; | 674 | bcopy(addr, host_addr, len); |
| 432 | h_addr_ptrs[1] = (char *)0; | 675 | h_addr_ptrs[0] = (char *)host_addr; |
| 433 | host_addr = *(struct in_addr *)addr; | 676 | h_addr_ptrs[1] = NULL; |
| 677 | if (af == AF_INET && (_res.options & RES_USE_INET6)) { | ||
| 678 | map_v4v6_address((char*)host_addr, | ||
| 679 | (char*)host_addr); | ||
| 680 | hp->h_addrtype = AF_INET6; | ||
| 681 | hp->h_length = IN6ADDRSZ; | ||
| 682 | } | ||
| 683 | h_errno = NETDB_SUCCESS; | ||
| 434 | break; | 684 | break; |
| 435 | case 'f': | 685 | case 'f': |
| 436 | hp = _gethtbyaddr(addr, len, type); | 686 | hp = _gethtbyaddr(addr, len, af); |
| 437 | break; | 687 | break; |
| 438 | } | 688 | } |
| 439 | } | 689 | } |
| @@ -465,35 +715,51 @@ _gethtent() | |||
| 465 | { | 715 | { |
| 466 | char *p; | 716 | char *p; |
| 467 | register char *cp, **q; | 717 | register char *cp, **q; |
| 718 | int af, len; | ||
| 468 | 719 | ||
| 469 | if (hostf == NULL && (hostf = fopen(_PATH_HOSTS, "r" )) == NULL) | 720 | if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) { |
| 721 | h_errno = NETDB_INTERNAL; | ||
| 470 | return (NULL); | 722 | return (NULL); |
| 471 | again: | 723 | } |
| 472 | if ((p = fgets(hostbuf, BUFSIZ, hostf)) == NULL) | 724 | again: |
| 725 | if (!(p = fgets(hostbuf, sizeof hostbuf, hostf))) { | ||
| 726 | h_errno = HOST_NOT_FOUND; | ||
| 473 | return (NULL); | 727 | return (NULL); |
| 728 | } | ||
| 474 | if (*p == '#') | 729 | if (*p == '#') |
| 475 | goto again; | 730 | goto again; |
| 476 | cp = strpbrk(p, "#\n"); | 731 | if (!(cp = strpbrk(p, "#\n"))) |
| 477 | if (cp == NULL) | ||
| 478 | goto again; | 732 | goto again; |
| 479 | *cp = '\0'; | 733 | *cp = '\0'; |
| 480 | cp = strpbrk(p, " \t"); | 734 | if (!(cp = strpbrk(p, " \t"))) |
| 481 | if (cp == NULL) | ||
| 482 | goto again; | 735 | goto again; |
| 483 | *cp++ = '\0'; | 736 | *cp++ = '\0'; |
| 484 | /* THIS STUFF IS INTERNET SPECIFIC */ | 737 | if ((_res.options & RES_USE_INET6) && |
| 485 | h_addr_ptrs[0] = (char *)&host_addr; | 738 | inet_pton(AF_INET6, p, host_addr) > 0) { |
| 739 | af = AF_INET6; | ||
| 740 | len = IN6ADDRSZ; | ||
| 741 | } else if (inet_pton(AF_INET, p, host_addr) > 0) { | ||
| 742 | if (_res.options & RES_USE_INET6) { | ||
| 743 | map_v4v6_address((char*)host_addr, (char*)host_addr); | ||
| 744 | af = AF_INET6; | ||
| 745 | len = IN6ADDRSZ; | ||
| 746 | } else { | ||
| 747 | af = AF_INET; | ||
| 748 | len = INADDRSZ; | ||
| 749 | } | ||
| 750 | } else { | ||
| 751 | goto again; | ||
| 752 | } | ||
| 753 | h_addr_ptrs[0] = (char *)host_addr; | ||
| 486 | h_addr_ptrs[1] = NULL; | 754 | h_addr_ptrs[1] = NULL; |
| 487 | (void) inet_aton(p, &host_addr); | ||
| 488 | host.h_addr_list = h_addr_ptrs; | 755 | host.h_addr_list = h_addr_ptrs; |
| 489 | host.h_length = sizeof(u_int32_t); | 756 | host.h_length = len; |
| 490 | host.h_addrtype = AF_INET; | 757 | host.h_addrtype = af; |
| 491 | while (*cp == ' ' || *cp == '\t') | 758 | while (*cp == ' ' || *cp == '\t') |
| 492 | cp++; | 759 | cp++; |
| 493 | host.h_name = cp; | 760 | host.h_name = cp; |
| 494 | q = host.h_aliases = host_aliases; | 761 | q = host.h_aliases = host_aliases; |
| 495 | cp = strpbrk(cp, " \t"); | 762 | if (cp = strpbrk(cp, " \t")) |
| 496 | if (cp != NULL) | ||
| 497 | *cp++ = '\0'; | 763 | *cp++ = '\0'; |
| 498 | while (cp && *cp) { | 764 | while (cp && *cp) { |
| 499 | if (*cp == ' ' || *cp == '\t') { | 765 | if (*cp == ' ' || *cp == '\t') { |
| @@ -502,11 +768,17 @@ again: | |||
| 502 | } | 768 | } |
| 503 | if (q < &host_aliases[MAXALIASES - 1]) | 769 | if (q < &host_aliases[MAXALIASES - 1]) |
| 504 | *q++ = cp; | 770 | *q++ = cp; |
| 505 | cp = strpbrk(cp, " \t"); | 771 | if (cp = strpbrk(cp, " \t")) |
| 506 | if (cp != NULL) | ||
| 507 | *cp++ = '\0'; | 772 | *cp++ = '\0'; |
| 508 | } | 773 | } |
| 509 | *q = NULL; | 774 | *q = NULL; |
| 775 | if (_res.options & RES_USE_INET6) { | ||
| 776 | char *bp = hostbuf; | ||
| 777 | int buflen = sizeof hostbuf; | ||
| 778 | |||
| 779 | map_v4v6_hostent(&host, &bp, &buflen); | ||
| 780 | } | ||
| 781 | h_errno = NETDB_SUCCESS; | ||
| 510 | return (&host); | 782 | return (&host); |
| 511 | } | 783 | } |
| 512 | 784 | ||
| @@ -514,58 +786,55 @@ struct hostent * | |||
| 514 | _gethtbyname(name) | 786 | _gethtbyname(name) |
| 515 | const char *name; | 787 | const char *name; |
| 516 | { | 788 | { |
| 789 | extern struct hostent *_gethtbyname2(); | ||
| 790 | struct hostent *hp; | ||
| 791 | |||
| 792 | if (_res.options & RES_USE_INET6) { | ||
| 793 | hp = _gethtbyname2(name, AF_INET6); | ||
| 794 | if (hp) | ||
| 795 | return (hp); | ||
| 796 | } | ||
| 797 | return (_gethtbyname2(name, AF_INET)); | ||
| 798 | } | ||
| 799 | |||
| 800 | struct hostent * | ||
| 801 | _gethtbyname2(name, af) | ||
| 802 | const char *name; | ||
| 803 | int af; | ||
| 804 | { | ||
| 517 | register struct hostent *p; | 805 | register struct hostent *p; |
| 518 | register char **cp; | 806 | register char **cp; |
| 519 | 807 | ||
| 520 | _sethtent(0); | 808 | _sethtent(0); |
| 521 | while (p = _gethtent()) { | 809 | while (p = _gethtent()) { |
| 810 | if (p->h_addrtype != af) | ||
| 811 | continue; | ||
| 522 | if (strcasecmp(p->h_name, name) == 0) | 812 | if (strcasecmp(p->h_name, name) == 0) |
| 523 | break; | 813 | break; |
| 524 | for (cp = p->h_aliases; *cp != 0; cp++) | 814 | for (cp = p->h_aliases; *cp != 0; cp++) |
| 525 | if (strcasecmp(*cp, name) == 0) | 815 | if (strcasecmp(*cp, name) == 0) |
| 526 | goto found; | 816 | goto found; |
| 527 | } | 817 | } |
| 528 | found: | 818 | found: |
| 529 | _endhtent(); | 819 | _endhtent(); |
| 530 | if (p==NULL) | ||
| 531 | h_errno = HOST_NOT_FOUND; | ||
| 532 | return (p); | 820 | return (p); |
| 533 | } | 821 | } |
| 534 | 822 | ||
| 535 | struct hostent * | 823 | struct hostent * |
| 536 | _gethtbyaddr(addr, len, type) | 824 | _gethtbyaddr(addr, len, af) |
| 537 | const char *addr; | 825 | const char *addr; |
| 538 | int len, type; | 826 | int len, af; |
| 539 | { | 827 | { |
| 540 | register struct hostent *p; | 828 | register struct hostent *p; |
| 541 | 829 | ||
| 542 | _sethtent(0); | 830 | _sethtent(0); |
| 543 | while (p = _gethtent()) | 831 | while (p = _gethtent()) |
| 544 | if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len)) | 832 | if (p->h_addrtype == af && !bcmp(p->h_addr, addr, len)) |
| 545 | break; | 833 | break; |
| 546 | _endhtent(); | 834 | _endhtent(); |
| 547 | if (p==NULL) | ||
| 548 | h_errno = HOST_NOT_FOUND; | ||
| 549 | return (p); | 835 | return (p); |
| 550 | } | 836 | } |
| 551 | 837 | ||
| 552 | static int | ||
| 553 | qcomp(a1, a2) | ||
| 554 | struct in_addr **a1, **a2; | ||
| 555 | { | ||
| 556 | int pos1, pos2; | ||
| 557 | |||
| 558 | for (pos1 = 0; pos1 < _res.nsort; pos1++) | ||
| 559 | if (_res.sort_list[pos1].addr.s_addr == | ||
| 560 | ((*a1)->s_addr & _res.sort_list[pos1].mask)) | ||
| 561 | break; | ||
| 562 | for (pos2 = 0; pos2 < _res.nsort; pos2++) | ||
| 563 | if (_res.sort_list[pos2].addr.s_addr == | ||
| 564 | ((*a2)->s_addr & _res.sort_list[pos2].mask)) | ||
| 565 | break; | ||
| 566 | return pos1 - pos2; | ||
| 567 | } | ||
| 568 | |||
| 569 | #ifdef YP | 838 | #ifdef YP |
| 570 | struct hostent * | 839 | struct hostent * |
| 571 | _yphostent(line) | 840 | _yphostent(line) |
| @@ -687,10 +956,104 @@ _yp_gethtbyname(name) | |||
| 687 | __ypcurrent = NULL; | 956 | __ypcurrent = NULL; |
| 688 | r = yp_match(__ypdomain, "hosts.byname", name, | 957 | r = yp_match(__ypdomain, "hosts.byname", name, |
| 689 | strlen(name), &__ypcurrent, &__ypcurrentlen); | 958 | strlen(name), &__ypcurrent, &__ypcurrentlen); |
| 690 | if (r==0) | 959 | if (r == 0) |
| 691 | hp = _yphostent(__ypcurrent); | 960 | hp = _yphostent(__ypcurrent); |
| 692 | if (hp==NULL) | 961 | if (hp == NULL) |
| 693 | h_errno = HOST_NOT_FOUND; | 962 | h_errno = HOST_NOT_FOUND; |
| 694 | return (hp); | 963 | return (hp); |
| 695 | } | 964 | } |
| 696 | #endif | 965 | #endif |
| 966 | |||
| 967 | static void | ||
| 968 | map_v4v6_address(src, dst) | ||
| 969 | const char *src; | ||
| 970 | char *dst; | ||
| 971 | { | ||
| 972 | u_char *p = (u_char *)dst; | ||
| 973 | char tmp[INADDRSZ]; | ||
| 974 | int i; | ||
| 975 | |||
| 976 | /* Stash a temporary copy so our caller can update in place. */ | ||
| 977 | bcopy(src, tmp, INADDRSZ); | ||
| 978 | /* Mark this ipv6 addr as a mapped ipv4. */ | ||
| 979 | for (i = 0; i < 10; i++) | ||
| 980 | *p++ = 0x00; | ||
| 981 | *p++ = 0xff; | ||
| 982 | *p++ = 0xff; | ||
| 983 | /* Retrieve the saved copy and we're done. */ | ||
| 984 | bcopy(tmp, (void*)p, INADDRSZ); | ||
| 985 | } | ||
| 986 | |||
| 987 | static void | ||
| 988 | map_v4v6_hostent(hp, bpp, lenp) | ||
| 989 | struct hostent *hp; | ||
| 990 | char **bpp; | ||
| 991 | int *lenp; | ||
| 992 | { | ||
| 993 | char **ap; | ||
| 994 | |||
| 995 | if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ) | ||
| 996 | return; | ||
| 997 | hp->h_addrtype = AF_INET6; | ||
| 998 | hp->h_length = IN6ADDRSZ; | ||
| 999 | for (ap = hp->h_addr_list; *ap; ap++) { | ||
| 1000 | int i = sizeof(align) - ((u_long)*bpp % sizeof(align)); | ||
| 1001 | |||
| 1002 | if (*lenp < (i + IN6ADDRSZ)) { | ||
| 1003 | /* Out of memory. Truncate address list here. XXX */ | ||
| 1004 | *ap = NULL; | ||
| 1005 | return; | ||
| 1006 | } | ||
| 1007 | *bpp += i; | ||
| 1008 | *lenp -= i; | ||
| 1009 | map_v4v6_address(*ap, *bpp); | ||
| 1010 | *ap = *bpp; | ||
| 1011 | *bpp += IN6ADDRSZ; | ||
| 1012 | *lenp -= IN6ADDRSZ; | ||
| 1013 | } | ||
| 1014 | } | ||
| 1015 | |||
| 1016 | #ifdef RESOLVSORT | ||
| 1017 | static void | ||
| 1018 | addrsort(ap, num) | ||
| 1019 | char **ap; | ||
| 1020 | int num; | ||
| 1021 | { | ||
| 1022 | int i, j; | ||
| 1023 | char **p; | ||
| 1024 | short aval[MAXADDRS]; | ||
| 1025 | int needsort = 0; | ||
| 1026 | |||
| 1027 | p = ap; | ||
| 1028 | for (i = 0; i < num; i++, p++) { | ||
| 1029 | for (j = 0 ; (unsigned)j < _res.nsort; j++) | ||
| 1030 | if (_res.sort_list[j].addr.s_addr == | ||
| 1031 | (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask)) | ||
| 1032 | break; | ||
| 1033 | aval[i] = j; | ||
| 1034 | if (needsort == 0 && i > 0 && j < aval[i-1]) | ||
| 1035 | needsort = i; | ||
| 1036 | } | ||
| 1037 | if (!needsort) | ||
| 1038 | return; | ||
| 1039 | |||
| 1040 | while (needsort < num) { | ||
| 1041 | for (j = needsort - 1; j >= 0; j--) { | ||
| 1042 | if (aval[j] > aval[j+1]) { | ||
| 1043 | char *hp; | ||
| 1044 | |||
| 1045 | i = aval[j]; | ||
| 1046 | aval[j] = aval[j+1]; | ||
| 1047 | aval[j+1] = i; | ||
| 1048 | |||
| 1049 | hp = ap[j]; | ||
| 1050 | ap[j] = ap[j+1]; | ||
| 1051 | ap[j+1] = hp; | ||
| 1052 | |||
| 1053 | } else | ||
| 1054 | break; | ||
| 1055 | } | ||
| 1056 | needsort++; | ||
| 1057 | } | ||
| 1058 | } | ||
| 1059 | #endif | ||
diff --git a/src/lib/libc/net/getnetbyaddr.c b/src/lib/libc/net/getnetbyaddr.c index aabd741a88..3d2b6e0352 100644 --- a/src/lib/libc/net/getnetbyaddr.c +++ b/src/lib/libc/net/getnetbyaddr.c | |||
| @@ -32,7 +32,7 @@ | |||
| 32 | */ | 32 | */ |
| 33 | 33 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | 34 | #if defined(LIBC_SCCS) && !defined(lint) |
| 35 | static char rcsid[] = "$OpenBSD: getnetbyaddr.c,v 1.2 1996/08/19 08:28:42 tholo Exp $"; | 35 | static char rcsid[] = "$OpenBSD: getnetbyaddr.c,v 1.3 1997/03/13 19:07:25 downsj Exp $"; |
| 36 | #endif /* LIBC_SCCS and not lint */ | 36 | #endif /* LIBC_SCCS and not lint */ |
| 37 | 37 | ||
| 38 | #include <netdb.h> | 38 | #include <netdb.h> |
| @@ -40,8 +40,8 @@ static char rcsid[] = "$OpenBSD: getnetbyaddr.c,v 1.2 1996/08/19 08:28:42 tholo | |||
| 40 | extern int _net_stayopen; | 40 | extern int _net_stayopen; |
| 41 | 41 | ||
| 42 | struct netent * | 42 | struct netent * |
| 43 | getnetbyaddr(net, type) | 43 | _getnetbyaddr(net, type) |
| 44 | register long net; | 44 | register unsigned long net; |
| 45 | register int type; | 45 | register int type; |
| 46 | { | 46 | { |
| 47 | register struct netent *p; | 47 | register struct netent *p; |
diff --git a/src/lib/libc/net/getnetbyname.c b/src/lib/libc/net/getnetbyname.c index d2a5b8679a..764c78b361 100644 --- a/src/lib/libc/net/getnetbyname.c +++ b/src/lib/libc/net/getnetbyname.c | |||
| @@ -32,7 +32,7 @@ | |||
| 32 | */ | 32 | */ |
| 33 | 33 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | 34 | #if defined(LIBC_SCCS) && !defined(lint) |
| 35 | static char rcsid[] = "$OpenBSD: getnetbyname.c,v 1.3 1996/08/19 08:28:44 tholo Exp $"; | 35 | static char rcsid[] = "$OpenBSD: getnetbyname.c,v 1.4 1997/03/13 19:07:26 downsj Exp $"; |
| 36 | #endif /* LIBC_SCCS and not lint */ | 36 | #endif /* LIBC_SCCS and not lint */ |
| 37 | 37 | ||
| 38 | #include <netdb.h> | 38 | #include <netdb.h> |
| @@ -41,7 +41,7 @@ static char rcsid[] = "$OpenBSD: getnetbyname.c,v 1.3 1996/08/19 08:28:44 tholo | |||
| 41 | extern int _net_stayopen; | 41 | extern int _net_stayopen; |
| 42 | 42 | ||
| 43 | struct netent * | 43 | struct netent * |
| 44 | getnetbyname(name) | 44 | _getnetbyname(name) |
| 45 | register const char *name; | 45 | register const char *name; |
| 46 | { | 46 | { |
| 47 | register struct netent *p; | 47 | register struct netent *p; |
diff --git a/src/lib/libc/net/getnetent.3 b/src/lib/libc/net/getnetent.3 index 9cd54a817c..a3aebf4310 100644 --- a/src/lib/libc/net/getnetent.3 +++ b/src/lib/libc/net/getnetent.3 | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | .\" $OpenBSD: getnetent.3,v 1.2 1996/08/19 08:28:45 tholo Exp $ | 1 | .\" $OpenBSD: getnetent.3,v 1.3 1997/03/13 19:07:26 downsj Exp $ |
| 2 | .\" | 2 | .\" |
| 3 | .\" Copyright (c) 1983, 1991, 1993 | 3 | .\" Copyright (c) 1983, 1991, 1993 |
| 4 | .\" The Regents of the University of California. All rights reserved. | 4 | .\" The Regents of the University of California. All rights reserved. |
| @@ -31,9 +31,9 @@ | |||
| 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 32 | .\" SUCH DAMAGE. | 32 | .\" SUCH DAMAGE. |
| 33 | .\" | 33 | .\" |
| 34 | .Dd June 4, 1993 | 34 | .Dd March 13, 1997 |
| 35 | .Dt GETNETENT 3 | 35 | .Dt GETNETENT 3 |
| 36 | .Os BSD 4.2 | 36 | .Os |
| 37 | .Sh NAME | 37 | .Sh NAME |
| 38 | .Nm getnetent , | 38 | .Nm getnetent , |
| 39 | .Nm getnetbyaddr , | 39 | .Nm getnetbyaddr , |
| @@ -48,7 +48,7 @@ | |||
| 48 | .Ft struct netent * | 48 | .Ft struct netent * |
| 49 | .Fn getnetbyname "char *name" | 49 | .Fn getnetbyname "char *name" |
| 50 | .Ft struct netent * | 50 | .Ft struct netent * |
| 51 | .Fn getnetbyaddr "long net" "int type" | 51 | .Fn getnetbyaddr "unsigned long net" "int type" |
| 52 | .Fn setnetent "int stayopen" | 52 | .Fn setnetent "int stayopen" |
| 53 | .Fn endnetent | 53 | .Fn endnetent |
| 54 | .Sh DESCRIPTION | 54 | .Sh DESCRIPTION |
| @@ -111,11 +111,10 @@ The | |||
| 111 | function | 111 | function |
| 112 | and | 112 | and |
| 113 | .Fn getnetbyaddr | 113 | .Fn getnetbyaddr |
| 114 | sequentially search from the beginning | 114 | search the domain name server if the system is configured to use one. |
| 115 | of the file until a matching | 115 | If the search fails, or no name server is configured, they sequentially |
| 116 | net name or | 116 | search from the beginning of the file until a matching net name or |
| 117 | net address and type is found, | 117 | net address and type is found, or until |
| 118 | or until | ||
| 119 | .Dv EOF | 118 | .Dv EOF |
| 120 | is encountered. | 119 | is encountered. |
| 121 | Network numbers are supplied in host order. | 120 | Network numbers are supplied in host order. |
| @@ -129,7 +128,8 @@ Null pointer | |||
| 129 | .Dv EOF | 128 | .Dv EOF |
| 130 | or error. | 129 | or error. |
| 131 | .Sh SEE ALSO | 130 | .Sh SEE ALSO |
| 132 | .Xr networks 5 | 131 | .Xr networks 5 , |
| 132 | .Xr resolver 3 | ||
| 133 | .Sh HISTORY | 133 | .Sh HISTORY |
| 134 | The | 134 | The |
| 135 | .Fn getnetent , | 135 | .Fn getnetent , |
| @@ -147,5 +147,4 @@ copied before any subsequent calls to these functions overwrite it. | |||
| 147 | Only Internet network | 147 | Only Internet network |
| 148 | numbers are currently understood. | 148 | numbers are currently understood. |
| 149 | Expecting network numbers to fit | 149 | Expecting network numbers to fit |
| 150 | in no more than 32 bits is probably | 150 | in no more than 32 bits is naive. |
| 151 | naive. | ||
diff --git a/src/lib/libc/net/getnetnamadr.c b/src/lib/libc/net/getnetnamadr.c new file mode 100644 index 0000000000..cc6ccc4275 --- /dev/null +++ b/src/lib/libc/net/getnetnamadr.c | |||
| @@ -0,0 +1,291 @@ | |||
| 1 | /* $OpenBSD: getnetnamadr.c,v 1.1 1997/03/13 19:07:27 downsj Exp $ */ | ||
| 2 | |||
| 3 | /* Copyright (c) 1993 Carlos Leandro and Rui Salgueiro | ||
| 4 | * Dep. Matematica Universidade de Coimbra, Portugal, Europe | ||
| 5 | * | ||
| 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 | ||
| 8 | * copyright notice and this permission notice appear in all copies. | ||
| 9 | */ | ||
| 10 | /* | ||
| 11 | * Copyright (c) 1983, 1993 | ||
| 12 | * The Regents of the University of California. All rights reserved. | ||
| 13 | * | ||
| 14 | * Redistribution and use in source and binary forms, with or without | ||
| 15 | * modification, are permitted provided that the following conditions | ||
| 16 | * are met: | ||
| 17 | * 1. Redistributions of source code must retain the above copyright | ||
| 18 | * notice, this list of conditions and the following disclaimer. | ||
| 19 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 20 | * notice, this list of conditions and the following disclaimer in the | ||
| 21 | * documentation and/or other materials provided with the distribution. | ||
| 22 | * 3. All advertising materials mentioning features or use of this software | ||
| 23 | * must display the following acknowledgement: | ||
| 24 | * This product includes software developed by the University of | ||
| 25 | * California, Berkeley and its contributors. | ||
| 26 | * 4. Neither the name of the University nor the names of its contributors | ||
| 27 | * may be used to endorse or promote products derived from this software | ||
| 28 | * without specific prior written permission. | ||
| 29 | * | ||
| 30 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
| 31 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 32 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 33 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
| 34 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 35 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 36 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 37 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 38 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 39 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 40 | * SUCH DAMAGE. | ||
| 41 | */ | ||
| 42 | |||
| 43 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 44 | #if 0 | ||
| 45 | static char sccsid[] = "@(#)getnetbyaddr.c 8.1 (Berkeley) 6/4/93"; | ||
| 46 | static char sccsid_[] = "from getnetnamadr.c 1.4 (Coimbra) 93/06/03"; | ||
| 47 | static char rcsid[] = "$From: getnetnamadr.c,v 8.7 1996/08/05 08:31:35 vixie Exp $"; | ||
| 48 | #else | ||
| 49 | static char rcsid[] = "$OpenBSD: getnetnamadr.c,v 1.1 1997/03/13 19:07:27 downsj Exp $"; | ||
| 50 | #endif | ||
| 51 | #endif /* LIBC_SCCS and not lint */ | ||
| 52 | |||
| 53 | #include <sys/types.h> | ||
| 54 | #include <sys/param.h> | ||
| 55 | #include <sys/socket.h> | ||
| 56 | #include <netinet/in.h> | ||
| 57 | #include <arpa/inet.h> | ||
| 58 | #include <arpa/nameser.h> | ||
| 59 | |||
| 60 | #include <stdio.h> | ||
| 61 | #include <netdb.h> | ||
| 62 | #include <resolv.h> | ||
| 63 | #include <ctype.h> | ||
| 64 | #include <errno.h> | ||
| 65 | #include <string.h> | ||
| 66 | |||
| 67 | extern int h_errno; | ||
| 68 | |||
| 69 | struct netent *_getnetbyaddr __P((long net, int type)); | ||
| 70 | struct netent *_getnetbyname __P((const char *name)); | ||
| 71 | |||
| 72 | #define BYADDR 0 | ||
| 73 | #define BYNAME 1 | ||
| 74 | #define MAXALIASES 35 | ||
| 75 | |||
| 76 | #if PACKETSZ > 1024 | ||
| 77 | #define MAXPACKET PACKETSZ | ||
| 78 | #else | ||
| 79 | #define MAXPACKET 1024 | ||
| 80 | #endif | ||
| 81 | |||
| 82 | typedef union { | ||
| 83 | HEADER hdr; | ||
| 84 | u_char buf[MAXPACKET]; | ||
| 85 | } querybuf; | ||
| 86 | |||
| 87 | typedef union { | ||
| 88 | long al; | ||
| 89 | char ac; | ||
| 90 | } align; | ||
| 91 | |||
| 92 | static struct netent * | ||
| 93 | getnetanswer(answer, anslen, net_i) | ||
| 94 | querybuf *answer; | ||
| 95 | int anslen; | ||
| 96 | int net_i; | ||
| 97 | { | ||
| 98 | |||
| 99 | register HEADER *hp; | ||
| 100 | register u_char *cp; | ||
| 101 | register int n; | ||
| 102 | u_char *eom; | ||
| 103 | int type, class, buflen, ancount, qdcount, haveanswer, i, nchar; | ||
| 104 | char aux1[30], aux2[30], ans[30], *in, *st, *pauxt, *bp, **ap, | ||
| 105 | *paux1 = &aux1[0], *paux2 = &aux2[0], flag = 0; | ||
| 106 | static struct netent net_entry; | ||
| 107 | static char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1]; | ||
| 108 | |||
| 109 | /* | ||
| 110 | * find first satisfactory answer | ||
| 111 | * | ||
| 112 | * answer --> +------------+ ( MESSAGE ) | ||
| 113 | * | Header | | ||
| 114 | * +------------+ | ||
| 115 | * | Question | the question for the name server | ||
| 116 | * +------------+ | ||
| 117 | * | Answer | RRs answering the question | ||
| 118 | * +------------+ | ||
| 119 | * | Authority | RRs pointing toward an authority | ||
| 120 | * | Additional | RRs holding additional information | ||
| 121 | * +------------+ | ||
| 122 | */ | ||
| 123 | eom = answer->buf + anslen; | ||
| 124 | hp = &answer->hdr; | ||
| 125 | ancount = ntohs(hp->ancount); /* #/records in the answer section */ | ||
| 126 | qdcount = ntohs(hp->qdcount); /* #/entries in the question section */ | ||
| 127 | bp = netbuf; | ||
| 128 | buflen = sizeof(netbuf); | ||
| 129 | cp = answer->buf + HFIXEDSZ; | ||
| 130 | if (!qdcount) { | ||
| 131 | if (hp->aa) | ||
| 132 | h_errno = HOST_NOT_FOUND; | ||
| 133 | else | ||
| 134 | h_errno = TRY_AGAIN; | ||
| 135 | return (NULL); | ||
| 136 | } | ||
| 137 | while (qdcount-- > 0) | ||
| 138 | cp += __dn_skipname(cp, eom) + QFIXEDSZ; | ||
| 139 | ap = net_aliases; | ||
| 140 | *ap = NULL; | ||
| 141 | net_entry.n_aliases = net_aliases; | ||
| 142 | haveanswer = 0; | ||
| 143 | while (--ancount >= 0 && cp < eom) { | ||
| 144 | n = dn_expand(answer->buf, eom, cp, bp, buflen); | ||
| 145 | if ((n < 0) || !res_dnok(bp)) | ||
| 146 | break; | ||
| 147 | cp += n; | ||
| 148 | ans[0] = '\0'; | ||
| 149 | (void)strcpy(&ans[0], bp); | ||
| 150 | GETSHORT(type, cp); | ||
| 151 | GETSHORT(class, cp); | ||
| 152 | cp += INT32SZ; /* TTL */ | ||
| 153 | GETSHORT(n, cp); | ||
| 154 | if (class == C_IN && type == T_PTR) { | ||
| 155 | n = dn_expand(answer->buf, eom, cp, bp, buflen); | ||
| 156 | if ((n < 0) || !res_hnok(bp)) { | ||
| 157 | cp += n; | ||
| 158 | return (NULL); | ||
| 159 | } | ||
| 160 | cp += n; | ||
| 161 | *ap++ = bp; | ||
| 162 | bp += strlen(bp) + 1; | ||
| 163 | net_entry.n_addrtype = | ||
| 164 | (class == C_IN) ? AF_INET : AF_UNSPEC; | ||
| 165 | haveanswer++; | ||
| 166 | } | ||
| 167 | } | ||
| 168 | if (haveanswer) { | ||
| 169 | *ap = NULL; | ||
| 170 | switch (net_i) { | ||
| 171 | case BYADDR: | ||
| 172 | net_entry.n_name = *net_entry.n_aliases; | ||
| 173 | net_entry.n_net = 0L; | ||
| 174 | break; | ||
| 175 | case BYNAME: | ||
| 176 | in = *net_entry.n_aliases; | ||
| 177 | net_entry.n_name = &ans[0]; | ||
| 178 | aux2[0] = '\0'; | ||
| 179 | for (i = 0; i < 4; i++) { | ||
| 180 | for (st = in, nchar = 0; | ||
| 181 | *st != '.'; | ||
| 182 | st++, nchar++) | ||
| 183 | ; | ||
| 184 | if (nchar != 1 || *in != '0' || flag) { | ||
| 185 | flag = 1; | ||
| 186 | (void)strncpy(paux1, | ||
| 187 | (i==0) ? in : in-1, | ||
| 188 | (i==0) ?nchar : nchar+1); | ||
| 189 | paux1[(i==0) ? nchar : nchar+1] = '\0'; | ||
| 190 | pauxt = paux2; | ||
| 191 | paux2 = strcat(paux1, paux2); | ||
| 192 | paux1 = pauxt; | ||
| 193 | } | ||
| 194 | in = ++st; | ||
| 195 | } | ||
| 196 | net_entry.n_net = inet_network(paux2); | ||
| 197 | break; | ||
| 198 | } | ||
| 199 | net_entry.n_aliases++; | ||
| 200 | return (&net_entry); | ||
| 201 | } | ||
| 202 | h_errno = TRY_AGAIN; | ||
| 203 | return (NULL); | ||
| 204 | } | ||
| 205 | |||
| 206 | struct netent * | ||
| 207 | getnetbyaddr(net, net_type) | ||
| 208 | register u_long net; | ||
| 209 | register int net_type; | ||
| 210 | { | ||
| 211 | unsigned int netbr[4]; | ||
| 212 | int nn, anslen; | ||
| 213 | querybuf buf; | ||
| 214 | char qbuf[MAXDNAME]; | ||
| 215 | unsigned long net2; | ||
| 216 | struct netent *net_entry; | ||
| 217 | |||
| 218 | if (net_type != AF_INET) | ||
| 219 | return (_getnetbyaddr(net, net_type)); | ||
| 220 | |||
| 221 | for (nn = 4, net2 = net; net2; net2 >>= 8) | ||
| 222 | netbr[--nn] = net2 & 0xff; | ||
| 223 | switch (nn) { | ||
| 224 | case 3: /* Class A */ | ||
| 225 | snprintf(qbuf, sizeof(qbuf), "0.0.0.%u.in-addr.arpa", netbr[3]); | ||
| 226 | break; | ||
| 227 | case 2: /* Class B */ | ||
| 228 | snprintf(qbuf, sizeof(qbuf), "0.0.%u.%u.in-addr.arpa", | ||
| 229 | netbr[3], netbr[2]); | ||
| 230 | break; | ||
| 231 | case 1: /* Class C */ | ||
| 232 | snprintf(qbuf, sizeof(qbuf), "0.%u.%u.%u.in-addr.arpa", | ||
| 233 | netbr[3], netbr[2], netbr[1]); | ||
| 234 | break; | ||
| 235 | case 0: /* Class D - E */ | ||
| 236 | snprintf(qbuf, sizeof(qbuf), "%u.%u.%u.%u.in-addr.arpa", | ||
| 237 | netbr[3], netbr[2], netbr[1], netbr[0]); | ||
| 238 | break; | ||
| 239 | } | ||
| 240 | anslen = res_query(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf)); | ||
| 241 | if (anslen < 0) { | ||
| 242 | #ifdef DEBUG | ||
| 243 | if (_res.options & RES_DEBUG) | ||
| 244 | printf("res_query failed\n"); | ||
| 245 | #endif | ||
| 246 | if (errno == ECONNREFUSED) | ||
| 247 | return (_getnetbyaddr(net, net_type)); | ||
| 248 | return (NULL); | ||
| 249 | } | ||
| 250 | net_entry = getnetanswer(&buf, anslen, BYADDR); | ||
| 251 | if (net_entry) { | ||
| 252 | unsigned u_net = net; /* maybe net should be unsigned ? */ | ||
| 253 | |||
| 254 | /* Strip trailing zeros */ | ||
| 255 | while ((u_net & 0xff) == 0 && u_net != 0) | ||
| 256 | u_net >>= 8; | ||
| 257 | net_entry->n_net = u_net; | ||
| 258 | return (net_entry); | ||
| 259 | } | ||
| 260 | return (_getnetbyaddr(net, net_type)); | ||
| 261 | } | ||
| 262 | |||
| 263 | struct netent * | ||
| 264 | getnetbyname(net) | ||
| 265 | register const char *net; | ||
| 266 | { | ||
| 267 | int anslen; | ||
| 268 | querybuf buf; | ||
| 269 | char qbuf[MAXDNAME]; | ||
| 270 | struct netent *net_entry; | ||
| 271 | |||
| 272 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) { | ||
| 273 | h_errno = NETDB_INTERNAL; | ||
| 274 | return (NULL); | ||
| 275 | } | ||
| 276 | strcpy(&qbuf[0], net); | ||
| 277 | anslen = res_search(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf)); | ||
| 278 | if (anslen < 0) { | ||
| 279 | #ifdef DEBUG | ||
| 280 | if (_res.options & RES_DEBUG) | ||
| 281 | printf("res_query failed\n"); | ||
| 282 | #endif | ||
| 283 | if (errno == ECONNREFUSED) | ||
| 284 | return (_getnetbyname(net)); | ||
| 285 | return (_getnetbyname(net)); | ||
| 286 | } | ||
| 287 | net_entry = getnetanswer(&buf, anslen, BYNAME); | ||
| 288 | if (net_entry) | ||
| 289 | return (net_entry); | ||
| 290 | return (_getnetbyname(net)); | ||
| 291 | } | ||
diff --git a/src/lib/libc/net/herror.c b/src/lib/libc/net/herror.c index 40da6562ad..737bb115a7 100644 --- a/src/lib/libc/net/herror.c +++ b/src/lib/libc/net/herror.c | |||
| @@ -1,7 +1,11 @@ | |||
| 1 | /*- | 1 | /* $OpenBSD: herror.c,v 1.4 1997/03/13 19:07:28 downsj Exp $ */ |
| 2 | |||
| 3 | /* | ||
| 4 | * ++Copyright++ 1987, 1993 | ||
| 5 | * - | ||
| 2 | * Copyright (c) 1987, 1993 | 6 | * Copyright (c) 1987, 1993 |
| 3 | * The Regents of the University of California. All rights reserved. | 7 | * The Regents of the University of California. All rights reserved. |
| 4 | * | 8 | * |
| 5 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions |
| 7 | * are met: | 11 | * are met: |
| @@ -12,12 +16,12 @@ | |||
| 12 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 17 | * 3. All advertising materials mentioning features or use of this software |
| 14 | * must display the following acknowledgement: | 18 | * must display the following acknowledgement: |
| 15 | * This product includes software developed by the University of | 19 | * This product includes software developed by the University of |
| 16 | * California, Berkeley and its contributors. | 20 | * California, Berkeley and its contributors. |
| 17 | * 4. Neither the name of the University nor the names of its contributors | 21 | * 4. Neither the name of the University nor the names of its contributors |
| 18 | * may be used to endorse or promote products derived from this software | 22 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 23 | * without specific prior written permission. |
| 20 | * | 24 | * |
| 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 25 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
| 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 26 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 27 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| @@ -52,16 +56,22 @@ | |||
| 52 | */ | 56 | */ |
| 53 | 57 | ||
| 54 | #if defined(LIBC_SCCS) && !defined(lint) | 58 | #if defined(LIBC_SCCS) && !defined(lint) |
| 55 | static char rcsid[] = "$OpenBSD: herror.c,v 1.3 1996/08/19 08:29:02 tholo Exp $"; | 59 | #if 0 |
| 60 | static char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93"; | ||
| 61 | static char rcsid[] = "$From: herror.c,v 8.3 1996/08/05 08:31:35 vixie Exp $"; | ||
| 62 | #else | ||
| 63 | static char rcsid[] = "$OpenBSD: herror.c,v 1.4 1997/03/13 19:07:28 downsj Exp $"; | ||
| 64 | #endif | ||
| 56 | #endif /* LIBC_SCCS and not lint */ | 65 | #endif /* LIBC_SCCS and not lint */ |
| 57 | 66 | ||
| 58 | #include <sys/types.h> | 67 | #include <sys/types.h> |
| 68 | #include <sys/param.h> | ||
| 59 | #include <sys/uio.h> | 69 | #include <sys/uio.h> |
| 60 | #include <netdb.h> | 70 | #include <netdb.h> |
| 61 | #include <unistd.h> | 71 | #include <unistd.h> |
| 62 | #include <string.h> | 72 | #include <string.h> |
| 63 | 73 | ||
| 64 | const char *h_errlist[] = { | 74 | const char *h_errlist[] = { |
| 65 | "Resolver Error 0 (no error)", | 75 | "Resolver Error 0 (no error)", |
| 66 | "Unknown host", /* 1 HOST_NOT_FOUND */ | 76 | "Unknown host", /* 1 HOST_NOT_FOUND */ |
| 67 | "Host name lookup failure", /* 2 TRY_AGAIN */ | 77 | "Host name lookup failure", /* 2 TRY_AGAIN */ |
diff --git a/src/lib/libc/net/inet_addr.c b/src/lib/libc/net/inet_addr.c index 99a6f66ad2..ef8ee4963b 100644 --- a/src/lib/libc/net/inet_addr.c +++ b/src/lib/libc/net/inet_addr.c | |||
| @@ -1,7 +1,11 @@ | |||
| 1 | /* $OpenBSD: inet_addr.c,v 1.4 1997/03/13 19:07:29 downsj Exp $ */ | ||
| 2 | |||
| 1 | /* | 3 | /* |
| 4 | * ++Copyright++ 1983, 1990, 1993 | ||
| 5 | * - | ||
| 2 | * Copyright (c) 1983, 1990, 1993 | 6 | * Copyright (c) 1983, 1990, 1993 |
| 3 | * The Regents of the University of California. All rights reserved. | 7 | * The Regents of the University of California. All rights reserved. |
| 4 | * | 8 | * |
| 5 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions |
| 7 | * are met: | 11 | * are met: |
| @@ -12,12 +16,12 @@ | |||
| 12 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 17 | * 3. All advertising materials mentioning features or use of this software |
| 14 | * must display the following acknowledgement: | 18 | * must display the following acknowledgement: |
| 15 | * This product includes software developed by the University of | 19 | * This product includes software developed by the University of |
| 16 | * California, Berkeley and its contributors. | 20 | * California, Berkeley and its contributors. |
| 17 | * 4. Neither the name of the University nor the names of its contributors | 21 | * 4. Neither the name of the University nor the names of its contributors |
| 18 | * may be used to endorse or promote products derived from this software | 22 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 23 | * without specific prior written permission. |
| 20 | * | 24 | * |
| 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 25 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
| 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 26 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 27 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| @@ -29,12 +33,38 @@ | |||
| 29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 33 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 34 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 31 | * SUCH DAMAGE. | 35 | * SUCH DAMAGE. |
| 36 | * - | ||
| 37 | * Portions Copyright (c) 1993 by Digital Equipment Corporation. | ||
| 38 | * | ||
| 39 | * Permission to use, copy, modify, and distribute this software for any | ||
| 40 | * purpose with or without fee is hereby granted, provided that the above | ||
| 41 | * copyright notice and this permission notice appear in all copies, and that | ||
| 42 | * the name of Digital Equipment Corporation not be used in advertising or | ||
| 43 | * publicity pertaining to distribution of the document or software without | ||
| 44 | * specific, written prior permission. | ||
| 45 | * | ||
| 46 | * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL | ||
| 47 | * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES | ||
| 48 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT | ||
| 49 | * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | ||
| 50 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | ||
| 51 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | ||
| 52 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | ||
| 53 | * SOFTWARE. | ||
| 54 | * - | ||
| 55 | * --Copyright-- | ||
| 32 | */ | 56 | */ |
| 33 | 57 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | 58 | #if defined(LIBC_SCCS) && !defined(lint) |
| 35 | static char rcsid[] = "$OpenBSD: inet_addr.c,v 1.3 1996/08/19 08:29:08 tholo Exp $"; | 59 | #if 0 |
| 60 | static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; | ||
| 61 | static char rcsid[] = "$From: inet_addr.c,v 8.5 1996/08/05 08:31:35 vixie Exp $"; | ||
| 62 | #else | ||
| 63 | static char rcsid[] = "$OpenBSD: inet_addr.c,v 1.4 1997/03/13 19:07:29 downsj Exp $"; | ||
| 64 | #endif | ||
| 36 | #endif /* LIBC_SCCS and not lint */ | 65 | #endif /* LIBC_SCCS and not lint */ |
| 37 | 66 | ||
| 67 | #include <sys/types.h> | ||
| 38 | #include <sys/param.h> | 68 | #include <sys/param.h> |
| 39 | #include <netinet/in.h> | 69 | #include <netinet/in.h> |
| 40 | #include <arpa/inet.h> | 70 | #include <arpa/inet.h> |
| @@ -73,50 +103,52 @@ inet_aton(cp, addr) | |||
| 73 | u_int parts[4]; | 103 | u_int parts[4]; |
| 74 | register u_int *pp = parts; | 104 | register u_int *pp = parts; |
| 75 | 105 | ||
| 106 | c = *cp; | ||
| 76 | for (;;) { | 107 | for (;;) { |
| 77 | /* | 108 | /* |
| 78 | * Collect number up to ``.''. | 109 | * Collect number up to ``.''. |
| 79 | * Values are specified as for C: | 110 | * Values are specified as for C: |
| 80 | * 0x=hex, 0=octal, other=decimal. | 111 | * 0x=hex, 0=octal, isdigit=decimal. |
| 81 | */ | 112 | */ |
| 113 | if (!isdigit(c)) | ||
| 114 | return (0); | ||
| 82 | val = 0; base = 10; | 115 | val = 0; base = 10; |
| 83 | if (*cp == '0') { | 116 | if (c == '0') { |
| 84 | if (*++cp == 'x' || *cp == 'X') | 117 | c = *++cp; |
| 85 | base = 16, cp++; | 118 | if (c == 'x' || c == 'X') |
| 119 | base = 16, c = *++cp; | ||
| 86 | else | 120 | else |
| 87 | base = 8; | 121 | base = 8; |
| 88 | } | 122 | } |
| 89 | while ((c = *cp) != '\0') { | 123 | for (;;) { |
| 90 | if (isascii(c) && isdigit(c)) { | 124 | if (isascii(c) && isdigit(c)) { |
| 91 | val = (val * base) + (c - '0'); | 125 | val = (val * base) + (c - '0'); |
| 92 | cp++; | 126 | c = *++cp; |
| 93 | continue; | 127 | } else if (base == 16 && isascii(c) && isxdigit(c)) { |
| 94 | } | 128 | val = (val << 4) | |
| 95 | if (base == 16 && isascii(c) && isxdigit(c)) { | ||
| 96 | val = (val << 4) + | ||
| 97 | (c + 10 - (islower(c) ? 'a' : 'A')); | 129 | (c + 10 - (islower(c) ? 'a' : 'A')); |
| 98 | cp++; | 130 | c = *++cp; |
| 99 | continue; | 131 | } else |
| 100 | } | 132 | break; |
| 101 | break; | ||
| 102 | } | 133 | } |
| 103 | if (*cp == '.') { | 134 | if (c == '.') { |
| 104 | /* | 135 | /* |
| 105 | * Internet format: | 136 | * Internet format: |
| 106 | * a.b.c.d | 137 | * a.b.c.d |
| 107 | * a.b.c (with c treated as 16-bits) | 138 | * a.b.c (with c treated as 16 bits) |
| 108 | * a.b (with b treated as 24 bits) | 139 | * a.b (with b treated as 24 bits) |
| 109 | */ | 140 | */ |
| 110 | if (pp >= parts + 3 || val > 0xff) | 141 | if (pp >= parts + 3) |
| 111 | return (0); | 142 | return (0); |
| 112 | *pp++ = val, cp++; | 143 | *pp++ = val; |
| 144 | c = *++cp; | ||
| 113 | } else | 145 | } else |
| 114 | break; | 146 | break; |
| 115 | } | 147 | } |
| 116 | /* | 148 | /* |
| 117 | * Check for trailing characters. | 149 | * Check for trailing characters. |
| 118 | */ | 150 | */ |
| 119 | if (*cp && (!isascii(*cp) || !isspace(*cp))) | 151 | if (c != '\0' && (!isascii(c) || !isspace(c))) |
| 120 | return (0); | 152 | return (0); |
| 121 | /* | 153 | /* |
| 122 | * Concoct the address according to | 154 | * Concoct the address according to |
diff --git a/src/lib/libc/net/inet_net_ntop.c b/src/lib/libc/net/inet_net_ntop.c new file mode 100644 index 0000000000..943ec44550 --- /dev/null +++ b/src/lib/libc/net/inet_net_ntop.c | |||
| @@ -0,0 +1,139 @@ | |||
| 1 | /* $OpenBSD: inet_net_ntop.c,v 1.1 1997/03/13 19:07:30 downsj Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 1996 by Internet Software Consortium. | ||
| 5 | * | ||
| 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 | ||
| 8 | * copyright notice and this permission notice appear in all copies. | ||
| 9 | * | ||
| 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS | ||
| 11 | * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES | ||
| 12 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE | ||
| 13 | * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | ||
| 14 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | ||
| 15 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | ||
| 16 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | ||
| 17 | * SOFTWARE. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 21 | #if 0 | ||
| 22 | static const char rcsid[] = "$From: inet_net_ntop.c,v 8.2 1996/08/08 06:54:44 vixie Exp $"; | ||
| 23 | #else | ||
| 24 | static const char rcsid[] = "$OpenBSD: inet_net_ntop.c,v 1.1 1997/03/13 19:07:30 downsj Exp $"; | ||
| 25 | #endif | ||
| 26 | #endif | ||
| 27 | |||
| 28 | #include <sys/types.h> | ||
| 29 | #include <sys/socket.h> | ||
| 30 | #include <netinet/in.h> | ||
| 31 | #include <arpa/inet.h> | ||
| 32 | |||
| 33 | #include <errno.h> | ||
| 34 | #include <stdio.h> | ||
| 35 | #include <string.h> | ||
| 36 | #include <stdlib.h> | ||
| 37 | |||
| 38 | static char * inet_net_ntop_ipv4 __P((const u_char *src, int bits, | ||
| 39 | char *dst, size_t size)); | ||
| 40 | |||
| 41 | /* | ||
| 42 | * char * | ||
| 43 | * inet_net_ntop(af, src, bits, dst, size) | ||
| 44 | * convert network number from network to presentation format. | ||
| 45 | * generates CIDR style result always. | ||
| 46 | * return: | ||
| 47 | * pointer to dst, or NULL if an error occurred (check errno). | ||
| 48 | * author: | ||
| 49 | * Paul Vixie (ISC), July 1996 | ||
| 50 | */ | ||
| 51 | char * | ||
| 52 | inet_net_ntop(af, src, bits, dst, size) | ||
| 53 | int af; | ||
| 54 | const void *src; | ||
| 55 | int bits; | ||
| 56 | char *dst; | ||
| 57 | size_t size; | ||
| 58 | { | ||
| 59 | switch (af) { | ||
| 60 | case AF_INET: | ||
| 61 | return (inet_net_ntop_ipv4(src, bits, dst, size)); | ||
| 62 | default: | ||
| 63 | errno = EAFNOSUPPORT; | ||
| 64 | return (NULL); | ||
| 65 | } | ||
| 66 | } | ||
| 67 | |||
| 68 | /* | ||
| 69 | * static char * | ||
| 70 | * inet_net_ntop_ipv4(src, bits, dst, size) | ||
| 71 | * convert IPv4 network number from network to presentation format. | ||
| 72 | * generates CIDR style result always. | ||
| 73 | * return: | ||
| 74 | * pointer to dst, or NULL if an error occurred (check errno). | ||
| 75 | * note: | ||
| 76 | * network byte order assumed. this means 192.5.5.240/28 has | ||
| 77 | * 0x11110000 in its fourth octet. | ||
| 78 | * author: | ||
| 79 | * Paul Vixie (ISC), July 1996 | ||
| 80 | */ | ||
| 81 | static char * | ||
| 82 | inet_net_ntop_ipv4(src, bits, dst, size) | ||
| 83 | const u_char *src; | ||
| 84 | int bits; | ||
| 85 | char *dst; | ||
| 86 | size_t size; | ||
| 87 | { | ||
| 88 | char *odst = dst; | ||
| 89 | char *t; | ||
| 90 | u_int m; | ||
| 91 | int b; | ||
| 92 | |||
| 93 | if (bits < 0 || bits > 32) { | ||
| 94 | errno = EINVAL; | ||
| 95 | return (NULL); | ||
| 96 | } | ||
| 97 | if (bits == 0) { | ||
| 98 | if (size < sizeof "0") | ||
| 99 | goto emsgsize; | ||
| 100 | *dst++ = '0'; | ||
| 101 | *dst = '\0'; | ||
| 102 | } | ||
| 103 | |||
| 104 | /* Format whole octets. */ | ||
| 105 | for (b = bits / 8; b > 0; b--) { | ||
| 106 | if (size < sizeof "255.") | ||
| 107 | goto emsgsize; | ||
| 108 | t = dst; | ||
| 109 | dst += sprintf(dst, "%u", *src++); | ||
| 110 | if (b > 1) { | ||
| 111 | *dst++ = '.'; | ||
| 112 | *dst = '\0'; | ||
| 113 | } | ||
| 114 | size -= (size_t)(dst - t); | ||
| 115 | } | ||
| 116 | |||
| 117 | /* Format partial octet. */ | ||
| 118 | b = bits % 8; | ||
| 119 | if (b > 0) { | ||
| 120 | if (size < sizeof ".255") | ||
| 121 | goto emsgsize; | ||
| 122 | t = dst; | ||
| 123 | if (dst != odst) | ||
| 124 | *dst++ = '.'; | ||
| 125 | m = ((1 << b) - 1) << (8 - b); | ||
| 126 | dst += sprintf(dst, "%u", *src & m); | ||
| 127 | size -= (size_t)(dst - t); | ||
| 128 | } | ||
| 129 | |||
| 130 | /* Format CIDR /width. */ | ||
| 131 | if (size < sizeof "/32") | ||
| 132 | goto emsgsize; | ||
| 133 | dst += sprintf(dst, "/%u", bits); | ||
| 134 | return (odst); | ||
| 135 | |||
| 136 | emsgsize: | ||
| 137 | errno = EMSGSIZE; | ||
| 138 | return (NULL); | ||
| 139 | } | ||
diff --git a/src/lib/libc/net/inet_net_pton.c b/src/lib/libc/net/inet_net_pton.c new file mode 100644 index 0000000000..b529e83664 --- /dev/null +++ b/src/lib/libc/net/inet_net_pton.c | |||
| @@ -0,0 +1,207 @@ | |||
| 1 | /* $OpenBSD: inet_net_pton.c,v 1.1 1997/03/13 19:07:30 downsj Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 1996 by Internet Software Consortium. | ||
| 5 | * | ||
| 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 | ||
| 8 | * copyright notice and this permission notice appear in all copies. | ||
| 9 | * | ||
| 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS | ||
| 11 | * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES | ||
| 12 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE | ||
| 13 | * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | ||
| 14 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | ||
| 15 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | ||
| 16 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | ||
| 17 | * SOFTWARE. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 21 | #if 0 | ||
| 22 | static const char rcsid[] = "$From: inet_net_pton.c,v 8.3 1996/11/11 06:36:52 vixie Exp $"; | ||
| 23 | #else | ||
| 24 | static const char rcsid[] = "$OpenBSD: inet_net_pton.c,v 1.1 1997/03/13 19:07:30 downsj Exp $"; | ||
| 25 | #endif | ||
| 26 | #endif | ||
| 27 | |||
| 28 | #include <sys/types.h> | ||
| 29 | #include <sys/socket.h> | ||
| 30 | #include <netinet/in.h> | ||
| 31 | #include <arpa/inet.h> | ||
| 32 | |||
| 33 | #include <assert.h> | ||
| 34 | #include <ctype.h> | ||
| 35 | #include <errno.h> | ||
| 36 | #include <stdio.h> | ||
| 37 | #include <string.h> | ||
| 38 | #include <stdlib.h> | ||
| 39 | |||
| 40 | static int inet_net_pton_ipv4 __P((const char *src, u_char *dst, | ||
| 41 | size_t size)); | ||
| 42 | |||
| 43 | /* | ||
| 44 | * static int | ||
| 45 | * inet_net_pton(af, src, dst, size) | ||
| 46 | * convert network number from presentation to network format. | ||
| 47 | * accepts hex octets, hex strings, decimal octets, and /CIDR. | ||
| 48 | * "size" is in bytes and describes "dst". | ||
| 49 | * return: | ||
| 50 | * number of bits, either imputed classfully or specified with /CIDR, | ||
| 51 | * or -1 if some failure occurred (check errno). ENOENT means it was | ||
| 52 | * not a valid network specification. | ||
| 53 | * author: | ||
| 54 | * Paul Vixie (ISC), June 1996 | ||
| 55 | */ | ||
| 56 | int | ||
| 57 | inet_net_pton(af, src, dst, size) | ||
| 58 | int af; | ||
| 59 | const char *src; | ||
| 60 | void *dst; | ||
| 61 | size_t size; | ||
| 62 | { | ||
| 63 | switch (af) { | ||
| 64 | case AF_INET: | ||
| 65 | return (inet_net_pton_ipv4(src, dst, size)); | ||
| 66 | default: | ||
| 67 | errno = EAFNOSUPPORT; | ||
| 68 | return (-1); | ||
| 69 | } | ||
| 70 | } | ||
| 71 | |||
| 72 | /* | ||
| 73 | * static int | ||
| 74 | * inet_net_pton_ipv4(src, dst, size) | ||
| 75 | * convert IPv4 network number from presentation to network format. | ||
| 76 | * accepts hex octets, hex strings, decimal octets, and /CIDR. | ||
| 77 | * "size" is in bytes and describes "dst". | ||
| 78 | * return: | ||
| 79 | * number of bits, either imputed classfully or specified with /CIDR, | ||
| 80 | * or -1 if some failure occurred (check errno). ENOENT means it was | ||
| 81 | * not an IPv4 network specification. | ||
| 82 | * note: | ||
| 83 | * network byte order assumed. this means 192.5.5.240/28 has | ||
| 84 | * 0x11110000 in its fourth octet. | ||
| 85 | * author: | ||
| 86 | * Paul Vixie (ISC), June 1996 | ||
| 87 | */ | ||
| 88 | static int | ||
| 89 | inet_net_pton_ipv4(src, dst, size) | ||
| 90 | const char *src; | ||
| 91 | u_char *dst; | ||
| 92 | size_t size; | ||
| 93 | { | ||
| 94 | static const char | ||
| 95 | xdigits[] = "0123456789abcdef", | ||
| 96 | digits[] = "0123456789"; | ||
| 97 | int n, ch, tmp, dirty, bits; | ||
| 98 | const u_char *odst = dst; | ||
| 99 | |||
| 100 | ch = *src++; | ||
| 101 | if (ch == '0' && (src[0] == 'x' || src[0] == 'X') | ||
| 102 | && isascii(src[1]) && isxdigit(src[1])) { | ||
| 103 | /* Hexadecimal: Eat nybble string. */ | ||
| 104 | if (size <= 0) | ||
| 105 | goto emsgsize; | ||
| 106 | *dst = 0, dirty = 0; | ||
| 107 | src++; /* skip x or X. */ | ||
| 108 | while ((ch = *src++) != '\0' && | ||
| 109 | isascii(ch) && isxdigit(ch)) { | ||
| 110 | if (isupper(ch)) | ||
| 111 | ch = tolower(ch); | ||
| 112 | n = strchr(xdigits, ch) - xdigits; | ||
| 113 | assert(n >= 0 && n <= 15); | ||
| 114 | *dst |= n; | ||
| 115 | if (!dirty++) | ||
| 116 | *dst <<= 4; | ||
| 117 | else if (size-- > 0) | ||
| 118 | *++dst = 0, dirty = 0; | ||
| 119 | else | ||
| 120 | goto emsgsize; | ||
| 121 | } | ||
| 122 | if (dirty) | ||
| 123 | size--; | ||
| 124 | } else if (isascii(ch) && isdigit(ch)) { | ||
| 125 | /* Decimal: eat dotted digit string. */ | ||
| 126 | for (;;) { | ||
| 127 | tmp = 0; | ||
| 128 | do { | ||
| 129 | n = strchr(digits, ch) - digits; | ||
| 130 | assert(n >= 0 && n <= 9); | ||
| 131 | tmp *= 10; | ||
| 132 | tmp += n; | ||
| 133 | if (tmp > 255) | ||
| 134 | goto enoent; | ||
| 135 | } while ((ch = *src++) != '\0' && | ||
| 136 | isascii(ch) && isdigit(ch)); | ||
| 137 | if (size-- <= 0) | ||
| 138 | goto emsgsize; | ||
| 139 | *dst++ = (u_char) tmp; | ||
| 140 | if (ch == '\0' || ch == '/') | ||
| 141 | break; | ||
| 142 | if (ch != '.') | ||
| 143 | goto enoent; | ||
| 144 | ch = *src++; | ||
| 145 | if (!isascii(ch) || !isdigit(ch)) | ||
| 146 | goto enoent; | ||
| 147 | } | ||
| 148 | } else | ||
| 149 | goto enoent; | ||
| 150 | |||
| 151 | bits = -1; | ||
| 152 | if (ch == '/' && isascii(src[0]) && isdigit(src[0]) && dst > odst) { | ||
| 153 | /* CIDR width specifier. Nothing can follow it. */ | ||
| 154 | ch = *src++; /* Skip over the /. */ | ||
| 155 | bits = 0; | ||
| 156 | do { | ||
| 157 | n = strchr(digits, ch) - digits; | ||
| 158 | assert(n >= 0 && n <= 9); | ||
| 159 | bits *= 10; | ||
| 160 | bits += n; | ||
| 161 | } while ((ch = *src++) != '\0' && | ||
| 162 | isascii(ch) && isdigit(ch)); | ||
| 163 | if (ch != '\0') | ||
| 164 | goto enoent; | ||
| 165 | if (bits > 32) | ||
| 166 | goto emsgsize; | ||
| 167 | } | ||
| 168 | |||
| 169 | /* Firey death and destruction unless we prefetched EOS. */ | ||
| 170 | if (ch != '\0') | ||
| 171 | goto enoent; | ||
| 172 | |||
| 173 | /* If nothing was written to the destination, we found no address. */ | ||
| 174 | if (dst == odst) | ||
| 175 | goto enoent; | ||
| 176 | /* If no CIDR spec was given, infer width from net class. */ | ||
| 177 | if (bits == -1) { | ||
| 178 | if (*odst >= 240) /* Class E */ | ||
| 179 | bits = 32; | ||
| 180 | else if (*odst >= 224) /* Class D */ | ||
| 181 | bits = 4; | ||
| 182 | else if (*odst >= 192) /* Class C */ | ||
| 183 | bits = 24; | ||
| 184 | else if (*odst >= 128) /* Class B */ | ||
| 185 | bits = 16; | ||
| 186 | else /* Class A */ | ||
| 187 | bits = 8; | ||
| 188 | /* If imputed mask is narrower than specified octets, widen. */ | ||
| 189 | if (bits >= 8 && bits < ((dst - odst) * 8)) | ||
| 190 | bits = (dst - odst) * 8; | ||
| 191 | } | ||
| 192 | /* Extend network to cover the actual mask. */ | ||
| 193 | while (bits > ((dst - odst) * 8)) { | ||
| 194 | if (size-- <= 0) | ||
| 195 | goto emsgsize; | ||
| 196 | *dst++ = '\0'; | ||
| 197 | } | ||
| 198 | return (bits); | ||
| 199 | |||
| 200 | enoent: | ||
| 201 | errno = ENOENT; | ||
| 202 | return (-1); | ||
| 203 | |||
| 204 | emsgsize: | ||
| 205 | errno = EMSGSIZE; | ||
| 206 | return (-1); | ||
| 207 | } | ||
diff --git a/src/lib/libc/net/inet_neta.c b/src/lib/libc/net/inet_neta.c new file mode 100644 index 0000000000..dffd1631b1 --- /dev/null +++ b/src/lib/libc/net/inet_neta.c | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | /* $OpenBSD: inet_neta.c,v 1.1 1997/03/13 19:07:31 downsj Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * Copyright (c) 1996 by Internet Software Consortium. | ||
| 5 | * | ||
| 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 | ||
| 8 | * copyright notice and this permission notice appear in all copies. | ||
| 9 | * | ||
| 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS | ||
| 11 | * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES | ||
| 12 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE | ||
| 13 | * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | ||
| 14 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | ||
| 15 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | ||
| 16 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | ||
| 17 | * SOFTWARE. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 21 | #if 0 | ||
| 22 | static const char rcsid[] = "$Id: inet_neta.c,v 1.1 1997/03/13 19:07:31 downsj Exp $"; | ||
| 23 | #else | ||
| 24 | static const char rcsid[] = "$OpenBSD: inet_neta.c,v 1.1 1997/03/13 19:07:31 downsj Exp $"; | ||
| 25 | #endif | ||
| 26 | #endif | ||
| 27 | |||
| 28 | #include <sys/types.h> | ||
| 29 | #include <sys/socket.h> | ||
| 30 | #include <netinet/in.h> | ||
| 31 | #include <arpa/inet.h> | ||
| 32 | |||
| 33 | #include <errno.h> | ||
| 34 | #include <stdio.h> | ||
| 35 | |||
| 36 | /* | ||
| 37 | * char * | ||
| 38 | * inet_neta(src, dst, size) | ||
| 39 | * format a u_long network number into presentation format. | ||
| 40 | * return: | ||
| 41 | * pointer to dst, or NULL if an error occurred (check errno). | ||
| 42 | * note: | ||
| 43 | * format of ``src'' is as for inet_network(). | ||
| 44 | * author: | ||
| 45 | * Paul Vixie (ISC), July 1996 | ||
| 46 | */ | ||
| 47 | char * | ||
| 48 | inet_neta(src, dst, size) | ||
| 49 | u_long src; | ||
| 50 | char *dst; | ||
| 51 | size_t size; | ||
| 52 | { | ||
| 53 | char *odst = dst; | ||
| 54 | char *tp; | ||
| 55 | |||
| 56 | while (src & 0xffffffff) { | ||
| 57 | u_char b = (src & 0xff000000) >> 24; | ||
| 58 | |||
| 59 | src <<= 8; | ||
| 60 | if (b) { | ||
| 61 | if (size < sizeof "255.") | ||
| 62 | goto emsgsize; | ||
| 63 | tp = dst; | ||
| 64 | dst += sprintf(dst, "%u", b); | ||
| 65 | if (src != 0L) { | ||
| 66 | *dst++ = '.'; | ||
| 67 | *dst = '\0'; | ||
| 68 | } | ||
| 69 | size -= (size_t)(dst - tp); | ||
| 70 | } | ||
| 71 | } | ||
| 72 | if (dst == odst) { | ||
| 73 | if (size < sizeof "0.0.0.0") | ||
| 74 | goto emsgsize; | ||
| 75 | strcpy(dst, "0.0.0.0"); | ||
| 76 | } | ||
| 77 | return (odst); | ||
| 78 | |||
| 79 | emsgsize: | ||
| 80 | errno = EMSGSIZE; | ||
| 81 | return (NULL); | ||
| 82 | } | ||
diff --git a/src/lib/libc/net/inet_ntop.c b/src/lib/libc/net/inet_ntop.c new file mode 100644 index 0000000000..64d0d13768 --- /dev/null +++ b/src/lib/libc/net/inet_ntop.c | |||
| @@ -0,0 +1,194 @@ | |||
| 1 | /* $OpenBSD: inet_ntop.c,v 1.1 1997/03/13 19:07:32 downsj Exp $ */ | ||
| 2 | |||
| 3 | /* Copyright (c) 1996 by Internet Software Consortium. | ||
| 4 | * | ||
| 5 | * Permission to use, copy, modify, and distribute this software for any | ||
| 6 | * purpose with or without fee is hereby granted, provided that the above | ||
| 7 | * copyright notice and this permission notice appear in all copies. | ||
| 8 | * | ||
| 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS | ||
| 10 | * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES | ||
| 11 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE | ||
| 12 | * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | ||
| 13 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | ||
| 14 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | ||
| 15 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | ||
| 16 | * SOFTWARE. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 20 | #if 0 | ||
| 21 | static char rcsid[] = "$From: inet_ntop.c,v 8.7 1996/08/05 08:41:18 vixie Exp $"; | ||
| 22 | #else | ||
| 23 | static char rcsid[] = "$OpenBSD: inet_ntop.c,v 1.1 1997/03/13 19:07:32 downsj Exp $"; | ||
| 24 | #endif | ||
| 25 | #endif /* LIBC_SCCS and not lint */ | ||
| 26 | |||
| 27 | #include <sys/param.h> | ||
| 28 | #include <sys/types.h> | ||
| 29 | #include <sys/socket.h> | ||
| 30 | #include <netinet/in.h> | ||
| 31 | #include <arpa/inet.h> | ||
| 32 | #include <arpa/nameser.h> | ||
| 33 | #include <string.h> | ||
| 34 | #include <errno.h> | ||
| 35 | #include <stdio.h> | ||
| 36 | |||
| 37 | /* | ||
| 38 | * WARNING: Don't even consider trying to compile this on a system where | ||
| 39 | * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. | ||
| 40 | */ | ||
| 41 | |||
| 42 | static const char *inet_ntop4 __P((const u_char *src, char *dst, size_t size)); | ||
| 43 | static const char *inet_ntop6 __P((const u_char *src, char *dst, size_t size)); | ||
| 44 | |||
| 45 | /* char * | ||
| 46 | * inet_ntop(af, src, dst, size) | ||
| 47 | * convert a network format address to presentation format. | ||
| 48 | * return: | ||
| 49 | * pointer to presentation format address (`dst'), or NULL (see errno). | ||
| 50 | * author: | ||
| 51 | * Paul Vixie, 1996. | ||
| 52 | */ | ||
| 53 | const char * | ||
| 54 | inet_ntop(af, src, dst, size) | ||
| 55 | int af; | ||
| 56 | const void *src; | ||
| 57 | char *dst; | ||
| 58 | size_t size; | ||
| 59 | { | ||
| 60 | switch (af) { | ||
| 61 | case AF_INET: | ||
| 62 | return (inet_ntop4(src, dst, size)); | ||
| 63 | case AF_INET6: | ||
| 64 | return (inet_ntop6(src, dst, size)); | ||
| 65 | default: | ||
| 66 | errno = EAFNOSUPPORT; | ||
| 67 | return (NULL); | ||
| 68 | } | ||
| 69 | /* NOTREACHED */ | ||
| 70 | } | ||
| 71 | |||
| 72 | /* const char * | ||
| 73 | * inet_ntop4(src, dst, size) | ||
| 74 | * format an IPv4 address, more or less like inet_ntoa() | ||
| 75 | * return: | ||
| 76 | * `dst' (as a const) | ||
| 77 | * notes: | ||
| 78 | * (1) uses no statics | ||
| 79 | * (2) takes a u_char* not an in_addr as input | ||
| 80 | * author: | ||
| 81 | * Paul Vixie, 1996. | ||
| 82 | */ | ||
| 83 | static const char * | ||
| 84 | inet_ntop4(src, dst, size) | ||
| 85 | const u_char *src; | ||
| 86 | char *dst; | ||
| 87 | size_t size; | ||
| 88 | { | ||
| 89 | static const char fmt[] = "%u.%u.%u.%u"; | ||
| 90 | char tmp[sizeof "255.255.255.255"]; | ||
| 91 | |||
| 92 | if (sprintf(tmp, fmt, src[0], src[1], src[2], src[3]) > size) { | ||
| 93 | errno = ENOSPC; | ||
| 94 | return (NULL); | ||
| 95 | } | ||
| 96 | strcpy(dst, tmp); | ||
| 97 | return (dst); | ||
| 98 | } | ||
| 99 | |||
| 100 | /* const char * | ||
| 101 | * inet_ntop6(src, dst, size) | ||
| 102 | * convert IPv6 binary address into presentation (printable) format | ||
| 103 | * author: | ||
| 104 | * Paul Vixie, 1996. | ||
| 105 | */ | ||
| 106 | static const char * | ||
| 107 | inet_ntop6(src, dst, size) | ||
| 108 | const u_char *src; | ||
| 109 | char *dst; | ||
| 110 | size_t size; | ||
| 111 | { | ||
| 112 | /* | ||
| 113 | * Note that int32_t and int16_t need only be "at least" large enough | ||
| 114 | * to contain a value of the specified size. On some systems, like | ||
| 115 | * Crays, there is no such thing as an integer variable with 16 bits. | ||
| 116 | * Keep this in mind if you think this function should have been coded | ||
| 117 | * to use pointer overlays. All the world's not a VAX. | ||
| 118 | */ | ||
| 119 | char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; | ||
| 120 | struct { int base, len; } best, cur; | ||
| 121 | u_int words[IN6ADDRSZ / INT16SZ]; | ||
| 122 | int i; | ||
| 123 | |||
| 124 | /* | ||
| 125 | * Preprocess: | ||
| 126 | * Copy the input (bytewise) array into a wordwise array. | ||
| 127 | * Find the longest run of 0x00's in src[] for :: shorthanding. | ||
| 128 | */ | ||
| 129 | memset(words, '\0', sizeof words); | ||
| 130 | for (i = 0; i < IN6ADDRSZ; i++) | ||
| 131 | words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); | ||
| 132 | best.base = -1; | ||
| 133 | cur.base = -1; | ||
| 134 | for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { | ||
| 135 | if (words[i] == 0) { | ||
| 136 | if (cur.base == -1) | ||
| 137 | cur.base = i, cur.len = 1; | ||
| 138 | else | ||
| 139 | cur.len++; | ||
| 140 | } else { | ||
| 141 | if (cur.base != -1) { | ||
| 142 | if (best.base == -1 || cur.len > best.len) | ||
| 143 | best = cur; | ||
| 144 | cur.base = -1; | ||
| 145 | } | ||
| 146 | } | ||
| 147 | } | ||
| 148 | if (cur.base != -1) { | ||
| 149 | if (best.base == -1 || cur.len > best.len) | ||
| 150 | best = cur; | ||
| 151 | } | ||
| 152 | if (best.base != -1 && best.len < 2) | ||
| 153 | best.base = -1; | ||
| 154 | |||
| 155 | /* | ||
| 156 | * Format the result. | ||
| 157 | */ | ||
| 158 | tp = tmp; | ||
| 159 | for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { | ||
| 160 | /* Are we inside the best run of 0x00's? */ | ||
| 161 | if (best.base != -1 && i >= best.base && | ||
| 162 | i < (best.base + best.len)) { | ||
| 163 | if (i == best.base) | ||
| 164 | *tp++ = ':'; | ||
| 165 | continue; | ||
| 166 | } | ||
| 167 | /* Are we following an initial run of 0x00s or any real hex? */ | ||
| 168 | if (i != 0) | ||
| 169 | *tp++ = ':'; | ||
| 170 | /* Is this address an encapsulated IPv4? */ | ||
| 171 | if (i == 6 && best.base == 0 && | ||
| 172 | (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { | ||
| 173 | if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) | ||
| 174 | return (NULL); | ||
| 175 | tp += strlen(tp); | ||
| 176 | break; | ||
| 177 | } | ||
| 178 | tp += sprintf(tp, "%x", words[i]); | ||
| 179 | } | ||
| 180 | /* Was it a trailing run of 0x00's? */ | ||
| 181 | if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) | ||
| 182 | *tp++ = ':'; | ||
| 183 | *tp++ = '\0'; | ||
| 184 | |||
| 185 | /* | ||
| 186 | * Check for overflow, copy, and we're done. | ||
| 187 | */ | ||
| 188 | if ((size_t)(tp - tmp) > size) { | ||
| 189 | errno = ENOSPC; | ||
| 190 | return (NULL); | ||
| 191 | } | ||
| 192 | strcpy(dst, tmp); | ||
| 193 | return (dst); | ||
| 194 | } | ||
diff --git a/src/lib/libc/net/inet_pton.c b/src/lib/libc/net/inet_pton.c new file mode 100644 index 0000000000..8ffe81ed12 --- /dev/null +++ b/src/lib/libc/net/inet_pton.c | |||
| @@ -0,0 +1,220 @@ | |||
| 1 | /* $OpenBSD: inet_pton.c,v 1.1 1997/03/13 19:07:33 downsj Exp $ */ | ||
| 2 | |||
| 3 | /* Copyright (c) 1996 by Internet Software Consortium. | ||
| 4 | * | ||
| 5 | * Permission to use, copy, modify, and distribute this software for any | ||
| 6 | * purpose with or without fee is hereby granted, provided that the above | ||
| 7 | * copyright notice and this permission notice appear in all copies. | ||
| 8 | * | ||
| 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS | ||
| 10 | * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES | ||
| 11 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE | ||
| 12 | * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | ||
| 13 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | ||
| 14 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | ||
| 15 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | ||
| 16 | * SOFTWARE. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 20 | #if 0 | ||
| 21 | static char rcsid[] = "$From: inet_pton.c,v 8.7 1996/08/05 08:31:35 vixie Exp $"; | ||
| 22 | #else | ||
| 23 | static char rcsid[] = "$OpenBSD: inet_pton.c,v 1.1 1997/03/13 19:07:33 downsj Exp $"; | ||
| 24 | #endif | ||
| 25 | #endif /* LIBC_SCCS and not lint */ | ||
| 26 | |||
| 27 | #include <sys/param.h> | ||
| 28 | #include <sys/types.h> | ||
| 29 | #include <sys/socket.h> | ||
| 30 | #include <netinet/in.h> | ||
| 31 | #include <arpa/inet.h> | ||
| 32 | #include <arpa/nameser.h> | ||
| 33 | #include <string.h> | ||
| 34 | #include <errno.h> | ||
| 35 | |||
| 36 | /* | ||
| 37 | * WARNING: Don't even consider trying to compile this on a system where | ||
| 38 | * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. | ||
| 39 | */ | ||
| 40 | |||
| 41 | static int inet_pton4 __P((const char *src, u_char *dst)); | ||
| 42 | static int inet_pton6 __P((const char *src, u_char *dst)); | ||
| 43 | |||
| 44 | /* int | ||
| 45 | * inet_pton(af, src, dst) | ||
| 46 | * convert from presentation format (which usually means ASCII printable) | ||
| 47 | * to network format (which is usually some kind of binary format). | ||
| 48 | * return: | ||
| 49 | * 1 if the address was valid for the specified address family | ||
| 50 | * 0 if the address wasn't valid (`dst' is untouched in this case) | ||
| 51 | * -1 if some other error occurred (`dst' is untouched in this case, too) | ||
| 52 | * author: | ||
| 53 | * Paul Vixie, 1996. | ||
| 54 | */ | ||
| 55 | int | ||
| 56 | inet_pton(af, src, dst) | ||
| 57 | int af; | ||
| 58 | const char *src; | ||
| 59 | void *dst; | ||
| 60 | { | ||
| 61 | switch (af) { | ||
| 62 | case AF_INET: | ||
| 63 | return (inet_pton4(src, dst)); | ||
| 64 | case AF_INET6: | ||
| 65 | return (inet_pton6(src, dst)); | ||
| 66 | default: | ||
| 67 | errno = EAFNOSUPPORT; | ||
| 68 | return (-1); | ||
| 69 | } | ||
| 70 | /* NOTREACHED */ | ||
| 71 | } | ||
| 72 | |||
| 73 | /* int | ||
| 74 | * inet_pton4(src, dst) | ||
| 75 | * like inet_aton() but without all the hexadecimal and shorthand. | ||
| 76 | * return: | ||
| 77 | * 1 if `src' is a valid dotted quad, else 0. | ||
| 78 | * notice: | ||
| 79 | * does not touch `dst' unless it's returning 1. | ||
| 80 | * author: | ||
| 81 | * Paul Vixie, 1996. | ||
| 82 | */ | ||
| 83 | static int | ||
| 84 | inet_pton4(src, dst) | ||
| 85 | const char *src; | ||
| 86 | u_char *dst; | ||
| 87 | { | ||
| 88 | static const char digits[] = "0123456789"; | ||
| 89 | int saw_digit, octets, ch; | ||
| 90 | u_char tmp[INADDRSZ], *tp; | ||
| 91 | |||
| 92 | saw_digit = 0; | ||
| 93 | octets = 0; | ||
| 94 | *(tp = tmp) = 0; | ||
| 95 | while ((ch = *src++) != '\0') { | ||
| 96 | const char *pch; | ||
| 97 | |||
| 98 | if ((pch = strchr(digits, ch)) != NULL) { | ||
| 99 | u_int new = *tp * 10 + (pch - digits); | ||
| 100 | |||
| 101 | if (new > 255) | ||
| 102 | return (0); | ||
| 103 | *tp = new; | ||
| 104 | if (! saw_digit) { | ||
| 105 | if (++octets > 4) | ||
| 106 | return (0); | ||
| 107 | saw_digit = 1; | ||
| 108 | } | ||
| 109 | } else if (ch == '.' && saw_digit) { | ||
| 110 | if (octets == 4) | ||
| 111 | return (0); | ||
| 112 | *++tp = 0; | ||
| 113 | saw_digit = 0; | ||
| 114 | } else | ||
| 115 | return (0); | ||
| 116 | } | ||
| 117 | if (octets < 4) | ||
| 118 | return (0); | ||
| 119 | |||
| 120 | memcpy(dst, tmp, INADDRSZ); | ||
| 121 | return (1); | ||
| 122 | } | ||
| 123 | |||
| 124 | /* int | ||
| 125 | * inet_pton6(src, dst) | ||
| 126 | * convert presentation level address to network order binary form. | ||
| 127 | * return: | ||
| 128 | * 1 if `src' is a valid [RFC1884 2.2] address, else 0. | ||
| 129 | * notice: | ||
| 130 | * (1) does not touch `dst' unless it's returning 1. | ||
| 131 | * (2) :: in a full address is silently ignored. | ||
| 132 | * credit: | ||
| 133 | * inspired by Mark Andrews. | ||
| 134 | * author: | ||
| 135 | * Paul Vixie, 1996. | ||
| 136 | */ | ||
| 137 | static int | ||
| 138 | inet_pton6(src, dst) | ||
| 139 | const char *src; | ||
| 140 | u_char *dst; | ||
| 141 | { | ||
| 142 | static const char xdigits_l[] = "0123456789abcdef", | ||
| 143 | xdigits_u[] = "0123456789ABCDEF"; | ||
| 144 | u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp; | ||
| 145 | const char *xdigits, *curtok; | ||
| 146 | int ch, saw_xdigit; | ||
| 147 | u_int val; | ||
| 148 | |||
| 149 | memset((tp = tmp), '\0', IN6ADDRSZ); | ||
| 150 | endp = tp + IN6ADDRSZ; | ||
| 151 | colonp = NULL; | ||
| 152 | /* Leading :: requires some special handling. */ | ||
| 153 | if (*src == ':') | ||
| 154 | if (*++src != ':') | ||
| 155 | return (0); | ||
| 156 | curtok = src; | ||
| 157 | saw_xdigit = 0; | ||
| 158 | val = 0; | ||
| 159 | while ((ch = *src++) != '\0') { | ||
| 160 | const char *pch; | ||
| 161 | |||
| 162 | if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) | ||
| 163 | pch = strchr((xdigits = xdigits_u), ch); | ||
| 164 | if (pch != NULL) { | ||
| 165 | val <<= 4; | ||
| 166 | val |= (pch - xdigits); | ||
| 167 | if (val > 0xffff) | ||
| 168 | return (0); | ||
| 169 | saw_xdigit = 1; | ||
| 170 | continue; | ||
| 171 | } | ||
| 172 | if (ch == ':') { | ||
| 173 | curtok = src; | ||
| 174 | if (!saw_xdigit) { | ||
| 175 | if (colonp) | ||
| 176 | return (0); | ||
| 177 | colonp = tp; | ||
| 178 | continue; | ||
| 179 | } | ||
| 180 | if (tp + INT16SZ > endp) | ||
| 181 | return (0); | ||
| 182 | *tp++ = (u_char) (val >> 8) & 0xff; | ||
| 183 | *tp++ = (u_char) val & 0xff; | ||
| 184 | saw_xdigit = 0; | ||
| 185 | val = 0; | ||
| 186 | continue; | ||
| 187 | } | ||
| 188 | if (ch == '.' && ((tp + INADDRSZ) <= endp) && | ||
| 189 | inet_pton4(curtok, tp) > 0) { | ||
| 190 | tp += INADDRSZ; | ||
| 191 | saw_xdigit = 0; | ||
| 192 | break; /* '\0' was seen by inet_pton4(). */ | ||
| 193 | } | ||
| 194 | return (0); | ||
| 195 | } | ||
| 196 | if (saw_xdigit) { | ||
| 197 | if (tp + INT16SZ > endp) | ||
| 198 | return (0); | ||
| 199 | *tp++ = (u_char) (val >> 8) & 0xff; | ||
| 200 | *tp++ = (u_char) val & 0xff; | ||
| 201 | } | ||
| 202 | if (colonp != NULL) { | ||
| 203 | /* | ||
| 204 | * Since some memmove()'s erroneously fail to handle | ||
| 205 | * overlapping regions, we'll do the shift by hand. | ||
| 206 | */ | ||
| 207 | const int n = tp - colonp; | ||
| 208 | int i; | ||
| 209 | |||
| 210 | for (i = 1; i <= n; i++) { | ||
| 211 | endp[- i] = colonp[n - i]; | ||
| 212 | colonp[n - i] = 0; | ||
| 213 | } | ||
| 214 | tp = endp; | ||
| 215 | } | ||
| 216 | if (tp != endp) | ||
| 217 | return (0); | ||
| 218 | memcpy(dst, tmp, IN6ADDRSZ); | ||
| 219 | return (1); | ||
| 220 | } | ||
diff --git a/src/lib/libc/net/nsap_addr.c b/src/lib/libc/net/nsap_addr.c index ce0a60a7d8..e62d952a07 100644 --- a/src/lib/libc/net/nsap_addr.c +++ b/src/lib/libc/net/nsap_addr.c | |||
| @@ -1,40 +1,31 @@ | |||
| 1 | /* $OpenBSD: nsap_addr.c,v 1.3 1997/03/13 19:07:34 downsj Exp $ */ | ||
| 2 | |||
| 1 | /* | 3 | /* |
| 2 | * Copyright (c) 1989, 1993 | 4 | * Copyright (c) 1996 by Internet Software Consortium. |
| 3 | * The Regents of the University of California. All rights reserved. | ||
| 4 | * | 5 | * |
| 5 | * Redistribution and use in source and binary forms, with or without | 6 | * Permission to use, copy, modify, and distribute this software for any |
| 6 | * modification, are permitted provided that the following conditions | 7 | * purpose with or without fee is hereby granted, provided that the above |
| 7 | * are met: | 8 | * copyright notice and this permission notice appear in all copies. |
| 8 | * 1. Redistributions of source code must retain the above copyright | ||
| 9 | * notice, this list of conditions and the following disclaimer. | ||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer in the | ||
| 12 | * documentation and/or other materials provided with the distribution. | ||
| 13 | * 3. All advertising materials mentioning features or use of this software | ||
| 14 | * must display the following acknowledgement: | ||
| 15 | * This product includes software developed by the University of | ||
| 16 | * California, Berkeley and its contributors. | ||
| 17 | * 4. Neither the name of the University nor the names of its contributors | ||
| 18 | * may be used to endorse or promote products derived from this software | ||
| 19 | * without specific prior written permission. | ||
| 20 | * | 9 | * |
| 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS |
| 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 11 | * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES |
| 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 12 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE |
| 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 13 | * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL |
| 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 14 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR |
| 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 15 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS |
| 27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 16 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS |
| 28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 17 | * SOFTWARE. |
| 29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 31 | * SUCH DAMAGE. | ||
| 32 | */ | 18 | */ |
| 33 | 19 | ||
| 34 | #if defined(LIBC_SCCS) && !defined(lint) | 20 | #if defined(LIBC_SCCS) && !defined(lint) |
| 35 | static char rcsid[] = "$OpenBSD: nsap_addr.c,v 1.2 1996/08/19 08:29:32 tholo Exp $"; | 21 | #if 0 |
| 22 | static char rcsid[] = "$From: nsap_addr.c,v 8.3 1996/08/05 08:31:35 vixie Exp $"; | ||
| 23 | #else | ||
| 24 | static char rcsid[] = "$OpenBSD: nsap_addr.c,v 1.3 1997/03/13 19:07:34 downsj Exp $"; | ||
| 25 | #endif | ||
| 36 | #endif /* LIBC_SCCS and not lint */ | 26 | #endif /* LIBC_SCCS and not lint */ |
| 37 | 27 | ||
| 28 | #include <sys/types.h> | ||
| 38 | #include <sys/param.h> | 29 | #include <sys/param.h> |
| 39 | #include <sys/socket.h> | 30 | #include <sys/socket.h> |
| 40 | #include <netinet/in.h> | 31 | #include <netinet/in.h> |
| @@ -49,12 +40,6 @@ xtob(c) | |||
| 49 | return (c - (((c >= '0') && (c <= '9')) ? '0' : '7')); | 40 | return (c - (((c >= '0') && (c <= '9')) ? '0' : '7')); |
| 50 | } | 41 | } |
| 51 | 42 | ||
| 52 | /* These have to be here for BIND and its utilities (DiG, nslookup, et al) | ||
| 53 | * but should not be promulgated since the calling interface is not pretty. | ||
| 54 | * (They do, however, implement the RFC standard way of representing ISO NSAPs | ||
| 55 | * and as such, are preferred over the more general iso_addr.c routines. | ||
| 56 | */ | ||
| 57 | |||
| 58 | u_int | 43 | u_int |
| 59 | inet_nsap_addr(ascii, binary, maxlen) | 44 | inet_nsap_addr(ascii, binary, maxlen) |
| 60 | const char *ascii; | 45 | const char *ascii; |
diff --git a/src/lib/libc/net/res_comp.c b/src/lib/libc/net/res_comp.c index f64a81d7ce..2e98003b85 100644 --- a/src/lib/libc/net/res_comp.c +++ b/src/lib/libc/net/res_comp.c | |||
| @@ -1,7 +1,11 @@ | |||
| 1 | /*- | 1 | /* $OpenBSD: res_comp.c,v 1.4 1997/03/13 19:07:35 downsj Exp $ */ |
| 2 | |||
| 3 | /* | ||
| 4 | * ++Copyright++ 1985, 1993 | ||
| 5 | * - | ||
| 2 | * Copyright (c) 1985, 1993 | 6 | * Copyright (c) 1985, 1993 |
| 3 | * The Regents of the University of California. All rights reserved. | 7 | * The Regents of the University of California. All rights reserved. |
| 4 | * | 8 | * |
| 5 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions |
| 7 | * are met: | 11 | * are met: |
| @@ -12,12 +16,12 @@ | |||
| 12 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 17 | * 3. All advertising materials mentioning features or use of this software |
| 14 | * must display the following acknowledgement: | 18 | * must display the following acknowledgement: |
| 15 | * This product includes software developed by the University of | 19 | * This product includes software developed by the University of |
| 16 | * California, Berkeley and its contributors. | 20 | * California, Berkeley and its contributors. |
| 17 | * 4. Neither the name of the University nor the names of its contributors | 21 | * 4. Neither the name of the University nor the names of its contributors |
| 18 | * may be used to endorse or promote products derived from this software | 22 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 23 | * without specific prior written permission. |
| 20 | * | 24 | * |
| 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 25 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
| 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 26 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 27 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| @@ -52,19 +56,28 @@ | |||
| 52 | */ | 56 | */ |
| 53 | 57 | ||
| 54 | #if defined(LIBC_SCCS) && !defined(lint) | 58 | #if defined(LIBC_SCCS) && !defined(lint) |
| 55 | static char rcsid[] = "$OpenBSD: res_comp.c,v 1.3 1996/08/19 08:29:42 tholo Exp $"; | 59 | #if 0 |
| 60 | static char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93"; | ||
| 61 | static char rcsid[] = "$From: res_comp.c,v 8.11 1996/12/02 09:17:22 vixie Exp $"; | ||
| 62 | #else | ||
| 63 | static char rcsid[] = "$OpenBSD: res_comp.c,v 1.4 1997/03/13 19:07:35 downsj Exp $"; | ||
| 64 | #endif | ||
| 56 | #endif /* LIBC_SCCS and not lint */ | 65 | #endif /* LIBC_SCCS and not lint */ |
| 57 | 66 | ||
| 67 | #include <sys/types.h> | ||
| 58 | #include <sys/param.h> | 68 | #include <sys/param.h> |
| 59 | #include <arpa/nameser.h> | ||
| 60 | #include <netinet/in.h> | 69 | #include <netinet/in.h> |
| 61 | #include <resolv.h> | 70 | #include <arpa/nameser.h> |
| 71 | |||
| 62 | #include <stdio.h> | 72 | #include <stdio.h> |
| 73 | #include <resolv.h> | ||
| 63 | #include <ctype.h> | 74 | #include <ctype.h> |
| 75 | |||
| 64 | #include <unistd.h> | 76 | #include <unistd.h> |
| 65 | #include <string.h> | 77 | #include <string.h> |
| 66 | 78 | ||
| 67 | static int dn_find __P((u_char *, u_char *, u_char **, u_char **)); | 79 | static int dn_find __P((u_char *exp_dn, u_char *msg, |
| 80 | u_char **dnptrs, u_char **lastdnptr)); | ||
| 68 | 81 | ||
| 69 | /* | 82 | /* |
| 70 | * Expand compressed domain name 'comp_dn' to full domain name. | 83 | * Expand compressed domain name 'comp_dn' to full domain name. |
| @@ -106,7 +119,7 @@ dn_expand(msg, eomorig, comp_dn, exp_dn, length) | |||
| 106 | return (-1); | 119 | return (-1); |
| 107 | checked += n + 1; | 120 | checked += n + 1; |
| 108 | while (--n >= 0) { | 121 | while (--n >= 0) { |
| 109 | if ((c = *cp++) == '.' || c == '\\') { | 122 | if (((c = *cp++) == '.') || (c == '\\')) { |
| 110 | if (dn + n + 2 >= eom) | 123 | if (dn + n + 2 >= eom) |
| 111 | return (-1); | 124 | return (-1); |
| 112 | *dn++ = '\\'; | 125 | *dn++ = '\\'; |
| @@ -138,9 +151,6 @@ dn_expand(msg, eomorig, comp_dn, exp_dn, length) | |||
| 138 | } | 151 | } |
| 139 | } | 152 | } |
| 140 | *dn = '\0'; | 153 | *dn = '\0'; |
| 141 | for (dn = exp_dn; (c = *dn) != '\0'; dn++) | ||
| 142 | if (isascii(c) && isspace(c)) | ||
| 143 | return (-1); | ||
| 144 | if (len < 0) | 154 | if (len < 0) |
| 145 | len = cp - comp_dn; | 155 | len = cp - comp_dn; |
| 146 | return (len); | 156 | return (len); |
| @@ -263,7 +273,7 @@ __dn_skipname(comp_dn, eom) | |||
| 263 | break; | 273 | break; |
| 264 | } | 274 | } |
| 265 | if (cp > eom) | 275 | if (cp > eom) |
| 266 | return -1; | 276 | return (-1); |
| 267 | return (cp - comp_dn); | 277 | return (cp - comp_dn); |
| 268 | } | 278 | } |
| 269 | 279 | ||
| @@ -330,14 +340,122 @@ dn_find(exp_dn, msg, dnptrs, lastdnptr) | |||
| 330 | } | 340 | } |
| 331 | 341 | ||
| 332 | /* | 342 | /* |
| 333 | * Routines to insert/extract short/long's. Must account for byte | 343 | * Verify that a domain name uses an acceptable character set. |
| 334 | * order and non-alignment problems. This code at least has the | ||
| 335 | * advantage of being portable. | ||
| 336 | * | ||
| 337 | * used by sendmail. | ||
| 338 | */ | 344 | */ |
| 339 | 345 | ||
| 340 | u_short | 346 | /* |
| 347 | * Note the conspicuous absence of ctype macros in these definitions. On | ||
| 348 | * non-ASCII hosts, we can't depend on string literals or ctype macros to | ||
| 349 | * tell us anything about network-format data. The rest of the BIND system | ||
| 350 | * is not careful about this, but for some reason, we're doing it right here. | ||
| 351 | */ | ||
| 352 | #define PERIOD 0x2e | ||
| 353 | #define hyphenchar(c) ((c) == 0x2d) | ||
| 354 | #define bslashchar(c) ((c) == 0x5c) | ||
| 355 | #define periodchar(c) ((c) == PERIOD) | ||
| 356 | #define asterchar(c) ((c) == 0x2a) | ||
| 357 | #define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \ | ||
| 358 | || ((c) >= 0x61 && (c) <= 0x7a)) | ||
| 359 | #define digitchar(c) ((c) >= 0x30 && (c) <= 0x39) | ||
| 360 | |||
| 361 | #define borderchar(c) (alphachar(c) || digitchar(c)) | ||
| 362 | #define middlechar(c) (borderchar(c) || hyphenchar(c)) | ||
| 363 | #define domainchar(c) ((c) > 0x20 && (c) < 0x7f) | ||
| 364 | |||
| 365 | int | ||
| 366 | res_hnok(dn) | ||
| 367 | const char *dn; | ||
| 368 | { | ||
| 369 | int ppch = '\0', pch = PERIOD, ch = *dn++; | ||
| 370 | |||
| 371 | while (ch != '\0') { | ||
| 372 | int nch = *dn++; | ||
| 373 | |||
| 374 | if (periodchar(ch)) { | ||
| 375 | NULL; | ||
| 376 | } else if (periodchar(pch)) { | ||
| 377 | if (!borderchar(ch)) | ||
| 378 | return (0); | ||
| 379 | } else if (periodchar(nch) || nch == '\0') { | ||
| 380 | if (!borderchar(ch)) | ||
| 381 | return (0); | ||
| 382 | } else { | ||
| 383 | if (!middlechar(ch)) | ||
| 384 | return (0); | ||
| 385 | } | ||
| 386 | ppch = pch, pch = ch, ch = nch; | ||
| 387 | } | ||
| 388 | return (1); | ||
| 389 | } | ||
| 390 | |||
| 391 | /* | ||
| 392 | * hostname-like (A, MX, WKS) owners can have "*" as their first label | ||
| 393 | * but must otherwise be as a host name. | ||
| 394 | */ | ||
| 395 | int | ||
| 396 | res_ownok(dn) | ||
| 397 | const char *dn; | ||
| 398 | { | ||
| 399 | if (asterchar(dn[0])) { | ||
| 400 | if (periodchar(dn[1])) | ||
| 401 | return (res_hnok(dn+2)); | ||
| 402 | if (dn[1] == '\0') | ||
| 403 | return (1); | ||
| 404 | } | ||
| 405 | return (res_hnok(dn)); | ||
| 406 | } | ||
| 407 | |||
| 408 | /* | ||
| 409 | * SOA RNAMEs and RP RNAMEs can have any printable character in their first | ||
| 410 | * label, but the rest of the name has to look like a host name. | ||
| 411 | */ | ||
| 412 | int | ||
| 413 | res_mailok(dn) | ||
| 414 | const char *dn; | ||
| 415 | { | ||
| 416 | int ch, escaped = 0; | ||
| 417 | |||
| 418 | /* "." is a valid missing representation */ | ||
| 419 | if (*dn == '\0') | ||
| 420 | return(1); | ||
| 421 | |||
| 422 | /* otherwise <label>.<hostname> */ | ||
| 423 | while ((ch = *dn++) != '\0') { | ||
| 424 | if (!domainchar(ch)) | ||
| 425 | return (0); | ||
| 426 | if (!escaped && periodchar(ch)) | ||
| 427 | break; | ||
| 428 | if (escaped) | ||
| 429 | escaped = 0; | ||
| 430 | else if (bslashchar(ch)) | ||
| 431 | escaped = 1; | ||
| 432 | } | ||
| 433 | if (periodchar(ch)) | ||
| 434 | return (res_hnok(dn)); | ||
| 435 | return(0); | ||
| 436 | } | ||
| 437 | |||
| 438 | /* | ||
| 439 | * This function is quite liberal, since RFC 1034's character sets are only | ||
| 440 | * recommendations. | ||
| 441 | */ | ||
| 442 | int | ||
| 443 | res_dnok(dn) | ||
| 444 | const char *dn; | ||
| 445 | { | ||
| 446 | int ch; | ||
| 447 | |||
| 448 | while ((ch = *dn++) != '\0') | ||
| 449 | if (!domainchar(ch)) | ||
| 450 | return (0); | ||
| 451 | return (1); | ||
| 452 | } | ||
| 453 | |||
| 454 | /* | ||
| 455 | * Routines to insert/extract short/long's. | ||
| 456 | */ | ||
| 457 | |||
| 458 | u_int16_t | ||
| 341 | _getshort(msgp) | 459 | _getshort(msgp) |
| 342 | register const u_char *msgp; | 460 | register const u_char *msgp; |
| 343 | { | 461 | { |
| @@ -347,6 +465,18 @@ _getshort(msgp) | |||
| 347 | return (u); | 465 | return (u); |
| 348 | } | 466 | } |
| 349 | 467 | ||
| 468 | #ifdef NeXT | ||
| 469 | /* | ||
| 470 | * nExt machines have some funky library conventions, which we must maintain. | ||
| 471 | */ | ||
| 472 | u_int16_t | ||
| 473 | res_getshort(msgp) | ||
| 474 | register const u_char *msgp; | ||
| 475 | { | ||
| 476 | return (_getshort(msgp)); | ||
| 477 | } | ||
| 478 | #endif | ||
| 479 | |||
| 350 | u_int32_t | 480 | u_int32_t |
| 351 | _getlong(msgp) | 481 | _getlong(msgp) |
| 352 | register const u_char *msgp; | 482 | register const u_char *msgp; |
| @@ -359,7 +489,7 @@ _getlong(msgp) | |||
| 359 | 489 | ||
| 360 | void | 490 | void |
| 361 | #if defined(__STDC__) || defined(__cplusplus) | 491 | #if defined(__STDC__) || defined(__cplusplus) |
| 362 | __putshort(register u_int16_t s, register u_char *msgp) | 492 | __putshort(register u_int16_t s, register u_char *msgp) /* must match proto */ |
| 363 | #else | 493 | #else |
| 364 | __putshort(s, msgp) | 494 | __putshort(s, msgp) |
| 365 | register u_int16_t s; | 495 | register u_int16_t s; |
diff --git a/src/lib/libc/net/res_data.c b/src/lib/libc/net/res_data.c new file mode 100644 index 0000000000..b0d19c36bb --- /dev/null +++ b/src/lib/libc/net/res_data.c | |||
| @@ -0,0 +1,117 @@ | |||
| 1 | /* $OpenBSD: res_data.c,v 1.1 1997/03/13 19:07:36 downsj Exp $ */ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * ++Copyright++ 1995 | ||
| 5 | * - | ||
| 6 | * Copyright (c) 1995 | ||
| 7 | * The Regents of the University of California. All rights reserved. | ||
| 8 | * | ||
| 9 | * Redistribution and use in source and binary forms, with or without | ||
| 10 | * modification, are permitted provided that the following conditions | ||
| 11 | * are met: | ||
| 12 | * 1. Redistributions of source code must retain the above copyright | ||
| 13 | * notice, this list of conditions and the following disclaimer. | ||
| 14 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 15 | * notice, this list of conditions and the following disclaimer in the | ||
| 16 | * documentation and/or other materials provided with the distribution. | ||
| 17 | * 3. All advertising materials mentioning features or use of this software | ||
| 18 | * must display the following acknowledgement: | ||
| 19 | * This product includes software developed by the University of | ||
| 20 | * California, Berkeley and its contributors. | ||
| 21 | * 4. Neither the name of the University nor the names of its contributors | ||
| 22 | * may be used to endorse or promote products derived from this software | ||
| 23 | * without specific prior written permission. | ||
| 24 | * | ||
| 25 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
| 26 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 27 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 28 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
| 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 31 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 32 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 33 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 34 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 35 | * SUCH DAMAGE. | ||
| 36 | * - | ||
| 37 | * Portions Copyright (c) 1993 by Digital Equipment Corporation. | ||
| 38 | * | ||
| 39 | * Permission to use, copy, modify, and distribute this software for any | ||
| 40 | * purpose with or without fee is hereby granted, provided that the above | ||
| 41 | * copyright notice and this permission notice appear in all copies, and that | ||
| 42 | * the name of Digital Equipment Corporation not be used in advertising or | ||
| 43 | * publicity pertaining to distribution of the document or software without | ||
| 44 | * specific, written prior permission. | ||
| 45 | * | ||
| 46 | * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL | ||
| 47 | * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES | ||
| 48 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT | ||
| 49 | * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | ||
| 50 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | ||
| 51 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | ||
| 52 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | ||
| 53 | * SOFTWARE. | ||
| 54 | * - | ||
| 55 | * --Copyright-- | ||
| 56 | */ | ||
| 57 | |||
| 58 | #if defined(LIBC_SCCS) && !defined(lint) | ||
| 59 | #if 0 | ||
| 60 | static char rcsid[] = "$From: res_data.c,v 8.2 1996/08/05 08:31:35 vixie Exp $"; | ||
| 61 | #else | ||
| 62 | static char rcsid[] = "$OpenBSD: res_data.c,v 1.1 1997/03/13 19:07:36 downsj Exp $"; | ||
| 63 | #endif | ||
| 64 | #endif /* LIBC_SCCS and not lint */ | ||
| 65 | |||
| 66 | #include <sys/types.h> | ||
| 67 | #include <sys/param.h> | ||
| 68 | #include <sys/socket.h> | ||
| 69 | #include <sys/time.h> | ||
| 70 | #include <netinet/in.h> | ||
| 71 | #include <arpa/inet.h> | ||
| 72 | #include <arpa/nameser.h> | ||
| 73 | |||
| 74 | #include <stdio.h> | ||
| 75 | #include <ctype.h> | ||
| 76 | #include <resolv.h> | ||
| 77 | #include <unistd.h> | ||
| 78 | #include <stdlib.h> | ||
| 79 | #include <string.h> | ||
| 80 | |||
| 81 | const char *_res_opcodes[] = { | ||
| 82 | "QUERY", | ||
| 83 | "IQUERY", | ||
| 84 | "CQUERYM", | ||
| 85 | "CQUERYU", /* experimental */ | ||
| 86 | "NOTIFY", /* experimental */ | ||
| 87 | "5", | ||
| 88 | "6", | ||
| 89 | "7", | ||
| 90 | "8", | ||
| 91 | "UPDATEA", | ||
| 92 | "UPDATED", | ||
| 93 | "UPDATEDA", | ||
| 94 | "UPDATEM", | ||
| 95 | "UPDATEMA", | ||
| 96 | "ZONEINIT", | ||
| 97 | "ZONEREF", | ||
| 98 | }; | ||
| 99 | |||
| 100 | const char *_res_resultcodes[] = { | ||
| 101 | "NOERROR", | ||
| 102 | "FORMERR", | ||
| 103 | "SERVFAIL", | ||
| 104 | "NXDOMAIN", | ||
| 105 | "NOTIMP", | ||
| 106 | "REFUSED", | ||
| 107 | "6", | ||
| 108 | "7", | ||
| 109 | "8", | ||
| 110 | "9", | ||
| 111 | "10", | ||
| 112 | "11", | ||
| 113 | "12", | ||
| 114 | "13", | ||
| 115 | "14", | ||
| 116 | "NOCHANGE", | ||
| 117 | }; | ||
diff --git a/src/lib/libc/net/res_debug.c b/src/lib/libc/net/res_debug.c index ae6c030a1f..7fd6d4a21c 100644 --- a/src/lib/libc/net/res_debug.c +++ b/src/lib/libc/net/res_debug.c | |||
| @@ -1,7 +1,11 @@ | |||
| 1 | /*- | 1 | /* $OpenBSD: res_debug.c,v 1.5 1997/03/13 19:07:37 downsj Exp $ */ |
| 2 | |||
| 3 | /* | ||
| 4 | * ++Copyright++ 1985, 1990, 1993 | ||
| 5 | * - | ||
| 2 | * Copyright (c) 1985, 1990, 1993 | 6 | * Copyright (c) 1985, 1990, 1993 |
| 3 | * The Regents of the University of California. All rights reserved. | 7 | * The Regents of the University of California. All rights reserved. |
| 4 | * | 8 | * |
| 5 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions |
| 7 | * are met: | 11 | * are met: |
| @@ -48,63 +52,61 @@ | |||
| 48 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | 52 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS |
| 49 | * SOFTWARE. | 53 | * SOFTWARE. |
| 50 | * - | 54 | * - |
| 55 | * Portions Copyright (c) 1995 by International Business Machines, Inc. | ||
| 56 | * | ||
| 57 | * International Business Machines, Inc. (hereinafter called IBM) grants | ||
| 58 | * permission under its copyrights to use, copy, modify, and distribute this | ||
| 59 | * Software with or without fee, provided that the above copyright notice and | ||
| 60 | * all paragraphs of this notice appear in all copies, and that the name of IBM | ||
| 61 | * not be used in connection with the marketing of any product incorporating | ||
| 62 | * the Software or modifications thereof, without specific, written prior | ||
| 63 | * permission. | ||
| 64 | * | ||
| 65 | * To the extent it has a right to do so, IBM grants an immunity from suit | ||
| 66 | * under its patents, if any, for the use, sale or manufacture of products to | ||
| 67 | * the extent that such products are used for performing Domain Name System | ||
| 68 | * dynamic updates in TCP/IP networks by means of the Software. No immunity is | ||
| 69 | * granted for any product per se or for any other function of any product. | ||
| 70 | * | ||
| 71 | * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, | ||
| 72 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | ||
| 73 | * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, | ||
| 74 | * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING | ||
| 75 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN | ||
| 76 | * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. | ||
| 51 | * --Copyright-- | 77 | * --Copyright-- |
| 52 | */ | 78 | */ |
| 53 | 79 | ||
| 54 | #if defined(LIBC_SCCS) && !defined(lint) | 80 | #if defined(LIBC_SCCS) && !defined(lint) |
| 55 | static char rcsid[] = "$OpenBSD: res_debug.c,v 1.4 1996/09/15 09:31:18 tholo Exp $"; | 81 | #if 0 |
| 82 | static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93"; | ||
| 83 | static char rcsid[] = "$From: res_debug.c,v 8.19 1996/11/26 10:11:23 vixie Exp $"; | ||
| 84 | #else | ||
| 85 | static char rcsid[] = "$OpenBSD: res_debug.c,v 1.5 1997/03/13 19:07:37 downsj Exp $"; | ||
| 86 | #endif | ||
| 56 | #endif /* LIBC_SCCS and not lint */ | 87 | #endif /* LIBC_SCCS and not lint */ |
| 57 | 88 | ||
| 58 | #include <sys/param.h> | 89 | #include <sys/param.h> |
| 90 | #include <sys/types.h> | ||
| 91 | #include <sys/socket.h> | ||
| 59 | #include <netinet/in.h> | 92 | #include <netinet/in.h> |
| 60 | #include <arpa/inet.h> | 93 | #include <arpa/inet.h> |
| 61 | #include <arpa/nameser.h> | 94 | #include <arpa/nameser.h> |
| 95 | |||
| 96 | #include <ctype.h> | ||
| 97 | #include <netdb.h> | ||
| 62 | #include <resolv.h> | 98 | #include <resolv.h> |
| 63 | #include <stdio.h> | 99 | #include <stdio.h> |
| 100 | #include <time.h> | ||
| 101 | |||
| 102 | #include <stdlib.h> | ||
| 64 | #include <string.h> | 103 | #include <string.h> |
| 65 | #include <netdb.h> | ||
| 66 | 104 | ||
| 67 | void __fp_query(); | 105 | extern const char *_res_opcodes[]; |
| 68 | 106 | extern const char *_res_resultcodes[]; | |
| 69 | char *_res_opcodes[] = { | ||
| 70 | "QUERY", | ||
| 71 | "IQUERY", | ||
| 72 | "CQUERYM", | ||
| 73 | "CQUERYU", /* experimental */ | ||
| 74 | "NOTIFY", /* experimental */ | ||
| 75 | "5", | ||
| 76 | "6", | ||
| 77 | "7", | ||
| 78 | "8", | ||
| 79 | "UPDATEA", | ||
| 80 | "UPDATED", | ||
| 81 | "UPDATEDA", | ||
| 82 | "UPDATEM", | ||
| 83 | "UPDATEMA", | ||
| 84 | "ZONEINIT", | ||
| 85 | "ZONEREF", | ||
| 86 | }; | ||
| 87 | 107 | ||
| 88 | char *_res_resultcodes[] = { | 108 | /* XXX: we should use getservbyport() instead. */ |
| 89 | "NOERROR", | 109 | static const char * |
| 90 | "FORMERR", | ||
| 91 | "SERVFAIL", | ||
| 92 | "NXDOMAIN", | ||
| 93 | "NOTIMP", | ||
| 94 | "REFUSED", | ||
| 95 | "6", | ||
| 96 | "7", | ||
| 97 | "8", | ||
| 98 | "9", | ||
| 99 | "10", | ||
| 100 | "11", | ||
| 101 | "12", | ||
| 102 | "13", | ||
| 103 | "14", | ||
| 104 | "NOCHANGE", | ||
| 105 | }; | ||
| 106 | |||
| 107 | static char * | ||
| 108 | dewks(wks) | 110 | dewks(wks) |
| 109 | int wks; | 111 | int wks; |
| 110 | { | 112 | { |
| @@ -200,7 +202,8 @@ do_rrset(msg, len, cp, cnt, pflag, file, hs) | |||
| 200 | */ | 202 | */ |
| 201 | sflag = (_res.pfcode & pflag); | 203 | sflag = (_res.pfcode & pflag); |
| 202 | if (n = ntohs(cnt)) { | 204 | if (n = ntohs(cnt)) { |
| 203 | if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) | 205 | if ((!_res.pfcode) || |
| 206 | ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) | ||
| 204 | fprintf(file, hs); | 207 | fprintf(file, hs); |
| 205 | while (--n >= 0) { | 208 | while (--n >= 0) { |
| 206 | if ((!_res.pfcode) || sflag) { | 209 | if ((!_res.pfcode) || sflag) { |
| @@ -208,20 +211,21 @@ do_rrset(msg, len, cp, cnt, pflag, file, hs) | |||
| 208 | } else { | 211 | } else { |
| 209 | unsigned int dlen; | 212 | unsigned int dlen; |
| 210 | cp += __dn_skipname(cp, cp + MAXCDNAME); | 213 | cp += __dn_skipname(cp, cp + MAXCDNAME); |
| 211 | cp += sizeof(u_int16_t); | 214 | cp += INT16SZ; |
| 212 | cp += sizeof(u_int16_t); | 215 | cp += INT16SZ; |
| 213 | cp += sizeof(u_int32_t); | 216 | cp += INT32SZ; |
| 214 | dlen = _getshort((u_char*)cp); | 217 | dlen = _getshort((u_char*)cp); |
| 215 | cp += sizeof(u_int16_t); | 218 | cp += INT16SZ; |
| 216 | cp += dlen; | 219 | cp += dlen; |
| 217 | } | 220 | } |
| 218 | if ((cp - msg) > len) | 221 | if ((cp - msg) > len) |
| 219 | return (NULL); | 222 | return (NULL); |
| 220 | } | 223 | } |
| 221 | if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) | 224 | if ((!_res.pfcode) || |
| 225 | ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) | ||
| 222 | putc('\n', file); | 226 | putc('\n', file); |
| 223 | } | 227 | } |
| 224 | return(cp); | 228 | return (cp); |
| 225 | } | 229 | } |
| 226 | 230 | ||
| 227 | void | 231 | void |
| @@ -268,7 +272,7 @@ __fp_nquery(msg, len, file) | |||
| 268 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) | 272 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) |
| 269 | return; | 273 | return; |
| 270 | 274 | ||
| 271 | #define TruncTest(x) if (x >= endMark) goto trunc | 275 | #define TruncTest(x) if (x > endMark) goto trunc |
| 272 | #define ErrorTest(x) if (x == NULL) goto error | 276 | #define ErrorTest(x) if (x == NULL) goto error |
| 273 | 277 | ||
| 274 | /* | 278 | /* |
| @@ -276,9 +280,9 @@ __fp_nquery(msg, len, file) | |||
| 276 | */ | 280 | */ |
| 277 | hp = (HEADER *)msg; | 281 | hp = (HEADER *)msg; |
| 278 | cp = msg + HFIXEDSZ; | 282 | cp = msg + HFIXEDSZ; |
| 279 | endMark = cp + len; | 283 | endMark = msg + len; |
| 280 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) { | 284 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) { |
| 281 | fprintf(file,";; ->>HEADER<<- opcode: %s, status: %s, id: %d", | 285 | fprintf(file, ";; ->>HEADER<<- opcode: %s, status: %s, id: %d", |
| 282 | _res_opcodes[hp->opcode], | 286 | _res_opcodes[hp->opcode], |
| 283 | _res_resultcodes[hp->rcode], | 287 | _res_resultcodes[hp->rcode], |
| 284 | ntohs(hp->id)); | 288 | ntohs(hp->id)); |
| @@ -287,22 +291,28 @@ __fp_nquery(msg, len, file) | |||
| 287 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX)) | 291 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX)) |
| 288 | putc(';', file); | 292 | putc(';', file); |
| 289 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) { | 293 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) { |
| 290 | fprintf(file,"; flags:"); | 294 | fprintf(file, "; flags:"); |
| 291 | if (hp->qr) | 295 | if (hp->qr) |
| 292 | fprintf(file," qr"); | 296 | fprintf(file, " qr"); |
| 293 | if (hp->aa) | 297 | if (hp->aa) |
| 294 | fprintf(file," aa"); | 298 | fprintf(file, " aa"); |
| 295 | if (hp->tc) | 299 | if (hp->tc) |
| 296 | fprintf(file," tc"); | 300 | fprintf(file, " tc"); |
| 297 | if (hp->rd) | 301 | if (hp->rd) |
| 298 | fprintf(file," rd"); | 302 | fprintf(file, " rd"); |
| 299 | if (hp->ra) | 303 | if (hp->ra) |
| 300 | fprintf(file," ra"); | 304 | fprintf(file, " ra"); |
| 305 | if (hp->unused) | ||
| 306 | fprintf(file, " UNUSED-BIT-ON"); | ||
| 307 | if (hp->ad) | ||
| 308 | fprintf(file, " ad"); | ||
| 309 | if (hp->cd) | ||
| 310 | fprintf(file, " cd"); | ||
| 301 | } | 311 | } |
| 302 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) { | 312 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) { |
| 303 | fprintf(file,"; Ques: %d", ntohs(hp->qdcount)); | 313 | fprintf(file, "; Ques: %d", ntohs(hp->qdcount)); |
| 304 | fprintf(file,", Ans: %d", ntohs(hp->ancount)); | 314 | fprintf(file, ", Ans: %d", ntohs(hp->ancount)); |
| 305 | fprintf(file,", Auth: %d", ntohs(hp->nscount)); | 315 | fprintf(file, ", Auth: %d", ntohs(hp->nscount)); |
| 306 | fprintf(file, ", Addit: %d", ntohs(hp->arcount)); | 316 | fprintf(file, ", Addit: %d", ntohs(hp->arcount)); |
| 307 | } | 317 | } |
| 308 | if ((!_res.pfcode) || (_res.pfcode & | 318 | if ((!_res.pfcode) || (_res.pfcode & |
| @@ -314,10 +324,10 @@ __fp_nquery(msg, len, file) | |||
| 314 | */ | 324 | */ |
| 315 | if (n = ntohs(hp->qdcount)) { | 325 | if (n = ntohs(hp->qdcount)) { |
| 316 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) | 326 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) |
| 317 | fprintf(file,";; QUESTIONS:\n"); | 327 | fprintf(file, ";; QUESTIONS:\n"); |
| 318 | while (--n >= 0) { | 328 | while (--n >= 0) { |
| 319 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) | 329 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) |
| 320 | fprintf(file,";;\t"); | 330 | fprintf(file, ";;\t"); |
| 321 | TruncTest(cp); | 331 | TruncTest(cp); |
| 322 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) | 332 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) |
| 323 | cp = p_cdnname(cp, msg, len, file); | 333 | cp = p_cdnname(cp, msg, len, file); |
| @@ -372,7 +382,7 @@ __fp_nquery(msg, len, file) | |||
| 372 | return; | 382 | return; |
| 373 | trunc: | 383 | trunc: |
| 374 | fprintf(file, "\n;; ...truncated\n"); | 384 | fprintf(file, "\n;; ...truncated\n"); |
| 375 | return; | 385 | return; |
| 376 | error: | 386 | error: |
| 377 | fprintf(file, "\n;; ...malformed\n"); | 387 | fprintf(file, "\n;; ...malformed\n"); |
| 378 | } | 388 | } |
| @@ -411,6 +421,30 @@ __p_cdname(cp, msg, file) | |||
| 411 | return (p_cdnname(cp, msg, PACKETSZ, file)); | 421 | return (p_cdnname(cp, msg, PACKETSZ, file)); |
| 412 | } | 422 | } |
| 413 | 423 | ||
| 424 | |||
| 425 | /* Return a fully-qualified domain name from a compressed name (with | ||
| 426 | length supplied). */ | ||
| 427 | |||
| 428 | const u_char * | ||
| 429 | __p_fqnname(cp, msg, msglen, name, namelen) | ||
| 430 | const u_char *cp, *msg; | ||
| 431 | int msglen; | ||
| 432 | char *name; | ||
| 433 | int namelen; | ||
| 434 | { | ||
| 435 | int n, newlen; | ||
| 436 | |||
| 437 | if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0) | ||
| 438 | return (NULL); | ||
| 439 | newlen = strlen (name); | ||
| 440 | if (newlen == 0 || name[newlen - 1] != '.') | ||
| 441 | if (newlen+1 >= namelen) /* Lack space for final dot */ | ||
| 442 | return (NULL); | ||
| 443 | else | ||
| 444 | strcpy(name + newlen, "."); | ||
| 445 | return (cp + n); | ||
| 446 | } | ||
| 447 | |||
| 414 | /* XXX: the rest of these functions need to become length-limited, too. (vix) | 448 | /* XXX: the rest of these functions need to become length-limited, too. (vix) |
| 415 | */ | 449 | */ |
| 416 | 450 | ||
| @@ -420,18 +454,13 @@ __p_fqname(cp, msg, file) | |||
| 420 | FILE *file; | 454 | FILE *file; |
| 421 | { | 455 | { |
| 422 | char name[MAXDNAME]; | 456 | char name[MAXDNAME]; |
| 423 | int n; | 457 | const u_char *n; |
| 424 | 458 | ||
| 425 | if ((n = dn_expand(msg, cp + MAXCDNAME, cp, name, sizeof name)) < 0) | 459 | n = __p_fqnname(cp, msg, MAXCDNAME, name, sizeof name); |
| 460 | if (n == NULL) | ||
| 426 | return (NULL); | 461 | return (NULL); |
| 427 | if (name[0] == '\0') { | 462 | fputs(name, file); |
| 428 | putc('.', file); | 463 | return (n); |
| 429 | } else { | ||
| 430 | fputs(name, file); | ||
| 431 | if (name[strlen(name) - 1] != '.') | ||
| 432 | putc('.', file); | ||
| 433 | } | ||
| 434 | return (cp + n); | ||
| 435 | } | 464 | } |
| 436 | 465 | ||
| 437 | /* | 466 | /* |
| @@ -447,21 +476,27 @@ __p_rr(cp, msg, file) | |||
| 447 | const u_char *cp1, *cp2; | 476 | const u_char *cp1, *cp2; |
| 448 | u_int32_t tmpttl, t; | 477 | u_int32_t tmpttl, t; |
| 449 | int lcnt; | 478 | int lcnt; |
| 479 | u_int16_t keyflags; | ||
| 480 | char rrname[MAXDNAME]; /* The fqdn of this RR */ | ||
| 481 | char base64_key[MAX_KEY_BASE64]; | ||
| 450 | 482 | ||
| 451 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) { | 483 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) { |
| 452 | h_errno = NETDB_INTERNAL; | 484 | h_errno = NETDB_INTERNAL; |
| 453 | return (NULL); | 485 | return (NULL); |
| 454 | } | 486 | } |
| 455 | if ((cp = p_fqname(cp, msg, file)) == NULL) | 487 | cp = __p_fqnname(cp, msg, MAXCDNAME, rrname, sizeof rrname); |
| 488 | if (!cp) | ||
| 456 | return (NULL); /* compression error */ | 489 | return (NULL); /* compression error */ |
| 457 | type = _getshort(cp); | 490 | fputs(rrname, file); |
| 458 | cp += sizeof(u_int16_t); | 491 | |
| 459 | class = _getshort(cp); | 492 | type = _getshort((u_char*)cp); |
| 460 | cp += sizeof(u_int16_t); | 493 | cp += INT16SZ; |
| 461 | tmpttl = _getlong(cp); | 494 | class = _getshort((u_char*)cp); |
| 462 | cp += sizeof(u_int32_t); | 495 | cp += INT16SZ; |
| 463 | dlen = _getshort(cp); | 496 | tmpttl = _getlong((u_char*)cp); |
| 464 | cp += sizeof(u_int16_t); | 497 | cp += INT32SZ; |
| 498 | dlen = _getshort((u_char*)cp); | ||
| 499 | cp += INT16SZ; | ||
| 465 | cp1 = cp; | 500 | cp1 = cp; |
| 466 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID)) | 501 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID)) |
| 467 | fprintf(file, "\t%lu", (u_long)tmpttl); | 502 | fprintf(file, "\t%lu", (u_long)tmpttl); |
| @@ -476,9 +511,9 @@ __p_rr(cp, msg, file) | |||
| 476 | switch (class) { | 511 | switch (class) { |
| 477 | case C_IN: | 512 | case C_IN: |
| 478 | case C_HS: | 513 | case C_HS: |
| 479 | bcopy(cp, (char *)&inaddr, sizeof(inaddr)); | 514 | bcopy(cp, (char *)&inaddr, INADDRSZ); |
| 480 | if (dlen == 4) { | 515 | if (dlen == 4) { |
| 481 | fprintf(file,"\t%s", inet_ntoa(inaddr)); | 516 | fprintf(file, "\t%s", inet_ntoa(inaddr)); |
| 482 | cp += dlen; | 517 | cp += dlen; |
| 483 | } else if (dlen == 7) { | 518 | } else if (dlen == 7) { |
| 484 | char *address; | 519 | char *address; |
| @@ -486,11 +521,11 @@ __p_rr(cp, msg, file) | |||
| 486 | u_short port; | 521 | u_short port; |
| 487 | 522 | ||
| 488 | address = inet_ntoa(inaddr); | 523 | address = inet_ntoa(inaddr); |
| 489 | cp += sizeof(inaddr); | 524 | cp += INADDRSZ; |
| 490 | protocol = *cp; | 525 | protocol = *(u_char*)cp; |
| 491 | cp += sizeof(u_char); | 526 | cp += sizeof (u_char); |
| 492 | port = _getshort(cp); | 527 | port = _getshort((u_char*)cp); |
| 493 | cp += sizeof(u_int16_t); | 528 | cp += INT16SZ; |
| 494 | fprintf(file, "\t%s\t; proto %d, port %d", | 529 | fprintf(file, "\t%s\t; proto %d, port %d", |
| 495 | address, protocol, port); | 530 | address, protocol, port); |
| 496 | } | 531 | } |
| @@ -513,15 +548,27 @@ __p_rr(cp, msg, file) | |||
| 513 | case T_HINFO: | 548 | case T_HINFO: |
| 514 | case T_ISDN: | 549 | case T_ISDN: |
| 515 | cp2 = cp + dlen; | 550 | cp2 = cp + dlen; |
| 516 | if (n = *cp++) { | 551 | (void) fputs("\t\"", file); |
| 517 | fprintf(file,"\t%.*s", n, cp); | 552 | if ((n = (unsigned char) *cp++) != 0) { |
| 518 | cp += n; | 553 | for (c = n; c > 0 && cp < cp2; c--) { |
| 554 | if (strchr("\n\"\\", *cp)) | ||
| 555 | (void) putc('\\', file); | ||
| 556 | (void) putc(*cp++, file); | ||
| 557 | } | ||
| 519 | } | 558 | } |
| 520 | if ((cp < cp2) && (n = *cp++)) { | 559 | putc('"', file); |
| 521 | fprintf(file,"\t%.*s", n, cp); | 560 | if (cp < cp2 && (n = (unsigned char) *cp++) != 0) { |
| 522 | cp += n; | 561 | (void) fputs ("\t\"", file); |
| 523 | } else if (type == T_HINFO) | 562 | for (c = n; c > 0 && cp < cp2; c--) { |
| 563 | if (strchr("\n\"\\", *cp)) | ||
| 564 | (void) putc('\\', file); | ||
| 565 | (void) putc(*cp++, file); | ||
| 566 | } | ||
| 567 | putc('"', file); | ||
| 568 | } else if (type == T_HINFO) { | ||
| 569 | (void) fputs("\"?\"", file); | ||
| 524 | fprintf(file, "\n;; *** Warning *** OS-type missing"); | 570 | fprintf(file, "\n;; *** Warning *** OS-type missing"); |
| 571 | } | ||
| 525 | break; | 572 | break; |
| 526 | 573 | ||
| 527 | case T_SOA: | 574 | case T_SOA: |
| @@ -532,18 +579,18 @@ __p_rr(cp, msg, file) | |||
| 532 | if ((cp = p_fqname(cp, msg, file)) == NULL) | 579 | if ((cp = p_fqname(cp, msg, file)) == NULL) |
| 533 | return (NULL); | 580 | return (NULL); |
| 534 | fputs(" (\n", file); | 581 | fputs(" (\n", file); |
| 535 | t = _getlong(cp); cp += sizeof(u_int32_t); | 582 | t = _getlong((u_char*)cp); cp += INT32SZ; |
| 536 | fprintf(file, "\t\t\t%lu\t; serial\n", (u_long)t); | 583 | fprintf(file, "\t\t\t%lu\t; serial\n", (u_long)t); |
| 537 | t = _getlong(cp); cp += sizeof(u_int32_t); | 584 | t = _getlong((u_char*)cp); cp += INT32SZ; |
| 538 | fprintf(file, "\t\t\t%lu\t; refresh (%s)\n", | 585 | fprintf(file, "\t\t\t%lu\t; refresh (%s)\n", |
| 539 | (u_long)t, __p_time(t)); | 586 | (u_long)t, __p_time(t)); |
| 540 | t = _getlong(cp); cp += sizeof(u_int32_t); | 587 | t = _getlong((u_char*)cp); cp += INT32SZ; |
| 541 | fprintf(file, "\t\t\t%lu\t; retry (%s)\n", | 588 | fprintf(file, "\t\t\t%lu\t; retry (%s)\n", |
| 542 | (u_long)t, __p_time(t)); | 589 | (u_long)t, __p_time(t)); |
| 543 | t = _getlong(cp); cp += sizeof(u_int32_t); | 590 | t = _getlong((u_char*)cp); cp += INT32SZ; |
| 544 | fprintf(file, "\t\t\t%lu\t; expire (%s)\n", | 591 | fprintf(file, "\t\t\t%lu\t; expire (%s)\n", |
| 545 | (u_long)t, __p_time(t)); | 592 | (u_long)t, __p_time(t)); |
| 546 | t = _getlong(cp); cp += sizeof(u_int32_t); | 593 | t = _getlong((u_char*)cp); cp += INT32SZ; |
| 547 | fprintf(file, "\t\t\t%lu )\t; minimum (%s)", | 594 | fprintf(file, "\t\t\t%lu )\t; minimum (%s)", |
| 548 | (u_long)t, __p_time(t)); | 595 | (u_long)t, __p_time(t)); |
| 549 | break; | 596 | break; |
| @@ -551,14 +598,14 @@ __p_rr(cp, msg, file) | |||
| 551 | case T_MX: | 598 | case T_MX: |
| 552 | case T_AFSDB: | 599 | case T_AFSDB: |
| 553 | case T_RT: | 600 | case T_RT: |
| 554 | fprintf(file, "\t%d ", _getshort(cp)); | 601 | fprintf(file, "\t%d ", _getshort((u_char*)cp)); |
| 555 | cp += INT16SZ; | 602 | cp += INT16SZ; |
| 556 | if ((cp = p_fqname(cp, msg, file)) == NULL) | 603 | if ((cp = p_fqname(cp, msg, file)) == NULL) |
| 557 | return (NULL); | 604 | return (NULL); |
| 558 | break; | 605 | break; |
| 559 | 606 | ||
| 560 | case T_PX: | 607 | case T_PX: |
| 561 | fprintf(file, "\t%d ", _getshort(cp)); | 608 | fprintf(file, "\t%d ", _getshort((u_char*)cp)); |
| 562 | cp += INT16SZ; | 609 | cp += INT16SZ; |
| 563 | if ((cp = p_fqname(cp, msg, file)) == NULL) | 610 | if ((cp = p_fqname(cp, msg, file)) == NULL) |
| 564 | return (NULL); | 611 | return (NULL); |
| @@ -567,28 +614,93 @@ __p_rr(cp, msg, file) | |||
| 567 | return (NULL); | 614 | return (NULL); |
| 568 | break; | 615 | break; |
| 569 | 616 | ||
| 570 | case T_TXT: | ||
| 571 | case T_X25: | 617 | case T_X25: |
| 618 | cp2 = cp + dlen; | ||
| 572 | (void) fputs("\t\"", file); | 619 | (void) fputs("\t\"", file); |
| 620 | if ((n = (unsigned char) *cp++) != 0) { | ||
| 621 | for (c = n; c > 0 && cp < cp2; c--) { | ||
| 622 | if (strchr("\n\"\\", *cp)) | ||
| 623 | (void) putc('\\', file); | ||
| 624 | (void) putc(*cp++, file); | ||
| 625 | } | ||
| 626 | } | ||
| 627 | putc('"', file); | ||
| 628 | break; | ||
| 629 | |||
| 630 | case T_TXT: | ||
| 631 | (void) putc('\t', file); | ||
| 573 | cp2 = cp1 + dlen; | 632 | cp2 = cp1 + dlen; |
| 574 | while (cp < cp2) { | 633 | while (cp < cp2) { |
| 634 | putc('"', file); | ||
| 575 | if (n = (unsigned char) *cp++) { | 635 | if (n = (unsigned char) *cp++) { |
| 576 | for (c = n; c > 0 && cp < cp2; c--) | 636 | for (c = n; c > 0 && cp < cp2; c--) { |
| 577 | if ((*cp == '\n') || (*cp == '"')) { | 637 | if (strchr("\n\"\\", *cp)) |
| 578 | (void) putc('\\', file); | 638 | (void) putc('\\', file); |
| 579 | (void) putc(*cp++, file); | 639 | (void) putc(*cp++, file); |
| 580 | } else | 640 | } |
| 581 | (void) putc(*cp++, file); | ||
| 582 | } | 641 | } |
| 642 | putc('"', file); | ||
| 643 | if (cp < cp2) | ||
| 644 | putc(' ', file); | ||
| 583 | } | 645 | } |
| 584 | putc('"', file); | 646 | break; |
| 585 | break; | ||
| 586 | 647 | ||
| 587 | case T_NSAP: | 648 | case T_NSAP: |
| 588 | (void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL)); | 649 | (void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL)); |
| 589 | cp += dlen; | 650 | cp += dlen; |
| 590 | break; | 651 | break; |
| 591 | 652 | ||
| 653 | case T_AAAA: { | ||
| 654 | char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; | ||
| 655 | |||
| 656 | fprintf(file, "\t%s", inet_ntop(AF_INET6, cp, t, sizeof t)); | ||
| 657 | cp += dlen; | ||
| 658 | break; | ||
| 659 | } | ||
| 660 | |||
| 661 | case T_LOC: { | ||
| 662 | char t[255]; | ||
| 663 | |||
| 664 | fprintf(file, "\t%s", loc_ntoa(cp, t)); | ||
| 665 | cp += dlen; | ||
| 666 | break; | ||
| 667 | } | ||
| 668 | |||
| 669 | case T_NAPTR: { | ||
| 670 | u_int order, preference; | ||
| 671 | |||
| 672 | order = _getshort(cp); cp += INT16SZ; | ||
| 673 | preference = _getshort(cp); cp += INT16SZ; | ||
| 674 | fprintf(file, "\t%u %u ",order, preference); | ||
| 675 | /* Flags */ | ||
| 676 | n = *cp++; | ||
| 677 | fprintf(file,"\"%.*s\" ", (int)n, cp); | ||
| 678 | cp += n; | ||
| 679 | /* Service */ | ||
| 680 | n = *cp++; | ||
| 681 | fprintf(file,"\"%.*s\" ", (int)n, cp); | ||
| 682 | cp += n; | ||
| 683 | /* Regexp */ | ||
| 684 | n = *cp++; | ||
| 685 | fprintf(file,"\"%.*s\" ", (int)n, cp); | ||
| 686 | cp += n; | ||
| 687 | if ((cp = p_fqname(cp, msg, file)) == NULL) | ||
| 688 | return (NULL); | ||
| 689 | break; | ||
| 690 | } | ||
| 691 | |||
| 692 | case T_SRV: { | ||
| 693 | u_int priority, weight, port; | ||
| 694 | |||
| 695 | priority = _getshort(cp); cp += INT16SZ; | ||
| 696 | weight = _getshort(cp); cp += INT16SZ; | ||
| 697 | port = _getshort(cp); cp += INT16SZ; | ||
| 698 | fprintf(file, "\t%u %u %u ", priority, weight, port); | ||
| 699 | if ((cp = p_fqname(cp, msg, file)) == NULL) | ||
| 700 | return (NULL); | ||
| 701 | break; | ||
| 702 | } | ||
| 703 | |||
| 592 | case T_MINFO: | 704 | case T_MINFO: |
| 593 | case T_RP: | 705 | case T_RP: |
| 594 | putc('\t', file); | 706 | putc('\t', file); |
| @@ -601,33 +713,33 @@ __p_rr(cp, msg, file) | |||
| 601 | 713 | ||
| 602 | case T_UINFO: | 714 | case T_UINFO: |
| 603 | putc('\t', file); | 715 | putc('\t', file); |
| 604 | fputs((char *) cp, file); | 716 | fputs((char *)cp, file); |
| 605 | cp += dlen; | 717 | cp += dlen; |
| 606 | break; | 718 | break; |
| 607 | 719 | ||
| 608 | case T_UID: | 720 | case T_UID: |
| 609 | case T_GID: | 721 | case T_GID: |
| 610 | if (dlen == 4) { | 722 | if (dlen == 4) { |
| 611 | fprintf(file,"\t%u", _getlong(cp)); | 723 | fprintf(file, "\t%u", _getlong((u_char*)cp)); |
| 612 | cp += sizeof(int32_t); | 724 | cp += INT32SZ; |
| 613 | } | 725 | } |
| 614 | break; | 726 | break; |
| 615 | 727 | ||
| 616 | case T_WKS: | 728 | case T_WKS: |
| 617 | if (dlen < sizeof(u_int32_t) + 1) | 729 | if (dlen < INT32SZ + 1) |
| 618 | break; | 730 | break; |
| 619 | bcopy(cp, (char *)&inaddr, sizeof(inaddr)); | 731 | bcopy(cp, (char *)&inaddr, INADDRSZ); |
| 620 | cp += sizeof(u_int32_t); | 732 | cp += INT32SZ; |
| 621 | fprintf(file, "\t%s %s ( ", | 733 | fprintf(file, "\t%s %s ( ", |
| 622 | inet_ntoa(inaddr), | 734 | inet_ntoa(inaddr), |
| 623 | deproto((int) *cp)); | 735 | deproto((int) *cp)); |
| 624 | cp += sizeof(u_char); | 736 | cp += sizeof (u_char); |
| 625 | n = 0; | 737 | n = 0; |
| 626 | lcnt = 0; | 738 | lcnt = 0; |
| 627 | while (cp < cp1 + dlen) { | 739 | while (cp < cp1 + dlen) { |
| 628 | c = *cp++; | 740 | c = *cp++; |
| 629 | do { | 741 | do { |
| 630 | if (c & 0200) { | 742 | if (c & 0200) { |
| 631 | if (lcnt == 0) { | 743 | if (lcnt == 0) { |
| 632 | fputs("\n\t\t\t", file); | 744 | fputs("\n\t\t\t", file); |
| 633 | lcnt = 5; | 745 | lcnt = 5; |
| @@ -636,12 +748,78 @@ __p_rr(cp, msg, file) | |||
| 636 | putc(' ', file); | 748 | putc(' ', file); |
| 637 | lcnt--; | 749 | lcnt--; |
| 638 | } | 750 | } |
| 639 | c <<= 1; | 751 | c <<= 1; |
| 640 | } while (++n & 07); | 752 | } while (++n & 07); |
| 641 | } | 753 | } |
| 642 | putc(')', file); | 754 | putc(')', file); |
| 643 | break; | 755 | break; |
| 644 | 756 | ||
| 757 | case T_KEY: | ||
| 758 | putc('\t', file); | ||
| 759 | keyflags = _getshort(cp); | ||
| 760 | cp += 2; | ||
| 761 | fprintf(file,"0x%04x", keyflags ); /* flags */ | ||
| 762 | fprintf(file," %u", *cp++); /* protocol */ | ||
| 763 | fprintf(file," %u (", *cp++); /* algorithm */ | ||
| 764 | |||
| 765 | n = b64_ntop(cp, (cp1 + dlen) - cp, | ||
| 766 | base64_key, sizeof base64_key); | ||
| 767 | for (c = 0; c < n; ++c) { | ||
| 768 | if (0 == (c & 0x3F)) | ||
| 769 | fprintf(file, "\n\t"); | ||
| 770 | putc(base64_key[c], file); /* public key data */ | ||
| 771 | } | ||
| 772 | |||
| 773 | fprintf(file, " )"); | ||
| 774 | if (n < 0) | ||
| 775 | fprintf(file, "\t; BAD BASE64"); | ||
| 776 | fflush(file); | ||
| 777 | cp = cp1 + dlen; | ||
| 778 | break; | ||
| 779 | |||
| 780 | case T_SIG: | ||
| 781 | type = _getshort((u_char*)cp); | ||
| 782 | cp += INT16SZ; | ||
| 783 | fprintf(file, " %s", p_type(type)); | ||
| 784 | fprintf(file, "\t%d", *cp++); /* algorithm */ | ||
| 785 | /* Check label value and print error if wrong. */ | ||
| 786 | n = *cp++; | ||
| 787 | c = dn_count_labels (rrname); | ||
| 788 | if (n != c) | ||
| 789 | fprintf(file, "\t; LABELS WRONG (%d should be %d)\n\t", | ||
| 790 | n, c); | ||
| 791 | /* orig ttl */ | ||
| 792 | n = _getlong((u_char*)cp); | ||
| 793 | if (n != tmpttl) | ||
| 794 | fprintf(file, " %u", n); | ||
| 795 | cp += INT32SZ; | ||
| 796 | /* sig expire */ | ||
| 797 | fprintf(file, " (\n\t%s", | ||
| 798 | __p_secstodate(_getlong((u_char*)cp))); | ||
| 799 | cp += INT32SZ; | ||
| 800 | /* time signed */ | ||
| 801 | fprintf(file, " %s", __p_secstodate(_getlong((u_char*)cp))); | ||
| 802 | cp += INT32SZ; | ||
| 803 | /* sig footprint */ | ||
| 804 | fprintf(file," %u ", _getshort((u_char*)cp)); | ||
| 805 | cp += INT16SZ; | ||
| 806 | /* signer's name */ | ||
| 807 | cp = p_fqname(cp, msg, file); | ||
| 808 | n = b64_ntop(cp, (cp1 + dlen) - cp, | ||
| 809 | base64_key, sizeof base64_key); | ||
| 810 | for (c = 0; c < n; c++) { | ||
| 811 | if (0 == (c & 0x3F)) | ||
| 812 | fprintf (file, "\n\t"); | ||
| 813 | putc(base64_key[c], file); /* signature */ | ||
| 814 | } | ||
| 815 | /* Clean up... */ | ||
| 816 | fprintf(file, " )"); | ||
| 817 | if (n < 0) | ||
| 818 | fprintf(file, "\t; BAD BASE64"); | ||
| 819 | fflush(file); | ||
| 820 | cp = cp1+dlen; | ||
| 821 | break; | ||
| 822 | |||
| 645 | #ifdef ALLOW_T_UNSPEC | 823 | #ifdef ALLOW_T_UNSPEC |
| 646 | case T_UNSPEC: | 824 | case T_UNSPEC: |
| 647 | { | 825 | { |
| @@ -660,7 +838,7 @@ __p_rr(cp, msg, file) | |||
| 660 | #endif /* ALLOW_T_UNSPEC */ | 838 | #endif /* ALLOW_T_UNSPEC */ |
| 661 | 839 | ||
| 662 | default: | 840 | default: |
| 663 | fprintf(file,"\t?%d?", type); | 841 | fprintf(file, "\t?%d?", type); |
| 664 | cp += dlen; | 842 | cp += dlen; |
| 665 | } | 843 | } |
| 666 | #if 0 | 844 | #if 0 |
| @@ -669,7 +847,7 @@ __p_rr(cp, msg, file) | |||
| 669 | putc('\n', file); | 847 | putc('\n', file); |
| 670 | #endif | 848 | #endif |
| 671 | if (cp - cp1 != dlen) { | 849 | if (cp - cp1 != dlen) { |
| 672 | fprintf(file,";; packet size error (found %d, dlen was %d)\n", | 850 | fprintf(file, ";; packet size error (found %d, dlen was %d)\n", |
| 673 | cp - cp1, dlen); | 851 | cp - cp1, dlen); |
| 674 | cp = NULL; | 852 | cp = NULL; |
| 675 | } | 853 | } |
| @@ -677,54 +855,144 @@ __p_rr(cp, msg, file) | |||
| 677 | } | 855 | } |
| 678 | 856 | ||
| 679 | /* | 857 | /* |
| 858 | * Names of RR classes and qclasses. Classes and qclasses are the same, except | ||
| 859 | * that C_ANY is a qclass but not a class. (You can ask for records of class | ||
| 860 | * C_ANY, but you can't have any records of that class in the database.) | ||
| 861 | */ | ||
| 862 | const struct res_sym __p_class_syms[] = { | ||
| 863 | {C_IN, "IN"}, | ||
| 864 | {C_CHAOS, "CHAOS"}, | ||
| 865 | {C_HS, "HS"}, | ||
| 866 | {C_HS, "HESIOD"}, | ||
| 867 | {C_ANY, "ANY"}, | ||
| 868 | {C_IN, (char *)0} | ||
| 869 | }; | ||
| 870 | |||
| 871 | /* | ||
| 872 | * Names of RR types and qtypes. Types and qtypes are the same, except | ||
| 873 | * that T_ANY is a qtype but not a type. (You can ask for records of type | ||
| 874 | * T_ANY, but you can't have any records of that type in the database.) | ||
| 875 | */ | ||
| 876 | const struct res_sym __p_type_syms[] = { | ||
| 877 | {T_A, "A", "address"}, | ||
| 878 | {T_NS, "NS", "name server"}, | ||
| 879 | {T_MD, "MD", "mail destination (deprecated)"}, | ||
| 880 | {T_MF, "MF", "mail forwarder (deprecated)"}, | ||
| 881 | {T_CNAME, "CNAME", "canonical name"}, | ||
| 882 | {T_SOA, "SOA", "start of authority"}, | ||
| 883 | {T_MB, "MB", "mailbox"}, | ||
| 884 | {T_MG, "MG", "mail group member"}, | ||
| 885 | {T_MR, "MR", "mail rename"}, | ||
| 886 | {T_NULL, "NULL", "null"}, | ||
| 887 | {T_WKS, "WKS", "well-known service (deprecated)"}, | ||
| 888 | {T_PTR, "PTR", "domain name pointer"}, | ||
| 889 | {T_HINFO, "HINFO", "host information"}, | ||
| 890 | {T_MINFO, "MINFO", "mailbox information"}, | ||
| 891 | {T_MX, "MX", "mail exchanger"}, | ||
| 892 | {T_TXT, "TXT", "text"}, | ||
| 893 | {T_RP, "RP", "responsible person"}, | ||
| 894 | {T_AFSDB, "AFSDB", "DCE or AFS server"}, | ||
| 895 | {T_X25, "X25", "X25 address"}, | ||
| 896 | {T_ISDN, "ISDN", "ISDN address"}, | ||
| 897 | {T_RT, "RT", "router"}, | ||
| 898 | {T_NSAP, "NSAP", "nsap address"}, | ||
| 899 | {T_NSAP_PTR, "NSAP_PTR", "domain name pointer"}, | ||
| 900 | {T_SIG, "SIG", "signature"}, | ||
| 901 | {T_KEY, "KEY", "key"}, | ||
| 902 | {T_PX, "PX", "mapping information"}, | ||
| 903 | {T_GPOS, "GPOS", "geographical position (withdrawn)"}, | ||
| 904 | {T_AAAA, "AAAA", "IPv6 address"}, | ||
| 905 | {T_LOC, "LOC", "location"}, | ||
| 906 | {T_NXT, "NXT", "next valid name (unimplemented)"}, | ||
| 907 | {T_EID, "EID", "endpoint identifier (unimplemented)"}, | ||
| 908 | {T_NIMLOC, "NIMLOC", "NIMROD locator (unimplemented)"}, | ||
| 909 | {T_SRV, "SRV", "server selection"}, | ||
| 910 | {T_ATMA, "ATMA", "ATM address (unimplemented)"}, | ||
| 911 | {T_IXFR, "IXFR", "incremental zone transfer"}, | ||
| 912 | {T_AXFR, "AXFR", "zone transfer"}, | ||
| 913 | {T_MAILB, "MAILB", "mailbox-related data (deprecated)"}, | ||
| 914 | {T_MAILA, "MAILA", "mail agent (deprecated)"}, | ||
| 915 | {T_UINFO, "UINFO", "user information (nonstandard)"}, | ||
| 916 | {T_UID, "UID", "user ID (nonstandard)"}, | ||
| 917 | {T_GID, "GID", "group ID (nonstandard)"}, | ||
| 918 | {T_NAPTR, "NAPTR", "URN Naming Authority"}, | ||
| 919 | #ifdef ALLOW_T_UNSPEC | ||
| 920 | {T_UNSPEC, "UNSPEC", "unspecified data (nonstandard)"}, | ||
| 921 | #endif /* ALLOW_T_UNSPEC */ | ||
| 922 | {T_ANY, "ANY", "\"any\""}, | ||
| 923 | {0, NULL, NULL} | ||
| 924 | }; | ||
| 925 | |||
| 926 | int | ||
| 927 | __sym_ston(syms, name, success) | ||
| 928 | const struct res_sym *syms; | ||
| 929 | char *name; | ||
| 930 | int *success; | ||
| 931 | { | ||
| 932 | for (NULL; syms->name != 0; syms++) { | ||
| 933 | if (strcasecmp (name, syms->name) == 0) { | ||
| 934 | if (success) | ||
| 935 | *success = 1; | ||
| 936 | return (syms->number); | ||
| 937 | } | ||
| 938 | } | ||
| 939 | if (success) | ||
| 940 | *success = 0; | ||
| 941 | return (syms->number); /* The default value. */ | ||
| 942 | } | ||
| 943 | |||
| 944 | const char * | ||
| 945 | __sym_ntos(syms, number, success) | ||
| 946 | const struct res_sym *syms; | ||
| 947 | int number; | ||
| 948 | int *success; | ||
| 949 | { | ||
| 950 | static char unname[20]; | ||
| 951 | |||
| 952 | for (NULL; syms->name != 0; syms++) { | ||
| 953 | if (number == syms->number) { | ||
| 954 | if (success) | ||
| 955 | *success = 1; | ||
| 956 | return (syms->name); | ||
| 957 | } | ||
| 958 | } | ||
| 959 | |||
| 960 | sprintf (unname, "%d", number); | ||
| 961 | if (success) | ||
| 962 | *success = 0; | ||
| 963 | return (unname); | ||
| 964 | } | ||
| 965 | |||
| 966 | |||
| 967 | const char * | ||
| 968 | __sym_ntop(syms, number, success) | ||
| 969 | const struct res_sym *syms; | ||
| 970 | int number; | ||
| 971 | int *success; | ||
| 972 | { | ||
| 973 | static char unname[20]; | ||
| 974 | |||
| 975 | for (NULL; syms->name != 0; syms++) { | ||
| 976 | if (number == syms->number) { | ||
| 977 | if (success) | ||
| 978 | *success = 1; | ||
| 979 | return (syms->humanname); | ||
| 980 | } | ||
| 981 | } | ||
| 982 | sprintf(unname, "%d", number); | ||
| 983 | if (success) | ||
| 984 | *success = 0; | ||
| 985 | return (unname); | ||
| 986 | } | ||
| 987 | |||
| 988 | /* | ||
| 680 | * Return a string for the type | 989 | * Return a string for the type |
| 681 | */ | 990 | */ |
| 682 | const char * | 991 | const char * |
| 683 | __p_type(type) | 992 | __p_type(type) |
| 684 | int type; | 993 | int type; |
| 685 | { | 994 | { |
| 686 | static char nbuf[20]; | 995 | return (__sym_ntos (__p_type_syms, type, (int *)0)); |
| 687 | |||
| 688 | switch (type) { | ||
| 689 | case T_A: return "A"; | ||
| 690 | case T_NS: return "NS"; | ||
| 691 | case T_CNAME: return "CNAME"; | ||
| 692 | case T_SOA: return "SOA"; | ||
| 693 | case T_MB: return "MB"; | ||
| 694 | case T_MG: return "MG"; | ||
| 695 | case T_MR: return "MR"; | ||
| 696 | case T_NULL: return "NULL"; | ||
| 697 | case T_WKS: return "WKS"; | ||
| 698 | case T_PTR: return "PTR"; | ||
| 699 | case T_HINFO: return "HINFO"; | ||
| 700 | case T_MINFO: return "MINFO"; | ||
| 701 | case T_MX: return "MX"; | ||
| 702 | case T_TXT: return "TXT"; | ||
| 703 | case T_RP: return "RP"; | ||
| 704 | case T_AFSDB: return "AFSDB"; | ||
| 705 | case T_X25: return "X25"; | ||
| 706 | case T_ISDN: return "ISDN"; | ||
| 707 | case T_RT: return "RT"; | ||
| 708 | case T_NSAP: return "NSAP"; | ||
| 709 | case T_NSAP_PTR: return "NSAP_PTR"; | ||
| 710 | case T_SIG: return "SIG"; | ||
| 711 | case T_KEY: return "KEY"; | ||
| 712 | case T_PX: return "PX"; | ||
| 713 | case T_GPOS: return "GPOS"; | ||
| 714 | case T_AAAA: return "AAAA"; | ||
| 715 | case T_LOC: return "LOC"; | ||
| 716 | case T_AXFR: return "AXFR"; | ||
| 717 | case T_MAILB: return "MAILB"; | ||
| 718 | case T_MAILA: return "MAILA"; | ||
| 719 | case T_ANY: return "ANY"; | ||
| 720 | case T_UINFO: return "UINFO"; | ||
| 721 | case T_UID: return "UID"; | ||
| 722 | case T_GID: return "GID"; | ||
| 723 | #ifdef ALLOW_T_UNSPEC | ||
| 724 | case T_UNSPEC: return "UNSPEC"; | ||
| 725 | #endif /* ALLOW_T_UNSPEC */ | ||
| 726 | default: (void)sprintf(nbuf, "%d", type); return (nbuf); | ||
| 727 | } | ||
| 728 | } | 996 | } |
| 729 | 997 | ||
| 730 | /* | 998 | /* |
| @@ -734,14 +1002,7 @@ const char * | |||
| 734 | __p_class(class) | 1002 | __p_class(class) |
| 735 | int class; | 1003 | int class; |
| 736 | { | 1004 | { |
| 737 | static char nbuf[20]; | 1005 | return (__sym_ntos (__p_class_syms, class, (int *)0)); |
| 738 | |||
| 739 | switch (class) { | ||
| 740 | case C_IN: return "IN"; | ||
| 741 | case C_HS: return "HS"; | ||
| 742 | case C_ANY: return "ANY"; | ||
| 743 | default: (void)sprintf(nbuf, "%d", class); return (nbuf); | ||
| 744 | } | ||
| 745 | } | 1006 | } |
| 746 | 1007 | ||
| 747 | /* | 1008 | /* |
| @@ -774,8 +1035,8 @@ __p_option(option) | |||
| 774 | /* | 1035 | /* |
| 775 | * Return a mnemonic for a time to live | 1036 | * Return a mnemonic for a time to live |
| 776 | */ | 1037 | */ |
| 777 | char * | 1038 | const char * |
| 778 | __p_time(value) | 1039 | p_time(value) |
| 779 | u_int32_t value; | 1040 | u_int32_t value; |
| 780 | { | 1041 | { |
| 781 | static char nbuf[40]; | 1042 | static char nbuf[40]; |
| @@ -784,7 +1045,7 @@ __p_time(value) | |||
| 784 | 1045 | ||
| 785 | if (value == 0) { | 1046 | if (value == 0) { |
| 786 | strcpy(nbuf, "0 secs"); | 1047 | strcpy(nbuf, "0 secs"); |
| 787 | return(nbuf); | 1048 | return (nbuf); |
| 788 | } | 1049 | } |
| 789 | 1050 | ||
| 790 | secs = value % 60; | 1051 | secs = value % 60; |
| @@ -819,5 +1080,437 @@ __p_time(value) | |||
| 819 | *p++ = ' '; | 1080 | *p++ = ' '; |
| 820 | (void)sprintf(p, "%d sec%s", PLURALIZE(secs)); | 1081 | (void)sprintf(p, "%d sec%s", PLURALIZE(secs)); |
| 821 | } | 1082 | } |
| 822 | return(nbuf); | 1083 | return (nbuf); |
| 1084 | } | ||
| 1085 | |||
| 1086 | /* | ||
| 1087 | * routines to convert between on-the-wire RR format and zone file format. | ||
| 1088 | * Does not contain conversion to/from decimal degrees; divide or multiply | ||
| 1089 | * by 60*60*1000 for that. | ||
| 1090 | */ | ||
| 1091 | |||
| 1092 | static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000, | ||
| 1093 | 1000000,10000000,100000000,1000000000}; | ||
| 1094 | |||
| 1095 | /* takes an XeY precision/size value, returns a string representation. */ | ||
| 1096 | static const char * | ||
| 1097 | precsize_ntoa(prec) | ||
| 1098 | u_int8_t prec; | ||
| 1099 | { | ||
| 1100 | static char retbuf[sizeof "90000000.00"]; | ||
| 1101 | unsigned long val; | ||
| 1102 | int mantissa, exponent; | ||
| 1103 | |||
| 1104 | mantissa = (int)((prec >> 4) & 0x0f) % 10; | ||
| 1105 | exponent = (int)((prec >> 0) & 0x0f) % 10; | ||
| 1106 | |||
| 1107 | val = mantissa * poweroften[exponent]; | ||
| 1108 | |||
| 1109 | (void) sprintf(retbuf, "%ld.%.2ld", val/100, val%100); | ||
| 1110 | return (retbuf); | ||
| 1111 | } | ||
| 1112 | |||
| 1113 | /* converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer. */ | ||
| 1114 | static u_int8_t | ||
| 1115 | precsize_aton(strptr) | ||
| 1116 | char **strptr; | ||
| 1117 | { | ||
| 1118 | unsigned int mval = 0, cmval = 0; | ||
| 1119 | u_int8_t retval = 0; | ||
| 1120 | register char *cp; | ||
| 1121 | register int exponent; | ||
| 1122 | register int mantissa; | ||
| 1123 | |||
| 1124 | cp = *strptr; | ||
| 1125 | |||
| 1126 | while (isdigit(*cp)) | ||
| 1127 | mval = mval * 10 + (*cp++ - '0'); | ||
| 1128 | |||
| 1129 | if (*cp == '.') { /* centimeters */ | ||
| 1130 | cp++; | ||
| 1131 | if (isdigit(*cp)) { | ||
| 1132 | cmval = (*cp++ - '0') * 10; | ||
| 1133 | if (isdigit(*cp)) { | ||
| 1134 | cmval += (*cp++ - '0'); | ||
| 1135 | } | ||
| 1136 | } | ||
| 1137 | } | ||
| 1138 | cmval = (mval * 100) + cmval; | ||
| 1139 | |||
| 1140 | for (exponent = 0; exponent < 9; exponent++) | ||
| 1141 | if (cmval < poweroften[exponent+1]) | ||
| 1142 | break; | ||
| 1143 | |||
| 1144 | mantissa = cmval / poweroften[exponent]; | ||
| 1145 | if (mantissa > 9) | ||
| 1146 | mantissa = 9; | ||
| 1147 | |||
| 1148 | retval = (mantissa << 4) | exponent; | ||
| 1149 | |||
| 1150 | *strptr = cp; | ||
| 1151 | |||
| 1152 | return (retval); | ||
| 1153 | } | ||
| 1154 | |||
| 1155 | /* converts ascii lat/lon to unsigned encoded 32-bit number. moves pointer. */ | ||
| 1156 | static u_int32_t | ||
| 1157 | latlon2ul(latlonstrptr,which) | ||
| 1158 | char **latlonstrptr; | ||
| 1159 | int *which; | ||
| 1160 | { | ||
| 1161 | register char *cp; | ||
| 1162 | u_int32_t retval; | ||
| 1163 | int deg = 0, min = 0, secs = 0, secsfrac = 0; | ||
| 1164 | |||
| 1165 | cp = *latlonstrptr; | ||
| 1166 | |||
| 1167 | while (isdigit(*cp)) | ||
| 1168 | deg = deg * 10 + (*cp++ - '0'); | ||
| 1169 | |||
| 1170 | while (isspace(*cp)) | ||
| 1171 | cp++; | ||
| 1172 | |||
| 1173 | if (!(isdigit(*cp))) | ||
| 1174 | goto fndhemi; | ||
| 1175 | |||
| 1176 | while (isdigit(*cp)) | ||
| 1177 | min = min * 10 + (*cp++ - '0'); | ||
| 1178 | |||
| 1179 | while (isspace(*cp)) | ||
| 1180 | cp++; | ||
| 1181 | |||
| 1182 | if (!(isdigit(*cp))) | ||
| 1183 | goto fndhemi; | ||
| 1184 | |||
| 1185 | while (isdigit(*cp)) | ||
| 1186 | secs = secs * 10 + (*cp++ - '0'); | ||
| 1187 | |||
| 1188 | if (*cp == '.') { /* decimal seconds */ | ||
| 1189 | cp++; | ||
| 1190 | if (isdigit(*cp)) { | ||
| 1191 | secsfrac = (*cp++ - '0') * 100; | ||
| 1192 | if (isdigit(*cp)) { | ||
| 1193 | secsfrac += (*cp++ - '0') * 10; | ||
| 1194 | if (isdigit(*cp)) { | ||
| 1195 | secsfrac += (*cp++ - '0'); | ||
| 1196 | } | ||
| 1197 | } | ||
| 1198 | } | ||
| 1199 | } | ||
| 1200 | |||
| 1201 | while (!isspace(*cp)) /* if any trailing garbage */ | ||
| 1202 | cp++; | ||
| 1203 | |||
| 1204 | while (isspace(*cp)) | ||
| 1205 | cp++; | ||
| 1206 | |||
| 1207 | fndhemi: | ||
| 1208 | switch (*cp) { | ||
| 1209 | case 'N': case 'n': | ||
| 1210 | case 'E': case 'e': | ||
| 1211 | retval = ((unsigned)1<<31) | ||
| 1212 | + (((((deg * 60) + min) * 60) + secs) * 1000) | ||
| 1213 | + secsfrac; | ||
| 1214 | break; | ||
| 1215 | case 'S': case 's': | ||
| 1216 | case 'W': case 'w': | ||
| 1217 | retval = ((unsigned)1<<31) | ||
| 1218 | - (((((deg * 60) + min) * 60) + secs) * 1000) | ||
| 1219 | - secsfrac; | ||
| 1220 | break; | ||
| 1221 | default: | ||
| 1222 | retval = 0; /* invalid value -- indicates error */ | ||
| 1223 | break; | ||
| 1224 | } | ||
| 1225 | |||
| 1226 | switch (*cp) { | ||
| 1227 | case 'N': case 'n': | ||
| 1228 | case 'S': case 's': | ||
| 1229 | *which = 1; /* latitude */ | ||
| 1230 | break; | ||
| 1231 | case 'E': case 'e': | ||
| 1232 | case 'W': case 'w': | ||
| 1233 | *which = 2; /* longitude */ | ||
| 1234 | break; | ||
| 1235 | default: | ||
| 1236 | *which = 0; /* error */ | ||
| 1237 | break; | ||
| 1238 | } | ||
| 1239 | |||
| 1240 | cp++; /* skip the hemisphere */ | ||
| 1241 | |||
| 1242 | while (!isspace(*cp)) /* if any trailing garbage */ | ||
| 1243 | cp++; | ||
| 1244 | |||
| 1245 | while (isspace(*cp)) /* move to next field */ | ||
| 1246 | cp++; | ||
| 1247 | |||
| 1248 | *latlonstrptr = cp; | ||
| 1249 | |||
| 1250 | return (retval); | ||
| 1251 | } | ||
| 1252 | |||
| 1253 | /* converts a zone file representation in a string to an RDATA on-the-wire | ||
| 1254 | * representation. */ | ||
| 1255 | int | ||
| 1256 | loc_aton(ascii, binary) | ||
| 1257 | const char *ascii; | ||
| 1258 | u_char *binary; | ||
| 1259 | { | ||
| 1260 | const char *cp, *maxcp; | ||
| 1261 | u_char *bcp; | ||
| 1262 | |||
| 1263 | u_int32_t latit = 0, longit = 0, alt = 0; | ||
| 1264 | u_int32_t lltemp1 = 0, lltemp2 = 0; | ||
| 1265 | int altmeters = 0, altfrac = 0, altsign = 1; | ||
| 1266 | u_int8_t hp = 0x16; /* default = 1e6 cm = 10000.00m = 10km */ | ||
| 1267 | u_int8_t vp = 0x13; /* default = 1e3 cm = 10.00m */ | ||
| 1268 | u_int8_t siz = 0x12; /* default = 1e2 cm = 1.00m */ | ||
| 1269 | int which1 = 0, which2 = 0; | ||
| 1270 | |||
| 1271 | cp = ascii; | ||
| 1272 | maxcp = cp + strlen(ascii); | ||
| 1273 | |||
| 1274 | lltemp1 = latlon2ul(&cp, &which1); | ||
| 1275 | |||
| 1276 | lltemp2 = latlon2ul(&cp, &which2); | ||
| 1277 | |||
| 1278 | switch (which1 + which2) { | ||
| 1279 | case 3: /* 1 + 2, the only valid combination */ | ||
| 1280 | if ((which1 == 1) && (which2 == 2)) { /* normal case */ | ||
| 1281 | latit = lltemp1; | ||
| 1282 | longit = lltemp2; | ||
| 1283 | } else if ((which1 == 2) && (which2 == 1)) { /* reversed */ | ||
| 1284 | longit = lltemp1; | ||
| 1285 | latit = lltemp2; | ||
| 1286 | } else { /* some kind of brokenness */ | ||
| 1287 | return (0); | ||
| 1288 | } | ||
| 1289 | break; | ||
| 1290 | default: /* we didn't get one of each */ | ||
| 1291 | return (0); | ||
| 1292 | } | ||
| 1293 | |||
| 1294 | /* altitude */ | ||
| 1295 | if (*cp == '-') { | ||
| 1296 | altsign = -1; | ||
| 1297 | cp++; | ||
| 1298 | } | ||
| 1299 | |||
| 1300 | if (*cp == '+') | ||
| 1301 | cp++; | ||
| 1302 | |||
| 1303 | while (isdigit(*cp)) | ||
| 1304 | altmeters = altmeters * 10 + (*cp++ - '0'); | ||
| 1305 | |||
| 1306 | if (*cp == '.') { /* decimal meters */ | ||
| 1307 | cp++; | ||
| 1308 | if (isdigit(*cp)) { | ||
| 1309 | altfrac = (*cp++ - '0') * 10; | ||
| 1310 | if (isdigit(*cp)) { | ||
| 1311 | altfrac += (*cp++ - '0'); | ||
| 1312 | } | ||
| 1313 | } | ||
| 1314 | } | ||
| 1315 | |||
| 1316 | alt = (10000000 + (altsign * (altmeters * 100 + altfrac))); | ||
| 1317 | |||
| 1318 | while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */ | ||
| 1319 | cp++; | ||
| 1320 | |||
| 1321 | while (isspace(*cp) && (cp < maxcp)) | ||
| 1322 | cp++; | ||
| 1323 | |||
| 1324 | if (cp >= maxcp) | ||
| 1325 | goto defaults; | ||
| 1326 | |||
| 1327 | siz = precsize_aton(&cp); | ||
| 1328 | |||
| 1329 | while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */ | ||
| 1330 | cp++; | ||
| 1331 | |||
| 1332 | while (isspace(*cp) && (cp < maxcp)) | ||
| 1333 | cp++; | ||
| 1334 | |||
| 1335 | if (cp >= maxcp) | ||
| 1336 | goto defaults; | ||
| 1337 | |||
| 1338 | hp = precsize_aton(&cp); | ||
| 1339 | |||
| 1340 | while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */ | ||
| 1341 | cp++; | ||
| 1342 | |||
| 1343 | while (isspace(*cp) && (cp < maxcp)) | ||
| 1344 | cp++; | ||
| 1345 | |||
| 1346 | if (cp >= maxcp) | ||
| 1347 | goto defaults; | ||
| 1348 | |||
| 1349 | vp = precsize_aton(&cp); | ||
| 1350 | |||
| 1351 | defaults: | ||
| 1352 | |||
| 1353 | bcp = binary; | ||
| 1354 | *bcp++ = (u_int8_t) 0; /* version byte */ | ||
| 1355 | *bcp++ = siz; | ||
| 1356 | *bcp++ = hp; | ||
| 1357 | *bcp++ = vp; | ||
| 1358 | PUTLONG(latit,bcp); | ||
| 1359 | PUTLONG(longit,bcp); | ||
| 1360 | PUTLONG(alt,bcp); | ||
| 1361 | |||
| 1362 | return (16); /* size of RR in octets */ | ||
| 1363 | } | ||
| 1364 | |||
| 1365 | /* takes an on-the-wire LOC RR and formats it in a human readable format. */ | ||
| 1366 | const char * | ||
| 1367 | loc_ntoa(binary, ascii) | ||
| 1368 | const u_char *binary; | ||
| 1369 | char *ascii; | ||
| 1370 | { | ||
| 1371 | static char *error = "?"; | ||
| 1372 | register const u_char *cp = binary; | ||
| 1373 | |||
| 1374 | int latdeg, latmin, latsec, latsecfrac; | ||
| 1375 | int longdeg, longmin, longsec, longsecfrac; | ||
| 1376 | char northsouth, eastwest; | ||
| 1377 | int altmeters, altfrac, altsign; | ||
| 1378 | |||
| 1379 | const int referencealt = 100000 * 100; | ||
| 1380 | |||
| 1381 | int32_t latval, longval, altval; | ||
| 1382 | u_int32_t templ; | ||
| 1383 | u_int8_t sizeval, hpval, vpval, versionval; | ||
| 1384 | |||
| 1385 | char *sizestr, *hpstr, *vpstr; | ||
| 1386 | |||
| 1387 | versionval = *cp++; | ||
| 1388 | |||
| 1389 | if (versionval) { | ||
| 1390 | sprintf(ascii, "; error: unknown LOC RR version"); | ||
| 1391 | return (ascii); | ||
| 1392 | } | ||
| 1393 | |||
| 1394 | sizeval = *cp++; | ||
| 1395 | |||
| 1396 | hpval = *cp++; | ||
| 1397 | vpval = *cp++; | ||
| 1398 | |||
| 1399 | GETLONG(templ, cp); | ||
| 1400 | latval = (templ - ((unsigned)1<<31)); | ||
| 1401 | |||
| 1402 | GETLONG(templ, cp); | ||
| 1403 | longval = (templ - ((unsigned)1<<31)); | ||
| 1404 | |||
| 1405 | GETLONG(templ, cp); | ||
| 1406 | if (templ < referencealt) { /* below WGS 84 spheroid */ | ||
| 1407 | altval = referencealt - templ; | ||
| 1408 | altsign = -1; | ||
| 1409 | } else { | ||
| 1410 | altval = templ - referencealt; | ||
| 1411 | altsign = 1; | ||
| 1412 | } | ||
| 1413 | |||
| 1414 | if (latval < 0) { | ||
| 1415 | northsouth = 'S'; | ||
| 1416 | latval = -latval; | ||
| 1417 | } else | ||
| 1418 | northsouth = 'N'; | ||
| 1419 | |||
| 1420 | latsecfrac = latval % 1000; | ||
| 1421 | latval = latval / 1000; | ||
| 1422 | latsec = latval % 60; | ||
| 1423 | latval = latval / 60; | ||
| 1424 | latmin = latval % 60; | ||
| 1425 | latval = latval / 60; | ||
| 1426 | latdeg = latval; | ||
| 1427 | |||
| 1428 | if (longval < 0) { | ||
| 1429 | eastwest = 'W'; | ||
| 1430 | longval = -longval; | ||
| 1431 | } else | ||
| 1432 | eastwest = 'E'; | ||
| 1433 | |||
| 1434 | longsecfrac = longval % 1000; | ||
| 1435 | longval = longval / 1000; | ||
| 1436 | longsec = longval % 60; | ||
| 1437 | longval = longval / 60; | ||
| 1438 | longmin = longval % 60; | ||
| 1439 | longval = longval / 60; | ||
| 1440 | longdeg = longval; | ||
| 1441 | |||
| 1442 | altfrac = altval % 100; | ||
| 1443 | altmeters = (altval / 100) * altsign; | ||
| 1444 | |||
| 1445 | if ((sizestr = strdup(precsize_ntoa(sizeval))) == NULL) | ||
| 1446 | sizestr = error; | ||
| 1447 | if ((hpstr = strdup(precsize_ntoa(hpval))) == NULL) | ||
| 1448 | hpstr = error; | ||
| 1449 | if ((vpstr = strdup(precsize_ntoa(vpval))) == NULL) | ||
| 1450 | vpstr = error; | ||
| 1451 | |||
| 1452 | sprintf(ascii, | ||
| 1453 | "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm", | ||
| 1454 | latdeg, latmin, latsec, latsecfrac, northsouth, | ||
| 1455 | longdeg, longmin, longsec, longsecfrac, eastwest, | ||
| 1456 | altmeters, altfrac, sizestr, hpstr, vpstr); | ||
| 1457 | |||
| 1458 | if (sizestr != error) | ||
| 1459 | free(sizestr); | ||
| 1460 | if (hpstr != error) | ||
| 1461 | free(hpstr); | ||
| 1462 | if (vpstr != error) | ||
| 1463 | free(vpstr); | ||
| 1464 | |||
| 1465 | return (ascii); | ||
| 1466 | } | ||
| 1467 | |||
| 1468 | |||
| 1469 | /* Return the number of DNS hierarchy levels in the name. */ | ||
| 1470 | int | ||
| 1471 | __dn_count_labels(name) | ||
| 1472 | char *name; | ||
| 1473 | { | ||
| 1474 | int i, len, count; | ||
| 1475 | |||
| 1476 | len = strlen(name); | ||
| 1477 | |||
| 1478 | for(i = 0, count = 0; i < len; i++) { | ||
| 1479 | if (name[i] == '.') | ||
| 1480 | count++; | ||
| 1481 | } | ||
| 1482 | |||
| 1483 | /* don't count initial wildcard */ | ||
| 1484 | if (name[0] == '*') | ||
| 1485 | if (count) | ||
| 1486 | count--; | ||
| 1487 | |||
| 1488 | /* don't count the null label for root. */ | ||
| 1489 | /* if terminating '.' not found, must adjust */ | ||
| 1490 | /* count to include last label */ | ||
| 1491 | if (len > 0 && name[len-1] != '.') | ||
| 1492 | count++; | ||
| 1493 | return (count); | ||
| 1494 | } | ||
| 1495 | |||
| 1496 | |||
| 1497 | /* | ||
| 1498 | * Make dates expressed in seconds-since-Jan-1-1970 easy to read. | ||
| 1499 | * SIG records are required to be printed like this, by the Secure DNS RFC. | ||
| 1500 | */ | ||
| 1501 | char * | ||
| 1502 | __p_secstodate (secs) | ||
| 1503 | unsigned long secs; | ||
| 1504 | { | ||
| 1505 | static char output[15]; /* YYYYMMDDHHMMSS and null */ | ||
| 1506 | time_t clock = secs; | ||
| 1507 | struct tm *time; | ||
| 1508 | |||
| 1509 | time = gmtime(&clock); | ||
| 1510 | time->tm_year += 1900; | ||
| 1511 | time->tm_mon += 1; | ||
| 1512 | sprintf(output, "%04d%02d%02d%02d%02d%02d", | ||
| 1513 | time->tm_year, time->tm_mon, time->tm_mday, | ||
| 1514 | time->tm_hour, time->tm_min, time->tm_sec); | ||
| 1515 | return (output); | ||
| 823 | } | 1516 | } |
diff --git a/src/lib/libc/net/res_init.c b/src/lib/libc/net/res_init.c index 6f4f39ef9f..46b9361126 100644 --- a/src/lib/libc/net/res_init.c +++ b/src/lib/libc/net/res_init.c | |||
| @@ -1,7 +1,11 @@ | |||
| 1 | /*- | 1 | /* $OpenBSD: res_init.c,v 1.11 1997/03/13 19:07:38 downsj Exp $ */ |
| 2 | |||
| 3 | /* | ||
| 4 | * ++Copyright++ 1985, 1989, 1993 | ||
| 5 | * - | ||
| 2 | * Copyright (c) 1985, 1989, 1993 | 6 | * Copyright (c) 1985, 1989, 1993 |
| 3 | * The Regents of the University of California. All rights reserved. | 7 | * The Regents of the University of California. All rights reserved. |
| 4 | * | 8 | * |
| 5 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions |
| 7 | * are met: | 11 | * are met: |
| @@ -12,12 +16,12 @@ | |||
| 12 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 17 | * 3. All advertising materials mentioning features or use of this software |
| 14 | * must display the following acknowledgement: | 18 | * must display the following acknowledgement: |
| 15 | * This product includes software developed by the University of | 19 | * This product includes software developed by the University of |
| 16 | * California, Berkeley and its contributors. | 20 | * California, Berkeley and its contributors. |
| 17 | * 4. Neither the name of the University nor the names of its contributors | 21 | * 4. Neither the name of the University nor the names of its contributors |
| 18 | * may be used to endorse or promote products derived from this software | 22 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 23 | * without specific prior written permission. |
| 20 | * | 24 | * |
| 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 25 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
| 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 26 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 27 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| @@ -52,33 +56,69 @@ | |||
| 52 | */ | 56 | */ |
| 53 | 57 | ||
| 54 | #if defined(LIBC_SCCS) && !defined(lint) | 58 | #if defined(LIBC_SCCS) && !defined(lint) |
| 55 | static char rcsid[] = "$OpenBSD: res_init.c,v 1.10 1996/09/22 11:52:07 deraadt Exp $"; | 59 | #if 0 |
| 60 | static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93"; | ||
| 61 | static char rcsid[] = "$From: res_init.c,v 8.7 1996/09/28 06:51:07 vixie Exp $"; | ||
| 62 | #else | ||
| 63 | static char rcsid[] = "$OpenBSD: res_init.c,v 1.11 1997/03/13 19:07:38 downsj Exp $"; | ||
| 64 | #endif | ||
| 56 | #endif /* LIBC_SCCS and not lint */ | 65 | #endif /* LIBC_SCCS and not lint */ |
| 57 | 66 | ||
| 67 | #include <sys/types.h> | ||
| 58 | #include <sys/param.h> | 68 | #include <sys/param.h> |
| 59 | #include <sys/socket.h> | 69 | #include <sys/socket.h> |
| 70 | #include <sys/time.h> | ||
| 60 | #include <netinet/in.h> | 71 | #include <netinet/in.h> |
| 61 | #include <arpa/inet.h> | 72 | #include <arpa/inet.h> |
| 62 | #include <arpa/nameser.h> | 73 | #include <arpa/nameser.h> |
| 74 | |||
| 75 | #include <stdio.h> | ||
| 76 | #include <ctype.h> | ||
| 63 | #include <resolv.h> | 77 | #include <resolv.h> |
| 64 | #include <unistd.h> | 78 | #include <unistd.h> |
| 65 | #include <stdio.h> | ||
| 66 | #include <stdlib.h> | 79 | #include <stdlib.h> |
| 67 | #include <string.h> | 80 | #include <string.h> |
| 68 | 81 | ||
| 82 | /*-------------------------------------- info about "sortlist" -------------- | ||
| 83 | * Marc Majka 1994/04/16 | ||
| 84 | * Allan Nathanson 1994/10/29 (BIND 4.9.3.x) | ||
| 85 | * | ||
| 86 | * NetInfo resolver configuration directory support. | ||
| 87 | * | ||
| 88 | * Allow a NetInfo directory to be created in the hierarchy which | ||
| 89 | * contains the same information as the resolver configuration file. | ||
| 90 | * | ||
| 91 | * - The local domain name is stored as the value of the "domain" property. | ||
| 92 | * - The Internet address(es) of the name server(s) are stored as values | ||
| 93 | * of the "nameserver" property. | ||
| 94 | * - The name server addresses are stored as values of the "nameserver" | ||
| 95 | * property. | ||
| 96 | * - The search list for host-name lookup is stored as values of the | ||
| 97 | * "search" property. | ||
| 98 | * - The sortlist comprised of IP address netmask pairs are stored as | ||
| 99 | * values of the "sortlist" property. The IP address and optional netmask | ||
| 100 | * should be seperated by a slash (/) or ampersand (&) character. | ||
| 101 | * - Internal resolver variables can be set from the value of the "options" | ||
| 102 | * property. | ||
| 103 | */ | ||
| 104 | |||
| 69 | static void res_setoptions __P((char *, char *)); | 105 | static void res_setoptions __P((char *, char *)); |
| 106 | |||
| 107 | #ifdef RESOLVSORT | ||
| 108 | static const char sort_mask[] = "/&"; | ||
| 109 | #define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL) | ||
| 70 | static u_int32_t net_mask __P((struct in_addr)); | 110 | static u_int32_t net_mask __P((struct in_addr)); |
| 111 | #endif | ||
| 71 | 112 | ||
| 72 | /* | 113 | /* |
| 73 | * Resolver state default settings | 114 | * Resolver state default settings. |
| 74 | */ | 115 | */ |
| 75 | 116 | ||
| 76 | struct __res_state _res = { | 117 | struct __res_state _res |
| 77 | RES_TIMEOUT, /* retransmition time interval */ | 118 | # if defined(__BIND_RES_TEXT) |
| 78 | 4, /* number of times to retransmit */ | 119 | = { RES_TIMEOUT, } /* Motorola, et al. */ |
| 79 | RES_DEFAULT, /* options flags */ | 120 | # endif |
| 80 | 1, /* number of name servers */ | 121 | ; |
| 81 | }; | ||
| 82 | 122 | ||
| 83 | /* | 123 | /* |
| 84 | * Set up default settings. If the configuration file exist, the values | 124 | * Set up default settings. If the configuration file exist, the values |
| @@ -105,25 +145,60 @@ int | |||
| 105 | res_init() | 145 | res_init() |
| 106 | { | 146 | { |
| 107 | register FILE *fp; | 147 | register FILE *fp; |
| 108 | register char *cp, **pp, *net; | 148 | register char *cp, **pp; |
| 109 | register int n; | 149 | register int n; |
| 110 | char buf[BUFSIZ], buf2[BUFSIZ]; | 150 | char buf[BUFSIZ]; |
| 111 | int nserv = 0; /* number of nameserver records read from file */ | 151 | int nserv = 0; /* number of nameserver records read from file */ |
| 112 | int haveenv = 0; | 152 | int haveenv = 0; |
| 113 | int havesearch = 0; | 153 | int havesearch = 0; |
| 154 | #ifdef RESOLVSORT | ||
| 114 | int nsort = 0; | 155 | int nsort = 0; |
| 156 | char *net; | ||
| 157 | #endif | ||
| 158 | #ifndef RFC1535 | ||
| 159 | int dots; | ||
| 160 | #endif | ||
| 115 | 161 | ||
| 116 | if (_res.id == 0) | 162 | /* |
| 163 | * These three fields used to be statically initialized. This made | ||
| 164 | * it hard to use this code in a shared library. It is necessary, | ||
| 165 | * now that we're doing dynamic initialization here, that we preserve | ||
| 166 | * the old semantics: if an application modifies one of these three | ||
| 167 | * fields of _res before res_init() is called, res_init() will not | ||
| 168 | * alter them. Of course, if an application is setting them to | ||
| 169 | * _zero_ before calling res_init(), hoping to override what used | ||
| 170 | * to be the static default, we can't detect it and unexpected results | ||
| 171 | * will follow. Zero for any of these fields would make no sense, | ||
| 172 | * so one can safely assume that the applications were already getting | ||
| 173 | * unexpected results. | ||
| 174 | * | ||
| 175 | * _res.options is tricky since some apps were known to diddle the bits | ||
| 176 | * before res_init() was first called. We can't replicate that semantic | ||
| 177 | * with dynamic initialization (they may have turned bits off that are | ||
| 178 | * set in RES_DEFAULT). Our solution is to declare such applications | ||
| 179 | * "broken". They could fool us by setting RES_INIT but none do (yet). | ||
| 180 | */ | ||
| 181 | if (!_res.retrans) | ||
| 182 | _res.retrans = RES_TIMEOUT; | ||
| 183 | if (!_res.retry) | ||
| 184 | _res.retry = 4; | ||
| 185 | if (!(_res.options & RES_INIT)) | ||
| 186 | _res.options = RES_DEFAULT; | ||
| 187 | |||
| 188 | /* | ||
| 189 | * This one used to initialize implicitly to zero, so unless the app | ||
| 190 | * has set it to something in particular, we can randomize it now. | ||
| 191 | */ | ||
| 192 | if (!_res.id) | ||
| 117 | _res.id = res_randomid(); | 193 | _res.id = res_randomid(); |
| 118 | 194 | ||
| 119 | _res.nsaddr.sin_len = sizeof(struct sockaddr_in); | ||
| 120 | _res.nsaddr.sin_family = AF_INET; | ||
| 121 | _res.nsaddr.sin_port = htons(NAMESERVER_PORT); | ||
| 122 | #ifdef USELOOPBACK | 195 | #ifdef USELOOPBACK |
| 123 | _res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1); | 196 | _res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1); |
| 124 | #else | 197 | #else |
| 125 | _res.nsaddr.sin_addr.s_addr = INADDR_ANY; | 198 | _res.nsaddr.sin_addr.s_addr = INADDR_ANY; |
| 126 | #endif | 199 | #endif |
| 200 | _res.nsaddr.sin_family = AF_INET; | ||
| 201 | _res.nsaddr.sin_port = htons(NAMESERVER_PORT); | ||
| 127 | _res.nscount = 1; | 202 | _res.nscount = 1; |
| 128 | _res.ndots = 1; | 203 | _res.ndots = 1; |
| 129 | _res.pfcode = 0; | 204 | _res.pfcode = 0; |
| @@ -133,8 +208,6 @@ res_init() | |||
| 133 | if (issetugid() == 0 && (cp = getenv("LOCALDOMAIN")) != NULL) { | 208 | if (issetugid() == 0 && (cp = getenv("LOCALDOMAIN")) != NULL) { |
| 134 | (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1); | 209 | (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1); |
| 135 | _res.defdname[sizeof(_res.defdname) - 1] = '\0'; | 210 | _res.defdname[sizeof(_res.defdname) - 1] = '\0'; |
| 136 | if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL) | ||
| 137 | *cp = '\0'; | ||
| 138 | haveenv++; | 211 | haveenv++; |
| 139 | 212 | ||
| 140 | /* | 213 | /* |
| @@ -148,7 +221,7 @@ res_init() | |||
| 148 | pp = _res.dnsrch; | 221 | pp = _res.dnsrch; |
| 149 | *pp++ = cp; | 222 | *pp++ = cp; |
| 150 | for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) { | 223 | for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) { |
| 151 | if (*cp == '\n') /* silly backwards compat */ | 224 | if (*cp == '\n') /* silly backwards compat */ |
| 152 | break; | 225 | break; |
| 153 | else if (*cp == ' ' || *cp == '\t') { | 226 | else if (*cp == ' ' || *cp == '\t') { |
| 154 | *cp = 0; | 227 | *cp = 0; |
| @@ -166,16 +239,21 @@ res_init() | |||
| 166 | *pp++ = 0; | 239 | *pp++ = 0; |
| 167 | } | 240 | } |
| 168 | 241 | ||
| 242 | #define MATCH(line, name) \ | ||
| 243 | (!strncmp(line, name, sizeof(name) - 1) && \ | ||
| 244 | (line[sizeof(name) - 1] == ' ' || \ | ||
| 245 | line[sizeof(name) - 1] == '\t')) | ||
| 246 | |||
| 169 | if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) { | 247 | if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) { |
| 170 | strncpy(_res.lookups, "bf", sizeof _res.lookups); | 248 | strncpy(_res.lookups, "bf", sizeof _res.lookups); |
| 171 | 249 | ||
| 172 | /* read the config file */ | 250 | /* read the config file */ |
| 173 | while (fgets(buf, sizeof(buf), fp) != NULL) { | 251 | while (fgets(buf, sizeof(buf), fp) != NULL) { |
| 174 | /* skip comments */ | 252 | /* skip comments */ |
| 175 | if ((*buf == ';') || (*buf == '#')) | 253 | if (*buf == ';' || *buf == '#') |
| 176 | continue; | 254 | continue; |
| 177 | /* read default domain name */ | 255 | /* read default domain name */ |
| 178 | if (!strncmp(buf, "domain", sizeof("domain") - 1)) { | 256 | if (MATCH(buf, "domain")) { |
| 179 | if (haveenv) /* skip if have from environ */ | 257 | if (haveenv) /* skip if have from environ */ |
| 180 | continue; | 258 | continue; |
| 181 | cp = buf + sizeof("domain") - 1; | 259 | cp = buf + sizeof("domain") - 1; |
| @@ -183,8 +261,7 @@ res_init() | |||
| 183 | cp++; | 261 | cp++; |
| 184 | if ((*cp == '\0') || (*cp == '\n')) | 262 | if ((*cp == '\0') || (*cp == '\n')) |
| 185 | continue; | 263 | continue; |
| 186 | (void)strncpy(_res.defdname, cp, | 264 | strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1); |
| 187 | sizeof(_res.defdname) - 1); | ||
| 188 | _res.defdname[sizeof(_res.defdname) - 1] = '\0'; | 265 | _res.defdname[sizeof(_res.defdname) - 1] = '\0'; |
| 189 | if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL) | 266 | if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL) |
| 190 | *cp = '\0'; | 267 | *cp = '\0'; |
| @@ -219,7 +296,7 @@ res_init() | |||
| 219 | continue; | 296 | continue; |
| 220 | } | 297 | } |
| 221 | /* set search list */ | 298 | /* set search list */ |
| 222 | if (!strncmp(buf, "search", sizeof("search") - 1)) { | 299 | if (MATCH(buf, "search")) { |
| 223 | if (haveenv) /* skip if have from environ */ | 300 | if (haveenv) /* skip if have from environ */ |
| 224 | continue; | 301 | continue; |
| 225 | cp = buf + sizeof("search") - 1; | 302 | cp = buf + sizeof("search") - 1; |
| @@ -227,8 +304,7 @@ res_init() | |||
| 227 | cp++; | 304 | cp++; |
| 228 | if ((*cp == '\0') || (*cp == '\n')) | 305 | if ((*cp == '\0') || (*cp == '\n')) |
| 229 | continue; | 306 | continue; |
| 230 | (void)strncpy(_res.defdname, cp, | 307 | strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1); |
| 231 | sizeof(_res.defdname) - 1); | ||
| 232 | _res.defdname[sizeof(_res.defdname) - 1] = '\0'; | 308 | _res.defdname[sizeof(_res.defdname) - 1] = '\0'; |
| 233 | if ((cp = strchr(_res.defdname, '\n')) != NULL) | 309 | if ((cp = strchr(_res.defdname, '\n')) != NULL) |
| 234 | *cp = '\0'; | 310 | *cp = '\0'; |
| @@ -257,84 +333,110 @@ res_init() | |||
| 257 | continue; | 333 | continue; |
| 258 | } | 334 | } |
| 259 | /* read nameservers to query */ | 335 | /* read nameservers to query */ |
| 260 | if (!strncmp(buf, "nameserver", sizeof("nameserver") - 1) && | 336 | if (MATCH(buf, "nameserver") && nserv < MAXNS) { |
| 261 | nserv < MAXNS) { | 337 | struct in_addr a; |
| 262 | struct in_addr a; | ||
| 263 | 338 | ||
| 264 | cp = buf + sizeof("nameserver") - 1; | 339 | cp = buf + sizeof("nameserver") - 1; |
| 265 | while (*cp == ' ' || *cp == '\t') | 340 | while (*cp == ' ' || *cp == '\t') |
| 266 | cp++; | 341 | cp++; |
| 267 | if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) { | 342 | if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) { |
| 268 | _res.nsaddr_list[nserv].sin_len = sizeof(struct sockaddr_in); | 343 | _res.nsaddr_list[nserv].sin_addr = a; |
| 269 | _res.nsaddr_list[nserv].sin_family = AF_INET; | 344 | _res.nsaddr_list[nserv].sin_family = AF_INET; |
| 270 | _res.nsaddr_list[nserv].sin_port = | 345 | _res.nsaddr_list[nserv].sin_port = |
| 271 | htons(NAMESERVER_PORT); | 346 | htons(NAMESERVER_PORT); |
| 272 | _res.nsaddr_list[nserv].sin_addr = a; | ||
| 273 | nserv++; | 347 | nserv++; |
| 274 | } | 348 | } |
| 275 | continue; | 349 | continue; |
| 276 | } | 350 | } |
| 277 | if (!strncmp(buf, "sortlist", sizeof("sortlist") - 1)) { | 351 | #ifdef RESOLVSORT |
| 352 | if (MATCH(buf, "sortlist")) { | ||
| 278 | struct in_addr a; | 353 | struct in_addr a; |
| 279 | 354 | ||
| 280 | cp = buf + sizeof("sortlist") - 1; | 355 | cp = buf + sizeof("sortlist") - 1; |
| 281 | while (*cp == ' ' || *cp == '\t') | 356 | while (nsort < MAXRESOLVSORT) { |
| 282 | cp++; | 357 | while (*cp == ' ' || *cp == '\t') |
| 283 | while (sscanf(cp,"%[0-9./]s", buf2) && nsort < MAXRESOLVSORT) { | 358 | cp++; |
| 284 | if (net = strchr(buf2, '/')) | 359 | if (*cp == '\0' || *cp == '\n' || *cp == ';') |
| 285 | *net = '\0'; | 360 | break; |
| 286 | if (inet_aton(buf2, &a)) { | 361 | net = cp; |
| 362 | while (*cp && !ISSORTMASK(*cp) && *cp != ';' && | ||
| 363 | isascii(*cp) && !isspace(*cp)) | ||
| 364 | cp++; | ||
| 365 | n = *cp; | ||
| 366 | *cp = 0; | ||
| 367 | if (inet_aton(net, &a)) { | ||
| 287 | _res.sort_list[nsort].addr = a; | 368 | _res.sort_list[nsort].addr = a; |
| 288 | if (net && inet_aton(net+1, &a)) { | 369 | if (ISSORTMASK(n)) { |
| 289 | _res.sort_list[nsort].mask = a.s_addr; | 370 | *cp++ = n; |
| 290 | } else { | 371 | net = cp; |
| 291 | _res.sort_list[nsort].mask = | 372 | while (*cp && *cp != ';' && |
| 373 | isascii(*cp) && !isspace(*cp)) | ||
| 374 | cp++; | ||
| 375 | n = *cp; | ||
| 376 | *cp = 0; | ||
| 377 | if (inet_aton(net, &a)) { | ||
| 378 | _res.sort_list[nsort].mask = a.s_addr; | ||
| 379 | } else { | ||
| 380 | _res.sort_list[nsort].mask = | ||
| 292 | net_mask(_res.sort_list[nsort].addr); | 381 | net_mask(_res.sort_list[nsort].addr); |
| 382 | } | ||
| 383 | } else { | ||
| 384 | _res.sort_list[nsort].mask = | ||
| 385 | net_mask(_res.sort_list[nsort].addr); | ||
| 293 | } | 386 | } |
| 294 | nsort++; | 387 | nsort++; |
| 295 | } | 388 | } |
| 296 | if (net) | 389 | *cp = n; |
| 297 | *net = '/'; | ||
| 298 | cp += strlen(buf2); | ||
| 299 | while (*cp == ' ' || *cp == '\t') | ||
| 300 | cp++; | ||
| 301 | } | 390 | } |
| 302 | continue; | 391 | continue; |
| 303 | } | 392 | } |
| 304 | if (!strncmp(buf, "options", sizeof("options") -1)) { | 393 | #endif |
| 394 | if (MATCH(buf, "options")) { | ||
| 305 | res_setoptions(buf + sizeof("options") - 1, "conf"); | 395 | res_setoptions(buf + sizeof("options") - 1, "conf"); |
| 306 | continue; | 396 | continue; |
| 307 | } | 397 | } |
| 308 | } | 398 | } |
| 309 | if (nserv > 1) | 399 | if (nserv > 1) |
| 310 | _res.nscount = nserv; | 400 | _res.nscount = nserv; |
| 401 | #ifdef RESOLVSORT | ||
| 311 | _res.nsort = nsort; | 402 | _res.nsort = nsort; |
| 403 | #endif | ||
| 312 | (void) fclose(fp); | 404 | (void) fclose(fp); |
| 313 | } | 405 | } |
| 314 | if (_res.defdname[0] == 0) { | 406 | if (_res.defdname[0] == 0 && |
| 315 | if (gethostname(buf, sizeof(_res.defdname) - 1) == 0 && | 407 | gethostname(buf, sizeof(_res.defdname) - 1) == 0 && |
| 316 | (cp = strchr(buf, '.'))) | 408 | (cp = strchr(buf, '.')) != NULL) |
| 317 | (void)strcpy(_res.defdname, cp + 1); | 409 | strcpy(_res.defdname, cp + 1); |
| 318 | } | ||
| 319 | 410 | ||
| 320 | /* find components of local domain that might be searched */ | 411 | /* find components of local domain that might be searched */ |
| 321 | if (havesearch == 0) { | 412 | if (havesearch == 0) { |
| 322 | pp = _res.dnsrch; | 413 | pp = _res.dnsrch; |
| 323 | *pp++ = _res.defdname; | 414 | *pp++ = _res.defdname; |
| 324 | #ifndef SEARCH_LOCAL_DOMAINS | ||
| 325 | *pp = NULL; | 415 | *pp = NULL; |
| 326 | #else | 416 | |
| 327 | for (cp = _res.defdname, n = 0; *cp; cp++) | 417 | #ifndef RFC1535 |
| 328 | if (*cp == '.') | 418 | dots = 0; |
| 329 | n++; | 419 | for (cp = _res.defdname; *cp; cp++) |
| 420 | dots += (*cp == '.'); | ||
| 421 | |||
| 330 | cp = _res.defdname; | 422 | cp = _res.defdname; |
| 331 | for (; n >= LOCALDOMAINPARTS && pp < _res.dnsrch + MAXDFLSRCH; | 423 | while (pp < _res.dnsrch + MAXDFLSRCH) { |
| 332 | n--) { | 424 | if (dots < LOCALDOMAINPARTS) |
| 333 | cp = strchr(cp, '.'); | 425 | break; |
| 334 | *pp++ = ++cp; | 426 | cp = strchr(cp, '.') + 1; /* we know there is one */ |
| 427 | *pp++ = cp; | ||
| 428 | dots--; | ||
| 335 | } | 429 | } |
| 336 | *pp++ = 0; | 430 | *pp = NULL; |
| 337 | #endif | 431 | #ifdef DEBUG |
| 432 | if (_res.options & RES_DEBUG) { | ||
| 433 | printf(";; res_init()... default dnsrch list:\n"); | ||
| 434 | for (pp = _res.dnsrch; *pp; pp++) | ||
| 435 | printf(";;\t%s\n", *pp); | ||
| 436 | printf(";;\t..END..\n"); | ||
| 437 | } | ||
| 438 | #endif /* DEBUG */ | ||
| 439 | #endif /* !RFC1535 */ | ||
| 338 | } | 440 | } |
| 339 | 441 | ||
| 340 | if (issetugid()) | 442 | if (issetugid()) |
| @@ -354,28 +456,26 @@ res_setoptions(options, source) | |||
| 354 | int i; | 456 | int i; |
| 355 | 457 | ||
| 356 | #ifdef DEBUG | 458 | #ifdef DEBUG |
| 357 | if (_res.options & RES_DEBUG) { | 459 | if (_res.options & RES_DEBUG) |
| 358 | printf(";; res_setoptions(\"%s\", \"%s\")...\n", | 460 | printf(";; res_setoptions(\"%s\", \"%s\")...\n", |
| 359 | options, source); | 461 | options, source); |
| 360 | } | ||
| 361 | #endif | 462 | #endif |
| 362 | while (*cp) { | 463 | while (*cp) { |
| 363 | /* skip leading and inner runs of spaces */ | 464 | /* skip leading and inner runs of spaces */ |
| 364 | while (*cp == ' ' || *cp == '\t') | 465 | while (*cp == ' ' || *cp == '\t') |
| 365 | cp++; | 466 | cp++; |
| 366 | /* search for and process individual options */ | 467 | /* search for and process individual options */ |
| 367 | if (!strncmp(cp, "ndots:", sizeof("ndots:")-1)) { | 468 | if (!strncmp(cp, "ndots:", sizeof("ndots:") - 1)) { |
| 368 | i = atoi(cp + sizeof("ndots:") - 1); | 469 | i = atoi(cp + sizeof("ndots:") - 1); |
| 369 | if (i <= RES_MAXNDOTS) | 470 | if (i <= RES_MAXNDOTS) |
| 370 | _res.ndots = i; | 471 | _res.ndots = i; |
| 371 | else | 472 | else |
| 372 | _res.ndots = RES_MAXNDOTS; | 473 | _res.ndots = RES_MAXNDOTS; |
| 373 | #ifdef DEBUG | 474 | #ifdef DEBUG |
| 374 | if (_res.options & RES_DEBUG) { | 475 | if (_res.options & RES_DEBUG) |
| 375 | printf(";;\tndots=%d\n", _res.ndots); | 476 | printf(";;\tndots=%d\n", _res.ndots); |
| 376 | } | ||
| 377 | #endif | 477 | #endif |
| 378 | } else if (!strncmp(cp, "debug", sizeof("debug")-1)) { | 478 | } else if (!strncmp(cp, "debug", sizeof("debug") - 1)) { |
| 379 | #ifdef DEBUG | 479 | #ifdef DEBUG |
| 380 | if (!(_res.options & RES_DEBUG)) { | 480 | if (!(_res.options & RES_DEBUG)) { |
| 381 | printf(";; res_setoptions(\"%s\", \"%s\")..\n", | 481 | printf(";; res_setoptions(\"%s\", \"%s\")..\n", |
| @@ -384,6 +484,8 @@ res_setoptions(options, source) | |||
| 384 | } | 484 | } |
| 385 | printf(";;\tdebug\n"); | 485 | printf(";;\tdebug\n"); |
| 386 | #endif | 486 | #endif |
| 487 | } else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) { | ||
| 488 | _res.options |= RES_USE_INET6; | ||
| 387 | } else { | 489 | } else { |
| 388 | /* XXX - print a warning here? */ | 490 | /* XXX - print a warning here? */ |
| 389 | } | 491 | } |
| @@ -393,6 +495,8 @@ res_setoptions(options, source) | |||
| 393 | } | 495 | } |
| 394 | } | 496 | } |
| 395 | 497 | ||
| 498 | #ifdef RESOLVSORT | ||
| 499 | /* XXX - should really support CIDR which means explicit masks always. */ | ||
| 396 | static u_int32_t | 500 | static u_int32_t |
| 397 | net_mask(in) /* XXX - should really use system's version of this */ | 501 | net_mask(in) /* XXX - should really use system's version of this */ |
| 398 | struct in_addr in; | 502 | struct in_addr in; |
| @@ -401,12 +505,13 @@ net_mask(in) /* XXX - should really use system's version of this */ | |||
| 401 | 505 | ||
| 402 | if (IN_CLASSA(i)) | 506 | if (IN_CLASSA(i)) |
| 403 | return (htonl(IN_CLASSA_NET)); | 507 | return (htonl(IN_CLASSA_NET)); |
| 404 | if (IN_CLASSB(i)) | 508 | else if (IN_CLASSB(i)) |
| 405 | return (htonl(IN_CLASSB_NET)); | 509 | return (htonl(IN_CLASSB_NET)); |
| 406 | return (htonl(IN_CLASSC_NET)); | 510 | return (htonl(IN_CLASSC_NET)); |
| 407 | } | 511 | } |
| 512 | #endif | ||
| 408 | 513 | ||
| 409 | u_int16_t | 514 | u_int |
| 410 | res_randomid() | 515 | res_randomid() |
| 411 | { | 516 | { |
| 412 | struct timeval now; | 517 | struct timeval now; |
diff --git a/src/lib/libc/net/res_mkquery.c b/src/lib/libc/net/res_mkquery.c index 6fbd6a3859..5faba01748 100644 --- a/src/lib/libc/net/res_mkquery.c +++ b/src/lib/libc/net/res_mkquery.c | |||
| @@ -1,7 +1,11 @@ | |||
| 1 | /*- | 1 | /* $OpenBSD: res_mkquery.c,v 1.6 1997/03/13 19:07:39 downsj Exp $ */ |
| 2 | |||
| 3 | /* | ||
| 4 | * ++Copyright++ 1985, 1993 | ||
| 5 | * - | ||
| 2 | * Copyright (c) 1985, 1993 | 6 | * Copyright (c) 1985, 1993 |
| 3 | * The Regents of the University of California. All rights reserved. | 7 | * The Regents of the University of California. All rights reserved. |
| 4 | * | 8 | * |
| 5 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions |
| 7 | * are met: | 11 | * are met: |
| @@ -12,12 +16,12 @@ | |||
| 12 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 17 | * 3. All advertising materials mentioning features or use of this software |
| 14 | * must display the following acknowledgement: | 18 | * must display the following acknowledgement: |
| 15 | * This product includes software developed by the University of | 19 | * This product includes software developed by the University of |
| 16 | * California, Berkeley and its contributors. | 20 | * California, Berkeley and its contributors. |
| 17 | * 4. Neither the name of the University nor the names of its contributors | 21 | * 4. Neither the name of the University nor the names of its contributors |
| 18 | * may be used to endorse or promote products derived from this software | 22 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 23 | * without specific prior written permission. |
| 20 | * | 24 | * |
| 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 25 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
| 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 26 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 27 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| @@ -52,14 +56,22 @@ | |||
| 52 | */ | 56 | */ |
| 53 | 57 | ||
| 54 | #if defined(LIBC_SCCS) && !defined(lint) | 58 | #if defined(LIBC_SCCS) && !defined(lint) |
| 55 | static char rcsid[] = "$OpenBSD: res_mkquery.c,v 1.5 1996/12/14 06:49:39 tholo Exp $"; | 59 | #if 0 |
| 60 | static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93"; | ||
| 61 | static char rcsid[] = "$From: res_mkquery.c,v 8.5 1996/08/27 08:33:28 vixie Exp $"; | ||
| 62 | #else | ||
| 63 | static char rcsid[] = "$OpenBSD: res_mkquery.c,v 1.6 1997/03/13 19:07:39 downsj Exp $"; | ||
| 64 | #endif | ||
| 56 | #endif /* LIBC_SCCS and not lint */ | 65 | #endif /* LIBC_SCCS and not lint */ |
| 57 | 66 | ||
| 67 | #include <sys/types.h> | ||
| 58 | #include <sys/param.h> | 68 | #include <sys/param.h> |
| 59 | #include <netinet/in.h> | 69 | #include <netinet/in.h> |
| 60 | #include <arpa/nameser.h> | 70 | #include <arpa/nameser.h> |
| 61 | #include <resolv.h> | 71 | |
| 62 | #include <stdio.h> | 72 | #include <stdio.h> |
| 73 | #include <netdb.h> | ||
| 74 | #include <resolv.h> | ||
| 63 | #include <string.h> | 75 | #include <string.h> |
| 64 | 76 | ||
| 65 | /* | 77 | /* |
| @@ -70,9 +82,9 @@ static char rcsid[] = "$OpenBSD: res_mkquery.c,v 1.5 1996/12/14 06:49:39 tholo E | |||
| 70 | int | 82 | int |
| 71 | res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen) | 83 | res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen) |
| 72 | int op; /* opcode of query */ | 84 | int op; /* opcode of query */ |
| 73 | const char *dname; /* domain name */ | 85 | const char *dname; /* domain name */ |
| 74 | int class, type; /* class and type of query */ | 86 | int class, type; /* class and type of query */ |
| 75 | const u_char *data; /* resource record data */ | 87 | const u_char *data; /* resource record data */ |
| 76 | int datalen; /* length of data */ | 88 | int datalen; /* length of data */ |
| 77 | const u_char *newrr_in; /* new rr for modify or append */ | 89 | const u_char *newrr_in; /* new rr for modify or append */ |
| 78 | u_char *buf; /* buffer to put query */ | 90 | u_char *buf; /* buffer to put query */ |
| @@ -81,11 +93,12 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen) | |||
| 81 | register HEADER *hp; | 93 | register HEADER *hp; |
| 82 | register u_char *cp; | 94 | register u_char *cp; |
| 83 | register int n; | 95 | register int n; |
| 84 | #ifdef ALLOW_UPDATES | 96 | u_char *dnptrs[20], **dpp, **lastdnptr; |
| 85 | struct rrec *newrr = (struct rrec *) newrr_in; | ||
| 86 | #endif /* ALLOW_UPDATES */ | ||
| 87 | u_char *dnptrs[10], **dpp, **lastdnptr; | ||
| 88 | 97 | ||
| 98 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) { | ||
| 99 | h_errno = NETDB_INTERNAL; | ||
| 100 | return (-1); | ||
| 101 | } | ||
| 89 | #ifdef DEBUG | 102 | #ifdef DEBUG |
| 90 | if (_res.options & RES_DEBUG) | 103 | if (_res.options & RES_DEBUG) |
| 91 | printf(";; res_mkquery(%d, %s, %d, %d)\n", | 104 | printf(";; res_mkquery(%d, %s, %d, %d)\n", |
| @@ -94,37 +107,36 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen) | |||
| 94 | /* | 107 | /* |
| 95 | * Initialize header fields. | 108 | * Initialize header fields. |
| 96 | */ | 109 | */ |
| 97 | if ((buf == NULL) || (buflen < sizeof(HEADER))) | 110 | if ((buf == NULL) || (buflen < HFIXEDSZ)) |
| 98 | return(-1); | 111 | return (-1); |
| 99 | bzero(buf, sizeof(HEADER)); | 112 | bzero(buf, HFIXEDSZ); |
| 100 | hp = (HEADER *) buf; | 113 | hp = (HEADER *) buf; |
| 101 | hp->id = htons(++_res.id); | 114 | hp->id = htons(++_res.id); |
| 102 | hp->opcode = op; | 115 | hp->opcode = op; |
| 103 | hp->pr = (_res.options & RES_PRIMARY) != 0; | ||
| 104 | hp->rd = (_res.options & RES_RECURSE) != 0; | 116 | hp->rd = (_res.options & RES_RECURSE) != 0; |
| 105 | hp->rcode = NOERROR; | 117 | hp->rcode = NOERROR; |
| 106 | cp = buf + sizeof(HEADER); | 118 | cp = buf + HFIXEDSZ; |
| 107 | buflen -= sizeof(HEADER); | 119 | buflen -= HFIXEDSZ; |
| 108 | dpp = dnptrs; | 120 | dpp = dnptrs; |
| 109 | *dpp++ = buf; | 121 | *dpp++ = buf; |
| 110 | *dpp++ = NULL; | 122 | *dpp++ = NULL; |
| 111 | lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]); | 123 | lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0]; |
| 112 | /* | 124 | /* |
| 113 | * perform opcode specific processing | 125 | * perform opcode specific processing |
| 114 | */ | 126 | */ |
| 115 | switch (op) { | 127 | switch (op) { |
| 116 | case QUERY: | 128 | case QUERY: /*FALLTHROUGH*/ |
| 117 | case NS_NOTIFY_OP: | 129 | case NS_NOTIFY_OP: |
| 118 | if ((buflen -= QFIXEDSZ) < 0) | 130 | if ((buflen -= QFIXEDSZ) < 0) |
| 119 | return(-1); | 131 | return (-1); |
| 120 | if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) | 132 | if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) |
| 121 | return (-1); | 133 | return (-1); |
| 122 | cp += n; | 134 | cp += n; |
| 123 | buflen -= n; | 135 | buflen -= n; |
| 124 | __putshort(type, cp); | 136 | __putshort(type, cp); |
| 125 | cp += sizeof(u_int16_t); | 137 | cp += INT16SZ; |
| 126 | __putshort(class, cp); | 138 | __putshort(class, cp); |
| 127 | cp += sizeof(u_int16_t); | 139 | cp += INT16SZ; |
| 128 | hp->qdcount = htons(1); | 140 | hp->qdcount = htons(1); |
| 129 | if (op == QUERY || data == NULL) | 141 | if (op == QUERY || data == NULL) |
| 130 | break; | 142 | break; |
| @@ -132,18 +144,19 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen) | |||
| 132 | * Make an additional record for completion domain. | 144 | * Make an additional record for completion domain. |
| 133 | */ | 145 | */ |
| 134 | buflen -= RRFIXEDSZ; | 146 | buflen -= RRFIXEDSZ; |
| 135 | if ((n = dn_comp((const char *)data, cp, buflen, dnptrs, lastdnptr)) < 0) | 147 | n = dn_comp((char *)data, cp, buflen, dnptrs, lastdnptr); |
| 148 | if (n < 0) | ||
| 136 | return (-1); | 149 | return (-1); |
| 137 | cp += n; | 150 | cp += n; |
| 138 | buflen -= n; | 151 | buflen -= n; |
| 139 | __putshort(T_NULL, cp); | 152 | __putshort(T_NULL, cp); |
| 140 | cp += sizeof(u_int16_t); | 153 | cp += INT16SZ; |
| 141 | __putshort(class, cp); | 154 | __putshort(class, cp); |
| 142 | cp += sizeof(u_int16_t); | 155 | cp += INT16SZ; |
| 143 | __putlong(0, cp); | 156 | __putlong(0, cp); |
| 144 | cp += sizeof(u_int32_t); | 157 | cp += INT32SZ; |
| 145 | __putshort(0, cp); | 158 | __putshort(0, cp); |
| 146 | cp += sizeof(u_int16_t); | 159 | cp += INT16SZ; |
| 147 | hp->arcount = htons(1); | 160 | hp->arcount = htons(1); |
| 148 | break; | 161 | break; |
| 149 | 162 | ||
| @@ -155,13 +168,13 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen) | |||
| 155 | return (-1); | 168 | return (-1); |
| 156 | *cp++ = '\0'; /* no domain name */ | 169 | *cp++ = '\0'; /* no domain name */ |
| 157 | __putshort(type, cp); | 170 | __putshort(type, cp); |
| 158 | cp += sizeof(u_int16_t); | 171 | cp += INT16SZ; |
| 159 | __putshort(class, cp); | 172 | __putshort(class, cp); |
| 160 | cp += sizeof(u_int16_t); | 173 | cp += INT16SZ; |
| 161 | __putlong(0, cp); | 174 | __putlong(0, cp); |
| 162 | cp += sizeof(u_int32_t); | 175 | cp += INT32SZ; |
| 163 | __putshort(datalen, cp); | 176 | __putshort(datalen, cp); |
| 164 | cp += sizeof(u_int16_t); | 177 | cp += INT16SZ; |
| 165 | if (datalen) { | 178 | if (datalen) { |
| 166 | bcopy(data, cp, datalen); | 179 | bcopy(data, cp, datalen); |
| 167 | cp += datalen; | 180 | cp += datalen; |
| @@ -169,64 +182,6 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen) | |||
| 169 | hp->ancount = htons(1); | 182 | hp->ancount = htons(1); |
| 170 | break; | 183 | break; |
| 171 | 184 | ||
| 172 | #ifdef ALLOW_UPDATES | ||
| 173 | /* | ||
| 174 | * For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA | ||
| 175 | * (Record to be modified is followed by its replacement in msg.) | ||
| 176 | */ | ||
| 177 | case UPDATEM: | ||
| 178 | case UPDATEMA: | ||
| 179 | |||
| 180 | case UPDATED: | ||
| 181 | /* | ||
| 182 | * The res code for UPDATED and UPDATEDA is the same; user | ||
| 183 | * calls them differently: specifies data for UPDATED; server | ||
| 184 | * ignores data if specified for UPDATEDA. | ||
| 185 | */ | ||
| 186 | case UPDATEDA: | ||
| 187 | buflen -= RRFIXEDSZ + datalen; | ||
| 188 | if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) | ||
| 189 | return (-1); | ||
| 190 | cp += n; | ||
| 191 | __putshort(type, cp); | ||
| 192 | cp += sizeof(u_int16_t); | ||
| 193 | __putshort(class, cp); | ||
| 194 | cp += sizeof(u_int16_t); | ||
| 195 | __putlong(0, cp); | ||
| 196 | cp += sizeof(u_int32_t); | ||
| 197 | __putshort(datalen, cp); | ||
| 198 | cp += sizeof(u_int16_t); | ||
| 199 | if (datalen) { | ||
| 200 | bcopy(data, cp, datalen); | ||
| 201 | cp += datalen; | ||
| 202 | } | ||
| 203 | if ( (op == UPDATED) || (op == UPDATEDA) ) { | ||
| 204 | hp->ancount = htons(0); | ||
| 205 | break; | ||
| 206 | } | ||
| 207 | /* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */ | ||
| 208 | |||
| 209 | case UPDATEA: /* Add new resource record */ | ||
| 210 | buflen -= RRFIXEDSZ + datalen; | ||
| 211 | if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) | ||
| 212 | return (-1); | ||
| 213 | cp += n; | ||
| 214 | __putshort(newrr->r_type, cp); | ||
| 215 | cp += sizeof(u_int16_t); | ||
| 216 | __putshort(newrr->r_class, cp); | ||
| 217 | cp += sizeof(u_int16_t); | ||
| 218 | __putlong(0, cp); | ||
| 219 | cp += sizeof(u_int32_t); | ||
| 220 | __putshort(newrr->r_size, cp); | ||
| 221 | cp += sizeof(u_int16_t); | ||
| 222 | if (newrr->r_size) { | ||
| 223 | bcopy(newrr->r_data, cp, newrr->r_size); | ||
| 224 | cp += newrr->r_size; | ||
| 225 | } | ||
| 226 | hp->ancount = htons(0); | ||
| 227 | break; | ||
| 228 | |||
| 229 | #endif /* ALLOW_UPDATES */ | ||
| 230 | default: | 185 | default: |
| 231 | return (-1); | 186 | return (-1); |
| 232 | } | 187 | } |
diff --git a/src/lib/libc/net/res_query.c b/src/lib/libc/net/res_query.c index fb2d22c119..fcb3954009 100644 --- a/src/lib/libc/net/res_query.c +++ b/src/lib/libc/net/res_query.c | |||
| @@ -1,7 +1,11 @@ | |||
| 1 | /*- | 1 | /* $OpenBSD: res_query.c,v 1.8 1997/03/13 19:07:40 downsj Exp $ */ |
| 2 | |||
| 3 | /* | ||
| 4 | * ++Copyright++ 1988, 1993 | ||
| 5 | * - | ||
| 2 | * Copyright (c) 1988, 1993 | 6 | * Copyright (c) 1988, 1993 |
| 3 | * The Regents of the University of California. All rights reserved. | 7 | * The Regents of the University of California. All rights reserved. |
| 4 | * | 8 | * |
| 5 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions |
| 7 | * are met: | 11 | * are met: |
| @@ -12,12 +16,12 @@ | |||
| 12 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software | 17 | * 3. All advertising materials mentioning features or use of this software |
| 14 | * must display the following acknowledgement: | 18 | * must display the following acknowledgement: |
| 15 | * This product includes software developed by the University of | 19 | * This product includes software developed by the University of |
| 16 | * California, Berkeley and its contributors. | 20 | * California, Berkeley and its contributors. |
| 17 | * 4. Neither the name of the University nor the names of its contributors | 21 | * 4. Neither the name of the University nor the names of its contributors |
| 18 | * may be used to endorse or promote products derived from this software | 22 | * may be used to endorse or promote products derived from this software |
| 19 | * without specific prior written permission. | 23 | * without specific prior written permission. |
| 20 | * | 24 | * |
| 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 25 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
| 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 26 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 27 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| @@ -52,16 +56,23 @@ | |||
| 52 | */ | 56 | */ |
| 53 | 57 | ||
| 54 | #if defined(LIBC_SCCS) && !defined(lint) | 58 | #if defined(LIBC_SCCS) && !defined(lint) |
| 55 | static char rcsid[] = "$OpenBSD: res_query.c,v 1.7 1996/08/27 03:32:54 deraadt Exp $"; | 59 | #if 0 |
| 60 | static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93"; | ||
| 61 | static char rcsid[] = "$From: res_query.c,v 8.9 1996/09/22 00:13:28 vixie Exp $"; | ||
| 62 | #else | ||
| 63 | static char rcsid[] = "$OpenBSD: res_query.c,v 1.8 1997/03/13 19:07:40 downsj Exp $"; | ||
| 64 | #endif | ||
| 56 | #endif /* LIBC_SCCS and not lint */ | 65 | #endif /* LIBC_SCCS and not lint */ |
| 57 | 66 | ||
| 67 | #include <sys/types.h> | ||
| 58 | #include <sys/param.h> | 68 | #include <sys/param.h> |
| 59 | #include <netinet/in.h> | 69 | #include <netinet/in.h> |
| 60 | #include <arpa/inet.h> | 70 | #include <arpa/inet.h> |
| 61 | #include <arpa/nameser.h> | 71 | #include <arpa/nameser.h> |
| 72 | |||
| 73 | #include <stdio.h> | ||
| 62 | #include <netdb.h> | 74 | #include <netdb.h> |
| 63 | #include <resolv.h> | 75 | #include <resolv.h> |
| 64 | #include <stdio.h> | ||
| 65 | #include <ctype.h> | 76 | #include <ctype.h> |
| 66 | #include <errno.h> | 77 | #include <errno.h> |
| 67 | #include <stdlib.h> | 78 | #include <stdlib.h> |
| @@ -73,7 +84,7 @@ static char rcsid[] = "$OpenBSD: res_query.c,v 1.7 1996/08/27 03:32:54 deraadt E | |||
| 73 | #define MAXPACKET 1024 | 84 | #define MAXPACKET 1024 |
| 74 | #endif | 85 | #endif |
| 75 | 86 | ||
| 76 | char *__hostalias __P((const char *)); | 87 | const char *hostalias __P((const char *)); |
| 77 | int h_errno; | 88 | int h_errno; |
| 78 | 89 | ||
| 79 | /* | 90 | /* |
| @@ -109,7 +120,7 @@ res_query(name, class, type, answer, anslen) | |||
| 109 | #endif | 120 | #endif |
| 110 | 121 | ||
| 111 | n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL, | 122 | n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL, |
| 112 | buf, sizeof(buf)); | 123 | buf, sizeof(buf)); |
| 113 | if (n <= 0) { | 124 | if (n <= 0) { |
| 114 | #ifdef DEBUG | 125 | #ifdef DEBUG |
| 115 | if (_res.options & RES_DEBUG) | 126 | if (_res.options & RES_DEBUG) |
| @@ -128,7 +139,6 @@ res_query(name, class, type, answer, anslen) | |||
| 128 | return (n); | 139 | return (n); |
| 129 | } | 140 | } |
| 130 | 141 | ||
| 131 | hp = (HEADER *) answer; | ||
| 132 | if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) { | 142 | if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) { |
| 133 | #ifdef DEBUG | 143 | #ifdef DEBUG |
| 134 | if (_res.options & RES_DEBUG) | 144 | if (_res.options & RES_DEBUG) |
| @@ -136,21 +146,21 @@ res_query(name, class, type, answer, anslen) | |||
| 136 | ntohs(hp->ancount)); | 146 | ntohs(hp->ancount)); |
| 137 | #endif | 147 | #endif |
| 138 | switch (hp->rcode) { | 148 | switch (hp->rcode) { |
| 139 | case NXDOMAIN: | 149 | case NXDOMAIN: |
| 140 | h_errno = HOST_NOT_FOUND; | 150 | h_errno = HOST_NOT_FOUND; |
| 141 | break; | 151 | break; |
| 142 | case SERVFAIL: | 152 | case SERVFAIL: |
| 143 | h_errno = TRY_AGAIN; | 153 | h_errno = TRY_AGAIN; |
| 144 | break; | 154 | break; |
| 145 | case NOERROR: | 155 | case NOERROR: |
| 146 | h_errno = NO_DATA; | 156 | h_errno = NO_DATA; |
| 147 | break; | 157 | break; |
| 148 | case FORMERR: | 158 | case FORMERR: |
| 149 | case NOTIMP: | 159 | case NOTIMP: |
| 150 | case REFUSED: | 160 | case REFUSED: |
| 151 | default: | 161 | default: |
| 152 | h_errno = NO_RECOVERY; | 162 | h_errno = NO_RECOVERY; |
| 153 | break; | 163 | break; |
| 154 | } | 164 | } |
| 155 | return (-1); | 165 | return (-1); |
| 156 | } | 166 | } |
| @@ -161,9 +171,7 @@ res_query(name, class, type, answer, anslen) | |||
| 161 | * Formulate a normal query, send, and retrieve answer in supplied buffer. | 171 | * Formulate a normal query, send, and retrieve answer in supplied buffer. |
| 162 | * Return the size of the response on success, -1 on error. | 172 | * Return the size of the response on success, -1 on error. |
| 163 | * If enabled, implement search rules until answer or unrecoverable failure | 173 | * If enabled, implement search rules until answer or unrecoverable failure |
| 164 | * is detected. Error number is left in h_errno. | 174 | * is detected. Error code, if any, is left in h_errno. |
| 165 | * Only useful for queries in the same name hierarchy as the local host | ||
| 166 | * (not, for example, for host address-to-name lookups in domain in-addr.arpa). | ||
| 167 | */ | 175 | */ |
| 168 | int | 176 | int |
| 169 | res_search(name, class, type, answer, anslen) | 177 | res_search(name, class, type, answer, anslen) |
| @@ -172,7 +180,7 @@ res_search(name, class, type, answer, anslen) | |||
| 172 | u_char *answer; /* buffer to put answer */ | 180 | u_char *answer; /* buffer to put answer */ |
| 173 | int anslen; /* size of answer */ | 181 | int anslen; /* size of answer */ |
| 174 | { | 182 | { |
| 175 | register char *cp, **domain; | 183 | register const char *cp, * const *domain; |
| 176 | HEADER *hp = (HEADER *) answer; | 184 | HEADER *hp = (HEADER *) answer; |
| 177 | u_int dots; | 185 | u_int dots; |
| 178 | int trailing_dot, ret, saved_herrno; | 186 | int trailing_dot, ret, saved_herrno; |
| @@ -182,15 +190,11 @@ res_search(name, class, type, answer, anslen) | |||
| 182 | h_errno = NETDB_INTERNAL; | 190 | h_errno = NETDB_INTERNAL; |
| 183 | return (-1); | 191 | return (-1); |
| 184 | } | 192 | } |
| 185 | |||
| 186 | got_nodata = 0; | ||
| 187 | errno = 0; | 193 | errno = 0; |
| 188 | h_errno = HOST_NOT_FOUND; /* default, if we never query */ | 194 | h_errno = HOST_NOT_FOUND; /* default, if we never query */ |
| 189 | dots = 0; | 195 | dots = 0; |
| 190 | for (cp = (char *)name; *cp; cp++) { | 196 | for (cp = name; *cp; cp++) |
| 191 | if (*cp == '.') | 197 | dots += (*cp == '.'); |
| 192 | dots++; | ||
| 193 | } | ||
| 194 | trailing_dot = 0; | 198 | trailing_dot = 0; |
| 195 | if (cp > name && *--cp == '.') | 199 | if (cp > name && *--cp == '.') |
| 196 | trailing_dot++; | 200 | trailing_dot++; |
| @@ -206,7 +210,6 @@ res_search(name, class, type, answer, anslen) | |||
| 206 | * 'as is'. The threshold can be set with the "ndots" option. | 210 | * 'as is'. The threshold can be set with the "ndots" option. |
| 207 | */ | 211 | */ |
| 208 | saved_herrno = -1; | 212 | saved_herrno = -1; |
| 209 | tried_as_is = 0; | ||
| 210 | if (dots >= _res.ndots) { | 213 | if (dots >= _res.ndots) { |
| 211 | ret = res_querydomain(name, NULL, class, type, answer, anslen); | 214 | ret = res_querydomain(name, NULL, class, type, answer, anslen); |
| 212 | if (ret > 0) | 215 | if (ret > 0) |
| @@ -223,13 +226,17 @@ res_search(name, class, type, answer, anslen) | |||
| 223 | */ | 226 | */ |
| 224 | if ((!dots && (_res.options & RES_DEFNAMES)) || | 227 | if ((!dots && (_res.options & RES_DEFNAMES)) || |
| 225 | (dots && !trailing_dot && (_res.options & RES_DNSRCH))) { | 228 | (dots && !trailing_dot && (_res.options & RES_DNSRCH))) { |
| 226 | for (domain = _res.dnsrch; *domain; domain++) { | 229 | int done = 0; |
| 227 | int done = 0; | 230 | |
| 231 | for (domain = (const char * const *)_res.dnsrch; | ||
| 232 | *domain && !done; | ||
| 233 | domain++) { | ||
| 228 | 234 | ||
| 229 | ret = res_querydomain(name, *domain, class, type, | 235 | ret = res_querydomain(name, *domain, class, type, |
| 230 | answer, anslen); | 236 | answer, anslen); |
| 231 | if (ret > 0) | 237 | if (ret > 0) |
| 232 | return (ret); | 238 | return (ret); |
| 239 | |||
| 233 | /* | 240 | /* |
| 234 | * If no server present, give up. | 241 | * If no server present, give up. |
| 235 | * If name isn't found in this domain, | 242 | * If name isn't found in this domain, |
| @@ -266,20 +273,16 @@ res_search(name, class, type, answer, anslen) | |||
| 266 | /* anything else implies that we're done */ | 273 | /* anything else implies that we're done */ |
| 267 | done++; | 274 | done++; |
| 268 | } | 275 | } |
| 269 | /* | 276 | |
| 270 | * if we got here for some reason other than DNSRCH, | 277 | /* if we got here for some reason other than DNSRCH, |
| 271 | * we only wanted one iteration of the loop, so stop. | 278 | * we only wanted one iteration of the loop, so stop. |
| 272 | */ | 279 | */ |
| 273 | if (!(_res.options & RES_DNSRCH)) | 280 | if (!(_res.options & RES_DNSRCH)) |
| 274 | done++; | 281 | done++; |
| 275 | |||
| 276 | if (done) | ||
| 277 | break; | ||
| 278 | } | 282 | } |
| 279 | } | 283 | } |
| 280 | 284 | ||
| 281 | /* | 285 | /* if we have not already tried the name "as is", do that now. |
| 282 | * if we have not already tried the name "as is", do that now. | ||
| 283 | * note that we do this regardless of how many dots were in the | 286 | * note that we do this regardless of how many dots were in the |
| 284 | * name or whether it ends with a dot. | 287 | * name or whether it ends with a dot. |
| 285 | */ | 288 | */ |
| @@ -287,11 +290,9 @@ res_search(name, class, type, answer, anslen) | |||
| 287 | ret = res_querydomain(name, NULL, class, type, answer, anslen); | 290 | ret = res_querydomain(name, NULL, class, type, answer, anslen); |
| 288 | if (ret > 0) | 291 | if (ret > 0) |
| 289 | return (ret); | 292 | return (ret); |
| 290 | saved_herrno = h_errno; | ||
| 291 | } | 293 | } |
| 292 | 294 | ||
| 293 | /* | 295 | /* if we got here, we didn't satisfy the search. |
| 294 | * if we got here, we didn't satisfy the search. | ||
| 295 | * if we did an initial full query, return that query's h_errno | 296 | * if we did an initial full query, return that query's h_errno |
| 296 | * (note that we wouldn't be here if that query had succeeded). | 297 | * (note that we wouldn't be here if that query had succeeded). |
| 297 | * else if we ever got a nodata, send that back as the reason. | 298 | * else if we ever got a nodata, send that back as the reason. |
| @@ -318,7 +319,7 @@ res_querydomain(name, domain, class, type, answer, anslen) | |||
| 318 | u_char *answer; /* buffer to put answer */ | 319 | u_char *answer; /* buffer to put answer */ |
| 319 | int anslen; /* size of answer */ | 320 | int anslen; /* size of answer */ |
| 320 | { | 321 | { |
| 321 | char nbuf[2*MAXDNAME+2]; | 322 | char nbuf[MAXDNAME]; |
| 322 | const char *longname = nbuf; | 323 | const char *longname = nbuf; |
| 323 | int n; | 324 | int n; |
| 324 | 325 | ||
| @@ -329,7 +330,7 @@ res_querydomain(name, domain, class, type, answer, anslen) | |||
| 329 | #ifdef DEBUG | 330 | #ifdef DEBUG |
| 330 | if (_res.options & RES_DEBUG) | 331 | if (_res.options & RES_DEBUG) |
| 331 | printf(";; res_querydomain(%s, %s, %d, %d)\n", | 332 | printf(";; res_querydomain(%s, %s, %d, %d)\n", |
| 332 | name, domain?domain:"<Nil>", class, type); | 333 | name, domain?domain:"<Nil>", class, type); |
| 333 | #endif | 334 | #endif |
| 334 | if (domain == NULL) { | 335 | if (domain == NULL) { |
| 335 | /* | 336 | /* |
| @@ -343,14 +344,13 @@ res_querydomain(name, domain, class, type, answer, anslen) | |||
| 343 | } else | 344 | } else |
| 344 | longname = name; | 345 | longname = name; |
| 345 | } else | 346 | } else |
| 346 | (void)sprintf(nbuf, "%.*s.%.*s", | 347 | sprintf(nbuf, "%.*s.%.*s", MAXDNAME, name, MAXDNAME, domain); |
| 347 | MAXDNAME, name, MAXDNAME, domain); | ||
| 348 | 348 | ||
| 349 | return (res_query(longname, class, type, answer, anslen)); | 349 | return (res_query(longname, class, type, answer, anslen)); |
| 350 | } | 350 | } |
| 351 | 351 | ||
| 352 | char * | 352 | const char * |
| 353 | __hostalias(name) | 353 | hostalias(name) |
| 354 | register const char *name; | 354 | register const char *name; |
| 355 | { | 355 | { |
| 356 | register char *cp1, *cp2; | 356 | register char *cp1, *cp2; |
| @@ -379,7 +379,7 @@ __hostalias(name) | |||
| 379 | break; | 379 | break; |
| 380 | for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2) | 380 | for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2) |
| 381 | ; | 381 | ; |
| 382 | (void)strncpy(abuf, cp1, sizeof(abuf) - 1); | 382 | strncpy(abuf, cp1, sizeof(abuf) - 1); |
| 383 | abuf[sizeof(abuf) - 1] = *cp2 = '\0'; | 383 | abuf[sizeof(abuf) - 1] = *cp2 = '\0'; |
| 384 | fclose(fp); | 384 | fclose(fp); |
| 385 | return (abuf); | 385 | return (abuf); |
diff --git a/src/lib/libc/net/res_send.c b/src/lib/libc/net/res_send.c index 1efd17df2b..bfc01f9b6a 100644 --- a/src/lib/libc/net/res_send.c +++ b/src/lib/libc/net/res_send.c | |||
| @@ -1,4 +1,8 @@ | |||
| 1 | /*- | 1 | /* $OpenBSD: res_send.c,v 1.4 1997/03/13 19:07:41 downsj Exp $ */ |
| 2 | |||
| 3 | /* | ||
| 4 | * ++Copyright++ 1985, 1989, 1993 | ||
| 5 | * - | ||
| 2 | * Copyright (c) 1985, 1989, 1993 | 6 | * Copyright (c) 1985, 1989, 1993 |
| 3 | * The Regents of the University of California. All rights reserved. | 7 | * The Regents of the University of California. All rights reserved. |
| 4 | * | 8 | * |
| @@ -52,7 +56,12 @@ | |||
| 52 | */ | 56 | */ |
| 53 | 57 | ||
| 54 | #if defined(LIBC_SCCS) && !defined(lint) | 58 | #if defined(LIBC_SCCS) && !defined(lint) |
| 55 | static char rcsid[] = "$OpenBSD: res_send.c,v 1.3 1996/08/19 08:29:49 tholo Exp $"; | 59 | #if 0 |
| 60 | static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93"; | ||
| 61 | static char rcsid[] = "$From: res_send.c,v 8.12 1996/10/08 04:51:06 vixie Exp $"; | ||
| 62 | #else | ||
| 63 | static char rcsid[] = "$OpenBSD: res_send.c,v 1.4 1997/03/13 19:07:41 downsj Exp $"; | ||
| 64 | #endif | ||
| 56 | #endif /* LIBC_SCCS and not lint */ | 65 | #endif /* LIBC_SCCS and not lint */ |
| 57 | 66 | ||
| 58 | /* change this to "0" | 67 | /* change this to "0" |
| @@ -66,6 +75,7 @@ static char rcsid[] = "$OpenBSD: res_send.c,v 1.3 1996/08/19 08:29:49 tholo Exp | |||
| 66 | * Send query to name server and wait for reply. | 75 | * Send query to name server and wait for reply. |
| 67 | */ | 76 | */ |
| 68 | 77 | ||
| 78 | #include <sys/types.h> | ||
| 69 | #include <sys/param.h> | 79 | #include <sys/param.h> |
| 70 | #include <sys/time.h> | 80 | #include <sys/time.h> |
| 71 | #include <sys/socket.h> | 81 | #include <sys/socket.h> |
| @@ -78,24 +88,24 @@ static char rcsid[] = "$OpenBSD: res_send.c,v 1.3 1996/08/19 08:29:49 tholo Exp | |||
| 78 | #include <netdb.h> | 88 | #include <netdb.h> |
| 79 | #include <errno.h> | 89 | #include <errno.h> |
| 80 | #include <resolv.h> | 90 | #include <resolv.h> |
| 81 | #if defined(BSD) && (BSD >= 199306) | 91 | #include <stdlib.h> |
| 82 | # include <stdlib.h> | 92 | #include <string.h> |
| 83 | # include <string.h> | 93 | #include <unistd.h> |
| 84 | # include <unistd.h> | ||
| 85 | #else | ||
| 86 | # include "../conf/portability.h" | ||
| 87 | #endif | ||
| 88 | |||
| 89 | #if defined(USE_OPTIONS_H) | ||
| 90 | # include <../conf/options.h> | ||
| 91 | #endif | ||
| 92 | |||
| 93 | void _res_close __P((void)); | ||
| 94 | 94 | ||
| 95 | static int s = -1; /* socket used for communications */ | 95 | static int s = -1; /* socket used for communications */ |
| 96 | static int connected = 0; /* is the socket connected */ | 96 | static int connected = 0; /* is the socket connected */ |
| 97 | static int vc = 0; /* is the socket a virtual ciruit? */ | 97 | static int vc = 0; /* is the socket a virtual ciruit? */ |
| 98 | 98 | ||
| 99 | #ifndef FD_SET | ||
| 100 | /* XXX - should be in portability.h */ | ||
| 101 | #define NFDBITS 32 | ||
| 102 | #define FD_SETSIZE 32 | ||
| 103 | #define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS))) | ||
| 104 | #define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS))) | ||
| 105 | #define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS))) | ||
| 106 | #define FD_ZERO(p) bzero((char *)(p), sizeof(*(p))) | ||
| 107 | #endif | ||
| 108 | |||
| 99 | #define CAN_RECONNECT 1 | 109 | #define CAN_RECONNECT 1 |
| 100 | 110 | ||
| 101 | #ifndef DEBUG | 111 | #ifndef DEBUG |
| @@ -301,7 +311,7 @@ res_send(buf, buflen, ans, anssiz) | |||
| 301 | struct sockaddr_in *nsap = &_res.nsaddr_list[ns]; | 311 | struct sockaddr_in *nsap = &_res.nsaddr_list[ns]; |
| 302 | same_ns: | 312 | same_ns: |
| 303 | if (badns & (1 << ns)) { | 313 | if (badns & (1 << ns)) { |
| 304 | _res_close(); | 314 | res_close(); |
| 305 | goto next_ns; | 315 | goto next_ns; |
| 306 | } | 316 | } |
| 307 | 317 | ||
| @@ -318,7 +328,7 @@ res_send(buf, buflen, ans, anssiz) | |||
| 318 | done = 1; | 328 | done = 1; |
| 319 | break; | 329 | break; |
| 320 | case res_nextns: | 330 | case res_nextns: |
| 321 | _res_close(); | 331 | res_close(); |
| 322 | goto next_ns; | 332 | goto next_ns; |
| 323 | case res_done: | 333 | case res_done: |
| 324 | return (resplen); | 334 | return (resplen); |
| @@ -353,7 +363,7 @@ res_send(buf, buflen, ans, anssiz) | |||
| 353 | truncated = 0; | 363 | truncated = 0; |
| 354 | if ((s < 0) || (!vc)) { | 364 | if ((s < 0) || (!vc)) { |
| 355 | if (s >= 0) | 365 | if (s >= 0) |
| 356 | _res_close(); | 366 | res_close(); |
| 357 | 367 | ||
| 358 | s = socket(PF_INET, SOCK_STREAM, 0); | 368 | s = socket(PF_INET, SOCK_STREAM, 0); |
| 359 | if (s < 0) { | 369 | if (s < 0) { |
| @@ -368,7 +378,7 @@ res_send(buf, buflen, ans, anssiz) | |||
| 368 | Aerror(stderr, "connect/vc", | 378 | Aerror(stderr, "connect/vc", |
| 369 | errno, *nsap); | 379 | errno, *nsap); |
| 370 | badns |= (1 << ns); | 380 | badns |= (1 << ns); |
| 371 | _res_close(); | 381 | res_close(); |
| 372 | goto next_ns; | 382 | goto next_ns; |
| 373 | } | 383 | } |
| 374 | vc = 1; | 384 | vc = 1; |
| @@ -385,12 +395,13 @@ res_send(buf, buflen, ans, anssiz) | |||
| 385 | terrno = errno; | 395 | terrno = errno; |
| 386 | Perror(stderr, "write failed", errno); | 396 | Perror(stderr, "write failed", errno); |
| 387 | badns |= (1 << ns); | 397 | badns |= (1 << ns); |
| 388 | _res_close(); | 398 | res_close(); |
| 389 | goto next_ns; | 399 | goto next_ns; |
| 390 | } | 400 | } |
| 391 | /* | 401 | /* |
| 392 | * Receive length & response | 402 | * Receive length & response |
| 393 | */ | 403 | */ |
| 404 | read_len: | ||
| 394 | cp = ans; | 405 | cp = ans; |
| 395 | len = INT16SZ; | 406 | len = INT16SZ; |
| 396 | while ((n = read(s, (char *)cp, (int)len)) > 0) { | 407 | while ((n = read(s, (char *)cp, (int)len)) > 0) { |
| @@ -401,7 +412,7 @@ res_send(buf, buflen, ans, anssiz) | |||
| 401 | if (n <= 0) { | 412 | if (n <= 0) { |
| 402 | terrno = errno; | 413 | terrno = errno; |
| 403 | Perror(stderr, "read failed", errno); | 414 | Perror(stderr, "read failed", errno); |
| 404 | _res_close(); | 415 | res_close(); |
| 405 | /* | 416 | /* |
| 406 | * A long running process might get its TCP | 417 | * A long running process might get its TCP |
| 407 | * connection reset if the remote server was | 418 | * connection reset if the remote server was |
| @@ -413,10 +424,10 @@ res_send(buf, buflen, ans, anssiz) | |||
| 413 | */ | 424 | */ |
| 414 | if (terrno == ECONNRESET && !connreset) { | 425 | if (terrno == ECONNRESET && !connreset) { |
| 415 | connreset = 1; | 426 | connreset = 1; |
| 416 | _res_close(); | 427 | res_close(); |
| 417 | goto same_ns; | 428 | goto same_ns; |
| 418 | } | 429 | } |
| 419 | _res_close(); | 430 | res_close(); |
| 420 | goto next_ns; | 431 | goto next_ns; |
| 421 | } | 432 | } |
| 422 | resplen = _getshort(ans); | 433 | resplen = _getshort(ans); |
| @@ -437,7 +448,7 @@ res_send(buf, buflen, ans, anssiz) | |||
| 437 | if (n <= 0) { | 448 | if (n <= 0) { |
| 438 | terrno = errno; | 449 | terrno = errno; |
| 439 | Perror(stderr, "read(vc)", errno); | 450 | Perror(stderr, "read(vc)", errno); |
| 440 | _res_close(); | 451 | res_close(); |
| 441 | goto next_ns; | 452 | goto next_ns; |
| 442 | } | 453 | } |
| 443 | if (truncated) { | 454 | if (truncated) { |
| @@ -459,6 +470,20 @@ res_send(buf, buflen, ans, anssiz) | |||
| 459 | break; | 470 | break; |
| 460 | } | 471 | } |
| 461 | } | 472 | } |
| 473 | /* | ||
| 474 | * The calling applicating has bailed out of | ||
| 475 | * a previous call and failed to arrange to have | ||
| 476 | * the circuit closed or the server has got | ||
| 477 | * itself confused. Anyway drop the packet and | ||
| 478 | * wait for the correct one. | ||
| 479 | */ | ||
| 480 | if (hp->id != anhp->id) { | ||
| 481 | DprintQ((_res.options & RES_DEBUG) || | ||
| 482 | (_res.pfcode & RES_PRF_REPLY), | ||
| 483 | (stdout, ";; old answer (unexpected):\n"), | ||
| 484 | ans, (resplen>anssiz)?anssiz:resplen); | ||
| 485 | goto read_len; | ||
| 486 | } | ||
| 462 | } else { | 487 | } else { |
| 463 | /* | 488 | /* |
| 464 | * Use datagrams. | 489 | * Use datagrams. |
| @@ -470,7 +495,7 @@ res_send(buf, buflen, ans, anssiz) | |||
| 470 | 495 | ||
| 471 | if ((s < 0) || vc) { | 496 | if ((s < 0) || vc) { |
| 472 | if (vc) | 497 | if (vc) |
| 473 | _res_close(); | 498 | res_close(); |
| 474 | s = socket(PF_INET, SOCK_DGRAM, 0); | 499 | s = socket(PF_INET, SOCK_DGRAM, 0); |
| 475 | if (s < 0) { | 500 | if (s < 0) { |
| 476 | #if !CAN_RECONNECT | 501 | #if !CAN_RECONNECT |
| @@ -510,7 +535,7 @@ res_send(buf, buflen, ans, anssiz) | |||
| 510 | "connect(dg)", | 535 | "connect(dg)", |
| 511 | errno, *nsap); | 536 | errno, *nsap); |
| 512 | badns |= (1 << ns); | 537 | badns |= (1 << ns); |
| 513 | _res_close(); | 538 | res_close(); |
| 514 | goto next_ns; | 539 | goto next_ns; |
| 515 | } | 540 | } |
| 516 | connected = 1; | 541 | connected = 1; |
| @@ -518,7 +543,7 @@ res_send(buf, buflen, ans, anssiz) | |||
| 518 | if (send(s, (char*)buf, buflen, 0) != buflen) { | 543 | if (send(s, (char*)buf, buflen, 0) != buflen) { |
| 519 | Perror(stderr, "send", errno); | 544 | Perror(stderr, "send", errno); |
| 520 | badns |= (1 << ns); | 545 | badns |= (1 << ns); |
| 521 | _res_close(); | 546 | res_close(); |
| 522 | goto next_ns; | 547 | goto next_ns; |
| 523 | } | 548 | } |
| 524 | } else { | 549 | } else { |
| @@ -555,7 +580,7 @@ res_send(buf, buflen, ans, anssiz) | |||
| 555 | != buflen) { | 580 | != buflen) { |
| 556 | Aerror(stderr, "sendto", errno, *nsap); | 581 | Aerror(stderr, "sendto", errno, *nsap); |
| 557 | badns |= (1 << ns); | 582 | badns |= (1 << ns); |
| 558 | _res_close(); | 583 | res_close(); |
| 559 | goto next_ns; | 584 | goto next_ns; |
| 560 | } | 585 | } |
| 561 | } | 586 | } |
| @@ -575,8 +600,10 @@ res_send(buf, buflen, ans, anssiz) | |||
| 575 | n = select(s+1, &dsmask, (fd_set *)NULL, | 600 | n = select(s+1, &dsmask, (fd_set *)NULL, |
| 576 | (fd_set *)NULL, &timeout); | 601 | (fd_set *)NULL, &timeout); |
| 577 | if (n < 0) { | 602 | if (n < 0) { |
| 603 | if (errno == EINTR) | ||
| 604 | goto wait; | ||
| 578 | Perror(stderr, "select", errno); | 605 | Perror(stderr, "select", errno); |
| 579 | _res_close(); | 606 | res_close(); |
| 580 | goto next_ns; | 607 | goto next_ns; |
| 581 | } | 608 | } |
| 582 | if (n == 0) { | 609 | if (n == 0) { |
| @@ -586,7 +613,7 @@ res_send(buf, buflen, ans, anssiz) | |||
| 586 | Dprint(_res.options & RES_DEBUG, | 613 | Dprint(_res.options & RES_DEBUG, |
| 587 | (stdout, ";; timeout\n")); | 614 | (stdout, ";; timeout\n")); |
| 588 | gotsomewhere = 1; | 615 | gotsomewhere = 1; |
| 589 | _res_close(); | 616 | res_close(); |
| 590 | goto next_ns; | 617 | goto next_ns; |
| 591 | } | 618 | } |
| 592 | errno = 0; | 619 | errno = 0; |
| @@ -595,7 +622,7 @@ res_send(buf, buflen, ans, anssiz) | |||
| 595 | (struct sockaddr *)&from, &fromlen); | 622 | (struct sockaddr *)&from, &fromlen); |
| 596 | if (resplen <= 0) { | 623 | if (resplen <= 0) { |
| 597 | Perror(stderr, "recvfrom", errno); | 624 | Perror(stderr, "recvfrom", errno); |
| 598 | _res_close(); | 625 | res_close(); |
| 599 | goto next_ns; | 626 | goto next_ns; |
| 600 | } | 627 | } |
| 601 | gotsomewhere = 1; | 628 | gotsomewhere = 1; |
| @@ -608,7 +635,7 @@ res_send(buf, buflen, ans, anssiz) | |||
| 608 | DprintQ((_res.options & RES_DEBUG) || | 635 | DprintQ((_res.options & RES_DEBUG) || |
| 609 | (_res.pfcode & RES_PRF_REPLY), | 636 | (_res.pfcode & RES_PRF_REPLY), |
| 610 | (stdout, ";; old answer:\n"), | 637 | (stdout, ";; old answer:\n"), |
| 611 | ans, resplen); | 638 | ans, (resplen>anssiz)?anssiz:resplen); |
| 612 | goto wait; | 639 | goto wait; |
| 613 | } | 640 | } |
| 614 | #if CHECK_SRVR_ADDR | 641 | #if CHECK_SRVR_ADDR |
| @@ -622,7 +649,7 @@ res_send(buf, buflen, ans, anssiz) | |||
| 622 | DprintQ((_res.options & RES_DEBUG) || | 649 | DprintQ((_res.options & RES_DEBUG) || |
| 623 | (_res.pfcode & RES_PRF_REPLY), | 650 | (_res.pfcode & RES_PRF_REPLY), |
| 624 | (stdout, ";; not our server:\n"), | 651 | (stdout, ";; not our server:\n"), |
| 625 | ans, resplen); | 652 | ans, (resplen>anssiz)?anssiz:resplen); |
| 626 | goto wait; | 653 | goto wait; |
| 627 | } | 654 | } |
| 628 | #endif | 655 | #endif |
| @@ -637,7 +664,7 @@ res_send(buf, buflen, ans, anssiz) | |||
| 637 | DprintQ((_res.options & RES_DEBUG) || | 664 | DprintQ((_res.options & RES_DEBUG) || |
| 638 | (_res.pfcode & RES_PRF_REPLY), | 665 | (_res.pfcode & RES_PRF_REPLY), |
| 639 | (stdout, ";; wrong query name:\n"), | 666 | (stdout, ";; wrong query name:\n"), |
| 640 | ans, resplen); | 667 | ans, (resplen>anssiz)?anssiz:resplen); |
| 641 | goto wait; | 668 | goto wait; |
| 642 | } | 669 | } |
| 643 | if (anhp->rcode == SERVFAIL || | 670 | if (anhp->rcode == SERVFAIL || |
| @@ -645,9 +672,9 @@ res_send(buf, buflen, ans, anssiz) | |||
| 645 | anhp->rcode == REFUSED) { | 672 | anhp->rcode == REFUSED) { |
| 646 | DprintQ(_res.options & RES_DEBUG, | 673 | DprintQ(_res.options & RES_DEBUG, |
| 647 | (stdout, "server rejected query:\n"), | 674 | (stdout, "server rejected query:\n"), |
| 648 | ans, resplen); | 675 | ans, (resplen>anssiz)?anssiz:resplen); |
| 649 | badns |= (1 << ns); | 676 | badns |= (1 << ns); |
| 650 | _res_close(); | 677 | res_close(); |
| 651 | /* don't retry if called from dig */ | 678 | /* don't retry if called from dig */ |
| 652 | if (!_res.pfcode) | 679 | if (!_res.pfcode) |
| 653 | goto next_ns; | 680 | goto next_ns; |
| @@ -660,7 +687,7 @@ res_send(buf, buflen, ans, anssiz) | |||
| 660 | Dprint(_res.options & RES_DEBUG, | 687 | Dprint(_res.options & RES_DEBUG, |
| 661 | (stdout, ";; truncated answer\n")); | 688 | (stdout, ";; truncated answer\n")); |
| 662 | v_circuit = 1; | 689 | v_circuit = 1; |
| 663 | _res_close(); | 690 | res_close(); |
| 664 | goto same_ns; | 691 | goto same_ns; |
| 665 | } | 692 | } |
| 666 | } /*if vc/dg*/ | 693 | } /*if vc/dg*/ |
| @@ -671,7 +698,7 @@ res_send(buf, buflen, ans, anssiz) | |||
| 671 | DprintQ((_res.options & RES_DEBUG) || | 698 | DprintQ((_res.options & RES_DEBUG) || |
| 672 | (_res.pfcode & RES_PRF_REPLY), | 699 | (_res.pfcode & RES_PRF_REPLY), |
| 673 | (stdout, ""), | 700 | (stdout, ""), |
| 674 | ans, resplen); | 701 | ans, (resplen>anssiz)?anssiz:resplen); |
| 675 | /* | 702 | /* |
| 676 | * If using virtual circuits, we assume that the first server | 703 | * If using virtual circuits, we assume that the first server |
| 677 | * is preferred over the rest (i.e. it is on the local | 704 | * is preferred over the rest (i.e. it is on the local |
| @@ -682,7 +709,7 @@ res_send(buf, buflen, ans, anssiz) | |||
| 682 | */ | 709 | */ |
| 683 | if ((v_circuit && (!(_res.options & RES_USEVC) || ns != 0)) || | 710 | if ((v_circuit && (!(_res.options & RES_USEVC) || ns != 0)) || |
| 684 | !(_res.options & RES_STAYOPEN)) { | 711 | !(_res.options & RES_STAYOPEN)) { |
| 685 | _res_close(); | 712 | res_close(); |
| 686 | } | 713 | } |
| 687 | if (Rhook) { | 714 | if (Rhook) { |
| 688 | int done = 0, loops = 0; | 715 | int done = 0, loops = 0; |
| @@ -698,7 +725,7 @@ res_send(buf, buflen, ans, anssiz) | |||
| 698 | done = 1; | 725 | done = 1; |
| 699 | break; | 726 | break; |
| 700 | case res_nextns: | 727 | case res_nextns: |
| 701 | _res_close(); | 728 | res_close(); |
| 702 | goto next_ns; | 729 | goto next_ns; |
| 703 | case res_modified: | 730 | case res_modified: |
| 704 | /* give the hook another try */ | 731 | /* give the hook another try */ |
| @@ -717,7 +744,7 @@ res_send(buf, buflen, ans, anssiz) | |||
| 717 | next_ns: ; | 744 | next_ns: ; |
| 718 | } /*foreach ns*/ | 745 | } /*foreach ns*/ |
| 719 | } /*foreach retry*/ | 746 | } /*foreach retry*/ |
| 720 | _res_close(); | 747 | res_close(); |
| 721 | if (!v_circuit) | 748 | if (!v_circuit) |
| 722 | if (!gotsomewhere) | 749 | if (!gotsomewhere) |
| 723 | errno = ECONNREFUSED; /* no nameservers found */ | 750 | errno = ECONNREFUSED; /* no nameservers found */ |
| @@ -736,7 +763,7 @@ res_send(buf, buflen, ans, anssiz) | |||
| 736 | * This routine is not expected to be user visible. | 763 | * This routine is not expected to be user visible. |
| 737 | */ | 764 | */ |
| 738 | void | 765 | void |
| 739 | _res_close() | 766 | res_close() |
| 740 | { | 767 | { |
| 741 | if (s >= 0) { | 768 | if (s >= 0) { |
| 742 | (void) close(s); | 769 | (void) close(s); |
