1 /* $NetBSD: npf_table_test.c,v 1.7 2013/11/12 00:46:34 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 "hash-table" 45 #define TREE_TID "tree-table" 46 47 static bool 48 npf_table_test_fill4(npf_tableset_t *tblset, npf_addr_t *addr) 49 { 50 const int alen = sizeof(struct in_addr); 51 const int nm = NPF_NO_NETMASK; 52 bool fail = false; 53 54 /* Fill both tables with IP addresses. */ 55 for (unsigned i = 0; i < __arraycount(ip_list); i++) { 56 npf_table_t *t; 57 int error; 58 59 addr->s6_addr32[0] = inet_addr(ip_list[i]); 60 61 t = npf_tableset_getbyname(tblset, HASH_TID); 62 error = npf_table_insert(t, alen, addr, nm); 63 fail |= !(error == 0); 64 error = npf_table_insert(t, alen, addr, nm); 65 fail |= !(error != 0); 66 67 t = npf_tableset_getbyname(tblset, TREE_TID); 68 error = npf_table_insert(t, alen, addr, nm); 69 fail |= !(error == 0); 70 error = npf_table_insert(t, alen, addr, nm); 71 fail |= !(error != 0); 72 } 73 return fail; 74 } 75 76 bool 77 npf_table_test(bool verbose) 78 { 79 npf_addr_t addr_storage, *addr = &addr_storage; 80 const int nm = NPF_NO_NETMASK; 81 npf_tableset_t *tblset; 82 npf_table_t *t, *t1, *t2; 83 int error, alen; 84 bool fail = false; 85 u_int i; 86 87 tblset = npf_tableset_create(2); 88 fail |= !(tblset != NULL); 89 90 /* Table ID 1, using hash table with 256 lists. */ 91 t1 = npf_table_create(HASH_TID, 0, NPF_TABLE_HASH, 256); 92 fail |= !(t1 != NULL); 93 error = npf_tableset_insert(tblset, t1); 94 fail |= !(error == 0); 95 96 /* Check for double-insert. */ 97 error = npf_tableset_insert(tblset, t1); 98 fail |= !(error != 0); 99 100 /* Table ID 2, using a prefix tree. */ 101 t2 = npf_table_create(TREE_TID, 1, NPF_TABLE_TREE, 0); 102 fail |= !(t2 != NULL); 103 error = npf_tableset_insert(tblset, t2); 104 fail |= !(error == 0); 105 106 /* Attempt to match non-existing entries - should fail. */ 107 addr->s6_addr32[0] = inet_addr(ip_list[0]); 108 alen = sizeof(struct in_addr); 109 110 t = npf_tableset_getbyname(tblset, HASH_TID); 111 error = npf_table_lookup(t, alen, addr); 112 fail |= !(error != 0); 113 114 t = npf_tableset_getbyname(tblset, TREE_TID); 115 error = npf_table_lookup(t, alen, addr); 116 fail |= !(error != 0); 117 118 /* Fill both tables with IP addresses. */ 119 fail |= npf_table_test_fill4(tblset, addr); 120 121 /* Attempt to add duplicates - should fail. */ 122 addr->s6_addr32[0] = inet_addr(ip_list[0]); 123 alen = sizeof(struct in_addr); 124 125 t = npf_tableset_getbyname(tblset, HASH_TID); 126 error = npf_table_insert(t, alen, addr, nm); 127 fail |= !(error != 0); 128 129 t = npf_tableset_getbyname(tblset, TREE_TID); 130 error = npf_table_insert(t, alen, addr, nm); 131 fail |= !(error != 0); 132 133 /* Match (validate) each IP entry. */ 134 for (i = 0; i < __arraycount(ip_list); i++) { 135 addr->s6_addr32[0] = inet_addr(ip_list[i]); 136 137 t = npf_tableset_getbyname(tblset, HASH_TID); 138 error = npf_table_lookup(t, alen, addr); 139 fail |= !(error == 0); 140 141 t = npf_tableset_getbyname(tblset, TREE_TID); 142 error = npf_table_lookup(t, alen, addr); 143 fail |= !(error == 0); 144 } 145 146 /* IPv6 addresses. */ 147 memcpy(addr, ip6_list[0], sizeof(ip6_list[0])); 148 alen = sizeof(struct in6_addr); 149 150 t = npf_tableset_getbyname(tblset, HASH_TID); 151 error = npf_table_insert(t, alen, addr, nm); 152 fail |= !(error == 0); 153 error = npf_table_lookup(t, alen, addr); 154 fail |= !(error == 0); 155 error = npf_table_remove(t, alen, addr, nm); 156 fail |= !(error == 0); 157 158 t = npf_tableset_getbyname(tblset, TREE_TID); 159 error = npf_table_insert(t, alen, addr, nm); 160 fail |= !(error == 0); 161 error = npf_table_lookup(t, alen, addr); 162 fail |= !(error == 0); 163 error = npf_table_remove(t, alen, addr, nm); 164 fail |= !(error == 0); 165 166 /* 167 * Masking: 96, 32, 127. 168 */ 169 170 memcpy(addr, ip6_list[1], sizeof(ip6_list[1])); 171 error = npf_table_insert(t, alen, addr, 96); 172 fail |= !(error == 0); 173 174 memcpy(addr, ip6_list[0], sizeof(ip6_list[0])); 175 error = npf_table_lookup(t, alen, addr); 176 fail |= !(error == 0); 177 178 memcpy(addr, ip6_list[1], sizeof(ip6_list[1])); 179 error = npf_table_remove(t, alen, addr, 96); 180 fail |= !(error == 0); 181 182 183 memcpy(addr, ip6_list[2], sizeof(ip6_list[2])); 184 error = npf_table_insert(t, alen, addr, 32); 185 fail |= !(error == 0); 186 187 memcpy(addr, ip6_list[0], sizeof(ip6_list[0])); 188 error = npf_table_lookup(t, alen, addr); 189 fail |= !(error == 0); 190 191 memcpy(addr, ip6_list[2], sizeof(ip6_list[2])); 192 error = npf_table_remove(t, alen, addr, 32); 193 fail |= !(error == 0); 194 195 196 memcpy(addr, ip6_list[3], sizeof(ip6_list[3])); 197 error = npf_table_insert(t, alen, addr, 126); 198 fail |= !(error == 0); 199 200 memcpy(addr, ip6_list[0], sizeof(ip6_list[0])); 201 error = npf_table_lookup(t, alen, addr); 202 fail |= !(error != 0); 203 204 memcpy(addr, ip6_list[3], sizeof(ip6_list[3])); 205 error = npf_table_remove(t, alen, addr, 126); 206 fail |= !(error == 0); 207 208 209 alen = sizeof(struct in_addr); 210 211 /* Remove all IPv4 entries. */ 212 for (i = 0; i < __arraycount(ip_list); i++) { 213 addr->s6_addr32[0] = inet_addr(ip_list[i]); 214 215 t = npf_tableset_getbyname(tblset, HASH_TID); 216 error = npf_table_remove(t, alen, addr, nm); 217 fail |= !(error == 0); 218 219 t = npf_tableset_getbyname(tblset, TREE_TID); 220 error = npf_table_remove(t, alen, addr, nm); 221 fail |= !(error == 0); 222 } 223 224 npf_tableset_destroy(tblset); 225 226 return !fail; 227 } 228