-static int
-dns_extract_data(kvarray_t *in, char **buf, uint32_t *len, struct sockaddr **from, uint32_t *fromlen)
-{
- int32_t status;
- struct in_addr addr4;
- struct sockaddr_in sin4;
- struct in6_addr addr6;
- struct sockaddr_in6 sin6;
- uint32_t d, k, kcount;
-
- if (in == NULL) return -1;
- if (buf == NULL) return -1;
- if (len == NULL) return -1;
- if (from == NULL) return -1;
- if (fromlen == NULL) return -1;
-
- *buf = NULL;
- *len = 0;
- *from = NULL;
- *fromlen = 0;
-
- d = in->curr;
- in->curr++;
-
- if (d >= in->count) return -1;
-
- kcount = in->dict[d].kcount;
-
- for (k = 0; k < kcount; k++)
- {
- if (!strcmp(in->dict[d].key[k], "data"))
- {
- if (in->dict[d].vcount[k] == 0) continue;
- if (*buf != NULL) continue;
-
- /*
- * dns_proxy contains binary data, possibly with embedded nuls,
- * so we extract the string length from the kvbuf_t reply that
- * Libinfo got from directory services, rather than calling strlen().
- */
- *len = kvbuf_get_len(in->dict[d].val[k][0]);
- if (*len == 0) continue;
-
- *buf = malloc(*len);
- if (*buf == NULL) return -1;
-
- memcpy(*buf, in->dict[d].val[k][0], *len);
- }
- else if (!strcmp(in->dict[d].key[k], "server"))
- {
- if (in->dict[d].vcount[k] == 0) continue;
- if (*from != NULL) continue;
-
- memset(&addr4, 0, sizeof(struct in_addr));
- memset(&sin4, 0, sizeof(struct sockaddr_in));
-
- memset(&addr6, 0, sizeof(struct in6_addr));
- memset(&sin6, 0, sizeof(struct sockaddr_in6));
-
- status = inet_pton(AF_INET6, in->dict[d].val[k][0], &addr6);
- if (status == 1)
- {
- sin6.sin6_addr = addr6;
- sin6.sin6_family = AF_INET6;
- sin6.sin6_len = sizeof(struct sockaddr_in6);
- *from = (struct sockaddr *)calloc(1, sin6.sin6_len);
- memcpy(*from, &sin6, sin6.sin6_len);
- *fromlen = sin6.sin6_len;
- }
-
- status = inet_pton(AF_INET, in->dict[d].val[k][0], &addr4);
- if (status == 1)
- {
- sin4.sin_addr = addr4;
- sin4.sin_family = AF_INET;
- sin4.sin_len = sizeof(struct sockaddr_in);
- *from = (struct sockaddr *)calloc(1, sin4.sin_len);
- memcpy(*from, &sin4, sin4.sin_len);
- *fromlen = sin4.sin_len;
- }
- }
- }
-
- return 0;
-}
-