xref: /freebsd-src/tests/sys/netinet/libalias/perf.c (revision 6fde066264e5cb784470e05c0ab6acbb16057bbc)
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  */
3433c1bdfcSLutz Donnerhacke #include <stdio.h>
3533c1bdfcSLutz Donnerhacke #include <stdlib.h>
3633c1bdfcSLutz Donnerhacke #include <strings.h>
3733c1bdfcSLutz Donnerhacke #include <sys/time.h>
3833c1bdfcSLutz Donnerhacke #include "util.h"
3933c1bdfcSLutz Donnerhacke #include <alias.h>
4033c1bdfcSLutz Donnerhacke 
41*6fde0662SAlfonso Gregory static void usage(void) __dead2;
42fef99da6SLutz Donnerhacke 
4333c1bdfcSLutz Donnerhacke #define	timevalcmp(tv, uv, cmp)			\
4433c1bdfcSLutz Donnerhacke 	(((tv).tv_sec == (uv).tv_sec)		\
4533c1bdfcSLutz Donnerhacke 	 ? ((tv).tv_usec cmp (uv).tv_usec)	\
4633c1bdfcSLutz Donnerhacke 	 : ((tv).tv_sec cmp (uv).tv_sec))
4733c1bdfcSLutz Donnerhacke 
48ccac04caSLutz Donnerhacke #define timevaldiff(n, o) (float)		\
4933c1bdfcSLutz Donnerhacke 	(((n).tv_sec - (o).tv_sec)*1000000l +	\
5033c1bdfcSLutz Donnerhacke 	 ((n).tv_usec - (o).tv_usec))
5133c1bdfcSLutz Donnerhacke 
526e87898aSLutz Donnerhacke #define check_timeout()	do {				\
536e87898aSLutz Donnerhacke 	if (check_timeout_cnt++ > 1000) {		\
546e87898aSLutz Donnerhacke 		check_timeout_cnt = 0;			\
556e87898aSLutz Donnerhacke 		gettimeofday(&now, NULL);		\
566e87898aSLutz Donnerhacke 		if (timevalcmp(now, timeout, >=))	\
576e87898aSLutz Donnerhacke 		    goto out;				\
586e87898aSLutz Donnerhacke 	} } while(0)
596e87898aSLutz Donnerhacke 
60d62e1ecbSLutz Donnerhacke static void
usage(void)61f4c460daSLutz Donnerhacke usage(void) {
62d62e1ecbSLutz Donnerhacke 	printf("Usage: perf [max_seconds [batch_size [random_size [attack_size [redir_size]]]]]\n");
63d62e1ecbSLutz Donnerhacke 	exit(1);
64d62e1ecbSLutz Donnerhacke }
656e87898aSLutz Donnerhacke 
main(int argc,char ** argv)6633c1bdfcSLutz Donnerhacke int main(int argc, char ** argv)
6733c1bdfcSLutz Donnerhacke {
6833c1bdfcSLutz Donnerhacke 	struct libalias *la;
695434ebd2SLutz Donnerhacke 	struct timeval timeout, now, start;
7033c1bdfcSLutz Donnerhacke 	struct ip *p;
7133c1bdfcSLutz Donnerhacke 	struct udphdr *u;
7233c1bdfcSLutz Donnerhacke 	struct {
7333c1bdfcSLutz Donnerhacke 		struct in_addr src, dst;
7433c1bdfcSLutz Donnerhacke 		uint16_t sport, dport, aport;
7533c1bdfcSLutz Donnerhacke 	} *batch;
7633c1bdfcSLutz Donnerhacke 	struct {
7733c1bdfcSLutz Donnerhacke 		unsigned long ok, fail;
786e87898aSLutz Donnerhacke 	} nat, usenat, unnat, random, attack;
79d62e1ecbSLutz Donnerhacke 	int i, round, check_timeout_cnt = 0;
80d62e1ecbSLutz Donnerhacke 	int max_seconds = 90, batch_size = 2000,
81d62e1ecbSLutz Donnerhacke 	    random_size = 1000, attack_size = 1000,
82d62e1ecbSLutz Donnerhacke 	    redir_size = 2000;
8333c1bdfcSLutz Donnerhacke 
84d62e1ecbSLutz Donnerhacke 	if (argc >= 2) {
85d62e1ecbSLutz Donnerhacke 		char * end;
86d62e1ecbSLutz Donnerhacke 
87d62e1ecbSLutz Donnerhacke 		max_seconds = strtol(argv[1], &end, 10);
88d62e1ecbSLutz Donnerhacke 		if (max_seconds < 2 || end[0] != '\0')
89d62e1ecbSLutz Donnerhacke 			usage();
9033c1bdfcSLutz Donnerhacke 	}
91d62e1ecbSLutz Donnerhacke 	if (argc > 2 && (batch_size  = atoi(argv[2])) < 0)	usage();
92d62e1ecbSLutz Donnerhacke 	if (argc > 3 && (random_size = atoi(argv[3])) < 0)	usage();
93d62e1ecbSLutz Donnerhacke 	if (argc > 4 && (attack_size = atoi(argv[4])) < 0)	usage();
94d62e1ecbSLutz Donnerhacke 	if (argc > 5 && (redir_size  = atoi(argv[5])) < 0)	usage();
95d62e1ecbSLutz Donnerhacke 
96d62e1ecbSLutz Donnerhacke 	printf("Running perfomance test with parameters:\n");
97d62e1ecbSLutz Donnerhacke 	printf("  Maximum Runtime (max_seconds) = %d\n", max_seconds);
98d62e1ecbSLutz Donnerhacke 	printf("  Amount of valid connections (batch_size) = %d\n", batch_size);
99d62e1ecbSLutz Donnerhacke 	printf("  Amount of random, incoming packets (batch_size) = %d\n", random_size);
100d62e1ecbSLutz Donnerhacke 	printf("  Repeat count of a random, incoming packet (attack_size) = %d\n", attack_size);
101d62e1ecbSLutz Donnerhacke 	printf("  Amount of open port forwardings (redir_size) = %d\n", redir_size);
102d62e1ecbSLutz Donnerhacke 	printf("\n");
103d62e1ecbSLutz Donnerhacke 
10433c1bdfcSLutz Donnerhacke 	if (NULL == (la = LibAliasInit(NULL))) {
10533c1bdfcSLutz Donnerhacke 		perror("LibAliasInit");
10633c1bdfcSLutz Donnerhacke 		return -1;
10733c1bdfcSLutz Donnerhacke 	}
10833c1bdfcSLutz Donnerhacke 
10933c1bdfcSLutz Donnerhacke 	bzero(&nat, sizeof(nat));
1106e87898aSLutz Donnerhacke 	bzero(&usenat, sizeof(usenat));
11133c1bdfcSLutz Donnerhacke 	bzero(&unnat, sizeof(unnat));
11233c1bdfcSLutz Donnerhacke 	bzero(&random, sizeof(random));
11333c1bdfcSLutz Donnerhacke 	bzero(&attack, sizeof(attack));
11433c1bdfcSLutz Donnerhacke 
11533c1bdfcSLutz Donnerhacke 	LibAliasSetAddress(la, masq);
116d62e1ecbSLutz Donnerhacke 	LibAliasSetMode(la, PKT_ALIAS_SAME_PORTS | PKT_ALIAS_DENY_INCOMING, ~0);
11733c1bdfcSLutz Donnerhacke 
118f1462ab0SLutz Donnerhacke 	prv1.s_addr &= htonl(0xffff0000);
11933c1bdfcSLutz Donnerhacke 	ext.s_addr &= htonl(0xffff0000);
12033c1bdfcSLutz Donnerhacke 
121d62e1ecbSLutz Donnerhacke 	for (i = 0; i < redir_size; i++) {
122d62e1ecbSLutz Donnerhacke 		int aport = htons(rand_range(1000, 2000));
123d62e1ecbSLutz Donnerhacke 		int sport = htons(rand_range(1000, 2000));
124d62e1ecbSLutz Donnerhacke 
125d62e1ecbSLutz Donnerhacke 		prv2.s_addr &= htonl(0xffff0000);
126d62e1ecbSLutz Donnerhacke 		prv2.s_addr |= rand_range(0, 0xffff);
127d62e1ecbSLutz Donnerhacke 		LibAliasRedirectPort(la, prv2, sport, ANY_ADDR, 0, masq, aport, IPPROTO_UDP);
128d62e1ecbSLutz Donnerhacke 	}
129d62e1ecbSLutz Donnerhacke 
130f1462ab0SLutz Donnerhacke 	p = ip_packet(0, 64);
13133c1bdfcSLutz Donnerhacke 	u = set_udp(p, 0, 0);
13233c1bdfcSLutz Donnerhacke 
13333c1bdfcSLutz Donnerhacke 	if (NULL == (batch = calloc(batch_size, sizeof(*batch)))) {
13433c1bdfcSLutz Donnerhacke 		perror("calloc(batch)");
13533c1bdfcSLutz Donnerhacke 		return -1;
13633c1bdfcSLutz Donnerhacke 	}
13733c1bdfcSLutz Donnerhacke 
13833c1bdfcSLutz Donnerhacke 	gettimeofday(&timeout, NULL);
13933c1bdfcSLutz Donnerhacke 	timeout.tv_sec += max_seconds;
14033c1bdfcSLutz Donnerhacke 
1416e87898aSLutz Donnerhacke 	printf("RND SECOND newNAT RANDOM ATTACK useNAT\n");
14233c1bdfcSLutz Donnerhacke 	for (round = 0; ; round++) {
143d62e1ecbSLutz Donnerhacke 		int res, cnt;
14433c1bdfcSLutz Donnerhacke 
14533c1bdfcSLutz Donnerhacke 		printf("%3d ", round+1);
14633c1bdfcSLutz Donnerhacke 
14733c1bdfcSLutz Donnerhacke 		gettimeofday(&start, NULL);
1486e87898aSLutz Donnerhacke 		printf("%6.1f ", max_seconds - timevaldiff(timeout, start)/1000000.0f);
14933c1bdfcSLutz Donnerhacke 		for (cnt = i = 0; i < batch_size; i++, cnt++) {
150f1462ab0SLutz Donnerhacke 			batch[i].src.s_addr = prv1.s_addr | htonl(rand_range(0, 0xffff));
15133c1bdfcSLutz Donnerhacke 			batch[i].dst.s_addr = ext.s_addr | htonl(rand_range(0, 0xffff));
15233c1bdfcSLutz Donnerhacke 			batch[i].sport = rand_range(1000, 60000);
15333c1bdfcSLutz Donnerhacke 			batch[i].dport = rand_range(1000, 60000);
15433c1bdfcSLutz Donnerhacke 
15533c1bdfcSLutz Donnerhacke 			p->ip_src = batch[i].src;
15633c1bdfcSLutz Donnerhacke 			p->ip_dst = batch[i].dst;
15733c1bdfcSLutz Donnerhacke 			u = set_udp(p, batch[i].sport, batch[i].dport);
15833c1bdfcSLutz Donnerhacke 
15933c1bdfcSLutz Donnerhacke 			res = LibAliasOut(la, p, 64);
16033c1bdfcSLutz Donnerhacke 			batch[i].aport = htons(u->uh_sport);
16133c1bdfcSLutz Donnerhacke 
16233c1bdfcSLutz Donnerhacke 			if (res == PKT_ALIAS_OK &&
16333c1bdfcSLutz Donnerhacke 			    u->uh_dport == htons(batch[i].dport) &&
16433c1bdfcSLutz Donnerhacke 			    addr_eq(p->ip_dst, batch[i].dst) &&
16533c1bdfcSLutz Donnerhacke 			    addr_eq(p->ip_src, masq))
16633c1bdfcSLutz Donnerhacke 				nat.ok++;
16733c1bdfcSLutz Donnerhacke 			else
16833c1bdfcSLutz Donnerhacke 				nat.fail++;
16933c1bdfcSLutz Donnerhacke 
1706e87898aSLutz Donnerhacke 			check_timeout();
17133c1bdfcSLutz Donnerhacke 		}
1726e87898aSLutz Donnerhacke 		gettimeofday(&now, NULL);
17333c1bdfcSLutz Donnerhacke 		if (cnt > 0)
1746e87898aSLutz Donnerhacke 			printf("%6.2f ", timevaldiff(now, start) / cnt);
175d62e1ecbSLutz Donnerhacke 		else
176d62e1ecbSLutz Donnerhacke 			printf("------ ");
17733c1bdfcSLutz Donnerhacke 
17833c1bdfcSLutz Donnerhacke 		start = now;
17933c1bdfcSLutz Donnerhacke 		for (cnt = i = 0; i < random_size; i++, cnt++) {
18033c1bdfcSLutz Donnerhacke 			p->ip_src.s_addr = ext.s_addr & htonl(0xfff00000);
18133c1bdfcSLutz Donnerhacke 			p->ip_src.s_addr |= htonl(rand_range(0, 0xffff));
18233c1bdfcSLutz Donnerhacke 			p->ip_dst = masq;
18333c1bdfcSLutz Donnerhacke 			u = set_udp(p, rand_range(1, 0xffff), rand_range(1, 0xffff));
18433c1bdfcSLutz Donnerhacke 
18533c1bdfcSLutz Donnerhacke 			res = LibAliasIn(la, p, 64);
18633c1bdfcSLutz Donnerhacke 
18733c1bdfcSLutz Donnerhacke 			if (res == PKT_ALIAS_OK)
18833c1bdfcSLutz Donnerhacke 				random.ok++;
18933c1bdfcSLutz Donnerhacke 			else
19033c1bdfcSLutz Donnerhacke 				random.fail++;
19133c1bdfcSLutz Donnerhacke 
1926e87898aSLutz Donnerhacke 			check_timeout();
19333c1bdfcSLutz Donnerhacke 		}
1946e87898aSLutz Donnerhacke 		gettimeofday(&now, NULL);
19533c1bdfcSLutz Donnerhacke 		if (cnt > 0)
1966e87898aSLutz Donnerhacke 			printf("%6.2f ", timevaldiff(now, start) / cnt);
197d62e1ecbSLutz Donnerhacke 		else
198d62e1ecbSLutz Donnerhacke 			printf("------ ");
19933c1bdfcSLutz Donnerhacke 
20033c1bdfcSLutz Donnerhacke 		start = now;
20133c1bdfcSLutz Donnerhacke 		p->ip_src.s_addr = ext.s_addr & htonl(0xfff00000);
20233c1bdfcSLutz Donnerhacke 		p->ip_src.s_addr |= htonl(rand_range(0, 0xffff));
20333c1bdfcSLutz Donnerhacke 		p->ip_dst = masq;
20433c1bdfcSLutz Donnerhacke 		u = set_udp(p, rand_range(1, 0xffff), rand_range(1, 0xffff));
205d62e1ecbSLutz Donnerhacke 		for (cnt = i = 0; i < attack_size; i++, cnt++) {
20633c1bdfcSLutz Donnerhacke 			res = LibAliasIn(la, p, 64);
20733c1bdfcSLutz Donnerhacke 
20833c1bdfcSLutz Donnerhacke 			if (res == PKT_ALIAS_OK)
20933c1bdfcSLutz Donnerhacke 				attack.ok++;
21033c1bdfcSLutz Donnerhacke 			else
21133c1bdfcSLutz Donnerhacke 				attack.fail++;
21233c1bdfcSLutz Donnerhacke 
2136e87898aSLutz Donnerhacke 			check_timeout();
21433c1bdfcSLutz Donnerhacke 		}
2156e87898aSLutz Donnerhacke 		gettimeofday(&now, NULL);
21633c1bdfcSLutz Donnerhacke 		if (cnt > 0)
2176e87898aSLutz Donnerhacke 			printf("%6.2f ", timevaldiff(now, start) / cnt);
218d62e1ecbSLutz Donnerhacke 		else
219d62e1ecbSLutz Donnerhacke 			printf("------ ");
22033c1bdfcSLutz Donnerhacke 
22133c1bdfcSLutz Donnerhacke 		qsort(batch, batch_size, sizeof(*batch), randcmp);
22233c1bdfcSLutz Donnerhacke 
22333c1bdfcSLutz Donnerhacke 		gettimeofday(&start, NULL);
2246e87898aSLutz Donnerhacke 		for (cnt = i = 0; i < batch_size; i++) {
2256e87898aSLutz Donnerhacke 			int j;
2266e87898aSLutz Donnerhacke 
2276e87898aSLutz Donnerhacke 			/* random communication length */
2286e87898aSLutz Donnerhacke 			for(j = rand_range(1, 150); j-- > 0; cnt++) {
2296e87898aSLutz Donnerhacke 				int k;
2306e87898aSLutz Donnerhacke 
2316e87898aSLutz Donnerhacke 				/* a random flow out of rolling window */
2326e87898aSLutz Donnerhacke 				k = rand_range(i, i + 25);
2336e87898aSLutz Donnerhacke 				if (k >= batch_size)
2346e87898aSLutz Donnerhacke 					k = i;
2356e87898aSLutz Donnerhacke 
2366e87898aSLutz Donnerhacke 				/* 10% outgoing, 90% incoming */
2376e87898aSLutz Donnerhacke 				if (rand_range(0, 100) > 10) {
2386e87898aSLutz Donnerhacke 					p->ip_src = batch[k].dst;
23933c1bdfcSLutz Donnerhacke 					p->ip_dst = masq;
2406e87898aSLutz Donnerhacke 					u = set_udp(p, batch[k].dport, batch[k].aport);
24133c1bdfcSLutz Donnerhacke 
24233c1bdfcSLutz Donnerhacke 					res = LibAliasIn(la, p, 64);
24333c1bdfcSLutz Donnerhacke 					if (res == PKT_ALIAS_OK &&
2446e87898aSLutz Donnerhacke 					    u->uh_sport == htons(batch[k].dport) &&
2456e87898aSLutz Donnerhacke 					    u->uh_dport == htons(batch[k].sport) &&
2466e87898aSLutz Donnerhacke 					    addr_eq(p->ip_dst, batch[k].src) &&
2476e87898aSLutz Donnerhacke 					    addr_eq(p->ip_src, batch[k].dst))
24833c1bdfcSLutz Donnerhacke 						unnat.ok++;
24933c1bdfcSLutz Donnerhacke 					else
25033c1bdfcSLutz Donnerhacke 						unnat.fail++;
2516e87898aSLutz Donnerhacke 				} else {
2526e87898aSLutz Donnerhacke 					p->ip_src = batch[k].src;
2536e87898aSLutz Donnerhacke 					p->ip_dst = batch[k].dst;
2546e87898aSLutz Donnerhacke 					u = set_udp(p, batch[k].sport, batch[k].dport);
25533c1bdfcSLutz Donnerhacke 
2566e87898aSLutz Donnerhacke 					res = LibAliasOut(la, p, 64);
2576e87898aSLutz Donnerhacke 					if (res == PKT_ALIAS_OK &&
2586e87898aSLutz Donnerhacke 					    u->uh_sport == htons(batch[k].aport) &&
2596e87898aSLutz Donnerhacke 					    u->uh_dport == htons(batch[k].dport) &&
2606e87898aSLutz Donnerhacke 					    addr_eq(p->ip_dst, batch[k].dst) &&
2616e87898aSLutz Donnerhacke 					    addr_eq(p->ip_src, masq))
2626e87898aSLutz Donnerhacke 						usenat.ok++;
2636e87898aSLutz Donnerhacke 					else
2646e87898aSLutz Donnerhacke 						usenat.fail++;
26533c1bdfcSLutz Donnerhacke 				}
2666e87898aSLutz Donnerhacke 				check_timeout();
2676e87898aSLutz Donnerhacke 			}
2686e87898aSLutz Donnerhacke 		}
2696e87898aSLutz Donnerhacke 		gettimeofday(&now, NULL);
27033c1bdfcSLutz Donnerhacke 		if (cnt > 0)
2716e87898aSLutz Donnerhacke 			printf("%6.2f ", timevaldiff(now, start) / cnt);
272d62e1ecbSLutz Donnerhacke 		else
273d62e1ecbSLutz Donnerhacke 			printf("------ ");
2746e87898aSLutz Donnerhacke 
2756e87898aSLutz Donnerhacke 		printf("\n");
27633c1bdfcSLutz Donnerhacke 	}
27733c1bdfcSLutz Donnerhacke out:
27833c1bdfcSLutz Donnerhacke 	printf("\n\n");
27933c1bdfcSLutz Donnerhacke 	free(batch);
28033c1bdfcSLutz Donnerhacke 	free(p);
28133c1bdfcSLutz Donnerhacke 
28233c1bdfcSLutz Donnerhacke 	printf("Results\n");
2836e87898aSLutz Donnerhacke 	printf("   Rounds  : %9u\n", round);
2846e87898aSLutz Donnerhacke 	printf("newNAT ok  : %9lu\n", nat.ok);
2856e87898aSLutz Donnerhacke 	printf("newNAT fail: %9lu\n", nat.fail);
2866e87898aSLutz Donnerhacke 	printf("useNAT ok  : %9lu (out)\n", usenat.ok);
2876e87898aSLutz Donnerhacke 	printf("useNAT fail: %9lu (out)\n", usenat.fail);
2886e87898aSLutz Donnerhacke 	printf("useNAT ok  : %9lu (in)\n", unnat.ok);
2896e87898aSLutz Donnerhacke 	printf("useNAT fail: %9lu (in)\n", unnat.fail);
2906e87898aSLutz Donnerhacke 	printf("RANDOM ok  : %9lu\n", random.ok);
2916e87898aSLutz Donnerhacke 	printf("RANDOM fail: %9lu\n", random.fail);
2926e87898aSLutz Donnerhacke 	printf("ATTACK ok  : %9lu\n", attack.ok);
2936e87898aSLutz Donnerhacke 	printf("ATTACK fail: %9lu\n", attack.fail);
2946e87898aSLutz Donnerhacke 	printf("             ---------\n");
2956e87898aSLutz Donnerhacke 	printf("      Total: %9lu\n",
2966e87898aSLutz Donnerhacke 	       nat.ok + nat.fail +
2976e87898aSLutz Donnerhacke 	       unnat.ok + unnat.fail +
2986e87898aSLutz Donnerhacke 	       usenat.ok + usenat.fail +
2996e87898aSLutz Donnerhacke 	       random.ok + random.fail +
3006e87898aSLutz Donnerhacke 	       attack.ok + attack.fail);
3015434ebd2SLutz Donnerhacke 
3025434ebd2SLutz Donnerhacke 	gettimeofday(&start, NULL);
3035434ebd2SLutz Donnerhacke 	printf("\n  Cleanup  : ");
3045434ebd2SLutz Donnerhacke 	LibAliasUninit(la);
3055434ebd2SLutz Donnerhacke 	gettimeofday(&now, NULL);
3065434ebd2SLutz Donnerhacke 	printf("%.2fs\n", timevaldiff(now, start)/1000000l);
30733c1bdfcSLutz Donnerhacke 	return (0);
30833c1bdfcSLutz Donnerhacke }
309