?? ping6.c
字號:
/* $KAME: ping6.c,v 1.158 2002/05/31 01:11:51 itojun Exp $ *//* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *//* BSDI ping.c,v 2.3 1996/01/21 17:56:50 jch Exp *//* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Mike Muuss. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char copyright[] ="@(#) Copyright (c) 1989, 1993\n\ The Regents of the University of California. All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "@(#)ping.c 8.1 (Berkeley) 6/5/93";#endif /* not lint *//* * Using the InterNet Control Message Protocol (ICMP) "ECHO" facility, * measure round-trip-delays and packet loss across network paths. * * Author - * Mike Muuss * U. S. Army Ballistic Research Laboratory * December, 1983 * * Status - * Public Domain. Distribution Unlimited. * Bugs - * More statistics could always be gathered. * This program has to run SUID to ROOT to access the ICMP socket. *//* * NOTE: * USE_SIN6_SCOPE_ID assumes that sin6_scope_id has the same semantics * as IPV6_PKTINFO. Some people object it (sin6_scope_id specifies *link* * while IPV6_PKTINFO specifies *interface*. Link is defined as collection of * network attached to 1 or more interfaces) */#include <sys/param.h>#include <sys/uio.h>#include <sys/socket.h>#include <sys/time.h>#include <net/if.h>#include <net/route.h>#include <netinet/in.h>#include <netinet/ip6.h>#include <netinet/icmp6.h>#include <arpa/inet.h>#include <arpa/nameser.h>#include <netdb.h>#include <ctype.h>#include <err.h>#include <errno.h>#include <fcntl.h>#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__)#include <math.h>#endif#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#ifdef IPSEC#include <netinet6/ah.h>#include <netinet6/ipsec.h>#endif#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)#include <md5.h>#else#include "md5.h"#endif/* portability */#if (defined(__bsdi__) && _BSDI_VERSION < 199802) || (defined(__FreeBSD__) && __FreeBSD__ < 3)#define socklen_t int#endifstruct tv32 { u_int32_t tv32_sec; u_int32_t tv32_usec;};#define MAXPACKETLEN 131072#define IP6LEN 40#define ICMP6ECHOLEN 8 /* icmp echo header len excluding time */#define ICMP6ECHOTMLEN sizeof(struct tv32)#define ICMP6_NIQLEN (ICMP6ECHOLEN + 8)/* FQDN case, 64 bits of nonce + 32 bits ttl */#define ICMP6_NIRLEN (ICMP6ECHOLEN + 12)#define EXTRA 256 /* for AH and various other headers. weird. */#define DEFDATALEN ICMP6ECHOTMLEN#define MAXDATALEN MAXPACKETLEN - IP6LEN - ICMP6ECHOLEN#define NROUTES 9 /* number of record route slots */#define A(bit) rcvd_tbl[(bit)>>3] /* identify byte in array */#define B(bit) (1 << ((bit) & 0x07)) /* identify bit in byte */#define SET(bit) (A(bit) |= B(bit))#define CLR(bit) (A(bit) &= (~B(bit)))#define TST(bit) (A(bit) & B(bit))#define F_FLOOD 0x0001#define F_INTERVAL 0x0002#define F_PINGFILLED 0x0008#define F_QUIET 0x0010#define F_RROUTE 0x0020#define F_SO_DEBUG 0x0040#define F_VERBOSE 0x0100#ifdef IPSEC#ifdef IPSEC_POLICY_IPSEC#define F_POLICY 0x0400#else#define F_AUTHHDR 0x0200#define F_ENCRYPT 0x0400#endif /*IPSEC_POLICY_IPSEC*/#endif /*IPSEC*/#define F_NODEADDR 0x0800#define F_FQDN 0x1000#define F_INTERFACE 0x2000#define F_SRCADDR 0x4000#ifdef IPV6_REACHCONF#define F_REACHCONF 0x8000#endif#define F_HOSTNAME 0x10000#define F_FQDNOLD 0x20000#define F_NIGROUP 0x40000#define F_SUPTYPES 0x80000#define F_NOMINMTU 0x100000#define F_NOUSERDATA (F_NODEADDR | F_FQDN | F_FQDNOLD | F_SUPTYPES)u_int options;#define IN6LEN sizeof(struct in6_addr)#define SA6LEN sizeof(struct sockaddr_in6)#define DUMMY_PORT 10101#define SIN6(s) ((struct sockaddr_in6 *)(s))/* * MAX_DUP_CHK is the number of bits in received table, i.e. the maximum * number of received sequence numbers we can keep track of. Change 128 * to 8192 for complete accuracy... */#define MAX_DUP_CHK (8 * 8192)int mx_dup_ck = MAX_DUP_CHK;char rcvd_tbl[MAX_DUP_CHK / 8];struct addrinfo *res;struct sockaddr_in6 dst; /* who to ping6 */struct sockaddr_in6 src; /* src addr of this packet */socklen_t srclen;int datalen = DEFDATALEN;int s; /* socket file descriptor */u_char outpack[MAXPACKETLEN];char BSPACE = '\b'; /* characters written for flood */char DOT = '.';char *hostname;int ident; /* process id to identify our packets */u_int8_t nonce[8]; /* nonce field for node information */int hoplimit = -1; /* hoplimit */int pathmtu = 0; /* path MTU for the destination. 0 = unspec. *//* counters */long npackets; /* max packets to transmit */long nreceived; /* # of packets we got back */long nrepeats; /* number of duplicates */long ntransmitted; /* sequence # for outbound packets = #sent */struct timeval interval = {1, 0}; /* interval between packets *//* timing */int timing; /* flag to do timing */double tmin = 999999999.0; /* minimum round trip time */double tmax = 0.0; /* maximum round trip time */double tsum = 0.0; /* sum of all times, for doing average */#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__)double tsumsq = 0.0; /* sum of all times squared, for std. dev. */#endif/* for node addresses */u_short naflags;/* for ancillary data(advanced API) */struct msghdr smsghdr;struct iovec smsgiov;char *scmsg = 0;volatile sig_atomic_t seenalrm;volatile sig_atomic_t seenint;#ifdef SIGINFOvolatile sig_atomic_t seeninfo;#endifint main __P((int, char *[]));void fill __P((char *, char *));int get_hoplim __P((struct msghdr *));int get_pathmtu __P((struct msghdr *));struct in6_pktinfo *get_rcvpktinfo __P((struct msghdr *));void onsignal __P((int));void retransmit __P((void));void onint __P((int));size_t pingerlen __P((void));int pinger __P((void));const char *pr_addr __P((struct sockaddr *, int));void pr_icmph __P((struct icmp6_hdr *, u_char *));void pr_iph __P((struct ip6_hdr *));void pr_suptypes __P((struct icmp6_nodeinfo *, size_t));void pr_nodeaddr __P((struct icmp6_nodeinfo *, int));int myechoreply __P((const struct icmp6_hdr *));int mynireply __P((const struct icmp6_nodeinfo *));char *dnsdecode __P((const u_char **, const u_char *, const u_char *, u_char *, size_t));void pr_pack __P((u_char *, int, struct msghdr *));void pr_exthdrs __P((struct msghdr *));void pr_ip6opt __P((void *));void pr_rthdr __P((void *));int pr_bitrange __P((u_int32_t, int, int));void pr_retip __P((struct ip6_hdr *, u_char *));void summary __P((void));void tvsub __P((struct timeval *, struct timeval *));int setpolicy __P((int, char *));char *nigroup __P((char *));void usage __P((void));intmain(argc, argv) int argc; char *argv[];{ struct itimerval itimer; struct sockaddr_in6 from; struct timeval timeout, *tv; struct addrinfo hints; fd_set *fdmaskp; int fdmasks; int cc, i; int ch, hold, packlen, preload, optval, ret_ga; u_char *datap, *packet; char *e, *target, *ifname = NULL, *gateway = NULL; int ip6optlen = 0; struct cmsghdr *scmsgp = NULL; int sockbufsize = 0; int usepktinfo = 0; struct in6_pktinfo *pktinfo = NULL;#ifdef USE_RFC2292BIS struct ip6_rthdr *rthdr = NULL;#endif#ifdef IPSEC_POLICY_IPSEC char *policy_in = NULL; char *policy_out = NULL;#endif double intval; size_t rthlen;#ifdef IPV6_USE_MIN_MTU int mflag = 0;#endif /* just to be sure */ memset(&smsghdr, 0, sizeof(&smsghdr)); memset(&smsgiov, 0, sizeof(&smsgiov)); preload = 0; datap = &outpack[ICMP6ECHOLEN + ICMP6ECHOTMLEN];#ifndef IPSEC#define ADDOPTS#else#ifdef IPSEC_POLICY_IPSEC#define ADDOPTS "P:"#else#define ADDOPTS "AE"#endif /*IPSEC_POLICY_IPSEC*/#endif while ((ch = getopt(argc, argv, "a:b:c:dfHg:h:I:i:l:mnNp:qRS:s:tvwW" ADDOPTS)) != -1) {#undef ADDOPTS switch (ch) { case 'a': { char *cp; options &= ~F_NOUSERDATA; options |= F_NODEADDR; for (cp = optarg; *cp != '\0'; cp++) { switch (*cp) { case 'a': naflags |= NI_NODEADDR_FLAG_ALL; break; case 'c': case 'C': naflags |= NI_NODEADDR_FLAG_COMPAT; break; case 'l': case 'L': naflags |= NI_NODEADDR_FLAG_LINKLOCAL; break; case 's': case 'S': naflags |= NI_NODEADDR_FLAG_SITELOCAL; break; case 'g': case 'G': naflags |= NI_NODEADDR_FLAG_GLOBAL; break; case 'A': /* experimental. not in the spec */#ifdef NI_NODEADDR_FLAG_ANYCAST naflags |= NI_NODEADDR_FLAG_ANYCAST; break;#else errx(1,"-a A is not supported on the platform"); /*NOTREACHED*/#endif default: usage(); /*NOTREACHED*/ } } break; } case 'b':#if defined(SO_SNDBUF) && defined(SO_RCVBUF) sockbufsize = atoi(optarg);#else errx(1,"-b option ignored: SO_SNDBUF/SO_RCVBUF socket options not supported");#endif break; case 'c': npackets = strtol(optarg, &e, 10); if (npackets <= 0 || *optarg == '\0' || *e != '\0') errx(1, "illegal number of packets -- %s", optarg); break; case 'd': options |= F_SO_DEBUG; break; case 'f': if (getuid()) { errno = EPERM; errx(1, "Must be superuser to flood ping"); } options |= F_FLOOD; setbuf(stdout, (char *)NULL); break; case 'g': gateway = optarg; break; case 'H': options |= F_HOSTNAME; break; case 'h': /* hoplimit */ hoplimit = strtol(optarg, &e, 10); if (*optarg == '\0' || *e != '\0') errx(1, "illegal hoplimit %s", optarg); if (255 < hoplimit || hoplimit < -1) errx(1, "illegal hoplimit -- %s", optarg); break; case 'I': ifname = optarg; options |= F_INTERFACE;#ifndef USE_SIN6_SCOPE_ID usepktinfo++;#endif break; case 'i': /* wait between sending packets */ intval = strtod(optarg, &e); if (*optarg == '\0' || *e != '\0') errx(1, "illegal timing interval %s", optarg); if (intval < 1 && getuid()) { errx(1, "%s: only root may use interval < 1s", strerror(EPERM)); } interval.tv_sec = (long)intval; interval.tv_usec = (long)((intval - interval.tv_sec) * 1000000); if (interval.tv_sec < 0) errx(1, "illegal timing interval %s", optarg); /* less than 1/hz does not make sense */ if (interval.tv_sec == 0 && interval.tv_usec < 10000) { warnx("too small interval, raised to 0.01"); interval.tv_usec = 10000; } options |= F_INTERVAL; break; case 'l': if (getuid()) { errno = EPERM; errx(1, "Must be superuser to preload"); } preload = strtol(optarg, &e, 10); if (preload < 0 || *optarg == '\0' || *e != '\0') errx(1, "illegal preload value -- %s", optarg); break; case 'm':#ifdef IPV6_USE_MIN_MTU mflag++; break;#else errx(1, "-%c is not supported on this platform", ch); /*NOTREACHED*/#endif case 'n': options &= ~F_HOSTNAME; break; case 'N': options |= F_NIGROUP; break; case 'p': /* fill buffer with user pattern */ options |= F_PINGFILLED; fill((char *)datap, optarg); break; case 'q': options |= F_QUIET; break; case 'R':#ifdef IPV6_REACHCONF options |= F_REACHCONF; break;#else errx(1, "-R is not supported in this configuration");#endif case 'S': memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_flags = AI_NUMERICHOST; /* allow hostname? */ hints.ai_family = AF_INET6; hints.ai_socktype = SOCK_RAW; hints.ai_protocol = IPPROTO_ICMPV6; ret_ga = getaddrinfo(optarg, NULL, &hints, &res); if (ret_ga) { errx(1, "invalid source address: %s", gai_strerror(ret_ga)); } /* * res->ai_family must be AF_INET6 and res->ai_addrlen * must be sizeof(src). */ memcpy(&src, res->ai_addr, res->ai_addrlen); srclen = res->ai_addrlen; freeaddrinfo(res); options |= F_SRCADDR; break; case 's': /* size of packet to send */ datalen = strtol(optarg, &e, 10); if (datalen <= 0 || *optarg == '\0' || *e != '\0') errx(1, "illegal datalen value -- %s", optarg); if (datalen > MAXDATALEN) { errx(1, "datalen value too large, maximum is %d", MAXDATALEN); } break; case 't': options &= ~F_NOUSERDATA; options |= F_SUPTYPES; break; case 'v': options |= F_VERBOSE; break; case 'w': options &= ~F_NOUSERDATA;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -