When we converted isc_sockaddr_t to sockaddr_storage we also moved to inet_net_pton(3). It turns out that was a mistake, at least it's not portable for AF_INET6. Effectively revert that part and hand-roll it using inet_pton(3).
OK? p.s. it is kinda telling that isc, who introduced the API is (no longer?) using it. diff --git dighost.c dighost.c index 2d2a52c86e2..2995b7e1602 100644 --- dighost.c +++ dighost.c @@ -935,10 +935,16 @@ parse_netprefix(struct sockaddr_storage **sap, int *plen, const char *value) { struct sockaddr_storage *sa = NULL; struct in_addr *in4; struct in6_addr *in6; - int prefix_length; + int prefix_length = -1, i; + char *sep; + char buf[INET6_ADDRSTRLEN + sizeof("/128")]; + const char *errstr; REQUIRE(sap != NULL && *sap == NULL); + if (strlcpy(buf, value, sizeof(buf)) >= sizeof(buf)) + fatal("invalid prefix '%s'\n", value); + sa = calloc(1, sizeof(*sa)); if (sa == NULL) fatal("out of memory"); @@ -952,14 +958,36 @@ parse_netprefix(struct sockaddr_storage **sap, int *plen, const char *value) { goto done; } - if ((prefix_length = inet_net_pton(AF_INET6, value, in6, sizeof(*in6))) - != -1) { + sep = strchr(buf, '/'); + if (sep != NULL) { + *sep++ = '\0'; + prefix_length = strtonum(sep, 0, 128, &errstr); + if (errstr != NULL) + fatal("invalid address '%s'", value); + } + + if (inet_pton(AF_INET6, buf, in6) == 1) { sa->ss_len = sizeof(struct sockaddr_in6); sa->ss_family = AF_INET6; - } else if ((prefix_length = inet_net_pton(AF_INET, value, in4, - sizeof(*in4))) != -1) { + if (prefix_length > 128 || prefix_length == -1) + prefix_length = 128; + } else if (inet_pton(AF_INET, buf, in4) == 1) { sa->ss_len = sizeof(struct sockaddr_in); sa->ss_family = AF_INET; + if (prefix_length > 32 || prefix_length == -1) + prefix_length = 32; + } else if (prefix_length != -1) { + if (prefix_length > 32) + prefix_length = 32; + for (i = 0; i < 3 ; i++) { + if (strlcat(buf, ".0", sizeof(buf)) > sizeof(buf)) + fatal("invalid address '%s'", value); + if (inet_pton(AF_INET, buf, in4) == 1) { + sa->ss_len = sizeof(struct sockaddr_in); + sa->ss_family = AF_INET; + goto done; + } + } } else fatal("invalid address '%s'", value); -- I'm not entirely sure you are real.