00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 #include "ink_config.h"
00070 #include "ink_defs.h"
00071
00072 #include <sys/types.h>
00073 #include <sys/param.h>
00074 #include <netinet/in.h>
00075 #include <arpa/nameser.h>
00076 #ifdef HAVE_ARPA_NAMESER_COMPAT_H
00077 #include <arpa/nameser_compat.h>
00078 #endif
00079 #include <netdb.h>
00080 #include <resolv.h>
00081 #include <stdio.h>
00082 #include <string.h>
00083
00084 #include "ink_error.h"
00085 #include "ink_resolver.h"
00086
00087 #define SPRINTF(x) (sprintf x)
00088
00089
00090
00091
00092
00093 int
00094 ink_res_mkquery(ink_res_state statp,
00095 int op,
00096 const char *dname,
00097 int _class, int type,
00098 const u_char *data,
00099 int datalen,
00100 const u_char *,
00101 u_char *buf,
00102 int buflen)
00103 {
00104 HEADER *hp;
00105 u_char *cp, *ep;
00106 int n;
00107 u_char *dnptrs[20], **dpp, **lastdnptr;
00108
00109
00110
00111
00112 if ((buf == NULL) || (buflen < HFIXEDSZ))
00113 return (-1);
00114 memset(buf, 0, HFIXEDSZ);
00115 hp = (HEADER *) buf;
00116 hp->id = htons(++statp->id);
00117 hp->opcode = op;
00118 hp->rd = (statp->options & INK_RES_RECURSE) != 0U;
00119 hp->rcode = NOERROR;
00120 cp = buf + HFIXEDSZ;
00121 ep = buf + buflen;
00122 dpp = dnptrs;
00123 *dpp++ = buf;
00124 *dpp++ = NULL;
00125 lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
00126
00127
00128
00129 switch (op) {
00130 case QUERY:
00131 case NS_NOTIFY_OP:
00132 if (ep - cp < QFIXEDSZ)
00133 return (-1);
00134 if ((n = dn_comp(dname, cp, ep - cp - QFIXEDSZ, dnptrs,
00135 lastdnptr)) < 0)
00136 return (-1);
00137 cp += n;
00138 NS_PUT16(type, cp);
00139 NS_PUT16(_class, cp);
00140 hp->qdcount = htons(1);
00141 if (op == QUERY || data == NULL)
00142 break;
00143
00144
00145
00146 if ((ep - cp) < RRFIXEDSZ)
00147 return (-1);
00148 n = dn_comp((const char *)data, cp, ep - cp - RRFIXEDSZ,
00149 dnptrs, lastdnptr);
00150 if (n < 0)
00151 return (-1);
00152 cp += n;
00153 NS_PUT16(T_NULL, cp);
00154 NS_PUT16(_class, cp);
00155 NS_PUT32(0, cp);
00156 NS_PUT16(0, cp);
00157 hp->arcount = htons(1);
00158 break;
00159
00160 case IQUERY:
00161
00162
00163
00164 if (ep - cp < 1 + RRFIXEDSZ + datalen)
00165 return (-1);
00166 *cp++ = '\0';
00167 NS_PUT16(type, cp);
00168 NS_PUT16(_class, cp);
00169 NS_PUT32(0, cp);
00170 NS_PUT16(datalen, cp);
00171 if (datalen) {
00172 memcpy(cp, data, datalen);
00173 cp += datalen;
00174 }
00175 hp->ancount = htons(1);
00176 break;
00177
00178 default:
00179 return (-1);
00180 }
00181 return (cp - buf);
00182 }
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 static int
00194 printable(int ch) {
00195 return (ch > 0x20 && ch < 0x7f);
00196 }
00197
00198 static const char digits[] = "0123456789";
00199
00200 static int
00201 labellen(const u_char *lp)
00202 {
00203 int bitlen;
00204 u_char l = *lp;
00205
00206 if ((l & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
00207
00208 return(-1);
00209 }
00210
00211 if ((l & NS_CMPRSFLGS) == INK_NS_TYPE_ELT) {
00212 if (l == INK_DNS_LABELTYPE_BITSTRING) {
00213 if ((bitlen = *(lp + 1)) == 0)
00214 bitlen = 256;
00215 return((bitlen + 7 ) / 8 + 1);
00216 }
00217 return(-1);
00218 }
00219 return(l);
00220 }
00221
00222 static int
00223 decode_bitstring(const unsigned char **cpp, char *dn, const char *eom)
00224 {
00225 const unsigned char *cp = *cpp;
00226 char *beg = dn, tc;
00227 int b, blen, plen, i;
00228
00229 if ((blen = (*cp & 0xff)) == 0)
00230 blen = 256;
00231 plen = (blen + 3) / 4;
00232 plen += sizeof("\\[x/]") + (blen > 99 ? 3 : (blen > 9) ? 2 : 1);
00233 if (dn + plen >= eom)
00234 return(-1);
00235
00236 cp++;
00237 i = SPRINTF((dn, "\\[x"));
00238 if (i < 0)
00239 return (-1);
00240 dn += i;
00241 for (b = blen; b > 7; b -= 8, cp++) {
00242 i = SPRINTF((dn, "%02x", *cp & 0xff));
00243 if (i < 0)
00244 return (-1);
00245 dn += i;
00246 }
00247 if (b > 4) {
00248 tc = *cp++;
00249 i = SPRINTF((dn, "%02x", tc & (0xff << (8 - b))));
00250 if (i < 0)
00251 return (-1);
00252 dn += i;
00253 } else if (b > 0) {
00254 tc = *cp++;
00255 i = SPRINTF((dn, "%1x",
00256 ((tc >> 4) & 0x0f) & (0x0f << (4 - b))));
00257 if (i < 0)
00258 return (-1);
00259 dn += i;
00260 }
00261 i = SPRINTF((dn, "/%d]", blen));
00262 if (i < 0)
00263 return (-1);
00264 dn += i;
00265
00266 *cpp = cp;
00267 return(dn - beg);
00268 }
00269
00270
00271
00272
00273
00274
00275
00276
00277 static int
00278 special(int ch) {
00279 switch (ch) {
00280 case 0x22:
00281 case 0x2E:
00282 case 0x3B:
00283 case 0x5C:
00284 case 0x28:
00285 case 0x29:
00286
00287 case 0x40:
00288 case 0x24:
00289 return (1);
00290 default:
00291 return (0);
00292 }
00293 }
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 int
00306 ink_ns_name_ntop(const u_char *src, char *dst, size_t dstsiz)
00307 {
00308 const u_char *cp;
00309 char *dn, *eom;
00310 u_char c;
00311 u_int n;
00312 int l;
00313
00314 cp = src;
00315 dn = dst;
00316 eom = dst + dstsiz;
00317
00318 while ((n = *cp++) != 0) {
00319 if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
00320
00321 errno = EMSGSIZE;
00322 return (-1);
00323 }
00324 if (dn != dst) {
00325 if (dn >= eom) {
00326 errno = EMSGSIZE;
00327 return (-1);
00328 }
00329 *dn++ = '.';
00330 }
00331 if ((l = labellen(cp - 1)) < 0) {
00332 errno = EMSGSIZE;
00333 return(-1);
00334 }
00335 if (dn + l >= eom) {
00336 errno = EMSGSIZE;
00337 return (-1);
00338 }
00339 if ((n & NS_CMPRSFLGS) == INK_NS_TYPE_ELT) {
00340 int m;
00341
00342 if (n != INK_DNS_LABELTYPE_BITSTRING) {
00343
00344 errno = EINVAL;
00345 return(-1);
00346 }
00347 if ((m = decode_bitstring(&cp, dn, eom)) < 0)
00348 {
00349 errno = EMSGSIZE;
00350 return(-1);
00351 }
00352 dn += m;
00353 continue;
00354 }
00355 for ((void)NULL; l > 0; l--) {
00356 c = *cp++;
00357 if (special(c)) {
00358 if (dn + 1 >= eom) {
00359 errno = EMSGSIZE;
00360 return (-1);
00361 }
00362 *dn++ = '\\';
00363 *dn++ = (char)c;
00364 } else if (!printable(c)) {
00365 if (dn + 3 >= eom) {
00366 errno = EMSGSIZE;
00367 return (-1);
00368 }
00369 *dn++ = '\\';
00370 *dn++ = digits[c / 100];
00371 *dn++ = digits[(c % 100) / 10];
00372 *dn++ = digits[c % 10];
00373 } else {
00374 if (dn >= eom) {
00375 errno = EMSGSIZE;
00376 return (-1);
00377 }
00378 *dn++ = (char)c;
00379 }
00380 }
00381 }
00382 if (dn == dst) {
00383 if (dn >= eom) {
00384 errno = EMSGSIZE;
00385 return (-1);
00386 }
00387 *dn++ = '.';
00388 }
00389 if (dn >= eom) {
00390 errno = EMSGSIZE;
00391 return (-1);
00392 }
00393 *dn++ = '\0';
00394 return (dn - dst);
00395 }
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407 #if defined(linux)
00408 int
00409 ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) __THROW
00410 #else
00411 int
00412 ns_name_ntop(const u_char *src, char *dst, size_t dstsiz)
00413 #endif
00414 {
00415 const u_char *cp;
00416 char *dn, *eom;
00417 u_char c;
00418 u_int n;
00419 int l;
00420
00421 cp = src;
00422 dn = dst;
00423 eom = dst + dstsiz;
00424
00425 while ((n = *cp++) != 0) {
00426 if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
00427
00428 errno = EMSGSIZE;
00429 return (-1);
00430 }
00431 if (dn != dst) {
00432 if (dn >= eom) {
00433 errno = EMSGSIZE;
00434 return (-1);
00435 }
00436 *dn++ = '.';
00437 }
00438 if ((l = labellen(cp - 1)) < 0) {
00439 errno = EMSGSIZE;
00440 return(-1);
00441 }
00442 if (dn + l >= eom) {
00443 errno = EMSGSIZE;
00444 return (-1);
00445 }
00446 if ((n & NS_CMPRSFLGS) == INK_NS_TYPE_ELT) {
00447 int m;
00448
00449 if (n != INK_DNS_LABELTYPE_BITSTRING) {
00450
00451 errno = EINVAL;
00452 return(-1);
00453 }
00454 if ((m = decode_bitstring(&cp, dn, eom)) < 0)
00455 {
00456 errno = EMSGSIZE;
00457 return(-1);
00458 }
00459 dn += m;
00460 continue;
00461 }
00462 for ((void)NULL; l > 0; l--) {
00463 c = *cp++;
00464 if (special(c)) {
00465 if (dn + 1 >= eom) {
00466 errno = EMSGSIZE;
00467 return (-1);
00468 }
00469 *dn++ = '\\';
00470 *dn++ = (char)c;
00471 } else if (!printable(c)) {
00472 if (dn + 3 >= eom) {
00473 errno = EMSGSIZE;
00474 return (-1);
00475 }
00476 *dn++ = '\\';
00477 *dn++ = digits[c / 100];
00478 *dn++ = digits[(c % 100) / 10];
00479 *dn++ = digits[c % 10];
00480 } else {
00481 if (dn >= eom) {
00482 errno = EMSGSIZE;
00483 return (-1);
00484 }
00485 *dn++ = (char)c;
00486 }
00487 }
00488 }
00489 if (dn == dst) {
00490 if (dn >= eom) {
00491 errno = EMSGSIZE;
00492 return (-1);
00493 }
00494 *dn++ = '.';
00495 }
00496 if (dn >= eom) {
00497 errno = EMSGSIZE;
00498 return (-1);
00499 }
00500 *dn++ = '\0';
00501 return (dn - dst);
00502 }
00503
00504 HostResStyle
00505 ats_host_res_from(int family, HostResPreferenceOrder order)
00506 {
00507 bool v4 = false, v6 = false;
00508 HostResPreference client = AF_INET6 == family ? HOST_RES_PREFER_IPV6 : HOST_RES_PREFER_IPV4;
00509
00510 for ( int i = 0 ; i < N_HOST_RES_PREFERENCE_ORDER ; ++i ) {
00511 HostResPreference p = order[i];
00512 if (HOST_RES_PREFER_CLIENT == p) p = client;
00513 if (HOST_RES_PREFER_IPV4 == p) {
00514 if (v6) return HOST_RES_IPV6;
00515 else v4 = true;
00516 } else if (HOST_RES_PREFER_IPV6 == p) {
00517 if (v4) return HOST_RES_IPV4;
00518 else v6 = true;
00519 } else {
00520 break;
00521 }
00522 }
00523 if (v4) return HOST_RES_IPV4_ONLY;
00524 else if (v6) return HOST_RES_IPV6_ONLY;
00525 return HOST_RES_NONE;
00526 }
00527
00528 HostResStyle
00529 ats_host_res_match(sockaddr const* addr)
00530 {
00531 HostResStyle zret = HOST_RES_NONE;
00532 if (ats_is_ip6(addr))
00533 zret = HOST_RES_IPV6_ONLY;
00534 else if (ats_is_ip4(addr))
00535 zret = HOST_RES_IPV4_ONLY;
00536 return zret;
00537 }