mirror of
https://github.com/sheumann/hush.git
synced 2025-01-03 00:31:16 +00:00
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:
parent
cb7edc2661
commit
5fb38491e3
@ -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_unaligned_int(v, intp) ((v) = *(bb__aliased_int*)(intp))
|
||||||
# define move_from_unaligned16(v, u16p) ((v) = *(bb__aliased_uint16_t*)(u16p))
|
# 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_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))
|
# define move_to_unaligned32(u32p, v) (*(bb__aliased_uint32_t*)(u32p) = (v))
|
||||||
/* #elif ... - add your favorite arch today! */
|
/* #elif ... - add your favorite arch today! */
|
||||||
#else
|
#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_unaligned_int(v, intp) (memcpy(&(v), (intp), sizeof(int)))
|
||||||
# define move_from_unaligned16(v, u16p) (memcpy(&(v), (u16p), 2))
|
# define move_from_unaligned16(v, u16p) (memcpy(&(v), (u16p), 2))
|
||||||
# define move_from_unaligned32(v, u32p) (memcpy(&(v), (u32p), 4))
|
# 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 { \
|
# define move_to_unaligned32(u32p, v) do { \
|
||||||
uint32_t __t = (v); \
|
uint32_t __t = (v); \
|
||||||
memcpy((u32p), &__t, 4); \
|
memcpy((u32p), &__t, 4); \
|
||||||
|
@ -44,7 +44,7 @@ struct dns_head {
|
|||||||
uint16_t nauth;
|
uint16_t nauth;
|
||||||
uint16_t nadd;
|
uint16_t nadd;
|
||||||
};
|
};
|
||||||
struct dns_prop {
|
struct type_and_class {
|
||||||
uint16_t type;
|
uint16_t type;
|
||||||
uint16_t class;
|
uint16_t class;
|
||||||
};
|
};
|
||||||
@ -291,7 +291,7 @@ QCLASS a two octet code that specifies the class of the query.
|
|||||||
(others are historic only)
|
(others are historic only)
|
||||||
255 any class
|
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:
|
The answer, authority, and additional sections all share the same format:
|
||||||
a variable number of resource records, where the number of records
|
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;
|
char *answstr;
|
||||||
struct dns_head *head;
|
struct dns_head *head;
|
||||||
struct dns_prop *unaligned_qprop;
|
struct type_and_class *unaligned_type_class;
|
||||||
char *query_string;
|
char *query_string;
|
||||||
uint8_t *answb;
|
uint8_t *answb;
|
||||||
uint16_t outr_rlen;
|
uint16_t outr_rlen;
|
||||||
uint16_t outr_flags;
|
uint16_t outr_flags;
|
||||||
uint16_t type;
|
uint16_t type;
|
||||||
uint16_t class;
|
uint16_t class;
|
||||||
int querystr_len;
|
int query_len;
|
||||||
|
|
||||||
head = (struct dns_head *)buf;
|
head = (struct dns_head *)buf;
|
||||||
if (head->nquer == 0) {
|
if (head->nquer == 0) {
|
||||||
@ -376,22 +376,22 @@ static int process_packet(struct dns_entry *conf_data,
|
|||||||
/* start of query string */
|
/* start of query string */
|
||||||
query_string = (void *)(head + 1);
|
query_string = (void *)(head + 1);
|
||||||
/* caller guarantees strlen is <= MAX_PACK_LEN */
|
/* caller guarantees strlen is <= MAX_PACK_LEN */
|
||||||
querystr_len = strlen(query_string) + 1;
|
query_len = strlen(query_string) + 1;
|
||||||
/* may be unaligned! */
|
/* may be unaligned! */
|
||||||
unaligned_qprop = (void *)(query_string + querystr_len);
|
unaligned_type_class = (void *)(query_string + query_len);
|
||||||
querystr_len += sizeof(unaligned_qprop);
|
query_len += sizeof(unaligned_type_class);
|
||||||
/* where to append answer block */
|
/* where to append answer block */
|
||||||
answb = (void *)(unaligned_qprop + 1);
|
answb = (void *)(unaligned_type_class + 1);
|
||||||
|
|
||||||
/* QR = 1 "response", RCODE = 4 "Not Implemented" */
|
/* QR = 1 "response", RCODE = 4 "Not Implemented" */
|
||||||
outr_flags = htons(0x8000 | 4);
|
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)) {
|
if (type != htons(REQ_A) && type != htons(REQ_PTR)) {
|
||||||
/* we can't handle the query type */
|
/* we can't handle the query type */
|
||||||
goto empty_packet;
|
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? */
|
if (class != htons(1)) { /* not class INET? */
|
||||||
goto empty_packet;
|
goto empty_packet;
|
||||||
}
|
}
|
||||||
@ -408,11 +408,11 @@ static int process_packet(struct dns_entry *conf_data,
|
|||||||
answstr = table_lookup(conf_data, type, query_string);
|
answstr = table_lookup(conf_data, type, query_string);
|
||||||
outr_rlen = 4;
|
outr_rlen = 4;
|
||||||
if (answstr && type == htons(REQ_PTR)) {
|
if (answstr && type == htons(REQ_PTR)) {
|
||||||
/* return a host name */
|
/* returning a host name */
|
||||||
outr_rlen = strlen(answstr) + 1;
|
outr_rlen = strlen(answstr) + 1;
|
||||||
}
|
}
|
||||||
if (!answstr
|
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"
|
/* QR = 1 "response"
|
||||||
* AA = 1 "Authoritative Answer"
|
* AA = 1 "Authoritative Answer"
|
||||||
@ -421,20 +421,23 @@ static int process_packet(struct dns_entry *conf_data,
|
|||||||
goto empty_packet;
|
goto empty_packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy query block to answer block */
|
/* Append answer Resource Record */
|
||||||
memcpy(answb, query_string, querystr_len);
|
memcpy(answb, query_string, query_len); /* name, type, class */
|
||||||
answb += querystr_len;
|
answb += query_len;
|
||||||
/* append answer Resource Record */
|
|
||||||
move_to_unaligned32((uint32_t *)answb, htonl(conf_ttl));
|
move_to_unaligned32((uint32_t *)answb, htonl(conf_ttl));
|
||||||
answb += 4;
|
answb += 4;
|
||||||
move_to_unaligned32((uint16_t *)answb, htons(outr_rlen));
|
move_to_unaligned16((uint16_t *)answb, htons(outr_rlen));
|
||||||
answb += 2;
|
answb += 2;
|
||||||
memcpy(answb, answstr, outr_rlen);
|
memcpy(answb, answstr, outr_rlen);
|
||||||
answb += outr_rlen;
|
answb += outr_rlen;
|
||||||
|
|
||||||
/* QR = 1 "response",
|
/* QR = 1 "response",
|
||||||
* AA = 1 "Authoritative Answer",
|
* 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);
|
outr_flags = htons(0x8000 | 0x0400 | 0);
|
||||||
/* we have one answer */
|
/* we have one answer */
|
||||||
head->nansw = htons(1);
|
head->nansw = htons(1);
|
||||||
|
Loading…
Reference in New Issue
Block a user