libnetfilter_conntrack  1.0.6
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_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 }
void nfexp_set_attr(struct nf_expect *exp, const enum nf_expect_attr type, const void *value)
Definition: expect/api.c:308
size_t nfexp_maxsize(void)
Definition: expect/api.c:76
void nfct_set_attr_l(struct nf_conntrack *ct, const enum nf_conntrack_attr type, const void *value, size_t len)
void nfct_set_attr_u32(struct nf_conntrack *ct, const enum nf_conntrack_attr type, uint32_t value)
void nfct_set_attr(struct nf_conntrack *ct, const enum nf_conntrack_attr type, const void *value)
void nfct_copy_attr(struct nf_conntrack *ct1, const struct nf_conntrack *ct2, const enum nf_conntrack_attr type)
int nfexp_cmp(const struct nf_expect *exp1, const struct nf_expect *exp2, unsigned int flags)
Definition: expect/api.c:126
int nfct_get_attr_grp(const struct nf_conntrack *ct, const enum nf_conntrack_attr_grp type, void *data)
void nfct_copy(struct nf_conntrack *dest, const struct nf_conntrack *source, unsigned int flags)
void nfct_destroy(struct nf_conntrack *ct)
Definition: conntrack/api.c:92
void nfct_set_attr_grp(struct nf_conntrack *ct, const enum nf_conntrack_attr_grp type, const void *value)
struct nf_expect * nfexp_new(void)
Definition: expect/api.c:28
int nfexp_attr_unset(struct nf_expect *exp, const enum nf_expect_attr type)
Definition: expect/api.c:465
uint32_t nfct_get_attr_u32(const struct nf_conntrack *ct, const enum nf_conntrack_attr type)
struct nf_conntrack * nfct_new(void)
Definition: conntrack/api.c:75
int nfct_cmp(const struct nf_conntrack *ct1, const struct nf_conntrack *ct2, unsigned int flags)
void nfct_set_attr_u8(struct nf_conntrack *ct, const enum nf_conntrack_attr type, uint8_t value)
const void * nfct_get_attr(const struct nf_conntrack *ct, const enum nf_conntrack_attr type)
int nfexp_attr_is_set(const struct nf_expect *exp, const enum nf_expect_attr type)
Definition: expect/api.c:445
int nfct_attr_is_set(const struct nf_conntrack *ct, const enum nf_conntrack_attr type)
void nfexp_destroy(struct nf_expect *exp)
Definition: expect/api.c:45
const void * nfexp_get_attr(const struct nf_expect *exp, const enum nf_expect_attr type)
Definition: expect/api.c:371
int nfct_attr_unset(struct nf_conntrack *ct, const enum nf_conntrack_attr type)