Home | History | Annotate | Line # | Download | only in libnpftest
npf_table_test.c revision 1.1.2.4
      1 /*	$NetBSD: npf_table_test.c,v 1.1.2.4 2014/05/22 11:43:07 yamt Exp $	*/
      2 
      3 /*
      4  * NPF tableset test.
      5  *
      6  * Public Domain.
      7  */
      8 
      9 #include <sys/types.h>
     10 #include <sys/malloc.h>
     11 
     12 #include "npf_impl.h"
     13 #include "npf_test.h"
     14 
     15 static const char *ip_list[] = {
     16 	"192.168.1.1",
     17 	"10.0.0.1",
     18 	"192.168.2.1",
     19 	"10.1.0.1",
     20 	"192.168.100.253",
     21 	"10.0.5.1",
     22 	"192.168.128.127",
     23 	"10.0.0.2",
     24 };
     25 
     26 static const uint16_t ip6_list[][8] = {
     27 	{
     28 	    htons(0xfe80), 0x0, 0x0, 0x0,
     29 	    htons(0x2a0), htons(0xc0ff), htons(0xfe10), htons(0x1234)
     30 	},
     31 	{
     32 	    htons(0xfe80), 0x0, 0x0, 0x0,
     33 	    htons(0x2a0), htons(0xc0ff), 0x00, 0x0
     34 	},
     35 	{
     36 	    htons(0xfe80), 0x0, 0x0, 0x0,
     37 	    0x0, 0x0, 0x0, 0x0
     38 	},
     39 	{
     40 	    htons(0xfe80), 0x0, 0x0, 0x0,
     41 	    htons(0x2a0), htons(0xc0ff), htons(0xfe10), htons(0x1230)
     42 	}
     43 };
     44 
     45 #define	HASH_TID		"hash-table"
     46 #define	TREE_TID		"tree-table"
     47 #define	CDB_TID			"cdb-table"
     48 
     49 static bool
     50 npf_table_test_fill4(npf_tableset_t *tblset, npf_addr_t *addr)
     51 {
     52 	const int alen = sizeof(struct in_addr);
     53 	const int nm = NPF_NO_NETMASK;
     54 	bool fail = false;
     55 
     56 	/* Fill both tables with IP addresses. */
     57 	for (unsigned i = 0; i < __arraycount(ip_list); i++) {
     58 		npf_table_t *t;
     59 		int error;
     60 
     61 		addr->s6_addr32[0] = inet_addr(ip_list[i]);
     62 
     63 		t = npf_tableset_getbyname(tblset, HASH_TID);
     64 		error = npf_table_insert(t, alen, addr, nm);
     65 		fail |= !(error == 0);
     66 		error = npf_table_insert(t, alen, addr, nm);
     67 		fail |= !(error != 0);
     68 
     69 		t = npf_tableset_getbyname(tblset, TREE_TID);
     70 		error = npf_table_insert(t, alen, addr, nm);
     71 		fail |= !(error == 0);
     72 		error = npf_table_insert(t, alen, addr, nm);
     73 		fail |= !(error != 0);
     74 	}
     75 	return fail;
     76 }
     77 
     78 bool
     79 npf_table_test(bool verbose, void *blob, size_t size)
     80 {
     81 	npf_addr_t addr_storage, *addr = &addr_storage;
     82 	const int nm = NPF_NO_NETMASK;
     83 	npf_table_t *t, *t1, *t2, *t3;
     84 	npf_tableset_t *tblset;
     85 	int error, alen;
     86 	bool fail = false;
     87 	void *cdb;
     88 	u_int i;
     89 
     90 	tblset = npf_tableset_create(3);
     91 	fail |= !(tblset != NULL);
     92 
     93 	/* Table ID 1, using hash table with 256 lists. */
     94 	t1 = npf_table_create(HASH_TID, 0, NPF_TABLE_HASH, NULL, 256);
     95 	fail |= !(t1 != NULL);
     96 	error = npf_tableset_insert(tblset, t1);
     97 	fail |= !(error == 0);
     98 
     99 	/* Check for double-insert. */
    100 	error = npf_tableset_insert(tblset, t1);
    101 	fail |= !(error != 0);
    102 
    103 	/* Table ID 2, using a prefix tree. */
    104 	t2 = npf_table_create(TREE_TID, 1, NPF_TABLE_TREE, NULL, 0);
    105 	fail |= !(t2 != NULL);
    106 	error = npf_tableset_insert(tblset, t2);
    107 	fail |= !(error == 0);
    108 
    109 	/* Table ID 3, using a CDB. */
    110 	cdb = malloc(size, M_TEMP, M_WAITOK);
    111 	memcpy(cdb, blob, size);
    112 
    113 	t3 = npf_table_create(CDB_TID, 2, NPF_TABLE_CDB, cdb, size);
    114 	fail |= !(t3 != NULL);
    115 	error = npf_tableset_insert(tblset, t3);
    116 	fail |= !(error == 0);
    117 
    118 	/* Attempt to match non-existing entries - should fail. */
    119 	addr->s6_addr32[0] = inet_addr(ip_list[0]);
    120 	alen = sizeof(struct in_addr);
    121 
    122 	t = npf_tableset_getbyname(tblset, HASH_TID);
    123 	error = npf_table_lookup(t, alen, addr);
    124 	fail |= !(error != 0);
    125 
    126 	t = npf_tableset_getbyname(tblset, TREE_TID);
    127 	error = npf_table_lookup(t, alen, addr);
    128 	fail |= !(error != 0);
    129 
    130 	/* Fill both tables with IP addresses. */
    131 	fail |= npf_table_test_fill4(tblset, addr);
    132 
    133 	/* Attempt to add duplicates - should fail. */
    134 	addr->s6_addr32[0] = inet_addr(ip_list[0]);
    135 	alen = sizeof(struct in_addr);
    136 
    137 	t = npf_tableset_getbyname(tblset, HASH_TID);
    138 	error = npf_table_insert(t, alen, addr, nm);
    139 	fail |= !(error != 0);
    140 
    141 	t = npf_tableset_getbyname(tblset, TREE_TID);
    142 	error = npf_table_insert(t, alen, addr, nm);
    143 	fail |= !(error != 0);
    144 
    145 	/* Match (validate) each IP entry. */
    146 	for (i = 0; i < __arraycount(ip_list); i++) {
    147 		addr->s6_addr32[0] = inet_addr(ip_list[i]);
    148 
    149 		t = npf_tableset_getbyname(tblset, HASH_TID);
    150 		error = npf_table_lookup(t, alen, addr);
    151 		fail |= !(error == 0);
    152 
    153 		t = npf_tableset_getbyname(tblset, TREE_TID);
    154 		error = npf_table_lookup(t, alen, addr);
    155 		fail |= !(error == 0);
    156 	}
    157 
    158 	/* IPv6 addresses. */
    159 	memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
    160 	alen = sizeof(struct in6_addr);
    161 
    162 	t = npf_tableset_getbyname(tblset, HASH_TID);
    163 	error = npf_table_insert(t, alen, addr, nm);
    164 	fail |= !(error == 0);
    165 	error = npf_table_lookup(t, alen, addr);
    166 	fail |= !(error == 0);
    167 	error = npf_table_remove(t, alen, addr, nm);
    168 	fail |= !(error == 0);
    169 
    170 	t = npf_tableset_getbyname(tblset, TREE_TID);
    171 	error = npf_table_insert(t, alen, addr, nm);
    172 	fail |= !(error == 0);
    173 	error = npf_table_lookup(t, alen, addr);
    174 	fail |= !(error == 0);
    175 	error = npf_table_remove(t, alen, addr, nm);
    176 	fail |= !(error == 0);
    177 
    178 	/*
    179 	 * Masking: 96, 32, 127.
    180 	 */
    181 
    182 	memcpy(addr, ip6_list[1], sizeof(ip6_list[1]));
    183 	error = npf_table_insert(t, alen, addr, 96);
    184 	fail |= !(error == 0);
    185 
    186 	memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
    187 	error = npf_table_lookup(t, alen, addr);
    188 	fail |= !(error == 0);
    189 
    190 	memcpy(addr, ip6_list[1], sizeof(ip6_list[1]));
    191 	error = npf_table_remove(t, alen, addr, 96);
    192 	fail |= !(error == 0);
    193 
    194 
    195 	memcpy(addr, ip6_list[2], sizeof(ip6_list[2]));
    196 	error = npf_table_insert(t, alen, addr, 32);
    197 	fail |= !(error == 0);
    198 
    199 	memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
    200 	error = npf_table_lookup(t, alen, addr);
    201 	fail |= !(error == 0);
    202 
    203 	memcpy(addr, ip6_list[2], sizeof(ip6_list[2]));
    204 	error = npf_table_remove(t, alen, addr, 32);
    205 	fail |= !(error == 0);
    206 
    207 
    208 	memcpy(addr, ip6_list[3], sizeof(ip6_list[3]));
    209 	error = npf_table_insert(t, alen, addr, 126);
    210 	fail |= !(error == 0);
    211 
    212 	memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
    213 	error = npf_table_lookup(t, alen, addr);
    214 	fail |= !(error != 0);
    215 
    216 	memcpy(addr, ip6_list[3], sizeof(ip6_list[3]));
    217 	error = npf_table_remove(t, alen, addr, 126);
    218 	fail |= !(error == 0);
    219 
    220 
    221 	alen = sizeof(struct in_addr);
    222 
    223 	/* Remove all IPv4 entries. */
    224 	for (i = 0; i < __arraycount(ip_list); i++) {
    225 		addr->s6_addr32[0] = inet_addr(ip_list[i]);
    226 
    227 		t = npf_tableset_getbyname(tblset, HASH_TID);
    228 		error = npf_table_remove(t, alen, addr, nm);
    229 		fail |= !(error == 0);
    230 
    231 		t = npf_tableset_getbyname(tblset, TREE_TID);
    232 		error = npf_table_remove(t, alen, addr, nm);
    233 		fail |= !(error == 0);
    234 	}
    235 
    236 	/* Test CDB. */
    237 	addr->s6_addr32[0] = inet_addr(ip_list[0]);
    238 	alen = sizeof(struct in_addr);
    239 	error = npf_table_lookup(t3, alen, addr);
    240 	fail |= !(error == 0);
    241 
    242 	for (i = 1; i < __arraycount(ip_list) - 1; i++) {
    243 		addr->s6_addr32[0] = inet_addr(ip_list[i]);
    244 		alen = sizeof(struct in_addr);
    245 		error = npf_table_lookup(t3, alen, addr);
    246 		fail |= !(error != 0);
    247 	}
    248 
    249 	npf_tableset_destroy(tblset);
    250 
    251 	return !fail;
    252 }
    253