Index: tests/sys/netinet/libalias/3_natin.c =================================================================== --- /dev/null +++ tests/sys/netinet/libalias/3_natin.c @@ -0,0 +1,273 @@ +#include +#include +#include +#include + +#include "util.h" + +ATF_TC_WITHOUT_HEAD(1_portforward); +ATF_TC_BODY(1_portforward, dummy) +{ + struct libalias *la = LibAliasInit(NULL); + struct alias_link *pf1, *pf2, *pf3, *pf4; + struct ip *p; + struct udphdr *u; + + ATF_REQUIRE(la != NULL); + LibAliasSetAddress(la, masq); + LibAliasSetMode(la, PKT_ALIAS_RESET_ON_ADDR_CHANGE, ~0); + LibAliasSetMode(la, PKT_ALIAS_DENY_INCOMING, PKT_ALIAS_DENY_INCOMING); + + /* + * Fully specified + */ + pf1 = LibAliasRedirectPort(la, prv1, ntohs(0x1234), ext, ntohs(0x5678), masq, ntohs(0xabcd), IPPROTO_UDP); + ATF_REQUIRE(pf1 != NULL); + + p = ip_packet(0, 64); + UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv1, 0x1234); + + /* try again */ + UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv1, 0x1234); + + /* different source */ + UDP_UNNAT_FAIL(p, u, pub, 0x5678, masq, 0xabcd); + UDP_UNNAT_FAIL(p, u, ext, 0xdead, masq, 0xabcd); + + /* clear table by keeping the address */ + LibAliasSetAddress(la, ext); + LibAliasSetAddress(la, masq); + + /* delete and try again */ + LibAliasRedirectDelete(la, pf1); + UDP_UNNAT_FAIL(p, u, ext, 0x5678, masq, 0xabcd); + + /* + * Any external port + */ + pf2 = LibAliasRedirectPort(la, prv2, ntohs(0x1234), ext, ntohs(0), masq, ntohs(0xabcd), IPPROTO_UDP); + ATF_REQUIRE(pf2 != NULL); + + u = set_udp(p, 0x5678, 0xabcd); + UNNAT_CHECK(p, ext, masq, prv2); + ATF_CHECK(u->uh_sport == ntohs(0x5678)); + ATF_CHECK(u->uh_dport == ntohs(0x1234)); + + /* try again */ + u = set_udp(p, 0x5678, 0xabcd); + UNNAT_CHECK(p, ext, masq, prv2); + ATF_CHECK(u->uh_sport == ntohs(0x5678)); + ATF_CHECK(u->uh_dport == ntohs(0x1234)); + + /* different source */ + u = set_udp(p, 0x5678, 0xabcd); + UNNAT_FAIL(p, pub, masq); + u = set_udp(p, 0xdead, 0xabcd); + UNNAT_CHECK(p, ext, masq, prv2); + ATF_CHECK(u->uh_sport == ntohs(0xdead)); + ATF_CHECK(u->uh_dport == ntohs(0x1234)); + + /* clear table by keeping the address */ + LibAliasSetAddress(la, ext); + LibAliasSetAddress(la, masq); + + LibAliasRedirectDelete(la, pf2); + /* try again, but not the existing flow */ + u = set_udp(p, 0x5678, 0xabcd); + UNNAT_FAIL(p, ext, masq); + + /* + * Any external host + */ + pf3 = LibAliasRedirectPort(la, prv3, ntohs(0x1234), ANY_ADDR, ntohs(0x5678), masq, ntohs(0xabcd), IPPROTO_UDP); + ATF_REQUIRE(pf3 != NULL); + + u = set_udp(p, 0x5678, 0xabcd); + UNNAT_CHECK(p, ext, masq, prv3); + ATF_CHECK(u->uh_sport == ntohs(0x5678)); + ATF_CHECK(u->uh_dport == ntohs(0x1234)); + + /* try again */ + u = set_udp(p, 0x5678, 0xabcd); + UNNAT_CHECK(p, ext, masq, prv3); + ATF_CHECK(u->uh_sport == ntohs(0x5678)); + ATF_CHECK(u->uh_dport == ntohs(0x1234)); + + /* different source */ + u = set_udp(p, 0x5678, 0xabcd); + UNNAT_CHECK(p, pub, masq, prv3); + ATF_CHECK(u->uh_sport == ntohs(0x5678)); + ATF_CHECK(u->uh_dport == ntohs(0x1234)); + u = set_udp(p, 0xdead, 0xabcd); + UNNAT_FAIL(p, ext, masq); + + /* clear table by keeping the address */ + LibAliasSetAddress(la, ext); + LibAliasSetAddress(la, masq); + + LibAliasRedirectDelete(la, pf3); + /* try again, but not the existing flow */ + u = set_udp(p, 0x5678, 0xabcd); + UNNAT_FAIL(p, ext, masq); + + /* + * Any external host, any port + */ + pf4 = LibAliasRedirectPort(la, cgn, ntohs(0x1234), ANY_ADDR, ntohs(0), masq, ntohs(0xabcd), IPPROTO_UDP); + ATF_REQUIRE(pf4 != NULL); + + u = set_udp(p, 0x5678, 0xabcd); + UNNAT_CHECK(p, ext, masq, cgn); + ATF_CHECK(u->uh_sport == ntohs(0x5678)); + ATF_CHECK(u->uh_dport == ntohs(0x1234)); + + /* try again */ + u = set_udp(p, 0x5678, 0xabcd); + UNNAT_CHECK(p, ext, masq, cgn); + ATF_CHECK(u->uh_sport == ntohs(0x5678)); + ATF_CHECK(u->uh_dport == ntohs(0x1234)); + + /* different source */ + u = set_udp(p, 0x5678, 0xabcd); + UNNAT_CHECK(p, pub, masq, cgn); + ATF_CHECK(u->uh_sport == ntohs(0x5678)); + ATF_CHECK(u->uh_dport == ntohs(0x1234)); + u = set_udp(p, 0xdead, 0xabcd); + UNNAT_CHECK(p, ext, masq, cgn); + ATF_CHECK(u->uh_sport == ntohs(0xdead)); + ATF_CHECK(u->uh_dport == ntohs(0x1234)); + + /* clear table by keeping the address */ + LibAliasSetAddress(la, ext); + LibAliasSetAddress(la, masq); + + LibAliasRedirectDelete(la, pf4); + /* try again, but not the existing flow */ + u = set_udp(p, 0x5678, 0xabcd); + UNNAT_FAIL(p, ext, masq); + + free(p); + LibAliasUninit(la); +} + +ATF_TC_WITHOUT_HEAD(2_portoverlap); +ATF_TC_BODY(2_portoverlap, dummy) +{ + struct libalias *la = LibAliasInit(NULL); + struct alias_link *pf1, *pf2, *pf3, *pf4; + struct ip *p; + struct udphdr *u; + + ATF_REQUIRE(la != NULL); + LibAliasSetAddress(la, masq); + LibAliasSetMode(la, PKT_ALIAS_RESET_ON_ADDR_CHANGE, ~0); + LibAliasSetMode(la, PKT_ALIAS_DENY_INCOMING, PKT_ALIAS_DENY_INCOMING); + + /* + * Fully specified + */ + pf1 = LibAliasRedirectPort(la, prv2, ntohs(0x1234), ext, ntohs(0x5678), masq, ntohs(0xabcd), IPPROTO_UDP); + ATF_REQUIRE(pf1 != NULL); + + p = ip_packet(0, 64); + UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv2, 0x1234); + + /* clear table by keeping the address */ + LibAliasSetAddress(la, ext); + LibAliasSetAddress(la, masq); + + /* + * Fully specified (override) + */ + pf1 = LibAliasRedirectPort(la, prv1, ntohs(0x1234), ext, ntohs(0x5678), masq, ntohs(0xabcd), IPPROTO_UDP); + ATF_REQUIRE(pf1 != NULL); + + UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv1, 0x1234); + + /* clear table by keeping the address */ + LibAliasSetAddress(la, ext); + LibAliasSetAddress(la, masq); + + /* + * Any external port + */ + pf2 = LibAliasRedirectPort(la, prv2, ntohs(0x1234), ext, ntohs(0), masq, ntohs(0xabcd), IPPROTO_UDP); + ATF_REQUIRE(pf2 != NULL); + + UDP_UNNAT_CHECK(p, u, ext, 0x5679, masq, 0xabcd, prv2, 0x1234); + /* more specific rule wins */ + UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv1, 0x1234); + + /* clear table by keeping the address */ + LibAliasSetAddress(la, ext); + LibAliasSetAddress(la, masq); + + /* + * Any external host + */ + pf3 = LibAliasRedirectPort(la, prv3, ntohs(0x1234), ANY_ADDR, ntohs(0x5678), masq, ntohs(0xabcd), IPPROTO_UDP); + ATF_REQUIRE(pf3 != NULL); + + UDP_UNNAT_CHECK(p, u, pub, 0x5678, masq, 0xabcd, prv3, 0x1234); + /* more specific rule wins */ + UDP_UNNAT_CHECK(p, u, ext, 0x5679, masq, 0xabcd, prv2, 0x1234); + UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv1, 0x1234); + + /* clear table by keeping the address */ + LibAliasSetAddress(la, ext); + LibAliasSetAddress(la, masq); + + /* + * Any external host, any port + */ + pf4 = LibAliasRedirectPort(la, cgn, ntohs(0x1234), ANY_ADDR, ntohs(0), masq, ntohs(0xabcd), IPPROTO_UDP); + ATF_REQUIRE(pf4 != NULL); + + UDP_UNNAT_CHECK(p, u, prv1, 0x5679, masq, 0xabcd, cgn, 0x1234); + /* more specific rule wins */ + UDP_UNNAT_CHECK(p, u, pub, 0x5678, masq, 0xabcd, prv3, 0x1234); + UDP_UNNAT_CHECK(p, u, ext, 0x5679, masq, 0xabcd, prv2, 0x1234); + UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv1, 0x1234); + + free(p); + LibAliasUninit(la); +} + +ATF_TC_WITHOUT_HEAD(3_redirectany); +ATF_TC_BODY(3_redirectany, dummy) +{ + struct libalias *la = LibAliasInit(NULL); + struct alias_link *pf; + struct ip *p; + struct udphdr *u; + + ATF_REQUIRE(la != NULL); + LibAliasSetMode(la, PKT_ALIAS_DENY_INCOMING, ~0); + p = ip_packet(0, 64); + + pf = LibAliasRedirectPort(la, prv1, ntohs(0x1234), ANY_ADDR, 0, ANY_ADDR, ntohs(0xabcd), IPPROTO_UDP); + ATF_REQUIRE(pf != NULL); + + LibAliasSetAddress(la, masq); + UDP_UNNAT_CHECK(p, u, ext, 0x5678, masq, 0xabcd, prv1, 0x1234); + UDP_UNNAT_FAIL(p, u, pub, 0x5678, pub, 0xabcd); + + LibAliasSetAddress(la, pub); + UDP_UNNAT_CHECK(p, u, pub, 0x5679, pub, 0xabcd, prv1, 0x1234); + UDP_UNNAT_FAIL(p, u, ext, 0x5679, masq, 0xabcd); + + free(p); + LibAliasUninit(la); +} + +ATF_TP_ADD_TCS(natin) +{ + /* Use "dd if=/dev/random bs=2 count=1 | od -x" to reproduce */ + srand(0xe859); + + ATF_TP_ADD_TC(natin, 1_portforward); + ATF_TP_ADD_TC(natin, 2_portoverlap); + ATF_TP_ADD_TC(natin, 3_redirectany); + + return atf_no_error(); +} Index: tests/sys/netinet/libalias/Makefile =================================================================== --- tests/sys/netinet/libalias/Makefile +++ tests/sys/netinet/libalias/Makefile @@ -7,6 +7,7 @@ ATF_TESTS_C+= 1_instance \ 2_natout \ + 3_natin \ PROGS+= perf @@ -14,6 +15,7 @@ SRCS.1_instance=1_instance.c util.c SRCS.2_natout= 2_natout.c util.c +SRCS.3_natin= 3_natin.c util.c SRCS.perf= perf.c util.c .include