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
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 #include "stdinc.h"
00084 #include "irc_reslib.h"
00085 #include "irc_res.h"
00086 #include "ircd_defs.h"
00087 #include "fileio.h"
00088 #include "irc_string.h"
00089 #include "irc_getaddrinfo.h"
00090
00091 #define NS_TYPE_ELT 0x40
00092 #define DNS_LABELTYPE_BITSTRING 0x41
00093 #define MAXLINE 128
00094
00095
00096
00097 struct irc_ssaddr irc_nsaddr_list[IRCD_MAXNS];
00098 int irc_nscount = 0;
00099 char irc_domain[HOSTLEN + 1];
00100
00101 static const char digitvalue[256] = {
00102 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00103 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00104 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00105 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
00106 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00107 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00108 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00109 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00110 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00111 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00112 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00113 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00114 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00115 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00116 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00117 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00118 };
00119
00120 static int parse_resvconf(void);
00121 static void add_nameserver(char *arg);
00122
00123 static const char digits[] = "0123456789";
00124 static int labellen(const unsigned char *lp);
00125 static int special(int ch);
00126 static int printable(int ch);
00127 static int irc_decode_bitstring(const char **cpp, char *dn, const char *eom);
00128 static int irc_ns_name_compress(const char *src, unsigned char *dst, size_t dstsiz,
00129 const unsigned char **dnptrs, const unsigned char **lastdnptr);
00130 static int irc_dn_find(const unsigned char *, const unsigned char *, const unsigned char * const *,
00131 const unsigned char * const *);
00132 static int irc_encode_bitsring(const char **, const char *, unsigned char **, unsigned char **,
00133 const char *);
00134 static int irc_ns_name_uncompress(const unsigned char *, const unsigned char *,
00135 const unsigned char *, char *, size_t);
00136 static int irc_ns_name_unpack(const unsigned char *, const unsigned char *,
00137 const unsigned char *, unsigned char *,
00138 size_t);
00139 static int irc_ns_name_ntop(const char *, char *, size_t);
00140 static int irc_ns_name_skip(const unsigned char **, const unsigned char *);
00141 static int mklower(int ch);
00142
00143 int
00144 irc_res_init(void)
00145 {
00146 irc_nscount = 0;
00147 return parse_resvconf();
00148 }
00149
00150
00151
00152
00153
00154
00155
00156 static int
00157 parse_resvconf(void)
00158 {
00159 char *p;
00160 char *opt;
00161 char *arg;
00162 char input[MAXLINE];
00163 FBFILE *file;
00164
00165
00166
00167
00168 if ((file = fbopen("/etc/resolv.conf", "r")) == NULL)
00169 return -1;
00170
00171 while (fbgets(input, sizeof(input), file) != NULL)
00172 {
00173
00174 if ((p = strpbrk(input, "\r\n")) != NULL)
00175 *p = '\0';
00176
00177 p = input;
00178
00179
00180 while (IsSpace(*p))
00181 ++p;
00182
00183
00184 if (*p == '\0')
00185 continue;
00186
00187
00188 if (*p == ';' || *p == '#')
00189 continue;
00190
00191
00192 opt = p;
00193 while (!IsSpace(*p) && *p)
00194 ++p;
00195
00196 if (*p == '\0')
00197 continue;
00198
00199
00200 *p++ = '\0';
00201
00202
00203 while (IsSpace(*p))
00204 ++p;
00205
00206
00207 arg = p;
00208
00209 if ((p = strpbrk(arg, " \t")) != NULL)
00210 *p = '\0';
00211
00212 if (irccmp(opt, "domain") == 0)
00213 strlcpy(irc_domain, arg, HOSTLEN);
00214 else if (irccmp(opt, "nameserver") == 0)
00215 add_nameserver(arg);
00216 }
00217
00218 fbclose(file);
00219 return 0;
00220 }
00221
00222
00223
00224
00225
00226
00227
00228
00229 static void
00230 add_nameserver(char *arg)
00231 {
00232 struct addrinfo hints, *res;
00233
00234 if ((irc_nscount) >= IRCD_MAXNS)
00235 return;
00236
00237 memset(&hints, 0, sizeof(hints));
00238 hints.ai_family = PF_UNSPEC;
00239 hints.ai_socktype = SOCK_DGRAM;
00240 hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
00241
00242 if (irc_getaddrinfo(arg, "domain", &hints, &res))
00243 return;
00244
00245 if (res == NULL)
00246 return;
00247
00248 memcpy(&irc_nsaddr_list[irc_nscount].ss, res->ai_addr, res->ai_addrlen);
00249 irc_nsaddr_list[irc_nscount].ss_len = res->ai_addrlen;
00250 irc_nscount++;
00251 irc_freeaddrinfo(res);
00252 }
00253
00254
00255
00256
00257
00258
00259
00260
00261 int
00262 irc_dn_expand(const unsigned char *msg, const unsigned char *eom,
00263 const unsigned char *src, char *dst, int dstsiz)
00264 {
00265 int n = irc_ns_name_uncompress(msg, eom, src, dst, (size_t)dstsiz);
00266
00267 if (n > 0 && dst[0] == '.')
00268 dst[0] = '\0';
00269 return(n);
00270 }
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 static int
00281 irc_ns_name_uncompress(const unsigned char *msg, const unsigned char *eom,
00282 const unsigned char *src, char *dst, size_t dstsiz)
00283 {
00284 unsigned char tmp[NS_MAXCDNAME];
00285 int n;
00286
00287 if ((n = irc_ns_name_unpack(msg, eom, src, tmp, sizeof tmp)) == -1)
00288 return(-1);
00289 if (irc_ns_name_ntop((char*)tmp, dst, dstsiz) == -1)
00290 return(-1);
00291 return(n);
00292 }
00293
00294
00295
00296
00297
00298
00299 static int
00300 irc_ns_name_unpack(const unsigned char *msg, const unsigned char *eom,
00301 const unsigned char *src, unsigned char *dst,
00302 size_t dstsiz)
00303 {
00304 const unsigned char *srcp, *dstlim;
00305 unsigned char *dstp;
00306 int n, len, checked, l;
00307
00308 len = -1;
00309 checked = 0;
00310 dstp = dst;
00311 srcp = src;
00312 dstlim = dst + dstsiz;
00313 if (srcp < msg || srcp >= eom) {
00314 errno = EMSGSIZE;
00315 return (-1);
00316 }
00317
00318 while ((n = *srcp++) != 0) {
00319
00320 switch (n & NS_CMPRSFLGS) {
00321 case 0:
00322 case NS_TYPE_ELT:
00323
00324 if ((l = labellen(srcp - 1)) < 0) {
00325 errno = EMSGSIZE;
00326 return(-1);
00327 }
00328 if (dstp + l + 1 >= dstlim || srcp + l >= eom) {
00329 errno = EMSGSIZE;
00330 return (-1);
00331 }
00332 checked += l + 1;
00333 *dstp++ = n;
00334 memcpy(dstp, srcp, l);
00335 dstp += l;
00336 srcp += l;
00337 break;
00338
00339 case NS_CMPRSFLGS:
00340 if (srcp >= eom) {
00341 errno = EMSGSIZE;
00342 return (-1);
00343 }
00344 if (len < 0)
00345 len = srcp - src + 1;
00346 srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
00347 if (srcp < msg || srcp >= eom) {
00348 errno = EMSGSIZE;
00349 return (-1);
00350 }
00351 checked += 2;
00352
00353
00354
00355
00356
00357 if (checked >= eom - msg) {
00358 errno = EMSGSIZE;
00359 return (-1);
00360 }
00361 break;
00362
00363 default:
00364 errno = EMSGSIZE;
00365 return (-1);
00366 }
00367 }
00368 *dstp = '\0';
00369 if (len < 0)
00370 len = srcp - src;
00371 return (len);
00372 }
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383 static int
00384 irc_ns_name_ntop(const char *src, char *dst, size_t dstsiz)
00385 {
00386 const char *cp;
00387 char *dn, *eom;
00388 unsigned char c;
00389 unsigned int n;
00390 int l;
00391
00392 cp = src;
00393 dn = dst;
00394 eom = dst + dstsiz;
00395
00396 while ((n = *cp++) != 0) {
00397 if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
00398
00399 errno = EMSGSIZE;
00400 return (-1);
00401 }
00402 if (dn != dst) {
00403 if (dn >= eom) {
00404 errno = EMSGSIZE;
00405 return (-1);
00406 }
00407 *dn++ = '.';
00408 }
00409 if ((l = labellen((unsigned char*)(cp - 1))) < 0) {
00410 errno = EMSGSIZE;
00411 return(-1);
00412 }
00413 if (dn + l >= eom) {
00414 errno = EMSGSIZE;
00415 return (-1);
00416 }
00417 if ((n & NS_CMPRSFLGS) == NS_TYPE_ELT) {
00418 int m;
00419
00420 if (n != DNS_LABELTYPE_BITSTRING) {
00421
00422 errno = EINVAL;
00423 return(-1);
00424 }
00425 if ((m = irc_decode_bitstring(&cp, dn, eom)) < 0)
00426 {
00427 errno = EMSGSIZE;
00428 return(-1);
00429 }
00430 dn += m;
00431 continue;
00432 }
00433 for ((void)NULL; l > 0; l--) {
00434 c = *cp++;
00435 if (special(c)) {
00436 if (dn + 1 >= eom) {
00437 errno = EMSGSIZE;
00438 return (-1);
00439 }
00440 *dn++ = '\\';
00441 *dn++ = (char)c;
00442 } else if (!printable(c)) {
00443 if (dn + 3 >= eom) {
00444 errno = EMSGSIZE;
00445 return (-1);
00446 }
00447 *dn++ = '\\';
00448 *dn++ = digits[c / 100];
00449 *dn++ = digits[(c % 100) / 10];
00450 *dn++ = digits[c % 10];
00451 } else {
00452 if (dn >= eom) {
00453 errno = EMSGSIZE;
00454 return (-1);
00455 }
00456 *dn++ = (char)c;
00457 }
00458 }
00459 }
00460 if (dn == dst) {
00461 if (dn >= eom) {
00462 errno = EMSGSIZE;
00463 return (-1);
00464 }
00465 *dn++ = '.';
00466 }
00467 if (dn >= eom) {
00468 errno = EMSGSIZE;
00469 return (-1);
00470 }
00471 *dn++ = '\0';
00472 return (dn - dst);
00473 }
00474
00475
00476
00477
00478
00479
00480 static int
00481 irc_dn_comp(const char *src, unsigned char *dst, int dstsiz,
00482 unsigned char **dnptrs, unsigned char **lastdnptr)
00483 {
00484 return(irc_ns_name_compress(src, dst, (size_t)dstsiz,
00485 (const unsigned char **)dnptrs,
00486 (const unsigned char **)lastdnptr));
00487 }
00488
00489
00490
00491
00492 int
00493 irc_dn_skipname(const unsigned char *ptr, const unsigned char *eom) {
00494 const unsigned char *saveptr = ptr;
00495
00496 if (irc_ns_name_skip(&ptr, eom) == -1)
00497 return(-1);
00498 return(ptr - saveptr);
00499 }
00500
00501
00502
00503
00504
00505
00506
00507 static int
00508 irc_ns_name_skip(const unsigned char **ptrptr, const unsigned char *eom)
00509 {
00510 const unsigned char *cp;
00511 unsigned int n;
00512 int l;
00513
00514 cp = *ptrptr;
00515
00516 while (cp < eom && (n = *cp++) != 0)
00517 {
00518
00519 switch (n & NS_CMPRSFLGS)
00520 {
00521 case 0:
00522 cp += n;
00523 continue;
00524 case NS_TYPE_ELT:
00525 if ((l = labellen(cp - 1)) < 0)
00526 {
00527 errno = EMSGSIZE;
00528 return(-1);
00529 }
00530
00531 cp += l;
00532 continue;
00533 case NS_CMPRSFLGS:
00534 cp++;
00535 break;
00536 default:
00537 errno = EMSGSIZE;
00538 return(-1);
00539 }
00540
00541 break;
00542 }
00543
00544 if (cp > eom)
00545 {
00546 errno = EMSGSIZE;
00547 return (-1);
00548 }
00549
00550 *ptrptr = cp;
00551 return(0);
00552 }
00553
00554 unsigned int
00555 irc_ns_get16(const unsigned char *src)
00556 {
00557 unsigned int dst;
00558
00559 IRC_NS_GET16(dst, src);
00560 return(dst);
00561 }
00562
00563 unsigned long
00564 irc_ns_get32(const unsigned char *src)
00565 {
00566 unsigned long dst;
00567
00568 IRC_NS_GET32(dst, src);
00569 return(dst);
00570 }
00571
00572 void
00573 irc_ns_put16(unsigned int src, unsigned char *dst)
00574 {
00575 IRC_NS_PUT16(src, dst);
00576 }
00577
00578 void
00579 irc_ns_put32(unsigned long src, unsigned char *dst)
00580 {
00581 IRC_NS_PUT32(src, dst);
00582 }
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593 static int
00594 special(int ch)
00595 {
00596 switch (ch)
00597 {
00598 case 0x22:
00599 case 0x2E:
00600 case 0x3B:
00601 case 0x5C:
00602 case 0x28:
00603 case 0x29:
00604
00605 case 0x40:
00606 case 0x24:
00607 return(1);
00608 default:
00609 return(0);
00610 }
00611 }
00612
00613 static int
00614 labellen(const unsigned char *lp)
00615 {
00616 int bitlen;
00617 unsigned char l = *lp;
00618
00619 if ((l & NS_CMPRSFLGS) == NS_CMPRSFLGS)
00620 {
00621
00622 return(-1);
00623 }
00624
00625 if ((l & NS_CMPRSFLGS) == NS_TYPE_ELT)
00626 {
00627 if (l == DNS_LABELTYPE_BITSTRING)
00628 {
00629 if ((bitlen = *(lp + 1)) == 0)
00630 bitlen = 256;
00631 return((bitlen + 7 ) / 8 + 1);
00632 }
00633
00634 return(-1);
00635 }
00636
00637 return(l);
00638 }
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648 static int
00649 printable(int ch)
00650 {
00651 return(ch > 0x20 && ch < 0x7f);
00652 }
00653
00654 static int
00655 irc_decode_bitstring(const char **cpp, char *dn, const char *eom)
00656 {
00657 const char *cp = *cpp;
00658 char *beg = dn, tc;
00659 int b, blen, plen;
00660
00661 if ((blen = (*cp & 0xff)) == 0)
00662 blen = 256;
00663 plen = (blen + 3) / 4;
00664 plen += sizeof("\\[x/]") + (blen > 99 ? 3 : (blen > 9) ? 2 : 1);
00665 if (dn + plen >= eom)
00666 return(-1);
00667
00668 cp++;
00669 dn += sprintf(dn, "\\[x");
00670 for (b = blen; b > 7; b -= 8, cp++)
00671 dn += sprintf(dn, "%02x", *cp & 0xff);
00672 if (b > 4) {
00673 tc = *cp++;
00674 dn += sprintf(dn, "%02x", tc & (0xff << (8 - b)));
00675 } else if (b > 0) {
00676 tc = *cp++;
00677 dn += sprintf(dn, "%1x",
00678 ((tc >> 4) & 0x0f) & (0x0f << (4 - b)));
00679 }
00680 dn += sprintf(dn, "/%d]", blen);
00681
00682 *cpp = cp;
00683 return(dn - beg);
00684 }
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696 static int
00697 irc_ns_name_pton(const char *src, unsigned char *dst, size_t dstsiz)
00698 {
00699 unsigned char *label, *bp, *eom;
00700 char *cp;
00701 int c, n, escaped, e = 0;
00702
00703 escaped = 0;
00704 bp = dst;
00705 eom = dst + dstsiz;
00706 label = bp++;
00707
00708
00709 while ((c = *src++) != 0) {
00710 if (escaped) {
00711 if (c == '[') {
00712 if ((cp = strchr(src, ']')) == NULL) {
00713 errno = EINVAL;
00714 return(-1);
00715 }
00716 if ((e = irc_encode_bitsring(&src,
00717 cp + 2,
00718 &label,
00719 &bp,
00720 (const char *)eom))
00721 != 0) {
00722 errno = e;
00723 return(-1);
00724 }
00725 escaped = 0;
00726 label = bp++;
00727 if ((c = *src++) == 0)
00728 goto done;
00729 else if (c != '.') {
00730 errno = EINVAL;
00731 return(-1);
00732 }
00733 continue;
00734 }
00735 else if ((cp = strchr(digits, c)) != NULL) {
00736 n = (cp - digits) * 100;
00737 if ((c = *src++) == 0 ||
00738 (cp = strchr(digits, c)) == NULL) {
00739 errno = EMSGSIZE;
00740 return (-1);
00741 }
00742 n += (cp - digits) * 10;
00743 if ((c = *src++) == 0 ||
00744 (cp = strchr(digits, c)) == NULL) {
00745 errno = EMSGSIZE;
00746 return (-1);
00747 }
00748 n += (cp - digits);
00749 if (n > 255) {
00750 errno = EMSGSIZE;
00751 return (-1);
00752 }
00753 c = n;
00754 }
00755 escaped = 0;
00756 } else if (c == '\\') {
00757 escaped = 1;
00758 continue;
00759 } else if (c == '.') {
00760 c = (bp - label - 1);
00761 if ((c & NS_CMPRSFLGS) != 0) {
00762 errno = EMSGSIZE;
00763 return (-1);
00764 }
00765 if (label >= eom) {
00766 errno = EMSGSIZE;
00767 return (-1);
00768 }
00769 *label = c;
00770
00771 if (*src == '\0') {
00772 if (c != 0) {
00773 if (bp >= eom) {
00774 errno = EMSGSIZE;
00775 return (-1);
00776 }
00777 *bp++ = '\0';
00778 }
00779 if ((bp - dst) > NS_MAXCDNAME) {
00780 errno = EMSGSIZE;
00781 return (-1);
00782 }
00783 return (1);
00784 }
00785 if (c == 0 || *src == '.') {
00786 errno = EMSGSIZE;
00787 return (-1);
00788 }
00789 label = bp++;
00790 continue;
00791 }
00792 if (bp >= eom) {
00793 errno = EMSGSIZE;
00794 return (-1);
00795 }
00796 *bp++ = (unsigned char)c;
00797 }
00798 c = (bp - label - 1);
00799 if ((c & NS_CMPRSFLGS) != 0) {
00800 errno = EMSGSIZE;
00801 return (-1);
00802 }
00803 done:
00804 if (label >= eom) {
00805 errno = EMSGSIZE;
00806 return (-1);
00807 }
00808 *label = c;
00809 if (c != 0) {
00810 if (bp >= eom) {
00811 errno = EMSGSIZE;
00812 return (-1);
00813 }
00814 *bp++ = 0;
00815 }
00816
00817 if ((bp - dst) > NS_MAXCDNAME)
00818 {
00819 errno = EMSGSIZE;
00820 return (-1);
00821 }
00822
00823 return (0);
00824 }
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843 static int
00844 irc_ns_name_pack(const unsigned char *src, unsigned char *dst, int dstsiz,
00845 const unsigned char **dnptrs, const unsigned char **lastdnptr)
00846 {
00847 unsigned char *dstp;
00848 const unsigned char **cpp, **lpp, *eob, *msg;
00849 const unsigned char *srcp;
00850 int n, l, first = 1;
00851
00852 srcp = src;
00853 dstp = dst;
00854 eob = dstp + dstsiz;
00855 lpp = cpp = NULL;
00856 if (dnptrs != NULL) {
00857 if ((msg = *dnptrs++) != NULL) {
00858 for (cpp = dnptrs; *cpp != NULL; cpp++)
00859 (void)NULL;
00860 lpp = cpp;
00861 }
00862 } else
00863 msg = NULL;
00864
00865
00866 l = 0;
00867 do {
00868 int l0;
00869
00870 n = *srcp;
00871 if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
00872 errno = EMSGSIZE;
00873 return (-1);
00874 }
00875 if ((l0 = labellen(srcp)) < 0) {
00876 errno = EINVAL;
00877 return(-1);
00878 }
00879 l += l0 + 1;
00880 if (l > NS_MAXCDNAME) {
00881 errno = EMSGSIZE;
00882 return (-1);
00883 }
00884 srcp += l0 + 1;
00885 } while (n != 0);
00886
00887
00888 srcp = src;
00889 do {
00890
00891 n = *srcp;
00892 if (n != 0 && msg != NULL) {
00893 l = irc_dn_find(srcp, msg, (const unsigned char * const *)dnptrs,
00894 (const unsigned char * const *)lpp);
00895 if (l >= 0) {
00896 if (dstp + 1 >= eob) {
00897 goto cleanup;
00898 }
00899 *dstp++ = (l >> 8) | NS_CMPRSFLGS;
00900 *dstp++ = l % 256;
00901 return (dstp - dst);
00902 }
00903
00904 if (lastdnptr != NULL && cpp < lastdnptr - 1 &&
00905 (dstp - msg) < 0x4000 && first) {
00906 *cpp++ = dstp;
00907 *cpp = NULL;
00908 first = 0;
00909 }
00910 }
00911
00912 if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
00913
00914 goto cleanup;
00915 }
00916 n = labellen(srcp);
00917 if (dstp + 1 + n >= eob) {
00918 goto cleanup;
00919 }
00920 memcpy(dstp, srcp, n + 1);
00921 srcp += n + 1;
00922 dstp += n + 1;
00923 } while (n != 0);
00924
00925 if (dstp > eob) {
00926 cleanup:
00927 if (msg != NULL)
00928 *lpp = NULL;
00929 errno = EMSGSIZE;
00930 return (-1);
00931 }
00932 return(dstp - dst);
00933 }
00934
00935 static int
00936 irc_ns_name_compress(const char *src, unsigned char *dst, size_t dstsiz,
00937 const unsigned char **dnptrs, const unsigned char **lastdnptr)
00938 {
00939 unsigned char tmp[NS_MAXCDNAME];
00940
00941 if (irc_ns_name_pton(src, tmp, sizeof tmp) == -1)
00942 return(-1);
00943 return(irc_ns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr));
00944 }
00945
00946 static int
00947 irc_encode_bitsring(const char **bp, const char *end, unsigned char **labelp,
00948 unsigned char **dst, const char *eom)
00949 {
00950 int afterslash = 0;
00951 const char *cp = *bp;
00952 char *tp, c;
00953 const char *beg_blen;
00954 char *end_blen = NULL;
00955 int value = 0, count = 0, tbcount = 0, blen = 0;
00956
00957 beg_blen = end_blen = NULL;
00958
00959
00960 if (end - cp < 2)
00961 return(EINVAL);
00962
00963
00964 if (*cp++ != 'x')
00965 return(EINVAL);
00966 if (!isxdigit((*cp) & 0xff))
00967 return(EINVAL);
00968
00969 for (tp = (char*)(dst + 1); cp < end && tp < eom; cp++) {
00970 switch((c = *cp)) {
00971 case ']':
00972 if (afterslash) {
00973 if (beg_blen == NULL)
00974 return(EINVAL);
00975 blen = (int)strtol(beg_blen, &end_blen, 10);
00976 if (*end_blen != ']')
00977 return(EINVAL);
00978 }
00979 if (count)
00980 *tp++ = ((value << 4) & 0xff);
00981 cp++;
00982 goto done;
00983 case '/':
00984 afterslash = 1;
00985 break;
00986 default:
00987 if (afterslash) {
00988 if (!isdigit(c&0xff))
00989 return(EINVAL);
00990 if (beg_blen == NULL) {
00991
00992 if (c == '0') {
00993
00994 return(EINVAL);
00995 }
00996 beg_blen = cp;
00997 }
00998 } else {
00999 if (!isxdigit(c&0xff))
01000 return(EINVAL);
01001 value <<= 4;
01002 value += digitvalue[(int)c];
01003 count += 4;
01004 tbcount += 4;
01005 if (tbcount > 256)
01006 return(EINVAL);
01007 if (count == 8) {
01008 *tp++ = value;
01009 count = 0;
01010 }
01011 }
01012 break;
01013 }
01014 }
01015 done:
01016 if (cp >= end || tp >= eom)
01017 return(EMSGSIZE);
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027 if (blen > 0) {
01028 int traillen;
01029
01030 if (((blen + 3) & ~3) != tbcount)
01031 return(EINVAL);
01032 traillen = tbcount - blen;
01033 if (((value << (8 - traillen)) & 0xff) != 0)
01034 return(EINVAL);
01035 }
01036 else
01037 blen = tbcount;
01038 if (blen == 256)
01039 blen = 0;
01040
01041
01042 **labelp = DNS_LABELTYPE_BITSTRING;
01043 **dst = blen;
01044
01045 *bp = cp;
01046 *dst = (unsigned char*)tp;
01047
01048 return(0);
01049 }
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060 static int
01061 irc_dn_find(const unsigned char *domain, const unsigned char *msg,
01062 const unsigned char * const *dnptrs,
01063 const unsigned char * const *lastdnptr)
01064 {
01065 const unsigned char *dn, *cp, *sp;
01066 const unsigned char * const *cpp;
01067 unsigned int n;
01068
01069 for (cpp = dnptrs; cpp < lastdnptr; cpp++)
01070 {
01071 sp = *cpp;
01072
01073
01074
01075
01076
01077
01078 while (*sp != 0 && (*sp & NS_CMPRSFLGS) == 0 &&
01079 (sp - msg) < 0x4000) {
01080 dn = domain;
01081 cp = sp;
01082 while ((n = *cp++) != 0) {
01083
01084
01085
01086 switch (n & NS_CMPRSFLGS) {
01087 case 0:
01088 n = labellen(cp - 1);
01089
01090 if (n != *dn++)
01091 goto next;
01092
01093 for ((void)NULL; n > 0; n--)
01094 if (mklower(*dn++) !=
01095 mklower(*cp++))
01096 goto next;
01097
01098 if (*dn == '\0' && *cp == '\0')
01099 return (sp - msg);
01100 if (*dn)
01101 continue;
01102 goto next;
01103 case NS_CMPRSFLGS:
01104 cp = msg + (((n & 0x3f) << 8) | *cp);
01105 break;
01106
01107 default:
01108 errno = EMSGSIZE;
01109 return (-1);
01110 }
01111 }
01112 next: ;
01113 sp += *sp + 1;
01114 }
01115 }
01116 errno = ENOENT;
01117 return (-1);
01118 }
01119
01120
01121
01122
01123
01124 static int
01125 mklower(int ch)
01126 {
01127 if (ch >= 0x41 && ch <= 0x5A)
01128 return(ch + 0x20);
01129
01130 return(ch);
01131 }
01132
01133
01134
01135
01136
01137
01138
01139 int
01140 irc_res_mkquery(
01141 const char *dname,
01142 int class, int type,
01143 unsigned char *buf,
01144 int buflen)
01145 {
01146 HEADER *hp;
01147 unsigned char *cp;
01148 int n;
01149 unsigned char *dnptrs[20], **dpp, **lastdnptr;
01150
01151
01152
01153
01154 if ((buf == NULL) || (buflen < HFIXEDSZ))
01155 return (-1);
01156 memset(buf, 0, HFIXEDSZ);
01157 hp = (HEADER *) buf;
01158
01159 hp->id = 0;
01160 hp->opcode = QUERY;
01161 hp->rd = 1;
01162 hp->rcode = NO_ERRORS;
01163 cp = buf + HFIXEDSZ;
01164 buflen -= HFIXEDSZ;
01165 dpp = dnptrs;
01166 *dpp++ = buf;
01167 *dpp++ = NULL;
01168 lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
01169
01170 if ((buflen -= QFIXEDSZ) < 0)
01171 return (-1);
01172 if ((n = irc_dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
01173 return (-1);
01174
01175 cp += n;
01176 buflen -= n;
01177 IRC_NS_PUT16(type, cp);
01178 IRC_NS_PUT16(class, cp);
01179 hp->qdcount = htons(1);
01180
01181 return (cp - buf);
01182 }