Index: tests/sys/netinet/libalias/Makefile =================================================================== --- tests/sys/netinet/libalias/Makefile +++ tests/sys/netinet/libalias/Makefile @@ -8,10 +8,13 @@ ATF_TESTS_C+= 1_instance \ 2_natout \ +PROGS+= perf + LIBADD+= alias SRCS.1_instance=1_instance.c util.c SRCS.2_natout= 2_natout.c util.c +SRCS.perf= perf.c util.c .include Index: tests/sys/netinet/libalias/perf.c =================================================================== --- /dev/null +++ tests/sys/netinet/libalias/perf.c @@ -0,0 +1,170 @@ +#include +#include +#include +#include +#include "util.h" +#include + +/* common ip ranges */ +static struct in_addr masq = { htonl(0x01020304) }; +static struct in_addr prv = { htonl(0x0a000000) }; +static struct in_addr ext = { htonl(0x12000000) }; + +int main(int argc, char ** argv) +{ + struct libalias *la; + struct timeval start, now; + struct ip *p; + struct udphdr *u; + struct { + struct in_addr src, dst; + uint16_t sport, dport, aport; + } *batch; + int batch_size, random_size, attack_length, round; + struct { + unsigned long ok, fail; + } nat, unnat, random, attack; + + if(argc != 4 || + 0 >= (batch_size = atoi(argv[1])) || + 0 >= (random_size = atoi(argv[2])) || + 0 >= (attack_length = atoi(argv[3]))) { + printf("Usage: %s batch_size random_size attack_length\n", argv[0]); + return 1; + } + if (NULL == (la = LibAliasInit(NULL))) { + perror("LibAliasInit"); + return -1; + } + + bzero(&nat, sizeof(nat)); + bzero(&unnat, sizeof(unnat)); + bzero(&random, sizeof(random)); + bzero(&attack, sizeof(attack)); + + LibAliasSetAddress(la, masq); + LibAliasSetMode(la, PKT_ALIAS_DENY_INCOMING, PKT_ALIAS_DENY_INCOMING); + + prv.s_addr &= htonl(0xffff0000); + ext.s_addr &= htonl(0xffff0000); + + p = ip_packet(prv, ext, 0, 64); + u = set_udp(p, 0, 0); + + if (NULL == (batch = calloc(batch_size, sizeof(*batch)))) { + perror("calloc(batch)"); + return -1; + } + + gettimeofday(&start, NULL); + + for (round = 0; ; round++) { + int i; + int res; + + for (i = 0; i < batch_size; i++) { + batch[i].src.s_addr = prv.s_addr | htonl(rand_range(0, 0xffff)); + batch[i].dst.s_addr = ext.s_addr | htonl(rand_range(0, 0xffff)); + batch[i].sport = rand_range(1000, 60000); + batch[i].dport = rand_range(1000, 60000); + + p->ip_src = batch[i].src; + p->ip_dst = batch[i].dst; + u = set_udp(p, batch[i].sport, batch[i].dport); + + res = LibAliasOut(la, p, 64); + batch[i].aport = htons(u->uh_sport); + + if (res == PKT_ALIAS_OK && + u->uh_dport == htons(batch[i].dport) && + addr_eq(p->ip_dst, batch[i].dst) && + addr_eq(p->ip_src, masq)) + nat.ok++; + else + nat.fail++; + + gettimeofday(&now, NULL); + if(now.tv_sec > start.tv_sec && now.tv_usec > start.tv_usec) + goto out; + } + + for (i = 0; i < random_size; i++) { + p->ip_src.s_addr = ext.s_addr & htonl(0xfff00000); + p->ip_src.s_addr |= htonl(rand_range(0, 0xffff)); + p->ip_dst = masq; + u = set_udp(p, rand_range(1, 0xffff), rand_range(1, 0xffff)); + + res = LibAliasIn(la, p, 64); + + if (res == PKT_ALIAS_OK) + random.ok++; + else + random.fail++; + + gettimeofday(&now, NULL); + if(now.tv_sec > start.tv_sec && now.tv_usec > start.tv_usec) + goto out; + } + + p->ip_src.s_addr = ext.s_addr & htonl(0xfff00000); + p->ip_src.s_addr |= htonl(rand_range(0, 0xffff)); + p->ip_dst = masq; + u = set_udp(p, rand_range(1, 0xffff), rand_range(1, 0xffff)); + for (i = 0; i < attack_length; i++) { + res = LibAliasIn(la, p, 64); + + if (res == PKT_ALIAS_OK) + attack.ok++; + else + attack.fail++; + + gettimeofday(&now, NULL); + if(now.tv_sec > start.tv_sec && now.tv_usec > start.tv_usec) + goto out; + } + + qsort(batch, batch_size, sizeof(*batch), randcmp); + + for (i = 0; i < batch_size; i++) { + p->ip_src = batch[i].dst; + p->ip_dst = masq; + u = set_udp(p, batch[i].dport, batch[i].aport); + + res = LibAliasIn(la, p, 64); + batch[i].aport = htons(u->uh_sport); + + if (res == PKT_ALIAS_OK && + u->uh_sport == htons(batch[i].dport) && + u->uh_dport == htons(batch[i].sport) && + addr_eq(p->ip_dst, batch[i].src) && + addr_eq(p->ip_src, batch[i].dst)) + unnat.ok++; + else + unnat.fail++; + + gettimeofday(&now, NULL); + if(now.tv_sec > start.tv_sec && now.tv_usec > start.tv_usec) + goto out; + } + } +out: + free(batch); + free(p); + LibAliasUninit(la); + + printf("Results\n"); + printf(" Rounds : %7u\n\n", round); + printf(" NAT ok : %7lu\n", nat.ok); + printf(" NAT fail: %7lu\n", nat.fail); + printf(" UNNAT ok : %7lu\n", unnat.ok); + printf(" UNNAT fail: %7lu\n", unnat.fail); + printf("RANDOM ok : %7lu\n", random.ok); + printf("RANDOM fail: %7lu\n", random.fail); + printf("ATTACK ok : %7lu\n", attack.ok); + printf("ATTACK fail: %7lu\n", attack.fail); + printf(" -------------------\n"); + printf(" Total: %7lu\n", + nat.ok + nat.fail + unnat.ok + unnat.fail + + random.ok + random.fail + attack.ok + attack.fail); + return (0); +} Index: tests/sys/netinet/libalias/util.c =================================================================== --- tests/sys/netinet/libalias/util.c +++ tests/sys/netinet/libalias/util.c @@ -1,4 +1,3 @@ -#include #include #include @@ -6,6 +5,14 @@ #include "util.h" +#define REQUIRE(x) do { \ + if (!(x)) { \ + fprintf(stderr, "Failed in %s %s:%d.\n",\ + __FUNCTION__, __FILE__, __LINE__); \ + exit(-1); \ + } \ +} while(0) + int randcmp(const void *a, const void *b) { @@ -42,10 +49,10 @@ { struct ip * p; - ATF_REQUIRE(len >= 64 && len <= IP_MAXPACKET); + REQUIRE(len >= 64 && len <= IP_MAXPACKET); p = calloc(1, len); - ATF_REQUIRE(p != NULL); + REQUIRE(p != NULL); p->ip_v = IPVERSION; p->ip_hl = sizeof(*p)/4; @@ -54,7 +61,7 @@ p->ip_src = src; p->ip_dst = dst; p->ip_p = protocol; - ATF_REQUIRE(p->ip_hl == 5); + REQUIRE(p->ip_hl == 5); return (p); } @@ -65,7 +72,7 @@ struct udphdr *u = (void *)&(up[p->ip_hl]); int payload = ntohs(p->ip_len) - 4*p->ip_hl; - ATF_REQUIRE(payload >= (int)sizeof(*u)); + REQUIRE(payload >= (int)sizeof(*u)); p->ip_p = IPPROTO_UDP; u->uh_sport = htons(sport); u->uh_dport = htons(dport);