ping_common.h revision 0baa1aef81c61170e9078704b28264d9e8864b69
121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <stdio.h>
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <stdlib.h>
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <unistd.h>
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <time.h>
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/param.h>
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/socket.h>
721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <linux/sockios.h>
8201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include <sys/file.h>
921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <sys/time.h>
1021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <signal.h>
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/ioctl.h>
12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <net/if.h>
13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/uio.h>
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/poll.h>
1521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <ctype.h>
1621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <errno.h>
1721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <string.h>
1821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <netdb.h>
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <netinet/in.h>
2121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <arpa/inet.h>
2221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <linux/errqueue.h>
2321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
2421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define	DEFDATALEN	(64 - 8)	/* default data length */
2521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
2621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define	MAXWAIT		10		/* max seconds to wait for response */
2721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define MININTERVAL	10		/* Minimal interpacket gap */
2821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define MINUSERINTERVAL	200		/* Minimal allowed interval for non-root */
2921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
3021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define SCHINT(a)	(((a) <= MININTERVAL) ? MININTERVAL : (a))
3121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
3221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define	A(bit)		rcvd_tbl[(bit)>>3]	/* identify byte in array */
3321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define	B(bit)		(1 << ((bit) & 0x07))	/* identify bit in byte */
3421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define	SET(bit)	(A(bit) |= B(bit))
3521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define	CLR(bit)	(A(bit) &= (~B(bit)))
3621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define	TST(bit)	(A(bit) & B(bit))
3721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
3821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen/* various options */
3921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern int options;
4021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define	F_FLOOD		0x001
4121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define	F_INTERVAL	0x002
4221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define	F_NUMERIC	0x004
4321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define	F_PINGFILLED	0x008
4421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define	F_QUIET		0x010
4521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define	F_RROUTE	0x020
4621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define	F_SO_DEBUG	0x040
4721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define	F_SO_DONTROUTE	0x080
4821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define	F_VERBOSE	0x100
4921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define	F_TIMESTAMP	0x200
5021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define	F_FLOWINFO	0x200
5121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define	F_SOURCEROUTE	0x400
5221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define	F_TCLASS	0x400
5321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define	F_FLOOD_POLL	0x800
5421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define	F_LATENCY	0x1000
5521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define	F_AUDIBLE	0x2000
5621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define	F_ADAPTIVE	0x4000
5721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define	F_STRICTSOURCE	0x8000
5821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define F_NOLOOP	0x10000
5921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define F_TTL		0x20000
6021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
6121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen/*
6221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen * MAX_DUP_CHK is the number of bits in received table, i.e. the maximum
6321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen * number of received sequence numbers we can keep track of.
6421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen */
6521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define	MAX_DUP_CHK	0x10000
6621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern int mx_dup_ck;
6721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern char rcvd_tbl[MAX_DUP_CHK / 8];
6821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
6921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
7021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern u_char outpack[];
7121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern int maxpacket;
7221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
7321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern int datalen;
7421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern char *hostname;
7521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern int uid;
7621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern int ident;			/* process id to identify our packets */
7721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
7821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern int sndbuf;
7921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern int ttl;
8021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
8121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern long npackets;			/* max packets to transmit */
8221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern long nreceived;			/* # of packets we got back */
8321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern long nrepeats;			/* number of duplicates */
8421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern long ntransmitted;		/* sequence # for outbound packets = #sent */
8521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern long nchecksum;			/* replies with bad checksum */
8621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern long nerrors;			/* icmp errors */
8721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern int interval;			/* interval between packets (msec) */
8821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern int preload;
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottextern int deadline;			/* time to die */
9021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern int lingertime;
9121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern struct timeval start_time, cur_time;
9221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern volatile int exiting;
9321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern volatile int status_snapshot;
9421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern int confirm;
9521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern int confirm_flag;
9621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern int working_recverr;
9721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
9821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#ifndef MSG_CONFIRM
9921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define MSG_CONFIRM 0
10021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#endif
10121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
10221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
10321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen/* timing */
10421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern int timing;			/* flag to do timing */
10521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern long tmin;			/* minimum round trip time */
10621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern long tmax;			/* maximum round trip time */
10721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern long long tsum;			/* sum of all times, for doing average */
10821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern long long tsum2;
10921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern int rtt;
11021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern __u16 acked;
11121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern int pipesize;
11221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
11321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define COMMON_OPTIONS \
11421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsencase 'a': case 'U': case 'c': case 'd': \
11521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsencase 'f': case 'i': case 'w': case 'l': \
11621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsencase 'S': case 'n': case 'p': case 'q': \
11721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsencase 'r': case 's': case 'v': case 'L': \
11821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsencase 't': case 'A': case 'W': case 'B':
11921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
12021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define COMMON_OPTSTR "h?VQ:I:M:aUc:dfi:w:l:S:np:qrs:vLt:AW:B"
12121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
12221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
12321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen/*
12421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen * tvsub --
12521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen *	Subtract 2 timeval structs:  out = out - in.  Out is assumed to
12621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen * be >= in.
127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */
128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic inline void tvsub(struct timeval *out, struct timeval *in)
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
13021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen	if ((out->tv_usec -= in->tv_usec) < 0) {
13121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen		--out->tv_sec;
13221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen		out->tv_usec += 1000000;
13321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen	}
13421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen	out->tv_sec -= in->tv_sec;
13521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
13621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
13721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenstatic inline void set_signal(int signo, void (*handler)(int))
13821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen{
13921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen	struct sigaction sa;
14021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
14121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen	memset(&sa, 0, sizeof(sa));
142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	sa.sa_handler = (void (*)(int))handler;
14421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#ifdef SA_INTERRUPT
14521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen	sa.sa_flags = SA_INTERRUPT;
14621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#endif
14721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen	sigaction(signo, &sa, NULL);
14821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
14921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
15021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern int __schedule_exit(int next);
15121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
15221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenstatic inline int schedule_exit(int next)
15321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen{
15421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen	if (npackets && ntransmitted >= npackets && !deadline)
15521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen		next = __schedule_exit(next);
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	return next;
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic inline int in_flight(void)
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	__u16 diff = (__u16)ntransmitted - acked;
162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	return (diff<=0x7FFF) ? diff : ntransmitted-nreceived-nerrors;
163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic inline void acknowledge(__u16 seq)
16621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen{
16721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen	__u16 diff = (__u16)ntransmitted - seq;
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (diff <= 0x7FFF) {
16921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen		if ((int)diff+1 > pipesize)
17021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen			pipesize = (int)diff+1;
17121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen		if ((__s16)(seq - acked) > 0 ||
17221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen		    (__u16)ntransmitted - acked > 0x7FFF)
17321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen			acked = seq;
17421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen	}
17521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
17621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
17721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenstatic inline void advance_ntransmitted(void)
17821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen{
17921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen	ntransmitted++;
18021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen	/* Invalidate acked, if 16 bit seq overflows. */
18121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen	if ((__u16)ntransmitted - acked > 0x7FFF)
182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		acked = (__u16)ntransmitted + 1;
18321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
18621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern int send_probe(void);
18721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern int receive_error_msg(void);
18821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern int parse_reply(struct msghdr *msg, int len, void *addr, struct timeval *);
18921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern void install_filter(void);
19021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
19121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern int pinger(void);
19221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern void sock_setbufs(int icmp_sock, int alloc);
19321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern void setup(int icmp_sock);
19421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern void main_loop(int icmp_sock, __u8 *buf, int buflen) __attribute__((noreturn));
19521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern void finish(void) __attribute__((noreturn));
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottextern void status(void);
19721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern void common_options(int ch);
19821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenextern int gather_statistics(__u8 *ptr, int cc, __u16 seq, int hops,
19921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen			     int csfailed, struct timeval *tv, char *from);
20021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen