Usermode/utests - Fix DNS utest, update libc utests to new format (no more EXP files)
authorJohn Hodge <[email protected]>
Tue, 17 Feb 2015 04:30:31 +0000 (12:30 +0800)
committerJohn Hodge <[email protected]>
Tue, 17 Feb 2015 04:30:31 +0000 (12:30 +0800)
13 files changed:
Usermode/Libraries/.gitignore
Usermode/Libraries/Makefile.tpl
Usermode/Libraries/_utest_include/utest_common.h [new file with mode: 0644]
Usermode/Libraries/libc.so_src/TEST_printf.c
Usermode/Libraries/libc.so_src/TEST_string.c
Usermode/Libraries/libc.so_src/TEST_strtoi.c
Usermode/Libraries/libnet.so_src/Makefile
Usermode/Libraries/libnet.so_src/TEST_dns.c [deleted file]
Usermode/Libraries/libnet.so_src/TEST_dns_proto.c [new file with mode: 0644]
Usermode/Libraries/libnet.so_src/dns.c
Usermode/Libraries/libnet.so_src/dns_proto.c [new file with mode: 0644]
Usermode/Libraries/libnet.so_src/include/dns.h
Usermode/Libraries/libnet.so_src/include/dns_int.h [new file with mode: 0644]

index de263f5..8706a0a 100644 (file)
@@ -63,9 +63,12 @@ _libs: $(HEADERS)
 
 utest: utest-build utest-run
 
-utest-build: $(UTESTS:%=TEST_%)
+utest-build: $(UTESTS:%=TEST_%)
 
-utest-run: $(UTESTS:%=runtest-%)
+utest-run: _ $(UTESTS:%=runtest-%)
+
+_:
+       @true
 
 $(UTESTS:%=runtest-%): runtest-%: TEST_%
        @echo --- [TEST] $*
@@ -132,7 +135,7 @@ $(OUTPUTDIR)Libs/%:
 obj-native/%.no: %.c
        @mkdir -p $(dir $@)
        @echo [CC Native] -o $@
-       @$(NCC) -g -c $< -o $@ -Wall -std=gnu99 -MD -MP -MF [email protected] '-D_SysDebug(f,v...)=fprintf(stderr,"DEBUG "f"\n",##v)' -include stdio.h
+       @$(NCC) -g -c $< -o $@ -Wall -std=gnu99 -MD -MP -MF [email protected] '-D_SysDebug(f,v...)=fprintf(stderr,"DEBUG "f"\n",##v)' -include stdio.h -I $(ACESSDIR)/Usermode/Libraries/_utest_include/
 
 TEST_%: obj-native/TEST_%.no obj-native/%.no
        @echo [CC Native] -o $@
diff --git a/Usermode/Libraries/_utest_include/utest_common.h b/Usermode/Libraries/_utest_include/utest_common.h
new file mode 100644 (file)
index 0000000..0b96586
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef _UTEST_COMMON_H_
+#define _UTEST_COMMON_H_
+
+#include <stdlib.h>
+
+// --- Test assertions
+#define TEST_REL_(_ty, _fmt, exp, rel, have) do { \
+       _ty a = (exp);\
+       _ty b = (have);\
+       if( !(a rel b) ) { \
+               fprintf(stderr, "TEST_REL_INT("#exp" {%"_fmt"} "#rel" "#have" {%"_fmt"}) FAILED\n", \
+                       a, b); \
+               return 1; \
+       } \
+} while(0)
+#define TEST_REL_INT(exp, rel, have)   TEST_REL_(int, "i", exp, rel, have)
+#define TEST_REL_PTR(exp, rel, have)   TEST_REL_(const void*, "p", exp, rel, have)
+
+// -- Header hooks (allowing inclusion of general headers)
+#define SYSCALL(rt, name)      rt name() { fprintf(stderr, "BUG: Calling syscall '"#name"' in unit test\n"); exit(2); }
+
+#endif
+
index 4376694..c1cdd79 100644 (file)
@@ -6,32 +6,40 @@
  * - Tests for printf.c
  */
 #include <stdio.h>
+#include <string.h>
+#include <utest_common.h>
 
