+ break;
+ case '.': {
+ uint32_t ip4;
+ unsigned int len;
+ len = ircd_aton_ip4(part_start, &ip4, pbits);
+ if (!len || (ii > 6))
+ return 0;
+ ip->in6_16[ii++] = htons(ntohl(ip4) >> 16);
+ ip->in6_16[ii++] = htons(ntohl(ip4) & 65535);
+ if (pbits)
+ *pbits += 96;
+ pos = part_start + len - input;
+ goto finish;
+ }
+ case '/':
+ if (!pbits || !IsDigit(input[pos + 1]))
+ return 0;
+ ip->in6_16[ii++] = htons(part);
+ for (part = 0; IsDigit(input[++pos]); )
+ part = part * 10 + input[pos] - '0';
+ if (part > 128)
+ return 0;
+ *pbits = part;
+ goto finish;
+ case '*':
+ while (input[++pos] == '*' || input[pos] == ':') ;
+ if (input[pos] != '\0' || colon < 8)
+ return 0;
+ if (part && ii < 8)
+ ip->in6_16[ii++] = htons(part);
+ if (pbits)
+ *pbits = ii * 16;
+ return pos;
+ case '\0':
+ ip->in6_16[ii++] = htons(part);
+ if (colon == 8 && ii < 8)
+ return 0;
+ if (pbits)
+ *pbits = 128;
+ goto finish;
+ default:
+ return 0;
+ }
+ if (input[pos] != '\0')
+ return 0;
+ finish:
+ if (colon < 8) {
+ unsigned int jj;
+ /* Shift stuff after "::" up and fill middle with zeros. */
+ for (jj = 0; jj < ii - colon; jj++)
+ ip->in6_16[7 - jj] = ip->in6_16[ii - jj - 1];
+ for (jj = 0; jj < 8 - ii; jj++)
+ ip->in6_16[colon + jj] = 0;