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, pf2); 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, pf2); 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