-#define TST(_name, fmt, val) \
-       printf(_name" %"fmt" '"#val"': '"fmt"'\n", val)
+#define TST(_name, exp, fmt, val...) do { \
+       char buf[64]; \
+       snprintf(buf, sizeof(buf), fmt, ##val); \
+       if( strcmp(buf, exp) != 0 ) { \
+               fprintf(stderr, "FAIL: exp '%s' != got '%s'\n", exp, buf);\
+               exit(1); \
+       } \
+} while(0)
 
 int main(int argc, char *argv[])
 {
-       printf("Hello World!\n");
-       TST("String", "%s", "teststring");
-       TST("String", "%.5s", "teststring");
-       TST("String", "%10.5s", "teststring");
-       TST("String", "%-10.5s", "teststring");
+       TST("None", "Hello World!\n", "Hello World!\n");
+       TST("String", "teststring", "%s", "teststring");
+       TST("String", "tests",      "%.5s", "teststring");
+       TST("String", "     tests", "%10.5s", "teststring");
+       TST("String", "tests     ", "%-10.5s", "teststring");
        
-       TST("Integer", "%i", 1234);
-       TST("Integer", "%d", 1234);
-       TST("Integer", "%u", 1234);
+       TST("Integer", "1234", "%i", 1234);
+       TST("Integer", "1234", "%d", 1234);
+       TST("Integer", "1234", "%u", 1234);
        
-       TST("Float", "%f", 3.1414926535);
-       TST("Float", "%f", 10.0);
-       TST("Float", "%f", -0.0);
-       TST("Float", "%.10f", 3.1414926535);
-       TST("Float", "%e", 3.1415926535);
-       TST("Float", "%g", 3.1415926535);
-       TST("Float", "%E", 1000000000.00);
-       TST("Float", "%a", 16.0);
-       TST("Float", "%a", 1024.0);
-       TST("Float", "%a", 1023.0);
-       TST("Float", "%A", 1000000000.00);
+       TST("Float", "3.141593", "%f", 3.1415926535);
+       TST("Float", "10.000000",    "%f", 10.0);
+       TST("Float", "-0.000000", "%f", -0.0);
+       TST("Float", "3.1415926535", "%.10f", 3.1415926535);
+       TST("Float", "3.141593e+00", "%e", 3.1415926535);
+       TST("Float", "3.14159", "%g", 3.1415926535);
+       TST("Float", "1.000000E+09", "%E", 1000000000.00);
+       TST("Float", "0x1p+4", "%a", 16.0);
+       TST("Float", "0x1p+10", "%a", 1024.0);
+       TST("Float", "0x1.ff8p+9", "%a", 1023.0);
+       TST("Float", "0X1.DCD65P+29", "%A", 1000000000.00);
        return 0;
 }
index 4ecca30..eb940c7 100644 (file)
@@ -2,50 +2,55 @@
  */
 #include <stdio.h>
 #include <string.h>
-
-#define ASSERT(cnd)    printf("ASSERT: "#cnd" == %s\n", ((cnd) ? "pass" : "FAIL"))
+#include <utest_common.h>
 
 int main()
 {
-       ASSERT(strcmp("hello", "world") < 0);
-       ASSERT(strcmp("hello", "hello") == 0);
-       ASSERT(strcmp("wello", "hello") > 0);
-       ASSERT(strcmp("\xff", "\1") > 0);
-       ASSERT(strcmp("\1", "\xff") < 0);
-       ASSERT(strcmp("Hello", "hello") < 0);
+       TEST_REL_INT(0, > , strcmp("hello", "world"));
+       TEST_REL_INT(0, ==, strcmp("hello", "hello"));
+       TEST_REL_INT(0, < , strcmp("wello", "hello"));
+       TEST_REL_INT(0, < , strcmp("\xff", "\1"));
+       TEST_REL_INT(0, > , strcmp("\1", "\xff"));
+       TEST_REL_INT(0, > , strcmp("Hello", "hello"));
        
-       ASSERT(strncmp("hello world", "hello", 5) == 0);
+       TEST_REL_INT(0, ==, strncmp("hello world", "hello", 5));
        
-       ASSERT(strcasecmp("hello", "world") < 0);
-       ASSERT(strcasecmp("hello", "hello") == 0);
-       ASSERT(strcasecmp("wello", "hello") > 0);
-       ASSERT(strcasecmp("\xff", "\1") > 0);
-       ASSERT(strcasecmp("\1", "\xff") < 0);
-       ASSERT(strcasecmp("Hello", "hello") == 0);
-       ASSERT(strcasecmp("Hello", "Hello") == 0);
-       ASSERT(strcasecmp("hellO", "Hello") == 0);
+       TEST_REL_INT(0, > , strcasecmp("hello", "world"));
+       TEST_REL_INT(0, ==, strcasecmp("hello", "hello"));
+       TEST_REL_INT(0, < , strcasecmp("wello", "hello"));
+       TEST_REL_INT(0, < , strcasecmp("\xff", "\1"));
+       TEST_REL_INT(0, > , strcasecmp("\1", "\xff"));
+       TEST_REL_INT(0, ==, strcasecmp("Hello", "hello"));
+       TEST_REL_INT(0, ==, strcasecmp("Hello", "Hello"));
+       TEST_REL_INT(0, ==, strcasecmp("hellO", "Hello"));
        
        char buf[13];
        memset(buf, 127, sizeof(buf));
-       ASSERT(buf[0] == 127);  ASSERT(buf[4] == 127);
+       TEST_REL_INT(127, ==, buf[0]);
+       TEST_REL_INT(127, ==, buf[4]);
        strncpy(buf, "hello", 4);
-       ASSERT(buf[3] == 'l');  ASSERT(buf[4] == 127);
+       TEST_REL_INT('l', ==, buf[3]);
+       TEST_REL_INT(127, ==, buf[4]);
        strncpy(buf, "hello", 8);
-       ASSERT(buf[4] == 'o');  ASSERT(buf[5] == '\0'); ASSERT(buf[7] == '\0'); ASSERT(buf[8] == 127);
+       TEST_REL_INT('o', ==, buf[4]);
+       TEST_REL_INT('\0', ==, buf[5]);
+               TEST_REL_INT('\0', ==, buf[7]);
+               TEST_REL_INT(127, ==, buf[8]);
        
        memset(buf, 0, 13);
-       ASSERT(buf[0] == 0);    ASSERT(buf[12] == 0);
+       TEST_REL_INT(0, ==, buf[0]);
+       TEST_REL_INT(0, ==, buf[12]);
        
-       ASSERT(memchr("\xffhello", 'x', 6) == NULL);
+       TEST_REL_PTR(NULL, ==, memchr("\xffhello", 'x', 6));
        
        const char *teststr_foo = "foo";
-       ASSERT(strchr(teststr_foo, 'f') == teststr_foo+0);
-       ASSERT(strchr(teststr_foo, 'o') == teststr_foo+1);
-       ASSERT(strchr(teststr_foo, '\0') == teststr_foo+3);
-       ASSERT(strchr(teststr_foo, 'X') == NULL);
-       ASSERT(strrchr(teststr_foo, 'f') == teststr_foo+0);
-       ASSERT(strrchr(teststr_foo, 'o') == teststr_foo+2);
-       ASSERT(strrchr(teststr_foo, '\0') == teststr_foo+3);
-       ASSERT(strrchr(teststr_foo, 'X') == NULL);
+       TEST_REL_PTR(teststr_foo+0, ==, strchr(teststr_foo, 'f'));
+       TEST_REL_PTR(teststr_foo+1, ==, strchr(teststr_foo, 'o'));
+       TEST_REL_PTR(teststr_foo+3, ==, strchr(teststr_foo, '\0'));
+       TEST_REL_PTR(NULL, ==, strchr(teststr_foo, 'X'));
+       TEST_REL_PTR(teststr_foo+0, ==, strrchr(teststr_foo, 'f'));
+       TEST_REL_PTR(teststr_foo+2, ==, strrchr(teststr_foo, 'o'));
+       TEST_REL_PTR(teststr_foo+3, ==, strrchr(teststr_foo, '\0'));
+       TEST_REL_PTR(NULL, ==, strrchr(teststr_foo, 'X'));
 }
 
index e065808..cf2d269 100644 (file)
        char *end;\
        errno = 0;\
        t ret = strto##class(in, &end, base); \
-       if( ret != exp ) \
+       if( ret != exp ) \
                fprintf(stderr, "FAIL strto"#class"('%s') != "#exp" (act "fmt")\n", in, ret);\
-       if( end != in+ofs ) \
+               exit(1); \
+       } \
+       if( end != in+ofs ) { \
                fprintf(stderr, "FAIL strto"#class"('%s') returned wrong end: %p (+%zi) instead of %p (+%zi)\n",\
                        in,end,end-in,in+ofs,(size_t)ofs);\
-       if( exp_errno != errno ) \
+               exit(1); \
+       } \
+       if( exp_errno != errno ) { \
                fprintf(stderr, "FAIL strto"#class"('%s') returned wrong errno, exp '%s', got '%s'\n",\
                        in, strerror(exp_errno), strerror(errno));\
+               exit(1); \
+       } \
 }while(0)
 
 #define PRIMEBUF(fmt, val)     buf_len = snprintf(buf, sizeof(buf), fmt, val)
