xref: /netbsd-src/tests/net/ipsec/natt_terminator.c (revision d1268e2e867abd97f55662dac658e00277bd45fa)
1*d1268e2eSknakahara /*	$NetBSD: natt_terminator.c,v 1.2 2018/11/22 04:51:41 knakahara Exp $	*/
20de7b049Sozaki-r 
30de7b049Sozaki-r /*-
40de7b049Sozaki-r  * Copyright (c) 2017 Internet Initiative Japan Inc.
50de7b049Sozaki-r  * All rights reserved.
60de7b049Sozaki-r  *
70de7b049Sozaki-r  * Redistribution and use in source and binary forms, with or without
80de7b049Sozaki-r  * modification, are permitted provided that the following conditions
90de7b049Sozaki-r  * are met:
100de7b049Sozaki-r  * 1. Redistributions of source code must retain the above copyright
110de7b049Sozaki-r  *    notice, this list of conditions and the following disclaimer.
120de7b049Sozaki-r  * 2. Redistributions in binary form must reproduce the above copyright
130de7b049Sozaki-r  *    notice, this list of conditions and the following disclaimer in the
140de7b049Sozaki-r  *    documentation and/or other materials provided with the distribution.
150de7b049Sozaki-r  *
160de7b049Sozaki-r  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
170de7b049Sozaki-r  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
180de7b049Sozaki-r  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
190de7b049Sozaki-r  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
200de7b049Sozaki-r  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
210de7b049Sozaki-r  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
220de7b049Sozaki-r  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
230de7b049Sozaki-r  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
240de7b049Sozaki-r  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
250de7b049Sozaki-r  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
260de7b049Sozaki-r  * POSSIBILITY OF SUCH DAMAGE.
270de7b049Sozaki-r  */
280de7b049Sozaki-r 
290de7b049Sozaki-r #include <sys/types.h>
300de7b049Sozaki-r #include <sys/socket.h>
310de7b049Sozaki-r #include <sys/wait.h>
320de7b049Sozaki-r #include <sys/time.h>
330de7b049Sozaki-r 
340de7b049Sozaki-r #include <netinet/in.h>
350de7b049Sozaki-r #include <netinet/udp.h>
360de7b049Sozaki-r 
370de7b049Sozaki-r #include <stdio.h>
380de7b049Sozaki-r #include <err.h>
390de7b049Sozaki-r #include <netdb.h>
400de7b049Sozaki-r #include <string.h>
410de7b049Sozaki-r #include <stdlib.h>
420de7b049Sozaki-r #include <unistd.h>
430de7b049Sozaki-r 
44*d1268e2eSknakahara static void
usage(void)45*d1268e2eSknakahara usage(void)
46*d1268e2eSknakahara {
47*d1268e2eSknakahara 	const char *prog = "natt_terminator";
48*d1268e2eSknakahara 
49*d1268e2eSknakahara 	fprintf(stderr, "Usage: %s [-46] <addr> <port>\n", prog);
50*d1268e2eSknakahara }
51*d1268e2eSknakahara 
520de7b049Sozaki-r int
main(int argc,char ** argv)530de7b049Sozaki-r main(int argc, char **argv)
540de7b049Sozaki-r {
550de7b049Sozaki-r 	struct addrinfo hints;
560de7b049Sozaki-r 	struct addrinfo *res;
570de7b049Sozaki-r 	int s, e;
580de7b049Sozaki-r 	const char *addr, *port;
590de7b049Sozaki-r 	int option;
60*d1268e2eSknakahara 	int c, family = AF_INET;
610de7b049Sozaki-r 
62*d1268e2eSknakahara 	while ((c = getopt(argc, argv, "46")) != -1) {
63*d1268e2eSknakahara 		switch (c) {
64*d1268e2eSknakahara 		case '4':
65*d1268e2eSknakahara 			family = AF_INET;
66*d1268e2eSknakahara 			break;
67*d1268e2eSknakahara 		case '6':
68*d1268e2eSknakahara 			family = AF_INET6;
69*d1268e2eSknakahara 			break;
70*d1268e2eSknakahara 		default:
71*d1268e2eSknakahara 			usage();
72*d1268e2eSknakahara 			return 1;
73*d1268e2eSknakahara 		}
74*d1268e2eSknakahara 	}
75*d1268e2eSknakahara 	argc -= optind;
76*d1268e2eSknakahara 	argv += optind;
77*d1268e2eSknakahara 
78*d1268e2eSknakahara 	if (argc != 2) {
79*d1268e2eSknakahara 		usage();
800de7b049Sozaki-r 		return 1;
810de7b049Sozaki-r 	}
820de7b049Sozaki-r 
83*d1268e2eSknakahara 	addr = argv[0];
84*d1268e2eSknakahara 	port = argv[1];
850de7b049Sozaki-r 
860de7b049Sozaki-r 	memset(&hints, 0, sizeof(hints));
87*d1268e2eSknakahara 	hints.ai_family = family;
880de7b049Sozaki-r 	hints.ai_socktype = SOCK_DGRAM;
890de7b049Sozaki-r 	hints.ai_protocol = IPPROTO_UDP;
900de7b049Sozaki-r 	hints.ai_flags = 0;
910de7b049Sozaki-r 
920de7b049Sozaki-r 	e = getaddrinfo(addr, port, &hints, &res);
930de7b049Sozaki-r 	if (e != 0)
940de7b049Sozaki-r 		errx(EXIT_FAILURE, "getaddrinfo failed: %s", gai_strerror(e));
950de7b049Sozaki-r 
960de7b049Sozaki-r 	s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
970de7b049Sozaki-r 	if (s == -1)
980de7b049Sozaki-r 		err(EXIT_FAILURE, "socket");
990de7b049Sozaki-r 
1000de7b049Sozaki-r 	/*
1010de7b049Sozaki-r 	 * Set the option to tell the kernel that the socket can handle
1020de7b049Sozaki-r 	 * UDP-encapsulated ESP packets for NAT-T.
1030de7b049Sozaki-r 	 */
1040de7b049Sozaki-r 	option = UDP_ENCAP_ESPINUDP;
1050de7b049Sozaki-r 	e = setsockopt(s, IPPROTO_UDP, UDP_ENCAP, &option, sizeof(option));
1060de7b049Sozaki-r 	if (e == -1)
1070de7b049Sozaki-r 		err(EXIT_FAILURE, "setsockopt(UDP_ENCAP)");
1080de7b049Sozaki-r 
1090de7b049Sozaki-r 	e = bind(s, res->ai_addr, res->ai_addrlen);
1100de7b049Sozaki-r 	if (e == -1)
1110de7b049Sozaki-r 		err(EXIT_FAILURE, "bind");
1120de7b049Sozaki-r 
1130de7b049Sozaki-r 	/* Receiving a packet make the NAPT create a mapping. */
1140de7b049Sozaki-r 	{
1150de7b049Sozaki-r 		char buf[64];
1160de7b049Sozaki-r 		struct sockaddr_storage z;
1170de7b049Sozaki-r 		socklen_t len = sizeof(z);
1180de7b049Sozaki-r 
1190de7b049Sozaki-r 		e = recvfrom(s, buf, 64, MSG_PEEK,
1200de7b049Sozaki-r 		    (struct sockaddr *)&z, &len);
1210de7b049Sozaki-r 		if (e == -1)
1220de7b049Sozaki-r 			err(EXIT_FAILURE, "recvfrom");
1230de7b049Sozaki-r 	}
1240de7b049Sozaki-r 
1250de7b049Sozaki-r 	/*
1260de7b049Sozaki-r 	 * Keep the socket in the kernel to handle UDP-encapsulated ESP packets.
1270de7b049Sozaki-r 	 */
1280de7b049Sozaki-r 	pause();
1290de7b049Sozaki-r 
1300de7b049Sozaki-r 	close(s);
1310de7b049Sozaki-r 
1320de7b049Sozaki-r 	return 0;
1330de7b049Sozaki-r }
134