dnsd: fix one big-endian goof; add a TODO about RA bit

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2010-02-06 22:48:10 +01:00
parent cb7edc2661
commit 5fb38491e3
2 changed files with 26 additions and 18 deletions

View File

@ -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); \

View File

@ -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);