libnetfilter_conntrack 1.0.9
test_api.c
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
21static 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
36static 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. */
147static 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
164static 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_SYNPROXY_ISN:
219 case ATTR_SYNPROXY_ITS:
220 case ATTR_SYNPROXY_TSOFF:
221
222 case ATTR_HELPER_INFO:
223 return 0; /* XXX */
224
225 default:
226 break;
227 }
228
229 if (attr >= ATTR_SCTP_STATE) {
230 nfct_set_attr_u8(ct1, ATTR_REPL_L4PROTO, IPPROTO_SCTP);
231 nfct_set_attr_u8(ct1, ATTR_L4PROTO, IPPROTO_SCTP);
232 } else if (attr >= ATTR_TCP_FLAGS_ORIG) {
233 nfct_set_attr_u8(ct1, ATTR_REPL_L4PROTO, IPPROTO_TCP);
234 nfct_set_attr_u8(ct1, ATTR_L4PROTO, IPPROTO_TCP);
235 } else if (attr >= ATTR_ICMP_CODE) {
236 nfct_set_attr_u8(ct1, ATTR_REPL_L4PROTO, IPPROTO_ICMP);
237 nfct_set_attr_u8(ct1, ATTR_L4PROTO, IPPROTO_ICMP);
238 } else if (attr >= ATTR_ORIG_PORT_SRC) {
239 nfct_set_attr_u8(ct1, ATTR_REPL_L4PROTO, IPPROTO_TCP);
240 nfct_set_attr_u8(ct1, ATTR_L4PROTO, IPPROTO_TCP);
241 }
242
243 nfct_copy(ct2, ct1, NFCT_CP_OVERRIDE);
244 memset(data, 42, sizeof(data));
245
246 assert(nfct_attr_is_set(ct1, attr));
247 assert(nfct_attr_is_set(ct2, attr));
248
249 switch (attr) {
250 case ATTR_CONNLABELS:
251 case ATTR_CONNLABELS_MASK:
252 b = (void *) nfct_get_attr(ct1, attr);
253 assert(b);
254 b = nfct_bitmask_clone(b);
255 assert(b);
256 bit = nfct_bitmask_maxbit(b);
257 if (nfct_bitmask_test_bit(b, bit)) {
258 nfct_bitmask_unset_bit(b, bit);
259 assert(!nfct_bitmask_test_bit(b, bit));
260 } else {
261 nfct_bitmask_set_bit(b, bit);
262 assert(nfct_bitmask_test_bit(b, bit));
263 }
264 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL) == 1);
265 nfct_set_attr(ct2, attr, b);
266 break;
267 case ATTR_HELPER_INFO:
268 nfct_set_attr_l(ct2, attr, "test", 4);
269 break;
270 default:
271 nfct_set_attr(ct2, attr, data);
272 break;
273 }
274
275 if (nfct_cmp(ct1, ct2, NFCT_CMP_ALL) != 0) {
276 fprintf(stderr, "nfct_cmp assert failure for attr %d\n", attr);
277 fprintf(stderr, "%p, %p, %x, %x\n", nfct_get_attr(ct1, attr),
278 nfct_get_attr(ct2, attr),
279 nfct_get_attr_u32(ct1, attr), nfct_get_attr_u32(ct2, attr));
280 return -1;
281 }
282 if (nfct_cmp(ct1, ct2, NFCT_CMP_ALL|NFCT_CMP_STRICT) != 0) {
283 fprintf(stderr, "nfct_cmp strict assert failure for attr %d\n", attr);
284 return -1;
285 }
286 return 0;
287}
288
289static int test_cmp_attr32(int attr, bool at1, bool at2,
290 uint32_t v1, uint32_t v2, unsigned int flags)
291{
292 struct nf_conntrack *ct1 = nfct_new();
293 struct nf_conntrack *ct2 = nfct_new();
294 int ret;
295
296 if (at1)
297 nfct_set_attr_u32(ct1, attr, v1);
298 if (at2)
299 nfct_set_attr_u32(ct2, attr, v2);
300
301 ret = nfct_cmp(ct1, ct2, NFCT_CMP_ALL | flags);
302
303 nfct_destroy(ct1);
304 nfct_destroy(ct2);
305
306 return ret;
307}
308
309static void test_nfct_cmp_attr(int attr)
310{
311 unsigned int flags = 0;
312
313 /* 0000, 1000, 1100, 0010, 1010... */
314 /* attr at1 at2 v1 v2 */
315 assert(test_cmp_attr32(attr, false, false, 0, 0, flags) == 1);
316 assert(test_cmp_attr32(attr, true, false, 0, 0, flags) == 1);
317 assert(test_cmp_attr32(attr, false, true, 0, 0, flags) == 1);
318 assert(test_cmp_attr32(attr, true, true, 0, 0, flags) == 1);
319 assert(test_cmp_attr32(attr, false, false, 1, 0, flags) == 1); /* verbose */
320 assert(test_cmp_attr32(attr, true, false, 1, 0, flags) == 1);
321 assert(test_cmp_attr32(attr, false, true, 1, 0, flags) == 1); /* verbose */
322 assert(test_cmp_attr32(attr, true, true, 1, 0, flags) == 0);
323 assert(test_cmp_attr32(attr, false, false, 0, 1, flags) == 1); /* verbose */
324 assert(test_cmp_attr32(attr, true, false, 0, 1, flags) == 1); /* verbose */
325 assert(test_cmp_attr32(attr, false, true, 0, 1, flags) == 1);
326 assert(test_cmp_attr32(attr, true, true, 0, 1, flags) == 0);
327 assert(test_cmp_attr32(attr, false, false, 1, 1, flags) == 1); /* verbose */
328 assert(test_cmp_attr32(attr, true, false, 1, 1, flags) == 1); /* verbose */
329 assert(test_cmp_attr32(attr, false, true, 1, 1, flags) == 1); /* verbose */
330 assert(test_cmp_attr32(attr, true, true, 1, 1, flags) == 1);
331
332 flags = NFCT_CMP_STRICT;
333 assert(test_cmp_attr32(attr, false, false, 0, 0, flags) == 1);
334 assert(test_cmp_attr32(attr, true, false, 0, 0, flags) == 1);
335 assert(test_cmp_attr32(attr, false, true, 0, 0, flags) == 1);
336 assert(test_cmp_attr32(attr, true, true, 0, 0, flags) == 1);
337 assert(test_cmp_attr32(attr, false, false, 1, 0, flags) == 1); /* verbose */
338 assert(test_cmp_attr32(attr, true, false, 1, 0, flags) == 0);
339 assert(test_cmp_attr32(attr, false, true, 1, 0, flags) == 1); /* verbose */
340 assert(test_cmp_attr32(attr, true, true, 1, 0, flags) == 0);
341 assert(test_cmp_attr32(attr, false, false, 0, 1, flags) == 1); /* verbose */
342 assert(test_cmp_attr32(attr, true, false, 0, 1, flags) == 1); /* verbose */
343 assert(test_cmp_attr32(attr, false, true, 0, 1, flags) == 0);
344 assert(test_cmp_attr32(attr, true, true, 0, 1, flags) == 0);
345 assert(test_cmp_attr32(attr, false, false, 1, 1, flags) == 1); /* verbose */
346 assert(test_cmp_attr32(attr, true, false, 1, 1, flags) == 0); /* verbose */
347 assert(test_cmp_attr32(attr, false, true, 1, 1, flags) == 0); /* verbose */
348 assert(test_cmp_attr32(attr, true, true, 1, 1, flags) == 1);
349
350 flags = NFCT_CMP_MASK;
351 assert(test_cmp_attr32(attr, false, false, 0, 0, flags) == 1);
352 assert(test_cmp_attr32(attr, true, false, 0, 0, flags) == 1);
353 assert(test_cmp_attr32(attr, false, true, 0, 0, flags) == 1);
354 assert(test_cmp_attr32(attr, true, true, 0, 0, flags) == 1);
355 assert(test_cmp_attr32(attr, false, false, 1, 0, flags) == 1); /* verbose */
356 assert(test_cmp_attr32(attr, true, false, 1, 0, flags) == 0);
357 assert(test_cmp_attr32(attr, false, true, 1, 0, flags) == 1); /* verbose */
358 assert(test_cmp_attr32(attr, true, true, 1, 0, flags) == 0);
359 assert(test_cmp_attr32(attr, false, false, 0, 1, flags) == 1); /* verbose */
360 assert(test_cmp_attr32(attr, true, false, 0, 1, flags) == 1); /* verbose */
361 assert(test_cmp_attr32(attr, false, true, 0, 1, flags) == 1);
362 assert(test_cmp_attr32(attr, true, true, 0, 1, flags) == 0);
363 assert(test_cmp_attr32(attr, false, false, 1, 1, flags) == 1); /* verbose */
364 assert(test_cmp_attr32(attr, true, false, 1, 1, flags) == 0); /* verbose */
365 assert(test_cmp_attr32(attr, false, true, 1, 1, flags) == 1); /* verbose */
366 assert(test_cmp_attr32(attr, true, true, 1, 1, flags) == 1);
367
368 flags = NFCT_CMP_STRICT|NFCT_CMP_MASK;
369 assert(test_cmp_attr32(attr, false, false, 0, 0, flags) == 1);
370 assert(test_cmp_attr32(attr, true, false, 0, 0, flags) == 1);
371 assert(test_cmp_attr32(attr, false, true, 0, 0, flags) == 1);
372 assert(test_cmp_attr32(attr, true, true, 0, 0, flags) == 1);
373 assert(test_cmp_attr32(attr, false, false, 1, 0, flags) == 1); /* verbose */
374 assert(test_cmp_attr32(attr, true, false, 1, 0, flags) == 0);
375 assert(test_cmp_attr32(attr, false, true, 1, 0, flags) == 1); /* verbose */
376 assert(test_cmp_attr32(attr, true, true, 1, 0, flags) == 0);
377 assert(test_cmp_attr32(attr, false, false, 0, 1, flags) == 1); /* verbose */
378 assert(test_cmp_attr32(attr, true, false, 0, 1, flags) == 1); /* verbose */
379 assert(test_cmp_attr32(attr, false, true, 0, 1, flags) == 0);
380 assert(test_cmp_attr32(attr, true, true, 0, 1, flags) == 0);
381 assert(test_cmp_attr32(attr, false, false, 1, 1, flags) == 1); /* verbose */
382 assert(test_cmp_attr32(attr, true, false, 1, 1, flags) == 0); /* verbose */
383 assert(test_cmp_attr32(attr, false, true, 1, 1, flags) == 0); /* verbose */
384 assert(test_cmp_attr32(attr, true, true, 1, 1, flags) == 1);
385}
386
387static void test_nfct_cmp_api(struct nf_conntrack *ct1, struct nf_conntrack *ct2)
388{
389 int i;
390
391 printf("== test cmp API ==\n");
392
393 test_nfct_cmp_attr(ATTR_ZONE);
394 test_nfct_cmp_attr(ATTR_ORIG_ZONE);
395 test_nfct_cmp_attr(ATTR_REPL_ZONE);
396 test_nfct_cmp_attr(ATTR_MARK);
397
398 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL) == 1);
399 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL|NFCT_CMP_STRICT) == 0);
400
401 nfct_copy(ct1, ct2, NFCT_CP_OVERRIDE);
402
403 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL) == 1);
404 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL|NFCT_CMP_STRICT) == 1);
405
406 for (i=0; i < ATTR_MAX ; i++) {
407 nfct_attr_unset(ct1, i);
408
409 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL) == 1);
410 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL|NFCT_CMP_STRICT) == 0);
411 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL|NFCT_CMP_MASK) == 1);
412 }
413 nfct_copy(ct1, ct2, NFCT_CP_OVERRIDE);
414 for (i=0; i < ATTR_MAX ; i++) {
415 nfct_attr_unset(ct2, i);
416
417 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL) == 1);
418 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL|NFCT_CMP_STRICT) == 0);
419 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL|NFCT_CMP_MASK) == 0);
420 }
421
422 for (i=0; i < ATTR_MAX ; i++)
423 assert(test_nfct_cmp_api_single(ct1, ct2, i) == 0);
424
425 nfct_copy(ct2, ct1, NFCT_CP_OVERRIDE);
426 for (i=0; i < ATTR_MAX ; i++) {
427 nfct_attr_unset(ct1, i);
428 nfct_attr_unset(ct2, i);
429
430 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL) == 1);
431 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL|NFCT_CMP_STRICT) == 1);
432 assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL|NFCT_CMP_MASK) == 1);
433 }
434 nfct_destroy(ct1);
435 nfct_destroy(ct2);
436}
437
438static void test_nfexp_cmp_api(struct nf_expect *ex1, struct nf_expect *ex2)
439{
440 int i;
441
442 printf("== test expect cmp API ==\n");
443
444 /* XXX: missing nfexp_copy API. */
445 memcpy(ex1, ex2, nfexp_maxsize());
446
447 assert(nfexp_cmp(ex1, ex2, 0) == 1);
448 assert(nfexp_cmp(ex1, ex2, NFCT_CMP_STRICT) == 1);
449
450 assert(nfexp_attr_is_set(ex1, 0) == 1);
451 nfexp_attr_unset(ex1, 0);
452 assert(nfexp_attr_is_set(ex1, 0) == 0);
453
454 memcpy(ex1, ex2, nfexp_maxsize());
455 for (i=0; i < ATTR_EXP_MAX; i++) {
456 nfexp_attr_unset(ex1, i);
457
458 assert(nfexp_cmp(ex1, ex2, 0) == 1);
459 assert(nfexp_cmp(ex1, ex2, NFCT_CMP_STRICT) == 0);
460 assert(nfexp_cmp(ex1, ex2, NFCT_CMP_MASK) == 1);
461 }
462 memcpy(ex1, ex2, nfexp_maxsize());
463 for (i=0; i < ATTR_EXP_MAX; i++) {
464 nfexp_attr_unset(ex2, i);
465
466 assert(nfexp_cmp(ex1, ex2, 0) == 1);
467 assert(nfexp_cmp(ex1, ex2, NFCT_CMP_MASK) == 0);
468 }
469 memcpy(ex1, ex2, nfexp_maxsize());
470 for (i=0; i < ATTR_EXP_MAX; i++) {
471 nfexp_attr_unset(ex1, i);
472 nfexp_attr_unset(ex2, i);
473
474 assert(nfexp_cmp(ex1, ex2, 0) == 1);
475 assert(nfexp_cmp(ex1, ex2, NFCT_CMP_STRICT) == 1);
476 assert(nfexp_cmp(ex1, ex2, NFCT_CMP_MASK) == 1);
477 }
478 nfexp_destroy(ex1);
479 nfexp_destroy(ex2);
480}
481
482int main(void)
483{
484 int ret, i;
485 struct nf_conntrack *ct, *ct2, *tmp;
486 struct nf_expect *exp, *tmp_exp;
487 char data[256];
488 const char *val;
489 int status;
490 struct nfct_bitmask *b, *b2;
491
492 srand(time(NULL));
493
494 /* initialize fake data for testing purposes */
495 for (i=0; i<sizeof(data); i++)
496 data[i] = 0x01;
497
498 ct = nfct_new();
499 if (!ct) {
500 perror("nfct_new");
501 return 0;
502 }
503 tmp = nfct_new();
504 if (!tmp) {
505 perror("nfct_new");
506 return 0;
507 }
508
509 printf("== test set API ==\n");
510 ret = fork();
511 if (ret == 0) {
512 for (i=0; i<ATTR_MAX; i++)
513 nfct_set_attr(ct, i, data);
514 exit(0);
515 } else {
516 wait(&status);
517 eval_sigterm(status);
518 }
519
520 b = nfct_bitmask_new(rand() & 0xffff);
521 assert(b);
522 b2 = nfct_bitmask_new(rand() & 0xffff);
523 assert(b2);
524
525 for (i=0; i<ATTR_MAX; i++) {
526 switch (i) {
527 case ATTR_CONNLABELS:
528 nfct_set_attr(ct, i, b);
529 break;
530 case ATTR_CONNLABELS_MASK:
531 nfct_set_attr(ct, i, b2);
532 break;
533 default:
534 nfct_set_attr(ct, i, data);
535 break;
536 }
537 }
538
539 printf("== test get API ==\n");
540 ret = fork();
541 if (ret == 0) {
542 for (i=0; i<ATTR_MAX; i++)
543 nfct_get_attr(ct, i);
544 exit(0);
545 } else {
546 wait(&status);
547 eval_sigterm(status);
548 }
549
550 printf("== validate set API ==\n");
551 ret = fork();
552 if (ret == 0) {
553 for (i=0; i<ATTR_MAX; i++) {
554 if (attr_is_readonly(i))
555 continue;
556 switch(i) {
557 /* These attributes require special handling */
558 case ATTR_HELPER_INFO:
559 nfct_set_attr_l(ct, i, data, sizeof(data));
560 break;
561 case ATTR_CONNLABELS:
562 case ATTR_CONNLABELS_MASK:
563 /* already set above */
564 break;
565 default:
566 data[0] = (uint8_t) i;
567 nfct_set_attr(ct, i, data);
568 }
569 val = nfct_get_attr(ct, i);
570 switch (i) {
571 case ATTR_CONNLABELS:
572 assert((void *) val == b);
573 continue;
574 case ATTR_CONNLABELS_MASK:
575 assert((void *) val == b2);
576 continue;
577 }
578
579 if (val[0] != data[0]) {
580 printf("ERROR: set/get operations don't match "
581 "for attribute %d (%x != %x)\n",
582 i, val[0], data[0]);
583 }
584 }
585 exit(0);
586 } else {
587 wait(&status);
588 eval_sigterm(status);
589 }
590
591 printf("== test copy API ==\n");
592 ret = fork();
593 if (ret == 0) {
594 for (i=0; i<ATTR_MAX; i++)
595 nfct_copy_attr(tmp, ct, i);
596 exit(0);
597 } else {
598 wait(&status);
599 eval_sigterm(status);
600 }
601
602 ret = fork();
603 if (ret == 0) {
604 test_nfct_cmp_api(tmp, ct);
605 exit(0);
606 } else {
607 wait(&status);
608 eval_sigterm(status);
609 }
610
611 exp = nfexp_new();
612 if (!exp) {
613 perror("nfexp_new");
614 return 0;
615 }
616 tmp_exp = nfexp_new();
617 if (!tmp_exp) {
618 perror("nfexp_new");
619 return 0;
620 }
621
622 printf("== test expect set API ==\n");
623 ret = fork();
624 if (ret == 0) {
625 for (i=0; i<ATTR_EXP_MAX; i++)
626 nfexp_set_attr(exp, i, data);
627 exit(0);
628 } else {
629 wait(&status);
630 eval_sigterm(status);
631 }
632
633 for (i=0; i<ATTR_EXP_MAX; i++)
634 nfexp_set_attr(exp, i, data);
635
636 printf("== test expect get API ==\n");
637 ret = fork();
638 if (ret == 0) {
639 for (i=0; i<ATTR_EXP_MAX; i++)
640 nfexp_get_attr(exp, i);
641 exit(0);
642 } else {
643 wait(&status);
644 eval_sigterm(status);
645 }
646
647 printf("== validate expect set API ==\n");
648 ret = fork();
649 if (ret == 0) {
650 for (i=0; i<ATTR_EXP_MAX; i++) {
651 data[0] = (uint8_t) i;
652 nfexp_set_attr(exp, i, data);
653 val = nfexp_get_attr(exp, i);
654 if (val[0] != data[0]) {
655 printf("ERROR: set/get operations don't match "
656 "for attribute %d (%x != %x)\n",
657 i, val[0], data[0]);
658 }
659 }
660 exit(0);
661 } else {
662 wait(&status);
663 eval_sigterm(status);
664 }
665
666 ret = fork();
667 if (ret == 0) {
668 test_nfexp_cmp_api(tmp_exp, exp);
669 exit(0);
670 } else {
671 wait(&status);
672 eval_sigterm(status);
673 }
674
675 ct2 = nfct_new();
676 if (!ct2) {
677 perror("nfct_new");
678 return 0;
679 }
680
681 printf("== test set grp API ==\n");
682 ret = fork();
683 if (ret == 0) {
684 for (i=0; i<ATTR_GRP_MAX; i++)
685 nfct_set_attr_grp(ct2, i, data);
686 exit(0);
687 } else {
688 wait(&status);
689 eval_sigterm(status);
690 }
691
692 for (i=0; i<ATTR_GRP_MAX; i++)
693 nfct_set_attr_grp(ct2, i, data);
694
695 printf("== test get grp API ==\n");
696 ret = fork();
697 if (ret == 0) {
698 char buf[32]; /* IPv6 group address is 16 bytes * 2 */
699
700 for (i=0; i<ATTR_GRP_MAX; i++)
701 nfct_get_attr_grp(ct2, i, buf);
702 exit(0);
703 } else {
704 wait(&status);
705 eval_sigterm(status);
706 }
707
708 printf("== validate set grp API ==\n");
709 ret = fork();
710 if (ret == 0) {
711 for (i=0; i<ATTR_GRP_MAX; i++) {
712 char buf[32]; /* IPv6 group address is 16 bytes */
713
714 data[0] = (uint8_t) i;
715 nfct_set_attr_grp(ct2, i, data);
716 nfct_get_attr_grp(ct2, i, buf);
717 /* These attributes cannot be set, ignore them. */
718 switch(i) {
719 case ATTR_GRP_ORIG_COUNTERS:
720 case ATTR_GRP_REPL_COUNTERS:
721 case ATTR_GRP_ORIG_ADDR_SRC:
722 case ATTR_GRP_ORIG_ADDR_DST:
723 case ATTR_GRP_REPL_ADDR_SRC:
724 case ATTR_GRP_REPL_ADDR_DST:
725 continue;
726 }
727 if (buf[0] != data[0]) {
728 printf("ERROR: set/get operations don't match "
729 "for attribute %d (%x != %x)\n",
730 i, buf[0], data[0]);
731 }
732 }
733 exit(0);
734 } else {
735 wait(&status);
736 eval_sigterm(status);
737 }
738
739 nfct_destroy(ct2);
740 printf("== destroy cloned ct entry ==\n");
741 nfct_destroy(ct);
742 nfct_destroy(tmp);
743 nfexp_destroy(exp);
744 nfexp_destroy(tmp_exp);
745
746 printf("OK\n");
747
748 test_nfct_bitmask();
749
750 return EXIT_SUCCESS;
751}
void nfct_set_attr_u32(struct nf_conntrack *ct, const enum nf_conntrack_attr type, uint32_t value)
void nfct_destroy(struct nf_conntrack *ct)
void nfct_copy_attr(struct nf_conntrack *ct1, const struct nf_conntrack *ct2, const enum nf_conntrack_attr type)
void nfct_set_attr(struct nf_conntrack *ct, const enum nf_conntrack_attr type, const void *value)
int nfct_get_attr_grp(const struct nf_conntrack *ct, const enum nf_conntrack_attr_grp type, void *data)
void nfct_set_attr_grp(struct nf_conntrack *ct, const enum nf_conntrack_attr_grp type, const void *value)
const void * nfct_get_attr(const struct nf_conntrack *ct, const enum nf_conntrack_attr type)
int nfct_attr_unset(struct nf_conntrack *ct, const enum nf_conntrack_attr type)
void nfct_copy(struct nf_conntrack *dest, const struct nf_conntrack *source, unsigned int flags)
int nfct_cmp(const struct nf_conntrack *ct1, const struct nf_conntrack *ct2, unsigned int flags)
uint32_t nfct_get_attr_u32(const struct nf_conntrack *ct, const enum nf_conntrack_attr type)
void nfct_set_attr_u8(struct nf_conntrack *ct, const enum nf_conntrack_attr type, uint8_t value)
void nfct_set_attr_l(struct nf_conntrack *ct, const enum nf_conntrack_attr type, const void *value, size_t len)
int nfct_attr_is_set(const struct nf_conntrack *ct, const enum nf_conntrack_attr type)
struct nf_conntrack * nfct_new(void)
struct nf_expect * nfexp_new(void)
Definition expect/api.c:29
const void * nfexp_get_attr(const struct nf_expect *exp, const enum nf_expect_attr type)
Definition expect/api.c:372
void nfexp_set_attr(struct nf_expect *exp, const enum nf_expect_attr type, const void *value)
Definition expect/api.c:309
int nfexp_cmp(const struct nf_expect *exp1, const struct nf_expect *exp2, unsigned int flags)
Definition expect/api.c:127
void nfexp_destroy(struct nf_expect *exp)
Definition expect/api.c:46
int nfexp_attr_unset(struct nf_expect *exp, const enum nf_expect_attr type)
Definition expect/api.c:466
int nfexp_attr_is_set(const struct nf_expect *exp, const enum nf_expect_attr type)
Definition expect/api.c:446
size_t nfexp_maxsize(void)
Definition expect/api.c:77