1 /* $NetBSD: npf_table_test.c,v 1.8 2014/02/06 02:51:28 rmind 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