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