summaryrefslogtreecommitdiff
path: root/jni/iodine/tests
diff options
context:
space:
mode:
Diffstat (limited to 'jni/iodine/tests')
-rw-r--r--jni/iodine/tests/Makefile27
-rw-r--r--jni/iodine/tests/base32.c142
-rw-r--r--jni/iodine/tests/base64.c155
-rw-r--r--jni/iodine/tests/dns.c252
-rw-r--r--jni/iodine/tests/encoding.c108
-rw-r--r--jni/iodine/tests/fw_query.c88
-rw-r--r--jni/iodine/tests/login.c70
-rw-r--r--jni/iodine/tests/read.c297
-rw-r--r--jni/iodine/tests/test.c66
-rw-r--r--jni/iodine/tests/test.h37
-rw-r--r--jni/iodine/tests/user.c199
11 files changed, 1441 insertions, 0 deletions
diff --git a/jni/iodine/tests/Makefile b/jni/iodine/tests/Makefile
new file mode 100644
index 0000000..3a7ac01
--- /dev/null
+++ b/jni/iodine/tests/Makefile
@@ -0,0 +1,27 @@
+CC = gcc
+TEST = test
+OBJS = test.o base32.o base64.o read.o dns.o encoding.o login.o user.o fw_query.o
+SRCOBJS = ../src/base32.o ../src/base64.o ../src/read.o ../src/dns.o ../src/encoding.o ../src/login.o ../src/md5.o ../src/user.o ../src/fw_query.o
+
+OS = `uname | tr "a-z" "A-Z"`
+
+CHECK_PATH = /usr/local
+LDFLAGS = -L$(CHECK_PATH)/lib -lcheck `../src/osflags link`
+CFLAGS = -g -Wall -D$(OS) -I../src -I$(CHECK_PATH)/include -pedantic `../src/osflags cflags`
+
+all: $(TEST)
+ @LD_LIBRARY_PATH=${CHECK_PATH}/lib ./$(TEST)
+
+$(TEST): $(OBJS) $(SRCOBJS)
+ @echo LD $(TEST)
+ @$(CC) -o $@ $(SRCOBJS) $(OBJS) $(LDFLAGS)
+
+.c.o:
+ @echo CC $<
+ @$(CC) $(CFLAGS) -c $<
+
+
+clean:
+ @echo "Cleaning tests/"
+ @rm -f *~ *.core $(TEST) $(OBJS)
+
diff --git a/jni/iodine/tests/base32.c b/jni/iodine/tests/base32.c
new file mode 100644
index 0000000..9ff0cf7
--- /dev/null
+++ b/jni/iodine/tests/base32.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2006-2009 Bjorn Andersson <flex@kryo.se>, Erik Ekman <yarrick@kryo.se>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <check.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "encoding.h"
+#include "base32.h"
+#include "test.h"
+
+#define TUPLES 5
+
+static struct tuple
+{
+ char *a;
+ char *b;
+} testpairs[TUPLES] = {
+ { "iodinetestingtesting", "nfxwi0lomv0gk21unfxgo3dfon0gs1th" },
+ { "abc123", "mfrggmjsgm" },
+ { "test", "orsxg3a" },
+ { "tst", "orzxi" },
+ { "", "" },
+};
+
+START_TEST(test_base32_encode)
+{
+ size_t len;
+ char buf[4096];
+ struct encoder *b32;
+ int val;
+
+ b32 = get_base32_encoder();
+
+ len = sizeof(buf);
+ val = b32->encode(buf, &len, testpairs[_i].a, strlen(testpairs[_i].a));
+
+ fail_unless(strcmp(buf, testpairs[_i].b) == 0,
+ "'%s' != '%s'", buf, testpairs[_i].b);
+}
+END_TEST
+
+START_TEST(test_base32_decode)
+{
+ size_t len;
+ char buf[4096];
+ struct encoder *b32;
+ int val;
+
+ b32 = get_base32_encoder();
+
+ len = sizeof(buf);
+ val = b32->decode(buf, &len, testpairs[_i].b, strlen(testpairs[_i].b));
+
+ fail_unless(buf != NULL, "buf == NULL");
+ fail_unless(strcmp(buf, testpairs[_i].a) == 0,
+ "'%s' != '%s'", buf, testpairs[_i].a);
+}
+END_TEST
+
+START_TEST(test_base32_5to8_8to5)
+{
+ int i;
+ int c;
+
+ for (i = 0; i < 32; i++) {
+ c = b32_5to8(i);
+ fail_unless(b32_8to5(c) == i);
+ }
+}
+END_TEST
+
+START_TEST(test_base32_blksize)
+{
+ size_t rawlen;
+ size_t enclen;
+ char *rawbuf;
+ char *encbuf;
+ struct encoder *b32;
+ int i;
+ int val;
+
+ b32 = get_base32_encoder();
+
+ rawlen = b32->blocksize_raw();
+ enclen = b32->blocksize_encoded();
+
+ rawbuf = malloc(rawlen + 16);
+ encbuf = malloc(enclen + 16);
+
+ for (i = 0; i < rawlen; i++) {
+ rawbuf[i] = 'A';
+ }
+ rawbuf[i] = 0;
+
+ val = b32->encode(encbuf, &enclen, rawbuf, rawlen);
+
+ fail_unless(rawlen == 5, "raw length was %d not 5", rawlen);
+ fail_unless(enclen == 5, "encoded %d bytes, not 5", enclen);
+ fail_unless(val == 8, "encoded string %s was length %d", encbuf, val);
+
+ memset(rawbuf, 0, rawlen + 16);
+
+ enclen = val;
+ val = b32->decode(rawbuf, &rawlen, encbuf, enclen);
+
+ fail_unless(rawlen == 5, "raw length was %d not 5", rawlen);
+ fail_unless(val == 5, "val was not 5 but %d", val);
+ for (i = 0; i < rawlen; i++) {
+ fail_unless(rawbuf[i] == 'A');
+ }
+}
+END_TEST
+
+TCase *
+test_base32_create_tests()
+{
+ TCase *tc;
+
+ tc = tcase_create("Base32");
+ tcase_add_loop_test(tc, test_base32_encode, 0, TUPLES);
+ tcase_add_loop_test(tc, test_base32_decode, 0, TUPLES);
+ tcase_add_test(tc, test_base32_5to8_8to5);
+ tcase_add_test(tc, test_base32_blksize);
+
+ return tc;
+}
diff --git a/jni/iodine/tests/base64.c b/jni/iodine/tests/base64.c
new file mode 100644
index 0000000..bd0e9ce
--- /dev/null
+++ b/jni/iodine/tests/base64.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2006-2009 Bjorn Andersson <flex@kryo.se>, Erik Ekman <yarrick@kryo.se>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <check.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "encoding.h"
+#include "base64.h"
+#include "test.h"
+
+#define TUPLES 5
+
+static struct tuple
+{
+ char *a;
+ char *b;
+} testpairs[TUPLES] = {
+ { "iodinetestingtesting", "Aw8KAw4LDgvZDgLUz2rLC2rPBMC" },
+ { "abc1231", "ywjJmtiZmq" },
+ {
+ "\xFF\xEF\x7C\xEF\xAE\x78\xDF\x6D\x74\xCF\x2C\x70\xBE\xEB\x6C\xAE\xAA\x68"
+ "\x9E\x69\x64\x8E\x28\x60\x7D\xE7\x5C\x6D\xA6\x58\x5D\x65\x54\x4D\x24\x50"
+ "\x3C\xE3\x4C\x2C\xA2\x48\x1C\x61\x44\x0C\x20\x40\x3F\x3F\x3C\xEF\xAE\x78"
+ "\xDF\x6D\x74\xCF\x2C\x70\xBE\xEB\x6C\xAE\xAA\x68\x9E\x69\x64\x8E\x28\x60"
+ "\x7D\xE7\x5C\x6D\xA6\x58\x5D\x65\x54\x4D\x24\x50\x3C\xE3\x4C\x2C\xA2\x48"
+ "\x1C\x61\x44\x0C\x20\x40\xFF\xEF\x7C\xEF\xAE\x78\xDF\x6D\x74\xCF\x2C\x70"
+ "\xBE\xEB\x6C\xAE\xAA\x68\x9E\x69\x64\x8E\x28\x60\x7D\xE7\x5C\x6D\xA6\x58"
+ "\x5D\x65\x54\x4D\x24\x50\x3C\xE3\x4C\x2C\xA2\x48\x1C\x61\x44\x0C\x20\x40",
+
+ "+9876543210-ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcbapZ"
+ "776543210-ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba+987654"
+ "3210-ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba"
+ },
+ {
+ "\xFF\xEF\x7C\xEF\xAE\x78\xDF\x6D\x74\xCF\x2C\x70\xBE\xEB\x6C\xAE\xAA\x68"
+ "\x9E\x69\x64\x8E\x28\x60\x7D\xE7\x5C\x6D\xA6\x58\x5D\x65\x54\x4D\x24\x50"
+ "\x3C\xE3\x4C\x2C\xA2\x48\x1C\x61\x44\x0C\x20\x40\x3F\x3F\x3C\xEF\xAE\x78"
+ "\xDF\x6D\x74\xCF\x2C\x70\xBE\xEB\x6C\xAE\xA1\x61\x91\x61\x61\x81\x28\x60"
+ "\x7D\xE7\x5C\x6D\xA6\x58\x5D\x65\x54\x4D\x24\x50\x3C\xE3\x4C\x2C\xA2\x48"
+ "\x1C\x61\x44\x0C\x20\x40\xFF\xEF\x7C\xEF\xAE\x78\xDF\x6D\x74\xCF\x2C\x70"
+ "\xBE\xEB\x6C\xAE\xA1\x61\x91\x61\x61\x81\x28\x60\x7D\xE7\x5C\x6D\xA6\x58"
+ "\x5D\x65\x54\x4D\x24\x50\x3C\xE3\x4C\x2C\xA2\x48\x1C\x61\x44\x0C\x20\x40",
+
+ "+9876543210-ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcbapZ"
+ "776543210-ZYXWVUTSRQfHKwfHGsHGFEDCBAzyxwvutsrqponmlkjihgfedcba+987654321"
+ "0-ZYXWVUTSRQfHKwfHGsHGFEDCBAzyxwvutsrqponmlkjihgfedcba"
+ },
+ { "", "" }
+};
+
+START_TEST(test_base64_encode)
+{
+ size_t len;
+ char buf[4096];
+ struct encoder *b64;
+ int val;
+
+ b64 = get_base64_encoder();
+
+ len = sizeof(buf);
+ val = b64->encode(buf, &len, testpairs[_i].a, strlen(testpairs[_i].a));
+
+ fail_unless(strcmp(buf, testpairs[_i].b) == 0,
+ "'%s' != '%s'", buf, testpairs[_i].b);
+}
+END_TEST
+
+START_TEST(test_base64_decode)
+{
+ size_t len;
+ char buf[4096];
+ struct encoder *b64;
+ int val;
+
+ b64 = get_base64_encoder();
+
+ len = sizeof(buf);
+ val = b64->decode(buf, &len, testpairs[_i].b, strlen(testpairs[_i].b));
+
+ fail_unless(buf != NULL, "buf == NULL");
+ fail_unless(strcmp(buf, testpairs[_i].a) == 0,
+ "'%s' != '%s'", buf, testpairs[_i].a);
+}
+END_TEST
+
+START_TEST(test_base64_blksize)
+{
+ size_t rawlen;
+ size_t enclen;
+ char *rawbuf;
+ char *encbuf;
+ struct encoder *b64;
+ int i;
+ int val;
+
+ b64 = get_base64_encoder();
+
+ rawlen = b64->blocksize_raw();
+ enclen = b64->blocksize_encoded();
+
+ rawbuf = malloc(rawlen + 16);
+ encbuf = malloc(enclen + 16);
+
+ for (i = 0; i < rawlen; i++) {
+ rawbuf[i] = 'A';
+ }
+ rawbuf[i] = 0;
+
+ val = b64->encode(encbuf, &enclen, rawbuf, rawlen);
+
+ fail_unless(rawlen == 3, "raw length was %d not 3", rawlen);
+ fail_unless(enclen == 3, "encoded %d bytes, not 3", enclen);
+ fail_unless(val == 4, "encoded string %s was length %d", encbuf, val);
+
+ memset(rawbuf, 0, rawlen + 16);
+
+ enclen = val;
+ val = b64->decode(rawbuf, &rawlen, encbuf, enclen);
+
+ fail_unless(rawlen == 3, "raw length was %d not 3", rawlen);
+ fail_unless(val == 3);
+ for (i = 0; i < rawlen; i++) {
+ fail_unless(rawbuf[i] == 'A');
+ }
+}
+END_TEST
+
+TCase *
+test_base64_create_tests()
+{
+ TCase *tc;
+
+ tc = tcase_create("Base64");
+ tcase_add_loop_test(tc, test_base64_encode, 0, TUPLES);
+ tcase_add_loop_test(tc, test_base64_decode, 0, TUPLES);
+ tcase_add_test(tc, test_base64_blksize);
+
+ return tc;
+}
diff --git a/jni/iodine/tests/dns.c b/jni/iodine/tests/dns.c
new file mode 100644
index 0000000..3d21e4c
--- /dev/null
+++ b/jni/iodine/tests/dns.c
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2006-2009 Bjorn Andersson <flex@kryo.se>, Erik Ekman <yarrick@kryo.se>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <check.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/stat.h>
+#include <arpa/nameser.h>
+
+#include "common.h"
+#include "dns.h"
+#include "encoding.h"
+#include "base32.h"
+#include "test.h"
+
+static void dump_packet(char *, size_t);
+
+static char query_packet[] =
+ "\x05\x39\x01\x00\x00\x01\x00\x00\x00\x00\x00\x01\x2D\x41\x6A\x62\x63"
+ "\x75\x79\x74\x63\x70\x65\x62\x30\x67\x71\x30\x6C\x74\x65\x62\x75\x78"
+ "\x67\x69\x64\x75\x6E\x62\x73\x73\x61\x33\x64\x66\x6F\x6E\x30\x63\x61"
+ "\x7A\x64\x62\x6F\x72\x71\x71\x04\x6B\x72\x79\x6F\x02\x73\x65\x00\x00"
+ "\x0A\x00\x01\x00\x00\x29\x10\x00\x00\x00\x80\x00\x00\x00";
+
+static char answer_packet[] =
+ "\x05\x39\x84\x00\x00\x01\x00\x01\x00\x00\x00\x00\x05\x73\x69\x6C\x6C"
+ "\x79\x04\x68\x6F\x73\x74\x02\x6F\x66\x06\x69\x6F\x64\x69\x6E\x65\x04"
+ "\x63\x6F\x64\x65\x04\x6B\x72\x79\x6F\x02\x73\x65\x00\x00\x0A\x00\x01"
+ "\xC0\x0C\x00\x0A\x00\x01\x00\x00\x00\x00\x00\x23\x74\x68\x69\x73\x20"
+ "\x69\x73\x20\x74\x68\x65\x20\x6D\x65\x73\x73\x61\x67\x65\x20\x74\x6F"
+ "\x20\x62\x65\x20\x64\x65\x6C\x69\x76\x65\x72\x65\x64";
+
+static char answer_packet_high_trans_id[] =
+ "\x85\x39\x84\x00\x00\x01\x00\x01\x00\x00\x00\x00\x05\x73\x69\x6C\x6C"
+ "\x79\x04\x68\x6F\x73\x74\x02\x6F\x66\x06\x69\x6F\x64\x69\x6E\x65\x04"
+ "\x63\x6F\x64\x65\x04\x6B\x72\x79\x6F\x02\x73\x65\x00\x00\x0A\x00\x01"
+ "\xC0\x0C\x00\x0A\x00\x01\x00\x00\x00\x00\x00\x23\x74\x68\x69\x73\x20"
+ "\x69\x73\x20\x74\x68\x65\x20\x6D\x65\x73\x73\x61\x67\x65\x20\x74\x6F"
+ "\x20\x62\x65\x20\x64\x65\x6C\x69\x76\x65\x72\x65\x64";
+static char *msgData = "this is the message to be delivered";
+static char *topdomain = "kryo.se";
+
+static char *innerData = "HELLO this is the test data";
+
+START_TEST(test_encode_query)
+{
+ char buf[512];
+ char resolv[512];
+ struct query q;
+ struct encoder *enc;
+ char *d;
+ size_t len;
+ size_t enclen;
+ int ret;
+
+ enclen = sizeof(resolv);
+ memset(&buf, 0, sizeof(buf));
+ memset(&resolv, 0, sizeof(resolv));
+ memset(&q, 0, sizeof(struct query));
+ q.type = T_NULL;
+ q.id = 1337;
+ d = resolv;
+ enc = get_base32_encoder();
+
+ *d++ = 'A';
+ enc->encode(d, &enclen, innerData, strlen(innerData));
+ d = resolv + strlen(resolv);
+ if (*d != '.') {
+ *d++ = '.';
+ }
+ strcpy(d, topdomain);
+ len = sizeof(buf);
+ ret = dns_encode(buf, len, &q, QR_QUERY, resolv, strlen(resolv));
+ len = sizeof(query_packet) - 1; /* Skip extra null character */
+
+ if (strncmp(query_packet, buf, sizeof(query_packet)) || ret != len) {
+ printf("\n");
+ dump_packet(query_packet, len);
+ dump_packet(buf, ret);
+ }
+ fail_unless(strncmp(query_packet, buf, sizeof(query_packet)) == 0, "Did not compile expected packet");
+ fail_unless(ret == len, "Bad packet length: %d, expected %d", ret, len);
+}
+END_TEST
+
+START_TEST(test_decode_query)
+{
+ char buf[512];
+ char *domain;
+ struct query q;
+ struct encoder *enc;
+ size_t len;
+
+ memset(&q, 0, sizeof(struct query));
+ memset(&buf, 0, sizeof(buf));
+ q.id = 0;
+ len = sizeof(query_packet) - 1;
+ enc = get_base32_encoder();
+
+ dns_decode(buf, sizeof(buf), &q, QR_QUERY, query_packet, len);
+ domain = strstr(q.name, topdomain);
+ len = sizeof(buf);
+ unpack_data(buf, len, &(q.name[1]), (int) (domain - q.name) - 1, enc);
+
+ fail_unless(strncmp(buf, innerData, strlen(innerData)) == 0, "Did not extract expected host: '%s'", buf);
+ fail_unless(strlen(buf) == strlen(innerData), "Bad host length: %d, expected %d: '%s'", strlen(buf), strlen(innerData), buf);
+}
+END_TEST
+
+START_TEST(test_encode_response)
+{
+ char buf[512];
+ char *host = "silly.host.of.iodine.code.kryo.se";
+ struct query q;
+ int len;
+ int ret;
+
+ len = sizeof(buf);
+ memset(&buf, 0, sizeof(buf));
+ memset(&q, 0, sizeof(struct query));
+ strncpy(q.name, host, strlen(host));
+ q.type = T_NULL;
+ q.id = 1337;
+
+ ret = dns_encode(buf, len, &q, QR_ANSWER, msgData, strlen(msgData));
+ len = sizeof(answer_packet) - 1; /* Skip extra null character */
+
+ fail_unless(strncmp(answer_packet, buf, sizeof(answer_packet)) == 0, "Did not compile expected packet");
+ fail_unless(ret == len, "Bad packet length: %d, expected %d", ret, len);
+}
+END_TEST
+
+START_TEST(test_decode_response)
+{
+ char buf[512];
+ struct query q;
+ int len;
+ int ret;
+
+ len = sizeof(buf);
+ memset(&buf, 0, sizeof(buf));
+
+ ret = dns_decode(buf, len, &q, QR_ANSWER, answer_packet, sizeof(answer_packet)-1);
+ fail_unless(strncmp(msgData, buf, sizeof(msgData)) == 0, "Did not extract expected data");
+ fail_unless(ret == strlen(msgData), "Bad data length: %d, expected %d", ret, strlen(msgData));
+ fail_unless(q.id == 0x0539);
+}
+END_TEST
+
+START_TEST(test_decode_response_with_high_trans_id)
+{
+ char buf[512];
+ struct query q;
+ int len;
+ int ret;
+
+ len = sizeof(buf);
+ memset(&buf, 0, sizeof(buf));
+
+ ret = dns_decode(buf, len, &q, QR_ANSWER, answer_packet_high_trans_id, sizeof(answer_packet_high_trans_id)-1);
+ fail_unless(strncmp(msgData, buf, sizeof(msgData)) == 0, "Did not extract expected data");
+ fail_unless(ret == strlen(msgData), "Bad data length: %d, expected %d", ret, strlen(msgData));
+ fail_unless(q.id == 0x8539, "q.id was %08X instead of %08X!", q.id, 0x8539);
+}
+END_TEST
+
+START_TEST(test_get_id_short_packet)
+{
+ char buf[5];
+ int len;
+ unsigned short id;
+
+ len = sizeof(buf);
+ memset(&buf, 5, sizeof(buf));
+
+ id = dns_get_id(buf, len);
+ fail_unless(id == 0);
+}
+END_TEST
+
+START_TEST(test_get_id_low)
+{
+ unsigned short id;
+
+ id = dns_get_id(answer_packet, sizeof(answer_packet));
+ fail_unless(id == 1337);
+}
+END_TEST
+
+START_TEST(test_get_id_high)
+{
+ unsigned short id;
+
+ id = dns_get_id(answer_packet_high_trans_id, sizeof(answer_packet_high_trans_id));
+ fail_unless(id == 0x8539);
+}
+END_TEST
+
+static void
+dump_packet(char *buf, size_t len)
+{
+ int pos;
+
+ for (pos = 0; pos < len; pos++) {
+ printf("\\x%02X", (unsigned char) buf[pos]);
+ }
+ printf("\n");
+ for (pos = 0; pos < len; pos++) {
+ if (isalnum((unsigned char) buf[pos])) {
+ printf(" %c ", (unsigned char) buf[pos]);
+ } else {
+ printf(" ");
+ }
+ }
+ printf("\n");
+}
+
+TCase *
+test_dns_create_tests()
+{
+ TCase *tc;
+
+ tc = tcase_create("Dns");
+ tcase_add_test(tc, test_encode_query);
+ tcase_add_test(tc, test_decode_query);
+ tcase_add_test(tc, test_encode_response);
+ tcase_add_test(tc, test_decode_response);
+ tcase_add_test(tc, test_decode_response_with_high_trans_id);
+ tcase_add_test(tc, test_get_id_short_packet);
+ tcase_add_test(tc, test_get_id_low);
+ tcase_add_test(tc, test_get_id_high);
+
+ return tc;
+}
diff --git a/jni/iodine/tests/encoding.c b/jni/iodine/tests/encoding.c
new file mode 100644
index 0000000..ac22452
--- /dev/null
+++ b/jni/iodine/tests/encoding.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2006-2009 Bjorn Andersson <flex@kryo.se>, Erik Ekman <yarrick@kryo.se>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <check.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "encoding.h"
+#include "test.h"
+#include "base32.h"
+#include "base64.h"
+
+#define TUPLES 4
+
+static struct tuple
+{
+ char *a;
+ char *b;
+} dottests[] = {
+ { "aaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ "aaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaa"},
+ { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."},
+ { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},
+ { "abc123", "abc123" },
+ { NULL, NULL }
+};
+
+START_TEST(test_inline_dotify)
+{
+ char temp[1024];
+ char *b;
+
+ memset(temp, 0, sizeof(temp));
+ strcpy(temp, dottests[_i].a);
+ b = temp;
+ inline_dotify(b, sizeof(temp));
+
+ fail_unless(strcmp(dottests[_i].b, temp) == 0,
+ "'%s' != '%s'", temp, dottests[_i].b);
+}
+END_TEST
+
+START_TEST(test_inline_undotify)
+{
+ char temp[1024];
+ char *b;
+
+ memset(temp, 0, sizeof(temp));
+ strcpy(temp, dottests[_i].b);
+ b = temp;
+ inline_undotify(b, sizeof(temp));
+
+ fail_unless(strcmp(dottests[_i].a, temp) == 0,
+ "'%s' != '%s'", temp, dottests[_i].a);
+}
+END_TEST
+
+START_TEST(test_build_hostname)
+{
+ char data[256];
+ char buf[1024];
+ char *topdomain = "a.c";
+ int buflen;
+ int i;
+
+ for (i = 0; i < sizeof(data); i++) {
+ data[i] = i & 0xFF;
+ }
+
+ buflen = sizeof(buf);
+
+ for (i = 1; i < sizeof(data); i++) {
+ int len = build_hostname(buf, buflen, data, i, topdomain, get_base32_encoder(), sizeof(buf));
+
+ fail_if(len > i);
+ fail_if(strstr(buf, ".."), "Found double dots when encoding data len %d! buf: %s", i, buf);
+ }
+}
+END_TEST
+
+TCase *
+test_encoding_create_tests()
+{
+ TCase *tc;
+
+ tc = tcase_create("Encoding");
+ tcase_add_loop_test(tc, test_inline_dotify, 0, TUPLES);
+ tcase_add_loop_test(tc, test_inline_undotify, 0, TUPLES);
+ tcase_add_test(tc, test_build_hostname);
+
+ return tc;
+}
diff --git a/jni/iodine/tests/fw_query.c b/jni/iodine/tests/fw_query.c
new file mode 100644
index 0000000..6d23924
--- /dev/null
+++ b/jni/iodine/tests/fw_query.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2006-2009 Erik Ekman <yarrick@kryo.se>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <check.h>
+
+#include "fw_query.h"
+#include "test.h"
+
+START_TEST(test_fw_query_simple)
+{
+ struct fw_query q;
+ struct fw_query *qp;
+
+ q.addrlen = 33;
+ q.id = 0x848A;
+
+ fw_query_init();
+
+ /* Test empty cache */
+ fw_query_get(0x848A, &qp);
+ fail_unless(qp == NULL);
+
+ fw_query_put(&q);
+
+ /* Test cache with one entry */
+ fw_query_get(0x848A, &qp);
+ fail_unless(qp->addrlen == q.addrlen);
+ fail_unless(qp->id == q.id);
+}
+END_TEST
+
+START_TEST(test_fw_query_edge)
+{
+ struct fw_query q;
+ struct fw_query *qp;
+ int i;
+
+ fw_query_init();
+
+ q.addrlen = 33;
+ q.id = 0x848A;
+ fw_query_put(&q);
+
+ for (i = 1; i < FW_QUERY_CACHE_SIZE; i++) {
+ q.addrlen++;
+ q.id++;
+ fw_query_put(&q);
+ }
+
+ /* The query should still be cached */
+ fw_query_get(0x848A, &qp);
+ fail_unless(qp->addrlen == 33);
+ fail_unless(qp->id == 0x848A);
+
+ q.addrlen++;
+ q.id++;
+ fw_query_put(&q);
+
+ /* but now it is overwritten */
+ fw_query_get(0x848A, &qp);
+ fail_unless(qp == NULL);
+}
+END_TEST
+
+TCase *
+test_fw_query_create_tests()
+{
+ TCase *tc;
+
+ tc = tcase_create("Forwarded query");
+ tcase_add_test(tc, test_fw_query_simple);
+ tcase_add_test(tc, test_fw_query_edge);
+
+ return tc;
+}
diff --git a/jni/iodine/tests/login.c b/jni/iodine/tests/login.c
new file mode 100644
index 0000000..1ef23f4
--- /dev/null
+++ b/jni/iodine/tests/login.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2006-2009 Bjorn Andersson <flex@kryo.se>, Erik Ekman <yarrick@kryo.se>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <check.h>
+#include <string.h>
+
+#include "test.h"
+#include "login.h"
+
+START_TEST(test_login_hash)
+{
+ char ans[16];
+ char good[] = "\x2A\x8A\x12\xB4\xE0\x42\xEE\xAB\xD0\x19\x17\x1E\x44\xA0\x88\xCD";
+ char pass[32] = "iodine is the shit";
+ int len;
+ int seed;
+
+ len = sizeof(ans);
+ seed = 15;
+
+ memset(ans, 0, sizeof(ans));
+ login_calculate(ans, len, pass, seed);
+ fail_unless(strncmp(ans, good, len) == 0, NULL);
+}
+END_TEST
+
+START_TEST(test_login_hash_short)
+{
+ char ans[8];
+ char check[sizeof(ans)];
+ char pass[32] = "iodine is the shit";
+ int len;
+ int seed;
+
+ len = sizeof(ans);
+ seed = 15;
+
+ memset(ans, 0, sizeof(ans));
+ memset(check, 0, sizeof(check));
+
+ /* If len < 16, it should do nothing */
+ login_calculate(ans, len, pass, seed);
+ fail_if(memcmp(ans, check, sizeof(ans)));
+}
+END_TEST
+
+TCase *
+test_login_create_tests()
+{
+ TCase *tc;
+
+ tc = tcase_create("Login");
+ tcase_add_test(tc, test_login_hash);
+ tcase_add_test(tc, test_login_hash_short);
+
+ return tc;
+}
diff --git a/jni/iodine/tests/read.c b/jni/iodine/tests/read.c
new file mode 100644
index 0000000..18cc29c
--- /dev/null
+++ b/jni/iodine/tests/read.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2006-2009 Bjorn Andersson <flex@kryo.se>, Erik Ekman <yarrick@kryo.se>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/stat.h>
+#include <arpa/nameser.h>
+#ifdef DARWIN
+#include <arpa/nameser8_compat.h>
+#endif
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <check.h>
+
+#include "common.h"
+#include "encoding.h"
+#include "dns.h"
+#include "read.h"
+#include "test.h"
+
+START_TEST(test_read_putshort)
+{
+ unsigned short k;
+ unsigned short l;
+ char* p;
+ int i;
+
+ for (i = 0; i < 65536; i++) {
+ p = (char*)&k;
+ putshort(&p, i);
+ fail_unless(ntohs(k) == i,
+ "Bad value on putshort for %d: %d != %d",
+ i, ntohs(k), i);
+
+ p = (char*)&k;
+ readshort(NULL, &p, (short *) &l);
+ fail_unless(l == i,
+ "Bad value on readshort for %d: %d != %d",
+ i, l, i);
+ }
+}
+END_TEST
+
+START_TEST(test_read_putlong)
+{
+ uint32_t k;
+ uint32_t l;
+ char* p;
+ int i;
+ int j;
+
+ for (i = 0; i < 32; i++) {
+ p = (char*)&k;
+ j = 0xf << i;
+
+ putlong(&p, j);
+
+ fail_unless(ntohl(k) == j,
+ "Bad value on putlong for %d: %d != %d", i, ntohl(j), j);
+
+ p = (char*)&k;
+ readlong(NULL, &p, &l);
+
+ fail_unless(l == j,
+ "Bad value on readlong for %d: %d != %d", i, l, j);
+ }
+}
+END_TEST
+
+START_TEST(test_read_name_empty_loop)
+{
+ unsigned char emptyloop[] = {
+ 'A', 'A', 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01 };
+ char buf[1024];
+ char *data;
+ int rv;
+
+ memset(buf, 0, sizeof(buf));
+ data = (char*) emptyloop + sizeof(HEADER);
+ buf[1023] = 'A';
+ rv = readname((char *) emptyloop, sizeof(emptyloop), &data, buf, 1023);
+ fail_unless(buf[1023] == 'A');
+}
+END_TEST
+
+START_TEST(test_read_name_inf_loop)
+{
+ unsigned char infloop[] = {
+ 'A', 'A', 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 'A', 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01 };
+ char buf[1024];
+ char *data;
+ int rv;
+
+ memset(buf, 0, sizeof(buf));
+ data = (char*) infloop + sizeof(HEADER);
+ buf[4] = '\a';
+ rv = readname((char*) infloop, sizeof(infloop), &data, buf, 4);
+ fail_unless(buf[4] == '\a');
+}
+END_TEST
+
+START_TEST(test_read_name_longname)
+{
+ unsigned char longname[] =
+ "AA\x81\x80\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
+ "\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
+ "\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
+ "\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
+ "\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
+ "\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
+ "\x00\x00\x01\x00\x01";
+ char buf[1024];
+ char *data;
+ int rv;
+
+ memset(buf, 0, sizeof(buf));
+ data = (char*) longname + sizeof(HEADER);
+ buf[256] = '\a';
+ rv = readname((char*) longname, sizeof(longname), &data, buf, 256);
+ fail_unless(buf[256] == '\a');
+}
+END_TEST
+
+START_TEST(test_read_name_onejump)
+{
+ unsigned char onejump[] =
+ "AA\x81\x80\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x02hh\xc0\x15\x00\x01\x00\x01\x05zBCDE\x00";
+ char buf[1024];
+ char *data;
+ int rv;
+
+ memset(buf, 0, sizeof(buf));
+ data = (char*) onejump + sizeof(HEADER);
+ rv = readname((char*) onejump, sizeof(onejump), &data, buf, 256);
+ fail_unless(rv == 9);
+}
+END_TEST
+
+START_TEST(test_read_name_badjump_start)
+{
+ unsigned char badjump[] = {
+ 'A', 'A', 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xfe, 0xcc, 0x00, 0x01, 0x00, 0x01 };
+ unsigned char *jumper;
+ char buf[1024];
+ char *data;
+ int rv;
+
+ /* This test uses malloc to cause segfault if jump is executed */
+ memset(buf, 0, sizeof(buf));
+ jumper = malloc(sizeof(badjump));
+ if (jumper) {
+ memcpy(jumper, badjump, sizeof(badjump));
+ data = (char*) jumper + sizeof(HEADER);
+ rv = readname((char*) jumper, sizeof(badjump), &data, buf, 256);
+
+ fail_unless(rv == 0);
+ fail_unless(buf[0] == 0);
+ }
+ free(jumper);
+}
+END_TEST
+
+START_TEST(test_read_name_badjump_second)
+{
+ unsigned char badjump2[] = {
+ 'A', 'A', 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 'B', 'A', 0xfe, 0xcc, 0x00, 0x01, 0x00, 0x01 };
+ unsigned char *jumper;
+ char buf[1024];
+ char *data;
+ int rv;
+
+ /* This test uses malloc to cause segfault if jump is executed */
+ memset(buf, 0, sizeof(buf));
+ jumper = malloc(sizeof(badjump2));
+ if (jumper) {
+ memcpy(jumper, badjump2, sizeof(badjump2));
+ data = (char*) jumper + sizeof(HEADER);
+ rv = readname((char*) jumper, sizeof(badjump2), &data, buf, 256);
+
+ fail_unless(rv == 4);
+ fail_unless(strcmp("BA.", buf) == 0,
+ "buf is not BA: %s", buf);
+ }
+ free(jumper);
+}
+END_TEST
+
+START_TEST(test_putname)
+{
+ char out[] = "\x06" "BADGER\x06" "BADGER\x04" "KRYO\x02" "SE\x00";
+ char buf[256];
+ char *domain = "BADGER.BADGER.KRYO.SE";
+ char *b;
+ int len;
+ int ret;
+
+ len = 256;
+
+ memset(buf, 0, 256);
+ b = buf;
+ ret = putname(&b, 256, domain);
+
+ fail_unless(ret == strlen(domain) + 1);
+ fail_unless(strncmp(buf, out, ret) == 0, "Happy flow failed");
+}
+END_TEST
+
+START_TEST(test_putname_nodot)
+{
+ char buf[256];
+ char *nodot =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ char *b;
+ int len;
+ int ret;
+
+ len = 256;
+
+ memset(buf, 0, 256);
+ b = buf;
+ ret = putname(&b, 256, nodot);
+
+ fail_unless(ret == -1);
+ fail_unless(b == buf);
+}
+END_TEST
+
+START_TEST(test_putname_toolong)
+{
+ char buf[256];
+ char *toolong =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ.";
+ char *b;
+ int len;
+ int ret;
+
+ len = 256;
+
+ memset(buf, 0, 256);
+ b = buf;
+ ret = putname(&b, 256, toolong);
+
+ fail_unless(ret == -1);
+ fail_unless(b == buf);
+}
+END_TEST
+
+
+TCase *
+test_read_create_tests()
+{
+ TCase *tc;
+
+ tc = tcase_create("Read");
+ tcase_set_timeout(tc, 60);
+ tcase_add_test(tc, test_read_putshort);
+ tcase_add_test(tc, test_read_putlong);
+ tcase_add_test(tc, test_read_name_empty_loop);
+ tcase_add_test(tc, test_read_name_inf_loop);
+ tcase_add_test(tc, test_read_name_longname);
+ tcase_add_test(tc, test_read_name_onejump);
+ tcase_add_test(tc, test_read_name_badjump_start);
+ tcase_add_test(tc, test_read_name_badjump_second);
+ tcase_add_test(tc, test_putname);
+ tcase_add_test(tc, test_putname_nodot);
+ tcase_add_test(tc, test_putname_toolong);
+
+ return tc;
+}
diff --git a/jni/iodine/tests/test.c b/jni/iodine/tests/test.c
new file mode 100644
index 0000000..5bee9d2
--- /dev/null
+++ b/jni/iodine/tests/test.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2006-2009 Bjorn Andersson <flex@kryo.se>, Erik Ekman <yarrick@kryo.se>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <check.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test.h"
+
+int
+main()
+{
+ SRunner *runner;
+ Suite *iodine;
+ TCase *test;
+ int failed;
+
+ iodine = suite_create("iodine");
+
+ test = test_base32_create_tests();
+ suite_add_tcase(iodine, test);
+
+ test = test_base64_create_tests();
+ suite_add_tcase(iodine, test);
+
+ test = test_dns_create_tests();
+ suite_add_tcase(iodine, test);
+
+ test = test_encoding_create_tests();
+ suite_add_tcase(iodine, test);
+
+ test = test_read_create_tests();
+ suite_add_tcase(iodine, test);
+
+ test = test_login_create_tests();
+ suite_add_tcase(iodine, test);
+
+ test = test_user_create_tests();
+ suite_add_tcase(iodine, test);
+
+ test = test_fw_query_create_tests();
+ suite_add_tcase(iodine, test);
+
+ runner = srunner_create(iodine);
+ srunner_run_all(runner, CK_NORMAL);
+ failed = srunner_ntests_failed(runner);
+
+ srunner_free(runner);
+
+ return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/jni/iodine/tests/test.h b/jni/iodine/tests/test.h
new file mode 100644
index 0000000..1022a9e
--- /dev/null
+++ b/jni/iodine/tests/test.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2006-2009 Bjorn Andersson <flex@kryo.se>, Erik Ekman <yarrick@kryo.se>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __TEST_H__
+#define __TEST_H__
+
+TCase *test_base32_create_tests();
+TCase *test_base64_create_tests();
+TCase *test_dns_create_tests();
+TCase *test_encoding_create_tests();
+TCase *test_read_create_tests();
+TCase *test_login_create_tests();
+TCase *test_user_create_tests();
+TCase *test_fw_query_create_tests();
+
+char *va_str(const char *, ...);
+
+#if (CHECK_MAJOR_VERSION == 0 && \
+ ((CHECK_MINOR_VERSION == 9 && CHECK_MICRO_VERSION < 2) || \
+ (CHECK_MINOR_VERSION < 9)))
+#define tcase_set_timeout(...)
+#endif
+
+#endif
diff --git a/jni/iodine/tests/user.c b/jni/iodine/tests/user.c
new file mode 100644
index 0000000..afd61ca
--- /dev/null
+++ b/jni/iodine/tests/user.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2006-2009 Bjorn Andersson <flex@kryo.se>, Erik Ekman <yarrick@kryo.se>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <check.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#include "common.h"
+#include "encoding.h"
+#include "user.h"
+#include "test.h"
+
+START_TEST(test_init_users)
+{
+ in_addr_t ip;
+ char givenip[16];
+ int i;
+
+ ip = inet_addr("127.0.0.1");
+ init_users(ip, 27);
+ for (i = 0; i < USERS; i++) {
+ fail_unless(users[i].id == i);
+ fail_unless(users[i].q.id == 0);
+ fail_unless(users[i].inpacket.len == 0);
+ fail_unless(users[i].outpacket.len == 0);
+ snprintf(givenip, sizeof(givenip), "127.0.0.%d", i + 2);
+ fail_unless(users[i].tun_ip == inet_addr(givenip));
+ }
+}
+END_TEST
+
+START_TEST(test_users_waiting)
+{
+ in_addr_t ip;
+
+ ip = inet_addr("127.0.0.1");
+ init_users(ip, 27);
+
+ fail_unless(users_waiting_on_reply() == 0);
+
+ users[3].active = 1;
+
+ fail_unless(users_waiting_on_reply() == 0);
+
+ users[3].last_pkt = time(NULL);
+
+ fail_unless(users_waiting_on_reply() == 0);
+
+ users[3].conn = CONN_DNS_NULL;
+ users[3].q.id = 1;
+
+ fail_unless(users_waiting_on_reply() == 1);
+}
+END_TEST
+
+START_TEST(test_find_user_by_ip)
+{
+ in_addr_t ip;
+ unsigned int testip;
+
+ ip = inet_addr("127.0.0.1");
+ init_users(ip, 27);
+ users[0].conn = CONN_DNS_NULL;
+
+ testip = (unsigned int) inet_addr("10.0.0.1");
+ fail_unless(find_user_by_ip(testip) == -1);
+
+ testip = (unsigned int) inet_addr("127.0.0.2");
+ fail_unless(find_user_by_ip(testip) == -1);
+
+ users[0].active = 1;
+
+ testip = (unsigned int) inet_addr("127.0.0.2");
+ fail_unless(find_user_by_ip(testip) == -1);
+
+ users[0].last_pkt = time(NULL);
+
+ testip = (unsigned int) inet_addr("127.0.0.2");
+ fail_unless(find_user_by_ip(testip) == 0);
+}
+END_TEST
+
+START_TEST(test_all_users_waiting_to_send)
+{
+ in_addr_t ip;
+
+ ip = inet_addr("127.0.0.1");
+ init_users(ip, 27);
+
+ fail_unless(all_users_waiting_to_send() == 1);
+
+ users[0].conn = CONN_DNS_NULL;
+ users[0].active = 1;
+
+ fail_unless(all_users_waiting_to_send() == 1);
+
+ users[0].last_pkt = time(NULL);
+ users[0].outpacket.len = 0;
+
+ fail_unless(all_users_waiting_to_send() == 0);
+
+#ifdef OUTPACKETQ_LEN
+ users[0].outpacketq_filled = 1;
+#else
+ users[0].outpacket.len = 44;
+#endif
+
+ fail_unless(all_users_waiting_to_send() == 1);
+}
+END_TEST
+
+START_TEST(test_find_available_user)
+{
+ in_addr_t ip;
+ int i;
+
+ ip = inet_addr("127.0.0.1");
+ init_users(ip, 27);
+
+ for (i = 0; i < USERS; i++) {
+ fail_unless(find_available_user() == i);
+ }
+
+ for (i = 0; i < USERS; i++) {
+ fail_unless(find_available_user() == -1);
+ }
+
+ users[3].active = 0;
+
+ fail_unless(find_available_user() == 3);
+ fail_unless(find_available_user() == -1);
+
+ users[3].last_pkt = 55;
+
+ fail_unless(find_available_user() == 3);
+ fail_unless(find_available_user() == -1);
+}
+END_TEST
+
+START_TEST(test_find_available_user_small_net)
+{
+ in_addr_t ip;
+ int i;
+
+ ip = inet_addr("127.0.0.1");
+ init_users(ip, 29); /* this should result in 5 enabled users */
+
+ for (i = 0; i < 5; i++) {
+ fail_unless(find_available_user() == i);
+ }
+
+ for (i = 0; i < USERS; i++) {
+ fail_unless(find_available_user() == -1);
+ }
+
+ users[3].active = 0;
+
+ fail_unless(find_available_user() == 3);
+ fail_unless(find_available_user() == -1);
+
+ users[3].last_pkt = 55;
+
+ fail_unless(find_available_user() == 3);
+ fail_unless(find_available_user() == -1);
+}
+END_TEST
+
+TCase *
+test_user_create_tests()
+{
+ TCase *tc;
+
+ tc = tcase_create("User");
+ tcase_add_test(tc, test_init_users);
+ tcase_add_test(tc, test_users_waiting);
+ tcase_add_test(tc, test_find_user_by_ip);
+ tcase_add_test(tc, test_all_users_waiting_to_send);
+ tcase_add_test(tc, test_find_available_user);
+ tcase_add_test(tc, test_find_available_user_small_net);
+
+ return tc;
+}