6
#include <sys/socket.h>
7
#include <linux/sockios.h>
10
#include <sys/signal.h>
11
#include <sys/ioctl.h>
20
#include <netinet/in.h>
21
#include <arpa/inet.h>
22
#include <linux/errqueue.h>
26
#define DEFDATALEN (64 - 8) /* default data length */
28
#define MAXWAIT 10 /* max seconds to wait for response */
29
#define MININTERVAL 10 /* Minimal interpacket gap */
30
#define MINUSERINTERVAL 200 /* Minimal allowed interval for non-root */
32
#define SCHINT(a) (((a) <= MININTERVAL) ? MININTERVAL : (a))
34
#define A(bit) rcvd_tbl[(bit)>>3] /* identify byte in array */
35
#define B(bit) (1 << ((bit) & 0x07)) /* identify bit in byte */
36
#define SET(bit) (A(bit) |= B(bit))
37
#define CLR(bit) (A(bit) &= (~B(bit)))
38
#define TST(bit) (A(bit) & B(bit))
43
#define F_INTERVAL 0x002
44
#define F_NUMERIC 0x004
45
#define F_PINGFILLED 0x008
47
#define F_RROUTE 0x020
48
#define F_SO_DEBUG 0x040
49
#define F_SO_DONTROUTE 0x080
50
#define F_VERBOSE 0x100
51
#define F_TIMESTAMP 0x200
52
#define F_FLOWINFO 0x200
53
#define F_SOURCEROUTE 0x400
54
#define F_TCLASS 0x400
55
#define F_FLOOD_POLL 0x800
56
#define F_LATENCY 0x1000
57
#define F_AUDIBLE 0x2000
58
#define F_ADAPTIVE 0x4000
60
/* multicast options */
62
#define MULTICAST_NOLOOP 0x001
63
#define MULTICAST_TTL 0x002
64
#define MULTICAST_IF 0x004
67
* MAX_DUP_CHK is the number of bits in received table, i.e. the maximum
68
* number of received sequence numbers we can keep track of. Change 128
69
* to 8192 for complete accuracy...
71
#define MAX_DUP_CHK 0x10000
73
extern char rcvd_tbl[MAX_DUP_CHK / 8];
76
extern u_char outpack[];
80
extern char *hostname;
82
extern int ident; /* process id to identify our packets */
87
extern long npackets; /* max packets to transmit */
88
extern long nreceived; /* # of packets we got back */
89
extern long nrepeats; /* number of duplicates */
90
extern long ntransmitted; /* sequence # for outbound packets = #sent */
91
extern long nchecksum; /* replies with bad checksum */
92
extern long nerrors; /* icmp errors */
93
extern int interval; /* interval between packets (msec) */
95
extern int deadline; /* time to die */
96
extern struct timeval start_time, cur_time;
97
extern volatile int exiting;
98
extern volatile int status_snapshot;
100
extern int confirm_flag;
101
extern int working_recverr;
104
#define MSG_CONFIRM 0
109
extern int timing; /* flag to do timing */
110
extern long tmin; /* minimum round trip time */
111
extern long tmax; /* maximum round trip time */
112
extern long long tsum; /* sum of all times, for doing average */
113
extern long long tsum2;
118
#define COMMON_OPTIONS \
119
case 'a': case 'U': case 'c': case 'd': \
120
case 'f': case 'i': case 'w': case 'l': \
121
case 'S': case 'n': case 'p': case 'q': \
122
case 'r': case 's': case 'v': case 'L': \
125
#define COMMON_OPTSTR "h?VQ:I:M:aUc:dfi:w:l:S:np:qrs:vLt:A"
130
* Subtract 2 timeval structs: out = out - in. Out is assumed to
133
static inline void tvsub(struct timeval *out, struct timeval *in)
135
if ((out->tv_usec -= in->tv_usec) < 0) {
137
out->tv_usec += 1000000;
139
out->tv_sec -= in->tv_sec;
142
static inline void set_signal(int signo, void (*handler)(int))
146
memset(&sa, 0, sizeof(sa));
148
sa.sa_handler = (void (*)(int))handler;
150
sa.sa_flags = SA_INTERRUPT;
152
sigaction(signo, &sa, NULL);
155
extern int __schedule_exit(int next);
157
static inline int schedule_exit(int next)
159
if (npackets && ntransmitted >= npackets && !deadline)
160
next = __schedule_exit(next);
164
static inline int in_flight(void)
166
__u16 diff = (__u16)ntransmitted - acked;
167
return (diff<=0x7FFF) ? diff : ntransmitted-nreceived-nerrors;
170
static inline void acknowledge(__u16 seq)
172
__u16 diff = (__u16)ntransmitted - seq;
173
if (diff <= 0x7FFF) {
174
if ((int)diff+1 > pipesize)
175
pipesize = (int)diff+1;
176
if ((__s16)(seq - acked) > 0 ||
177
(__u16)ntransmitted - acked > 0x7FFF)
182
static inline void advance_ntransmitted(void)
185
/* Invalidate acked, if 16 bit seq overflows. */
186
if ((__u16)ntransmitted - acked > 0x7FFF)
187
acked = (__u16)ntransmitted + 1;
191
extern int send_probe(void);
192
extern int receive_error_msg(void);
193
extern int parse_reply(struct msghdr *msg, int len, void *addr, struct timeval *);
194
extern void install_filter(void);
196
extern int pinger(void);
197
extern void sock_setbufs(int icmp_sock, int alloc);
198
extern void setup(int icmp_sock);
199
extern void main_loop(int icmp_sock, __u8 *buf, int buflen) __attribute__((noreturn));
200
extern void finish(void) __attribute__((noreturn));
201
extern void status(void);
202
extern void common_options(int ch);
203
extern int gather_statistics(__u8 *ptr, int cc, __u16 seq, int hops,
204
int csfailed, struct timeval *tv, char *from);