⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ping6.c

📁 linux下常用的网络工具的代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright (C) 1998, 2001, 2002, 2004, 2005 Free Software Foundation, Inc.   This file is part of GNU Inetutils.   GNU Inetutils is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2, or (at your option)   any later version.   GNU Inetutils is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with GNU Inetutils; see the file COPYING.  If not, write   to the Free Software Foundation, Inc., 51 Franklin Street,   Fifth Floor, Boston, MA 02110-1301 USA. */#ifdef HAVE_CONFIG_H# include <config.h>#endif#include <sys/socket.h>#include <sys/time.h>#include <signal.h>#include <netinet/in.h>#include <netinet/ip6.h>#include <netinet/icmp6.h>#include <netdb.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <stdio.h>#include <ctype.h>#include <errno.h>#include <limits.h>#include <getopt.h>#include <xalloc.h>#include "ping_common.h"#include "ping6.h"static char short_options[] = "VLhc:dfi:l:np:qRrs:t:v";static struct option long_options[] = {  /* Help options */  {"version", no_argument, NULL, 'V'},  {"license", no_argument, NULL, 'L'},  {"help",    no_argument, NULL, 'h'},  /* Common options */  {"count",   required_argument, NULL, 'c'},  {"debug",   no_argument, NULL, 'd'},  {"ignore-routing", no_argument, NULL, 'r'},  {"size",    required_argument, NULL, 's'},  {"interval",required_argument, NULL, 'i'},  {"numeric", no_argument, NULL, 'n'},  /* echo-specific options */  {"flood",   no_argument, NULL, 'f'},  {"preload", required_argument, NULL, 'l'},  {"pattern", required_argument, NULL, 'p'},  {"quiet",   no_argument, NULL, 'q'},  {NULL,      no_argument, NULL, 0}};static PING *ping;unsigned char *data_buffer;size_t data_length = PING_DATALEN;static unsigned int options;static unsigned long preload = 0;static int ping_echo (int argc, char **argv);static void show_usage (void);static int send_echo (PING *ping);char *program_name;intmain (int argc, char **argv){  int c;  char *p;  int one = 1;  u_char pattern[16];  int pattern_len = 16;  u_char *patptr = NULL;  int is_root = getuid () == 0;  program_name = argv[0];  if ((ping = ping_init (0, getpid ())) == NULL)    {      fprintf (stderr, "can't init ping: %s\n", strerror (errno));      exit (1);    }  setsockopt (ping->ping_fd, SOL_SOCKET, SO_BROADCAST, (char *)&one, sizeof (one));  /* Reset root privileges */  setuid (getuid ());  /* Parse command line */  while ((c = getopt_long (argc, argv, short_options, long_options, NULL))	 != EOF)    {      switch (c)	{	case 'V':	  printf ("ping - %s %s\n", PACKAGE_NAME, PACKAGE_VERSION);	  printf ("Copyright (C) 2005 Free Software Foundation, Inc.\n");	  printf ("%s comes with ABSOLUTELY NO WARRANTY.\n", PACKAGE_NAME);	  printf ("You may redistribute copies of %s\n", PACKAGE_NAME);	  printf ("under the terms of the GNU General Public License.\n");	  printf ("For more information about these matters, ");	  printf ("see the files named COPYING.\n");	  exit (0);	  break;	  	case 'L':	  show_license ();	  exit (0);	  	case 'h':	  show_usage ();	  exit (0);	  break;	  	case 'c':	  ping->ping_count = ping_cvt_number (optarg, 0, 0);	  break;	  	case 'd':	  setsockopt (ping->ping_fd, SOL_SOCKET, SO_DEBUG, &one, sizeof (one));	  break;	  	case 'r':	  setsockopt (ping->ping_fd, SOL_SOCKET, SO_DONTROUTE, &one, sizeof (one));	  break;	  	case 'i':	  options |= OPT_INTERVAL;	  ping->ping_interval = ping_cvt_number (optarg, 0, 0);	  break;	  	case 'p':	  decode_pattern (optarg, &pattern_len, pattern);	  patptr = pattern;	  break;	   	case 's':	  data_length = ping_cvt_number (optarg, PING_MAX_DATALEN, 1); 	  break;	  	case 'n':	  options |= OPT_NUMERIC;	  break;	  	case 'q':	  options |= OPT_QUIET;	  break;	  	case 'l':	  if (!is_root)	    {	      fprintf (stderr, "ping: option not allowed: --preload\n");	      exit (1);	    }	  preload = strtoul (optarg, &p, 0);	  if (*p || preload > INT_MAX)	    {	      fprintf (stderr, "ping: invalid preload value (%s)\n", optarg);	      exit (1);	    }	  break;	case 'f':	  if (!is_root)	    {	      fprintf (stderr, "ping: option not allowed: --flood\n");	      exit (1);	    }	  options |= OPT_FLOOD;	  setbuf (stdout, (char *)NULL);	  break;	default:	  fprintf (stderr, "%c: not implemented\n", c);	  exit (1);	}    }  argc -= optind;  argv += optind;  if (argc == 0)     {      show_usage ();      exit (0);    }  init_data_buffer (patptr, pattern_len);  return ping_echo (argc, argv);}static char *ipaddr2str (struct sockaddr_in6 *from){  int err;  size_t len;  char *buf, ipstr[256], hoststr[256];  err = getnameinfo ((struct sockaddr *) from, sizeof (*from), ipstr,		     sizeof (ipstr), NULL, 0, NI_NUMERICHOST);  if (err)    {      const char *errmsg;            if (err == EAI_SYSTEM)	errmsg = strerror (errno);      else	errmsg = gai_strerror (err);            fprintf (stderr, "ping: getnameinfo: %s\n", errmsg);      return xstrdup ("unknown");    }    if (options & OPT_NUMERIC)    return xstrdup (ipstr);  err = getnameinfo ((struct sockaddr *) from, sizeof (*from), hoststr,		     sizeof (hoststr), NULL, 0, NI_NAMEREQD);  if (err)    return xstrdup (ipstr);  len = strlen (ipstr) + strlen (hoststr) + 4; /* Pair of parentheses, a space						  and a NUL. */  buf = xmalloc (len);  sprintf (buf, "%s (%s)", hoststr, ipstr);  return buf;}static volatile int stop = 0;static RETSIGTYPEsig_int (int signal){  stop = 1;}static intping_run (PING *ping, int (*finish)()){  fd_set fdset;  int fdmax;  struct timeval timeout;  struct timeval last, intvl, now;  struct timeval *t = NULL;  int finishing = 0;  int nresp = 0;  signal (SIGINT, sig_int);    fdmax = ping->ping_fd+1;  while (preload--)          send_echo (ping);  if (options & OPT_FLOOD)    {      intvl.tv_sec = 0;      intvl.tv_usec = 10000;    }  else    {      intvl.tv_sec = ping->ping_interval;      intvl.tv_usec = 0;    }    gettimeofday (&last, NULL);  send_echo (ping);  while (!stop)    {      int n;            FD_ZERO (&fdset);      FD_SET (ping->ping_fd, &fdset);      gettimeofday (&now, NULL);      timeout.tv_sec = last.tv_sec + intvl.tv_sec - now.tv_sec;      timeout.tv_usec = last.tv_usec + intvl.tv_usec - now.tv_usec;      while (timeout.tv_usec < 0)	{	  timeout.tv_usec += 1000000;	  timeout.tv_sec--;	}      while (timeout.tv_usec >= 1000000)	{	  timeout.tv_usec -= 1000000;	  timeout.tv_sec++;	}      if (timeout.tv_sec < 0)	timeout.tv_sec = timeout.tv_usec = 0;      n = select (fdmax, &fdset, NULL, NULL, &timeout);      if (n < 0)	{	  if (errno != EINTR)	    perror ("select");	  continue;	}      else if (n == 1)	{	  if (ping_recv (ping) == 0)	    nresp++;	  if (t == 0)	    {	      gettimeofday (&now, NULL);	      t = &now;	    }	  if (ping->ping_count && nresp >= ping->ping_count)	    break;	}      else	{	  if (!ping->ping_count || ping->ping_num_xmit < ping->ping_count)	    {	      send_echo (ping);	      if (!(options & OPT_QUIET) && options & OPT_FLOOD)		{		  putchar ('.');		}	    }	  else if (finishing)	    break;	  else 	    {	      finishing = 1;	      intvl.tv_sec = MAXWAIT;	    }	  gettimeofday (&last, NULL);	}    }  if (finish)    return (*finish)();  return 0;}static intsend_echo (PING *ping){  int off = 0;    if (PING_TIMING (data_length))    {      struct timeval tv;      gettimeofday (&tv, NULL);      ping_set_data (ping, &tv, 0, sizeof (tv));      off += sizeof (tv);    }  if (data_buffer)    ping_set_data (ping, data_buffer, off,		   data_length > PING_HEADER_LEN ?		   data_length - PING_HEADER_LEN : data_length);  return ping_xmit (ping);}static intping_finish (){  fflush (stdout);  printf ("--- %s ping statistics ---\n", ping->ping_hostname);  printf ("%ld packets transmitted, ", ping->ping_num_xmit);  printf ("%ld packets received, ", ping->ping_num_recv);  if (ping->ping_num_rept)    printf ("+%ld duplicates, ", ping->ping_num_rept);    if (ping->ping_num_xmit)    {      if (ping->ping_num_recv > ping->ping_num_xmit)	printf ("-- somebody's printing up packets!");      else	printf ("%d%% packet loss",	       (int) (((ping->ping_num_xmit - ping->ping_num_recv) * 100) /		      ping->ping_num_xmit));    }  printf ("\n");  return 0;}static int print_echo (int dup, int hops, struct ping_stat *stat,		       struct sockaddr_in6 *dest, struct sockaddr_in6 *from,		       struct icmp6_hdr *icmp6, int datalen);static void print_icmp_error (struct sockaddr_in6 *from,			      struct icmp6_hdr *icmp6, int len);static int echo_finish (void);static intping_echo (int argc, char **argv){  int err;  char buffer[256];  struct ping_stat ping_stat;  if (options & OPT_FLOOD && options & OPT_INTERVAL)    {      fprintf (stderr,	       "ping: -f and -i incompatible options.\n");      return 2;    }  memset (&ping_stat, 0, sizeof (ping_stat));  ping_stat.tmin = 999999999.0;  ping->ping_datalen = data_length;  ping->ping_closure = &ping_stat;    if (ping_set_dest (ping, *argv))    {      fprintf (stderr, "ping: unknown host\n");      exit (1);    }  err = getnameinfo ((struct sockaddr *) &ping->ping_dest,		     sizeof (ping->ping_dest), buffer,		     sizeof (buffer), NULL, 0, NI_NUMERICHOST);  if (err)    {      const char *errmsg;            if (err == EAI_SYSTEM)	errmsg = strerror (errno);      else	errmsg = gai_strerror (err);      fprintf (stderr, "ping: getnameinfo: %s\n", errmsg);      exit (1);    }    printf ("PING %s (%s): %d data bytes\n",	  ping->ping_hostname, buffer, data_length);  return ping_run (ping, echo_finish);}static intprint_echo (int dupflag, int hops, struct ping_stat *ping_stat,	    struct sockaddr_in6 *dest, struct sockaddr_in6 *from,	    struct icmp6_hdr *icmp6, int datalen){  int err;  char buf[256];  struct timeval tv;  int timing = 0;  double triptime = 0.0;  gettimeofday (&tv, NULL);  /* Do timing */  if (PING_TIMING (datalen - sizeof (struct icmp6_hdr)))    {      struct timeval tv1, *tp;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -