Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/tests/sys/netinet/libalias/3_natin.c
39488 views
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
}
382
383