Skip to content

Commit

Permalink
For #5 - add tinytest by Joe Walnes & add some tests for dns_compare_…
Browse files Browse the repository at this point in the history
…name (taken from lwip). Add dns_compare_name function initial pull in with some added parameters that I'll be using to support name compression while working on #6.
  • Loading branch information
eastein committed Aug 9, 2015
1 parent d04cdc2 commit 4ae2083
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 37 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "tinytest"]
path = tinytest
url = https://github.com/joewalnes/tinytest.git
39 changes: 39 additions & 0 deletions tests/testsuite.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include <stdint.h>

#include "../tinytest/tinytest.h"
#include "../user/dns_util.h"

void test_dnsname()
{
unsigned char dns_response[] = {
0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, // 12 bytes of random stuff for fun..
1, 'a', 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 3, 'c', 'o', 'm', 0,
1, 'a', 0xc0 + 14, 3, 'c', 'o', 'm', 0,
};


// no dns compression, name compare simply and it works
ASSERT_EQUALS(0, dns_compare_name("a.example.com", dns_response, sizeof(dns_response), 12));
// no dns compression, name compare simply and it works. Trailing dot ok.
ASSERT_EQUALS(0, dns_compare_name("a.example.com.", dns_response, sizeof(dns_response), 12));
// pointer to the wrong part of the name, shouldn't compare successfully, we pointed at example.com
ASSERT_EQUALS(1, dns_compare_name("a.example.com", dns_response, sizeof(dns_response), 14));
// pointer to the start of the message, but is only the start of the hostname, so this should fail
ASSERT_EQUALS(1, dns_compare_name("a.example", dns_response, sizeof(dns_response), 12));
// pointer to the part of the message that used DNS compression properly. False positive in stock LWIP...
ASSERT_EQUALS(0, dns_compare_name("a.example.com", dns_response, sizeof(dns_response), 27));


// below here is where things failed before my substantive changes. This code code from lwip had
// anything that has dns compression matching everything as soon as the compression kicks in..
// pointer to the compressed a.example.com in the message, but we aren't comparing that
//FIXME re-enable test once working...
//ASSERT_EQUALS(1, dns_compare_name("a.google.com", dns_response, sizeof(dns_response), 27));
}

/* test runner */
int main()
{
RUN(test_dnsname);
return TEST_REPORT();
}
1 change: 1 addition & 0 deletions tinytest
Submodule tinytest added at 04eff7
38 changes: 1 addition & 37 deletions user/dns.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,43 +118,7 @@ PACK_STRUCT_END
#define DNS_RRCLASS_HS 4 /* Hesiod [Dyer 87] */
#define DNS_RRCLASS_FLUSH 0x800 /* Flush bit */

// mostly taken from lwip core/dns.c, with modifications
size_t hostname_to_queryformat(char* name, char* query) {
/*
@param name char pointer to the start of a c string of the name to convert into query format and copy into the query buffer
@param query pointer to location where the query formatted version of the name should be written to
@returns number of bytes used in the query buffer by encoding the name
*/
uint8_t n;
char* nptr;
size_t bytes_used = 0;
name--;

/* convert hostname into suitable query format. */
do {
++name;
nptr = query;
++query;
bytes_used++; // nptr points to where the length will be stored. we have 'used' that.
for(n = 0; *name != '.' && *name != 0; ++name) {
*query = *name;
bytes_used++; // we used a byte to store a byte of the name
++query;
++n;
}
// we write back to the start (it's length prefix encoded, unsigned 8 bit int)
*nptr = n;
} while(*name != 0);
// write a 0 over the end, and then increment the query pointer
// this means we're using another byte, I guess... but isn't the *nptr = n line already doing this?

bytes_used++;
*query++='\0';

DEBUGUART("name written to dns query using %d bytes.\r\n", bytes_used);

return bytes_used;
}
#include "dns_util.h"

inline void write_uint16(char* buf, uint16_t v) {
// alignment for 16 bit is 2 bytes, so we can't treat it that way unless we're lucky to be on
Expand Down
85 changes: 85 additions & 0 deletions user/dns_util.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#ifndef BK_DNS_UTIL_H
#define BK_DNS_UTIL_H 1

// mostly taken from lwip core/dns.c, with modifications
size_t hostname_to_queryformat(char* name, char* query) {
/*
@param name char pointer to the start of a c string of the name to convert into query format and copy into the query buffer
@param query pointer to location where the query formatted version of the name should be written to
@returns number of bytes used in the query buffer by encoding the name
*/
uint8_t n;
char* nptr;
size_t bytes_used = 0;
name--;

/* convert hostname into suitable query format. */
do {
++name;
nptr = query;
++query;
bytes_used++; // nptr points to where the length will be stored. we have 'used' that.
for(n = 0; *name != '.' && *name != 0; ++name) {
*query = *name;
bytes_used++; // we used a byte to store a byte of the name
++query;
++n;
}
// we write back to the start (it's length prefix encoded, unsigned 8 bit int)
*nptr = n;
} while(*name != 0);
// write a 0 over the end, and then increment the query pointer
// this means we're using another byte, I guess... but isn't the *nptr = n line already doing this?

bytes_used++;
*query++='\0';

//DEBUGUART("name written to dns query using %d bytes.\r\n", bytes_used);

return bytes_used;
}

// from lwip
/**
* Compare the "dotted" name "query" with the encoded name "response"
*
* @param query hostname (not encoded) from the dns_table
* @param response_ptr pointer to the start of the DNS response
* @param response_size number of bytes in the dns response packet, used to ensure we don't read outside
the response message
* @param offset offset of the encoded hostname in the DNS response. Assumed to be less than response_size
* @return 0: names equal; 1: names differ
*/
static uint8_t
dns_compare_name(unsigned char *query, unsigned char *response_ptr, uint16_t response_size, uint16_t offset)
{
unsigned char n;
unsigned char* response = response_ptr;
unsigned char* end = response_ptr + response_size;
response += offset;

do {
n = *response++;
/** @see RFC 1035 - 4.1.4. Message compression */
if ((n & 0xc0) == 0xc0) {
/* Compressed name */
break;
} else {
/* Not compressed name */
while (n > 0) {
if ((*query) != (*response)) {
return 1;
}
++response;
++query;
--n;
};
++query;
}
} while (*response != 0);

return 0;
}


#endif

0 comments on commit 4ae2083

Please sign in to comment.