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