index 10d5b96..ef73370 100644 (file)
@@ -7,9 +7,9 @@ CFLAGS   += -Wall
 LDFLAGS  += -lc -soname libnet.so
 
 OBJ = main.o address.o socket.o
-OBJ += hostnames.o dns.o
+OBJ += hostnames.o dns.o dns_proto.o
 BIN = libnet.so
 
-UTESTS = dns
+UTESTS = dns_prot
 
 include ../Makefile.tpl
diff --git a/Usermode/Libraries/libnet.so_src/TEST_dns.c b/Usermode/Libraries/libnet.so_src/TEST_dns.c
deleted file mode 100644 (file)
index 26b36bf..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- */
-#include "include/dns.h"
-#include <string.h>
-#include <stdio.h>
-#include <stdint.h>
-
-extern int DNS_int_ParseResponse(const void* packet, size_t return_len, void *info, handle_record_t* handle_record_t);
-
-// Complex response from "Q ssh.ucc.asn.au A IN"
-const uint8_t test_packet_1[] = {
-       0xac, 0x00, 0x80, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x03, 0x73, 0x73, 0x68, 0x03, 0x75, 0x63, 0x63, 0x03, 0x61, 0x73, 0x6e, 0x02, 0x61, 0x75, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x18, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x01, 0x77, 0xc0, 0x18, 0xc0, 0x18, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x01, 0x78, 0xc0, 0x18, 0xc0, 0x18, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x01, 0x79, 0xc0, 0x18, 0xc0, 0x18, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x01, 0x61, 0xc0, 0x18, 0xc0, 0x18, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x01, 0x7a, 0xc0, 0x18, 0xc0, 0x18, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x01, 0x62, 0xc0, 0x18, 0xc0, 0x18, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x01, 0x75, 0xc0, 0x18, 0xc0, 0x18, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x01, 0x76, 0xc0, 0x18, 0xc0, 0x2c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x25, 0xd1, 0xc0, 0x05, 0xc0, 0x3c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x25, 0xd1, 0xc2, 0x05, 0xc0, 0x4c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x25, 0xd1, 0xc4, 0x05, 0xc0, 0x5c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x3a, 0x41, 0xfe, 0x49, 0xc0, 0x6c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x25, 0xd1, 0xc6, 0x05, 0xc0, 0x7c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x3a, 0x41, 0xfd, 0x49, 0xc0, 0x8c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0xd3, 0x1d, 0x85, 0x20, 0xc0, 0x9c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0xca, 0x0c, 0x1f, 0x8d, 
-       };
-
-#define TEST_REL_INT(exp, rel, have) do { \
-       int a = (exp);\
-       int b = (have);\
-       if( !(a rel b) ) { \
-               fprintf(stderr, "TEST_REL_INT("#exp" "#rel" "#exp") FAILED l=%i r=%i", \
-                       a, b); \
-               return 1; \
-       } \
-} while(0)
-       
-int test_response_parse_1_cb(void *info, const char *name, enum eTypes type, enum eClass class, unsigned int ttl, size_t rdlength, const void *rdata)
-{
-       int* stagep = info;
-       switch( *stagep )
-       {
-       case 0:
-               TEST_REL_INT(0, ==, strcmp(name, "au."));
-               break;
-       }
-       (*stagep) += 1;
-       return 0;
-}
-int test_response_parse_1(void)
-{
-       int stage = 0;
-       TEST_REL_INT(0, ==, DNS_int_ParseResponse(test_packet_1, sizeof(test_packet_1), &stage, test_response_parse_1_cb) );
-       return 0;
-}
-
-int main(void)
-{
-        int rv = 0;
-       // - Name Encode
-       // - Name Decode
-       // - Response parsing
-       rv |= test_response_parse_1();
-       return rv;
-}
diff --git a/Usermode/Libraries/libnet.so_src/TEST_dns_proto.c b/Usermode/Libraries/libnet.so_src/TEST_dns_proto.c
new file mode 100644 (file)
index 0000000..49ba023
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ */
+#include <utest_common.h>
+#include "include/dns_int.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdint.h>
+
+// Complex response from "Q ssh.ucc.asn.au A IN"
+const uint8_t test_packet_1[] = {
+       0xac, 0x00, 0x80, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x03, 0x73, 0x73, 0x68, 0x03, 0x75, 0x63, 0x63, 0x03, 0x61, 0x73, 0x6e, 0x02, 0x61, 0x75, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x18, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x01, 0x77, 0xc0, 0x18, 0xc0, 0x18, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x01, 0x78, 0xc0, 0x18, 0xc0, 0x18, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x01, 0x79, 0xc0, 0x18, 0xc0, 0x18, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x01, 0x61, 0xc0, 0x18, 0xc0, 0x18, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x01, 0x7a, 0xc0, 0x18, 0xc0, 0x18, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x01, 0x62, 0xc0, 0x18, 0xc0, 0x18, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x01, 0x75, 0xc0, 0x18, 0xc0, 0x18, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x01, 0x76, 0xc0, 0x18, 0xc0, 0x2c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x25, 0xd1, 0xc0, 0x05, 0xc0, 0x3c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x25, 0xd1, 0xc2, 0x05, 0xc0, 0x4c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x25, 0xd1, 0xc4, 0x05, 0xc0, 0x5c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x3a, 0x41, 0xfe, 0x49, 0xc0, 0x6c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x25, 0xd1, 0xc6, 0x05, 0xc0, 0x7c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0x3a, 0x41, 0xfd, 0x49, 0xc0, 0x8c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0xd3, 0x1d, 0x85, 0x20, 0xc0, 0x9c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xe6, 0xd6, 0x00, 0x04, 0xca, 0x0c, 0x1f, 0x8d, 
+       };
+const uint8_t test_packet_2[] ={
+       0xac,0x00,0x81,0x80,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x03,0x73,0x73,0x68,0x03,0x75,0x63,0x63,0x03,0x61,0x73,0x6e,0x02,0x61,0x75,0x00,0x00,0x01,0x00,0x01,0xc0,0x0c,0x00,0x01,0x00,0x01,0x00,0x00,0x0e,0x10,0x00,0x04,0x82,0x5f,0x0d,0x0b
+};
+
+int test_response_parse_1_cb(void *info, const char *name, enum eTypes type, enum eClass class, unsigned int ttl, size_t rdlength, const void *rdata)
+{
+       int* stagep = info;
+       int curstage = *stagep;
+       *stagep = -1;
+       switch( curstage )
+       {
+       case 0:
+               TEST_REL_INT(0, ==, strcmp(name, "w.au."));
+               break;
+       case 1:
+               TEST_REL_INT(0, ==, strcmp(name, "x.au."));
+               break;
+       }
+       *stagep = curstage + 1;
+       return 0;
+}
+int test_response_parse_1(void)
+{
+       int stage = 0;
+       TEST_REL_INT(0, ==, DNS_int_ParseResponse(test_packet_1, sizeof(test_packet_1), &stage, test_response_parse_1_cb) );
+       TEST_REL_INT(stage, ==, 8);
+       return 0;
+}
+
+int test_response_parse_2_cb(void *info, const char *name, enum eTypes type, enum eClass class, unsigned int ttl, size_t rdlength, const void *rdata)
+{
+       int* stagep = info;
+       int curstage = *stagep;
+       *stagep = -1;
+       switch( curstage )
+       {
+       case 0:
+               TEST_REL_INT(0, ==, strcmp(name, "ssh.ucc.asn.au."));
+               TEST_REL_INT(TYPE_A, ==, type);
+               TEST_REL_INT(CLASS_IN, ==, class);
+               TEST_REL_INT(4, ==, rdlength);
+               TEST_REL_INT(130, ==, ((uint8_t*)rdata)[0]);
+               TEST_REL_INT( 95, ==, ((uint8_t*)rdata)[1]);
+               TEST_REL_INT( 13, ==, ((uint8_t*)rdata)[2]);
+               TEST_REL_INT( 11, ==, ((uint8_t*)rdata)[3]);
+               break;
+       }
+       *stagep = curstage + 1;
+       return 0;
+}
+int test_response_parse_2(void)
+{
+       int stage = 0;
+       TEST_REL_INT(0, ==, DNS_int_ParseResponse(test_packet_2, sizeof(test_packet_2), &stage, test_response_parse_2_cb) );
+       TEST_REL_INT(stage, ==, 1); 
+       return 0;
+}
+
+int main(void)
+{
+        int rv = 0;
+       // - Name Encode
+       // - Name Decode
+       // - Response parsing
+       rv |= test_response_parse_1();
+       rv |= test_response_parse_2();
+       return rv;
+}
index 3bb9c35..9ac9198 100644 (file)
 #include <acess/fd_set.h>      // FD_SET
 #include <net.h>
 #include "include/dns.h"
