diff options
| -rw-r--r-- | include/platform.h | 5 | ||||
| -rw-r--r-- | networking/dnsd.c | 39 | 
2 files changed, 26 insertions, 18 deletions
diff --git a/include/platform.h b/include/platform.h index dcc61a77b..a134a9e42 100644 --- a/include/platform.h +++ b/include/platform.h @@ -208,6 +208,7 @@ typedef uint32_t bb__aliased_uint32_t FIX_ALIASING;  # define move_from_unaligned_int(v, intp) ((v) = *(bb__aliased_int*)(intp))  # define move_from_unaligned16(v, u16p) ((v) = *(bb__aliased_uint16_t*)(u16p))  # define move_from_unaligned32(v, u32p) ((v) = *(bb__aliased_uint32_t*)(u32p)) +# define move_to_unaligned16(u16p, v)   (*(bb__aliased_uint16_t*)(u16p) = (v))  # define move_to_unaligned32(u32p, v)   (*(bb__aliased_uint32_t*)(u32p) = (v))  /* #elif ... - add your favorite arch today! */  #else @@ -215,6 +216,10 @@ typedef uint32_t bb__aliased_uint32_t FIX_ALIASING;  # define move_from_unaligned_int(v, intp) (memcpy(&(v), (intp), sizeof(int)))  # define move_from_unaligned16(v, u16p) (memcpy(&(v), (u16p), 2))  # define move_from_unaligned32(v, u32p) (memcpy(&(v), (u32p), 4)) +# define move_to_unaligned16(u16p, v) do { \ +	uint16_t __t = (v); \ +	memcpy((u16p), &__t, 4); \ +} while (0)  # define move_to_unaligned32(u32p, v) do { \  	uint32_t __t = (v); \  	memcpy((u32p), &__t, 4); \ diff --git a/networking/dnsd.c b/networking/dnsd.c index 56ede3fca..91d66edcc 100644 --- a/networking/dnsd.c +++ b/networking/dnsd.c @@ -44,7 +44,7 @@ struct dns_head {  	uint16_t nauth;  	uint16_t nadd;  }; -struct dns_prop { +struct type_and_class {  	uint16_t type;  	uint16_t class;  }; @@ -291,7 +291,7 @@ QCLASS  a two octet code that specifies the class of the query.          (others are historic only)          255 any class -4.1.3. Resource record format +4.1.3. Resource Record format  The answer, authority, and additional sections all share the same format:  a variable number of resource records, where the number of records @@ -353,14 +353,14 @@ static int process_packet(struct dns_entry *conf_data,  {  	char *answstr;  	struct dns_head *head; -	struct dns_prop *unaligned_qprop; +	struct type_and_class *unaligned_type_class;  	char *query_string;  	uint8_t *answb;  	uint16_t outr_rlen;  	uint16_t outr_flags;  	uint16_t type;  	uint16_t class; -	int querystr_len; +	int query_len;  	head = (struct dns_head *)buf;  	if (head->nquer == 0) { @@ -376,22 +376,22 @@ static int process_packet(struct dns_entry *conf_data,  	/* start of query string */  	query_string = (void *)(head + 1);  	/* caller guarantees strlen is <= MAX_PACK_LEN */ -	querystr_len = strlen(query_string) + 1; +	query_len = strlen(query_string) + 1;  	/* may be unaligned! */ -	unaligned_qprop = (void *)(query_string + querystr_len); -	querystr_len += sizeof(unaligned_qprop); +	unaligned_type_class = (void *)(query_string + query_len); +	query_len += sizeof(unaligned_type_class);  	/* where to append answer block */ -	answb = (void *)(unaligned_qprop + 1); +	answb = (void *)(unaligned_type_class + 1);  	/* QR = 1 "response", RCODE = 4 "Not Implemented" */  	outr_flags = htons(0x8000 | 4); -	move_from_unaligned16(type, &unaligned_qprop->type); +	move_from_unaligned16(type, &unaligned_type_class->type);  	if (type != htons(REQ_A) && type != htons(REQ_PTR)) {  		/* we can't handle the query type */  		goto empty_packet;  	} -	move_from_unaligned16(class, &unaligned_qprop->class); +	move_from_unaligned16(class, &unaligned_type_class->class);  	if (class != htons(1)) { /* not class INET? */  		goto empty_packet;  	} @@ -408,11 +408,11 @@ static int process_packet(struct dns_entry *conf_data,  	answstr = table_lookup(conf_data, type, query_string);  	outr_rlen = 4;  	if (answstr && type == htons(REQ_PTR)) { -		/* return a host name */ +		/* returning a host name */  		outr_rlen = strlen(answstr) + 1;  	}  	if (!answstr -	 || (unsigned)(answb - buf) + querystr_len + 4 + 2 + outr_rlen > MAX_PACK_LEN +	 || (unsigned)(answb - buf) + query_len + 4 + 2 + outr_rlen > MAX_PACK_LEN  	) {  		/* QR = 1 "response"  		 * AA = 1 "Authoritative Answer" @@ -421,20 +421,23 @@ static int process_packet(struct dns_entry *conf_data,  		goto empty_packet;  	} -	/* copy query block to answer block */ -	memcpy(answb, query_string, querystr_len); -	answb += querystr_len; -	/* append answer Resource Record */ +	/* Append answer Resource Record */ +	memcpy(answb, query_string, query_len); /* name, type, class */ +	answb += query_len;  	move_to_unaligned32((uint32_t *)answb, htonl(conf_ttl));  	answb += 4; -	move_to_unaligned32((uint16_t *)answb, htons(outr_rlen)); +	move_to_unaligned16((uint16_t *)answb, htons(outr_rlen));  	answb += 2;  	memcpy(answb, answstr, outr_rlen);  	answb += outr_rlen;  	/* QR = 1 "response",  	 * AA = 1 "Authoritative Answer", -	 * RCODE = 0 "success" */ +	 * TODO: need to set RA bit 0x80? One user says nslookup complains +	 * "Got recursion not available from SERVER, trying next server" +	 * "** server can't find HOSTNAME" +	 * RCODE = 0 "success" +	 */  	outr_flags = htons(0x8000 | 0x0400 | 0);  	/* we have one answer */  	head->nansw = htons(1);  | 
