1 /* 2 * Run this after adding a new attribute to the nf_conntrack object 3 */ 4 5 #include <assert.h> 6 #include <stdio.h> 7 #include <stdbool.h> 8 #include <stdlib.h> 9 #include <unistd.h> 10 #include <string.h> 11 #include <sys/wait.h> 12 #include <time.h> 13 #include <errno.h> 14 15 #include <libnetfilter_conntrack/libnetfilter_conntrack.h> 16 17 /* 18 * this file contains a test to check the set/get/copy/cmp APIs. 19 */ 20 21 static void eval_sigterm(int status) 22 { 23 switch(WTERMSIG(status)) { 24 case SIGSEGV: 25 printf("received SIGSEV\n"); 26 break; 27 case 0: 28 printf("OK\n"); 29 break; 30 default: 31 printf("exited with signal: %d\n", WTERMSIG(status)); 32 break; 33 } 34 } 35 36 static void test_nfct_bitmask(void) 37 { 38 struct nfct_bitmask *a, *b; 39 unsigned short int maxb, i; 40 struct nf_conntrack *ct1, *ct2; 41 42 printf("== test nfct_bitmask_* API ==\n"); 43 44 maxb = rand() & 0xffff; 45 46 a = nfct_bitmask_new(maxb); 47 48 assert(!nfct_bitmask_test_bit(a, maxb + 32)); 49 nfct_bitmask_set_bit(a, maxb + 32); 50 assert(!nfct_bitmask_test_bit(a, maxb + 32)); 51 52 for (i = 0; i <= maxb; i++) 53 assert(!nfct_bitmask_test_bit(a, i)); 54 55 for (i = 0; i <= maxb; i++) { 56 if (rand() & 1) { 57 assert(!nfct_bitmask_test_bit(a, i)); 58 continue; 59 } 60 nfct_bitmask_set_bit(a, i); 61 assert(nfct_bitmask_test_bit(a, i)); 62 } 63 64 b = nfct_bitmask_clone(a); 65 assert(b); 66 67 for (i = 0; i <= maxb; i++) { 68 if (nfct_bitmask_test_bit(a, i)) 69 assert(nfct_bitmask_test_bit(b, i)); 70 else 71 assert(!nfct_bitmask_test_bit(b, i)); 72 } 73 74 nfct_bitmask_destroy(a); 75 76 for (i = 0; i <= maxb; i++) { 77 if (rand() & 1) 78 continue; 79 nfct_bitmask_unset_bit(b, i); 80 assert(!nfct_bitmask_test_bit(b, i)); 81 } 82 83 /* nfct_bitmask_clear() */ 84 for (i = 0; i < maxb; i++) { 85 nfct_bitmask_set_bit(b, i); 86 assert(nfct_bitmask_test_bit(b, i)); 87 nfct_bitmask_clear(b); 88 assert(!nfct_bitmask_test_bit(b, i)); 89 } 90 91 for (i = 0; i < maxb; i++) 92 nfct_bitmask_set_bit(b, i); 93 nfct_bitmask_clear(b); 94 for (i = 0; i < maxb; i++) 95 assert(!nfct_bitmask_test_bit(b, i)); 96 97 /* nfct_bitmask_equal() */ 98 for (i = 0; i < maxb / 32 * 32; i += 32) { 99 a = nfct_bitmask_new(i); 100 assert(!nfct_bitmask_equal(a, b)); 101 nfct_bitmask_destroy(a); 102 } 103 104 a = nfct_bitmask_clone(b); 105 assert(nfct_bitmask_equal(a, b)); 106 for (i = 0; i < maxb; i++) { 107 if (nfct_bitmask_test_bit(a, i)) { 108 nfct_bitmask_unset_bit(a, i); 109 assert(!nfct_bitmask_equal(a, b)); 110 nfct_bitmask_set_bit(a, i); 111 } else { 112 nfct_bitmask_set_bit(a, i); 113 assert(!nfct_bitmask_equal(a, b)); 114 nfct_bitmask_unset_bit(a, i); 115 } 116 assert(nfct_bitmask_equal(a, b)); 117 } 118 119 nfct_bitmask_destroy(a); 120 nfct_bitmask_destroy(b); 121 122 ct1 = nfct_new(); 123 ct2 = nfct_new(); 124 125 maxb = rand() & 0xff; 126 maxb += 128; 127 maxb /= 2; 128 a = nfct_bitmask_new(maxb * 2); 129 b = nfct_bitmask_new(maxb); 130 nfct_set_attr(ct1, ATTR_CONNLABELS, a); 131 nfct_set_attr(ct2, ATTR_CONNLABELS, b); 132 133 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL) == 1); 134 135 nfct_bitmask_set_bit(a, maxb); 136 nfct_bitmask_set_bit(b, maxb); 137 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL) == 1); 138 139 nfct_bitmask_set_bit(a, maxb * 2); 140 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL) == 0); 141 nfct_destroy(ct1); 142 nfct_destroy(ct2); 143 printf("OK\n"); 144 } 145 146 /* These attributes cannot be set, ignore them. */ 147 static int attr_is_readonly(int attr) 148 { 149 switch (attr) { 150 case ATTR_ORIG_COUNTER_PACKETS: 151 case ATTR_REPL_COUNTER_PACKETS: 152 case ATTR_ORIG_COUNTER_BYTES: 153 case ATTR_REPL_COUNTER_BYTES: 154 case ATTR_USE: 155 case ATTR_SECCTX: 156 case ATTR_TIMESTAMP_START: 157 case ATTR_TIMESTAMP_STOP: 158 return 1; 159 } 160 return 0; 161 } 162 163 164 static int test_nfct_cmp_api_single(struct nf_conntrack *ct1, 165 struct nf_conntrack *ct2, int attr) 166 { 167 char data[256]; 168 struct nfct_bitmask *b; 169 int bit; 170 171 if (attr_is_readonly(attr)) 172 return 0; 173 174 switch (attr) { 175 case ATTR_SECMARK: /* obsolete */ 176 return 0; 177 178 /* FIXME: not implemented comparators: */ 179 case ATTR_SNAT_IPV4: 180 case ATTR_DNAT_IPV4: 181 case ATTR_SNAT_IPV6: 182 case ATTR_DNAT_IPV6: 183 case ATTR_SNAT_PORT: 184 case ATTR_DNAT_PORT: 185 186 case ATTR_TCP_FLAGS_ORIG: 187 case ATTR_TCP_FLAGS_REPL: 188 case ATTR_TCP_MASK_ORIG: 189 case ATTR_TCP_MASK_REPL: 190 191 case ATTR_MASTER_IPV4_SRC: 192 case ATTR_MASTER_IPV4_DST: 193 case ATTR_MASTER_IPV6_SRC: 194 case ATTR_MASTER_IPV6_DST: 195 case ATTR_MASTER_PORT_SRC: 196 case ATTR_MASTER_PORT_DST: 197 case ATTR_MASTER_L3PROTO: 198 case ATTR_MASTER_L4PROTO: 199 200 case ATTR_ORIG_NAT_SEQ_CORRECTION_POS: 201 case ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE: 202 case ATTR_ORIG_NAT_SEQ_OFFSET_AFTER: 203 case ATTR_REPL_NAT_SEQ_CORRECTION_POS: 204 case ATTR_REPL_NAT_SEQ_OFFSET_BEFORE: 205 case ATTR_REPL_NAT_SEQ_OFFSET_AFTER: 206 207 case ATTR_SCTP_VTAG_ORIG: 208 case ATTR_SCTP_VTAG_REPL: 209 210 case ATTR_HELPER_NAME: 211 212 case ATTR_DCCP_ROLE: 213 case ATTR_DCCP_HANDSHAKE_SEQ: 214 215 case ATTR_TCP_WSCALE_ORIG: 216 case ATTR_TCP_WSCALE_REPL: 217 218 case ATTR_HELPER_INFO: 219 return 0; /* XXX */ 220 221 default: 222 break; 223 } 224 225 if (attr >= ATTR_SCTP_STATE) { 226 nfct_set_attr_u8(ct1, ATTR_REPL_L4PROTO, IPPROTO_SCTP); 227 nfct_set_attr_u8(ct1, ATTR_L4PROTO, IPPROTO_SCTP); 228 } else if (attr >= ATTR_TCP_FLAGS_ORIG) { 229 nfct_set_attr_u8(ct1, ATTR_REPL_L4PROTO, IPPROTO_TCP); 230 nfct_set_attr_u8(ct1, ATTR_L4PROTO, IPPROTO_TCP); 231 } else if (attr >= ATTR_ICMP_CODE) { 232 nfct_set_attr_u8(ct1, ATTR_REPL_L4PROTO, IPPROTO_ICMP); 233 nfct_set_attr_u8(ct1, ATTR_L4PROTO, IPPROTO_ICMP); 234 } else if (attr >= ATTR_ORIG_PORT_SRC) { 235 nfct_set_attr_u8(ct1, ATTR_REPL_L4PROTO, IPPROTO_TCP); 236 nfct_set_attr_u8(ct1, ATTR_L4PROTO, IPPROTO_TCP); 237 } 238 239 nfct_copy(ct2, ct1, NFCT_CP_OVERRIDE); 240 memset(data, 42, sizeof(data)); 241 242 assert(nfct_attr_is_set(ct1, attr)); 243 assert(nfct_attr_is_set(ct2, attr)); 244 245 switch (attr) { 246 case ATTR_CONNLABELS: 247 case ATTR_CONNLABELS_MASK: 248 b = (void *) nfct_get_attr(ct1, attr); 249 assert(b); 250 b = nfct_bitmask_clone(b); 251 assert(b); 252 bit = nfct_bitmask_maxbit(b); 253 if (nfct_bitmask_test_bit(b, bit)) { 254 nfct_bitmask_unset_bit(b, bit); 255 assert(!nfct_bitmask_test_bit(b, bit)); 256 } else { 257 nfct_bitmask_set_bit(b, bit); 258 assert(nfct_bitmask_test_bit(b, bit)); 259 } 260 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL) == 1); 261 nfct_set_attr(ct2, attr, b); 262 break; 263 case ATTR_HELPER_INFO: 264 nfct_set_attr_l(ct2, attr, "test", 4); 265 break; 266 default: 267 nfct_set_attr(ct2, attr, data); 268 break; 269 } 270 271 if (nfct_cmp(ct1, ct2, NFCT_CMP_ALL) != 0) { 272 fprintf(stderr, "nfct_cmp assert failure for attr %d\n", attr); 273 fprintf(stderr, "%p, %p, %x, %x\n", nfct_get_attr(ct1, attr), 274 nfct_get_attr(ct2, attr), 275 nfct_get_attr_u32(ct1, attr), nfct_get_attr_u32(ct2, attr)); 276 return -1; 277 } 278 if (nfct_cmp(ct1, ct2, NFCT_CMP_ALL|NFCT_CMP_STRICT) != 0) { 279 fprintf(stderr, "nfct_cmp strict assert failure for attr %d\n", attr); 280 return -1; 281 } 282 return 0; 283 } 284 285 static int test_cmp_attr32(int attr, bool at1, bool at2, 286 uint32_t v1, uint32_t v2, unsigned int flags) 287 { 288 struct nf_conntrack *ct1 = nfct_new(); 289 struct nf_conntrack *ct2 = nfct_new(); 290 int ret; 291 292 if (at1) 293 nfct_set_attr_u32(ct1, attr, v1); 294 if (at2) 295 nfct_set_attr_u32(ct2, attr, v2); 296 297 ret = nfct_cmp(ct1, ct2, NFCT_CMP_ALL | flags); 298 299 nfct_destroy(ct1); 300 nfct_destroy(ct2); 301 302 return ret; 303 } 304 305 static void test_nfct_cmp_attr(int attr) 306 { 307 unsigned int flags = 0; 308 309 /* 0000, 1000, 1100, 0010, 1010... */ 310 /* attr at1 at2 v1 v2 */ 311 assert(test_cmp_attr32(attr, false, false, 0, 0, flags) == 1); 312 assert(test_cmp_attr32(attr, true, false, 0, 0, flags) == 1); 313 assert(test_cmp_attr32(attr, false, true, 0, 0, flags) == 1); 314 assert(test_cmp_attr32(attr, true, true, 0, 0, flags) == 1); 315 assert(test_cmp_attr32(attr, false, false, 1, 0, flags) == 1); /* verbose */ 316 assert(test_cmp_attr32(attr, true, false, 1, 0, flags) == 1); 317 assert(test_cmp_attr32(attr, false, true, 1, 0, flags) == 1); /* verbose */ 318 assert(test_cmp_attr32(attr, true, true, 1, 0, flags) == 0); 319 assert(test_cmp_attr32(attr, false, false, 0, 1, flags) == 1); /* verbose */ 320 assert(test_cmp_attr32(attr, true, false, 0, 1, flags) == 1); /* verbose */ 321 assert(test_cmp_attr32(attr, false, true, 0, 1, flags) == 1); 322 assert(test_cmp_attr32(attr, true, true, 0, 1, flags) == 0); 323 assert(test_cmp_attr32(attr, false, false, 1, 1, flags) == 1); /* verbose */ 324 assert(test_cmp_attr32(attr, true, false, 1, 1, flags) == 1); /* verbose */ 325 assert(test_cmp_attr32(attr, false, true, 1, 1, flags) == 1); /* verbose */ 326 assert(test_cmp_attr32(attr, true, true, 1, 1, flags) == 1); 327 328 flags = NFCT_CMP_STRICT; 329 assert(test_cmp_attr32(attr, false, false, 0, 0, flags) == 1); 330 assert(test_cmp_attr32(attr, true, false, 0, 0, flags) == 1); 331 assert(test_cmp_attr32(attr, false, true, 0, 0, flags) == 1); 332 assert(test_cmp_attr32(attr, true, true, 0, 0, flags) == 1); 333 assert(test_cmp_attr32(attr, false, false, 1, 0, flags) == 1); /* verbose */ 334 assert(test_cmp_attr32(attr, true, false, 1, 0, flags) == 0); 335 assert(test_cmp_attr32(attr, false, true, 1, 0, flags) == 1); /* verbose */ 336 assert(test_cmp_attr32(attr, true, true, 1, 0, flags) == 0); 337 assert(test_cmp_attr32(attr, false, false, 0, 1, flags) == 1); /* verbose */ 338 assert(test_cmp_attr32(attr, true, false, 0, 1, flags) == 1); /* verbose */ 339 assert(test_cmp_attr32(attr, false, true, 0, 1, flags) == 0); 340 assert(test_cmp_attr32(attr, true, true, 0, 1, flags) == 0); 341 assert(test_cmp_attr32(attr, false, false, 1, 1, flags) == 1); /* verbose */ 342 assert(test_cmp_attr32(attr, true, false, 1, 1, flags) == 0); /* verbose */ 343 assert(test_cmp_attr32(attr, false, true, 1, 1, flags) == 0); /* verbose */ 344 assert(test_cmp_attr32(attr, true, true, 1, 1, flags) == 1); 345 346 flags = NFCT_CMP_MASK; 347 assert(test_cmp_attr32(attr, false, false, 0, 0, flags) == 1); 348 assert(test_cmp_attr32(attr, true, false, 0, 0, flags) == 1); 349 assert(test_cmp_attr32(attr, false, true, 0, 0, flags) == 1); 350 assert(test_cmp_attr32(attr, true, true, 0, 0, flags) == 1); 351 assert(test_cmp_attr32(attr, false, false, 1, 0, flags) == 1); /* verbose */ 352 assert(test_cmp_attr32(attr, true, false, 1, 0, flags) == 0); 353 assert(test_cmp_attr32(attr, false, true, 1, 0, flags) == 1); /* verbose */ 354 assert(test_cmp_attr32(attr, true, true, 1, 0, flags) == 0); 355 assert(test_cmp_attr32(attr, false, false, 0, 1, flags) == 1); /* verbose */ 356 assert(test_cmp_attr32(attr, true, false, 0, 1, flags) == 1); /* verbose */ 357 assert(test_cmp_attr32(attr, false, true, 0, 1, flags) == 1); 358 assert(test_cmp_attr32(attr, true, true, 0, 1, flags) == 0); 359 assert(test_cmp_attr32(attr, false, false, 1, 1, flags) == 1); /* verbose */ 360 assert(test_cmp_attr32(attr, true, false, 1, 1, flags) == 0); /* verbose */ 361 assert(test_cmp_attr32(attr, false, true, 1, 1, flags) == 1); /* verbose */ 362 assert(test_cmp_attr32(attr, true, true, 1, 1, flags) == 1); 363 364 flags = NFCT_CMP_STRICT|NFCT_CMP_MASK; 365 assert(test_cmp_attr32(attr, false, false, 0, 0, flags) == 1); 366 assert(test_cmp_attr32(attr, true, false, 0, 0, flags) == 1); 367 assert(test_cmp_attr32(attr, false, true, 0, 0, flags) == 1); 368 assert(test_cmp_attr32(attr, true, true, 0, 0, flags) == 1); 369 assert(test_cmp_attr32(attr, false, false, 1, 0, flags) == 1); /* verbose */ 370 assert(test_cmp_attr32(attr, true, false, 1, 0, flags) == 0); 371 assert(test_cmp_attr32(attr, false, true, 1, 0, flags) == 1); /* verbose */ 372 assert(test_cmp_attr32(attr, true, true, 1, 0, flags) == 0); 373 assert(test_cmp_attr32(attr, false, false, 0, 1, flags) == 1); /* verbose */ 374 assert(test_cmp_attr32(attr, true, false, 0, 1, flags) == 1); /* verbose */ 375 assert(test_cmp_attr32(attr, false, true, 0, 1, flags) == 0); 376 assert(test_cmp_attr32(attr, true, true, 0, 1, flags) == 0); 377 assert(test_cmp_attr32(attr, false, false, 1, 1, flags) == 1); /* verbose */ 378 assert(test_cmp_attr32(attr, true, false, 1, 1, flags) == 0); /* verbose */ 379 assert(test_cmp_attr32(attr, false, true, 1, 1, flags) == 0); /* verbose */ 380 assert(test_cmp_attr32(attr, true, true, 1, 1, flags) == 1); 381 } 382 383 static void test_nfct_cmp_api(struct nf_conntrack *ct1, struct nf_conntrack *ct2) 384 { 385 int i; 386 387 printf("== test cmp API ==\n"); 388 389 test_nfct_cmp_attr(ATTR_ZONE); 390 test_nfct_cmp_attr(ATTR_ORIG_ZONE); 391 test_nfct_cmp_attr(ATTR_REPL_ZONE); 392 test_nfct_cmp_attr(ATTR_MARK); 393 394 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL) == 1); 395 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL|NFCT_CMP_STRICT) == 0); 396 397 nfct_copy(ct1, ct2, NFCT_CP_OVERRIDE); 398 399 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL) == 1); 400 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL|NFCT_CMP_STRICT) == 1); 401 402 for (i=0; i < ATTR_MAX ; i++) { 403 nfct_attr_unset(ct1, i); 404 405 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL) == 1); 406 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL|NFCT_CMP_STRICT) == 0); 407 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL|NFCT_CMP_MASK) == 1); 408 } 409 nfct_copy(ct1, ct2, NFCT_CP_OVERRIDE); 410 for (i=0; i < ATTR_MAX ; i++) { 411 nfct_attr_unset(ct2, i); 412 413 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL) == 1); 414 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL|NFCT_CMP_STRICT) == 0); 415 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL|NFCT_CMP_MASK) == 0); 416 } 417 418 for (i=0; i < ATTR_MAX ; i++) 419 assert(test_nfct_cmp_api_single(ct1, ct2, i) == 0); 420 421 nfct_copy(ct2, ct1, NFCT_CP_OVERRIDE); 422 for (i=0; i < ATTR_MAX ; i++) { 423 nfct_attr_unset(ct1, i); 424 nfct_attr_unset(ct2, i); 425 426 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL) == 1); 427 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL|NFCT_CMP_STRICT) == 1); 428 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL|NFCT_CMP_MASK) == 1); 429 } 430 nfct_destroy(ct1); 431 nfct_destroy(ct2); 432 } 433 434 static void test_nfexp_cmp_api(struct nf_expect *ex1, struct nf_expect *ex2) 435 { 436 int i; 437 438 printf("== test expect cmp API ==\n"); 439 440 /* XXX: missing nfexp_copy API. */ 441 memcpy(ex1, ex2, nfexp_maxsize()); 442 443 assert(nfexp_cmp(ex1, ex2, 0) == 1); 444 assert(nfexp_cmp(ex1, ex2, NFCT_CMP_STRICT) == 1); 445 446 assert(nfexp_attr_is_set(ex1, 0) == 1); 447 nfexp_attr_unset(ex1, 0); 448 assert(nfexp_attr_is_set(ex1, 0) == 0); 449 450 memcpy(ex1, ex2, nfexp_maxsize()); 451 for (i=0; i < ATTR_EXP_MAX; i++) { 452 nfexp_attr_unset(ex1, i); 453 454 assert(nfexp_cmp(ex1, ex2, 0) == 1); 455 assert(nfexp_cmp(ex1, ex2, NFCT_CMP_STRICT) == 0); 456 assert(nfexp_cmp(ex1, ex2, NFCT_CMP_MASK) == 1); 457 } 458 memcpy(ex1, ex2, nfexp_maxsize()); 459 for (i=0; i < ATTR_EXP_MAX; i++) { 460 nfexp_attr_unset(ex2, i); 461 462 assert(nfexp_cmp(ex1, ex2, 0) == 1); 463 assert(nfexp_cmp(ex1, ex2, NFCT_CMP_MASK) == 0); 464 } 465 memcpy(ex1, ex2, nfexp_maxsize()); 466 for (i=0; i < ATTR_EXP_MAX; i++) { 467 nfexp_attr_unset(ex1, i); 468 nfexp_attr_unset(ex2, i); 469 470 assert(nfexp_cmp(ex1, ex2, 0) == 1); 471 assert(nfexp_cmp(ex1, ex2, NFCT_CMP_STRICT) == 1); 472 assert(nfexp_cmp(ex1, ex2, NFCT_CMP_MASK) == 1); 473 } 474 nfexp_destroy(ex1); 475 nfexp_destroy(ex2); 476 } 477 478 int main(void) 479 { 480 int ret, i; 481 struct nf_conntrack *ct, *ct2, *tmp; 482 struct nf_expect *exp, *tmp_exp; 483 char data[256]; 484 const char *val; 485 int status; 486 struct nfct_bitmask *b, *b2; 487 488 srand(time(NULL)); 489 490 /* initialize fake data for testing purposes */ 491 for (i=0; i<sizeof(data); i++) 492 data[i] = 0x01; 493 494 ct = nfct_new(); 495 if (!ct) { 496 perror("nfct_new"); 497 return 0; 498 } 499 tmp = nfct_new(); 500 if (!tmp) { 501 perror("nfct_new"); 502 return 0; 503 } 504 505 printf("== test set API ==\n"); 506 ret = fork(); 507 if (ret == 0) { 508 for (i=0; i<ATTR_MAX; i++) 509 nfct_set_attr(ct, i, data); 510 exit(0); 511 } else { 512 wait(&status); 513 eval_sigterm(status); 514 } 515 516 b = nfct_bitmask_new(rand() & 0xffff); 517 assert(b); 518 b2 = nfct_bitmask_new(rand() & 0xffff); 519 assert(b2); 520 521 for (i=0; i<ATTR_MAX; i++) { 522 switch (i) { 523 case ATTR_CONNLABELS: 524 nfct_set_attr(ct, i, b); 525 break; 526 case ATTR_CONNLABELS_MASK: 527 nfct_set_attr(ct, i, b2); 528 break; 529 default: 530 nfct_set_attr(ct, i, data); 531 break; 532 } 533 } 534 535 printf("== test get API ==\n"); 536 ret = fork(); 537 if (ret == 0) { 538 for (i=0; i<ATTR_MAX; i++) 539 nfct_get_attr(ct, i); 540 exit(0); 541 } else { 542 wait(&status); 543 eval_sigterm(status); 544 } 545 546 printf("== validate set API ==\n"); 547 ret = fork(); 548 if (ret == 0) { 549 for (i=0; i<ATTR_MAX; i++) { 550 if (attr_is_readonly(i)) 551 continue; 552 switch(i) { 553 /* These attributes require special handling */ 554 case ATTR_HELPER_INFO: 555 nfct_set_attr_l(ct, i, data, sizeof(data)); 556 break; 557 case ATTR_CONNLABELS: 558 case ATTR_CONNLABELS_MASK: 559 /* already set above */ 560 break; 561 default: 562 data[0] = (uint8_t) i; 563 nfct_set_attr(ct, i, data); 564 } 565 val = nfct_get_attr(ct, i); 566 switch (i) { 567 case ATTR_CONNLABELS: 568 assert((void *) val == b); 569 continue; 570 case ATTR_CONNLABELS_MASK: 571 assert((void *) val == b2); 572 continue; 573 } 574 575 if (val[0] != data[0]) { 576 printf("ERROR: set/get operations don't match " 577 "for attribute %d (%x != %x)\n", 578 i, val[0], data[0]); 579 } 580 } 581 exit(0); 582 } else { 583 wait(&status); 584 eval_sigterm(status); 585 } 586 587 printf("== test copy API ==\n"); 588 ret = fork(); 589 if (ret == 0) { 590 for (i=0; i<ATTR_MAX; i++) 591 nfct_copy_attr(tmp, ct, i); 592 exit(0); 593 } else { 594 wait(&status); 595 eval_sigterm(status); 596 } 597 598 ret = fork(); 599 if (ret == 0) { 600 test_nfct_cmp_api(tmp, ct); 601 exit(0); 602 } else { 603 wait(&status); 604 eval_sigterm(status); 605 } 606 607 exp = nfexp_new(); 608 if (!exp) { 609 perror("nfexp_new"); 610 return 0; 611 } 612 tmp_exp = nfexp_new(); 613 if (!tmp_exp) { 614 perror("nfexp_new"); 615 return 0; 616 } 617 618 printf("== test expect set API ==\n"); 619 ret = fork(); 620 if (ret == 0) { 621 for (i=0; i<ATTR_EXP_MAX; i++) 622 nfexp_set_attr(exp, i, data); 623 exit(0); 624 } else { 625 wait(&status); 626 eval_sigterm(status); 627 } 628 629 for (i=0; i<ATTR_EXP_MAX; i++) 630 nfexp_set_attr(exp, i, data); 631 632 printf("== test expect get API ==\n"); 633 ret = fork(); 634 if (ret == 0) { 635 for (i=0; i<ATTR_EXP_MAX; i++) 636 nfexp_get_attr(exp, i); 637 exit(0); 638 } else { 639 wait(&status); 640 eval_sigterm(status); 641 } 642 643 printf("== validate expect set API ==\n"); 644 ret = fork(); 645 if (ret == 0) { 646 for (i=0; i<ATTR_EXP_MAX; i++) { 647 data[0] = (uint8_t) i; 648 nfexp_set_attr(exp, i, data); 649 val = nfexp_get_attr(exp, i); 650 if (val[0] != data[0]) { 651 printf("ERROR: set/get operations don't match " 652 "for attribute %d (%x != %x)\n", 653 i, val[0], data[0]); 654 } 655 } 656 exit(0); 657 } else { 658 wait(&status); 659 eval_sigterm(status); 660 } 661 662 ret = fork(); 663 if (ret == 0) { 664 test_nfexp_cmp_api(tmp_exp, exp); 665 exit(0); 666 } else { 667 wait(&status); 668 eval_sigterm(status); 669 } 670 671 ct2 = nfct_new(); 672 if (!ct2) { 673 perror("nfct_new"); 674 return 0; 675 } 676 677 printf("== test set grp API ==\n"); 678 ret = fork(); 679 if (ret == 0) { 680 for (i=0; i<ATTR_GRP_MAX; i++) 681 nfct_set_attr_grp(ct2, i, data); 682 exit(0); 683 } else { 684 wait(&status); 685 eval_sigterm(status); 686 } 687 688 for (i=0; i<ATTR_GRP_MAX; i++) 689 nfct_set_attr_grp(ct2, i, data); 690 691 printf("== test get grp API ==\n"); 692 ret = fork(); 693 if (ret == 0) { 694 char buf[32]; /* IPv6 group address is 16 bytes * 2 */ 695 696 for (i=0; i<ATTR_GRP_MAX; i++) 697 nfct_get_attr_grp(ct2, i, buf); 698 exit(0); 699 } else { 700 wait(&status); 701 eval_sigterm(status); 702 } 703 704 printf("== validate set grp API ==\n"); 705 ret = fork(); 706 if (ret == 0) { 707 for (i=0; i<ATTR_GRP_MAX; i++) { 708 char buf[32]; /* IPv6 group address is 16 bytes */ 709 710 data[0] = (uint8_t) i; 711 nfct_set_attr_grp(ct2, i, data); 712 nfct_get_attr_grp(ct2, i, buf); 713 /* These attributes cannot be set, ignore them. */ 714 switch(i) { 715 case ATTR_GRP_ORIG_COUNTERS: 716 case ATTR_GRP_REPL_COUNTERS: 717 case ATTR_GRP_ORIG_ADDR_SRC: 718 case ATTR_GRP_ORIG_ADDR_DST: 719 case ATTR_GRP_REPL_ADDR_SRC: 720 case ATTR_GRP_REPL_ADDR_DST: 721 continue; 722 } 723 if (buf[0] != data[0]) { 724 printf("ERROR: set/get operations don't match " 725 "for attribute %d (%x != %x)\n", 726 i, buf[0], data[0]); 727 } 728 } 729 exit(0); 730 } else { 731 wait(&status); 732 eval_sigterm(status); 733 } 734 735 nfct_destroy(ct2); 736 printf("== destroy cloned ct entry ==\n"); 737 nfct_destroy(ct); 738 nfct_destroy(tmp); 739 nfexp_destroy(exp); 740 nfexp_destroy(tmp_exp); 741 742 printf("OK\n"); 743 744 test_nfct_bitmask(); 745 746 return EXIT_SUCCESS; 747 } 748