summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-02-06 21:48:10 (GMT)
committer Denys Vlasenko <vda.linux@googlemail.com>2010-02-06 21:48:10 (GMT)
commit5fb38491e3ef093fb9cf642f0f3da5f2ed051f33 (patch)
tree3566bdff9b5ce23b1bd4531653a66cf112715dca
parentcb7edc26611f8df6b81ef4337206d5833ea98771 (diff)
downloadbusybox-5fb38491e3ef093fb9cf642f0f3da5f2ed051f33.tar.gz
busybox-5fb38491e3ef093fb9cf642f0f3da5f2ed051f33.tar.bz2
dnsd: fix one big-endian goof; add a TODO about RA bit
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--include/platform.h5
-rw-r--r--networking/dnsd.c39
2 files changed, 26 insertions, 18 deletions
diff --git a/include/platform.h b/include/platform.h
index dcc61a7..a134a9e 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 56ede3f..91d66ed 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);