+ struct dns_header *h;
+ uint8_t *b = buffer;
+ int rlen = len;
+
+ h = dns_consume_header(&b, &rlen);
+ if (!h) {
+ fprintf(stderr, "dropping: bad header\n");
+ return;
+ }
+
+ if (h->questions && !iface->multicast && port != MCAST_PORT)
+ /* silently drop unicast questions that dont originate from port 5353 */
+ return;
+
+ while (h->questions-- > 0) {
+ char *name = dns_consume_name(buffer, len, &b, &rlen);
+ struct dns_question *q;
+
+ if (!name || rlen < 0) {
+ fprintf(stderr, "dropping: bad name\n");
+ return;
+ }
+
+ q = dns_consume_question(&b, &rlen);
+ if (!q) {
+ fprintf(stderr, "dropping: bad question\n");
+ return;
+ }
+
+ if (!(h->flags & FLAG_RESPONSE))
+ parse_question(iface, from, name, q);
+ }
+
+ if (!(h->flags & FLAG_RESPONSE))
+ return;
+
+ while (h->answers-- > 0)
+ if (parse_answer(iface, from, buffer, len, &b, &rlen, 1))
+ return;
+
+ while (h->authority-- > 0)
+ if (parse_answer(iface, from, buffer, len, &b, &rlen, 1))
+ return;
+
+ while (h->additional-- > 0)
+ if (parse_answer(iface, from, buffer, len, &b, &rlen, 1))
+ return;
+