11.2Sknakahar/* $NetBSD: natt_terminator.c,v 1.2 2018/11/22 04:51:41 knakahara Exp $ */ 21.1Sozaki 31.1Sozaki/*- 41.1Sozaki * Copyright (c) 2017 Internet Initiative Japan Inc. 51.1Sozaki * All rights reserved. 61.1Sozaki * 71.1Sozaki * Redistribution and use in source and binary forms, with or without 81.1Sozaki * modification, are permitted provided that the following conditions 91.1Sozaki * are met: 101.1Sozaki * 1. Redistributions of source code must retain the above copyright 111.1Sozaki * notice, this list of conditions and the following disclaimer. 121.1Sozaki * 2. Redistributions in binary form must reproduce the above copyright 131.1Sozaki * notice, this list of conditions and the following disclaimer in the 141.1Sozaki * documentation and/or other materials provided with the distribution. 151.1Sozaki * 161.1Sozaki * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 171.1Sozaki * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 181.1Sozaki * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 191.1Sozaki * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 201.1Sozaki * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 211.1Sozaki * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 221.1Sozaki * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 231.1Sozaki * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 241.1Sozaki * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 251.1Sozaki * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 261.1Sozaki * POSSIBILITY OF SUCH DAMAGE. 271.1Sozaki */ 281.1Sozaki 291.1Sozaki#include <sys/types.h> 301.1Sozaki#include <sys/socket.h> 311.1Sozaki#include <sys/wait.h> 321.1Sozaki#include <sys/time.h> 331.1Sozaki 341.1Sozaki#include <netinet/in.h> 351.1Sozaki#include <netinet/udp.h> 361.1Sozaki 371.1Sozaki#include <stdio.h> 381.1Sozaki#include <err.h> 391.1Sozaki#include <netdb.h> 401.1Sozaki#include <string.h> 411.1Sozaki#include <stdlib.h> 421.1Sozaki#include <unistd.h> 431.1Sozaki 441.2Sknakaharstatic void 451.2Sknakaharusage(void) 461.2Sknakahar{ 471.2Sknakahar const char *prog = "natt_terminator"; 481.2Sknakahar 491.2Sknakahar fprintf(stderr, "Usage: %s [-46] <addr> <port>\n", prog); 501.2Sknakahar} 511.2Sknakahar 521.1Sozakiint 531.1Sozakimain(int argc, char **argv) 541.1Sozaki{ 551.1Sozaki struct addrinfo hints; 561.1Sozaki struct addrinfo *res; 571.1Sozaki int s, e; 581.1Sozaki const char *addr, *port; 591.1Sozaki int option; 601.2Sknakahar int c, family = AF_INET; 611.2Sknakahar 621.2Sknakahar while ((c = getopt(argc, argv, "46")) != -1) { 631.2Sknakahar switch (c) { 641.2Sknakahar case '4': 651.2Sknakahar family = AF_INET; 661.2Sknakahar break; 671.2Sknakahar case '6': 681.2Sknakahar family = AF_INET6; 691.2Sknakahar break; 701.2Sknakahar default: 711.2Sknakahar usage(); 721.2Sknakahar return 1; 731.2Sknakahar } 741.2Sknakahar } 751.2Sknakahar argc -= optind; 761.2Sknakahar argv += optind; 771.1Sozaki 781.2Sknakahar if (argc != 2) { 791.2Sknakahar usage(); 801.1Sozaki return 1; 811.1Sozaki } 821.1Sozaki 831.2Sknakahar addr = argv[0]; 841.2Sknakahar port = argv[1]; 851.1Sozaki 861.1Sozaki memset(&hints, 0, sizeof(hints)); 871.2Sknakahar hints.ai_family = family; 881.1Sozaki hints.ai_socktype = SOCK_DGRAM; 891.1Sozaki hints.ai_protocol = IPPROTO_UDP; 901.1Sozaki hints.ai_flags = 0; 911.1Sozaki 921.1Sozaki e = getaddrinfo(addr, port, &hints, &res); 931.1Sozaki if (e != 0) 941.1Sozaki errx(EXIT_FAILURE, "getaddrinfo failed: %s", gai_strerror(e)); 951.1Sozaki 961.1Sozaki s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 971.1Sozaki if (s == -1) 981.1Sozaki err(EXIT_FAILURE, "socket"); 991.1Sozaki 1001.1Sozaki /* 1011.1Sozaki * Set the option to tell the kernel that the socket can handle 1021.1Sozaki * UDP-encapsulated ESP packets for NAT-T. 1031.1Sozaki */ 1041.1Sozaki option = UDP_ENCAP_ESPINUDP; 1051.1Sozaki e = setsockopt(s, IPPROTO_UDP, UDP_ENCAP, &option, sizeof(option)); 1061.1Sozaki if (e == -1) 1071.1Sozaki err(EXIT_FAILURE, "setsockopt(UDP_ENCAP)"); 1081.1Sozaki 1091.1Sozaki e = bind(s, res->ai_addr, res->ai_addrlen); 1101.1Sozaki if (e == -1) 1111.1Sozaki err(EXIT_FAILURE, "bind"); 1121.1Sozaki 1131.1Sozaki /* Receiving a packet make the NAPT create a mapping. */ 1141.1Sozaki { 1151.1Sozaki char buf[64]; 1161.1Sozaki struct sockaddr_storage z; 1171.1Sozaki socklen_t len = sizeof(z); 1181.1Sozaki 1191.1Sozaki e = recvfrom(s, buf, 64, MSG_PEEK, 1201.1Sozaki (struct sockaddr *)&z, &len); 1211.1Sozaki if (e == -1) 1221.1Sozaki err(EXIT_FAILURE, "recvfrom"); 1231.1Sozaki } 1241.1Sozaki 1251.1Sozaki /* 1261.1Sozaki * Keep the socket in the kernel to handle UDP-encapsulated ESP packets. 1271.1Sozaki */ 1281.1Sozaki pause(); 1291.1Sozaki 1301.1Sozaki close(s); 1311.1Sozaki 1321.1Sozaki return 0; 1331.1Sozaki} 134