libnetfilter_conntrack  1.0.8
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 
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_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 
289 static 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 
309 static 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 
387 static 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 
438 static 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 
482 int 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)
Definition: conntrack/api.c:93
void nfct_copy_attr(struct nf_conntrack *ct1, const struct nf_conntrack *ct2, const enum nf_conntrack_attr type)
const void * nfct_get_attr(const struct nf_conntrack *ct, const enum nf_conntrack_attr type)
struct nf_conntrack * nfct_new(void)
Definition: conntrack/api.c:76
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)
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)
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
const void * nfexp_get_attr(const struct nf_expect *exp, const enum nf_expect_attr type)
Definition: expect/api.c:372
struct nf_expect * nfexp_new(void)
Definition: expect/api.c:29
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