home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-07-02 | 42.2 KB | 1,395 lines |
- Newsgroups: comp.sources.unix
- From: schemers@Slapshot.Stanford.EDU (Roland J. Schemers III)
- Subject: v26i278: fping - A tool to quickly ping N number of hosts, Part01/01
- Sender: unix-sources-moderator@gw.home.vix.com
- Approved: vixie@gw.home.vix.com
-
- Submitted-By: schemers@Slapshot.Stanford.EDU (Roland J. Schemers III)
- Posting-Number: Volume 26, Issue 278
- Archive-Name: fping/part01
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: README CHANGES fping.c fping.man Makefile README.VMS
- # Wrapped by schemers@Slapshot.Stanford.EDU on Mon Feb 22 16:19:25 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(2334 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- X
- X fping - A tool to quickly ping N number of hosts to determine
- X their reachability without flooding the network.
- X
- X Roland J. Schemers III - Stanford University
- X schemers@Slapshot.Stanford.EDU
- X
- X fping is a ping(1) like program which uses the Internet Control
- X Message Protocol (ICMP) echo request to determine if a host is
- X up. fping is different from ping in that you can specify any
- X number of hosts on the command line, or specify a file containing
- X the lists of hosts to ping. Instead of trying one host until it
- X timeouts or replies, fping will send out a ping packet and move
- X on to the next host in a round-robin fashion. If a host replies,
- X it is noted and removed from the list of hosts to check. If a host
- X does not respond within a certain time limit and/or retry limit it
- X will be considered unreachable.
- X
- XSite
- X Stanford University has a large TCP/IP network with over 12,000
- X assigned IP addresses and over 100 IP subnets.
- X
- XProblem and Issues
- X
- X With a large a number of IP addresses in use, its becomes more and
- X more time consuming to check on which IP addresses are actively
- X in use, and which critical machines (routers, bridges, servers, etc)
- X are reachable. One example is we have a program which goes through
- X all of our routers arp caches looking for IP addresses that are in
- X use. After finding a list of IP addresses that aren't in any arp
- X caches fping can then be used to see if these IP addresses really
- X aren't being used, or are just behind the routers. Checking 2500
- X hosts (99% of which are unreachable) via ping can take hours.
- X
- XSolution
- X
- X fping was written to solve the problem of pinging N number of hosts
- X in an efficient manner. By sending out pings in a round-robin fashion
- X and checking on responses as they come in at random, a large number of
- X hosts can be checked at once. Checking 2500 hosts (5 packets per host,
- X 10 msec between ping packets) takes under 3 minutes. Also, using fping
- X to check 30 routers that are currently reachable takes about 420
- X milliseconds (elapsed real time).
- X
- X Unlike ping, fping is meant to be used in scripts and its
- X output is easy to parse.
- END_OF_FILE
- if test 2334 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'CHANGES' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'CHANGES'\"
- else
- echo shar: Extracting \"'CHANGES'\" \(2952 characters\)
- sed "s/^X//" >'CHANGES' <<'END_OF_FILE'
- X* Revision 1.20 1993/02/23 00:16:38 schemers
- X
- Xfixed syntax error (should have compiled before checking in...)
- X
- X* Revision 1.19 1993/02/23 00:15:15 schemers
- X
- Xturned off printing of "is alive" when -a is specified.
- X
- X* Revision 1.18 1992/07/28 15:16:44 schemers
- X
- Xadded a fflush(stdout) call before the summary is sent to stderr, so
- Xeverything shows up in the right order.
- X
- X* Revision 1.17 1992/07/23 03:29:42 schemers
- X* Revision 1.16 1992/07/22 19:24:37 schemers
- X
- XFixed declaration of timeval_diff. Didn't notice the problem because
- XI use 'cc' in stead of gcc under Ultrix. Time to switch? :-)
- X
- XModified file reaing so it would skip blank lines or lines starting
- Xwith a '#'. Now you can do something like:
- X
- Xfping -ad < /etc/hosts
- X
- X* Revision 1.15 1992/07/21 17:07:18 schemers
- X
- XPut in sanity checks so only root can specify "dangerous" options.
- XChanged usage to show switchs in alphabetical order.
- X* Revision 1.14 1992/07/21 16:40:52 schemers
- X* Revision 1.13 1992/07/17 21:02:17 schemers
- X
- XChanged the default timeout to 2500 msec, and retry to 3. This was
- Xdue to suggestions from people with slow (WAN) networks. The default
- X1 sec timeout was too fast.
- X
- X
- XAdded '-e' option for showing elapsed (round-trip) times on pakets, and
- Xmodified the -s option to include min, max, and average round-trip times,
- Xand over all elapsed time.
- X
- XModified action taken when a error is returned from sendto. The action
- Xtaken now considers the host unreachable and prints the hostname
- Xfollowed by the errno message. The program will not exit and will continue
- Xto try other hosts.
- X
- X* Revision 1.12 1992/07/17 16:38:54 schemers
- X* Revision 1.11 1992/07/17 16:28:38 schemers
- X
- X move socket create call so I could do a setuid(getuid()) before the
- X fopen call is made. Once the socket is created root privs aren't needed
- X to send stuff out on it.
- X
- X moved num_timeout counter. It really was for debug purposes and didn't
- X make sense to the general public :-) Now it is the number of timeouts
- X (pings that didn't get received with the time limit).
- X
- X
- X* Revision 1.10 1992/07/16 16:24:38 schemers
- X* Revision 1.9 1992/07/16 16:00:04 schemers
- X* Revision 1.8 1992/07/16 05:44:41 schemers
- X
- XAdded _NO_PROTO stuff for older compilers, and _POSIX_SOURCE
- Xfor unistd.h, and _POSIX_SOURCE for stdlib.h. Also added
- Xcheck for __cplusplus.
- X
- XNow compiles ok under Ultrix 3.1, and Sun4 using cc. Also compiled
- Xok using g++ 2.2.2.
- X
- XChanged '-a' and '-u' flags to be mutually exclusive (makes sense, since
- Xspecifiying both '-a' and '-u' is the same as not specifiying anything.
- XSince '-a' and '-u' are mutually exclusive, these options now only print
- Xthe hostname, and not the 'is alive' or 'is unreachable' messages.
- XThis makes it much easier to do stuff like:
- X
- X#!/usr/local/bin/perl
- X$hosts_to_backup=`cat /etc/hosts.backup|fping -a`;
- X
- XSince you don't have to strip off the 'is alive' messages.
- X
- XChanged usage to and stats to print to stderr instead of stdout.
- X
- X
- END_OF_FILE
- if test 2952 -ne `wc -c <'CHANGES'`; then
- echo shar: \"'CHANGES'\" unpacked with wrong size!
- fi
- # end of 'CHANGES'
- fi
- if test -f 'fping.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'fping.c'\"
- else
- echo shar: Extracting \"'fping.c'\" \(23070 characters\)
- sed "s/^X//" >'fping.c' <<'END_OF_FILE'
- X/*
- X * fping: fast-ping, file-ping
- X *
- X * Used to send out ping requests to a list of hosts in a round robin
- X * fashion.
- X *
- X *
- X * fping has been compiled tested under the following systems:
- X *
- X * Ultrix 4.2a DECstation
- X * Ultrix 3.1 VAX
- X * NeXT 2.1
- X * SunOS 4.1.1 Sparcstation (gcc and cc)
- X * AIX 3.1 RISC System/6000
- X *
- X */
- X
- X/*
- X ***************************************************
- X *
- X * Standard RCS Header information (see co(1))
- X *
- X * $Author: schemers $
- X *
- X * $Date: 1993/02/23 00:16:38 $
- X *
- X * $Revision: 1.20 $
- X *
- X * $Locker: schemers $
- X *
- X * $Source: /networking/src/fping/RCS/fping.c,v $
- X *
- X * $State: Exp $
- X *
- X * $Log: fping.c,v $
- X * Revision 1.20 1993/02/23 00:16:38 schemers
- X * fixed syntax error (should have compiled before checking in...)
- X *
- X * Revision 1.19 1993/02/23 00:15:15 schemers
- X * turned off printing of "is alive" when -a is specified.
- X *
- X * Revision 1.18 1992/07/28 15:16:44 schemers
- X * added a fflush(stdout) call before the summary is sent to stderr, so
- X * everything shows up in the right order.
- X *
- X * Revision 1.17 1992/07/23 03:29:42 schemers
- X * fixed declaration of timeval_diff.
- X *
- X * Revision 1.16 1992/07/22 19:24:37 schemers
- X * Modified file reading so it would skip blanks lines or lines starting
- X * with a '#'. Now you can do something like:
- X *
- X * fping -ad < /etc/hosts
- X *
- X * Revision 1.15 1992/07/21 17:07:18 schemers
- X * Put in sanity checks so only root can specify "dangerous" options.
- X * Changed usage to show switchs in alphabetical order.
- X *
- X * Revision 1.14 1992/07/21 16:40:52 schemers
- X * Now when sendto returns an error, the host is considered unreachable and
- X * and the error message (from errno) is displayed.
- X *
- X * Revision 1.13 1992/07/17 21:02:17 schemers
- X * changed default timeout to 2500 msec (for WANs), and default try
- X * to 3. This gives 10 second overall timeout.
- X *
- X * Added -e option for showing elapsed (round-trip) time on packets
- X *
- X * Modified -s option to inlude to round-trip stats
- X *
- X * Added #ifndef DEFAULT_* stuff its easier to change the defaults
- X *
- X * Reorganized main loop.
- X *
- X * cleaned up timeval stuff. removed set_timeval and timeval_expired
- X * since they aren't needed anymore. Just use timeval_diff.
- X *
- X * Revision 1.12 1992/07/17 16:38:54 schemers
- X * move socket create call so I could do a setuid(getuid()) before the
- X * fopen call is made. Once the socket is created root privs aren't needed
- X * to send stuff out on it.
- X *
- X * Revision 1.11 1992/07/17 16:28:38 schemers
- X * moved num_timeout counter. It really was for debug purposes and didn't
- X * make sense to the general public :-) Now it is the number of timeouts
- X * (pings that didn't get received with the time limit).
- X *
- X * Revision 1.10 1992/07/16 16:24:38 schemers
- X * changed usage() to use fprintf(stderr,"...");
- X *
- X * Revision 1.9 1992/07/16 16:00:04 schemers
- X * Added _NO_PROTO stuff for older compilers, and _POSIX_SOURCE
- X * for unistd.h, and _POSIX_SOURCE for stdlib.h. Also added
- X * check for __cplusplus.
- X *
- X * Revision 1.8 1992/07/16 05:44:41 schemers
- X * changed -a and -u to only show hostname in results. This is
- X * for easier parsing. Also added -v flag
- X *
- X * Revision 1.7 1992/07/14 18:45:23 schemers
- X * initialized last_time in add_host function
- X *
- X * Revision 1.6 1992/07/14 18:32:40 schemers
- X * changed select to use FD_ macros
- X *
- X * Revision 1.5 1992/07/14 17:21:22 schemers
- X * standardized exit status codes
- X *
- X * Revision 1.4 1992/06/26 15:25:35 schemers
- X * changed name from rrping to fping
- X *
- X * Revision 1.3 1992/06/24 15:39:32 schemers
- X * added -d option for unreachable systems
- X *
- X * Revision 1.2 1992/06/23 03:01:23 schemers
- X * misc fixes from R.L. "Bob" Morgan
- X *
- X * Revision 1.1 1992/06/19 18:23:52 schemers
- X * Initial revision
- X *
- X *--------------------------------------------------
- X * Copyright (c) 1992 Board of Trustees
- X * Leland Stanford Jr. University
- X ***************************************************
- X */
- X
- X/*
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice and this paragraph are
- X * duplicated in all such forms and that any documentation,
- X * advertising materials, and other materials related to such
- X * distribution and use acknowledge that the software was developed
- X * by Stanford University. The name of the University may not be used
- X * to endorse or promote products derived from this software without
- X * specific prior written permission.
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X */
- X
- X#ifndef _NO_PROTO
- X#if !__STDC__ && !defined(__cplusplus) && !defined(FUNCPROTO) \
- X && !defined(_POSIX_SOURCE)
- X#define _NO_PROTO
- X#endif /* __STDC__ */
- X#endif /* _NO_PROTO */
- X
- X#ifdef __cplusplus
- Xextern "C" {
- X#endif
- X
- X#include <stdio.h>
- X#include <errno.h>
- X#include <time.h>
- X
- X#ifdef _POSIX_SOURCE
- X#include <unistd.h>
- X#endif
- X
- X#ifdef __STDC__
- X#include <stdlib.h>
- X#endif
- X
- X#include <string.h>
- X
- X#include <sys/types.h>
- X#include <sys/time.h>
- X#include <sys/socket.h>
- X
- X
- X#include <netinet/in_systm.h>
- X#include <netinet/in.h>
- X#include <netinet/ip.h>
- X#include <netinet/ip_icmp.h>
- X#include <arpa/inet.h>
- X
- X#include <netdb.h>
- X
- X/* RS6000 has sys/select.h */
- X#ifndef FD_SET
- X#include <sys/select.h>
- X#endif
- X
- X/* externals */
- X
- Xextern char *optarg;
- Xextern int optind,opterr;
- Xextern char *sys_errlist[];
- X
- X
- X#ifdef __cplusplus
- X}
- X#endif
- X
- X/* constants */
- X
- X#ifndef DEFAULT_INTERVAL
- X#define DEFAULT_INTERVAL 25 /* default time between packets (msec) */
- X#endif
- X
- X#ifndef DEFAULT_TIMEOUT
- X#define DEFAULT_TIMEOUT 2500 /* individual host timeouts */
- X#endif
- X
- X#ifndef DEFAULT_RETRY
- X#define DEFAULT_RETRY 3 /* number of times to retry a host */
- X#endif
- X
- X
- X/* typedef's */
- X
- X/* entry used to keep track of each host we are pinging */
- X
- Xtypedef struct host_entry {
- X char *host; /* text description of host */
- X struct sockaddr_in saddr; /* internet address */
- X int i; /* index into array */
- X int num_packets_sent; /* number of ping packets sent */
- X struct host_entry *prev,*next; /* doubly linked list */
- X struct timeval last_time; /* time of last packet sent */
- X} HOST_ENTRY;
- X
- X/* globals */
- X
- XHOST_ENTRY *rrlist=NULL; /* linked list of hosts be pinged */
- XHOST_ENTRY **table=NULL; /* array of pointers to items in the list */
- XHOST_ENTRY *cursor;
- X
- Xchar *prog;
- Xint ident; /* our pid */
- Xint s; /* socket */
- X
- Xint retry = DEFAULT_RETRY;
- Xint timeout = DEFAULT_TIMEOUT;
- Xint interval = DEFAULT_INTERVAL;
- X
- Xlong max_reply=0;
- Xlong min_reply=10000;
- Xint total_replies=0;
- Xdouble sum_replies=0;
- X
- Xstruct timeval timeout_timeval;
- Xstruct timezone tz;
- X
- Xint num_waiting=0; /* number of hosts we are pinging */
- Xint num_hosts; /* total number of hosts */
- X
- Xint num_alive=0, /* total number alive */
- X num_unreachable=0, /* total number unreachable */
- X num_noaddress=0; /* total number of addresses not found */
- X
- Xint num_timeout=0, /* number of times select timed out */
- X num_pingsent=0, /* total pings sent */
- X num_pingreceived=0; /* total pings received */
- X
- Xstruct timeval current_time; /* current time (pseudo) */
- Xstruct timeval start_time;
- Xstruct timeval end_time;
- X
- X/* switches */
- Xint verbose_flag,dns_flag,stats_flag,unreachable_flag,alive_flag;
- Xint elapsed_flag,version_flag;
- X
- Xchar *filename=NULL; /* file containing hosts to ping */
- X
- X/* forward declarations */
- X
- X#ifdef _NO_PROTO
- X
- Xvoid add_host();
- Xvoid crash_and_burn();
- Xvoid errno_crash_and_burn();
- Xchar *get_host_by_address();
- Xint in_cksum();
- Xint recvfrom_wto ();
- Xvoid remove_job();
- Xvoid send_ping();
- Xvoid usage();
- Xint wait_for_reply();
- Xlong timeval_diff();
- X#else
- X
- Xvoid add_host(char *host);
- Xvoid crash_and_burn(char *message);
- Xvoid errno_crash_and_burn(char *message);
- Xchar *get_host_by_address(struct in_addr in);
- Xint in_cksum(u_short *p, int n);
- Xint recvfrom_wto (int s, char *buf, int len, struct sockaddr *saddr, int timo);
- Xvoid remove_job(HOST_ENTRY *h);
- Xvoid send_ping(int s,HOST_ENTRY *h);
- Xlong timeval_diff(struct timeval *a,struct timeval *b);
- Xvoid usage();
- Xint wait_for_reply();
- X
- X#endif
- X
- X#ifdef _NO_PROTO
- Xint main(argc,argv)
- Xint argc; char **argv;
- X#else
- Xint main(int argc, char **argv)
- X#endif
- X{
- X
- X int c;
- X
- X struct protoent *proto;
- X
- X /* check if we are root */
- X
- X if (geteuid()) {
- X fprintf(stderr,
- X "This program can only be run by root, or it must be setuid root.\n");
- X exit(3);
- X }
- X
- X if ((proto = getprotobyname("icmp")) == NULL)
- X crash_and_burn("icmp: unknown protocol");
- X
- X /* create the socket here as root. Then setuid back to
- X the person running the program. This is so they
- X can't open a file that doesn't belong to them! */
- X
- X s = socket(AF_INET, SOCK_RAW, proto->p_proto);
- X if (s<0) errno_crash_and_burn("can't create raw socket");
- X
- X setuid(getuid());
- X
- X prog = argv[0];
- X ident = getpid() & 0xFFFF;
- X
- X verbose_flag=1;
- X
- X opterr=0;
- X
- X while ((c = getopt(argc,argv,"edhqusavt:i:f:r:")) != EOF)
- X switch (c) {
- X case 't': if ( (timeout=atoi(optarg)) <0) usage(); break;
- X case 'f': filename= optarg; break;
- X case 'r': if ((retry=atoi(optarg))<0) usage(); break;
- X case 'i': if ((interval=atoi(optarg))<0) usage(); break;
- X case 'h': usage(); break;
- X case 'q': verbose_flag = 0; break;
- X case 'e': elapsed_flag = 1; break;
- X case 'd': dns_flag = 1; break;
- X case 's': stats_flag = 1; break;
- X case 'u': unreachable_flag = 1; break;
- X case 'a': alive_flag = 1; break;
- X case 'v':
- X printf("%s: $Revision: 1.20 $ $Date: 1993/02/23 00:16:38 $\n",argv[0]);
- X printf("%s: comments to schemers@Stanford.EDU\n",argv[0]);
- X exit(0);
- X default : fprintf(stderr,"Unknown flag: %s\n",argv[0]);
- X usage(); break;
- X }
- X
- X if (unreachable_flag && alive_flag) {
- X fprintf(stderr,"%s: specify only one of a,u\n",argv[0]);
- X usage();
- X }
- X
- X if ( (interval<10 || retry >20 || timeout <250) && getuid()) {
- X fprintf(stderr,"%s: these options are too risky for mere mortals.\n",prog);
- X fprintf(stderr,"%s: You need i >=10, retry < 20, and t >= 250\n",prog);
- X exit(3);
- X }
- X
- X if (alive_flag || unreachable_flag) verbose_flag=0;
- X
- X argv = &argv[optind];
- X if (*argv && filename) { usage(); }
- X if (!*argv && !filename) { filename = "-"; }
- X
- X if (*argv) while (*argv) {
- X add_host(*argv);
- X ++argv;
- X } else if (filename) {
- X FILE *ping_file;
- X char line[132];
- X char host[132],*p;
- X if (strcmp(filename,"-")==0) {
- X ping_file=fdopen(0,"r");
- X } else {
- X ping_file=fopen(filename,"r");
- X }
- X if (!ping_file) errno_crash_and_burn("fopen");
- X while(fgets(line,132,ping_file)) {
- X sscanf(line,"%s",host);
- X if ((!*host) || (host[0]=='#')) /* magic to avoid comments */
- X continue;
- X p=(char*)malloc(strlen(host)+1);
- X if (!p) crash_and_burn("can't malloc host");
- X strcpy(p,host);
- X add_host(p);
- X }
- X fclose(ping_file);
- X } else usage();
- X
- X if (!num_hosts) exit(2);
- X
- X /* allocate array to hold outstanding ping requests */
- X
- X table = (HOST_ENTRY **) malloc(sizeof(HOST_ENTRY *)*num_hosts);
- X if (!table) crash_and_burn("Can't malloc array of hosts");
- X
- X cursor=rrlist;
- X
- X for( num_waiting=0; num_waiting < num_hosts; num_waiting++ ) {
- X table[num_waiting]=cursor;
- X cursor->i = num_waiting;
- X cursor=cursor->next;
- X }
- X
- X gettimeofday(&start_time,&tz);
- X cursor=rrlist;
- X while (num_waiting) { /* while pings are outstanding */
- X if ( (timeval_diff(¤t_time,&cursor->last_time)> timeout) ||
- X cursor->num_packets_sent==0) {
- X if (cursor->num_packets_sent>0) num_timeout++;
- X if (cursor->num_packets_sent == retry+1) {
- X if(verbose_flag || unreachable_flag) {
- X if (dns_flag) printf("%s",
- X get_host_by_address(cursor->saddr.sin_addr));
- X else printf("%s",cursor->host);
- X if (verbose_flag) printf(" is unreachable");
- X printf("\n");
- X }
- X num_unreachable++;
- X remove_job(cursor);
- X } else send_ping(s,cursor);
- X }
- X while(wait_for_reply() && num_waiting) { /* call wfr until we timeout */
- X /* wait! */
- X }
- X gettimeofday(¤t_time,&tz);
- X if (cursor) cursor = cursor->next;
- X }
- X
- X gettimeofday(&end_time,&tz);
- X
- X if (stats_flag) {
- X fflush(stdout);
- X fprintf(stderr,"\n");
- X fprintf(stderr," %8d hosts\n",num_hosts);
- X fprintf(stderr," %8d alive\n",num_alive);
- X fprintf(stderr," %8d unreachable\n",num_unreachable);
- X fprintf(stderr," %8d unknown addresses\n",num_noaddress);
- X fprintf(stderr,"\n");
- X fprintf(stderr," %8d timeouts (waiting for response)\n",num_timeout);
- X fprintf(stderr," %8d pings sent\n",num_pingsent);
- X fprintf(stderr," %8d pings received\n",num_pingreceived);
- X fprintf(stderr,"\n");
- X
- Xif (total_replies==0) {
- X min_reply=0; max_reply=0; total_replies=1; sum_replies=0;
- X}
- X
- X fprintf(stderr," %8d msec (min round trip time)\n",min_reply);
- X fprintf(stderr," %8d msec (avg round trip time)\n",(int)sum_replies/total_replies);
- X fprintf(stderr," %8d msec (max round trip time)\n",max_reply);
- X fprintf(stderr," %8.3f sec (elapsed real time)\n",
- X timeval_diff( &end_time,&start_time)/1000.0);
- X fprintf(stderr,"\n");
- X
- X }
- X
- X if (num_noaddress) exit(2);
- X else if (num_alive != num_hosts) exit(1);
- X
- X exit(0);
- X
- X}
- X
- X
- X/*
- X *
- X * Compose and transmit an ICMP_ECHO REQUEST packet. The IP packet
- X * will be added on by the kernel. The ID field is our UNIX process ID,
- X * and the sequence number is an index into an array of outstanding
- X * ping requests. The sequence number will later be used to quickly
- X * figure out who the ping reply came from.
- X *
- X */
- X
- X#ifdef _NO_PROTO
- Xvoid send_ping(s,h)
- Xint s; HOST_ENTRY *h;
- X#else
- Xvoid send_ping(int s,HOST_ENTRY *h)
- X#endif
- X{
- X static char buffer[32];
- X struct icmp *icp = (struct icmp *) buffer;
- X int n,len;
- X
- X gettimeofday(&h->last_time,&tz);
- X
- X icp->icmp_type = ICMP_ECHO;
- X icp->icmp_code = 0;
- X icp->icmp_cksum = 0;
- X icp->icmp_seq = h->i;
- X icp->icmp_id = ident;
- X#define SIZE_ICMP_HDR 8
- X#define SIZE_PACK_SENT (sizeof(h->num_packets_sent))
- X#define SIZE_LAST_TIME (sizeof(h->last_time))
- X
- X bcopy(&h->last_time,&buffer[SIZE_ICMP_HDR],SIZE_LAST_TIME);
- X bcopy(&h->num_packets_sent,
- X &buffer[SIZE_ICMP_HDR+SIZE_LAST_TIME], SIZE_PACK_SENT);
- X
- X len = SIZE_ICMP_HDR+SIZE_LAST_TIME+SIZE_PACK_SENT;
- X
- X icp->icmp_cksum = in_cksum( (u_short *)icp, len );
- X
- X n = sendto( s, buffer, len, 0, (struct sockaddr *)&h->saddr,
- X sizeof(struct sockaddr_in) );
- X if( n < 0 || n != len ) {
- X if (verbose_flag || unreachable_flag) {
- X if (dns_flag) printf("%s",get_host_by_address(h->saddr.sin_addr));
- X else printf("%s",cursor->host);
- X if (verbose_flag) printf(" error while sending ping: %s\n",
- X sys_errlist[errno]);
- X printf("\n");
- X }
- X num_unreachable++;
- X remove_job(h);
- X } else {
- X h->num_packets_sent++;
- X num_pingsent++;
- X }
- X
- X}
- X
- X#ifdef _NO_PROTO
- Xint wait_for_reply()
- X#else
- Xint wait_for_reply()
- X#endif
- X{
- Xint result;
- Xstatic char buffer[4096];
- Xstruct sockaddr_in response_addr;
- Xstruct ip *ip;
- Xint hlen;
- Xstruct icmp *icp;
- Xint n;
- XHOST_ENTRY *h;
- X
- Xlong this_reply;
- Xint the_index;
- Xstruct timeval sent_time;
- X
- X
- X result=recvfrom_wto(s,buffer,4096,
- X (struct sockaddr *)&response_addr,interval);
- X
- X if (result<0) { return 0; } /* timeout */
- X
- X ip = (struct ip *) buffer;
- X hlen = ip->ip_hl << 2;
- X if (result < hlen+ICMP_MINLEN) { return(1); /* too short */ }
- X
- X icp = (struct icmp *)(buffer + hlen);
- X
- X if (
- X ( icp->icmp_type != ICMP_ECHOREPLY ) ||
- X ( icp->icmp_id != ident )
- X ) {
- X return 1; /* packet received, but not the one we are looking for! */
- X }
- X
- X num_pingreceived++;
- X
- X if ( ( icp->icmp_seq >= num_hosts ) ||
- X ( !table[icp->icmp_seq] ) ||
- X ( table[icp->icmp_seq]->saddr.sin_addr.s_addr
- X != response_addr.sin_addr.s_addr)) {
- X return 1; /* packet received, don't about it anymore */
- X }
- X
- X n=icp->icmp_seq;
- X h=table[n];
- X
- X gettimeofday(¤t_time,&tz);
- X bcopy(&icp->icmp_data[0],&sent_time,sizeof(sent_time));
- X bcopy(&icp->icmp_data[SIZE_LAST_TIME],&the_index, sizeof(the_index));
- X this_reply = timeval_diff(¤t_time,&sent_time);
- X if (this_reply>max_reply) max_reply=this_reply;
- X if (this_reply<min_reply) min_reply=this_reply;
- X sum_replies += this_reply;
- X total_replies++;
- X
- X if(verbose_flag||alive_flag) {
- X if (dns_flag) printf("%s",get_host_by_address(response_addr.sin_addr));
- X else printf("%s",h->host);
- X if (verbose_flag) printf(" is alive");
- X if (elapsed_flag) printf(" (%d msec)",this_reply);
- X printf("\n");
- X }
- X num_alive++;
- X remove_job(h); /* remove job */
- X return num_waiting;
- X}
- X
- X/*
- X * Checksum routine for Internet Protocol family headers (C Version)
- X * From ping examples in W.Richard Stevens "UNIX NETWORK PROGRAMMING" book.
- X */
- X
- X#ifdef _NO_PROTO
- Xint in_cksum(p,n)
- Xu_short *p; int n;
- X#else
- Xint in_cksum(u_short *p, int n)
- X#endif
- X{
- X register u_short answer;
- X register long sum = 0;
- X u_short odd_byte = 0;
- X
- X while( n > 1 ) { sum += *p++; n -= 2; }
- X
- X /* mop up an odd byte, if necessary */
- X if( n == 1 ) {
- X *(u_char *)(&odd_byte) = *(u_char *)p;
- X sum += odd_byte;
- X }
- X
- X sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
- X sum += (sum >> 16); /* add carry */
- X answer = ~sum; /* ones-complement, truncate*/
- X return (answer);
- X}
- X
- X
- X/* add host to linked list of hosts to be pinged */
- X/* assume memory for *host is ours!!! */
- X
- X#ifdef _NO_PROTO
- Xvoid add_host(host)
- Xchar *host;
- X#else
- Xvoid add_host(char *host)
- X#endif
- X{
- X HOST_ENTRY *p;
- X struct hostent *host_ent;
- X struct in_addr *host_add;
- X
- X u_long ipaddress = inet_addr(host);
- X
- X if ( (ipaddress == -1) &&
- X ( ((host_ent=gethostbyname(host)) == 0) ||
- X ((host_add = (struct in_addr *) *(host_ent->h_addr_list))==0))
- X ) {
- X if (verbose_flag) fprintf(stderr,"%s address not found\n",host);
- X num_noaddress++;
- X return;
- X }
- X
- X p = (HOST_ENTRY *) malloc(sizeof(HOST_ENTRY));
- X if (!p) crash_and_burn("can't allocate HOST_ENTRY");
- X
- X p->host=host;
- X p->num_packets_sent = 0;
- X p->last_time.tv_sec =0;
- X p->last_time.tv_usec =0;
- X
- X bzero((char*) &p->saddr, sizeof(p->saddr));
- X p->saddr.sin_family = AF_INET;
- X
- X if (ipaddress==-1) p->saddr.sin_addr = *host_add;
- X else p->saddr.sin_addr.s_addr = ipaddress;
- X
- X if (!rrlist) {
- X rrlist = p;
- X p->next = p;
- X p->prev = p;
- X } else {
- X p->next = rrlist;
- X p->prev = rrlist->prev;
- X p->prev->next = p;
- X p->next->prev = p;
- X rrlist = p;
- X }
- X num_hosts++;
- X}
- X
- X#ifdef _NO_PROTO
- Xvoid remove_job(h)
- XHOST_ENTRY *h;
- X#else
- Xvoid remove_job(HOST_ENTRY *h)
- X#endif
- X{
- X
- X table[h->i]=NULL;
- X --num_waiting;
- X
- X if (num_waiting) { /* remove us from list of jobs */
- X h->prev->next = h->next;
- X h->next->prev = h->prev;
- X if (h==cursor) { cursor = h-> next; }
- X } else {
- X cursor=NULL;
- X rrlist=NULL;
- X }
- X
- X}
- X
- X#ifdef _NO_PROTO
- Xchar *get_host_by_address(in)
- Xstruct in_addr in;
- X#else
- Xchar *get_host_by_address(struct in_addr in)
- X#endif
- X{
- X struct hostent *h;
- X h=gethostbyaddr((char *) &in,sizeof(struct in_addr),AF_INET);
- X if (h==NULL || h->h_name==NULL) return inet_ntoa(in);
- X else return h->h_name;
- X}
- X
- X
- X#ifdef _NO_PROTO
- Xvoid crash_and_burn(message)
- Xchar *message;
- X#else
- Xvoid crash_and_burn(char *message)
- X#endif
- X{
- X if (verbose_flag) fprintf(stderr,"%s: %s\n",prog,message);
- X exit(4);
- X}
- X
- X#ifdef _NO_PROTO
- Xvoid errno_crash_and_burn(message)
- Xchar *message;
- X#else
- Xvoid errno_crash_and_burn(char *message)
- X#endif
- X{
- X if (verbose_flag)
- X fprintf(stderr,"%s: %s : %s\n",prog,message,sys_errlist[errno]);
- X exit(4);
- X}
- X
- X#ifdef _NO_PROTO
- Xlong timeval_diff(a,b)
- Xstruct timeval *a,*b;
- X#else
- Xlong timeval_diff(struct timeval *a,struct timeval *b)
- X#endif
- X{
- Xdouble temp;
- X
- Xtemp =
- X (((a->tv_sec*1000000)+ a->tv_usec) -
- X ((b->tv_sec*1000000)+ b->tv_usec))/1000;
- X
- Xreturn (long) temp;
- X
- X}
- X
- X/*
- X * recvfrom_wto: receive with timeout
- X * returns length of data read or -1 if timeout
- X * crash_and_burn on any other errrors
- X *
- X */
- X
- X
- X#ifdef _NO_PROTO
- Xint recvfrom_wto (s,buf,len, saddr, timo)
- Xint s; char *buf; int len; struct sockaddr *saddr; int timo;
- X#else
- Xint recvfrom_wto (int s, char *buf, int len, struct sockaddr *saddr, int timo)
- X#endif
- X{
- X int nfound,slen,n;
- X struct timeval to;
- X fd_set readset,writeset;
- X
- X to.tv_sec = timo/1000;
- X to.tv_usec = (timo - (to.tv_sec*1000))*1000;
- X
- X FD_ZERO(&readset);
- X FD_ZERO(&writeset);
- X FD_SET(s,&readset);
- X nfound = select(s+1,&readset,&writeset,NULL,&to);
- X if (nfound<0) errno_crash_and_burn("select");
- X if (nfound==0) return -1; /* timeout */
- X slen=sizeof(struct sockaddr);
- X n=recvfrom(s,buf,len,0,saddr,&slen);
- X if (n<0) errno_crash_and_burn("recvfrom");
- X return n;
- X}
- X
- X#ifdef _NO_PROTO
- Xvoid usage()
- X#else
- Xvoid usage()
- X#endif
- X{
- X fprintf(stderr,"\n");
- X fprintf(stderr,"Usage: %s [options] [systems...]\n",prog);
- X fprintf(stderr," -a show systems that are alive\n");
- X fprintf(stderr," -d use dns to lookup address for return ping packet\n");
- X fprintf(stderr," -e show elapsed time on return packets\n");
- X fprintf(stderr," -f file read list of systems from a file ( - means stdin)\n");
- X fprintf(stderr," -i n interval (between ping packets) in milliseconds (default %d)\n",interval);
- X fprintf(stderr," -q quiet (don't show per host results)\n");
- X fprintf(stderr," -r n retry limit (default %d)\n",retry);
- X fprintf(stderr," -s dump final stats\n");
- X fprintf(stderr," -t n individual host timeout in milliseconds (default %d)\n",timeout);
- X fprintf(stderr," -u show systems that are unreachable\n");
- X fprintf(stderr," -v show version\n");
- X fprintf(stderr," systems list of systems to check (if no -f specified)\n");
- X fprintf(stderr,"\n");
- X exit(3);
- X}
- END_OF_FILE
- if test 23070 -ne `wc -c <'fping.c'`; then
- echo shar: \"'fping.c'\" unpacked with wrong size!
- fi
- # end of 'fping.c'
- fi
- if test -f 'fping.man' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'fping.man'\"
- else
- echo shar: Extracting \"'fping.man'\" \(3896 characters\)
- sed "s/^X//" >'fping.man' <<'END_OF_FILE'
- X.TH fping l
- X.SH NAME
- Xfping \- send ICMP ECHO_REQUEST packets to network hosts
- X.SH SYNOPSIS
- X.B fping
- X[ \fIoptions\fR ]
- X[ \fIsystems...\fR ]
- X
- X.SH DESCRIPTION
- X.NXR "fping command"
- X.NXR "ICMP ECHO_REQUEST"
- X
- X
- X.B fping
- Xis a
- X.MS ping 8
- Xlike program which uses the Internet Control
- XMessage Protocol (ICMP) echo request to determine if a host is
- Xup.
- X.B fping
- Xis different from ping in that you can specify any
- Xnumber of hosts on the command line, or specify a file containing
- Xthe lists of hosts to ping. Instead of trying one host until it
- Xtimeouts or replies,
- X.B fping
- Xwill send out a ping packet and move
- Xon to the next host in a round-robin fashion. If a host replies,
- Xit is noted and removed from the list of hosts to check. If a host
- Xdoes not respond within a certain time limit and/or retry limit it
- Xwill be considered unreachable.
- X.PP
- XUnlike
- X.MS ping 8
- X,
- X.B fping
- Xis meant to be used in scripts and its output is easy to parse.
- X.SH OPTIONS
- X.IP \fB-a\fR 5
- XShow systems that are alive.
- X.IP \fB-d\fR 5
- XUse DNS to lookup address of return ping packet. This allows you to give
- Xfping a list of IP addresses as input and print hostnames in the output.
- X.IP \fB-e\fR 5
- XShow elapsed (round-trip) time of packets
- X.IP \fB-f\fR 5
- XRead list of system from a file.
- X.IP \fB-i\fIn\fR 5
- XThe minimum amount of time (in milliseconds) between sending a ping packet to any host (default is 25).
- X.IP \fB-q\fR 5
- XQuiet. Don't show per host results, just set final exit status.
- X.IP \fB-r\fIn\fR 5
- XRetry limit (default 3). This is the number of times an attempt at pinging
- Xa host will be made, not including the first try.
- X.IP \fB-s\fR 5
- XDump final statistics.
- X.IP \fB-t\fIn\fR 5
- XIndividual host timeout in milliseconds (default 2500). This is the
- Xminimum number of milliseconds between ping packets directed towards a given
- Xhost.
- X.IP \fB-u\fR 5
- XShow systems that are unreachable.
- X.B fping
- Xa list of IP addresses as input and have the results printed as hostnames.
- X.SH EXAMPLES
- XThe following perl script will check a list of hosts and send mail if
- Xany are unreachable. It uses the open2 function which allows a program
- Xto be opened for reading and writing. fping does not start pinging the
- Xlist of systems until it reads EOF, which it gets after INPUT is closed.
- XSure the open2 usage is not need in this example, but its a good open2
- Xexample none the less.
- X.nf
- X
- X#!/usr/local/bin/perl
- Xrequire 'open2.pl';
- X
- X$MAILTO = "root";
- X
- X$pid = &open2("OUTPUT","INPUT","/usr/local/bin/fping -u");
- X
- X@check=("slapshot","foo","foobar");
- X
- Xforeach(@check) { print INPUT "$_\\n"; }
- Xclose(INPUT);
- X@output=<OUTPUT>;
- X
- Xif ($#output != -1) {
- X chop($date=`date`);
- X open(MAIL,"|mail -s 'unreachable systems' $MAILTO");
- X print MAIL "\\nThe following systems are unreachable as of: $date\\n\\n";
- X print MAIL @output;
- X close MAIL;
- X}
- X
- X.ni
- XAnother good example is when you want to perform an action only on hosts
- Xthat are currently reachable.
- X.nf
- X
- X#!/usr/local/bin/perl
- X
- X$hosts_to_backup = `cat /etc/hosts.backup | fping -a`;
- X
- Xforeach $host (split(/\\n/,$hosts_to_backup)) {
- X # do it
- X}
- X
- X.ni
- X
- X.SH AUTHOR
- XRoland J. Schemers III, Stanford University
- X.SH DIAGNOSTICS
- XExit status is 0 if all the hosts are reachable, 1 if some hosts were
- Xunreachable, 2 if any IP addresses were not found, 3 for invalid
- Xcommand line arguments, and 4 for a system call failure.
- X.SH BUGS
- XHa! If there were any I knew of I would have fixed them!
- X.SH RESTRICTIONS
- XIf certain options are used (i.e, a low value for -i and -t, and a
- Xhigh value for -r) it is possible to flood the network. This program
- Xmust be installed as setuid root in order to open up a raw socket,
- Xor must be run by root. In order to stop mere mortals from hosing the
- Xnetwork (when fping is installed setuid root) , normal users can't specify
- Xthe following:
- X.nf
- X
- X -i n where n < 10 msec
- X -r n where n > 20
- X -t n where n < 250 msec
- X
- X.ni
- X.SH SEE ALSO
- Xnetstat(1), ping(8), ifconfig(8c)
- X
- END_OF_FILE
- if test 3896 -ne `wc -c <'fping.man'`; then
- echo shar: \"'fping.man'\" unpacked with wrong size!
- fi
- # end of 'fping.man'
- fi
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(1077 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- X
- XPROG= fping
- XOBJS= fping.o
- XSRC= fping.c
- XBIN= /usr/local/bin
- XMAN= /usr/man/manl
- XMANSRC= fping.man
- XMANDST= fping.l
- X
- X#
- X# Interval is the minimum amount of time between sending a ping packet to
- X# any host.
- X#
- X# Timeout is the minimum amount of time between sending a ping packet to
- X# a particular host.
- X#
- X# Retry is the number of ping packets to send to a host before giving up.
- X#
- X
- XDEFAULTS= -DDEFAULT_INTERVAL=25 \
- X -DDEFAULT_TIMEOUT=2500 \
- X -DDEFAULT_RETRY=3
- X#
- X# some systems need the following:
- X#
- X#LIBS= -lsocket
- X
- XLIBS=
- X
- Xall: $(PROG)
- X
- X$(PROG) : $(OBJS)
- X $(CC) $(OBJS) -o $(PROG) $(LIBS)
- X
- X$(OBJS) : $(SRC)
- X $(CC) $(CFLAGS) -c $(DEFAULTS) $(SRC)
- X
- X# if you don't have install type:
- X# cp $(PROG) /usr/local/bin
- X# chown root /usr/local/bin/$(PROG)
- X# chmod 4555 /usr/local/bin/$(PROG)
- X# strip /usr/local/bin/$(PROG)
- X#
- X
- Xinstall:
- X install -c -m 4555 -o root -s $(PROG) $(BIN)/$(PROG)
- X install -c -m 0444 -o root $(MANSRC) $(MAN)/$(MANDST)
- X
- Xclean:
- X rm -f a.out core *~ *.o $(PROG)
- X
- Xshar:
- X shar README CHANGES fping.c fping.man Makefile README.VMS > fping.shar
- END_OF_FILE
- if test 1077 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'README.VMS' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README.VMS'\"
- else
- echo shar: Extracting \"'README.VMS'\" \(5510 characters\)
- sed "s/^X//" >'README.VMS' <<'END_OF_FILE'
- XFrom <@jessica.stanford.edu:IVERSEN@VSFYS1.FI.UIB.NO> Mon Jul 27 08:54:26 1992
- XReceived: from Argus.Stanford.EDU by jessica.stanford.edu (5.59/25-eef) id AA28695; Mon, 27 Jul 92 08:54:22 PDT
- XReceived: from vsfys1.fi.uib.no by Argus.Stanford.EDU (5.65/inc-1.0)
- X id AA28942; Mon, 27 Jul 92 08:54:19 -0700
- XDate: Mon, 27 Jul 1992 17:54:17 +0200
- XFrom: IVERSEN@VSFYS1.FI.UIB.NO (Per Steinar Iversen, Dept. of Physics, Univ. of Bergen, Norway, phone +47-5-212770)
- XMessage-Id: <920727175417.21e004ce@VSFYS1.FI.UIB.NO>
- XSubject: FPING under VMS
- XTo: schemers@Stanford.EDU
- XX-Vmsmail-To: SMTP%"schemers@Stanford.EDU"
- XStatus: OR
- X
- XHello,
- X
- XI rather liked your recently posted fping, and I decided to port it to VMS,
- Xunder MultiNet TCP/IP 3.0H and VAXC 3.2. Only some very minor modifications are
- Xnecessary to run it under VMS 5.5:
- X
- X1) The 2 following lines must be put onto one single line, otherwise VAXC
- Xcomplains:
- X
- X#if !__STDC__ && !defined(__cplusplus) && !defined(FUNCPROTO) \
- X && !defined(_POSIX_SOURCE)
- X
- Xgoes to:
- X
- X#if !__STDC__ && !defined(__cplusplus) && !defined(FUNCPROTO) && !defined(_POSIX_SOURCE)
- X
- X2) The single following line must be changed:
- X
- Xextern char *sys_errlist[];
- X
- Xto:
- X
- X#ifndef VMS
- Xextern char *sys_errlist[];
- X#else
- Xextern noshare char *sys_errlist[];
- X#endif
- X
- X3) VMS runs privileged programs in a different manner from UNIX. geteuid is
- X"supported" by VAXC but the result is not really meaningful.
- X
- XThese lines are thus Unix specific:
- X
- X /* check if we are root */
- X
- X#ifndef VMS
- X if (geteuid()) {
- X fprintf(stderr,
- X "This program can only be run by root, or it must be setuid root.\n");
- X exit(3);
- X }
- X#endif
- X
- X4) VAXC does not support getopt. I got my copies of getopt, index and rindex
- Xfrom a fileserver with bsd-sources, using anonymous FTP. These routines
- Xcompiled without complaints and works fine under VAXC 3.2 at least.
- X
- X5) The VMS concept of exit codes is different from the Unix version. After some
- Xthought I decided to short circuit the VAXC attempt of translating the Unix
- Xreturn codes into VMS style return codes. My version of FPING always returns
- X"exit(1)", which is VMS success. However the FPING status codes are put into a
- XVMS symbol, FPING_STATUS. It is thus very easy to use the FPING return status
- Xcodes for further action if needed.
- X
- XThe line at the end of main in FPING, "return 0;", must be changed to
- X"exit(0);" for VMS, this should be OK for Unix too?
- X
- XA small routine is needed to handle the translation, it will probably not
- Xget any rewards for nice C-code (I usually program in Fortran), and it was
- Xlargely created by copying an example from the VAXC manuals:
- X
- X/* VMS-EXIT.C */
- X#include <ssdef>
- X#include <stdio>
- X#include <descrip>
- X
- Xint LIB$SET_SYMBOL();
- X
- Xvms_exit (ecode)
- Xint ecode;
- X{
- X int status = 1;
- X static $DESCRIPTOR(fping_name, "FPING_STATUS");
- X static $DESCRIPTOR(fping_exit_0,"0");
- X static $DESCRIPTOR(fping_exit_1,"1");
- X static $DESCRIPTOR(fping_exit_2,"2");
- X static $DESCRIPTOR(fping_exit_3,"3");
- X static $DESCRIPTOR(fping_exit_4,"4");
- X static $DESCRIPTOR(fping_exit_5,"5");
- X
- X switch(ecode) {
- X case 0 :
- X status = LIB$SET_SYMBOL(&fping_name,&fping_exit_0);
- X break;
- X case 1 :
- X status = LIB$SET_SYMBOL(&fping_name,&fping_exit_1);
- X break;
- X case 2 :
- X status = LIB$SET_SYMBOL(&fping_name,&fping_exit_2);
- X break;
- X case 3 :
- X status = LIB$SET_SYMBOL(&fping_name,&fping_exit_3);
- X break;
- X case 4 :
- X status = LIB$SET_SYMBOL(&fping_name,&fping_exit_4);
- X break;
- X default:
- X status = LIB$SET_SYMBOL(&fping_name,&fping_exit_5);
- X break;
- X }
- X
- X exit(1);
- X
- X}
- X
- X
- X6) The following command file (script) was used to compile and link under VMS:
- X
- X$! VMS-CC-MAKE.COM
- X$!
- X$! This compile+link procedure has been tested with VAXC 3.2 and
- X$! MultiNet 3.0H.
- X$!
- X$! NOTE: getopt, index, and rindex are not part of VAXC, however the BSD
- X$! versions works fine. They should be available by anonymous FTP
- X$! from a number of fileservers.
- X$!
- X$ define/user arpa multinet_root:[multinet.include.arpa]
- X$ define/user netinet multinet_root:[multinet.include.netinet]
- X$ define/user sys multinet_root:[multinet.include.sys],sys$library
- X$ cc /nolist /define="exit=vms_exit" fping.c
- X$ cc /nolist vms-exit.c
- X$ cc /nolist getopt.c
- X$ cc /nolist index.c
- X$ cc /nolist rindex.c
- X$ link /nomap/notrace fping,vms-exit,getopt,index,rindex,sys$input/opt
- Xmultinet:multinet_socket_library/share
- Xsys$share:vaxcrtl/share
- X$ delete fping.obj.*,vms-exit.obj.*,getopt.obj.*,index.obj.*,rindex.obj.*
- X$ purge fping.exe
- X$ fping :== $'f$environment("default")'fping
- X
- X7) Piping files into fping is not available under VMS, but the "f" option does
- Xthe same job.
- X
- X8) fping must be installed with privileges if it is to be used by
- Xnon-privileged users under VMS.
- X
- XThe question then is, does it work? Well, as far I can see the answer is yes!
- XHere are some examples of output:
- X
- X$ fping xxx
- Xxxx address not found
- X$ show symbol fping_status
- X FPING_STATUS = "2"
- X$ fping vxcrna.cern.ch
- Xvxcrna.cern.ch is alive
- X$ show symbol fping_status
- X FPING_STATUS = "0"
- X$ fping -de vxcrna.cern.ch
- Xvxcrna.cern.ch is alive (320 msec)
- X$ show symbol fping_status
- X FPING_STATUS = "0"
- X$ fping -v
- Xvsfys5$dkb100:[scratch.iversen]fping.exe;7: $Revision: 1.17 $ $Date: 1992/07/23 03:29:42 $
- Xvsfys5$dkb100:[scratch.iversen]fping.exe;7: comments to schemers@Stanford.EDU
- X
- XRegards, Per (iversen@vsfys1.fi.uib.no)
- X
- END_OF_FILE
- if test 5510 -ne `wc -c <'README.VMS'`; then
- echo shar: \"'README.VMS'\" unpacked with wrong size!
- fi
- # end of 'README.VMS'
- fi
- echo shar: End of shell archive.
- exit 0
-