Path: blob/main/tests/sys/netinet/libalias/3_natin.c
39488 views
/*1* SPDX-License-Identifier: BSD-3-Clause2*3* Copyright 2021 Lutz Donnerhacke4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8*9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11* 2. Redistributions in binary form must reproduce the above12* copyright notice, this list of conditions and the following13* disclaimer in the documentation and/or other materials provided14* with the distribution.15* 3. Neither the name of the copyright holder nor the names of its16* contributors may be used to endorse or promote products derived17* from this software without specific prior written permission.18*19* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND20* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,21* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF22* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE23* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS24* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,25* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED26* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,27* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON28* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR29* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF30* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF31* SUCH DAMAGE.32*/33#include <atf-c.h>34#include <alias.h>35#include <stdio.h>36#include <stdlib.h>3738#include "util.h"3940ATF_TC_WITHOUT_HEAD(1_portforward);41ATF_TC_BODY(1_portforward, dummy)42{43struct libalias *la = LibAliasInit(NULL);44struct alias_link *pf1, *pf2, *pf3, *pf4;45struct ip *p;46struct udphdr *u;4748ATF_REQUIRE(la != NULL);49LibAliasSetAddress(la, masq);50LibAliasSetMode(la, PKT_ALIAS_RESET_ON_ADDR_CHANGE, ~0);51LibAliasSetMode(la, PKT_ALIAS_DENY_INCOMING, PKT_ALIAS_DENY_INCOMING);5253/*54* Fully specified55*/56pf1 = LibAliasRedirectPort(la, prv1, ntohs(0x1234), ext, ntohs(0x5678), masq, ntohs(0xabcd), IPPROTO_UDP);57ATF_REQUIRE(pf1 != NULL);5859p = ip_packet(0, 64);60UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv1, 0x1234);61/* try again */62UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv1, 0x1234);63/* different source */64UDP_UNNAT_FAIL(p, u, pub, 0x5678, masq, 0xabcd);65UDP_UNNAT_FAIL(p, u, ext, 0xdead, masq, 0xabcd);6667/* clear table by keeping the address */68LibAliasSetAddress(la, ext);69LibAliasSetAddress(la, masq);7071/* delete and try again */72LibAliasRedirectDelete(la, pf1);73UDP_UNNAT_FAIL(p, u, ext, 0x5678, masq, 0xabcd);7475/*76* Any external port77*/78pf2 = LibAliasRedirectPort(la, prv2, ntohs(0x1234), ext, ntohs(0), masq, ntohs(0xabcd), IPPROTO_UDP);79ATF_REQUIRE(pf2 != NULL);8081UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv2, 0x1234);82/* try again */83UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv2, 0x1234);84/* different source */85UDP_UNNAT_FAIL(p, u, pub, 0x5678, masq, 0xabcd);86UDP_UNNAT_CHECK(p, u, ext, 0xdead, masq, 0xabcd, prv2, 0x1234);8788/* clear table by keeping the address */89LibAliasSetAddress(la, ext);90LibAliasSetAddress(la, masq);9192/* delete and try again */93LibAliasRedirectDelete(la, pf2);94UDP_UNNAT_FAIL(p, u, ext, 0x5678, masq, 0xabcd);9596/*97* Any external host98*/99pf3 = LibAliasRedirectPort(la, prv3, ntohs(0x1234), ANY_ADDR, ntohs(0x5678), masq, ntohs(0xabcd), IPPROTO_UDP);100ATF_REQUIRE(pf3 != NULL);101102UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv3, 0x1234);103/* try again */104UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv3, 0x1234);105/* different source */106UDP_UNNAT_CHECK(p, u, pub, 0x5678, masq, 0xabcd, prv3, 0x1234);107UDP_UNNAT_FAIL(p, u, ext, 0xdead, masq, 0xabcd);108109/* clear table by keeping the address */110LibAliasSetAddress(la, ext);111LibAliasSetAddress(la, masq);112113/* delete and try again */114LibAliasRedirectDelete(la, pf3);115UDP_UNNAT_FAIL(p, u, ext, 0x5678, masq, 0xabcd);116117/*118* Any external host, any port119*/120pf4 = LibAliasRedirectPort(la, cgn, ntohs(0x1234), ANY_ADDR, ntohs(0), masq, ntohs(0xabcd), IPPROTO_UDP);121ATF_REQUIRE(pf4 != NULL);122123UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, cgn, 0x1234);124/* try again */125UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, cgn, 0x1234);126/* different source */127UDP_UNNAT_CHECK(p, u, pub, 0x5678, masq, 0xabcd, cgn, 0x1234);128UDP_UNNAT_CHECK(p, u, ext, 0xdead, masq, 0xabcd, cgn, 0x1234);129130/* clear table by keeping the address */131LibAliasSetAddress(la, ext);132LibAliasSetAddress(la, masq);133134/* delete and try again */135LibAliasRedirectDelete(la, pf4);136UDP_UNNAT_FAIL(p, u, ext, 0x5678, masq, 0xabcd);137138free(p);139LibAliasUninit(la);140}141142ATF_TC_WITHOUT_HEAD(2_portoverlap);143ATF_TC_BODY(2_portoverlap, dummy)144{145struct libalias *la = LibAliasInit(NULL);146struct alias_link *pf1, *pf2, *pf3, *pf4;147struct ip *p;148struct udphdr *u;149150ATF_REQUIRE(la != NULL);151LibAliasSetAddress(la, masq);152LibAliasSetMode(la, PKT_ALIAS_RESET_ON_ADDR_CHANGE, ~0);153LibAliasSetMode(la, PKT_ALIAS_DENY_INCOMING, PKT_ALIAS_DENY_INCOMING);154155/*156* Fully specified157*/158pf1 = LibAliasRedirectPort(la, prv2, ntohs(0x1234), ext, ntohs(0x5678), masq, ntohs(0xabcd), IPPROTO_UDP);159ATF_REQUIRE(pf1 != NULL);160161p = ip_packet(0, 64);162UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv2, 0x1234);163164/* clear table by keeping the address */165LibAliasSetAddress(la, ext);166LibAliasSetAddress(la, masq);167168/*169* Fully specified (override)170*/171pf1 = LibAliasRedirectPort(la, prv1, ntohs(0x1234), ext, ntohs(0x5678), masq, ntohs(0xabcd), IPPROTO_UDP);172ATF_REQUIRE(pf1 != NULL);173174UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv1, 0x1234);175176/* clear table by keeping the address */177LibAliasSetAddress(la, ext);178LibAliasSetAddress(la, masq);179180/*181* Any external port182*/183pf2 = LibAliasRedirectPort(la, prv2, ntohs(0x1234), ext, ntohs(0), masq, ntohs(0xabcd), IPPROTO_UDP);184ATF_REQUIRE(pf2 != NULL);185186UDP_UNNAT_CHECK(p, u, ext, 0x5679, masq, 0xabcd, prv2, 0x1234);187/* more specific rule wins */188UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv1, 0x1234);189190/* clear table by keeping the address */191LibAliasSetAddress(la, ext);192LibAliasSetAddress(la, masq);193194/*195* Any external host196*/197pf3 = LibAliasRedirectPort(la, prv3, ntohs(0x1234), ANY_ADDR, ntohs(0x5678), masq, ntohs(0xabcd), IPPROTO_UDP);198ATF_REQUIRE(pf3 != NULL);199200UDP_UNNAT_CHECK(p, u, pub, 0x5678, masq, 0xabcd, prv3, 0x1234);201/* more specific rule wins */202UDP_UNNAT_CHECK(p, u, ext, 0x5679, masq, 0xabcd, prv2, 0x1234);203UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv1, 0x1234);204205/* clear table by keeping the address */206LibAliasSetAddress(la, ext);207LibAliasSetAddress(la, masq);208209/*210* Any external host, any port211*/212pf4 = LibAliasRedirectPort(la, cgn, ntohs(0x1234), ANY_ADDR, ntohs(0), masq, ntohs(0xabcd), IPPROTO_UDP);213ATF_REQUIRE(pf4 != NULL);214215UDP_UNNAT_CHECK(p, u, prv1, 0x5679, masq, 0xabcd, cgn, 0x1234);216/* more specific rule wins */217UDP_UNNAT_CHECK(p, u, pub, 0x5678, masq, 0xabcd, prv3, 0x1234);218UDP_UNNAT_CHECK(p, u, ext, 0x5679, masq, 0xabcd, prv2, 0x1234);219UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv1, 0x1234);220221free(p);222LibAliasUninit(la);223}224225ATF_TC_WITHOUT_HEAD(3_redirectany);226ATF_TC_BODY(3_redirectany, dummy)227{228struct libalias *la = LibAliasInit(NULL);229struct alias_link *pf;230struct ip *p;231struct udphdr *u;232233ATF_REQUIRE(la != NULL);234LibAliasSetMode(la, PKT_ALIAS_DENY_INCOMING, ~0);235p = ip_packet(0, 64);236237pf = LibAliasRedirectPort(la, prv1, ntohs(0x1234), ANY_ADDR, 0, ANY_ADDR, ntohs(0xabcd), IPPROTO_UDP);238ATF_REQUIRE(pf != NULL);239240LibAliasSetAddress(la, masq);241UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv1, 0x1234);242UDP_UNNAT_FAIL(p, u, pub, 0x5678, pub, 0xabcd);243244LibAliasSetAddress(la, pub);245UDP_UNNAT_CHECK(p, u, pub, 0x5679, pub, 0xabcd, prv1, 0x1234);246UDP_UNNAT_FAIL(p, u, ext, 0x5679, masq, 0xabcd);247248free(p);249LibAliasUninit(la);250}251252ATF_TC_WITHOUT_HEAD(4_redirectaddr);253ATF_TC_BODY(4_redirectaddr, dummy)254{255struct libalias *la = LibAliasInit(NULL);256struct alias_link *pf1, *pf2;257struct ip *p;258259ATF_REQUIRE(la != NULL);260LibAliasSetAddress(la, masq);261pf1 = LibAliasRedirectAddr(la, prv1, pub);262ATF_REQUIRE(pf1 != NULL);263264p = ip_packet(254, 64);265UNNAT_CHECK(p, ext, pub, prv1);266UNNAT_CHECK(p, ext, masq, masq);267268pf2 = LibAliasRedirectAddr(la, prv2, pub);269ATF_REQUIRE(pf2 != NULL);270UNNAT_CHECK(p, ext, pub, prv1);271p->ip_p = 253; /* new flows */272UNNAT_CHECK(p, ext, pub, prv2);273UNNAT_CHECK(p, ext, masq, masq);274275p->ip_p = 252; /* new flows */276NAT_CHECK(p, prv1, ext, pub);277NAT_CHECK(p, prv2, ext, pub);278NAT_CHECK(p, prv3, ext, masq);279280LibAliasSetMode(la, PKT_ALIAS_DENY_INCOMING, ~0);281p->ip_p = 251; /* new flows */282UNNAT_FAIL(p, ext, pub);283UNNAT_FAIL(p, ext, masq);284285/* unhide older version */286LibAliasRedirectDelete(la, pf2);287LibAliasSetMode(la, 0, ~0);288p->ip_p = 250; /* new flows */289UNNAT_CHECK(p, ext, pub, prv1);290291p->ip_p = 249; /* new flows */292NAT_CHECK(p, prv1, ext, pub);293NAT_CHECK(p, prv2, ext, masq);294NAT_CHECK(p, prv3, ext, masq);295296free(p);297LibAliasUninit(la);298}299300ATF_TC_WITHOUT_HEAD(5_lsnat);301ATF_TC_BODY(5_lsnat, dummy)302{303struct libalias *la = LibAliasInit(NULL);304struct alias_link *pf;305struct ip *p;306struct udphdr *u;307308ATF_REQUIRE(la != NULL);309LibAliasSetMode(la, 0, ~0);310p = ip_packet(0, 64);311312pf = LibAliasRedirectPort(la, cgn, ntohs(0xdead), ANY_ADDR, 0, masq, ntohs(0xabcd), IPPROTO_UDP);313ATF_REQUIRE(pf != NULL);314315ATF_REQUIRE(0 == LibAliasAddServer(la, pf, prv1, ntohs(0x1234)));316ATF_REQUIRE(0 == LibAliasAddServer(la, pf, prv2, ntohs(0x2345)));317ATF_REQUIRE(0 == LibAliasAddServer(la, pf, prv3, ntohs(0x3456)));318319UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv3, 0x3456);320UDP_UNNAT_CHECK(p, u, ext, 0x5679, masq, 0xabcd, prv2, 0x2345);321UDP_UNNAT_CHECK(p, u, ext, 0x567a, masq, 0xabcd, prv1, 0x1234);322UDP_UNNAT_CHECK(p, u, ext, 0x567b, masq, 0xabcd, prv3, 0x3456);323UDP_UNNAT_CHECK(p, u, ext, 0x567c, masq, 0xabcd, prv2, 0x2345);324UDP_UNNAT_CHECK(p, u, ext, 0x567d, masq, 0xabcd, prv1, 0x1234);325326free(p);327LibAliasUninit(la);328}329330ATF_TC_WITHOUT_HEAD(6_oneshot);331ATF_TC_BODY(6_oneshot, dummy)332{333struct libalias *la = LibAliasInit(NULL);334struct alias_link *pf;335struct ip *p;336struct udphdr *u;337338ATF_REQUIRE(la != NULL);339LibAliasSetMode(la, 0, ~0);340LibAliasSetMode(la, PKT_ALIAS_RESET_ON_ADDR_CHANGE, ~0);341LibAliasSetMode(la, PKT_ALIAS_DENY_INCOMING, PKT_ALIAS_DENY_INCOMING);342343pf = LibAliasRedirectPort(la, prv1, ntohs(0x1234), ANY_ADDR, 0, masq, ntohs(0xabcd), IPPROTO_UDP);344ATF_REQUIRE(pf != NULL);345/* only for fully specified links */346ATF_CHECK(-1 == LibAliasRedirectDynamic(la, pf));347LibAliasRedirectDelete(la, pf);348349pf = LibAliasRedirectPort(la, prv1, ntohs(0x1234), ext, ntohs(0x5678), masq, ntohs(0xabcd), IPPROTO_UDP);350ATF_REQUIRE(pf != NULL);351ATF_CHECK(0 == LibAliasRedirectDynamic(la, pf));352353p = ip_packet(0, 64);354UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv1, 0x1234);355356/* clear table by keeping the address */357LibAliasSetAddress(la, ext);358LibAliasSetAddress(la, masq);359360/* does not work anymore */361UDP_UNNAT_FAIL(p, u, ext, 0x5678, masq, 0xabcd);362363free(p);364LibAliasUninit(la);365}366367ATF_TP_ADD_TCS(natin)368{369/* Use "dd if=/dev/random bs=2 count=1 | od -x" to reproduce */370srand(0xe859);371372ATF_TP_ADD_TC(natin, 1_portforward);373ATF_TP_ADD_TC(natin, 2_portoverlap);374ATF_TP_ADD_TC(natin, 3_redirectany);375ATF_TP_ADD_TC(natin, 4_redirectaddr);376ATF_TP_ADD_TC(natin, 5_lsnat);377ATF_TP_ADD_TC(natin, 6_oneshot);378379return atf_no_error();380}381382383