[BACK]Return to ns_name.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libc / nameser

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/lib/libc/nameser/ns_name.c between version 1.6.6.2 and 1.7

version 1.6.6.2, 2008/06/21 20:41:49 version 1.7, 2009/04/12 17:07:17
Line 20 
Line 20 
 #include <sys/cdefs.h>  #include <sys/cdefs.h>
 #ifndef lint  #ifndef lint
 #ifdef notdef  #ifdef notdef
 static const char rcsid[] = "Id: ns_name.c,v 1.10 2005/04/27 04:56:40 sra Exp";  static const char rcsid[] = "Id: ns_name.c,v 1.11 2009/01/23 19:59:16 each Exp";
 #else  #else
 __RCSID("$NetBSD$");  __RCSID("$NetBSD$");
 #endif  #endif
Line 128  ns_name_ntop(const u_char *src, char *ds
Line 128  ns_name_ntop(const u_char *src, char *ds
                 }                  }
                 if ((l = labellen(cp - 1)) < 0) {                  if ((l = labellen(cp - 1)) < 0) {
                         errno = EMSGSIZE; /*%< XXX */                          errno = EMSGSIZE; /*%< XXX */
                         return(-1);                          return (-1);
                 }                  }
                 if (dn + l >= eom) {                  if (dn + l >= eom) {
                         errno = EMSGSIZE;                          errno = EMSGSIZE;
Line 140  ns_name_ntop(const u_char *src, char *ds
Line 140  ns_name_ntop(const u_char *src, char *ds
                         if (n != DNS_LABELTYPE_BITSTRING) {                          if (n != DNS_LABELTYPE_BITSTRING) {
                                 /* XXX: labellen should reject this case */                                  /* XXX: labellen should reject this case */
                                 errno = EINVAL;                                  errno = EINVAL;
                                 return(-1);                                  return (-1);
                         }                          }
                         if ((m = decode_bitstring(&cp, dn, eom)) < 0)                          if ((m = decode_bitstring(&cp, dn, eom)) < 0)
                         {                          {
                                 errno = EMSGSIZE;                                  errno = EMSGSIZE;
                                 return(-1);                                  return (-1);
                         }                          }
                         dn += m;                          dn += m;
                         continue;                          continue;
Line 204  ns_name_ntop(const u_char *src, char *ds
Line 204  ns_name_ntop(const u_char *src, char *ds
  * notes:   * notes:
  *\li   Enforces label and domain length limits.   *\li   Enforces label and domain length limits.
  */   */
   int
   ns_name_pton(const char *src, u_char *dst, size_t dstsiz) {
           return (ns_name_pton2(src, dst, dstsiz, NULL));
   }
   
   /*
    * ns_name_pton2(src, dst, dstsiz, *dstlen)
    *      Convert a ascii string into an encoded domain name as per RFC1035.
    * return:
    *      -1 if it fails
    *      1 if string was fully qualified
    *      0 is string was not fully qualified
    * side effects:
    *      fills in *dstlen (if non-NULL)
    * notes:
    *      Enforces label and domain length limits.
    */
 int  int
 ns_name_pton(const char *src, u_char *dst, size_t dstsiz)  ns_name_pton2(const char *src, u_char *dst, size_t dstsiz, size_t *dstlen) {
 {  
         u_char *label, *bp, *eom;          u_char *label, *bp, *eom;
         int c, n, escaped, e = 0;          int c, n, escaped, e = 0;
         char *cp;          char *cp;
Line 222  ns_name_pton(const char *src, u_char *ds
Line 237  ns_name_pton(const char *src, u_char *ds
                         if (c == '[') { /*%< start a bit string label */                          if (c == '[') { /*%< start a bit string label */
                                 if ((cp = strchr(src, ']')) == NULL) {                                  if ((cp = strchr(src, ']')) == NULL) {
                                         errno = EINVAL; /*%< ??? */                                          errno = EINVAL; /*%< ??? */
                                         return(-1);                                          return (-1);
                                 }                                  }
                                 if ((e = encode_bitsring(&src, cp + 2,                                  if ((e = encode_bitsring(&src, cp + 2,
                                                          &label, &bp, eom))                                                           &label, &bp, eom))
                                     != 0) {                                      != 0) {
                                         errno = e;                                          errno = e;
                                         return(-1);                                          return (-1);
                                 }                                  }
                                 escaped = 0;                                  escaped = 0;
                                 label = bp++;                                  label = bp++;
Line 236  ns_name_pton(const char *src, u_char *ds
Line 251  ns_name_pton(const char *src, u_char *ds
                                         goto done;                                          goto done;
                                 else if (c != '.') {                                  else if (c != '.') {
                                         errno = EINVAL;                                          errno = EINVAL;
                                         return(-1);                                          return  (-1);
                                 }                                  }
                                 continue;                                  continue;
                         }                          }
Line 288  ns_name_pton(const char *src, u_char *ds
Line 303  ns_name_pton(const char *src, u_char *ds
                                         errno = EMSGSIZE;                                          errno = EMSGSIZE;
                                         return (-1);                                          return (-1);
                                 }                                  }
                                   if (dstlen != NULL)
                                           *dstlen = (bp - dst);
                                 return (1);                                  return (1);
                         }                          }
                         if (c == 0 || *src == '.') {                          if (c == 0 || *src == '.') {
Line 325  ns_name_pton(const char *src, u_char *ds
Line 342  ns_name_pton(const char *src, u_char *ds
                 errno = EMSGSIZE;                  errno = EMSGSIZE;
                 return (-1);                  return (-1);
         }          }
           if (dstlen != NULL)
                   *dstlen = (bp - dst);
         return (0);          return (0);
 }  }
   
Line 372  ns_name_ntol(const u_char *src, u_char *
Line 391  ns_name_ntol(const u_char *src, u_char *
                 }                  }
                 for (; l > 0; l--) {                  for (; l > 0; l--) {
                         c = *cp++;                          c = *cp++;
                         if (isupper(c))                          if (isascii(c) && isupper(c))
                                 *dn++ = tolower(c);                                  *dn++ = tolower(c);
                         else                          else
                                 *dn++ = c;                                  *dn++ = c;
Line 392  int
Line 411  int
 ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,  ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
                u_char *dst, size_t dstsiz)                 u_char *dst, size_t dstsiz)
 {  {
           return (ns_name_unpack2(msg, eom, src, dst, dstsiz, NULL));
   }
   
   /*
    * ns_name_unpack2(msg, eom, src, dst, dstsiz, *dstlen)
    *      Unpack a domain name from a message, source may be compressed.
    * return:
    *      -1 if it fails, or consumed octets if it succeeds.
    * side effect:
    *      fills in *dstlen (if non-NULL).
    */
   int
   ns_name_unpack2(const u_char *msg, const u_char *eom, const u_char *src,
                   u_char *dst, size_t dstsiz, size_t *dstlen)
   {
         const u_char *srcp, *dstlim;          const u_char *srcp, *dstlim;
         u_char *dstp;          u_char *dstp;
         int n, len, checked, l;          int n, len, checked, l;
Line 414  ns_name_unpack(const u_char *msg, const 
Line 448  ns_name_unpack(const u_char *msg, const 
                         /* Limit checks. */                          /* Limit checks. */
                         if ((l = labellen(srcp - 1)) < 0) {                          if ((l = labellen(srcp - 1)) < 0) {
                                 errno = EMSGSIZE;                                  errno = EMSGSIZE;
                                 return(-1);                                  return (-1);
                         }                          }
                         if (dstp + l + 1 >= dstlim || srcp + l >= eom) {                          if (dstp + l + 1 >= dstlim || srcp + l >= eom) {
                                 errno = EMSGSIZE;                                  errno = EMSGSIZE;
Line 456  ns_name_unpack(const u_char *msg, const 
Line 490  ns_name_unpack(const u_char *msg, const 
                         return (-1);                    /*%< flag error */                          return (-1);                    /*%< flag error */
                 }                  }
         }          }
         *dstp = '\0';          *dstp++ = 0;
           if (dstlen != NULL)
                   *dstlen = dstp - dst;
         if (len < 0)          if (len < 0)
                 len = srcp - src;                  len = srcp - src;
         return (len);          return (len);
Line 515  ns_name_pack(const u_char *src, u_char *
Line 551  ns_name_pack(const u_char *src, u_char *
                 }                  }
                 if ((l0 = labellen(srcp)) < 0) {                  if ((l0 = labellen(srcp)) < 0) {
                         errno = EINVAL;                          errno = EINVAL;
                         return(-1);                          return (-1);
                 }                  }
                 l += l0 + 1;                  l += l0 + 1;
                 if (l > MAXCDNAME) {                  if (l > MAXCDNAME) {
Line 662  ns_name_skip(const u_char **ptrptr, cons
Line 698  ns_name_skip(const u_char **ptrptr, cons
                 case NS_TYPE_ELT: /*%< EDNS0 extended label */                  case NS_TYPE_ELT: /*%< EDNS0 extended label */
                         if ((l = labellen(cp - 1)) < 0) {                          if ((l = labellen(cp - 1)) < 0) {
                                 errno = EMSGSIZE; /*%< XXX */                                  errno = EMSGSIZE; /*%< XXX */
                                 return(-1);                                  return (-1);
                         }                          }
                         cp += l;                          cp += l;
                         continue;                          continue;
Line 683  ns_name_skip(const u_char **ptrptr, cons
Line 719  ns_name_skip(const u_char **ptrptr, cons
         return (0);          return (0);
 }  }
   
   /* Find the number of octets an nname takes up, including the root label.
    * (This is basically ns_name_skip() without compression-pointer support.)
    * ((NOTE: can only return zero if passed-in namesiz argument is zero.))
    */
   ssize_t
   ns_name_length(ns_nname_ct nname, size_t namesiz) {
           ns_nname_ct orig = nname;
           u_int n;
   
           while (namesiz-- > 0 && (n = *nname++) != 0) {
                   if ((n & NS_CMPRSFLGS) != 0) {
                           errno = EISDIR;
                           return (-1);
                   }
                   if (n > namesiz) {
                           errno = EMSGSIZE;
                           return (-1);
                   }
                   nname += n;
                   namesiz -= n;
           }
           return (nname - orig);
   }
   
   /* Compare two nname's for equality.  Return -1 on error (setting errno).
    */
   int
   ns_name_eq(ns_nname_ct a, size_t as, ns_nname_ct b, size_t bs) {
           ns_nname_ct ae = a + as, be = b + bs;
           int ac, bc;
   
           while (ac = *a, bc = *b, ac != 0 && bc != 0) {
                   if ((ac & NS_CMPRSFLGS) != 0 || (bc & NS_CMPRSFLGS) != 0) {
                           errno = EISDIR;
                           return (-1);
                   }
                   if (a + ac >= ae || b + bc >= be) {
                           errno = EMSGSIZE;
                           return (-1);
                   }
                   if (ac != bc || strncasecmp((const char *) ++a,
                                               (const char *) ++b, ac) != 0)
                           return (0);
                   a += ac, b += bc;
           }
           return (ac == 0 && bc == 0);
   }
   
   /* Is domain "A" owned by (at or below) domain "B"?
    */
   int
   ns_name_owned(ns_namemap_ct a, int an, ns_namemap_ct b, int bn) {
           /* If A is shorter, it cannot be owned by B. */
           if (an < bn)
                   return (0);
   
           /* If they are unequal before the length of the shorter, A cannot... */
           while (bn > 0) {
                   if (a->len != b->len ||
                       strncasecmp((const char *) a->base,
                                   (const char *) b->base, a->len) != 0)
                           return (0);
                   a++, an--;
                   b++, bn--;
           }
   
           /* A might be longer or not, but either way, B owns it. */
           return (1);
   }
   
   /* Build an array of <base,len> tuples from an nname, top-down order.
    * Return the number of tuples (labels) thus discovered.
    */
   int
   ns_name_map(ns_nname_ct nname, size_t namelen, ns_namemap_t map, int mapsize) {
           u_int n;
           int l;
   
           n = *nname++;
           namelen--;
   
           /* Root zone? */
           if (n == 0) {
                   /* Extra data follows name? */
                   if (namelen > 0) {
                           errno = EMSGSIZE;
                           return (-1);
                   }
                   return (0);
           }
   
           /* Compression pointer? */
           if ((n & NS_CMPRSFLGS) != 0) {
                   errno = EISDIR;
                   return (-1);
           }
   
           /* Label too long? */
           if (n > namelen) {
                   errno = EMSGSIZE;
                   return (-1);
           }
   
           /* Recurse to get rest of name done first. */
           l = ns_name_map(nname + n, namelen - n, map, mapsize);
           if (l < 0)
                   return (-1);
   
           /* Too many labels? */
           if (l >= mapsize) {
                   errno = ENAMETOOLONG;
                   return (-1);
           }
   
           /* We're on our way back up-stack, store current map data. */
           map[l].base = nname;
           map[l].len = n;
           return (l + 1);
   }
   
   /* Count the labels in a domain name.  Root counts, so COM. has two.  This
    * is to make the result comparable to the result of ns_name_map().
    */
   int
   ns_name_labels(ns_nname_ct nname, size_t namesiz) {
           int ret = 0;
           u_int n;
   
           while (namesiz-- > 0 && (n = *nname++) != 0) {
                   if ((n & NS_CMPRSFLGS) != 0) {
                           errno = EISDIR;
                           return (-1);
                   }
                   if (n > namesiz) {
                           errno = EMSGSIZE;
                           return (-1);
                   }
                   nname += n;
                   namesiz -= n;
                   ret++;
           }
           return (ret + 1);
   }
   
 /* Private. */  /* Private. */
   
 /*%  /*%
Line 813  decode_bitstring(const unsigned char **c
Line 993  decode_bitstring(const unsigned char **c
         plen = (blen + 3) / 4;          plen = (blen + 3) / 4;
         plen += sizeof("\\[x/]") + (blen > 99 ? 3 : (blen > 9) ? 2 : 1);          plen += sizeof("\\[x/]") + (blen > 99 ? 3 : (blen > 9) ? 2 : 1);
         if (dn + plen >= eom)          if (dn + plen >= eom)
                 return(-1);                  return (-1);
   
         cp++;          cp++;
         i = SPRINTF((dn, "\\[x"));          i = SPRINTF((dn, "\\[x"));
Line 846  decode_bitstring(const unsigned char **c
Line 1026  decode_bitstring(const unsigned char **c
         dn += i;          dn += i;
   
         *cpp = cp;          *cpp = cp;
         return(dn - beg);          return (dn - beg);
 }  }
   
 static int  static int
 encode_bitsring(const char **bp, const char *end, unsigned char **labelp,  encode_bitsring(const char **bp, const char *end, unsigned char **labelp,
                 unsigned char ** dst, unsigned const char *eom)                  unsigned char ** dst, unsigned const char *eom)
 {  {
         int afterslash = 0;          int afterslash = 0;
         const char *cp = *bp;          const char *cp = *bp;
Line 865  encode_bitsring(const char **bp, const c
Line 1045  encode_bitsring(const char **bp, const c
   
         /* a bitstring must contain at least 2 characters */          /* a bitstring must contain at least 2 characters */
         if (end - cp < 2)          if (end - cp < 2)
                 return(EINVAL);                  return (EINVAL);
   
         /* XXX: currently, only hex strings are supported */          /* XXX: currently, only hex strings are supported */
         if (*cp++ != 'x')          if (*cp++ != 'x')
                 return(EINVAL);                  return (EINVAL);
         if (!isxdigit((*cp) & 0xff)) /*%< reject '\[x/BLEN]' */          if (!isxdigit((*cp) & 0xff)) /*%< reject '\[x/BLEN]' */
                 return(EINVAL);                  return (EINVAL);
   
         for (tp = *dst + 1; cp < end && tp < eom; cp++) {          for (tp = *dst + 1; cp < end && tp < eom; cp++) {
                 switch((c = *cp)) {                  switch((c = *cp)) {
                 case ']':       /*%< end of the bitstring */                  case ']':       /*%< end of the bitstring */
                         if (afterslash) {                          if (afterslash) {
                                 if (beg_blen == NULL)                                  if (beg_blen == NULL)
                                         return(EINVAL);                                          return (EINVAL);
                                 blen = (int)strtol(beg_blen, &end_blen, 10);                                  blen = (int)strtol(beg_blen, &end_blen, 10);
                                 if (*end_blen != ']')                                  if (*end_blen != ']')
                                         return(EINVAL);                                          return (EINVAL);
                         }                          }
                         if (count)                          if (count)
                                 *tp++ = ((value << 4) & 0xff);                                  *tp++ = ((value << 4) & 0xff);
Line 893  encode_bitsring(const char **bp, const c
Line 1073  encode_bitsring(const char **bp, const c
                 default:                  default:
                         if (afterslash) {                          if (afterslash) {
                                 if (!isdigit(c&0xff))                                  if (!isdigit(c&0xff))
                                         return(EINVAL);                                          return (EINVAL);
                                 if (beg_blen == NULL) {                                  if (beg_blen == NULL) {
   
                                         if (c == '0') {                                          if (c == '0') {
                                                 /* blen never begings with 0 */                                                  /* blen never begings with 0 */
                                                 return(EINVAL);                                                  return (EINVAL);
                                         }                                          }
                                         beg_blen = cp;                                          beg_blen = cp;
                                 }                                  }
                         } else {                          } else {
                                 if (!isxdigit(c&0xff))                                  if (!isxdigit(c&0xff))
                                         return(EINVAL);                                          return (EINVAL);
                                 value <<= 4;                                  value <<= 4;
                                 value += digitvalue[(int)c];                                  value += digitvalue[(int)c];
                                 count += 4;                                  count += 4;
                                 tbcount += 4;                                  tbcount += 4;
                                 if (tbcount > 256)                                  if (tbcount > 256)
                                         return(EINVAL);                                          return (EINVAL);
                                 if (count == 8) {                                  if (count == 8) {
                                         *tp++ = value;                                          *tp++ = value;
                                         count = 0;                                          count = 0;
Line 921  encode_bitsring(const char **bp, const c
Line 1101  encode_bitsring(const char **bp, const c
         }          }
   done:    done:
         if (cp >= end || tp >= eom)          if (cp >= end || tp >= eom)
                 return(EMSGSIZE);                  return (EMSGSIZE);
   
         /*          /*
          * bit length validation:           * bit length validation:
Line 935  encode_bitsring(const char **bp, const c
Line 1115  encode_bitsring(const char **bp, const c
                 int traillen;                  int traillen;
   
                 if (((blen + 3) & ~3) != tbcount)                  if (((blen + 3) & ~3) != tbcount)
                         return(EINVAL);                          return (EINVAL);
                 traillen = tbcount - blen; /*%< between 0 and 3 */                  traillen = tbcount - blen; /*%< between 0 and 3 */
                 if (((value << (8 - traillen)) & 0xff) != 0)                  if (((value << (8 - traillen)) & 0xff) != 0)
                         return(EINVAL);                          return (EINVAL);
         }          }
         else          else
                 blen = tbcount;                  blen = tbcount;
Line 952  encode_bitsring(const char **bp, const c
Line 1132  encode_bitsring(const char **bp, const c
         *bp = cp;          *bp = cp;
         *dst = tp;          *dst = tp;
   
         return(0);          return (0);
 }  }
   
 static int  static int
Line 963  labellen(const u_char *lp)
Line 1143  labellen(const u_char *lp)
   
         if ((l & NS_CMPRSFLGS) == NS_CMPRSFLGS) {          if ((l & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
                 /* should be avoided by the caller */                  /* should be avoided by the caller */
                 return(-1);                  return (-1);
         }          }
   
         if ((l & NS_CMPRSFLGS) == NS_TYPE_ELT) {          if ((l & NS_CMPRSFLGS) == NS_TYPE_ELT) {
                 if (l == DNS_LABELTYPE_BITSTRING) {                  if (l == DNS_LABELTYPE_BITSTRING) {
                         if ((bitlen = *(lp + 1)) == 0)                          if ((bitlen = *(lp + 1)) == 0)
                                 bitlen = 256;                                  bitlen = 256;
                         return((bitlen + 7 ) / 8 + 1);                          return ((bitlen + 7 ) / 8 + 1);
                 }                  }
                 return(-1);     /*%< unknwon ELT */                  return (-1);    /*%< unknwon ELT */
         }          }
         return(l);          return (l);
 }  }
   
 /*! \file */  /*! \file */

Legend:
Removed from v.1.6.6.2  
changed lines
  Added in v.1.7

CVSweb <webmaster@jp.NetBSD.org>