/* $NetBSD: npf_table_test.c,v 1.6 2012/10/29 02:27:11 rmind Exp $ */ /* * NPF tableset test. * * Public Domain. */ #include #include "npf_impl.h" #include "npf_test.h" static const char *ip_list[] = { "192.168.1.1", "10.0.0.1", "192.168.2.1", "10.1.0.1", "192.168.100.253", "10.0.5.1", "192.168.128.127", "10.0.0.2", }; static const uint16_t ip6_list[][8] = { { htons(0xfe80), 0x0, 0x0, 0x0, htons(0x2a0), htons(0xc0ff), htons(0xfe10), htons(0x1234) }, { htons(0xfe80), 0x0, 0x0, 0x0, htons(0x2a0), htons(0xc0ff), 0x00, 0x0 }, { htons(0xfe80), 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { htons(0xfe80), 0x0, 0x0, 0x0, htons(0x2a0), htons(0xc0ff), htons(0xfe10), htons(0x1230) } }; #define HASH_TID 1 #define TREE_TID 2 static bool npf_table_test_fill4(npf_tableset_t *tblset, npf_addr_t *addr) { const int alen = sizeof(struct in_addr); const int nm = NPF_NO_NETMASK; bool fail = false; /* Fill both tables with IP addresses. */ for (unsigned i = 0; i < __arraycount(ip_list); i++) { int error; addr->s6_addr32[0] = inet_addr(ip_list[i]); error = npf_table_insert(tblset, HASH_TID, alen, addr, nm); fail |= !(error == 0); error = npf_table_insert(tblset, HASH_TID, alen, addr, nm); fail |= !(error != 0); error = npf_table_insert(tblset, TREE_TID, alen, addr, nm); fail |= !(error == 0); error = npf_table_insert(tblset, TREE_TID, alen, addr, nm); fail |= !(error != 0); } return fail; } bool npf_table_test(bool verbose) { npf_addr_t addr_storage, *addr = &addr_storage; const int nm = NPF_NO_NETMASK; npf_tableset_t *tblset; npf_table_t *t1, *t2; int error, alen; bool fail = false; u_int i; tblset = npf_tableset_create(); fail |= !(tblset != NULL); /* Table ID 1, using hash table with 256 lists. */ t1 = npf_table_create(HASH_TID, NPF_TABLE_HASH, 256); fail |= !(t1 != NULL); error = npf_tableset_insert(tblset, t1); fail |= !(error == 0); /* Check for double-insert. */ error = npf_tableset_insert(tblset, t1); fail |= !(error != 0); /* Table ID 2, using RB-tree. */ t2 = npf_table_create(TREE_TID, NPF_TABLE_TREE, 0); fail |= !(t2 != NULL); error = npf_tableset_insert(tblset, t2); fail |= !(error == 0); /* Attempt to match non-existing entries - should fail. */ addr->s6_addr32[0] = inet_addr(ip_list[0]); alen = sizeof(struct in_addr); error = npf_table_lookup(tblset, HASH_TID, alen, addr); fail |= !(error != 0); error = npf_table_lookup(tblset, TREE_TID, alen, addr); fail |= !(error != 0); /* Fill both tables with IP addresses. */ fail |= npf_table_test_fill4(tblset, addr); /* Attempt to add duplicates - should fail. */ addr->s6_addr32[0] = inet_addr(ip_list[0]); alen = sizeof(struct in_addr); error = npf_table_insert(tblset, HASH_TID, alen, addr, nm); fail |= !(error != 0); error = npf_table_insert(tblset, TREE_TID, alen, addr, nm); fail |= !(error != 0); /* Match (validate) each IP entry. */ for (i = 0; i < __arraycount(ip_list); i++) { addr->s6_addr32[0] = inet_addr(ip_list[i]); error = npf_table_lookup(tblset, HASH_TID, alen, addr); fail |= !(error == 0); error = npf_table_lookup(tblset, TREE_TID, alen, addr); fail |= !(error == 0); } /* IPv6 addresses. */ memcpy(addr, ip6_list[0], sizeof(ip6_list[0])); alen = sizeof(struct in6_addr); error = npf_table_insert(tblset, HASH_TID, alen, addr, nm); fail |= !(error == 0); error = npf_table_lookup(tblset, HASH_TID, alen, addr); fail |= !(error == 0); error = npf_table_remove(tblset, HASH_TID, alen, addr, nm); fail |= !(error == 0); error = npf_table_insert(tblset, TREE_TID, alen, addr, nm); fail |= !(error == 0); error = npf_table_lookup(tblset, TREE_TID, alen, addr); fail |= !(error == 0); error = npf_table_remove(tblset, TREE_TID, alen, addr, nm); fail |= !(error == 0); /* * Masking: 96, 32, 127. */ memcpy(addr, ip6_list[1], sizeof(ip6_list[1])); error = npf_table_insert(tblset, TREE_TID, alen, addr, 96); fail |= !(error == 0); memcpy(addr, ip6_list[0], sizeof(ip6_list[0])); error = npf_table_lookup(tblset, TREE_TID, alen, addr); fail |= !(error == 0); memcpy(addr, ip6_list[1], sizeof(ip6_list[1])); error = npf_table_remove(tblset, TREE_TID, alen, addr, 96); fail |= !(error == 0); memcpy(addr, ip6_list[2], sizeof(ip6_list[2])); error = npf_table_insert(tblset, TREE_TID, alen, addr, 32); fail |= !(error == 0); memcpy(addr, ip6_list[0], sizeof(ip6_list[0])); error = npf_table_lookup(tblset, TREE_TID, alen, addr); fail |= !(error == 0); memcpy(addr, ip6_list[2], sizeof(ip6_list[2])); error = npf_table_remove(tblset, TREE_TID, alen, addr, 32); fail |= !(error == 0); memcpy(addr, ip6_list[3], sizeof(ip6_list[3])); error = npf_table_insert(tblset, TREE_TID, alen, addr, 126); fail |= !(error == 0); memcpy(addr, ip6_list[0], sizeof(ip6_list[0])); error = npf_table_lookup(tblset, TREE_TID, alen, addr); fail |= !(error != 0); memcpy(addr, ip6_list[3], sizeof(ip6_list[3])); error = npf_table_remove(tblset, TREE_TID, alen, addr, 126); fail |= !(error == 0); alen = sizeof(struct in_addr); /* Remove all IPv4 entries. */ for (i = 0; i < __arraycount(ip_list); i++) { addr->s6_addr32[0] = inet_addr(ip_list[i]); error = npf_table_remove(tblset, HASH_TID, alen, addr, nm); fail |= !(error == 0); error = npf_table_remove(tblset, TREE_TID, alen, addr, nm); fail |= !(error == 0); } npf_tableset_destroy(tblset); return !fail; }