• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <errno.h>
5 #include <arpa/inet.h>
6 
7 #include <libnetfilter_conntrack/libnetfilter_conntrack.h>
8 #include <libnetfilter_conntrack/libnetfilter_conntrack_tcp.h>
9 
10 /*
11  * This example shows how to setup a user-space expectation. This requires
12  * a Linux kernel >= 2.6.37.
13  */
14 
main(void)15 int main(void)
16 {
17 	int ret;
18 	struct nfct_handle *h;
19 	struct nf_conntrack *master, *expected, *mask;
20 	struct nf_expect *exp;
21 
22 	/*
23 	 * Step 1: Setup master conntrack
24 	 */
25 
26 	master = nfct_new();
27 	if (!master) {
28 		perror("nfct_new");
29 		exit(EXIT_FAILURE);
30 	}
31 
32 	nfct_set_attr_u8(master, ATTR_L3PROTO, AF_INET);
33 	nfct_set_attr_u32(master, ATTR_IPV4_SRC, inet_addr("1.1.1.1"));
34 	nfct_set_attr_u32(master, ATTR_IPV4_DST, inet_addr("2.2.2.2"));
35 
36 	nfct_set_attr_u8(master, ATTR_L4PROTO, IPPROTO_TCP);
37 	nfct_set_attr_u16(master, ATTR_PORT_SRC, htons(1025));
38 	nfct_set_attr_u16(master, ATTR_PORT_DST, htons(21));
39 
40 	nfct_setobjopt(master, NFCT_SOPT_SETUP_REPLY);
41 
42 	nfct_set_attr_u8(master, ATTR_TCP_STATE, TCP_CONNTRACK_ESTABLISHED);
43 	nfct_set_attr_u32(master, ATTR_TIMEOUT, 200);
44 
45 	h = nfct_open(CONNTRACK, 0);
46 	if (!h) {
47 		perror("nfct_open");
48 		nfct_destroy(master);
49 		return -1;
50 	}
51 
52 	/*
53 	 * In a real scenario in which you want to implement an helper in
54 	 * user-space with NFQUEUE, the master conntrack does not need to
55 	 * be created, since it should already exist.
56 	 */
57 	ret = nfct_query(h, NFCT_Q_CREATE, master);
58 
59 	printf("TEST: add master conntrack ");
60 	if (ret == -1)
61 		printf("(%d)(%s)\n", ret, strerror(errno));
62 	else
63 		printf("(OK)\n");
64 
65 	nfct_close(h);
66 
67 	expected = nfct_new();
68 	if (!expected) {
69 		perror("nfct_new");
70 		nfct_destroy(master);
71 		exit(EXIT_FAILURE);
72 	}
73 
74 	nfct_set_attr_u8(expected, ATTR_L3PROTO, AF_INET);
75 	nfct_set_attr_u32(expected, ATTR_IPV4_SRC, inet_addr("1.1.1.1"));
76 	nfct_set_attr_u32(expected, ATTR_IPV4_DST, inet_addr("2.2.2.2"));
77 
78 	nfct_set_attr_u8(expected, ATTR_L4PROTO, IPPROTO_TCP);
79 	nfct_set_attr_u16(expected, ATTR_PORT_SRC, 0);
80 	nfct_set_attr_u16(expected, ATTR_PORT_DST, htons(10241));
81 
82 	mask = nfct_new();
83 	if (!mask) {
84 		perror("nfct_new");
85 		nfct_destroy(master);
86 		nfct_destroy(expected);
87 		exit(EXIT_FAILURE);
88 	}
89 
90 	nfct_set_attr_u8(mask, ATTR_L3PROTO, AF_INET);
91 	nfct_set_attr_u32(mask, ATTR_IPV4_SRC, 0xffffffff);
92 	nfct_set_attr_u32(mask, ATTR_IPV4_DST, 0xffffffff);
93 
94 	nfct_set_attr_u8(mask, ATTR_L4PROTO, IPPROTO_TCP);
95 	nfct_set_attr_u16(mask, ATTR_PORT_SRC, 0x0000);
96 	nfct_set_attr_u16(mask, ATTR_PORT_DST, 0xffff);
97 
98 	/*
99 	 * Step 2: Setup expectation
100 	 */
101 
102 	exp = nfexp_new();
103 	if (!exp) {
104 		perror("nfexp_new");
105 		nfct_destroy(master);
106 		nfct_destroy(expected);
107 		nfct_destroy(mask);
108 		exit(EXIT_FAILURE);
109 	}
110 
111 	nfexp_set_attr(exp, ATTR_EXP_MASTER, master);
112 	nfexp_set_attr(exp, ATTR_EXP_EXPECTED, expected);
113 	nfexp_set_attr(exp, ATTR_EXP_MASK, mask);
114 	nfexp_set_attr_u32(exp, ATTR_EXP_TIMEOUT, 200);
115 
116 	nfct_destroy(master);
117 	nfct_destroy(expected);
118 	nfct_destroy(mask);
119 
120 	h = nfct_open(EXPECT, 0);
121 	if (!h) {
122 		perror("nfct_open");
123 		return -1;
124 	}
125 
126 	ret = nfexp_query(h, NFCT_Q_CREATE, exp);
127 
128 	printf("TEST: create expectation ");
129 	if (ret == -1)
130 		printf("(%d)(%s)\n", ret, strerror(errno));
131 	else
132 		printf("(OK)\n");
133 
134 	nfct_close(h);
135 
136 	ret == -1 ? exit(EXIT_FAILURE) : exit(EXIT_SUCCESS);
137 }
138