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