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
eval_sigterm(int status)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
test_nfct_bitmask(void)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. */
attr_is_readonly(int attr)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
test_nfct_cmp_api_single(struct nf_conntrack * ct1,struct nf_conntrack * ct2,int attr)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
test_cmp_attr32(int attr,bool at1,bool at2,uint32_t v1,uint32_t v2,unsigned int flags)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
test_nfct_cmp_attr(int attr)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
test_nfct_cmp_api(struct nf_conntrack * ct1,struct nf_conntrack * ct2)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
test_nfexp_cmp_api(struct nf_expect * ex1,struct nf_expect * ex2)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
main(void)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