} else if (netmask != 0xffffffff) {
int i;
- for (i = 0; i < 3; i++) {
+ for (i = 0; i < 3 && strlen(buf) < sizeof(buf) - 2; i++) {
strlcat(buf, ".0", sizeof(buf));
if (inet_pton(AF_INET, buf, &in4) == 1) {
parsed = ISC_TRUE;
}
if (lookup->ecs_addr != NULL) {
- isc_uint32_t prefixlen;
+ isc_uint8_t addr[16], family;
+ isc_uint32_t plen;
struct sockaddr *sa;
struct sockaddr_in *sin;
struct sockaddr_in6 *sin6;
- const isc_uint8_t *addr;
size_t addrl;
- isc_uint8_t mask;
sa = &lookup->ecs_addr->type.sa;
- prefixlen = lookup->ecs_addr->length;
+ plen = lookup->ecs_addr->length;
/* Round up prefix len to a multiple of 8 */
- addrl = (prefixlen + 7) / 8;
- if (prefixlen % 8 == 0)
- mask = 0xff;
- else
- mask = 0xffU << (8 - (prefixlen % 8));
+ addrl = (plen + 7) / 8;
INSIST(i < DNS_EDNSOPTIONS);
opts[i].code = DNS_OPT_CLIENT_SUBNET;
check_result(result, "isc_buffer_allocate");
isc_buffer_init(&b, ecsbuf, sizeof(ecsbuf));
if (sa->sa_family == AF_INET) {
+ family = 1;
sin = (struct sockaddr_in *) sa;
- addr = (isc_uint8_t *) &sin->sin_addr;
- /* family */
- isc_buffer_putuint16(&b, 1);
- /* source prefix-length */
- isc_buffer_putuint8(&b, prefixlen);
- /* scope prefix-length */
- isc_buffer_putuint8(&b, 0);
- /* address */
- if (addrl > 0) {
- isc_buffer_putmem(&b, addr,
- (unsigned)addrl - 1);
- isc_buffer_putuint8(&b,
- (addr[addrl - 1] &
- mask));
- }
+ memcpy(addr, &sin->sin_addr, 4);
+ if ((plen % 8) != 0)
+ addr[addrl-1] &=
+ ~0 << (8 - (plen % 8));
} else {
+ family = 2;
sin6 = (struct sockaddr_in6 *) sa;
- addr = (isc_uint8_t *) &sin6->sin6_addr;
- /* family */
- isc_buffer_putuint16(&b, 2);
- /* source prefix-length */
- isc_buffer_putuint8(&b, prefixlen);
- /* scope prefix-length */
- isc_buffer_putuint8(&b, 0);
- /* address */
- if (addrl > 0) {
- isc_buffer_putmem(&b, addr,
- (unsigned)addrl - 1);
- isc_buffer_putuint8(&b,
- (addr[addrl - 1] &
- mask));
- }
+ memcpy(addr, &sin6->sin6_addr, 16);
}
+ /* Mask off last address byte */
+ if (addrl > 0 && (plen % 8) != 0)
+ addr[addrl - 1] &= ~0 << (8 - (plen % 8));
+
+ /* family */
+ isc_buffer_putuint16(&b, family);
+ /* source prefix-length */
+ isc_buffer_putuint8(&b, plen);
+ /* scope prefix-length */
+ isc_buffer_putuint8(&b, 0);
+ /* address */
+ if (addrl > 0)
+ isc_buffer_putmem(&b, addr,
+ (unsigned)addrl);
+
opts[i].value = (isc_uint8_t *) ecsbuf;
i++;
}
}
if (query->ecs_addr != NULL) {
- isc_uint32_t prefixlen;
+ isc_uint8_t addr[16], family;
+ isc_uint32_t plen;
struct sockaddr *sa;
struct sockaddr_in *sin;
struct sockaddr_in6 *sin6;
- const isc_uint8_t *addr;
size_t addrl;
- isc_uint8_t mask;
isc_buffer_t b;
sa = &query->ecs_addr->type.sa;
- prefixlen = query->ecs_addr->length;
+ plen = query->ecs_addr->length;
/* Round up prefix len to a multiple of 8 */
- addrl = (prefixlen + 7) / 8;
- if (prefixlen % 8 == 0)
- mask = 0xff;
- else
- mask = 0xffU << (8 - (prefixlen % 8));
+ addrl = (plen + 7) / 8;
INSIST(i < DNS_EDNSOPTIONS);
opts[i].code = DNS_OPT_CLIENT_SUBNET;
CHECK("isc_buffer_allocate", result);
isc_buffer_init(&b, ecsbuf, sizeof(ecsbuf));
if (sa->sa_family == AF_INET) {
+ family = 1;
sin = (struct sockaddr_in *) sa;
- addr = (isc_uint8_t *) &sin->sin_addr;
- /* family */
- isc_buffer_putuint16(&b, 1);
- /* source prefix-length */
- isc_buffer_putuint8(&b, prefixlen);
- /* scope prefix-length */
- isc_buffer_putuint8(&b, 0);
- /* address */
- if (addrl > 0) {
- isc_buffer_putmem(&b, addr,
- (unsigned)addrl - 1);
- isc_buffer_putuint8(&b,
- (addr[addrl - 1] &
- mask));
- }
+ memcpy(addr, &sin->sin_addr, 4);
+ if ((plen % 8) != 0)
+ addr[addrl-1] &=
+ ~0 << (8 - (plen % 8));
} else {
+ family = 2;
sin6 = (struct sockaddr_in6 *) sa;
- addr = (isc_uint8_t *) &sin6->sin6_addr;
- /* family */
- isc_buffer_putuint16(&b, 2);
- /* source prefix-length */
- isc_buffer_putuint8(&b, prefixlen);
- /* scope prefix-length */
- isc_buffer_putuint8(&b, 0);
- /* address */
- if (addrl > 0) {
- isc_buffer_putmem(&b, addr,
- (unsigned)addrl - 1);
- isc_buffer_putuint8(&b,
- (addr[addrl - 1] &
- mask));
- }
+ memcpy(addr, &sin6->sin6_addr, 16);
}
+ /* Mask off last address byte */
+ if (addrl > 0 && (plen % 8) != 0)
+ addr[addrl - 1] &= ~0 << (8 - (plen % 8));
+
+ /* family */
+ isc_buffer_putuint16(&b, family);
+ /* source prefix-length */
+ isc_buffer_putuint8(&b, plen);
+ /* scope prefix-length */
+ isc_buffer_putuint8(&b, 0);
+ /* address */
+ if (addrl > 0)
+ isc_buffer_putmem(&b, addr,
+ (unsigned)addrl);
+
opts[i].value = (isc_uint8_t *) ecsbuf;
i++;
}
slash = strchr(buf, '/');
if (slash != NULL) {
+ *slash = '\0';
result = isc_parse_uint32(&netmask, slash + 1, 10);
if (result != ISC_R_SUCCESS) {
fatal("invalid prefix length in '%s': %s\n",
} else if (netmask != 0xffffffff) {
int i;
- for (i = 0; i < 3; i++) {
+ for (i = 0; i < 3 && strlen(buf) < sizeof(buf) - 2; i++) {
strlcat(buf, ".0", sizeof(buf));
if (inet_pton(AF_INET, buf, &in4) == 1) {
parsed = ISC_TRUE;
/*% Main processing routine for mdig */
int
-main(int argc, char *argv[])
-{
+main(int argc, char *argv[]) {
struct query *query;
isc_sockaddr_t bind_any;
isc_log_t *lctx;
fatal("could not find either IPv4 or IPv6");
mctx = NULL;
+isc_mem_debugging = ISC_MEM_DEBUGRECORD;
RUNCHECK(isc_mem_create(0, 0, &mctx));
lctx = NULL;
while (query != NULL) {
struct query *next = ISC_LIST_NEXT(query, link);
- if (query->ecs_addr != NULL)
+ if (query->ecs_addr != NULL) {
isc_mem_free(mctx, query->ecs_addr);
+ query->ecs_addr = NULL;
+ }
isc_mem_free(mctx, query);
query = next;
}
+ if (default_query.ecs_addr != NULL)
+ isc_mem_free(mctx, default_query.ecs_addr);
+
dns_view_detach(&view);
dns_requestmgr_shutdown(requestmgr);