2 * SPDX-License-Identifier: BSD-3-Clause
4 * Copyright 2021 Lutz Donnerhacke
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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
41 ATF_TC_WITHOUT_HEAD(1_portforward);
42 ATF_TC_BODY(1_portforward, dummy)
44 struct libalias *la = LibAliasInit(NULL);
45 struct alias_link *pf1, *pf2, *pf3, *pf4;
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);
57 pf1 = LibAliasRedirectPort(la, prv1, ntohs(0x1234), ext, ntohs(0x5678), masq, ntohs(0xabcd), IPPROTO_UDP);
58 ATF_REQUIRE(pf1 != NULL);
61 UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv1, 0x1234);
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);
68 /* clear table by keeping the address */
69 LibAliasSetAddress(la, ext);
70 LibAliasSetAddress(la, masq);
72 /* delete and try again */
73 LibAliasRedirectDelete(la, pf1);
74 UDP_UNNAT_FAIL(p, u, ext, 0x5678, masq, 0xabcd);
79 pf2 = LibAliasRedirectPort(la, prv2, ntohs(0x1234), ext, ntohs(0), masq, ntohs(0xabcd), IPPROTO_UDP);
80 ATF_REQUIRE(pf2 != NULL);
82 UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv2, 0x1234);
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);
89 /* clear table by keeping the address */
90 LibAliasSetAddress(la, ext);
91 LibAliasSetAddress(la, masq);
93 /* delete and try again */
94 LibAliasRedirectDelete(la, pf2);
95 UDP_UNNAT_FAIL(p, u, ext, 0x5678, masq, 0xabcd);
100 pf3 = LibAliasRedirectPort(la, prv3, ntohs(0x1234), ANY_ADDR, ntohs(0x5678), masq, ntohs(0xabcd), IPPROTO_UDP);
101 ATF_REQUIRE(pf3 != NULL);
103 UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv3, 0x1234);
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);
110 /* clear table by keeping the address */
111 LibAliasSetAddress(la, ext);
112 LibAliasSetAddress(la, masq);
114 /* delete and try again */
115 LibAliasRedirectDelete(la, pf3);
116 UDP_UNNAT_FAIL(p, u, ext, 0x5678, masq, 0xabcd);
119 * Any external host, any port
121 pf4 = LibAliasRedirectPort(la, cgn, ntohs(0x1234), ANY_ADDR, ntohs(0), masq, ntohs(0xabcd), IPPROTO_UDP);
122 ATF_REQUIRE(pf4 != NULL);
124 UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, cgn, 0x1234);
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);
131 /* clear table by keeping the address */
132 LibAliasSetAddress(la, ext);
133 LibAliasSetAddress(la, masq);
135 /* delete and try again */
136 LibAliasRedirectDelete(la, pf4);
137 UDP_UNNAT_FAIL(p, u, ext, 0x5678, masq, 0xabcd);
143 ATF_TC_WITHOUT_HEAD(2_portoverlap);
144 ATF_TC_BODY(2_portoverlap, dummy)
146 struct libalias *la = LibAliasInit(NULL);
147 struct alias_link *pf1, *pf2, *pf3, *pf4;
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);
159 pf1 = LibAliasRedirectPort(la, prv2, ntohs(0x1234), ext, ntohs(0x5678), masq, ntohs(0xabcd), IPPROTO_UDP);
160 ATF_REQUIRE(pf1 != NULL);
162 p = ip_packet(0, 64);
163 UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv2, 0x1234);
165 /* clear table by keeping the address */
166 LibAliasSetAddress(la, ext);
167 LibAliasSetAddress(la, masq);
170 * Fully specified (override)
172 pf1 = LibAliasRedirectPort(la, prv1, ntohs(0x1234), ext, ntohs(0x5678), masq, ntohs(0xabcd), IPPROTO_UDP);
173 ATF_REQUIRE(pf1 != NULL);
175 UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv1, 0x1234);
177 /* clear table by keeping the address */
178 LibAliasSetAddress(la, ext);
179 LibAliasSetAddress(la, masq);
184 pf2 = LibAliasRedirectPort(la, prv2, ntohs(0x1234), ext, ntohs(0), masq, ntohs(0xabcd), IPPROTO_UDP);
185 ATF_REQUIRE(pf2 != NULL);
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);
191 /* clear table by keeping the address */
192 LibAliasSetAddress(la, ext);
193 LibAliasSetAddress(la, masq);
198 pf3 = LibAliasRedirectPort(la, prv3, ntohs(0x1234), ANY_ADDR, ntohs(0x5678), masq, ntohs(0xabcd), IPPROTO_UDP);
199 ATF_REQUIRE(pf3 != NULL);
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);
206 /* clear table by keeping the address */
207 LibAliasSetAddress(la, ext);
208 LibAliasSetAddress(la, masq);
211 * Any external host, any port
213 pf4 = LibAliasRedirectPort(la, cgn, ntohs(0x1234), ANY_ADDR, ntohs(0), masq, ntohs(0xabcd), IPPROTO_UDP);
214 ATF_REQUIRE(pf4 != NULL);
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);
226 ATF_TC_WITHOUT_HEAD(3_redirectany);
227 ATF_TC_BODY(3_redirectany, dummy)
229 struct libalias *la = LibAliasInit(NULL);
230 struct alias_link *pf;
234 ATF_REQUIRE(la != NULL);
235 LibAliasSetMode(la, PKT_ALIAS_DENY_INCOMING, ~0);
236 p = ip_packet(0, 64);
238 pf = LibAliasRedirectPort(la, prv1, ntohs(0x1234), ANY_ADDR, 0, ANY_ADDR, ntohs(0xabcd), IPPROTO_UDP);
239 ATF_REQUIRE(pf != NULL);
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);
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);
253 ATF_TC_WITHOUT_HEAD(4_redirectaddr);
254 ATF_TC_BODY(4_redirectaddr, dummy)
256 struct libalias *la = LibAliasInit(NULL);
257 struct alias_link *pf1, *pf2;
260 ATF_REQUIRE(la != NULL);
261 LibAliasSetAddress(la, masq);
262 pf1 = LibAliasRedirectAddr(la, prv1, pub);
263 ATF_REQUIRE(pf1 != NULL);
265 p = ip_packet(254, 64);
266 UNNAT_CHECK(p, ext, pub, prv1);
267 UNNAT_CHECK(p, ext, masq, masq);
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);
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);
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);
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);
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);
301 ATF_TC_WITHOUT_HEAD(5_lsnat);
302 ATF_TC_BODY(5_lsnat, dummy)
304 struct libalias *la = LibAliasInit(NULL);
305 struct alias_link *pf;
309 ATF_REQUIRE(la != NULL);
310 LibAliasSetMode(la, 0, ~0);
311 p = ip_packet(0, 64);
313 pf = LibAliasRedirectPort(la, cgn, ntohs(0xdead), ANY_ADDR, 0, masq, ntohs(0xabcd), IPPROTO_UDP);
314 ATF_REQUIRE(pf != NULL);
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)));
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);
331 ATF_TC_WITHOUT_HEAD(6_oneshot);
332 ATF_TC_BODY(6_oneshot, dummy)
334 struct libalias *la = LibAliasInit(NULL);
335 struct alias_link *pf;
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);
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);
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));
354 p = ip_packet(0, 64);
355 UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv1, 0x1234);
357 /* clear table by keeping the address */
358 LibAliasSetAddress(la, ext);
359 LibAliasSetAddress(la, masq);
361 /* does not work anymore */
362 UDP_UNNAT_FAIL(p, u, ext, 0x5678, masq, 0xabcd);
368 ATF_TP_ADD_TCS(natin)
370 /* Use "dd if=/dev/random bs=2 count=1 | od -x" to reproduce */
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);
380 return atf_no_error();