17cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/* $NetBSD: ping6.c,v 1.73 2010/09/20 11:49:48 ahoka Exp $ */ 27cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/* $KAME: ping6.c,v 1.164 2002/11/16 14:05:37 itojun Exp $ */ 37cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 47cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/* 57cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 67cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * All rights reserved. 77cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * 87cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * Redistribution and use in source and binary forms, with or without 97cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * modification, are permitted provided that the following conditions 107cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * are met: 117cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * 1. Redistributions of source code must retain the above copyright 127cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * notice, this list of conditions and the following disclaimer. 137cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * 2. Redistributions in binary form must reproduce the above copyright 147cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * notice, this list of conditions and the following disclaimer in the 157cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * documentation and/or other materials provided with the distribution. 167cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * 3. Neither the name of the project nor the names of its contributors 177cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * may be used to endorse or promote products derived from this software 187cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * without specific prior written permission. 197cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * 207cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 217cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 227cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 237cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 247cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 257cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 267cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 277cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 287cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 297cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 307cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * SUCH DAMAGE. 317cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 327cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 337cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/* BSDI ping.c,v 2.3 1996/01/21 17:56:50 jch Exp */ 347cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 357cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/* 367cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * Copyright (c) 1989, 1993 377cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * The Regents of the University of California. All rights reserved. 387cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * 397cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * This code is derived from software contributed to Berkeley by 407cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * Mike Muuss. 417cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * 427cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * Redistribution and use in source and binary forms, with or without 437cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * modification, are permitted provided that the following conditions 447cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * are met: 457cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * 1. Redistributions of source code must retain the above copyright 467cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * notice, this list of conditions and the following disclaimer. 477cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * 2. Redistributions in binary form must reproduce the above copyright 487cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * notice, this list of conditions and the following disclaimer in the 497cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * documentation and/or other materials provided with the distribution. 507cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * 3. Neither the name of the University nor the names of its contributors 517cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * may be used to endorse or promote products derived from this software 527cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * without specific prior written permission. 537cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * 547cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 557cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 567cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 577cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 587cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 597cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 607cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 617cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 627cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 637cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 647cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * SUCH DAMAGE. 657cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 667cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 677cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#if 0 687cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifndef lint 697cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonstatic char copyright[] = 707cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson"@(#) Copyright (c) 1989, 1993\n\ 717cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson The Regents of the University of California. All rights reserved.\n"; 727cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif /* not lint */ 737cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 747cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifndef lint 757cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonstatic char sccsid[] = "@(#)ping.c 8.1 (Berkeley) 6/5/93"; 767cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif /* not lint */ 777cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#else 787cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#include <sys/cdefs.h> 797cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifndef lint 807cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson__RCSID("$NetBSD: ping6.c,v 1.73 2010/09/20 11:49:48 ahoka Exp $"); 817cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 827cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 837cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 847cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/* 857cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * Using the InterNet Control Message Protocol (ICMP) "ECHO" facility, 867cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * measure round-trip-delays and packet loss across network paths. 877cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * 887cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * Author - 897cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * Mike Muuss 907cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * U. S. Army Ballistic Research Laboratory 917cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * December, 1983 927cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * 937cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * Status - 947cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * Public Domain. Distribution Unlimited. 957cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * Bugs - 967cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * More statistics could always be gathered. 977cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * This program has to run SUID to ROOT to access the ICMP socket. 987cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 997cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/* 1007cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * NOTE: 1017cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * USE_SIN6_SCOPE_ID assumes that sin6_scope_id has the same semantics 1027cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * as IPV6_PKTINFO. Some people object it (sin6_scope_id specifies *link* 1037cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * while IPV6_PKTINFO specifies *interface*. Link is defined as collection of 1047cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * network attached to 1 or more interfaces) 1057cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 1067cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 1077cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#include <sys/param.h> 1087cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#include <sys/uio.h> 1097cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#include <sys/socket.h> 1107cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#include <sys/time.h> 1117cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 1127cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#include <net/if.h> 1137cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#include <net/route.h> 1147cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 1157cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#include <netinet/in.h> 1167cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#include <netinet/ip6.h> 1177cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#include <netinet/icmp6.h> 1187cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#include <arpa/inet.h> 1197cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#include <arpa/nameser.h> 1207cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#include <netdb.h> 1217cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 1227cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#include <ctype.h> 1237cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#include <err.h> 1247cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#include <errno.h> 1257cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#include <fcntl.h> 1267cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#include <math.h> 1277cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#include <signal.h> 1287cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#include <stdio.h> 1297cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#include <stdlib.h> 1307cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#include <string.h> 1317cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#include <unistd.h> 1327cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#include <poll.h> 1337cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 1347cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPSEC 1357cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#include <netinet6/ah.h> 1367cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#include <netinet6/ipsec.h> 1377cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 1387cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 1392f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson/* 1402f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson * We currently don't have the libc support required for these two features in 1412f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson * Android. Should we get enough support later, feel free to remove the #ifdefs 1422f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson * altogether. 1432f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson */ 1442f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#undef ANDROID_INCLUDE_MD5_SUPPORT 1452f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#undef ANDROID_INCLUDE_RTHDR_SUPPORT 1462f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson 1472f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#ifdef ANDROID_INCLUDE_MD5_SUPPORT 1487cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#include <md5.h> 1492f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#endif 1507cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 1517cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonstruct tv32 { 1527cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson u_int32_t tv32_sec; 1537cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson u_int32_t tv32_usec; 1547cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson}; 1557cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 1567cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define MAXPACKETLEN 131072 1577cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define IP6LEN 40 1587cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define ICMP6ECHOLEN 8 /* icmp echo header len excluding time */ 1597cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define ICMP6ECHOTMLEN sizeof(struct tv32) 1607cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define ICMP6_NIQLEN (ICMP6ECHOLEN + 8) 1617cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/* FQDN case, 64 bits of nonce + 32 bits ttl */ 1627cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define ICMP6_NIRLEN (ICMP6ECHOLEN + 12) 1637cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define EXTRA 256 /* for AH and various other headers. weird. */ 1647cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define DEFDATALEN ICMP6ECHOTMLEN 1657cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define MAXDATALEN MAXPACKETLEN - IP6LEN - ICMP6ECHOLEN 1667cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define NROUTES 9 /* number of record route slots */ 1677cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 1687cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define A(bit) rcvd_tbl[(bit)>>3] /* identify byte in array */ 1697cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define B(bit) (1 << ((bit) & 0x07)) /* identify bit in byte */ 1707cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define SET(bit) (A(bit) |= B(bit)) 1717cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define CLR(bit) (A(bit) &= (~B(bit))) 1727cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define TST(bit) (A(bit) & B(bit)) 1737cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 1747cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define F_FLOOD 0x0001 1757cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define F_INTERVAL 0x0002 1767cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define F_PINGFILLED 0x0008 1777cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define F_QUIET 0x0010 1787cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define F_RROUTE 0x0020 1797cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define F_SO_DEBUG 0x0040 1807cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define F_VERBOSE 0x0100 1817cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPSEC 1827cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPSEC_POLICY_IPSEC 1837cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define F_POLICY 0x0400 1847cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#else 1857cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define F_AUTHHDR 0x0200 1867cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define F_ENCRYPT 0x0400 1877cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif /*IPSEC_POLICY_IPSEC*/ 1887cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif /*IPSEC*/ 1897cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define F_NODEADDR 0x0800 1907cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define F_FQDN 0x1000 1917cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define F_INTERFACE 0x2000 1927cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define F_SRCADDR 0x4000 1937cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPV6_REACHCONF 1947cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define F_REACHCONF 0x8000 1957cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 1967cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define F_HOSTNAME 0x10000 1977cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define F_FQDNOLD 0x20000 1987cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define F_NIGROUP 0x40000 1997cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define F_SUPTYPES 0x80000 2007cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define F_NOMINMTU 0x100000 2017cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define F_NOUSERDATA (F_NODEADDR | F_FQDN | F_FQDNOLD | F_SUPTYPES) 2027cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonu_int options; 2037cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 2047cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define IN6LEN sizeof(struct in6_addr) 2057cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define SA6LEN sizeof(struct sockaddr_in6) 2067cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define DUMMY_PORT 10101 2077cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 2087cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define SIN6(s) ((struct sockaddr_in6 *)(s)) 2097cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 2102f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson/* Android-specific hacks to get this to compile.*/ 2112f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#define INFTIM -1 2122f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#define MAXDNAME 1025 2132f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson 2147cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/* 2157cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * MAX_DUP_CHK is the number of bits in received table, i.e. the maximum 2167cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * number of received sequence numbers we can keep track of. Change 128 2177cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * to 8192 for complete accuracy... 2187cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 2197cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define MAX_DUP_CHK (8 * 8192) 2207cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonint mx_dup_ck = MAX_DUP_CHK; 2217cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonchar rcvd_tbl[MAX_DUP_CHK / 8]; 2227cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 2237cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonstruct addrinfo *res; 2247cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonstruct sockaddr_in6 dst; /* who to ping6 */ 2257cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonstruct sockaddr_in6 src; /* src addr of this packet */ 2267cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonsocklen_t srclen; 2277cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonint datalen = DEFDATALEN; 2287cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonint s; /* socket file descriptor */ 2297cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonu_char outpack[MAXPACKETLEN]; 2307cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonchar BSPACE = '\b'; /* characters written for flood */ 2317cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonchar DOT = '.'; 2327cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonchar *hostname; 2337cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonint ident; /* process id to identify our packets */ 2347cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonu_int8_t nonce[8]; /* nonce field for node information */ 2357cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonint hoplimit = -1; /* hoplimit */ 2367cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonint pathmtu = 0; /* path MTU for the destination. 0 = unspec. */ 2377cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 2387cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/* counters */ 2397cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonlong npackets; /* max packets to transmit */ 2407cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonlong nreceived; /* # of packets we got back */ 2417cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonlong nrepeats; /* number of duplicates */ 2427cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonlong ntransmitted; /* sequence # for outbound packets = #sent */ 2437cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonstruct timeval interval = {1, 0}; /* interval between packets */ 2447cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 2457cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/* timing */ 2467cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonint timing; /* flag to do timing */ 2477cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersondouble tmin = 999999999.0; /* minimum round trip time */ 2487cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersondouble tmax = 0.0; /* maximum round trip time */ 2497cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersondouble tsum = 0.0; /* sum of all times, for doing average */ 2507cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersondouble tsumsq = 0.0; /* sum of all times squared, for std. dev. */ 2517cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 2527cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/* for node addresses */ 2537cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonu_short naflags; 2547cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 2557cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/* for ancillary data(advanced API) */ 2567cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonstruct msghdr smsghdr; 2577cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonstruct iovec smsgiov; 2587cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonchar *scmsg = 0; 2597cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 2607cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvolatile sig_atomic_t seenalrm; 2617cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvolatile sig_atomic_t seenint; 2627cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef SIGINFO 2637cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvolatile sig_atomic_t seeninfo; 2647cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 2657cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 2667cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid fill(char *, char *); 2677cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonint get_hoplim(struct msghdr *); 2687cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonint get_pathmtu(struct msghdr *); 2697cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonstruct in6_pktinfo *get_rcvpktinfo(struct msghdr *); 2707cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid onsignal(int); 2717cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid retransmit(void); 2727cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid onint(int); 2737cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonsize_t pingerlen(void); 2747cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonint pinger(void); 2757cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonconst char *pr_addr(struct sockaddr *, int); 2767cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid pr_icmph(struct icmp6_hdr *, u_char *); 2777cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid pr_iph(struct ip6_hdr *); 2787cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid pr_suptypes(struct icmp6_nodeinfo *, size_t); 2797cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid pr_nodeaddr(struct icmp6_nodeinfo *, int); 2807cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonint myechoreply(const struct icmp6_hdr *); 2817cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonint mynireply(const struct icmp6_nodeinfo *); 2827cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonchar *dnsdecode(const u_char **, const u_char *, const u_char *, 2837cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson char *, size_t); 2847cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid pr_pack(u_char *, int, struct msghdr *); 2857cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid pr_exthdrs(struct msghdr *); 2862f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#ifdef ANDROID_INCLUDE_RTHDR_SUPPORT 2877cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid pr_ip6opt(void *); 2887cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid pr_rthdr(void *); 2892f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#endif 2907cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonint pr_bitrange(u_int32_t, int, int); 2917cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid pr_retip(struct ip6_hdr *, u_char *); 2927cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid summary(void); 2937cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid tvsub(struct timeval *, struct timeval *); 2947cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonint setpolicy(int, char *); 2952f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#ifdef ANDROID_INCLUDE_MD5_SUPPORT 2967cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonchar *nigroup(char *); 2972f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#endif 2987cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid usage(void); 2997cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 3007cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonint 3017cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonmain(int argc, char *argv[]) 3027cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 3037cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct itimerval itimer; 3047cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct sockaddr_in6 from; 3057cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int timeout; 3067cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct addrinfo hints; 3077cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct pollfd fdmaskp[1]; 3087cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int cc; 3097cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson u_int i, packlen; 3107cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int ch, hold, preload, optval, ret_ga; 3117cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson u_char *datap, *packet; 3127cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson char *e, *target, *ifname = NULL, *gateway = NULL; 3137cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int ip6optlen = 0; 3147cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct cmsghdr *scmsgp = NULL; 3157cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#if defined(SO_SNDBUF) && defined(SO_RCVBUF) 3167cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson u_long lsockbufsize; 3177cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int sockbufsize = 0; 3187cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 3197cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int usepktinfo = 0; 3207cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct in6_pktinfo *pktinfo = NULL; 3212f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#ifdef ANDROID_INCLUDE_RTHDR_SUPPORT 3227cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct ip6_rthdr *rthdr = NULL; 3232f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#endif 3247cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPSEC_POLICY_IPSEC 3257cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson char *policy_in = NULL; 3267cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson char *policy_out = NULL; 3277cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 3287cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson double intval; 3297cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson size_t rthlen; 3307cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPV6_USE_MIN_MTU 3317cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int mflag = 0; 3327cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 3337cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 3347cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* just to be sure */ 3357cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson memset(&smsghdr, 0, sizeof(smsghdr)); 3367cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson memset(&smsgiov, 0, sizeof(smsgiov)); 3377cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 3387cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson preload = 0; 3397cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson datap = &outpack[ICMP6ECHOLEN + ICMP6ECHOTMLEN]; 3407cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifndef IPSEC 3417cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define ADDOPTS 3427cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#else 3437cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPSEC_POLICY_IPSEC 3447cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define ADDOPTS "P:" 3457cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#else 3467cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define ADDOPTS "AE" 3477cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif /*IPSEC_POLICY_IPSEC*/ 3487cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 3492f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson 3502f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#ifdef ANDROID_INCLUDE_MD5_SUPPORT 3512f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#define ANDROID_MD5_OPTS "N" 3522f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#else 3532f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#define ANDROID_MD5_OPTS "" 3542f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#endif 3557cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson while ((ch = getopt(argc, argv, 3562f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson "a:b:c:dfHg:h:I:i:l:mnp:qRS:s:tvwW" ADDOPTS ANDROID_MD5_OPTS)) != -1) { 3577cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#undef ADDOPTS 3587cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson switch (ch) { 3597cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'a': 3607cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson { 3617cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson char *cp; 3627cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 3637cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson options &= ~F_NOUSERDATA; 3647cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson options |= F_NODEADDR; 3657cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson for (cp = optarg; *cp != '\0'; cp++) { 3667cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson switch (*cp) { 3677cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'a': 3687cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson naflags |= NI_NODEADDR_FLAG_ALL; 3697cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 3707cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'c': 3717cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'C': 3727cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson naflags |= NI_NODEADDR_FLAG_COMPAT; 3737cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 3747cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'l': 3757cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'L': 3767cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson naflags |= NI_NODEADDR_FLAG_LINKLOCAL; 3777cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 3787cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 's': 3797cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'S': 3807cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson naflags |= NI_NODEADDR_FLAG_SITELOCAL; 3817cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 3827cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'g': 3837cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'G': 3847cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson naflags |= NI_NODEADDR_FLAG_GLOBAL; 3857cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 3867cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'A': /* experimental. not in the spec */ 3877cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef NI_NODEADDR_FLAG_ANYCAST 3887cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson naflags |= NI_NODEADDR_FLAG_ANYCAST; 3897cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 3907cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#else 3917cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, 3927cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson"-a A is not supported on the platform"); 3937cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /*NOTREACHED*/ 3947cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 3957cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson default: 3967cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson usage(); 3977cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /*NOTREACHED*/ 3987cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 3997cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 4007cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 4017cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 4027cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'b': 4037cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#if defined(SO_SNDBUF) && defined(SO_RCVBUF) 4047cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errno = 0; 4057cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson e = NULL; 4067cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson lsockbufsize = strtoul(optarg, &e, 10); 4077cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sockbufsize = lsockbufsize; 4087cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (errno || !*optarg || *e || 4097cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (u_long)sockbufsize != lsockbufsize) 4107cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "invalid socket buffer size"); 4117cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#else 4127cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, 4137cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson"-b option ignored: SO_SNDBUF/SO_RCVBUF socket options not supported"); 4147cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 4157cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 4167cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'c': 4177cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson npackets = strtol(optarg, &e, 10); 4187cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (npackets <= 0 || *optarg == '\0' || *e != '\0') 4197cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, 4207cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson "illegal number of packets -- %s", optarg); 4217cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 4227cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'd': 4237cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson options |= F_SO_DEBUG; 4247cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 4257cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'f': 4267cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (getuid()) { 4277cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errno = EPERM; 4287cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "Must be superuser to flood ping"); 4297cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 4307cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson options |= F_FLOOD; 4317cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson setbuf(stdout, (char *)NULL); 4327cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 4337cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'g': 4347cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson gateway = optarg; 4357cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 4367cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'H': 4377cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson options |= F_HOSTNAME; 4387cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 4397cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'h': /* hoplimit */ 4407cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson hoplimit = strtol(optarg, &e, 10); 4417cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (*optarg == '\0' || *e != '\0') 4427cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "illegal hoplimit %s", optarg); 4437cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (255 < hoplimit || hoplimit < -1) 4447cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, 4457cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson "illegal hoplimit -- %s", optarg); 4467cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 4477cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'I': 4487cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ifname = optarg; 4497cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson options |= F_INTERFACE; 4507cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifndef USE_SIN6_SCOPE_ID 4517cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson usepktinfo++; 4527cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 4537cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 4547cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'i': /* wait between sending packets */ 4557cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson intval = strtod(optarg, &e); 4567cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (*optarg == '\0' || *e != '\0') 4577cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "illegal timing interval %s", optarg); 4587cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (intval < 1 && getuid()) { 4597cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "%s: only root may use interval < 1s", 4607cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson strerror(EPERM)); 4617cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 4627cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson interval.tv_sec = (long)intval; 4637cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson interval.tv_usec = 4647cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (long)((intval - interval.tv_sec) * 1000000); 4657cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (interval.tv_sec < 0) 4667cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "illegal timing interval %s", optarg); 4677cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* less than 1/hz does not make sense */ 4687cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (interval.tv_sec == 0 && interval.tv_usec < 10000) { 4697cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson warnx("too small interval, raised to 0.01"); 4707cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson interval.tv_usec = 10000; 4717cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 4727cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson options |= F_INTERVAL; 4737cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 4747cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'l': 4757cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (getuid()) { 4767cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errno = EPERM; 4777cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "Must be superuser to preload"); 4787cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 4797cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson preload = strtol(optarg, &e, 10); 4807cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (preload < 0 || *optarg == '\0' || *e != '\0') 4817cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "illegal preload value -- %s", optarg); 4827cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 4837cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'm': 4847cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPV6_USE_MIN_MTU 4857cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson mflag++; 4867cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 4877cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#else 4887cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "-%c is not supported on this platform", ch); 4897cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /*NOTREACHED*/ 4907cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 4917cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'n': 4927cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson options &= ~F_HOSTNAME; 4937cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 4942f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#ifdef ANDROID_INCLUDE_MD5_SUPPORT 4957cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'N': 4967cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson options |= F_NIGROUP; 4977cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 4982f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#endif 4997cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'p': /* fill buffer with user pattern */ 5007cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson options |= F_PINGFILLED; 5017cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson fill((char *)datap, optarg); 5027cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 5037cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'q': 5047cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson options |= F_QUIET; 5057cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 5067cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'R': 5077cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPV6_REACHCONF 5087cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson options |= F_REACHCONF; 5097cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 5107cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#else 5117cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "-R is not supported in this configuration"); 5127cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 5137cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'S': 5147cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson memset(&hints, 0, sizeof(struct addrinfo)); 5157cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson hints.ai_flags = AI_NUMERICHOST; /* allow hostname? */ 5167cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson hints.ai_family = AF_INET6; 5177cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson hints.ai_socktype = SOCK_RAW; 5187cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson hints.ai_protocol = IPPROTO_ICMPV6; 5197cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 5207cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ret_ga = getaddrinfo(optarg, NULL, &hints, &res); 5217cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (ret_ga) { 5227cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "invalid source address: %s", 5237cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson gai_strerror(ret_ga)); 5247cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 5257cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* 5267cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * res->ai_family must be AF_INET6 and res->ai_addrlen 5277cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * must be sizeof(src). 5287cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 5297cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson memcpy(&src, res->ai_addr, res->ai_addrlen); 5307cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson srclen = res->ai_addrlen; 5317cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson freeaddrinfo(res); 5327cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson options |= F_SRCADDR; 5337cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 5347cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 's': /* size of packet to send */ 5357cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson datalen = strtol(optarg, &e, 10); 5367cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (datalen <= 0 || *optarg == '\0' || *e != '\0') 5377cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "illegal datalen value -- %s", optarg); 5387cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (datalen > MAXDATALEN) { 5397cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, 5407cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson "datalen value too large, maximum is %d", 5417cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson MAXDATALEN); 5427cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 5437cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 5447cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 't': 5457cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson options &= ~F_NOUSERDATA; 5467cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson options |= F_SUPTYPES; 5477cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 5487cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'v': 5497cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson options |= F_VERBOSE; 5507cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 5517cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'w': 5527cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson options &= ~F_NOUSERDATA; 5537cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson options |= F_FQDN; 5547cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 5557cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'W': 5567cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson options &= ~F_NOUSERDATA; 5577cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson options |= F_FQDNOLD; 5587cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 5597cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPSEC 5607cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPSEC_POLICY_IPSEC 5617cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'P': 5627cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson options |= F_POLICY; 5637cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (!strncmp("in", optarg, 2)) { 5647cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((policy_in = strdup(optarg)) == NULL) 5657cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "strdup"); 5667cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else if (!strncmp("out", optarg, 3)) { 5677cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((policy_out = strdup(optarg)) == NULL) 5687cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "strdup"); 5697cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else 5707cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "invalid security policy"); 5717cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 5727cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#else 5737cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'A': 5747cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson options |= F_AUTHHDR; 5757cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 5767cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 'E': 5777cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson options |= F_ENCRYPT; 5787cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 5797cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif /*IPSEC_POLICY_IPSEC*/ 5807cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif /*IPSEC*/ 5817cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson default: 5827cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson usage(); 5837cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /*NOTREACHED*/ 5847cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 5857cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 5867cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 5877cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson argc -= optind; 5887cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson argv += optind; 5897cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 5907cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (argc < 1) { 5917cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson usage(); 5927cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /*NOTREACHED*/ 5937cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 5947cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 5957cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (argc > 1) { 5962f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#ifdef ANDROID_INCLUDE_RTHDR_SUPPORT 5977cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson rthlen = CMSG_SPACE(inet6_rth_space(IPV6_RTHDR_TYPE_0, 5987cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson argc - 1)); 5997cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (rthlen == 0) { 6007cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "too many intermediate hops"); 6017cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /*NOTREACHED*/ 6027cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 6037cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ip6optlen += rthlen; 6042f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#else 6052f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson errx(1, "compiled without support for routing headers"); 6062f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#endif 6077cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 6087cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 6092f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#ifdef ANDROID_INCLUDE_MD5_SUPPORT 6107cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (options & F_NIGROUP) { 6117cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson target = nigroup(argv[argc - 1]); 6127cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (target == NULL) { 6137cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson usage(); 6147cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /*NOTREACHED*/ 6157cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 6167cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else 6172f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#endif 6187cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson target = argv[argc - 1]; 6197cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 6207cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* getaddrinfo */ 6217cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson memset(&hints, 0, sizeof(struct addrinfo)); 6227cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson hints.ai_flags = AI_CANONNAME; 6237cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson hints.ai_family = AF_INET6; 6247cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson hints.ai_socktype = SOCK_RAW; 6257cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson hints.ai_protocol = IPPROTO_ICMPV6; 6267cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 6277cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ret_ga = getaddrinfo(target, NULL, &hints, &res); 6287cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (ret_ga) 6297cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "%s", gai_strerror(ret_ga)); 6307cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (res->ai_canonname) 6317cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson hostname = res->ai_canonname; 6327cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson else 6337cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson hostname = target; 6347cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 6357cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (!res->ai_addr) 6367cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "getaddrinfo failed"); 6377cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 6387cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)memcpy(&dst, res->ai_addr, res->ai_addrlen); 6397cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 6407cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((s = socket(res->ai_family, res->ai_socktype, 6417cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson res->ai_protocol)) < 0) 6427cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "socket"); 6437cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 6447cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* set the source address if specified. */ 6457cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((options & F_SRCADDR) && 6467cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson bind(s, (struct sockaddr *)&src, srclen) != 0) { 6477cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "bind"); 6487cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 6497cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 6507cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* set the gateway (next hop) if specified */ 6517cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (gateway) { 6527cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct addrinfo ghints, *gres; 6537cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int error; 6547cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 6557cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson memset(&ghints, 0, sizeof(ghints)); 6567cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ghints.ai_family = AF_INET6; 6577cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ghints.ai_socktype = SOCK_RAW; 6587cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ghints.ai_protocol = IPPROTO_ICMPV6; 6597cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 6607cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson error = getaddrinfo(gateway, NULL, &hints, &gres); 6617cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (error) { 6627cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "getaddrinfo for the gateway %s: %s", 6637cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson gateway, gai_strerror(error)); 6647cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 6657cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (gres->ai_next && (options & F_VERBOSE)) 6667cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson warnx("gateway resolves to multiple addresses"); 6677cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 6687cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (setsockopt(s, IPPROTO_IPV6, IPV6_NEXTHOP, 6697cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson gres->ai_addr, gres->ai_addrlen)) { 6707cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "setsockopt(IPV6_NEXTHOP)"); 6717cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 6727cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 6737cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson freeaddrinfo(gres); 6747cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 6757cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 6767cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* 6777cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * let the kerel pass extension headers of incoming packets, 6787cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * for privileged socket options 6797cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 6807cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((options & F_VERBOSE) != 0) { 6817cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int opton = 1; 6827cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 6837cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPV6_RECVHOPOPTS 6847cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVHOPOPTS, &opton, 6857cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(opton))) 6867cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "setsockopt(IPV6_RECVHOPOPTS)"); 6877cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#else /* old adv. API */ 6887cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (setsockopt(s, IPPROTO_IPV6, IPV6_HOPOPTS, &opton, 6897cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(opton))) 6907cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "setsockopt(IPV6_HOPOPTS)"); 6917cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 6927cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPV6_RECVDSTOPTS 6937cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVDSTOPTS, &opton, 6947cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(opton))) 6957cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "setsockopt(IPV6_RECVDSTOPTS)"); 6967cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#else /* old adv. API */ 6977cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (setsockopt(s, IPPROTO_IPV6, IPV6_DSTOPTS, &opton, 6987cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(opton))) 6997cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "setsockopt(IPV6_DSTOPTS)"); 7007cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 7017cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPV6_RECVRTHDRDSTOPTS 7027cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVRTHDRDSTOPTS, &opton, 7037cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(opton))) 7047cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "setsockopt(IPV6_RECVRTHDRDSTOPTS)"); 7057cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 7067cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 7077cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 7087cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* revoke root privilege */ 7097cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson seteuid(getuid()); 7107cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson setuid(getuid()); 7117cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 7127cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((options & F_FLOOD) && (options & F_INTERVAL)) 7137cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "-f and -i incompatible options"); 7147cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 7157cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((options & F_NOUSERDATA) == 0) { 7167cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (datalen >= (int)sizeof(struct tv32)) { 7177cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* we can time transfer */ 7187cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson timing = 1; 7197cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else 7207cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson timing = 0; 7217cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* in F_VERBOSE case, we may get non-echoreply packets*/ 7227cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (options & F_VERBOSE) 7237cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson packlen = 2048 + IP6LEN + ICMP6ECHOLEN + EXTRA; 7247cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson else 7257cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson packlen = datalen + IP6LEN + ICMP6ECHOLEN + EXTRA; 7267cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else { 7277cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* suppress timing for node information query */ 7287cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson timing = 0; 7297cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson datalen = 2048; 7307cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson packlen = 2048 + IP6LEN + ICMP6ECHOLEN + EXTRA; 7317cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 7327cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 7337cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (!(packet = (u_char *)malloc(packlen))) 7347cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "Unable to allocate packet"); 7357cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (!(options & F_PINGFILLED)) 7367cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson for (i = ICMP6ECHOLEN; i < packlen; ++i) 7377cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson *datap++ = i; 7387cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 7397cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ident = arc4random() & 0xFFFF; 7407cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson memset(nonce, 0, sizeof(nonce)); 7417cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson for (i = 0; i < sizeof(nonce); i += sizeof(u_int32_t)) 7427cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson *((u_int32_t *)&nonce[i]) = arc4random(); 7437cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 7447cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson hold = 1; 7457cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 7467cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (options & F_SO_DEBUG) 7477cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&hold, 7487cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(hold)); 7497cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson optval = IPV6_DEFHLIM; 7507cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr)) 7517cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, 7527cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson &optval, sizeof(optval)) == -1) 7537cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "IPV6_MULTICAST_HOPS"); 7547cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPV6_USE_MIN_MTU 7557cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (mflag != 1) { 7567cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson optval = mflag > 1 ? 0 : 1; 7577cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 7587cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (setsockopt(s, IPPROTO_IPV6, IPV6_USE_MIN_MTU, 7597cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson &optval, sizeof(optval)) == -1) 7607cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "setsockopt(IPV6_USE_MIN_MTU)"); 7617cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 7627cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPV6_RECVPATHMTU 7637cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson else { 7647cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson optval = 1; 7657cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVPATHMTU, 7667cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson &optval, sizeof(optval)) == -1) 7677cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "setsockopt(IPV6_RECVPATHMTU)"); 7687cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 7697cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif /* IPV6_RECVPATHMTU */ 7707cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif /* IPV6_USE_MIN_MTU */ 7717cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 7727cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPSEC 7737cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPSEC_POLICY_IPSEC 7747cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (options & F_POLICY) { 7757cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (setpolicy(s, policy_in) < 0) 7767cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "%s", ipsec_strerror()); 7777cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (setpolicy(s, policy_out) < 0) 7787cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "%s", ipsec_strerror()); 7797cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 7807cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#else 7817cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (options & F_AUTHHDR) { 7827cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson optval = IPSEC_LEVEL_REQUIRE; 7837cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPV6_AUTH_TRANS_LEVEL 7847cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (setsockopt(s, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, 7857cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson &optval, sizeof(optval)) == -1) 7867cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "setsockopt(IPV6_AUTH_TRANS_LEVEL)"); 7877cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#else /* old def */ 7887cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (setsockopt(s, IPPROTO_IPV6, IPV6_AUTH_LEVEL, 7897cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson &optval, sizeof(optval)) == -1) 7907cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "setsockopt(IPV6_AUTH_LEVEL)"); 7917cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 7927cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 7937cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (options & F_ENCRYPT) { 7947cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson optval = IPSEC_LEVEL_REQUIRE; 7957cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (setsockopt(s, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, 7967cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson &optval, sizeof(optval)) == -1) 7977cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "setsockopt(IPV6_ESP_TRANS_LEVEL)"); 7987cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 7997cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif /*IPSEC_POLICY_IPSEC*/ 8007cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 8017cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 8027cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef ICMP6_FILTER 8037cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson { 8047cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct icmp6_filter filt; 8057cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (!(options & F_VERBOSE)) { 8067cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ICMP6_FILTER_SETBLOCKALL(&filt); 8077cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((options & F_FQDN) || (options & F_FQDNOLD) || 8087cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (options & F_NODEADDR) || (options & F_SUPTYPES)) 8097cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ICMP6_FILTER_SETPASS(ICMP6_NI_REPLY, &filt); 8107cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson else 8117cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ICMP6_FILTER_SETPASS(ICMP6_ECHO_REPLY, &filt); 8127cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else { 8137cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ICMP6_FILTER_SETPASSALL(&filt); 8147cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 8157cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, 8167cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(filt)) < 0) 8177cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "setsockopt(ICMP6_FILTER)"); 8187cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 8197cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif /*ICMP6_FILTER*/ 8207cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 8217cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* let the kerel pass extension headers of incoming packets */ 8227cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((options & F_VERBOSE) != 0) { 8237cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int opton = 1; 8247cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 8257cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPV6_RECVRTHDR 8267cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVRTHDR, &opton, 8277cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(opton))) 8287cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "setsockopt(IPV6_RECVRTHDR)"); 8297cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#else /* old adv. API */ 8307cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (setsockopt(s, IPPROTO_IPV6, IPV6_RTHDR, &opton, 8317cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(opton))) 8327cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "setsockopt(IPV6_RTHDR)"); 8337cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 8347cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 8357cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 8367cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/* 8377cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson optval = 1; 8387cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr)) 8397cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, 8407cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson &optval, sizeof(optval)) == -1) 8417cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "IPV6_MULTICAST_LOOP"); 8427cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson*/ 8437cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 8447cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* Specify the outgoing interface and/or the source address */ 8457cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (usepktinfo) 8467cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ip6optlen += CMSG_SPACE(sizeof(struct in6_pktinfo)); 8477cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 8487cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (hoplimit != -1) 8497cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ip6optlen += CMSG_SPACE(sizeof(int)); 8507cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 8517cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPV6_REACHCONF 8527cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (options & F_REACHCONF) 8537cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ip6optlen += CMSG_SPACE(0); 8547cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 8557cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 8567cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* set IP6 packet options */ 8577cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (ip6optlen) { 8587cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((scmsg = (char *)malloc(ip6optlen)) == 0) 8597cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "can't allocate enough memory"); 8607cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson smsghdr.msg_control = (caddr_t)scmsg; 8617cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson smsghdr.msg_controllen = ip6optlen; 8627cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson scmsgp = (struct cmsghdr *)scmsg; 8637cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 8647cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (usepktinfo) { 8657cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson pktinfo = (struct in6_pktinfo *)(CMSG_DATA(scmsgp)); 8667cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson memset(pktinfo, 0, sizeof(*pktinfo)); 8677cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson scmsgp->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); 8687cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson scmsgp->cmsg_level = IPPROTO_IPV6; 8697cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson scmsgp->cmsg_type = IPV6_PKTINFO; 8707cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp); 8717cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 8727cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 8737cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* set the outgoing interface */ 8747cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (ifname) { 8757cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifndef USE_SIN6_SCOPE_ID 8767cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* pktinfo must have already been allocated */ 8777cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((pktinfo->ipi6_ifindex = if_nametoindex(ifname)) == 0) 8787cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "%s: invalid interface name", ifname); 8797cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#else 8807cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((dst.sin6_scope_id = if_nametoindex(ifname)) == 0) 8817cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "%s: invalid interface name", ifname); 8827cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 8837cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 8847cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (hoplimit != -1) { 8857cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson scmsgp->cmsg_len = CMSG_LEN(sizeof(int)); 8867cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson scmsgp->cmsg_level = IPPROTO_IPV6; 8877cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson scmsgp->cmsg_type = IPV6_HOPLIMIT; 8887cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson *(int *)(CMSG_DATA(scmsgp)) = hoplimit; 8897cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 8907cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp); 8917cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 8927cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPV6_REACHCONF 8937cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (options & F_REACHCONF) { 8947cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson scmsgp->cmsg_len = CMSG_LEN(0); 8957cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson scmsgp->cmsg_level = IPPROTO_IPV6; 8967cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson scmsgp->cmsg_type = IPV6_REACHCONF; 8977cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 8987cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp); 8997cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 9007cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 9017cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 9027cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (argc > 1) { /* some intermediate addrs are specified */ 9032f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#ifdef ANDROID_INCLUDE_RTHDR_SUPPORT 9047cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int hops, error; 9057cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int rthdrlen; 9067cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 9077cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson rthdrlen = inet6_rth_space(IPV6_RTHDR_TYPE_0, argc - 1); 9087cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson scmsgp->cmsg_len = CMSG_LEN(rthdrlen); 9097cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson scmsgp->cmsg_level = IPPROTO_IPV6; 9107cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson scmsgp->cmsg_type = IPV6_RTHDR; 9117cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson rthdr = (struct ip6_rthdr *)CMSG_DATA(scmsgp); 9127cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson rthdr = inet6_rth_init((void *)rthdr, rthdrlen, 9137cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson IPV6_RTHDR_TYPE_0, argc - 1); 9147cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (rthdr == NULL) 9157cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "can't initialize rthdr"); 9167cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 9177cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson for (hops = 0; hops < argc - 1; hops++) { 9187cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct addrinfo *iaip; 9197cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 9207cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((error = getaddrinfo(argv[hops], NULL, &hints, 9217cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson &iaip))) 9227cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "%s", gai_strerror(error)); 9237cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (SIN6(iaip->ai_addr)->sin6_family != AF_INET6) 9247cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, 9257cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson "bad addr family of an intermediate addr"); 9267cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 9277cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (inet6_rth_add(rthdr, 9287cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson &(SIN6(iaip->ai_addr))->sin6_addr)) 9297cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "can't add an intermediate node"); 9307cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson freeaddrinfo(iaip); 9317cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 9327cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 9337cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp); 9342f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#else 9352f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson errx(1, "compiled without support for routing headers"); 9362f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#endif 9377cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 9387cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 9397cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (!(options & F_SRCADDR)) { 9407cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* 9417cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * get the source address. XXX since we revoked the root 9427cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * privilege, we cannot use a raw socket for this. 9437cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 9447cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int dummy; 9457cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson socklen_t len = sizeof(src); 9467cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 9477cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((dummy = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) 9487cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "UDP socket"); 9497cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 9507cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson src.sin6_family = AF_INET6; 9517cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson src.sin6_addr = dst.sin6_addr; 9527cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson src.sin6_port = ntohs(DUMMY_PORT); 9537cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson src.sin6_scope_id = dst.sin6_scope_id; 9547cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 9557cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (pktinfo && 9567cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson setsockopt(dummy, IPPROTO_IPV6, IPV6_PKTINFO, 9577cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void *)pktinfo, sizeof(*pktinfo))) 9587cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "UDP setsockopt(IPV6_PKTINFO)"); 9597cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 9607cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (hoplimit != -1 && 9617cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson setsockopt(dummy, IPPROTO_IPV6, IPV6_UNICAST_HOPS, 9627cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void *)&hoplimit, sizeof(hoplimit))) 9637cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "UDP setsockopt(IPV6_UNICAST_HOPS)"); 9647cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 9657cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (hoplimit != -1 && 9667cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson setsockopt(dummy, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, 9677cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void *)&hoplimit, sizeof(hoplimit))) 9687cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "UDP setsockopt(IPV6_MULTICAST_HOPS)"); 9697cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 9702f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#ifdef ANDROID_INCLUDE_RTHDR_SUPPORT 9717cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (rthdr && 9727cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson setsockopt(dummy, IPPROTO_IPV6, IPV6_RTHDR, 9737cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void *)rthdr, (rthdr->ip6r_len + 1) << 3)) 9747cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "UDP setsockopt(IPV6_RTHDR)"); 9752f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#endif 9767cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 9777cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (connect(dummy, (struct sockaddr *)&src, len) < 0) 9787cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "UDP connect"); 9797cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 9807cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (getsockname(dummy, (struct sockaddr *)&src, &len) < 0) 9817cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "getsockname"); 9827cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 9837cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson close(dummy); 9847cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 9857cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 9867cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#if defined(SO_SNDBUF) && defined(SO_RCVBUF) 9877cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (sockbufsize) { 9887cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (datalen > sockbufsize) 9897cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson warnx("you need -b to increase socket buffer size"); 9907cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sockbufsize, 9917cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(sockbufsize)) < 0) 9927cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "setsockopt(SO_SNDBUF)"); 9937cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &sockbufsize, 9947cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(sockbufsize)) < 0) 9957cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson err(1, "setsockopt(SO_RCVBUF)"); 9967cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 9977cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson else { 9987cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (datalen > 8 * 1024) /*XXX*/ 9997cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson warnx("you need -b to increase socket buffer size"); 10007cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* 10017cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * When pinging the broadcast address, you can get a lot of 10027cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * answers. Doing something so evil is useful if you are trying 10037cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * to stress the ethernet, or just want to fill the arp cache 10047cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * to get some stuff for /etc/ethers. 10057cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 10067cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson hold = 48 * 1024; 10077cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&hold, 10087cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(hold)); 10097cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 10107cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 10117cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 10127cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson optval = 1; 10137cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifndef USE_SIN6_SCOPE_ID 10147cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPV6_RECVPKTINFO 10157cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO, &optval, 10167cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(optval)) < 0) 10177cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson warn("setsockopt(IPV6_RECVPKTINFO)"); /* XXX err? */ 10187cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#else /* old adv. API */ 10197cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (setsockopt(s, IPPROTO_IPV6, IPV6_PKTINFO, &optval, 10207cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(optval)) < 0) 10217cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson warn("setsockopt(IPV6_PKTINFO)"); /* XXX err? */ 10227cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 10237cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif /* USE_SIN6_SCOPE_ID */ 10247cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPV6_RECVHOPLIMIT 10257cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &optval, 10267cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(optval)) < 0) 10277cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson warn("setsockopt(IPV6_RECVHOPLIMIT)"); /* XXX err? */ 10287cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#else /* old adv. API */ 10297cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (setsockopt(s, IPPROTO_IPV6, IPV6_HOPLIMIT, &optval, 10307cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(optval)) < 0) 10317cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson warn("setsockopt(IPV6_HOPLIMIT)"); /* XXX err? */ 10327cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 10337cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 10347cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("PING6(%lu=40+8+%lu bytes) ", (unsigned long)(40 + pingerlen()), 10357cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (unsigned long)(pingerlen() - 8)); 10367cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("%s --> ", pr_addr((struct sockaddr *)&src, sizeof(src))); 10377cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("%s\n", pr_addr((struct sockaddr *)&dst, sizeof(dst))); 10387cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 10397cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson while (preload--) /* Fire off them quickies. */ 10407cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)pinger(); 10417cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 10427cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)signal(SIGINT, onsignal); 10437cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef SIGINFO 10447cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)signal(SIGINFO, onsignal); 10457cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 10467cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 10477cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((options & F_FLOOD) == 0) { 10487cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)signal(SIGALRM, onsignal); 10497cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson itimer.it_interval = interval; 10507cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson itimer.it_value = interval; 10517cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)setitimer(ITIMER_REAL, &itimer, NULL); 10527cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (ntransmitted == 0) 10537cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson retransmit(); 10547cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 10557cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 10567cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson seenalrm = seenint = 0; 10577cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef SIGINFO 10587cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson seeninfo = 0; 10597cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 10607cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 10617cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson for (;;) { 10627cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct msghdr m; 10637cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct cmsghdr *cm; 10647cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson u_char buf[1024]; 10657cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct iovec iov[2]; 10667cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 10677cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* signal handling */ 10687cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (seenalrm) { 10697cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson retransmit(); 10707cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson seenalrm = 0; 10717cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson continue; 10727cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 10737cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (seenint) { 10747cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson onint(SIGINT); 10757cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson seenint = 0; 10767cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson continue; 10777cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 10787cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef SIGINFO 10797cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (seeninfo) { 10807cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson summary(); 10817cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson seeninfo = 0; 10827cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson continue; 10837cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 10847cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 10857cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 10867cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (options & F_FLOOD) { 10877cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)pinger(); 10887cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson timeout = 10; 10897cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else { 10907cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson timeout = INFTIM; 10917cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 10927cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson fdmaskp[0].fd = s; 10937cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson fdmaskp[0].events = POLLIN; 10947cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cc = poll(fdmaskp, 1, timeout); 10957cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (cc < 0) { 10967cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (errno != EINTR) { 10977cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson warn("poll"); 10987cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sleep(1); 10997cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 11007cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson continue; 11017cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else if (cc == 0) 11027cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson continue; 11037cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 11047cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson m.msg_name = (caddr_t)&from; 11057cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson m.msg_namelen = sizeof(from); 11067cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson memset(&iov, 0, sizeof(iov)); 11077cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson iov[0].iov_base = (caddr_t)packet; 11087cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson iov[0].iov_len = packlen; 11097cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson m.msg_iov = iov; 11107cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson m.msg_iovlen = 1; 11117cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cm = (struct cmsghdr *)buf; 11127cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson m.msg_control = (caddr_t)buf; 11137cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson m.msg_controllen = sizeof(buf); 11147cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 11157cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cc = recvmsg(s, &m, 0); 11167cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (cc < 0) { 11177cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (errno != EINTR) { 11187cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson warn("recvmsg"); 11197cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sleep(1); 11207cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 11217cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson continue; 11227cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else if (cc == 0) { 11237cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int mtu; 11247cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 11257cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* 11267cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * receive control messages only. Process the 11277cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * exceptions (currently the only possiblity is 11287cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * a path MTU notification.) 11297cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 11307cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((mtu = get_pathmtu(&m)) > 0) { 11317cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((options & F_VERBOSE) != 0) { 11327cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("new path MTU (%d) is " 11337cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson "notified\n", mtu); 11347cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 11357cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 11367cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson continue; 11377cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else { 11387cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* 11397cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * an ICMPv6 message (probably an echoreply) arrived. 11407cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 11417cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson pr_pack(packet, cc, &m); 11427cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 11437cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (npackets && nreceived >= npackets) 11447cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 11457cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 11467cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson summary(); 11477cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson exit(nreceived == 0); 11487cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 11497cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 11507cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid 11517cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersononsignal(int sig) 11527cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 11537cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 11547cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson switch (sig) { 11557cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case SIGALRM: 11567cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson seenalrm++; 11577cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 11587cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case SIGINT: 11597cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson seenint++; 11607cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 11617cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef SIGINFO 11627cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case SIGINFO: 11637cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson seeninfo++; 11647cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 11657cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 11667cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 11677cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 11687cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 11697cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/* 11707cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * retransmit -- 11717cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * This routine transmits another ping6. 11727cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 11737cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid 11747cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonretransmit(void) 11757cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 11767cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct itimerval itimer; 11777cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 11787cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (pinger() == 0) 11797cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return; 11807cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 11817cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* 11827cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * If we're not transmitting any more packets, change the timer 11837cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * to wait two round-trip times if we've received any packets or 11847cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * ten seconds if we haven't. 11857cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 11867cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define MAXWAIT 10 11877cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (nreceived) { 11887cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson itimer.it_value.tv_sec = 2 * tmax / 1000; 11897cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (itimer.it_value.tv_sec == 0) 11907cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson itimer.it_value.tv_sec = 1; 11917cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else 11927cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson itimer.it_value.tv_sec = MAXWAIT; 11937cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson itimer.it_interval.tv_sec = 0; 11947cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson itimer.it_interval.tv_usec = 0; 11957cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson itimer.it_value.tv_usec = 0; 11967cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 11977cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)signal(SIGALRM, onint); 11987cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)setitimer(ITIMER_REAL, &itimer, NULL); 11997cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 12007cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 12017cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/* 12027cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * pinger -- 12037cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * Compose and transmit an ICMP ECHO REQUEST packet. The IP packet 12047cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * will be added on by the kernel. The ID field is our UNIX process ID, 12057cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * and the sequence number is an ascending integer. The first 8 bytes 12067cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * of the data portion are used to hold a UNIX "timeval" struct in VAX 12077cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * byte-order, to compute the round-trip time. 12087cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 12097cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonsize_t 12107cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonpingerlen(void) 12117cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 12127cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson size_t l; 12137cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 12147cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (options & F_FQDN) 12157cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson l = ICMP6_NIQLEN + sizeof(dst.sin6_addr); 12167cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson else if (options & F_FQDNOLD) 12177cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson l = ICMP6_NIQLEN; 12187cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson else if (options & F_NODEADDR) 12197cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson l = ICMP6_NIQLEN + sizeof(dst.sin6_addr); 12207cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson else if (options & F_SUPTYPES) 12217cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson l = ICMP6_NIQLEN; 12227cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson else 12237cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson l = ICMP6ECHOLEN + datalen; 12247cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 12257cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return l; 12267cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 12277cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 12287cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonint 12297cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonpinger(void) 12307cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 12317cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct icmp6_hdr *icp; 12327cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct iovec iov[2]; 12337cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int i, cc; 12347cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct icmp6_nodeinfo *nip; 12357cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int seq; 12367cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 12377cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (npackets && ntransmitted >= npackets) 12387cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return(-1); /* no more transmission */ 12397cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 12407cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson icp = (struct icmp6_hdr *)outpack; 12417cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson nip = (struct icmp6_nodeinfo *)outpack; 12427cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson memset(icp, 0, sizeof(*icp)); 12437cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson icp->icmp6_cksum = 0; 12447cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson seq = ntransmitted++; 12457cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson CLR(seq % mx_dup_ck); 12467cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 12477cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (options & F_FQDN) { 12487cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson icp->icmp6_type = ICMP6_NI_QUERY; 12497cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson icp->icmp6_code = ICMP6_NI_SUBJ_IPV6; 12507cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson nip->ni_qtype = htons(NI_QTYPE_FQDN); 12517cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson nip->ni_flags = htons(0); 12527cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 12537cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson memcpy(nip->icmp6_ni_nonce, nonce, 12547cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(nip->icmp6_ni_nonce)); 12557cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson *(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq); 12567cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 12577cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson memcpy(&outpack[ICMP6_NIQLEN], &dst.sin6_addr, 12587cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(dst.sin6_addr)); 12597cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cc = ICMP6_NIQLEN + sizeof(dst.sin6_addr); 12607cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson datalen = 0; 12617cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else if (options & F_FQDNOLD) { 12627cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* packet format in 03 draft - no Subject data on queries */ 12637cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson icp->icmp6_type = ICMP6_NI_QUERY; 12647cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson icp->icmp6_code = 0; /* code field is always 0 */ 12657cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson nip->ni_qtype = htons(NI_QTYPE_FQDN); 12667cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson nip->ni_flags = htons(0); 12677cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 12687cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson memcpy(nip->icmp6_ni_nonce, nonce, 12697cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(nip->icmp6_ni_nonce)); 12707cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson *(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq); 12717cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 12727cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cc = ICMP6_NIQLEN; 12737cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson datalen = 0; 12747cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else if (options & F_NODEADDR) { 12757cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson icp->icmp6_type = ICMP6_NI_QUERY; 12767cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson icp->icmp6_code = ICMP6_NI_SUBJ_IPV6; 12777cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson nip->ni_qtype = htons(NI_QTYPE_NODEADDR); 12787cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson nip->ni_flags = naflags; 12797cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 12807cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson memcpy(nip->icmp6_ni_nonce, nonce, 12817cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(nip->icmp6_ni_nonce)); 12827cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson *(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq); 12837cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 12847cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson memcpy(&outpack[ICMP6_NIQLEN], &dst.sin6_addr, 12857cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(dst.sin6_addr)); 12867cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cc = ICMP6_NIQLEN + sizeof(dst.sin6_addr); 12877cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson datalen = 0; 12887cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else if (options & F_SUPTYPES) { 12897cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson icp->icmp6_type = ICMP6_NI_QUERY; 12907cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson icp->icmp6_code = ICMP6_NI_SUBJ_FQDN; /*empty*/ 12917cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson nip->ni_qtype = htons(NI_QTYPE_SUPTYPES); 12927cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* we support compressed bitmap */ 12937cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson nip->ni_flags = NI_SUPTYPE_FLAG_COMPRESS; 12947cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 12957cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson memcpy(nip->icmp6_ni_nonce, nonce, 12967cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(nip->icmp6_ni_nonce)); 12977cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson *(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq); 12987cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cc = ICMP6_NIQLEN; 12997cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson datalen = 0; 13007cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else { 13017cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson icp->icmp6_type = ICMP6_ECHO_REQUEST; 13027cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson icp->icmp6_code = 0; 13037cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson icp->icmp6_id = htons(ident); 13047cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson icp->icmp6_seq = ntohs(seq); 13057cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (timing) { 13067cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct timeval tv; 13077cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct tv32 *tv32; 13087cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)gettimeofday(&tv, NULL); 13097cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson tv32 = (struct tv32 *)&outpack[ICMP6ECHOLEN]; 13107cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson tv32->tv32_sec = htonl(tv.tv_sec); 13117cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson tv32->tv32_usec = htonl(tv.tv_usec); 13127cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 13137cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cc = ICMP6ECHOLEN + datalen; 13147cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 13157cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 13167cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef DIAGNOSTIC 13177cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (pingerlen() != cc) 13187cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "internal error; length mismatch"); 13197cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 13207cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 13217cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson smsghdr.msg_name = (caddr_t)&dst; 13227cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson smsghdr.msg_namelen = sizeof(dst); 13237cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson memset(&iov, 0, sizeof(iov)); 13247cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson iov[0].iov_base = (caddr_t)outpack; 13257cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson iov[0].iov_len = cc; 13267cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson smsghdr.msg_iov = iov; 13277cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson smsghdr.msg_iovlen = 1; 13287cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 13297cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson i = sendmsg(s, &smsghdr, 0); 13307cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 13317cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (i < 0 || i != cc) { 13327cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (i < 0) 13337cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson warn("sendmsg"); 13347cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("ping6: wrote %s %d chars, ret=%d\n", 13357cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson hostname, cc, i); 13367cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 13377cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (!(options & F_QUIET) && options & F_FLOOD) 13387cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)write(STDOUT_FILENO, &DOT, 1); 13397cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 13407cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return(0); 13417cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 13427cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 13437cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonint 13447cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonmyechoreply(const struct icmp6_hdr *icp) 13457cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 13467cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (ntohs(icp->icmp6_id) == ident) 13477cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return 1; 13487cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson else 13497cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return 0; 13507cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 13517cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 13527cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonint 13537cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonmynireply(const struct icmp6_nodeinfo *nip) 13547cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 13557cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (memcmp(nip->icmp6_ni_nonce + sizeof(u_int16_t), 13567cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson nonce + sizeof(u_int16_t), 13577cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(nonce) - sizeof(u_int16_t)) == 0) 13587cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return 1; 13597cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson else 13607cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return 0; 13617cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 13627cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 13637cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonchar * 13647cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersondnsdecode(const u_char **sp, const u_char *ep, const u_char *base, char *buf, 13657cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson size_t bufsiz) 13667cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 13677cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int i; 13687cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson const u_char *cp; 13697cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson char cresult[MAXDNAME + 1]; 13707cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson const u_char *comp; 13717cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int l; 13727cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 13737cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson i = 0; /* XXXGCC -Wuninitialized [sun2] */ 13747cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 13757cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cp = *sp; 13767cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson *buf = '\0'; 13777cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 13787cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (cp >= ep) 13797cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return NULL; 13807cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson while (cp < ep) { 13817cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson i = *cp; 13827cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (i == 0 || cp != *sp) { 13837cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (strlcat((char *)buf, ".", bufsiz) >= bufsiz) 13847cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return NULL; /*result overrun*/ 13857cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 13867cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (i == 0) 13877cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 13887cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cp++; 13897cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 13907cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((i & 0xc0) == 0xc0 && cp - base > (i & 0x3f)) { 13917cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* DNS compression */ 13927cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (!base) 13937cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return NULL; 13947cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 13957cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson comp = base + (i & 0x3f); 13967cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (dnsdecode(&comp, cp, base, cresult, 13977cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(cresult)) == NULL) 13987cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return NULL; 13997cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (strlcat(buf, cresult, bufsiz) >= bufsiz) 14007cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return NULL; /*result overrun*/ 14017cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 14027cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else if ((i & 0x3f) == i) { 14037cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (i > ep - cp) 14047cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return NULL; /*source overrun*/ 14057cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson while (i-- > 0 && cp < ep) { 14067cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson l = snprintf(cresult, sizeof(cresult), 14077cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson isprint(*cp) ? "%c" : "\\%03o", *cp & 0xff); 14087cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (l >= (int)sizeof(cresult) || l < 0) 14097cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return NULL; 14107cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (strlcat(buf, cresult, bufsiz) >= bufsiz) 14117cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return NULL; /*result overrun*/ 14127cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cp++; 14137cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 14147cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else 14157cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return NULL; /*invalid label*/ 14167cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 14177cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (i != 0) 14187cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return NULL; /*not terminated*/ 14197cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cp++; 14207cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson *sp = cp; 14217cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return buf; 14227cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 14237cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 14247cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/* 14257cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * pr_pack -- 14267cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * Print out the packet, if it came from us. This logic is necessary 14277cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * because ALL readers of the ICMP socket get a copy of ALL ICMP packets 14287cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * which arrive ('tis only fair). This permits multiple copies of this 14297cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * program to be run without having intermingled output (or statistics!). 14307cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 14317cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid 14327cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonpr_pack(u_char *buf, int cc, struct msghdr *mhdr) 14337cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 14347cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define safeputc(c) printf((isprint((c)) ? "%c" : "\\%03o"), c) 14357cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct icmp6_hdr *icp; 14367cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct icmp6_nodeinfo *ni; 14377cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int i; 14387cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int hoplim; 14397cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct sockaddr *from; 14407cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int fromlen; 14417cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson u_char *cp = NULL, *dp, *end = buf + cc; 14427cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct in6_pktinfo *pktinfo = NULL; 14437cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct timeval tv, tp; 14447cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct tv32 *tpp; 14457cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson double triptime = 0; 14467cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int dupflag; 14477cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson size_t off; 14487cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int oldfqdn; 14497cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson u_int16_t seq; 14507cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson char dnsname[MAXDNAME + 1]; 14517cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 14527cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)gettimeofday(&tv, NULL); 14537cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 14547cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (!mhdr || !mhdr->msg_name || 14557cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson mhdr->msg_namelen != sizeof(struct sockaddr_in6) || 14567cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ((struct sockaddr *)mhdr->msg_name)->sa_family != AF_INET6) { 14577cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (options & F_VERBOSE) 14587cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson warnx("invalid peername"); 14597cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return; 14607cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 14617cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson from = (struct sockaddr *)mhdr->msg_name; 14627cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson fromlen = mhdr->msg_namelen; 14637cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (cc < (int)sizeof(struct icmp6_hdr)) { 14647cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (options & F_VERBOSE) 14657cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson warnx("packet too short (%d bytes) from %s", cc, 14667cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson pr_addr(from, fromlen)); 14677cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return; 14687cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 14697cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson icp = (struct icmp6_hdr *)buf; 14707cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ni = (struct icmp6_nodeinfo *)buf; 14717cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson off = 0; 14727cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 14737cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((hoplim = get_hoplim(mhdr)) == -1) { 14747cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson warnx("failed to get receiving hop limit"); 14757cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return; 14767cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 14777cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((pktinfo = get_rcvpktinfo(mhdr)) == NULL) { 14787cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson warnx("failed to get receiving packet information"); 14797cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return; 14807cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 14817cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 14827cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (icp->icmp6_type == ICMP6_ECHO_REPLY && myechoreply(icp)) { 14837cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson seq = ntohs(icp->icmp6_seq); 14847cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ++nreceived; 14857cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (timing) { 14867cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson tpp = (struct tv32 *)(icp + 1); 14877cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson tp.tv_sec = ntohl(tpp->tv32_sec); 14887cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson tp.tv_usec = ntohl(tpp->tv32_usec); 14897cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson tvsub(&tv, &tp); 14907cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson triptime = ((double)tv.tv_sec) * 1000.0 + 14917cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ((double)tv.tv_usec) / 1000.0; 14927cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson tsum += triptime; 14937cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson tsumsq += triptime * triptime; 14947cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (triptime < tmin) 14957cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson tmin = triptime; 14967cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (triptime > tmax) 14977cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson tmax = triptime; 14987cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 14997cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 15007cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (TST(seq % mx_dup_ck)) { 15017cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ++nrepeats; 15027cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson --nreceived; 15037cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson dupflag = 1; 15047cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else { 15057cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson SET(seq % mx_dup_ck); 15067cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson dupflag = 0; 15077cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 15087cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 15097cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (options & F_QUIET) 15107cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return; 15117cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 15127cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (options & F_FLOOD) 15137cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)write(STDOUT_FILENO, &BSPACE, 1); 15147cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson else { 15157cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("%d bytes from %s, icmp_seq=%u", cc, 15167cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson pr_addr(from, fromlen), seq); 15177cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf(" hlim=%d", hoplim); 15187cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((options & F_VERBOSE) != 0) { 15197cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct sockaddr_in6 dstsa; 15207cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 15217cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson memset(&dstsa, 0, sizeof(dstsa)); 15227cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson dstsa.sin6_family = AF_INET6; 15237cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef SIN6_LEN 15247cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson dstsa.sin6_len = sizeof(dstsa); 15257cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 15267cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson dstsa.sin6_scope_id = pktinfo->ipi6_ifindex; 15277cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson dstsa.sin6_addr = pktinfo->ipi6_addr; 15287cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf(" dst=%s", 15297cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson pr_addr((struct sockaddr *)&dstsa, 15307cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(dstsa))); 15317cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 15327cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (timing) 15337cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf(" time=%.3f ms", triptime); 15347cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (dupflag) 15357cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("(DUP!)"); 15367cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* check the data */ 15377cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cp = buf + off + ICMP6ECHOLEN + ICMP6ECHOTMLEN; 15387cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson dp = outpack + ICMP6ECHOLEN + ICMP6ECHOTMLEN; 15397cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson for (i = 8; cp < end; ++i, ++cp, ++dp) { 15407cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (*cp != *dp) { 15417cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("\nwrong data byte #%d should be 0x%x but was 0x%x", i, *dp, *cp); 15427cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 15437cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 15447cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 15457cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 15467cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else if (icp->icmp6_type == ICMP6_NI_REPLY && mynireply(ni)) { 15477cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson seq = ntohs(*(u_int16_t *)ni->icmp6_ni_nonce); 15487cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ++nreceived; 15497cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (TST(seq % mx_dup_ck)) { 15507cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ++nrepeats; 15517cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson --nreceived; 15527cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson dupflag = 1; 15537cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else { 15547cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson SET(seq % mx_dup_ck); 15557cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson dupflag = 0; 15567cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 15577cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 15587cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (options & F_QUIET) 15597cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return; 15607cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 15617cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("%d bytes from %s: ", cc, pr_addr(from, fromlen)); 15627cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 15637cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson switch (ntohs(ni->ni_code)) { 15647cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_NI_SUCCESS: 15657cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 15667cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_NI_REFUSED: 15677cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("refused, type 0x%x", ntohs(ni->ni_type)); 15687cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson goto fqdnend; 15697cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_NI_UNKNOWN: 15707cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("unknown, type 0x%x", ntohs(ni->ni_type)); 15717cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson goto fqdnend; 15727cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson default: 15737cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("unknown code 0x%x, type 0x%x", 15747cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ntohs(ni->ni_code), ntohs(ni->ni_type)); 15757cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson goto fqdnend; 15767cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 15777cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 15787cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson switch (ntohs(ni->ni_qtype)) { 15797cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case NI_QTYPE_NOOP: 15807cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("NodeInfo NOOP"); 15817cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 15827cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case NI_QTYPE_SUPTYPES: 15837cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson pr_suptypes(ni, end - (u_char *)ni); 15847cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 15857cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case NI_QTYPE_NODEADDR: 15867cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson pr_nodeaddr(ni, end - (u_char *)ni); 15877cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 15887cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case NI_QTYPE_FQDN: 15897cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson default: /* XXX: for backward compatibility */ 15907cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cp = (u_char *)ni + ICMP6_NIRLEN; 15917cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (buf[off + ICMP6_NIRLEN] == 15927cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cc - off - ICMP6_NIRLEN - 1) 15937cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson oldfqdn = 1; 15947cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson else 15957cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson oldfqdn = 0; 15967cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (oldfqdn) { 15977cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cp++; /* skip length */ 15987cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson while (cp < end) { 15997cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson safeputc(*cp & 0xff); 16007cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cp++; 16017cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 16027cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else { 16037cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson i = 0; 16047cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson while (cp < end) { 16057cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (dnsdecode((const u_char **)&cp, end, 16067cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (const u_char *)(ni + 1), dnsname, 16077cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(dnsname)) == NULL) { 16087cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("???"); 16097cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 16107cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 16117cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* 16127cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * name-lookup special handling for 16137cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * truncated name 16147cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 16157cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (cp + 1 <= end && !*cp && 16167cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson strlen(dnsname) > 0) { 16177cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson dnsname[strlen(dnsname) - 1] = '\0'; 16187cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cp++; 16197cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 16207cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("%s%s", i > 0 ? "," : "", 16217cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson dnsname); 16227cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 16237cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 16247cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (options & F_VERBOSE) { 16257cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int32_t ttl; 16267cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int comma = 0; 16277cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 16287cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf(" ("); /*)*/ 16297cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 16307cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson switch (ni->ni_code) { 16317cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_NI_REFUSED: 16327cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("refused"); 16337cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson comma++; 16347cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 16357cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_NI_UNKNOWN: 16367cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("unknown qtype"); 16377cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson comma++; 16387cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 16397cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 16407cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 16417cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((end - (u_char *)ni) < ICMP6_NIRLEN) { 16427cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* case of refusion, unknown */ 16437cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /*(*/ 16447cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson putchar(')'); 16457cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson goto fqdnend; 16467cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 16477cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ttl = (int32_t)ntohl(*(u_long *)&buf[off+ICMP6ECHOLEN+8]); 16487cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (comma) 16497cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf(","); 16507cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (!(ni->ni_flags & NI_FQDN_FLAG_VALIDTTL)) { 16517cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("TTL=%d:meaningless", 16527cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (int)ttl); 16537cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else { 16547cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (ttl < 0) { 16557cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("TTL=%d:invalid", 16567cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ttl); 16577cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else 16587cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("TTL=%d", ttl); 16597cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 16607cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson comma++; 16617cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 16627cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (oldfqdn) { 16637cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (comma) 16647cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf(","); 16657cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("03 draft"); 16667cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson comma++; 16677cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else { 16687cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cp = (u_char *)ni + ICMP6_NIRLEN; 16697cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (cp == end) { 16707cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (comma) 16717cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf(","); 16727cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("no name"); 16737cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson comma++; 16747cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 16757cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 16767cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 16777cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (buf[off + ICMP6_NIRLEN] != 16787cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cc - off - ICMP6_NIRLEN - 1 && oldfqdn) { 16797cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (comma) 16807cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf(","); 16817cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("invalid namelen:%d/%lu", 16827cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson buf[off + ICMP6_NIRLEN], 16837cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (u_long)cc - off - ICMP6_NIRLEN - 1); 16847cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson comma++; 16857cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 16867cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /*(*/ 16877cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson putchar(')'); 16887cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 16897cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson fqdnend: 16907cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ; 16917cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 16927cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else { 16937cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* We've got something other than an ECHOREPLY */ 16947cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (!(options & F_VERBOSE)) 16957cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return; 16967cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("%d bytes from %s: ", cc, pr_addr(from, fromlen)); 16977cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson pr_icmph(icp, end); 16987cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 16997cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 17007cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (!(options & F_FLOOD)) { 17017cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)putchar('\n'); 17027cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (options & F_VERBOSE) 17037cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson pr_exthdrs(mhdr); 17047cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)fflush(stdout); 17057cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 17067cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#undef safeputc 17077cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 17087cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 17097cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid 17107cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonpr_exthdrs(struct msghdr *mhdr) 17117cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 17127cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct cmsghdr *cm; 17137cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 17147cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; 17157cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { 17167cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (cm->cmsg_level != IPPROTO_IPV6) 17177cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson continue; 17187cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 17197cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson switch (cm->cmsg_type) { 17202f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#ifdef ANDROID_INCLUDE_RTHDR_SUPPORT 17217cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case IPV6_HOPOPTS: 17227cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf(" HbH Options: "); 17237cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson pr_ip6opt(CMSG_DATA(cm)); 17247cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 17257cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case IPV6_DSTOPTS: 17267cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPV6_RTHDRDSTOPTS 17277cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case IPV6_RTHDRDSTOPTS: 17287cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 17297cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf(" Dst Options: "); 17307cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson pr_ip6opt(CMSG_DATA(cm)); 17317cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 17327cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case IPV6_RTHDR: 17337cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf(" Routing: "); 17347cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson pr_rthdr(CMSG_DATA(cm)); 17357cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 17362f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#endif 17377cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 17387cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 17397cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 17407cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 17412f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#ifdef ANDROID_INCLUDE_RTHDR_SUPPORT 17427cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid 17437cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonpr_ip6opt(void *extbuf) 17447cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 17457cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct ip6_hbh *ext; 17467cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int currentlen; 17477cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson u_int8_t type; 17487cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson size_t extlen; 17497cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson socklen_t len; 17507cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson void *databuf; 17517cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson size_t offset; 17527cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson u_int16_t value2; 17537cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson u_int32_t value4; 17547cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 17557cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ext = (struct ip6_hbh *)extbuf; 17567cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson extlen = (ext->ip6h_len + 1) * 8; 17577cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("nxt %u, len %u (%lu bytes)\n", ext->ip6h_nxt, 17587cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (unsigned int)ext->ip6h_len, (unsigned long)extlen); 17597cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 17607cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson currentlen = 0; 17617cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson while (1) { 17627cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson currentlen = inet6_opt_next(extbuf, extlen, currentlen, 17637cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson &type, &len, &databuf); 17647cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (currentlen == -1) 17657cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 17667cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson switch (type) { 17677cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* 17687cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * Note that inet6_opt_next automatically skips any padding 17697cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * optins. 17707cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 17717cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case IP6OPT_JUMBO: 17727cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson offset = 0; 17737cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson offset = inet6_opt_get_val(databuf, offset, 17747cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson &value4, sizeof(value4)); 17757cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf(" Jumbo Payload Opt: Length %u\n", 17767cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (u_int32_t)ntohl(value4)); 17777cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 17787cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case IP6OPT_ROUTER_ALERT: 17797cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson offset = 0; 17807cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson offset = inet6_opt_get_val(databuf, offset, 17817cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson &value2, sizeof(value2)); 17827cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf(" Router Alert Opt: Type %u\n", 17837cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ntohs(value2)); 17847cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 17857cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson default: 17867cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf(" Received Opt %u len %lu\n", 17877cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson type, (unsigned long)len); 17887cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 17897cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 17907cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 17917cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return; 17927cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 17932f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#endif 17947cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 17952f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#ifdef ANDROID_INCLUDE_RTHDR_SUPPORT 17967cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid 17977cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonpr_rthdr(void *extbuf) 17987cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 17997cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct in6_addr *in6; 18007cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson char ntopbuf[INET6_ADDRSTRLEN]; 18017cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct ip6_rthdr *rh = (struct ip6_rthdr *)extbuf; 18027cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int i, segments; 18037cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 18047cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* print fixed part of the header */ 18057cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("nxt %u, len %u (%d bytes), type %u, ", rh->ip6r_nxt, 18067cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson rh->ip6r_len, (rh->ip6r_len + 1) << 3, rh->ip6r_type); 18077cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((segments = inet6_rth_segments(extbuf)) >= 0) 18087cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("%d segments, ", segments); 18097cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson else 18107cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("segments unknown, "); 18117cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("%d left\n", rh->ip6r_segleft); 18127cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 18137cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson for (i = 0; i < segments; i++) { 18147cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson in6 = inet6_rth_getaddr(extbuf, i); 18157cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (in6 == NULL) 18167cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf(" [%d]<NULL>\n", i); 18177cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson else { 18187cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (!inet_ntop(AF_INET6, in6, ntopbuf, 18197cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(ntopbuf))) 18207cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson strlcpy(ntopbuf, "?", sizeof(ntopbuf)); 18217cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf(" [%d]%s\n", i, ntopbuf); 18227cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 18237cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 18247cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 18257cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return; 18267cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 18277cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 18282f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#endif 18297cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 18307cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonint 18317cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonpr_bitrange(u_int32_t v, int soff, int ii) 18327cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 18337cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int off; 18347cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int i; 18357cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 18367cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson off = 0; 18377cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson while (off < 32) { 18387cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* shift till we have 0x01 */ 18397cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((v & 0x01) == 0) { 18407cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (ii > 1) 18417cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("-%u", soff + off - 1); 18427cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ii = 0; 18437cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson switch (v & 0x0f) { 18447cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 0x00: 18457cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson v >>= 4; 18467cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson off += 4; 18477cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson continue; 18487cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 0x08: 18497cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson v >>= 3; 18507cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson off += 3; 18517cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson continue; 18527cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case 0x04: case 0x0c: 18537cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson v >>= 2; 18547cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson off += 2; 18557cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson continue; 18567cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson default: 18577cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson v >>= 1; 18587cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson off += 1; 18597cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson continue; 18607cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 18617cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 18627cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 18637cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* we have 0x01 with us */ 18647cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson for (i = 0; i < 32 - off; i++) { 18657cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((v & (0x01 << i)) == 0) 18667cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 18677cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 18687cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (!ii) 18697cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf(" %u", soff + off); 18707cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ii += i; 18717cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson v >>= i; off += i; 18727cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 18737cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return ii; 18747cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 18757cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 18767cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid 18777cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonpr_suptypes(struct icmp6_nodeinfo *ni /* ni->qtype must be SUPTYPES */, 18787cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson size_t nilen) 18797cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 18807cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson size_t clen; 18817cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson u_int32_t v; 18827cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson const u_char *cp, *end; 18837cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson u_int16_t cur; 18847cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct cbit { 18857cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson u_int16_t words; /*32bit count*/ 18867cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson u_int16_t skip; 18877cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } cbit; 18887cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#define MAXQTYPES (1 << 16) 18897cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson size_t off; 18907cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int b; 18917cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 18927cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cp = (u_char *)(ni + 1); 18937cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson end = ((u_char *)ni) + nilen; 18947cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cur = 0; 18957cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson b = 0; 18967cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 18977cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("NodeInfo Supported Qtypes"); 18987cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (options & F_VERBOSE) { 18997cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (ni->ni_flags & NI_SUPTYPE_FLAG_COMPRESS) 19007cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf(", compressed bitmap"); 19017cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson else 19027cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf(", raw bitmap"); 19037cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 19047cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 19057cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson while (cp < end) { 19067cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson clen = (size_t)(end - cp); 19077cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((ni->ni_flags & NI_SUPTYPE_FLAG_COMPRESS) == 0) { 19087cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (clen == 0 || clen > MAXQTYPES / 8 || 19097cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson clen % sizeof(v)) { 19107cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("???"); 19117cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return; 19127cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 19137cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else { 19147cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (clen < sizeof(cbit) || clen % sizeof(v)) 19157cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return; 19167cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson memcpy(&cbit, cp, sizeof(cbit)); 19177cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (sizeof(cbit) + ntohs(cbit.words) * sizeof(v) > 19187cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson clen) 19197cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return; 19207cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cp += sizeof(cbit); 19217cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson clen = ntohs(cbit.words) * sizeof(v); 19227cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (cur + clen * 8 + (u_long)ntohs(cbit.skip) * 32 > 19237cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson MAXQTYPES) 19247cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return; 19257cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 19267cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 19277cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson for (off = 0; off < clen; off += sizeof(v)) { 19287cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson memcpy(&v, cp + off, sizeof(v)); 19297cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson v = (u_int32_t)ntohl(v); 19307cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson b = pr_bitrange(v, (int)(cur + off * 8), b); 19317cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 19327cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* flush the remaining bits */ 19337cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson b = pr_bitrange(0, (int)(cur + off * 8), b); 19347cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 19357cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cp += clen; 19367cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cur += clen * 8; 19377cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((ni->ni_flags & NI_SUPTYPE_FLAG_COMPRESS) != 0) 19387cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cur += ntohs(cbit.skip) * 32; 19397cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 19407cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 19417cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 19427cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid 19437cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonpr_nodeaddr(struct icmp6_nodeinfo *ni, /* ni->qtype must be NODEADDR */ 19447cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int nilen) 19457cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 19467cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson u_char *cp = (u_char *)(ni + 1); 19477cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson char ntop_buf[INET6_ADDRSTRLEN]; 19487cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int withttl = 0; 19497cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 19507cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson nilen -= sizeof(struct icmp6_nodeinfo); 19517cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 19527cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (options & F_VERBOSE) { 19537cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson switch (ni->ni_code) { 19547cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_NI_REFUSED: 19557cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("refused"); 19567cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 19577cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_NI_UNKNOWN: 19587cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("unknown qtype"); 19597cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 19607cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 19617cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (ni->ni_flags & NI_NODEADDR_FLAG_TRUNCATE) 19627cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf(" truncated"); 19637cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 19647cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson putchar('\n'); 19657cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (nilen <= 0) 19667cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf(" no address\n"); 19677cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 19687cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* 19697cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * In icmp-name-lookups 05 and later, TTL of each returned address 19707cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * is contained in the resposne. We try to detect the version 19717cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * by the length of the data, but note that the detection algorithm 19727cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * is incomplete. We assume the latest draft by default. 19737cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 19747cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (nilen % (sizeof(u_int32_t) + sizeof(struct in6_addr)) == 0) 19757cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson withttl = 1; 19767cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson while (nilen > 0) { 19777cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson u_int32_t ttl = 0; 19787cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 19797cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (withttl) { 19807cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* XXX: alignment? */ 19817cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ttl = (u_int32_t)ntohl(*(u_int32_t *)cp); 19827cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cp += sizeof(u_int32_t); 19837cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson nilen -= sizeof(u_int32_t); 19847cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 19857cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 19867cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (inet_ntop(AF_INET6, cp, ntop_buf, sizeof(ntop_buf)) == 19877cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson NULL) 19887cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson strlcpy(ntop_buf, "?", sizeof(ntop_buf)); 19897cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf(" %s", ntop_buf); 19907cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (withttl) { 19917cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (ttl == 0xffffffff) { 19927cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* 19937cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * XXX: can this convention be applied to all 19947cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * type of TTL (i.e. non-ND TTL)? 19957cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 19967cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("(TTL=infty)"); 19977cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 19987cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson else 19997cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("(TTL=%u)", ttl); 20007cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 20017cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson putchar('\n'); 20027cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 20037cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson nilen -= sizeof(struct in6_addr); 20047cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cp += sizeof(struct in6_addr); 20057cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 20067cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 20077cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 20087cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonint 20097cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonget_hoplim(struct msghdr *mhdr) 20107cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 20117cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct cmsghdr *cm; 20127cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 20137cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; 20147cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { 20157cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (cm->cmsg_len == 0) 20167cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return(-1); 20177cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 20187cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (cm->cmsg_level == IPPROTO_IPV6 && 20197cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cm->cmsg_type == IPV6_HOPLIMIT && 20207cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cm->cmsg_len == CMSG_LEN(sizeof(int))) 20217cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return(*(int *)CMSG_DATA(cm)); 20227cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 20237cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 20247cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return(-1); 20257cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 20267cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 20277cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonstruct in6_pktinfo * 20287cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonget_rcvpktinfo(struct msghdr *mhdr) 20297cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 20307cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct cmsghdr *cm; 20317cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 20327cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; 20337cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { 20347cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (cm->cmsg_len == 0) 20357cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return(NULL); 20367cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 20377cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (cm->cmsg_level == IPPROTO_IPV6 && 20387cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cm->cmsg_type == IPV6_PKTINFO && 20397cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cm->cmsg_len == CMSG_LEN(sizeof(struct in6_pktinfo))) 20407cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return((struct in6_pktinfo *)CMSG_DATA(cm)); 20417cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 20427cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 20437cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return(NULL); 20447cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 20457cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 20467cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonint 20477cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonget_pathmtu(struct msghdr *mhdr) 20487cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 20497cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPV6_RECVPATHMTU 20507cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct cmsghdr *cm; 20517cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct ip6_mtuinfo *mtuctl = NULL; 20527cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 20537cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; 20547cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { 20557cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (cm->cmsg_len == 0) 20567cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return(0); 20577cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 20587cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (cm->cmsg_level == IPPROTO_IPV6 && 20597cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cm->cmsg_type == IPV6_PATHMTU && 20607cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cm->cmsg_len == CMSG_LEN(sizeof(struct ip6_mtuinfo))) { 20617cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson mtuctl = (struct ip6_mtuinfo *)CMSG_DATA(cm); 20627cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 20637cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* 20647cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * If the notified destination is different from 20657cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * the one we are pinging, just ignore the info. 20667cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * We check the scope ID only when both notified value 20677cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * and our own value have non-0 values, because we may 20687cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * have used the default scope zone ID for sending, 20697cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * in which case the scope ID value is 0. 20707cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 20717cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (!IN6_ARE_ADDR_EQUAL(&mtuctl->ip6m_addr.sin6_addr, 20727cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson &dst.sin6_addr) || 20737cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (mtuctl->ip6m_addr.sin6_scope_id && 20747cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson dst.sin6_scope_id && 20757cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson mtuctl->ip6m_addr.sin6_scope_id != 20767cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson dst.sin6_scope_id)) { 20777cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((options & F_VERBOSE) != 0) { 20787cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("path MTU for %s is notified. " 20797cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson "(ignored)\n", 20807cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson pr_addr((struct sockaddr *)&mtuctl->ip6m_addr, 20817cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(mtuctl->ip6m_addr))); 20827cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 20837cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return(0); 20847cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 20857cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 20867cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* 20877cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * Ignore an invalid MTU. XXX: can we just believe 20887cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * the kernel check? 20897cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 20907cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (mtuctl->ip6m_mtu < IPV6_MMTU) 20917cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return(0); 20927cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 20937cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* notification for our destination. return the MTU. */ 20947cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return((int)mtuctl->ip6m_mtu); 20957cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 20967cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 20977cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 20987cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return(0); 20997cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 21007cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 21017cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/* 21027cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * tvsub -- 21037cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * Subtract 2 timeval structs: out = out - in. Out is assumed to 21047cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * be >= in. 21057cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 21067cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid 21077cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersontvsub(struct timeval *out, struct timeval *in) 21087cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 21097cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((out->tv_usec -= in->tv_usec) < 0) { 21107cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson --out->tv_sec; 21117cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson out->tv_usec += 1000000; 21127cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 21137cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson out->tv_sec -= in->tv_sec; 21147cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 21157cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 21167cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/* 21177cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * onint -- 21187cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * SIGINT handler. 21197cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 21207cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/* ARGSUSED */ 21217cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid 21227cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersononint(int notused) 21237cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 21247cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson summary(); 21257cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 21267cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)signal(SIGINT, SIG_DFL); 21277cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)kill(getpid(), SIGINT); 21287cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 21297cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* NOTREACHED */ 21307cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson exit(1); 21317cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 21327cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 21337cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/* 21347cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * summary -- 21357cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * Print out statistics. 21367cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 21377cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid 21387cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonsummary(void) 21397cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 21407cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 21417cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("\n--- %s ping6 statistics ---\n", hostname); 21427cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("%ld packets transmitted, ", ntransmitted); 21437cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("%ld packets received, ", nreceived); 21447cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (nrepeats) 21457cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("+%ld duplicates, ", nrepeats); 21467cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (ntransmitted) { 21477cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (nreceived > ntransmitted) 21487cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("-- somebody's duplicating packets!"); 21497cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson else 21507cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("%.1f%% packet loss", 21517cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ((((double)ntransmitted - nreceived) * 100.0) / 21527cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ntransmitted)); 21537cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 21547cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)putchar('\n'); 21557cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (nreceived && timing) { 21567cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* Only display average to microseconds */ 21577cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson double num = nreceived + nrepeats; 21587cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson double dev, avg; 21597cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (num > 1) { 21607cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson avg = tsum / num; 21617cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson dev = sqrt((tsumsq - num * avg * avg) / (num - 1)); 21627cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else { 21637cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson avg = tsum; 21647cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson dev = 0.0; 21657cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 21667cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf( 21677cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson "round-trip min/avg/max/std-dev = %.3f/%.3f/%.3f/%.3f ms\n", 21687cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson tmin, avg, tmax, dev); 21697cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)fflush(stdout); 21707cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 21717cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)fflush(stdout); 21727cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 21737cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 21747cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/*subject type*/ 21757cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonstatic const char *niqcode[] = { 21767cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson "IPv6 address", 21777cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson "DNS label", /*or empty*/ 21787cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson "IPv4 address", 21797cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson}; 21807cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 21817cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/*result code*/ 21827cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonstatic const char *nircode[] = { 21837cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson "Success", "Refused", "Unknown", 21847cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson}; 21857cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 21867cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 21877cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/* 21887cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * pr_icmph -- 21897cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * Print a descriptive string about an ICMP header. 21907cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 21917cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid 21927cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonpr_icmph(struct icmp6_hdr *icp, u_char *end) 21937cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 21947cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson char ntop_buf[INET6_ADDRSTRLEN]; 21957cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct nd_redirect *red; 21967cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct icmp6_nodeinfo *ni; 21977cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson char dnsname[MAXDNAME + 1]; 21987cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson const u_char *cp; 21997cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson size_t l; 22007cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 22017cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson switch (icp->icmp6_type) { 22027cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_DST_UNREACH: 22037cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson switch (icp->icmp6_code) { 22047cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_DST_UNREACH_NOROUTE: 22057cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("No Route to Destination\n"); 22067cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 22077cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_DST_UNREACH_ADMIN: 22087cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Destination Administratively " 22097cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson "Unreachable\n"); 22107cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 22117cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_DST_UNREACH_BEYONDSCOPE: 22127cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Destination Unreachable Beyond Scope\n"); 22137cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 22147cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_DST_UNREACH_ADDR: 22157cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Destination Host Unreachable\n"); 22167cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 22177cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_DST_UNREACH_NOPORT: 22187cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Destination Port Unreachable\n"); 22197cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 22207cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson default: 22217cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Destination Unreachable, Bad Code: %d\n", 22227cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson icp->icmp6_code); 22237cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 22247cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 22257cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* Print returned IP header information */ 22267cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson pr_retip((struct ip6_hdr *)(icp + 1), end); 22277cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 22287cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_PACKET_TOO_BIG: 22297cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Packet too big mtu = %d\n", 22307cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (int)ntohl(icp->icmp6_mtu)); 22317cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson pr_retip((struct ip6_hdr *)(icp + 1), end); 22327cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 22337cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_TIME_EXCEEDED: 22347cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson switch (icp->icmp6_code) { 22357cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_TIME_EXCEED_TRANSIT: 22367cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Time to live exceeded\n"); 22377cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 22387cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_TIME_EXCEED_REASSEMBLY: 22397cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Frag reassembly time exceeded\n"); 22407cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 22417cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson default: 22427cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Time exceeded, Bad Code: %d\n", 22437cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson icp->icmp6_code); 22447cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 22457cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 22467cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson pr_retip((struct ip6_hdr *)(icp + 1), end); 22477cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 22487cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_PARAM_PROB: 22497cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Parameter problem: "); 22507cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson switch (icp->icmp6_code) { 22517cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_PARAMPROB_HEADER: 22527cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Erroneous Header "); 22537cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 22547cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_PARAMPROB_NEXTHEADER: 22557cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Unknown Nextheader "); 22567cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 22577cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_PARAMPROB_OPTION: 22587cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Unrecognized Option "); 22597cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 22607cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson default: 22617cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Bad code(%d) ", icp->icmp6_code); 22627cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 22637cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 22647cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("pointer = 0x%02x\n", 22657cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (u_int32_t)ntohl(icp->icmp6_pptr)); 22667cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson pr_retip((struct ip6_hdr *)(icp + 1), end); 22677cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 22687cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_ECHO_REQUEST: 22697cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Echo Request"); 22707cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* XXX ID + Seq + Data */ 22717cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 22727cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_ECHO_REPLY: 22737cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Echo Reply"); 22747cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* XXX ID + Seq + Data */ 22757cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 22767cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_MEMBERSHIP_QUERY: 22777cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Listener Query"); 22787cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 22797cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_MEMBERSHIP_REPORT: 22807cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Listener Report"); 22817cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 22827cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_MEMBERSHIP_REDUCTION: 22837cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Listener Done"); 22847cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 22857cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ND_ROUTER_SOLICIT: 22867cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Router Solicitation"); 22877cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 22887cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ND_ROUTER_ADVERT: 22897cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Router Advertisement"); 22907cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 22917cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ND_NEIGHBOR_SOLICIT: 22927cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Neighbor Solicitation"); 22937cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 22947cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ND_NEIGHBOR_ADVERT: 22957cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Neighbor Advertisement"); 22967cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 22977cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ND_REDIRECT: 22987cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson red = (struct nd_redirect *)icp; 22997cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Redirect\n"); 23007cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (!inet_ntop(AF_INET6, &red->nd_rd_dst, ntop_buf, 23017cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(ntop_buf))) 23027cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson strlcpy(ntop_buf, "?", sizeof(ntop_buf)); 23037cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Destination: %s", ntop_buf); 23047cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (!inet_ntop(AF_INET6, &red->nd_rd_target, ntop_buf, 23057cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(ntop_buf))) 23067cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson strlcpy(ntop_buf, "?", sizeof(ntop_buf)); 23077cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf(" New Target: %s", ntop_buf); 23087cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 23097cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_NI_QUERY: 23107cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Node Information Query"); 23117cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* XXX ID + Seq + Data */ 23127cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ni = (struct icmp6_nodeinfo *)icp; 23137cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson l = end - (u_char *)(ni + 1); 23147cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf(", "); 23157cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson switch (ntohs(ni->ni_qtype)) { 23167cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case NI_QTYPE_NOOP: 23177cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("NOOP"); 23187cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 23197cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case NI_QTYPE_SUPTYPES: 23207cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Supported qtypes"); 23217cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 23227cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case NI_QTYPE_FQDN: 23237cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("DNS name"); 23247cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 23257cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case NI_QTYPE_NODEADDR: 23267cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("nodeaddr"); 23277cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 23287cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case NI_QTYPE_IPV4ADDR: 23297cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("IPv4 nodeaddr"); 23307cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 23317cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson default: 23327cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("unknown qtype"); 23337cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 23347cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 23357cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (options & F_VERBOSE) { 23367cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson switch (ni->ni_code) { 23377cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_NI_SUBJ_IPV6: 23387cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (l == sizeof(struct in6_addr) && 23397cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson inet_ntop(AF_INET6, ni + 1, ntop_buf, 23407cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(ntop_buf)) != NULL) { 23417cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf(", subject=%s(%s)", 23427cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson niqcode[ni->ni_code], ntop_buf); 23437cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else { 23447cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#if 1 23457cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* backward compat to -W */ 23467cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf(", oldfqdn"); 23477cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#else 23487cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf(", invalid"); 23497cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 23507cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 23517cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 23527cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_NI_SUBJ_FQDN: 23537cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (end == (u_char *)(ni + 1)) { 23547cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf(", no subject"); 23557cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 23567cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 23577cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf(", subject=%s", niqcode[ni->ni_code]); 23587cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cp = (const u_char *)(ni + 1); 23597cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (dnsdecode(&cp, end, NULL, dnsname, 23607cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(dnsname)) != NULL) 23617cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("(%s)", dnsname); 23627cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson else 23637cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("(invalid)"); 23647cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 23657cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_NI_SUBJ_IPV4: 23667cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (l == sizeof(struct in_addr) && 23677cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson inet_ntop(AF_INET, ni + 1, ntop_buf, 23687cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson sizeof(ntop_buf)) != NULL) { 23697cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf(", subject=%s(%s)", 23707cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson niqcode[ni->ni_code], ntop_buf); 23717cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } else 23727cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf(", invalid"); 23737cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 23747cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson default: 23757cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf(", invalid"); 23767cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 23777cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 23787cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 23797cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 23807cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case ICMP6_NI_REPLY: 23817cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Node Information Reply"); 23827cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* XXX ID + Seq + Data */ 23837cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ni = (struct icmp6_nodeinfo *)icp; 23847cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf(", "); 23857cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson switch (ntohs(ni->ni_qtype)) { 23867cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case NI_QTYPE_NOOP: 23877cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("NOOP"); 23887cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 23897cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case NI_QTYPE_SUPTYPES: 23907cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Supported qtypes"); 23917cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 23927cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case NI_QTYPE_FQDN: 23937cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("DNS name"); 23947cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 23957cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case NI_QTYPE_NODEADDR: 23967cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("nodeaddr"); 23977cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 23987cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case NI_QTYPE_IPV4ADDR: 23997cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("IPv4 nodeaddr"); 24007cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 24017cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson default: 24027cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("unknown qtype"); 24037cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 24047cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 24057cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (options & F_VERBOSE) { 24067cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (ni->ni_code >= sizeof(nircode) / sizeof(nircode[0])) 24077cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf(", invalid"); 24087cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson else 24097cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf(", %s", nircode[ni->ni_code]); 24107cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 24117cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 24127cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson default: 24137cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("Bad ICMP type: %d", icp->icmp6_type); 24147cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 24157cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 24167cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 24177cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/* 24187cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * pr_iph -- 24197cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * Print an IP6 header. 24207cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 24217cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid 24227cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonpr_iph(struct ip6_hdr *ip6) 24237cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 24247cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson u_int32_t flow = ip6->ip6_flow & IPV6_FLOWLABEL_MASK; 24257cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson u_int8_t tc; 24267cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson char ntop_buf[INET6_ADDRSTRLEN]; 24277cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 24287cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson tc = *(&ip6->ip6_vfc + 1); /* XXX */ 24297cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson tc = (tc >> 4) & 0x0f; 24307cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson tc |= (ip6->ip6_vfc << 4); 24317cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 24327cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("Vr TC Flow Plen Nxt Hlim\n"); 24337cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf(" %1x %02x %05x %04x %02x %02x\n", 24347cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (ip6->ip6_vfc & IPV6_VERSION_MASK) >> 4, tc, (u_int32_t)ntohl(flow), 24357cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ntohs(ip6->ip6_plen), ip6->ip6_nxt, ip6->ip6_hlim); 24367cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (!inet_ntop(AF_INET6, &ip6->ip6_src, ntop_buf, sizeof(ntop_buf))) 24377cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson strlcpy(ntop_buf, "?", sizeof(ntop_buf)); 24387cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("%s->", ntop_buf); 24397cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (!inet_ntop(AF_INET6, &ip6->ip6_dst, ntop_buf, sizeof(ntop_buf))) 24407cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson strlcpy(ntop_buf, "?", sizeof(ntop_buf)); 24417cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("%s\n", ntop_buf); 24427cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 24437cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 24447cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/* 24457cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * pr_addr -- 24467cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * Return an ascii host address as a dotted quad and optionally with 24477cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * a hostname. 24487cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 24497cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonconst char * 24507cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonpr_addr(struct sockaddr *addr, int addrlen) 24517cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 24527cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson static char buf[NI_MAXHOST]; 24537cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int flag = 0; 24547cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 24557cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((options & F_HOSTNAME) == 0) 24567cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson flag |= NI_NUMERICHOST; 24577cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 24587cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0, flag) == 0) 24597cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return (buf); 24607cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson else 24617cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return "?"; 24627cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 24637cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 24647cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/* 24657cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * pr_retip -- 24667cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson * Dump some info on a returned (via ICMPv6) IPv6 packet. 24677cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson */ 24687cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid 24697cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonpr_retip(struct ip6_hdr *ip6, u_char *end) 24707cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 24717cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson u_char *cp = (u_char *)ip6, nh; 24727cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int hlen; 24737cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 24747cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (end - (u_char *)ip6 < (intptr_t)sizeof(*ip6)) { 24757cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("IP6"); 24767cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson goto trunc; 24777cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 24787cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson pr_iph(ip6); 24797cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson hlen = sizeof(*ip6); 24807cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 24817cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson nh = ip6->ip6_nxt; 24827cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson cp += hlen; 24837cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson while (end - cp >= 8) { 24847cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson switch (nh) { 24857cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case IPPROTO_HOPOPTS: 24867cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("HBH "); 24877cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson hlen = (((struct ip6_hbh *)cp)->ip6h_len+1) << 3; 24887cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson nh = ((struct ip6_hbh *)cp)->ip6h_nxt; 24897cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 24907cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case IPPROTO_DSTOPTS: 24917cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("DSTOPT "); 24927cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson hlen = (((struct ip6_dest *)cp)->ip6d_len+1) << 3; 24937cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson nh = ((struct ip6_dest *)cp)->ip6d_nxt; 24947cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 24957cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case IPPROTO_FRAGMENT: 24967cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("FRAG "); 24977cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson hlen = sizeof(struct ip6_frag); 24987cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson nh = ((struct ip6_frag *)cp)->ip6f_nxt; 24997cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 25007cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case IPPROTO_ROUTING: 25017cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("RTHDR "); 25027cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson hlen = (((struct ip6_rthdr *)cp)->ip6r_len+1) << 3; 25037cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson nh = ((struct ip6_rthdr *)cp)->ip6r_nxt; 25047cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 25057cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPSEC 25067cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case IPPROTO_AH: 25077cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("AH "); 25087cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson hlen = (((struct ah *)cp)->ah_len+2) << 2; 25097cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson nh = ((struct ah *)cp)->ah_nxt; 25107cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson break; 25117cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 25127cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case IPPROTO_ICMPV6: 25137cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("ICMP6: type = %d, code = %d\n", 25147cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson *cp, *(cp + 1)); 25157cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return; 25167cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case IPPROTO_ESP: 25177cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("ESP\n"); 25187cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return; 25197cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case IPPROTO_TCP: 25207cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("TCP: from port %u, to port %u (decimal)\n", 25217cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (*cp * 256 + *(cp + 1)), 25227cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (*(cp + 2) * 256 + *(cp + 3))); 25237cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return; 25247cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson case IPPROTO_UDP: 25257cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("UDP: from port %u, to port %u (decimal)\n", 25267cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (*cp * 256 + *(cp + 1)), 25277cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (*(cp + 2) * 256 + *(cp + 3))); 25287cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return; 25297cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson default: 25307cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("Unknown Header(%d)\n", nh); 25317cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return; 25327cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 25337cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 25347cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if ((cp += hlen) >= end) 25357cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson goto trunc; 25367cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 25377cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (end - cp < 8) 25387cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson goto trunc; 25397cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 25407cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson putchar('\n'); 25417cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return; 25427cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 25437cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson trunc: 25447cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson printf("...\n"); 25457cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return; 25467cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 25477cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 25487cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid 25497cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonfill(char *bp, char *patp) 25507cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 25517cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int ii, jj, kk; 25527cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson int pat[16]; 25537cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson char *cp; 25547cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 25557cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson for (cp = patp; *cp; cp++) 25567cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (!isxdigit((unsigned char)*cp)) 25577cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "patterns must be specified as hex digits"); 25587cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ii = sscanf(patp, 25597cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", 25607cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson &pat[0], &pat[1], &pat[2], &pat[3], &pat[4], &pat[5], &pat[6], 25617cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson &pat[7], &pat[8], &pat[9], &pat[10], &pat[11], &pat[12], 25627cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson &pat[13], &pat[14], &pat[15]); 25637cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 25647cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson/* xxx */ 25657cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (ii > 0) 25667cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson for (kk = 0; 25677cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson kk <= (int)(MAXDATALEN - (8 + sizeof(struct tv32) + ii)); 25687cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson kk += ii) 25697cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson for (jj = 0; jj < ii; ++jj) 25707cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson bp[jj + kk] = pat[jj]; 25717cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (!(options & F_QUIET)) { 25727cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("PATTERN: 0x"); 25737cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson for (jj = 0; jj < ii; ++jj) 25747cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("%02x", bp[jj] & 0xFF); 25757cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)printf("\n"); 25767cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 25777cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 25787cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 25797cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPSEC 25807cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPSEC_POLICY_IPSEC 25817cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonint 25827cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonsetpolicy(int so, char *policy) 25837cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 25847cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson char *buf; 25857cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 25867cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (policy == NULL) 25877cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return 0; /* ignore */ 25887cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 25897cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson buf = ipsec_set_policy(policy, strlen(policy)); 25907cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (buf == NULL) 25917cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson errx(1, "%s", ipsec_strerror()); 25927cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (setsockopt(s, IPPROTO_IPV6, IPV6_IPSEC_POLICY, buf, 25937cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson ipsec_get_policylen(buf)) < 0) 25947cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson warnx("Unable to set IPsec policy"); 25957cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson free(buf); 25967cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 25977cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return 0; 25987cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 25997cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 26007cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 26017cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 26022f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#ifdef ANDROID_INCLUDE_MD5_SUPPORT 26037cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonchar * 26047cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonnigroup(char *name) 26057cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 26067cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson char *p; 26077cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson char *q; 26087cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson MD5_CTX ctxt; 26097cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson u_int8_t digest[16]; 26107cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson u_int8_t c; 26117cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson size_t l; 26127cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson char hbuf[NI_MAXHOST]; 26137cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson struct in6_addr in6; 26147cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 26157cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson p = strchr(name, '.'); 26167cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (!p) 26177cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson p = name + strlen(name); 26187cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson l = p - name; 26197cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (l > 63 || l > sizeof(hbuf) - 1) 26207cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return NULL; /*label too long*/ 26217cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson strncpy(hbuf, name, l); 26227cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson hbuf[(int)l] = '\0'; 26237cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 26247cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson for (q = name; *q; q++) { 26257cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (isupper(*(unsigned char *)q)) 26267cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson *q = tolower(*(unsigned char *)q); 26277cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson } 26287cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 26297cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson /* generate 8 bytes of pseudo-random value. */ 26307cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson memset(&ctxt, 0, sizeof(ctxt)); 26317cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson MD5Init(&ctxt); 26327cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson c = l & 0xff; 26337cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson MD5Update(&ctxt, &c, sizeof(c)); 26347cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson MD5Update(&ctxt, (unsigned char *)name, l); 26357cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson MD5Final(digest, &ctxt); 26367cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 26377cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (inet_pton(AF_INET6, "ff02::2:0000:0000", &in6) != 1) 26387cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return NULL; /*XXX*/ 26397cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson bcopy(digest, &in6.s6_addr[12], 4); 26407cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 26417cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson if (inet_ntop(AF_INET6, &in6, hbuf, sizeof(hbuf)) == NULL) 26427cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return NULL; 26437cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 26447cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson return strdup(hbuf); 26457cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 26462f62753130da5b9e96475deae475c244b813c083Steinar H. Gunderson#endif 26477cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson 26487cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonvoid 26497cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gundersonusage(void) 26507cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson{ 26517cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson (void)fprintf(stderr, 26527cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson "usage: ping6 [-dfH" 26537cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPV6_USE_MIN_MTU 26547cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson "m" 26557cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 26567cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson "nNqtvwW" 26577cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPV6_REACHCONF 26587cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson "R" 26597cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 26607cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPSEC 26617cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#ifdef IPSEC_POLICY_IPSEC 26627cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson "] [-P policy" 26637cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#else 26647cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson "AE" 26657cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 26667cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson#endif 26677cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson "] [-a [aAclsg]] [-b sockbufsiz] [-c count] \n" 26687cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson "\t[-I interface] [-i wait] [-l preload] [-p pattern] " 26697cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson "[-S sourceaddr]\n" 26707cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson "\t[-s packetsize] [-h hoplimit] [-g gateway] [hops...] host\n"); 26717cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson exit(1); 26727cf372809c69c92b0cadcdb1a43f31af821dc8cdSteinar H. Gunderson} 2673