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 * WARNING: This test file creates an expectation for the FTP helper.
12 * Therefore, make sure you have load nf_conntrack_ftp before executing it.
13 */
14
15int main(void)
16{
17	int ret;
18	struct nfct_handle *h;
19	struct nf_conntrack *master, *expected, *mask, *nat;
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	nfct_set_attr(master, ATTR_HELPER_NAME, "ftp");
45
46	h = nfct_open(CONNTRACK, 0);
47	if (!h) {
48		perror("nfct_open");
49		nfct_destroy(master);
50		return -1;
51	}
52
53	ret = nfct_query(h, NFCT_Q_CREATE, master);
54
55	printf("TEST: add master conntrack ");
56	if (ret == -1)
57		printf("(%d)(%s)\n", ret, strerror(errno));
58	else
59		printf("(OK)\n");
60
61	nfct_close(h);
62
63	expected = nfct_new();
64	if (!expected) {
65		perror("nfct_new");
66		exit(EXIT_FAILURE);
67	}
68
69	nfct_set_attr_u8(expected, ATTR_L3PROTO, AF_INET);
70	nfct_set_attr_u32(expected, ATTR_IPV4_SRC, inet_addr("1.1.1.1"));
71	nfct_set_attr_u32(expected, ATTR_IPV4_DST, inet_addr("2.2.2.2"));
72
73	nfct_set_attr_u8(expected, ATTR_L4PROTO, IPPROTO_TCP);
74	nfct_set_attr_u16(expected, ATTR_PORT_SRC, 0);
75	nfct_set_attr_u16(expected, ATTR_PORT_DST, htons(10241));
76
77	mask = nfct_new();
78	if (!mask) {
79		perror("nfct_new");
80		nfct_destroy(master);
81		nfct_destroy(expected);
82		exit(EXIT_FAILURE);
83	}
84
85	nfct_set_attr_u8(mask, ATTR_L3PROTO, AF_INET);
86	nfct_set_attr_u32(mask, ATTR_IPV4_SRC, 0xffffffff);
87	nfct_set_attr_u32(mask, ATTR_IPV4_DST, 0xffffffff);
88
89	nfct_set_attr_u8(mask, ATTR_L4PROTO, IPPROTO_TCP);
90	nfct_set_attr_u16(mask, ATTR_PORT_SRC, 0x0000);
91	nfct_set_attr_u16(mask, ATTR_PORT_DST, 0xffff);
92
93	nat = nfct_new();
94	if (!nat) {
95		perror("nfct_new");
96		nfct_destroy(mask);
97		nfct_destroy(master);
98		nfct_destroy(expected);
99		exit(EXIT_FAILURE);
100	}
101
102	nfct_set_attr_u8(nat, ATTR_L3PROTO, AF_INET);
103	nfct_set_attr_u32(nat, ATTR_IPV4_SRC, inet_addr("3.3.3.3"));
104	nfct_set_attr_u32(nat, ATTR_IPV4_DST, 0);
105
106	nfct_set_attr_u8(nat, ATTR_L4PROTO, IPPROTO_TCP);
107	nfct_set_attr_u16(nat, ATTR_PORT_SRC, 12345);
108	nfct_set_attr_u16(nat, ATTR_PORT_DST, 0);
109
110	/*
111	 * Step 2: Setup expectation
112	 */
113
114	exp = nfexp_new();
115	if (!exp) {
116		perror("nfexp_new");
117		nfct_destroy(master);
118		nfct_destroy(expected);
119		nfct_destroy(mask);
120		exit(EXIT_FAILURE);
121	}
122
123	nfexp_set_attr(exp, ATTR_EXP_MASTER, master);
124	nfexp_set_attr(exp, ATTR_EXP_EXPECTED, expected);
125	nfexp_set_attr(exp, ATTR_EXP_MASK, mask);
126	nfexp_set_attr(exp, ATTR_EXP_NAT_TUPLE, nat);
127	nfexp_set_attr_u32(exp, ATTR_EXP_NAT_DIR, 0);
128	nfexp_set_attr_u32(exp, ATTR_EXP_TIMEOUT, 200);
129
130	nfct_destroy(master);
131	nfct_destroy(expected);
132	nfct_destroy(mask);
133	nfct_destroy(nat);
134
135	h = nfct_open(EXPECT, 0);
136	if (!h) {
137		perror("nfct_open");
138		return -1;
139	}
140
141	ret = nfexp_query(h, NFCT_Q_CREATE, exp);
142
143	printf("TEST: create expectation ");
144	if (ret == -1)
145		printf("(%d)(%s)\n", ret, strerror(errno));
146	else
147		printf("(OK)\n");
148
149	nfct_close(h);
150
151	ret == -1 ? exit(EXIT_FAILURE) : exit(EXIT_SUCCESS);
152}
153