+static int inet6_rev_parsecomp(const char *p, size_t n)
+{
+ if (n != 1) return -1;
+ else if ('0' <= *p && *p <= '9') return *p - '0';
+ else if ('a' <= *p && *p <= 'f') return *p - 'a' + 10;
+ else if ('A' <= *p && *p <= 'F') return *p - 'a' + 10;
+ else return -1;
+}
+
+static void inet6_rev_mkaddr(union gen_addr *addr, const byte *ipv)
+{
+ unsigned char *a = addr->v6.s6_addr;
+ int i;
+
+ for (i = 0; i < 16; i++)
+ a[i] = (ipv[31-2*i] << 4) | (ipv[30-2*i] << 0);
+}
+
+static char *inet6_rev_mkname(struct sockaddr *sa, char *buf)
+{
+ unsigned char *a = SIN6(sa)->sin6_addr.s6_addr + 16;
+ unsigned c, y;
+ int i, j;
+
+ for (i = 0; i < 16; i++) {
+ c = *--a;
+ for (j = 0; j < 2; j++) {
+ if (i || j) *buf++ = '.';
+ y = c & 0xf;
+ if (y < 10) *buf++ = y + '0';
+ else *buf++ = y - 10 + 'a';
+ c >>= 4;
+ }
+ }
+ return buf;
+}
+