--- tinydns-data.c.old	2006-09-06 07:39:08.000000000 +0000
+++ tinydns-data.c	2006-09-06 07:46:32.000000000 +0000
@@ -34,6 +34,10 @@
 {
   strerr_die1sys(111,FATAL);
 }
+static void badprefix6(void)
+{ strerr_die2x(100,FATAL,"bad ipv6 client address prefix"); }
+static void badprefix4(void)
+{ strerr_die2x(100,FATAL,"bad ipv4 client address prefix"); }
 
 void ttdparse(stralloc *sa,char ttd[8])
 {
@@ -60,18 +64,41 @@
   loc[1] = (sa->len > 1) ? sa->s[1] : 0;
 }
 
+static int unhexnibble(unsigned char c) {
+  if (c>='0' && c<='9') return c-'0';
+  else if (c>='A' && c<='F') return c-'A'+10;
+  else if (c>='a' && c<='f') return c-'a'+10;
+  return -1;
+}
+
 void ipprefix_cat(stralloc *out,char *s)
 {
   unsigned long u;
   char ch;
   unsigned int j;
-
+  /* ip6 prefixes for locations have to start with a plus sign. */
+  if (*s=='+') {
+    s++;
+    while (*s) {
+      if (!s[1]) badprefix6();
+      int n1,n2;
+      n1=unhexnibble(s[0]);
+      n2=unhexnibble(s[1]);
+      if (-1==n1 || -1==n2) badprefix6();
+      ch=16*n1+n2;
+      if (!stralloc_catb(out,&ch,1)) nomem();
+      s+=2;
+    }
+    return;
+  }
   for (;;)
     if (*s == '.')
       ++s;
     else {
+      if (!*s) return;
       j = scan_ulong(s,&u);
-      if (!j) return;
+      if (!j) badprefix4();
+      if (u>255) badprefix4();
       s += j;
       ch = u;
       if (!stralloc_catb(out,&ch,1)) nomem();
