13cde9171SAlan Somers /*- 23cde9171SAlan Somers * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 33cde9171SAlan Somers * 43cde9171SAlan Somers * Copyright (C) 2019 Jan Sucan <jansucan@FreeBSD.org> 53cde9171SAlan Somers * All rights reserved. 63cde9171SAlan Somers * 73cde9171SAlan Somers * Redistribution and use in source and binary forms, with or without 83cde9171SAlan Somers * modification, are permitted provided that the following conditions 93cde9171SAlan Somers * are met: 103cde9171SAlan Somers * 1. Redistributions of source code must retain the above copyright 113cde9171SAlan Somers * notice, this list of conditions and the following disclaimer. 123cde9171SAlan Somers * 2. Redistributions in binary form must reproduce the above copyright 133cde9171SAlan Somers * notice, this list of conditions and the following disclaimer in the 143cde9171SAlan Somers * documentation and/or other materials provided with the distribution. 153cde9171SAlan Somers * 163cde9171SAlan Somers * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 173cde9171SAlan Somers * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 183cde9171SAlan Somers * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 193cde9171SAlan Somers * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 203cde9171SAlan Somers * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 213cde9171SAlan Somers * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 223cde9171SAlan Somers * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 233cde9171SAlan Somers * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 243cde9171SAlan Somers * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 253cde9171SAlan Somers * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 263cde9171SAlan Somers * SUCH DAMAGE. 273cde9171SAlan Somers */ 283cde9171SAlan Somers 293cde9171SAlan Somers #include <sys/cdefs.h> 303cde9171SAlan Somers __FBSDID("$FreeBSD$"); 313cde9171SAlan Somers 323cde9171SAlan Somers #include <sys/types.h> 333cde9171SAlan Somers #include <sys/socket.h> 343cde9171SAlan Somers 353cde9171SAlan Somers #include <arpa/inet.h> 363cde9171SAlan Somers #include <netdb.h> 373cde9171SAlan Somers #include <netinet/in.h> 383cde9171SAlan Somers 393cde9171SAlan Somers #include <err.h> 403cde9171SAlan Somers #include <stdbool.h> 413cde9171SAlan Somers #include <stdio.h> 423cde9171SAlan Somers #include <stdlib.h> 433cde9171SAlan Somers #include <string.h> 443cde9171SAlan Somers #include <unistd.h> 453cde9171SAlan Somers 463cde9171SAlan Somers #include "main.h" 473cde9171SAlan Somers #include "ping.h" 483cde9171SAlan Somers #ifdef INET6 493cde9171SAlan Somers #include "ping6.h" 503cde9171SAlan Somers #endif 513cde9171SAlan Somers 523cde9171SAlan Somers #ifdef INET6 533cde9171SAlan Somers #define OPTSTR ":46" 543cde9171SAlan Somers #else 553cde9171SAlan Somers #define OPTSTR ":4" 563cde9171SAlan Somers #endif 573cde9171SAlan Somers 583cde9171SAlan Somers int 593cde9171SAlan Somers main(int argc, char *argv[]) 603cde9171SAlan Somers { 613cde9171SAlan Somers struct in_addr a; 623cde9171SAlan Somers struct addrinfo hints; 633cde9171SAlan Somers int ch; 643cde9171SAlan Somers bool ipv4; 653cde9171SAlan Somers #ifdef INET6 663cde9171SAlan Somers struct in6_addr a6; 673cde9171SAlan Somers bool ipv6; 683cde9171SAlan Somers 69*d2624517SAlan Somers if (strcmp(getprogname(), "ping6") == 0) 70*d2624517SAlan Somers ipv6 = true; 71*d2624517SAlan Somers else 723cde9171SAlan Somers ipv6 = false; 733cde9171SAlan Somers #endif 743cde9171SAlan Somers ipv4 = false; 753cde9171SAlan Somers 763cde9171SAlan Somers while ((ch = getopt(argc, argv, OPTSTR)) != -1) { 773cde9171SAlan Somers switch(ch) { 783cde9171SAlan Somers case '4': 793cde9171SAlan Somers ipv4 = true; 803cde9171SAlan Somers break; 813cde9171SAlan Somers #ifdef INET6 823cde9171SAlan Somers case '6': 833cde9171SAlan Somers ipv6 = true; 843cde9171SAlan Somers break; 853cde9171SAlan Somers #endif 863cde9171SAlan Somers default: 873cde9171SAlan Somers break; 883cde9171SAlan Somers } 893cde9171SAlan Somers } 903cde9171SAlan Somers 913cde9171SAlan Somers if (optind >= argc) 923cde9171SAlan Somers usage(); 933cde9171SAlan Somers 943cde9171SAlan Somers optreset = 1; 953cde9171SAlan Somers optind = 1; 963cde9171SAlan Somers #ifdef INET6 973cde9171SAlan Somers if (ipv4 && ipv6) 983cde9171SAlan Somers errx(1, "-4 and -6 cannot be used simultaneously"); 993cde9171SAlan Somers #endif 1003cde9171SAlan Somers 1013cde9171SAlan Somers if (inet_pton(AF_INET, argv[argc - 1], &a) == 1) { 1023cde9171SAlan Somers #ifdef INET6 1033cde9171SAlan Somers if (ipv6) 1043cde9171SAlan Somers errx(1, "IPv6 requested but IPv4 target address " 1053cde9171SAlan Somers "provided"); 1063cde9171SAlan Somers #endif 1073cde9171SAlan Somers hints.ai_family = AF_INET; 1083cde9171SAlan Somers } 1093cde9171SAlan Somers #ifdef INET6 1103cde9171SAlan Somers else if (inet_pton(AF_INET6, argv[argc - 1], &a6) == 1) { 1113cde9171SAlan Somers if (ipv4) 1123cde9171SAlan Somers errx(1, "IPv4 requested but IPv6 target address " 1133cde9171SAlan Somers "provided"); 1143cde9171SAlan Somers hints.ai_family = AF_INET6; 1153cde9171SAlan Somers } else if (ipv6) 1163cde9171SAlan Somers hints.ai_family = AF_INET6; 1173cde9171SAlan Somers #endif 1183cde9171SAlan Somers else if (ipv4) 1193cde9171SAlan Somers hints.ai_family = AF_INET; 1203cde9171SAlan Somers else { 1213cde9171SAlan Somers struct addrinfo *res; 1223cde9171SAlan Somers 1233cde9171SAlan Somers memset(&hints, 0, sizeof(hints)); 1243cde9171SAlan Somers hints.ai_socktype = SOCK_RAW; 1253cde9171SAlan Somers hints.ai_family = AF_UNSPEC; 1263cde9171SAlan Somers getaddrinfo(argv[argc - 1], NULL, &hints, &res); 1273cde9171SAlan Somers if (res != NULL) { 1283cde9171SAlan Somers hints.ai_family = res[0].ai_family; 1293cde9171SAlan Somers freeaddrinfo(res); 1303cde9171SAlan Somers } 1313cde9171SAlan Somers } 1323cde9171SAlan Somers 1333cde9171SAlan Somers if (hints.ai_family == AF_INET) 1343cde9171SAlan Somers return ping(argc, argv); 1353cde9171SAlan Somers #ifdef INET6 1363cde9171SAlan Somers else if (hints.ai_family == AF_INET6) 1373cde9171SAlan Somers return ping6(argc, argv); 1383cde9171SAlan Somers #endif 1393cde9171SAlan Somers else 1403cde9171SAlan Somers errx(1, "Unknown host"); 1413cde9171SAlan Somers } 1423cde9171SAlan Somers 1433cde9171SAlan Somers void 1443cde9171SAlan Somers usage(void) 1453cde9171SAlan Somers { 1463cde9171SAlan Somers (void)fprintf(stderr, 1473cde9171SAlan Somers "usage: ping [-4AaDdfHnoQqRrv] [-C pcp] [-c count] " 1483cde9171SAlan Somers "[-G sweepmaxsize]\n" 1493cde9171SAlan Somers " [-g sweepminsize] [-h sweepincrsize] [-i wait] " 1503cde9171SAlan Somers "[-l preload]\n" 1513cde9171SAlan Somers " [-M mask | time] [-m ttl]" 1523cde9171SAlan Somers #ifdef IPSEC 1533cde9171SAlan Somers "[-P policy] " 1543cde9171SAlan Somers #endif 1553cde9171SAlan Somers "[-p pattern] [-S src_addr] \n" 1563cde9171SAlan Somers " [-s packetsize] [-t timeout] [-W waittime] [-z tos] " 1573cde9171SAlan Somers "IPv4-host\n" 1583cde9171SAlan Somers " ping [-4AaDdfHLnoQqRrv] [-C pcp] [-c count] [-I iface] " 1593cde9171SAlan Somers "[-i wait]\n" 1603cde9171SAlan Somers " [-l preload] [-M mask | time] [-m ttl] " 1613cde9171SAlan Somers #ifdef IPSEC 1623cde9171SAlan Somers "[-P policy] " 1633cde9171SAlan Somers #endif 1643cde9171SAlan Somers "[-p pattern]\n" 1653cde9171SAlan Somers " [-S src_addr] [-s packetsize] [-T ttl] [-t timeout] [-W waittime]\n" 1663cde9171SAlan Somers " [-z tos] IPv4-mcast-group\n" 1673cde9171SAlan Somers #ifdef INET6 1683cde9171SAlan Somers " ping [-6aADd" 1693cde9171SAlan Somers #if defined(IPSEC) && !defined(IPSEC_POLICY_IPSEC) 1703cde9171SAlan Somers "E" 1713cde9171SAlan Somers #endif 1723cde9171SAlan Somers "fHnNoOq" 1733cde9171SAlan Somers #ifdef IPV6_USE_MIN_MTU 1743cde9171SAlan Somers "u" 1753cde9171SAlan Somers #endif 1763cde9171SAlan Somers "vyY" 1773cde9171SAlan Somers #if defined(IPSEC) && !defined(IPSEC_POLICY_IPSEC) 1783cde9171SAlan Somers "Z" 1793cde9171SAlan Somers #endif 1803cde9171SAlan Somers "] " 1813cde9171SAlan Somers "[-b bufsiz] [-c count] [-e gateway]\n" 1823cde9171SAlan Somers " [-I interface] [-i wait] [-k addrtype] [-l preload] " 1833cde9171SAlan Somers "[-m hoplimit]\n" 1843cde9171SAlan Somers " [-p pattern]" 1853cde9171SAlan Somers #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) 1863cde9171SAlan Somers " [-P policy]" 1873cde9171SAlan Somers #endif 1883cde9171SAlan Somers " [-S sourceaddr] [-s packetsize] [-t timeout]\n" 1893cde9171SAlan Somers " [-W waittime] [-z tclass] [IPv6-hops ...] IPv6-host\n" 1903cde9171SAlan Somers #endif /* INET6 */ 1913cde9171SAlan Somers ); 1923cde9171SAlan Somers 1933cde9171SAlan Somers exit(1); 1943cde9171SAlan Somers } 195