resolv: Fix for word alignment issues in mdns_prep_host_announce_packet().

This commit is contained in:
Robert Quattlebaum 2013-05-16 09:38:42 -07:00
parent 5af6540980
commit 0bed4b17a2

View File

@ -570,22 +570,55 @@ mdns_write_announce_records(unsigned char *queryptr, uint8_t *count)
static size_t static size_t
mdns_prep_host_announce_packet(void) mdns_prep_host_announce_packet(void)
{ {
static const struct {
uint16_t type;
uint16_t class;
uint16_t ttl[2];
uint16_t len;
uint8_t data[8];
} nsec_record = {
UIP_HTONS(DNS_TYPE_NSEC),
UIP_HTONS(DNS_CLASS_IN | 0x8000),
{ 0, UIP_HTONS(120) },
UIP_HTONS(8),
{
0xc0,
sizeof(struct dns_hdr), /* Name compression. Re-using the name of first record. */
0x00,
0x04,
#if UIP_CONF_IPV6
0x00,
0x00,
0x00,
0x08,
#else /* UIP_CONF_IPV6 */
0x40,
0x00,
0x00,
0x00,
#endif /* UIP_CONF_IPV6 */
}
};
unsigned char *queryptr; unsigned char *queryptr;
struct dns_answer *ans;
struct dns_hdr *hdr;
uint8_t total_answers = 0; uint8_t total_answers = 0;
hdr = (struct dns_hdr *)uip_appdata; struct dns_answer *ans;
/* Be aware that, unless `ARCH_DOESNT_NEED_ALIGNED_STRUCTS` is set,
* writing directly to the uint16_t members of this struct is an error. */
struct dns_hdr *hdr = (struct dns_hdr *)uip_appdata;
/* Zero out the header */
memset((void *)hdr, 0, sizeof(*hdr));
hdr->flags1 |= DNS_FLAG1_RESPONSE | DNS_FLAG1_AUTHORATIVE; hdr->flags1 |= DNS_FLAG1_RESPONSE | DNS_FLAG1_AUTHORATIVE;
hdr->numquestions = UIP_HTONS(0);
hdr->numauthrr = 0;
hdr->numextrarr = 0;
queryptr = (unsigned char *)hdr + sizeof(*hdr); queryptr = (unsigned char *)uip_appdata + sizeof(*hdr);
queryptr = mdns_write_announce_records(queryptr, &total_answers); queryptr = mdns_write_announce_records(queryptr, &total_answers);
@ -595,34 +628,17 @@ mdns_prep_host_announce_packet(void)
if(!total_answers) { if(!total_answers) {
queryptr = encode_name(queryptr, resolv_hostname); queryptr = encode_name(queryptr, resolv_hostname);
} else { } else {
/* Name compression. Re-using the name of first record. */
*queryptr++ = 0xc0; *queryptr++ = 0xc0;
*queryptr++ = sizeof(*hdr); *queryptr++ = sizeof(*hdr);
} }
ans = (struct dns_answer *)queryptr;
ans->type = UIP_HTONS(DNS_TYPE_NSEC);
ans->class = UIP_HTONS(DNS_CLASS_IN | 0x8000);
ans->ttl[0] = 0;
ans->ttl[1] = UIP_HTONS(120);
ans->len = UIP_HTONS(8);
queryptr += 10;
*queryptr++ = 0xc0;
*queryptr++ = sizeof(*hdr);
*queryptr++ = 0x00;
*queryptr++ = 0x04;
#if UIP_CONF_IPV6
*queryptr++ = 0x00;
*queryptr++ = 0x00;
*queryptr++ = 0x00;
*queryptr++ = 0x08;
#else /* UIP_CONF_IPV6 */
*queryptr++ = 0x40;
*queryptr++ = 0x00;
*queryptr++ = 0x00;
*queryptr++ = 0x00;
#endif /* UIP_CONF_IPV6 */
hdr->numanswers = uip_htons(total_answers); memcpy((void *)queryptr, (void *)&nsec_record, sizeof(nsec_record));
hdr->numextrarr = UIP_HTONS(1);
/* This platform might be picky about alignment. To avoid the possibility
* of doing an unaligned write, we are going to do this manually. */
((uint8_t*)&hdr->numanswers)[1] = total_answers;
((uint8_t*)&hdr->numextrarr)[1] = 1;
return (queryptr - (unsigned char *)uip_appdata); return (queryptr - (unsigned char *)uip_appdata);
} }
@ -1485,4 +1501,4 @@ resolv_found(char *name, uip_ipaddr_t * ipaddr)
#endif /* UIP_UDP */ #endif /* UIP_UDP */
/** @} */ /** @} */
/** @} */ /** @} */