+#include "include/dns_int.h"
 
 // === PROTOTYPES ===
 //int DNS_Query(int ServerAType, const void *ServerAddr, const char *name, enum eTypes type, enum eClass class, handle_record_t* handle_record, void *info);
-int DNS_int_ParseResponse(const void* packet, size_t return_len, void *info, handle_record_t* handle_record_t);
-size_t DNS_EncodeName(void *buf, const char *dotted_name);
-int DNS_DecodeName(char dotted_name[256], const void *buf, size_t ofs, size_t space);
-int DNS_int_ParseRR(const void *buf, size_t ofs, size_t space, char* name_p, enum eTypes* type_p, enum eClass* class_p, uint32_t* ttl_p, size_t* rdlength_p);
-
-static uint16_t        get16(const void *buf);
-static uint32_t        get32(const void *buf);
-static size_t put16(void *buf, uint16_t val);
-
 
 // === CODE ===
 int DNS_Query(int ServerAType, const void *ServerAddr, const char *name, enum eTypes type, enum eClass class, handle_record_t* handle_record, void *info)
 {
-       int namelen = DNS_EncodeName(NULL, name);
-       assert(namelen < 256);
-       size_t  pos = 0;
-       char    packet[ 512 ];
-       assert( (6*2) + (namelen + 2*2) < 512 );
-       // - Header
-       pos += put16(packet + pos, 0xAC00);     // Identifier (arbitary)
-       pos += put16(packet + pos, (0 << 0) | (0 << 1) | (1 << 8) );    // Op : Query, Standard, Recursion
-       pos += put16(packet + pos, 1);  // QDCount
-       pos += put16(packet + pos, 0);  // ANCount
-       pos += put16(packet + pos, 0);  // NSCount
-       pos += put16(packet + pos, 0);  // ARCount
-       // - Question
-       pos += DNS_EncodeName(packet + pos, name);
-       pos += put16(packet + pos, type);       // QType
-       pos += put16(packet + pos, class);      // QClass
-       
-       assert(pos <= sizeof(packet));
+       char    packet[512];
+       size_t packlen = DNS_int_EncodeQuery(packet, sizeof(packet), name, type, class);
        
        // Send and wait for reply
        // - Lock
@@ -102,237 +78,3 @@ int DNS_Query(int ServerAType, const void *ServerAddr, const char *name, enum eT
        return DNS_int_ParseResponse(packet, return_len, info, handle_record);
 }
 
-int DNS_int_ParseResponse(const void* buf, size_t return_len, void *info, handle_record_t* handle_record)
-{
-       const uint8_t* packet = buf;
-       char    rr_name[256];
-       unsigned int id = get16(packet + 0);
-       if( id != 0xAC00 ) {
-               _SysDebug("DNS_Query - Packet ID mismatch");
-               return 2;
-       }
-       unsigned int flags = get16(packet + 2);
-       unsigned int qd_count = get16(packet + 4);
-       unsigned int an_count = get16(packet + 6);
-       unsigned int ns_count = get16(packet + 8);
-       unsigned int ar_count = get16(packet + 10);
-       size_t pos = 6*2;
-       // TODO: Can I safely assert / fail if qd_count is non-zero?
-       // - Questions, ignored
-       for( unsigned int i = 0; i < qd_count; i ++ ) {
-               int rv = DNS_DecodeName(rr_name, packet, pos, return_len);
-               if( rv < 0 ) {
-                       _SysDebug("DNS_Query - Parse error in QD");
-                       return 1;
-               }
-               pos += rv + 2*2;
-       }
-       // - Answers, pass on to handler
-       for( unsigned int i = 0; i < an_count; i ++ )
-       {
-               enum eTypes     type;
-               enum eClass     class;
-               uint32_t        ttl;
-               size_t  rdlength;
-               int rv = DNS_int_ParseRR(packet, pos, return_len, rr_name, &type, &class, &ttl, &rdlength);
-               if( rv < 0 ) {
-                       _SysDebug("DNS_Query - Parse error in AN");
-                       return 1;
-               }
-               pos += rv;
-               
-               handle_record(info, rr_name, type, class, ttl, rdlength, packet + pos - rdlength);
-       }
-       // Authority Records (should all be NS records)
-       for( unsigned int i = 0; i < ns_count; i ++ )
-       {
-               size_t  rdlength;
-               int rv = DNS_int_ParseRR(packet, pos, return_len, rr_name, NULL, NULL, NULL, &rdlength);
-               if( rv < 0 ) {
-                       _SysDebug("DNS_Query - Parse error in NS");
-                       return 1;
-               }
-               pos += rv;
-       }
-       // - Additional records, pass to handler
-       for( unsigned int i = 0; i < ar_count; i ++ )
-       {
-               enum eTypes     type;
-               enum eClass     class;
-               uint32_t        ttl;
-               size_t  rdlength;
-               int rv = DNS_int_ParseRR(packet, pos, return_len, rr_name, &type, &class, &ttl, &rdlength);
-               if( rv < 0 ) {
-                       _SysDebug("DNS_Query - Parse error in AR");
-                       return 1;
-               }
-               pos += rv;
-               
-               handle_record(info, rr_name, type, class, ttl, rdlength, packet + pos - rdlength);
-       }
-       
-       return 0;
-}
-
-/// Encode a dotted name as a DNS name
-size_t DNS_EncodeName(void *buf, const char *dotted_name)
-{
-       size_t  ret = 0;
-       const char *str = dotted_name;
-       uint8_t *buf8 = buf;
-       while( *str )
-       {
-               const char *next = strchr(str, '.');
-               size_t seg_len = (next ? next - str : strlen(str));
-               if( seg_len > 63 ) {
-                       // Oops, too long (truncate)
-                       seg_len = 63;
-               }
-               if( seg_len == 0 && next != NULL ) {
-                       // '..' encountered, invalid (skip)
-                       str = next+1;
-                       continue ;
-               }
-               
-               if( buf8 )
-               {
-                       buf8[ret] = seg_len;
-                       memcpy(buf8+ret+1, str, seg_len);
-               }
-               ret += 1 + seg_len;
-               
-               if( next == NULL ) {
-                       // No trailing '.', assume it's there? Yes, need to be NUL terminated
-                       if(buf8)        buf8[ret] = 0;
-                       ret ++;
-                       break;
-               }
-               else {
-                       str = next + 1;
-               }
-       }
-       return ret;
-}
-
-// Decode a name (including trailing . for root)
-int DNS_DecodeName(char dotted_name[256], const void *buf, size_t ofs, size_t space)
-{
-       int consumed = 0;
-       int out_pos = 0;
-       const uint8_t *buf8 = (const uint8_t*)buf + ofs;
-       for( ;; )
-       {
-               if( ofs + consumed + 1 > space ) {
-                       _SysDebug("DNS_DecodeName - Len byte OOR space=%i", space);
-                       return -1;
-               }
-               uint8_t seg_len = *buf8;
-               buf8 ++;
-               consumed ++;
-               // Done
-               if( seg_len == 0 )
-                       break;
-               if( (seg_len & 0xC0) == 0xC0 )
-               {
-                       // Backreference, the rest of the name is a backref
-                       char tmp[256];
-                       int ref_ofs = get16(buf8 - 1) & 0x3FFF;
-                       consumed += 1, buf8 += 1;       // Only one, previous inc still applies
-                       _SysDebug("DNS_DecodeName - Nested at %i", ref_ofs);
-                       if( DNS_DecodeName(tmp, buf, ref_ofs, space) < 0 )
-                               return -1;
-                       memcpy(dotted_name+out_pos, tmp, strlen(tmp));
-                       out_pos += strlen(tmp);
-                       break;
-               }
-               // Protocol violation (segment too long)
-               if( seg_len >= 64 ) {
-                       _SysDebug("DNS_DecodeName - Seg too long %i", seg_len);
-                       return -1;
-               }
-               // Protocol violation (overflowed end of buffer)
-               if( ofs + consumed + seg_len > space ) {
-                       _SysDebug("DNS_DecodeName - Seg OOR %i+%i>%i", consumed, seg_len, space);
-                       return -1;
-               }
-               // Protocol violation (name was too long)
-               if( out_pos + seg_len + 1 > 255 ) {
-                       _SysDebug("DNS_DecodeName - Dotted name too long %i+%i+1 > %i",
-                               out_pos, seg_len, 255);
-                       return -1;
-               }
-               
-               _SysDebug("DNS_DecodeName : Seg %i '%.*s'", seg_len, seg_len, buf8);
-               
-               // Read segment
-               memcpy(dotted_name + out_pos, buf8, seg_len);
-               buf8 += seg_len;
-               consumed += seg_len;
-               out_pos += seg_len;
-               
-               // Place '.'
-               dotted_name[out_pos] = '.';
-               out_pos ++;
-       }
-       dotted_name[out_pos] = '\0';
-       _SysDebug("DNS_DecodeName - '%s', consumed = %i", dotted_name, consumed);
-       return consumed;
-}
-
-// Parse a Resource Record
-int DNS_int_ParseRR(const void *buf, size_t ofs, size_t space, char* name_p, enum eTypes* type_p, enum eClass* class_p, uint32_t* ttl_p, size_t* rdlength_p)
-{
-       const uint8_t   *buf8 = buf;
-       size_t  consumed = 0;
-       
-       // 1. Name
-       int rv = DNS_DecodeName(name_p, buf, ofs, space);
-       if(rv < 0)      return -1;
-       
-       ofs += rv, consumed += rv;
-       
-       if( type_p )
-               *type_p = get16(buf8 + ofs);
-       ofs += 2, consumed += 2;
-       
-       if( class_p )
-               *class_p = get16(buf8 + ofs);
-       ofs += 2, consumed += 2;
-       
-       if( ttl_p )
-               *ttl_p = get32(buf + ofs);
-       ofs += 4, consumed += 4;
-       
-       size_t rdlength = get16(buf + ofs);
-       if( rdlength_p )
-               *rdlength_p = rdlength;
-       ofs += 2, consumed += 2;
-       
-       _SysDebug("DNS_int_ParseRR - name='%s', rdlength=%i", name_p, rdlength);
-       
-       return consumed + rdlength;
-}
-
-static uint16_t get16(const void *buf) {
-       const uint8_t* buf8 = buf;
-       uint16_t rv = 0;
-       rv |= (uint16_t)buf8[0] << 8;
-       rv |= (uint16_t)buf8[1] << 0;
-       return rv;
-}
-static uint32_t get32(const void *buf) {
-       const uint8_t* buf8 = buf;
-       uint32_t rv = 0;
-       rv |= (uint32_t)buf8[0] << 24;
-       rv |= (uint32_t)buf8[1] << 16;
-       rv |= (uint32_t)buf8[2] << 8;
-       rv |= (uint32_t)buf8[3] << 0;
-       return rv;
-}
-static size_t put16(void *buf, uint16_t val) {
-       uint8_t* buf8 = buf;
-       buf8[0] = val >> 8;
-       buf8[1] = val & 0xFF;
-       return 2;
-}
-
diff --git a/Usermode/Libraries/libnet.so_src/dns_proto.c b/Usermode/Libraries/libnet.so_src/dns_proto.c
new file mode 100644 (file)
index 0000000..ce3cfb3
--- /dev/null
@@ -0,0 +1,281 @@
+/*
+ */
+
+#include "include/dns.h"
+#include "include/dns_int.h"
+#include <stdint.h>
+#include <string.h>
+#include <assert.h>
+
+// === PROTOTYPES ===
+extern int DNS_int_ParseRR(const void *buf, size_t ofs, size_t space, char* name_p, enum eTypes* type_p, enum eClass* class_p, uint32_t* ttl_p, size_t* rdlength_p);
+
+static uint16_t        get16(const void *buf);
+static uint32_t        get32(const void *buf);
+static size_t put16(void *buf, uint16_t val);
+
+// === CODE ===
+size_t DNS_int_EncodeQuery(void *buf, size_t bufsize, const char *name, enum eTypes type, enum eClass class)
+{
+       int namelen = DNS_EncodeName(NULL, name);
+       if( namelen >= 256 ) {
+               _SysDebug("DNS_int_EncodeQuery - ERROR: Name encoded to >= 256 bytes");
+               return 0;
+       }
+       size_t  pos = 0;
+       uint8_t *packet = buf;
+       if( (6*2) + (namelen + 2*2) > bufsize ) {
+               _SysDebug("DNS_int_EncodeQuery - ERROR: Passed buffer too small");
+               return 0;
+       }
+       // - Header
+       pos += put16(packet + pos, 0xAC00);     // Identifier (arbitary)
+       pos += put16(packet + pos, (0 << 0) | (0 << 1) | (1 << 8) );    // Op : Query, Standard, Recursion
+       pos += put16(packet + pos, 1);  // QDCount
+       pos += put16(packet + pos, 0);  // ANCount
+       pos += put16(packet + pos, 0);  // NSCount
+       pos += put16(packet + pos, 0);  // ARCount
+       // - Question
+       pos += DNS_EncodeName(packet + pos, name);
+       pos += put16(packet + pos, type);       // QType
+       pos += put16(packet + pos, class);      // QClass
+       
+       assert(pos <= bufsize);
+       return pos;
+}
+
+int DNS_int_ParseResponse(const void* buf, size_t return_len, void *info, handle_record_t* handle_record)
+{
+       const uint8_t* packet = buf;
+       char    rr_name[256];
+       unsigned int id = get16(packet + 0);
+       if( id != 0xAC00 ) {
+               _SysDebug("DNS_Query - Packet ID mismatch");
+               return 2;
+       }
+       unsigned int flags = get16(packet + 2);
+       unsigned int qd_count = get16(packet + 4);
+       unsigned int an_count = get16(packet + 6);
+       unsigned int ns_count = get16(packet + 8);
+       unsigned int ar_count = get16(packet + 10);
+       size_t pos = 6*2;
+       // TODO: Can I safely assert / fail if qd_count is non-zero?
+       // - Questions, ignored
+       for( unsigned int i = 0; i < qd_count; i ++ ) {
+               int rv = DNS_DecodeName(rr_name, packet, pos, return_len);
+               if( rv < 0 ) {
+                       _SysDebug("DNS_Query - Parse error in QD");
+                       return 1;
+               }
+               pos += rv + 2*2;
+       }
+       // - Answers, pass on to handler
+       for( unsigned int i = 0; i < an_count; i ++ )
+       {
+               enum eTypes     type;
+               enum eClass     class;
+               uint32_t        ttl;
+               size_t  rdlength;
+               int rv = DNS_int_ParseRR(packet, pos, return_len, rr_name, &type, &class, &ttl, &rdlength);
+               if( rv < 0 ) {
+                       _SysDebug("DNS_Query - Parse error in AN");
+                       return 1;
+               }
+               pos += rv;
+               
+               if( handle_record(info, rr_name, type, class, ttl, rdlength, packet + pos - rdlength) )
+                       return 0;
+       }
+       // Authority Records (should all be NS records)
+       for( unsigned int i = 0; i < ns_count; i ++ )
+       {
+               size_t  rdlength;
+               int rv = DNS_int_ParseRR(packet, pos, return_len, rr_name, NULL, NULL, NULL, &rdlength);
+               if( rv < 0 ) {
+                       _SysDebug("DNS_Query - Parse error in NS");
+                       return 1;
+               }
+               pos += rv;
+       }
+       // - Additional records, pass to handler
+       for( unsigned int i = 0; i < ar_count; i ++ )
+       {
+               enum eTypes     type;
+               enum eClass     class;
+               uint32_t        ttl;
+               size_t  rdlength;
+               int rv = DNS_int_ParseRR(packet, pos, return_len, rr_name, &type, &class, &ttl, &rdlength);
+               if( rv < 0 ) {
+                       _SysDebug("DNS_Query - Parse error in AR");
+                       return 1;
+               }
+               pos += rv;
+               
+               if( handle_record(info, rr_name, type, class, ttl, rdlength, packet + pos - rdlength) )
+                       return 0;
+       }
+       
+       return 0;
+}
+
+/// Encode a dotted name as a DNS name
+size_t DNS_EncodeName(void *buf, const char *dotted_name)
+{
+       size_t  ret = 0;
+       const char *str = dotted_name;
+       uint8_t *buf8 = buf;
+       while( *str )
+       {
+               const char *next = strchr(str, '.');
+               size_t seg_len = (next ? next - str : strlen(str));
+               if( seg_len > 63 ) {
+                       // Oops, too long (truncate)
+                       seg_len = 63;
+               }
+               if( seg_len == 0 && next != NULL ) {
+                       // '..' encountered, invalid (skip)
+                       str = next+1;
+                       continue ;
+               }
+               
+               if( buf8 )
+               {
+                       buf8[ret] = seg_len;
+                       memcpy(buf8+ret+1, str, seg_len);
+               }
+               ret += 1 + seg_len;
+               
+               if( next == NULL ) {
+                       // No trailing '.', assume it's there? Yes, need to be NUL terminated
+                       if(buf8)        buf8[ret] = 0;
+                       ret ++;
+                       break;
+               }
+               else {
+                       str = next + 1;
+               }
+       }
+       return ret;
+}
+
+// Decode a name (including trailing . for root)
+int DNS_DecodeName(char dotted_name[256], const void *buf, size_t ofs, size_t space)
+{
+       int consumed = 0;
+       int out_pos = 0;
+       const uint8_t *buf8 = (const uint8_t*)buf + ofs;
+       for( ;; )
+       {
+               if( ofs + consumed + 1 > space ) {
+                       _SysDebug("DNS_DecodeName - Len byte OOR space=%zi", space);
+                       return -1;
+               }
+               uint8_t seg_len = *buf8;
+               buf8 ++;
+               consumed ++;
+               // Done
+               if( seg_len == 0 )
+                       break;
+               if( (seg_len & 0xC0) == 0xC0 )
+               {
+                       // Backreference, the rest of the name is a backref
+                       char tmp[256];
+                       int ref_ofs = get16(buf8 - 1) & 0x3FFF;
+                       consumed += 1, buf8 += 1;       // Only one, previous inc still applies
+                       //_SysDebug("DNS_DecodeName - Nested at %i", ref_ofs);
+                       if( DNS_DecodeName(tmp, buf, ref_ofs, space) < 0 )
+                               return -1;
+                       memcpy(dotted_name+out_pos, tmp, strlen(tmp));
+                       out_pos += strlen(tmp);
+                       break;
+               }
+               // Protocol violation (segment too long)
+               if( seg_len >= 64 ) {
+                       _SysDebug("DNS_DecodeName - Seg too long %i", seg_len);
+                       return -1;
+               }
+               // Protocol violation (overflowed end of buffer)
+               if( ofs + consumed + seg_len > space ) {
+                       _SysDebug("DNS_DecodeName - Seg OOR %i+%i>%zi", consumed, seg_len, space);
+                       return -1;
+               }
+               // Protocol violation (name was too long)
+               if( out_pos + seg_len + 1 > 255 ) {
+                       _SysDebug("DNS_DecodeName - Dotted name too long %i+%i+1 > %i",
+                               out_pos, seg_len, 255);
+                       return -1;
+               }
+               
+               //_SysDebug("DNS_DecodeName : Seg %i '%.*s'", seg_len, seg_len, buf8);
+               
+               // Read segment
+               memcpy(dotted_name + out_pos, buf8, seg_len);
+               buf8 += seg_len;
+               consumed += seg_len;
+               out_pos += seg_len;
+               
+               // Place '.'
+               dotted_name[out_pos] = '.';
+               out_pos ++;
+       }
+       dotted_name[out_pos] = '\0';
+       //_SysDebug("DNS_DecodeName - '%s', consumed = %i", dotted_name, consumed);
+       return consumed;
+}
+
+// Parse a Resource Record
+int DNS_int_ParseRR(const void *buf, size_t ofs, size_t space, char* name_p, enum eTypes* type_p, enum eClass* class_p, uint32_t* ttl_p, size_t* rdlength_p)
+{
+       const uint8_t   *buf8 = buf;
+       size_t  consumed = 0;
+       
+       // 1. Name
+       int rv = DNS_DecodeName(name_p, buf, ofs, space);
+       if(rv < 0)      return -1;
+       
+       ofs += rv, consumed += rv;
+       
+       if( type_p )
+               *type_p = get16(buf8 + ofs);
+       ofs += 2, consumed += 2;
+       
+       if( class_p )
+               *class_p = get16(buf8 + ofs);
+       ofs += 2, consumed += 2;
+       
+       if( ttl_p )
+               *ttl_p = get32(buf + ofs);
+       ofs += 4, consumed += 4;
+       
+       size_t rdlength = get16(buf + ofs);
+       if( rdlength_p )
+               *rdlength_p = rdlength;
+       ofs += 2, consumed += 2;
+       
+       _SysDebug("DNS_int_ParseRR - name='%s', rdlength=%zi", name_p, rdlength);
+       
+       return consumed + rdlength;
+}
+
+static uint16_t get16(const void *buf) {
+       const uint8_t* buf8 = buf;
+       uint16_t rv = 0;
+       rv |= (uint16_t)buf8[0] << 8;
+       rv |= (uint16_t)buf8[1] << 0;
+       return rv;
+}
+static uint32_t get32(const void *buf) {
+       const uint8_t* buf8 = buf;
+       uint32_t rv = 0;
+       rv |= (uint32_t)buf8[0] << 24;
+       rv |= (uint32_t)buf8[1] << 16;
+       rv |= (uint32_t)buf8[2] << 8;
+       rv |= (uint32_t)buf8[3] << 0;
+       return rv;
+}
+static size_t put16(void *buf, uint16_t val) {
+       uint8_t* buf8 = buf;
+       buf8[0] = val >> 8;
+       buf8[1] = val & 0xFF;
+       return 2;
+}
index dc7a58b..61daeac 100644 (file)
@@ -39,8 +39,9 @@ enum eClass
  * \param class        Record class (may not be equal to requested)
  * \param rdlength     Length of data pointed to by 'rdata'
  * \param rdata        Record data
+ * \return Non-zero terminates parsing
  */
-typedef void   handle_record_t(void *info, const char *name, enum eTypes type, enum eClass class, unsigned int ttl, size_t rdlength, const void *rdata);
+typedef int    handle_record_t(void *info, const char *name, enum eTypes type, enum eClass class, unsigned int ttl, size_t rdlength, const void *rdata);
 
 int DNS_Query(int ServerAType, const void *ServerAddr, const char *name, enum eTypes type, enum eClass class, handle_record_t* handle_record, void *info);
 
diff --git a/Usermode/Libraries/libnet.so_src/include/dns_int.h b/Usermode/Libraries/libnet.so_src/include/dns_int.h
new file mode 100644 (file)
index 0000000..0e20ea1
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ */
+#ifndef _DNS_INT_H_
+#define _DNS_INT_H_
+
+#include "dns.h"
+
+extern size_t  DNS_int_EncodeQuery(void *buf, size_t bufsize, const char *name, enum eTypes type, enum eClass class);
+extern int     DNS_int_ParseResponse(const void* packet, size_t return_len, void *info, handle_record_t* handle_record_t);
+
+extern size_t  DNS_EncodeName(void *buf, const char *dotted_name);
+extern int DNS_DecodeName(char dotted_name[256], const void *buf, size_t ofs, size_t space);
+#endif
+

UCC git Repository :: git.ucc.asn.au