diff --git a/mdns.c b/mdns.c index c5cc45a..3f44ac2 100644 --- a/mdns.c +++ b/mdns.c @@ -378,6 +378,13 @@ struct rr_entry *rr_create_a(uint8_t *name, uint32_t addr) { return rr; } +struct rr_entry *rr_create_aaaa(uint8_t *name, struct in6_addr *addr) { + DECL_MALLOC_ZERO_STRUCT(rr, rr_entry); + FILL_RR_ENTRY(rr, name, RR_AAAA); + rr->data.AAAA.addr = addr; + return rr; +} + struct rr_entry *rr_create_srv(uint8_t *name, uint16_t port, uint8_t *target) { DECL_MALLOC_ZERO_STRUCT(rr, rr_entry); FILL_RR_ENTRY(rr, name, RR_SRV); @@ -649,6 +656,18 @@ static size_t mdns_parse_rr(uint8_t *pkt_buf, size_t pkt_len, size_t off, p += sizeof(uint32_t); break; + case RR_AAAA: + if (rr_data_len < sizeof(struct in6_addr)) { + DEBUG_PRINTF("invalid rr_data_len=%lu for AAAA record\n", rr_data_len); + parse_error = 1; + break; + } + rr->data.AAAA.addr = malloc(sizeof(struct in6_addr)); + for (int i = 0; i < sizeof(struct in6_addr); i++) + rr->data.AAAA.addr->s6_addr[i] = p[i]; + p += sizeof(struct in6_addr); + break; + case RR_PTR: rr->data.PTR.name = uncompress_nlabel(pkt_buf, pkt_len, p - pkt_buf); if (rr->data.PTR.name == NULL) { @@ -838,6 +857,11 @@ static size_t mdns_encode_rr(uint8_t *pkt_buf, size_t pkt_len, size_t off, p = mdns_write_u32(p, htonl(rr->data.A.addr)); break; + case RR_AAAA: + for (i = 0; i < sizeof(struct in6_addr); i++) + *p++ = rr->data.AAAA.addr->s6_addr[i]; + break; + case RR_PTR: label = rr->data.PTR.name ? rr->data.PTR.name : diff --git a/mdns.h b/mdns.h index bf28c72..609abf8 100644 --- a/mdns.h +++ b/mdns.h @@ -32,6 +32,7 @@ #include #include #include +#include #define MALLOC_ZERO_STRUCT(x, type) \ x = malloc(sizeof(struct type)); \ @@ -76,6 +77,10 @@ struct rr_data_a { uint32_t addr; }; +struct rr_data_aaaa { + struct in6_addr *addr; +}; + struct rr_entry { uint8_t *name; @@ -106,6 +111,7 @@ struct rr_entry { struct rr_data_txt TXT; struct rr_data_ptr PTR; struct rr_data_a A; + struct rr_data_aaaa AAAA; } data; }; @@ -168,6 +174,7 @@ void rr_list_destroy(struct rr_list *rr, char destroy_items); struct rr_entry *rr_create_ptr(uint8_t *name, struct rr_entry *d_rr); struct rr_entry *rr_create_srv(uint8_t *name, uint16_t port, uint8_t *target); +struct rr_entry *rr_create_aaaa(uint8_t *name, struct in6_addr *addr); struct rr_entry *rr_create_a(uint8_t *name, uint32_t addr); struct rr_entry *rr_create(uint8_t *name, enum rr_type type); void rr_set_nsec(struct rr_entry *rr_nsec, enum rr_type type);