]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tests/sys/netinet/libalias/3_natin.c
tests/libalias: Bugfix in used variables
[FreeBSD/FreeBSD.git] / tests / sys / netinet / libalias / 3_natin.c
1 /*
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Copyright 2021 Lutz Donnerhacke
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above
13  *    copyright notice, this list of conditions and the following
14  *    disclaimer in the documentation and/or other materials provided
15  *    with the distribution.
16  * 3. Neither the name of the copyright holder nor the names of its
17  *    contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
21  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
22  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
30  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
31  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 #include <atf-c.h>
35 #include <alias.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38
39 #include "util.h"
40
41 ATF_TC_WITHOUT_HEAD(1_portforward);
42 ATF_TC_BODY(1_portforward, dummy)
43 {
44         struct libalias *la = LibAliasInit(NULL);
45         struct alias_link *pf1, *pf2, *pf3, *pf4;
46         struct ip *p;
47         struct udphdr *u;
48
49         ATF_REQUIRE(la != NULL);
50         LibAliasSetAddress(la, masq);
51         LibAliasSetMode(la, PKT_ALIAS_RESET_ON_ADDR_CHANGE, ~0);
52         LibAliasSetMode(la, PKT_ALIAS_DENY_INCOMING, PKT_ALIAS_DENY_INCOMING);
53
54         /*
55          * Fully specified
56          */
57         pf1 = LibAliasRedirectPort(la, prv1, ntohs(0x1234), ext, ntohs(0x5678), masq, ntohs(0xabcd), IPPROTO_UDP);
58         ATF_REQUIRE(pf1 != NULL);
59
60         p = ip_packet(0, 64);
61         UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv1, 0x1234);
62         /* try again */
63         UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv1, 0x1234);
64         /* different source */
65         UDP_UNNAT_FAIL(p, u, pub, 0x5678, masq, 0xabcd);
66         UDP_UNNAT_FAIL(p, u, ext, 0xdead, masq, 0xabcd);
67
68         /* clear table by keeping the address */
69         LibAliasSetAddress(la, ext);
70         LibAliasSetAddress(la, masq);
71
72         /* delete and try again */
73         LibAliasRedirectDelete(la, pf1);
74         UDP_UNNAT_FAIL(p, u, ext, 0x5678, masq, 0xabcd);
75
76         /*
77          * Any external port
78          */
79         pf2 = LibAliasRedirectPort(la, prv2, ntohs(0x1234), ext, ntohs(0), masq, ntohs(0xabcd), IPPROTO_UDP);
80         ATF_REQUIRE(pf2 != NULL);
81
82         UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv2, 0x1234);
83         /* try again */
84         UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv2, 0x1234);
85         /* different source */
86         UDP_UNNAT_FAIL(p, u, pub, 0x5678, masq, 0xabcd);
87         UDP_UNNAT_CHECK(p, u, ext, 0xdead, masq, 0xabcd, prv2, 0x1234);
88
89         /* clear table by keeping the address */
90         LibAliasSetAddress(la, ext);
91         LibAliasSetAddress(la, masq);
92
93         /* delete and try again */
94         LibAliasRedirectDelete(la, pf2);
95         UDP_UNNAT_FAIL(p, u, ext, 0x5678, masq, 0xabcd);
96
97         /*
98          * Any external host
99          */
100         pf3 = LibAliasRedirectPort(la, prv3, ntohs(0x1234), ANY_ADDR, ntohs(0x5678), masq, ntohs(0xabcd), IPPROTO_UDP);
101         ATF_REQUIRE(pf3 != NULL);
102
103         UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv3, 0x1234);
104         /* try again */
105         UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv3, 0x1234);
106         /* different source */
107         UDP_UNNAT_CHECK(p, u, pub, 0x5678, masq, 0xabcd, prv3, 0x1234);
108         UDP_UNNAT_FAIL(p, u, ext, 0xdead, masq, 0xabcd);
109
110         /* clear table by keeping the address */
111         LibAliasSetAddress(la, ext);
112         LibAliasSetAddress(la, masq);
113
114         /* delete and try again */
115         LibAliasRedirectDelete(la, pf3);
116         UDP_UNNAT_FAIL(p, u, ext, 0x5678, masq, 0xabcd);
117
118         /*
119          * Any external host, any port
120          */
121         pf4 = LibAliasRedirectPort(la, cgn, ntohs(0x1234), ANY_ADDR, ntohs(0), masq, ntohs(0xabcd), IPPROTO_UDP);
122         ATF_REQUIRE(pf4 != NULL);
123
124         UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, cgn, 0x1234);
125         /* try again */
126         UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, cgn, 0x1234);
127         /* different source */
128         UDP_UNNAT_CHECK(p, u, pub, 0x5678, masq, 0xabcd, cgn, 0x1234);
129         UDP_UNNAT_CHECK(p, u, ext, 0xdead, masq, 0xabcd, cgn, 0x1234);
130
131         /* clear table by keeping the address */
132         LibAliasSetAddress(la, ext);
133         LibAliasSetAddress(la, masq);
134
135         /* delete and try again */
136         LibAliasRedirectDelete(la, pf4);
137         UDP_UNNAT_FAIL(p, u, ext, 0x5678, masq, 0xabcd);
138
139         free(p);
140         LibAliasUninit(la);
141 }
142
143 ATF_TC_WITHOUT_HEAD(2_portoverlap);
144 ATF_TC_BODY(2_portoverlap, dummy)
145 {
146         struct libalias *la = LibAliasInit(NULL);
147         struct alias_link *pf1, *pf2, *pf3, *pf4;
148         struct ip *p;
149         struct udphdr *u;
150
151         ATF_REQUIRE(la != NULL);
152         LibAliasSetAddress(la, masq);
153         LibAliasSetMode(la, PKT_ALIAS_RESET_ON_ADDR_CHANGE, ~0);
154         LibAliasSetMode(la, PKT_ALIAS_DENY_INCOMING, PKT_ALIAS_DENY_INCOMING);
155
156         /*
157          * Fully specified
158          */
159         pf1 = LibAliasRedirectPort(la, prv2, ntohs(0x1234), ext, ntohs(0x5678), masq, ntohs(0xabcd), IPPROTO_UDP);
160         ATF_REQUIRE(pf1 != NULL);
161
162         p = ip_packet(0, 64);
163         UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv2, 0x1234);
164
165         /* clear table by keeping the address */
166         LibAliasSetAddress(la, ext);
167         LibAliasSetAddress(la, masq);
168
169         /*
170          * Fully specified (override)
171          */
172         pf1 = LibAliasRedirectPort(la, prv1, ntohs(0x1234), ext, ntohs(0x5678), masq, ntohs(0xabcd), IPPROTO_UDP);
173         ATF_REQUIRE(pf1 != NULL);
174
175         UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv1, 0x1234);
176
177         /* clear table by keeping the address */
178         LibAliasSetAddress(la, ext);
179         LibAliasSetAddress(la, masq);
180
181         /*
182          * Any external port
183          */
184         pf2 = LibAliasRedirectPort(la, prv2, ntohs(0x1234), ext, ntohs(0), masq, ntohs(0xabcd), IPPROTO_UDP);
185         ATF_REQUIRE(pf2 != NULL);
186
187         UDP_UNNAT_CHECK(p, u, ext, 0x5679, masq, 0xabcd, prv2, 0x1234);
188         /* more specific rule wins */
189         UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv1, 0x1234);
190
191         /* clear table by keeping the address */
192         LibAliasSetAddress(la, ext);
193         LibAliasSetAddress(la, masq);
194
195         /*
196          * Any external host
197          */
198         pf3 = LibAliasRedirectPort(la, prv3, ntohs(0x1234), ANY_ADDR, ntohs(0x5678), masq, ntohs(0xabcd), IPPROTO_UDP);
199         ATF_REQUIRE(pf3 != NULL);
200
201         UDP_UNNAT_CHECK(p, u, pub, 0x5678, masq, 0xabcd, prv3, 0x1234);
202         /* more specific rule wins */
203         UDP_UNNAT_CHECK(p, u, ext, 0x5679, masq, 0xabcd, prv2, 0x1234);
204         UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv1, 0x1234);
205
206         /* clear table by keeping the address */
207         LibAliasSetAddress(la, ext);
208         LibAliasSetAddress(la, masq);
209
210         /*
211          * Any external host, any port
212          */
213         pf4 = LibAliasRedirectPort(la, cgn, ntohs(0x1234), ANY_ADDR, ntohs(0), masq, ntohs(0xabcd), IPPROTO_UDP);
214         ATF_REQUIRE(pf4 != NULL);
215
216         UDP_UNNAT_CHECK(p, u, prv1, 0x5679, masq, 0xabcd, cgn, 0x1234);
217         /* more specific rule wins */
218         UDP_UNNAT_CHECK(p, u, pub, 0x5678, masq, 0xabcd, prv3, 0x1234);
219         UDP_UNNAT_CHECK(p, u, ext, 0x5679, masq, 0xabcd, prv2, 0x1234);
220         UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv1, 0x1234);
221
222         free(p);
223         LibAliasUninit(la);
224 }
225
226 ATF_TC_WITHOUT_HEAD(3_redirectany);
227 ATF_TC_BODY(3_redirectany, dummy)
228 {
229         struct libalias *la = LibAliasInit(NULL);
230         struct alias_link *pf;
231         struct ip *p;
232         struct udphdr *u;
233
234         ATF_REQUIRE(la != NULL);
235         LibAliasSetMode(la, PKT_ALIAS_DENY_INCOMING, ~0);
236         p = ip_packet(0, 64);
237
238         pf = LibAliasRedirectPort(la, prv1, ntohs(0x1234), ANY_ADDR, 0, ANY_ADDR, ntohs(0xabcd), IPPROTO_UDP);
239         ATF_REQUIRE(pf != NULL);
240
241         LibAliasSetAddress(la, masq);
242         UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv1, 0x1234);
243         UDP_UNNAT_FAIL(p, u, pub, 0x5678, pub, 0xabcd);
244
245         LibAliasSetAddress(la, pub);
246         UDP_UNNAT_CHECK(p, u, pub, 0x5679, pub, 0xabcd, prv1, 0x1234);
247         UDP_UNNAT_FAIL(p, u, ext, 0x5679, masq, 0xabcd);
248
249         free(p);
250         LibAliasUninit(la);
251 }
252
253 ATF_TC_WITHOUT_HEAD(4_redirectaddr);
254 ATF_TC_BODY(4_redirectaddr, dummy)
255 {
256         struct libalias *la = LibAliasInit(NULL);
257         struct alias_link *pf1, *pf2;
258         struct ip *p;
259
260         ATF_REQUIRE(la != NULL);
261         LibAliasSetAddress(la, masq);
262         pf1 = LibAliasRedirectAddr(la, prv1, pub);
263         ATF_REQUIRE(pf1 != NULL);
264
265         p = ip_packet(254, 64);
266         UNNAT_CHECK(p, ext, pub, prv1);
267         UNNAT_CHECK(p, ext, masq, masq);
268
269         pf2 = LibAliasRedirectAddr(la, prv2, pub);
270         ATF_REQUIRE(pf2 != NULL);
271         UNNAT_CHECK(p, ext, pub, prv1);
272         p->ip_p = 253;                 /* new flows */
273         UNNAT_CHECK(p, ext, pub, prv2);
274         UNNAT_CHECK(p, ext, masq, masq);
275
276         p->ip_p = 252;                 /* new flows */
277         NAT_CHECK(p, prv1, ext, pub);
278         NAT_CHECK(p, prv2, ext, pub);
279         NAT_CHECK(p, prv3, ext, masq);
280
281         LibAliasSetMode(la, PKT_ALIAS_DENY_INCOMING, ~0);
282         p->ip_p = 251;                 /* new flows */
283         UNNAT_FAIL(p, ext, pub);
284         UNNAT_FAIL(p, ext, masq);
285
286         /* unhide older version */
287         LibAliasRedirectDelete(la, pf2);
288         LibAliasSetMode(la, 0, ~0);
289         p->ip_p = 250;                 /* new flows */
290         UNNAT_CHECK(p, ext, pub, prv1);
291
292         p->ip_p = 249;                 /* new flows */
293         NAT_CHECK(p, prv1, ext, pub);
294         NAT_CHECK(p, prv2, ext, masq);
295         NAT_CHECK(p, prv3, ext, masq);
296
297         free(p);
298         LibAliasUninit(la);
299 }
300
301 ATF_TC_WITHOUT_HEAD(5_lsnat);
302 ATF_TC_BODY(5_lsnat, dummy)
303 {
304         struct libalias *la = LibAliasInit(NULL);
305         struct alias_link *pf;
306         struct ip *p;
307         struct udphdr *u;
308
309         ATF_REQUIRE(la != NULL);
310         LibAliasSetMode(la, 0, ~0);
311         p = ip_packet(0, 64);
312
313         pf = LibAliasRedirectPort(la, cgn, ntohs(0xdead), ANY_ADDR, 0, masq, ntohs(0xabcd), IPPROTO_UDP);
314         ATF_REQUIRE(pf != NULL);
315
316         ATF_REQUIRE(0 == LibAliasAddServer(la, pf, prv1, ntohs(0x1234)));
317         ATF_REQUIRE(0 == LibAliasAddServer(la, pf, prv2, ntohs(0x2345)));
318         ATF_REQUIRE(0 == LibAliasAddServer(la, pf, prv3, ntohs(0x3456)));
319
320         UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv3, 0x3456);
321         UDP_UNNAT_CHECK(p, u, ext, 0x5679, masq, 0xabcd, prv2, 0x2345);
322         UDP_UNNAT_CHECK(p, u, ext, 0x567a, masq, 0xabcd, prv1, 0x1234);
323         UDP_UNNAT_CHECK(p, u, ext, 0x567b, masq, 0xabcd, prv3, 0x3456);
324         UDP_UNNAT_CHECK(p, u, ext, 0x567c, masq, 0xabcd, prv2, 0x2345);
325         UDP_UNNAT_CHECK(p, u, ext, 0x567d, masq, 0xabcd, prv1, 0x1234);
326
327         free(p);
328         LibAliasUninit(la);
329 }
330
331 ATF_TC_WITHOUT_HEAD(6_oneshot);
332 ATF_TC_BODY(6_oneshot, dummy)
333 {
334         struct libalias *la = LibAliasInit(NULL);
335         struct alias_link *pf;
336         struct ip *p;
337         struct udphdr *u;
338
339         ATF_REQUIRE(la != NULL);
340         LibAliasSetMode(la, 0, ~0);
341         LibAliasSetMode(la, PKT_ALIAS_RESET_ON_ADDR_CHANGE, ~0);
342         LibAliasSetMode(la, PKT_ALIAS_DENY_INCOMING, PKT_ALIAS_DENY_INCOMING);
343
344         pf = LibAliasRedirectPort(la, prv1, ntohs(0x1234), ANY_ADDR, 0, masq, ntohs(0xabcd), IPPROTO_UDP);
345         ATF_REQUIRE(pf != NULL);
346         /* only for fully specified links */
347         ATF_CHECK(-1 == LibAliasRedirectDynamic(la, pf));
348         LibAliasRedirectDelete(la, pf);
349
350         pf = LibAliasRedirectPort(la, prv1, ntohs(0x1234), ext, ntohs(0x5678), masq, ntohs(0xabcd), IPPROTO_UDP);
351         ATF_REQUIRE(pf != NULL);
352         ATF_CHECK(0 == LibAliasRedirectDynamic(la, pf));
353
354         p = ip_packet(0, 64);
355         UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv1, 0x1234);
356
357         /* clear table by keeping the address */
358         LibAliasSetAddress(la, ext);
359         LibAliasSetAddress(la, masq);
360
361         /* does not work anymore */
362         UDP_UNNAT_FAIL(p, u, ext, 0x5678, masq, 0xabcd);
363
364         free(p);
365         LibAliasUninit(la);
366 }
367
368 ATF_TP_ADD_TCS(natin)
369 {
370         /* Use "dd if=/dev/random bs=2 count=1 | od -x" to reproduce */
371         srand(0xe859);
372
373         ATF_TP_ADD_TC(natin, 1_portforward);
374         ATF_TP_ADD_TC(natin, 2_portoverlap);
375         ATF_TP_ADD_TC(natin, 3_redirectany);
376         ATF_TP_ADD_TC(natin, 4_redirectaddr);
377         ATF_TP_ADD_TC(natin, 5_lsnat);
378         ATF_TP_ADD_TC(natin, 6_oneshot);
379
380         return atf_no_error();
381 }