interface: fix interface memory corruption
[project/mdnsd.git] / dns.c
diff --git a/dns.c b/dns.c
index 86e5ea3aaa6c7f44cc4d52d4082b8ec9580046e0..2ebb6241deef9d5ca135efd7705a952ea6688959 100644 (file)
--- a/dns.c
+++ b/dns.c
@@ -200,10 +200,8 @@ dns_reply_a(struct interface *iface, struct sockaddr *to, int ttl)
                        dns_add_answer(TYPE_A, (uint8_t *) &sa->sin_addr, 4, ttl);
                }
                if (ifa->ifa_addr->sa_family == AF_INET6) {
-                       uint8_t ll_prefix[] = {0xfe, 0x80 };
                        sa6 = (struct sockaddr_in6 *) ifa->ifa_addr;
-                       if (!memcmp(&sa6->sin6_addr, &ll_prefix, 2))
-                               dns_add_answer(TYPE_AAAA, (uint8_t *) &sa6->sin6_addr, 16, ttl);
+                       dns_add_answer(TYPE_AAAA, (uint8_t *) &sa6->sin6_addr, 16, ttl);
                }
        }
        dns_send_answer(iface, to, mdns_hostname_local);
@@ -222,6 +220,7 @@ scan_name(const uint8_t *buffer, int len)
                if (IS_COMPRESSED(l))
                        return offset + 2;
 
+               if (l + 1 > len) return -1;
                len -= l + 1;
                offset += l + 1;
                buffer += l + 1;
@@ -317,7 +316,7 @@ static int parse_answer(struct interface *iface, struct sockaddr *from,
        struct dns_answer *a;
        uint8_t *rdata;
 
-       if (!name) {
+       if (!name || *rlen < 0) {
                fprintf(stderr, "dropping: bad question\n");
                return -1;
        }
@@ -355,8 +354,8 @@ parse_question(struct interface *iface, struct sockaddr *from, char *name, struc
        /* TODO: Multicast if more than one quarter of TTL has passed */
        if (q->class & CLASS_UNICAST) {
                to = from;
-               if (iface->multicast)
-                       iface = iface->peer;
+               if (interface_multicast(iface))
+                       iface = interface_get(iface->name, iface->type | SOCKTYPE_BIT_UNICAST);
        }
 
        DBG(1, "Q -> %s %s\n", dns_type_string(q->type), name);
@@ -413,7 +412,7 @@ dns_handle_packet(struct interface *iface, struct sockaddr *from, uint16_t port,
                return;
        }
 
-       if (h->questions && !iface->multicast && port != MCAST_PORT)
+       if (h->questions && !interface_multicast(iface) && port != MCAST_PORT)
                /* silently drop unicast questions that dont originate from port 5353 */
                return;
 
@@ -421,7 +420,7 @@ dns_handle_packet(struct interface *iface, struct sockaddr *from, uint16_t port,
                char *name = dns_consume_name(buffer, len, &b, &rlen);
                struct dns_question *q;
 
-               if (!name) {
+               if (!name || rlen < 0) {
                        fprintf(stderr, "dropping: bad name\n");
                        return;
                }