17b8696bfSLutz Donnerhacke /* 27b8696bfSLutz Donnerhacke * SPDX-License-Identifier: BSD-3-Clause 37b8696bfSLutz Donnerhacke * 47b8696bfSLutz Donnerhacke * Copyright 2021 Lutz Donnerhacke 57b8696bfSLutz Donnerhacke * 67b8696bfSLutz Donnerhacke * Redistribution and use in source and binary forms, with or without 77b8696bfSLutz Donnerhacke * modification, are permitted provided that the following conditions 87b8696bfSLutz Donnerhacke * are met: 97b8696bfSLutz Donnerhacke * 107b8696bfSLutz Donnerhacke * 1. Redistributions of source code must retain the above copyright 117b8696bfSLutz Donnerhacke * notice, this list of conditions and the following disclaimer. 127b8696bfSLutz Donnerhacke * 2. Redistributions in binary form must reproduce the above 137b8696bfSLutz Donnerhacke * copyright notice, this list of conditions and the following 147b8696bfSLutz Donnerhacke * disclaimer in the documentation and/or other materials provided 157b8696bfSLutz Donnerhacke * with the distribution. 167b8696bfSLutz Donnerhacke * 3. Neither the name of the copyright holder nor the names of its 177b8696bfSLutz Donnerhacke * contributors may be used to endorse or promote products derived 187b8696bfSLutz Donnerhacke * from this software without specific prior written permission. 197b8696bfSLutz Donnerhacke * 207b8696bfSLutz Donnerhacke * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 217b8696bfSLutz Donnerhacke * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 227b8696bfSLutz Donnerhacke * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 237b8696bfSLutz Donnerhacke * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 247b8696bfSLutz Donnerhacke * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 257b8696bfSLutz Donnerhacke * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 267b8696bfSLutz Donnerhacke * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 277b8696bfSLutz Donnerhacke * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 287b8696bfSLutz Donnerhacke * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 297b8696bfSLutz Donnerhacke * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 307b8696bfSLutz Donnerhacke * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 317b8696bfSLutz Donnerhacke * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 327b8696bfSLutz Donnerhacke * SUCH DAMAGE. 337b8696bfSLutz Donnerhacke */ 34c1fbb54fSLutz Donnerhacke #include <atf-c.h> 35c1fbb54fSLutz Donnerhacke #include <alias.h> 36c1fbb54fSLutz Donnerhacke #include <stdio.h> 37c1fbb54fSLutz Donnerhacke #include <stdlib.h> 38c1fbb54fSLutz Donnerhacke 39c1fbb54fSLutz Donnerhacke #include "util.h" 40c1fbb54fSLutz Donnerhacke 41c1fbb54fSLutz Donnerhacke ATF_TC_WITHOUT_HEAD(1_simplemasq); 42c1fbb54fSLutz Donnerhacke ATF_TC_BODY(1_simplemasq, dummy) 43c1fbb54fSLutz Donnerhacke { 44c1fbb54fSLutz Donnerhacke struct libalias *la = LibAliasInit(NULL); 45c1fbb54fSLutz Donnerhacke struct ip *pip; 46c1fbb54fSLutz Donnerhacke 47c1fbb54fSLutz Donnerhacke ATF_REQUIRE(la != NULL); 48c1fbb54fSLutz Donnerhacke LibAliasSetAddress(la, masq); 49c1fbb54fSLutz Donnerhacke LibAliasSetMode(la, 0, ~0); 50c1fbb54fSLutz Donnerhacke 51f1462ab0SLutz Donnerhacke pip = ip_packet(254, 64); 52f1462ab0SLutz Donnerhacke NAT_CHECK(pip, prv1, ext, masq); 53f1462ab0SLutz Donnerhacke NAT_CHECK(pip, prv2, ext, masq); 54f1462ab0SLutz Donnerhacke NAT_CHECK(pip, prv3, ext, masq); 55f1462ab0SLutz Donnerhacke NAT_CHECK(pip, cgn, ext, masq); 56f1462ab0SLutz Donnerhacke NAT_CHECK(pip, pub, ext, masq); 57c1fbb54fSLutz Donnerhacke 58c1fbb54fSLutz Donnerhacke free(pip); 59c1fbb54fSLutz Donnerhacke LibAliasUninit(la); 60c1fbb54fSLutz Donnerhacke } 61c1fbb54fSLutz Donnerhacke 62c1fbb54fSLutz Donnerhacke ATF_TC_WITHOUT_HEAD(2_unregistered); 63c1fbb54fSLutz Donnerhacke ATF_TC_BODY(2_unregistered, dummy) 64c1fbb54fSLutz Donnerhacke { 65c1fbb54fSLutz Donnerhacke struct libalias *la = LibAliasInit(NULL); 66c1fbb54fSLutz Donnerhacke struct ip *pip; 67c1fbb54fSLutz Donnerhacke 68c1fbb54fSLutz Donnerhacke ATF_REQUIRE(la != NULL); 69c1fbb54fSLutz Donnerhacke LibAliasSetAddress(la, masq); 70c1fbb54fSLutz Donnerhacke LibAliasSetMode(la, PKT_ALIAS_UNREGISTERED_ONLY, ~0); 71c1fbb54fSLutz Donnerhacke 72f1462ab0SLutz Donnerhacke pip = ip_packet(254, 64); 73f1462ab0SLutz Donnerhacke NAT_CHECK(pip, prv1, ext, masq); 74f1462ab0SLutz Donnerhacke NAT_CHECK(pip, prv2, ext, masq); 75f1462ab0SLutz Donnerhacke NAT_CHECK(pip, prv3, ext, masq); 76f1462ab0SLutz Donnerhacke NAT_CHECK(pip, cgn, ext, cgn); 77f1462ab0SLutz Donnerhacke NAT_CHECK(pip, pub, ext, pub); 78c1fbb54fSLutz Donnerhacke 79c1fbb54fSLutz Donnerhacke /* 80c1fbb54fSLutz Donnerhacke * State is only for new connections 81c1fbb54fSLutz Donnerhacke * Because they are now active, 82c1fbb54fSLutz Donnerhacke * the mode setting should be ignored 83c1fbb54fSLutz Donnerhacke */ 84c1fbb54fSLutz Donnerhacke LibAliasSetMode(la, 0, PKT_ALIAS_UNREGISTERED_ONLY); 85f1462ab0SLutz Donnerhacke NAT_CHECK(pip, prv1, ext, masq); 86f1462ab0SLutz Donnerhacke NAT_CHECK(pip, prv2, ext, masq); 87f1462ab0SLutz Donnerhacke NAT_CHECK(pip, prv3, ext, masq); 88f1462ab0SLutz Donnerhacke NAT_CHECK(pip, cgn, ext, cgn); 89f1462ab0SLutz Donnerhacke NAT_CHECK(pip, pub, ext, pub); 90c1fbb54fSLutz Donnerhacke 91c1fbb54fSLutz Donnerhacke free(pip); 92c1fbb54fSLutz Donnerhacke LibAliasUninit(la); 93c1fbb54fSLutz Donnerhacke } 94c1fbb54fSLutz Donnerhacke 95c1fbb54fSLutz Donnerhacke ATF_TC_WITHOUT_HEAD(3_cgn); 96c1fbb54fSLutz Donnerhacke ATF_TC_BODY(3_cgn, dummy) 97c1fbb54fSLutz Donnerhacke { 98c1fbb54fSLutz Donnerhacke struct libalias *la = LibAliasInit(NULL); 99c1fbb54fSLutz Donnerhacke struct ip *pip; 100c1fbb54fSLutz Donnerhacke 101c1fbb54fSLutz Donnerhacke ATF_REQUIRE(la != NULL); 102c1fbb54fSLutz Donnerhacke LibAliasSetAddress(la, masq); 103c1fbb54fSLutz Donnerhacke LibAliasSetMode(la, PKT_ALIAS_UNREGISTERED_CGN, ~0); 104c1fbb54fSLutz Donnerhacke 105f1462ab0SLutz Donnerhacke pip = ip_packet(254, 64); 106f1462ab0SLutz Donnerhacke NAT_CHECK(pip, prv1, ext, masq); 107f1462ab0SLutz Donnerhacke NAT_CHECK(pip, prv2, ext, masq); 108f1462ab0SLutz Donnerhacke NAT_CHECK(pip, prv3, ext, masq); 109f1462ab0SLutz Donnerhacke NAT_CHECK(pip, cgn, ext, masq); 110f1462ab0SLutz Donnerhacke NAT_CHECK(pip, pub, ext, pub); 111c1fbb54fSLutz Donnerhacke 112c1fbb54fSLutz Donnerhacke /* 113c1fbb54fSLutz Donnerhacke * State is only for new connections 114c1fbb54fSLutz Donnerhacke * Because they are now active, 115c1fbb54fSLutz Donnerhacke * the mode setting should be ignored 116c1fbb54fSLutz Donnerhacke */ 117c1fbb54fSLutz Donnerhacke LibAliasSetMode(la, 0, PKT_ALIAS_UNREGISTERED_CGN); 118f1462ab0SLutz Donnerhacke NAT_CHECK(pip, prv1, ext, masq); 119f1462ab0SLutz Donnerhacke NAT_CHECK(pip, prv2, ext, masq); 120f1462ab0SLutz Donnerhacke NAT_CHECK(pip, prv3, ext, masq); 121f1462ab0SLutz Donnerhacke NAT_CHECK(pip, cgn, ext, masq); 122f1462ab0SLutz Donnerhacke NAT_CHECK(pip, pub, ext, pub); 123c1fbb54fSLutz Donnerhacke 124c1fbb54fSLutz Donnerhacke free(pip); 125c1fbb54fSLutz Donnerhacke LibAliasUninit(la); 126c1fbb54fSLutz Donnerhacke } 127c1fbb54fSLutz Donnerhacke 128c1fbb54fSLutz Donnerhacke ATF_TC_WITHOUT_HEAD(4_udp); 129c1fbb54fSLutz Donnerhacke ATF_TC_BODY(4_udp, dummy) 130c1fbb54fSLutz Donnerhacke { 131c1fbb54fSLutz Donnerhacke struct libalias *la = LibAliasInit(NULL); 132c1fbb54fSLutz Donnerhacke struct ip *po, *pi; 133c1fbb54fSLutz Donnerhacke struct udphdr *ui, *uo; 134c1fbb54fSLutz Donnerhacke uint16_t sport = 0x1234; 135c1fbb54fSLutz Donnerhacke uint16_t dport = 0x5678; 136c1fbb54fSLutz Donnerhacke uint16_t aport; 137c1fbb54fSLutz Donnerhacke 138c1fbb54fSLutz Donnerhacke ATF_REQUIRE(la != NULL); 139c1fbb54fSLutz Donnerhacke LibAliasSetAddress(la, masq); 140c1fbb54fSLutz Donnerhacke LibAliasSetMode(la, 0, ~0); 141c1fbb54fSLutz Donnerhacke 142c1fbb54fSLutz Donnerhacke /* Query from prv1 */ 143f1462ab0SLutz Donnerhacke po = ip_packet(0, 64); 144f1462ab0SLutz Donnerhacke UDP_NAT_CHECK(po, uo, prv1, sport, ext, dport, masq); 145c1fbb54fSLutz Donnerhacke aport = ntohs(uo->uh_sport); 146c1fbb54fSLutz Donnerhacke /* should use a different external port */ 147c1fbb54fSLutz Donnerhacke ATF_CHECK(aport != sport); 148c1fbb54fSLutz Donnerhacke 149c1fbb54fSLutz Donnerhacke /* Response */ 150f1462ab0SLutz Donnerhacke pi = ip_packet(0, 64); 151f1462ab0SLutz Donnerhacke UDP_UNNAT_CHECK(pi, ui, ext, dport, masq, aport, prv1, sport); 152c1fbb54fSLutz Donnerhacke 153c1fbb54fSLutz Donnerhacke /* Query from different source with same ports */ 154f1462ab0SLutz Donnerhacke UDP_NAT_CHECK(po, uo, prv2, sport, ext, dport, masq); 155c1fbb54fSLutz Donnerhacke /* should use a different external port */ 156c1fbb54fSLutz Donnerhacke ATF_CHECK(uo->uh_sport != htons(aport)); 157c1fbb54fSLutz Donnerhacke 158c1fbb54fSLutz Donnerhacke /* Response to prv2 */ 159c1fbb54fSLutz Donnerhacke ui->uh_dport = uo->uh_sport; 160f1462ab0SLutz Donnerhacke UDP_UNNAT_CHECK(pi, ui, ext, dport, masq, htons(uo->uh_sport), prv2, sport); 161c1fbb54fSLutz Donnerhacke 162c1fbb54fSLutz Donnerhacke /* Response to prv1 again */ 163f1462ab0SLutz Donnerhacke UDP_UNNAT_CHECK(pi, ui, ext, dport, masq, aport, prv1, sport); 164c1fbb54fSLutz Donnerhacke 165c1fbb54fSLutz Donnerhacke free(pi); 166c1fbb54fSLutz Donnerhacke free(po); 167c1fbb54fSLutz Donnerhacke LibAliasUninit(la); 168c1fbb54fSLutz Donnerhacke } 169c1fbb54fSLutz Donnerhacke 170c1fbb54fSLutz Donnerhacke ATF_TC_WITHOUT_HEAD(5_sameport); 171c1fbb54fSLutz Donnerhacke ATF_TC_BODY(5_sameport, dummy) 172c1fbb54fSLutz Donnerhacke { 173c1fbb54fSLutz Donnerhacke struct libalias *la = LibAliasInit(NULL); 174c1fbb54fSLutz Donnerhacke struct ip *p; 175c1fbb54fSLutz Donnerhacke struct udphdr *u; 176c1fbb54fSLutz Donnerhacke uint16_t sport = 0x1234; 177c1fbb54fSLutz Donnerhacke uint16_t dport = 0x5678; 178c1fbb54fSLutz Donnerhacke uint16_t aport; 179c1fbb54fSLutz Donnerhacke 180c1fbb54fSLutz Donnerhacke ATF_REQUIRE(la != NULL); 181c1fbb54fSLutz Donnerhacke LibAliasSetAddress(la, masq); 182c1fbb54fSLutz Donnerhacke LibAliasSetMode(la, PKT_ALIAS_SAME_PORTS, ~0); 183c1fbb54fSLutz Donnerhacke 184c1fbb54fSLutz Donnerhacke /* Query from prv1 */ 185f1462ab0SLutz Donnerhacke p = ip_packet(0, 64); 186f1462ab0SLutz Donnerhacke UDP_NAT_CHECK(p, u, prv1, sport, ext, dport, masq); 187c1fbb54fSLutz Donnerhacke aport = ntohs(u->uh_sport); 188c1fbb54fSLutz Donnerhacke /* should use the same external port */ 189c1fbb54fSLutz Donnerhacke ATF_CHECK(aport == sport); 190c1fbb54fSLutz Donnerhacke 191c1fbb54fSLutz Donnerhacke /* Query from different source with same ports */ 192f1462ab0SLutz Donnerhacke UDP_NAT_CHECK(p, u, prv2, sport, ext, dport, masq); 193c1fbb54fSLutz Donnerhacke /* should use a different external port */ 194c1fbb54fSLutz Donnerhacke ATF_CHECK(u->uh_sport != htons(aport)); 195c1fbb54fSLutz Donnerhacke 196c1fbb54fSLutz Donnerhacke free(p); 197c1fbb54fSLutz Donnerhacke LibAliasUninit(la); 198c1fbb54fSLutz Donnerhacke } 199c1fbb54fSLutz Donnerhacke 200c1fbb54fSLutz Donnerhacke ATF_TC_WITHOUT_HEAD(6_cleartable); 201c1fbb54fSLutz Donnerhacke ATF_TC_BODY(6_cleartable, dummy) 202c1fbb54fSLutz Donnerhacke { 203c1fbb54fSLutz Donnerhacke struct libalias *la = LibAliasInit(NULL); 204c1fbb54fSLutz Donnerhacke struct ip *po, *pi; 205*c555dcddSJohn Baldwin struct udphdr *ui __unused, *uo; 206c1fbb54fSLutz Donnerhacke uint16_t sport = 0x1234; 207c1fbb54fSLutz Donnerhacke uint16_t dport = 0x5678; 208c1fbb54fSLutz Donnerhacke uint16_t aport; 209c1fbb54fSLutz Donnerhacke 210c1fbb54fSLutz Donnerhacke ATF_REQUIRE(la != NULL); 211c1fbb54fSLutz Donnerhacke LibAliasSetAddress(la, masq); 212c1fbb54fSLutz Donnerhacke LibAliasSetMode(la, PKT_ALIAS_RESET_ON_ADDR_CHANGE, ~0); 213c1fbb54fSLutz Donnerhacke LibAliasSetMode(la, PKT_ALIAS_SAME_PORTS, PKT_ALIAS_SAME_PORTS); 214c1fbb54fSLutz Donnerhacke LibAliasSetMode(la, PKT_ALIAS_DENY_INCOMING, PKT_ALIAS_DENY_INCOMING); 215c1fbb54fSLutz Donnerhacke 216c1fbb54fSLutz Donnerhacke /* Query from prv1 */ 217f1462ab0SLutz Donnerhacke po = ip_packet(0, 64); 218f1462ab0SLutz Donnerhacke UDP_NAT_CHECK(po, uo, prv1, sport, ext, dport, masq); 219c1fbb54fSLutz Donnerhacke aport = ntohs(uo->uh_sport); 220c1fbb54fSLutz Donnerhacke /* should use the same external port */ 221c1fbb54fSLutz Donnerhacke ATF_CHECK(aport == sport); 222c1fbb54fSLutz Donnerhacke 223c1fbb54fSLutz Donnerhacke /* Response */ 224f1462ab0SLutz Donnerhacke pi = ip_packet(0, 64); 225f1462ab0SLutz Donnerhacke UDP_UNNAT_CHECK(po, uo, ext, dport, masq, aport, prv1, sport); 226c1fbb54fSLutz Donnerhacke 227c1fbb54fSLutz Donnerhacke /* clear table by keeping the address */ 228c1fbb54fSLutz Donnerhacke LibAliasSetAddress(la, ext); 229c1fbb54fSLutz Donnerhacke LibAliasSetAddress(la, masq); 230c1fbb54fSLutz Donnerhacke 231c1fbb54fSLutz Donnerhacke /* Response to prv1 again -> DENY_INCOMING */ 232f1462ab0SLutz Donnerhacke UDP_UNNAT_FAIL(pi, ui, ext, dport, masq, aport); 233c1fbb54fSLutz Donnerhacke 234c1fbb54fSLutz Donnerhacke /* Query from different source with same ports */ 235f1462ab0SLutz Donnerhacke UDP_NAT_CHECK(po, uo, prv2, sport, ext, dport, masq); 236c1fbb54fSLutz Donnerhacke /* should use the same external port, because it's free */ 237c1fbb54fSLutz Donnerhacke ATF_CHECK(uo->uh_sport == htons(aport)); 238c1fbb54fSLutz Donnerhacke 239c1fbb54fSLutz Donnerhacke /* Response to prv2 */ 240f1462ab0SLutz Donnerhacke UDP_UNNAT_CHECK(po, uo, ext, dport, masq, htons(uo->uh_sport), prv2, sport); 241c1fbb54fSLutz Donnerhacke 242c1fbb54fSLutz Donnerhacke free(pi); 243c1fbb54fSLutz Donnerhacke free(po); 244c1fbb54fSLutz Donnerhacke LibAliasUninit(la); 245c1fbb54fSLutz Donnerhacke } 246c1fbb54fSLutz Donnerhacke 247c1fbb54fSLutz Donnerhacke ATF_TC_WITHOUT_HEAD(7_stress); 248c1fbb54fSLutz Donnerhacke ATF_TC_BODY(7_stress, dummy) 249c1fbb54fSLutz Donnerhacke { 250c1fbb54fSLutz Donnerhacke struct libalias *la = LibAliasInit(NULL); 251c1fbb54fSLutz Donnerhacke struct ip *p; 252c1fbb54fSLutz Donnerhacke struct udphdr *u; 253c1fbb54fSLutz Donnerhacke struct { 254c1fbb54fSLutz Donnerhacke struct in_addr src, dst; 255c1fbb54fSLutz Donnerhacke uint16_t sport, dport, aport; 256c1fbb54fSLutz Donnerhacke } *batch; 257a660948bSLutz Donnerhacke size_t const batch_size = 1200; 258c1fbb54fSLutz Donnerhacke size_t const rounds = 25; 259c1fbb54fSLutz Donnerhacke size_t i, j; 260c1fbb54fSLutz Donnerhacke 261c1fbb54fSLutz Donnerhacke ATF_REQUIRE(la != NULL); 262c1fbb54fSLutz Donnerhacke LibAliasSetAddress(la, masq); 263c1fbb54fSLutz Donnerhacke 264f1462ab0SLutz Donnerhacke p = ip_packet(0, 64); 265c1fbb54fSLutz Donnerhacke 266c1fbb54fSLutz Donnerhacke batch = calloc(batch_size, sizeof(*batch)); 267c1fbb54fSLutz Donnerhacke ATF_REQUIRE(batch != NULL); 268c1fbb54fSLutz Donnerhacke for (j = 0; j < rounds; j++) { 269c1fbb54fSLutz Donnerhacke for (i = 0; i < batch_size; i++) { 270c1fbb54fSLutz Donnerhacke struct in_addr s, d; 271c1fbb54fSLutz Donnerhacke switch (i&3) { 272c1fbb54fSLutz Donnerhacke case 0: s = prv1; d = ext; break; 273c1fbb54fSLutz Donnerhacke case 1: s = prv2; d = pub; break; 274c1fbb54fSLutz Donnerhacke case 2: s = prv3; d = ext; break; 275c1fbb54fSLutz Donnerhacke case 3: s = cgn; d = pub; break; 276c1fbb54fSLutz Donnerhacke } 277c1fbb54fSLutz Donnerhacke s.s_addr &= htonl(0xffff0000); 278c1fbb54fSLutz Donnerhacke d.s_addr &= htonl(0xffff0000); 279c1fbb54fSLutz Donnerhacke batch[i].src.s_addr = s.s_addr | htonl(rand_range(0, 0xffff)); 280c1fbb54fSLutz Donnerhacke batch[i].dst.s_addr = d.s_addr | htonl(rand_range(0, 0xffff)); 281c1fbb54fSLutz Donnerhacke batch[i].sport = rand_range(1000, 60000); 282c1fbb54fSLutz Donnerhacke batch[i].dport = rand_range(1000, 60000); 283c1fbb54fSLutz Donnerhacke } 284c1fbb54fSLutz Donnerhacke 285c1fbb54fSLutz Donnerhacke for (i = 0; i < batch_size; i++) { 286f1462ab0SLutz Donnerhacke UDP_NAT_CHECK(p, u, 287f1462ab0SLutz Donnerhacke batch[i].src, batch[i].sport, 288f1462ab0SLutz Donnerhacke batch[i].dst, batch[i].dport, 289f1462ab0SLutz Donnerhacke masq); 290c1fbb54fSLutz Donnerhacke batch[i].aport = htons(u->uh_sport); 291c1fbb54fSLutz Donnerhacke } 292c1fbb54fSLutz Donnerhacke 293c1fbb54fSLutz Donnerhacke qsort(batch, batch_size, sizeof(*batch), randcmp); 294c1fbb54fSLutz Donnerhacke 295c1fbb54fSLutz Donnerhacke for (i = 0; i < batch_size; i++) { 296f1462ab0SLutz Donnerhacke UDP_UNNAT_CHECK(p, u, 297f1462ab0SLutz Donnerhacke batch[i].dst, batch[i].dport, 298f1462ab0SLutz Donnerhacke masq, batch[i].aport, 299f1462ab0SLutz Donnerhacke batch[i].src, batch[i].sport); 300c1fbb54fSLutz Donnerhacke } 301c1fbb54fSLutz Donnerhacke } 302c1fbb54fSLutz Donnerhacke 303c1fbb54fSLutz Donnerhacke free(batch); 304c1fbb54fSLutz Donnerhacke free(p); 305c1fbb54fSLutz Donnerhacke LibAliasUninit(la); 306c1fbb54fSLutz Donnerhacke } 307c1fbb54fSLutz Donnerhacke 3082c733b50SLutz Donnerhacke ATF_TC_WITHOUT_HEAD(8_portrange); 3092c733b50SLutz Donnerhacke ATF_TC_BODY(8_portrange, dummy) 3102c733b50SLutz Donnerhacke { 3112c733b50SLutz Donnerhacke struct libalias *la = LibAliasInit(NULL); 3122c733b50SLutz Donnerhacke struct ip *po; 3132c733b50SLutz Donnerhacke struct udphdr *uo; 3142c733b50SLutz Donnerhacke uint16_t sport = 0x1234; 3152c733b50SLutz Donnerhacke uint16_t dport = 0x5678; 3162c733b50SLutz Donnerhacke uint16_t aport; 3172c733b50SLutz Donnerhacke 3182c733b50SLutz Donnerhacke ATF_REQUIRE(la != NULL); 3192c733b50SLutz Donnerhacke LibAliasSetAddress(la, masq); 3202c733b50SLutz Donnerhacke LibAliasSetMode(la, 0, ~0); 3212c733b50SLutz Donnerhacke po = ip_packet(0, 64); 3222c733b50SLutz Donnerhacke 3232c733b50SLutz Donnerhacke LibAliasSetAliasPortRange(la, 0, 0); /* reinit like ipfw */ 3242c733b50SLutz Donnerhacke UDP_NAT_CHECK(po, uo, prv1, sport, ext, dport, masq); 3252c733b50SLutz Donnerhacke aport = ntohs(uo->uh_sport); 3262c733b50SLutz Donnerhacke ATF_CHECK(aport >= 0x8000); 3272c733b50SLutz Donnerhacke 3282c733b50SLutz Donnerhacke /* Different larger range */ 3292c733b50SLutz Donnerhacke LibAliasSetAliasPortRange(la, 2000, 3000); 3302c733b50SLutz Donnerhacke dport++; 3312c733b50SLutz Donnerhacke UDP_NAT_CHECK(po, uo, prv1, sport, ext, dport, masq); 3322c733b50SLutz Donnerhacke aport = ntohs(uo->uh_sport); 3332c733b50SLutz Donnerhacke ATF_CHECK(aport >= 2000 && aport < 3000); 3342c733b50SLutz Donnerhacke 3352c733b50SLutz Donnerhacke /* Different small range (contains two ports) */ 3362c733b50SLutz Donnerhacke LibAliasSetAliasPortRange(la, 4000, 4001); 3372c733b50SLutz Donnerhacke dport++; 3382c733b50SLutz Donnerhacke UDP_NAT_CHECK(po, uo, prv1, sport, ext, dport, masq); 3392c733b50SLutz Donnerhacke aport = ntohs(uo->uh_sport); 3402c733b50SLutz Donnerhacke ATF_CHECK(aport >= 4000 && aport <= 4001); 3412c733b50SLutz Donnerhacke 3422c733b50SLutz Donnerhacke sport++; 3432c733b50SLutz Donnerhacke UDP_NAT_CHECK(po, uo, prv1, sport, ext, dport, masq); 3442c733b50SLutz Donnerhacke aport = ntohs(uo->uh_sport); 3452c733b50SLutz Donnerhacke ATF_CHECK(aport >= 4000 && aport <= 4001); 3462c733b50SLutz Donnerhacke 3472c733b50SLutz Donnerhacke /* Third port not available in the range */ 3482c733b50SLutz Donnerhacke sport++; 3492c733b50SLutz Donnerhacke UDP_NAT_FAIL(po, uo, prv1, sport, ext, dport); 3502c733b50SLutz Donnerhacke 3512c733b50SLutz Donnerhacke /* Back to normal */ 3522c733b50SLutz Donnerhacke LibAliasSetAliasPortRange(la, 0, 0); 3532c733b50SLutz Donnerhacke dport++; 3542c733b50SLutz Donnerhacke UDP_NAT_CHECK(po, uo, prv1, sport, ext, dport, masq); 3552c733b50SLutz Donnerhacke aport = ntohs(uo->uh_sport); 3562c733b50SLutz Donnerhacke ATF_CHECK(aport >= 0x8000); 3572c733b50SLutz Donnerhacke 3582c733b50SLutz Donnerhacke free(po); 3592c733b50SLutz Donnerhacke LibAliasUninit(la); 3602c733b50SLutz Donnerhacke } 3612c733b50SLutz Donnerhacke 362c1fbb54fSLutz Donnerhacke ATF_TP_ADD_TCS(natout) 363c1fbb54fSLutz Donnerhacke { 364c1fbb54fSLutz Donnerhacke /* Use "dd if=/dev/random bs=2 count=1 | od -x" to reproduce */ 365c1fbb54fSLutz Donnerhacke srand(0x0b61); 366c1fbb54fSLutz Donnerhacke 367c1fbb54fSLutz Donnerhacke ATF_TP_ADD_TC(natout, 1_simplemasq); 368c1fbb54fSLutz Donnerhacke ATF_TP_ADD_TC(natout, 2_unregistered); 369c1fbb54fSLutz Donnerhacke ATF_TP_ADD_TC(natout, 3_cgn); 370c1fbb54fSLutz Donnerhacke ATF_TP_ADD_TC(natout, 4_udp); 371c1fbb54fSLutz Donnerhacke ATF_TP_ADD_TC(natout, 5_sameport); 372c1fbb54fSLutz Donnerhacke ATF_TP_ADD_TC(natout, 6_cleartable); 373c1fbb54fSLutz Donnerhacke ATF_TP_ADD_TC(natout, 7_stress); 3742c733b50SLutz Donnerhacke ATF_TP_ADD_TC(natout, 8_portrange); 375c1fbb54fSLutz Donnerhacke 376c1fbb54fSLutz Donnerhacke return atf_no_error(); 377c1fbb54fSLutz Donnerhacke } 378