1313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <stdio.h>
2313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <stdlib.h>
3313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <unistd.h>
4313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <time.h>
5313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/param.h>
6313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/socket.h>
7313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <linux/sockios.h>
8313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/file.h>
9313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/time.h>
10313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/signal.h>
11313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/ioctl.h>
12313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <net/if.h>
13313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/uio.h>
14313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/poll.h>
15313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <ctype.h>
16313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <errno.h>
17313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <string.h>
18313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <netdb.h>
19313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <setjmp.h>
20313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
21313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifdef CAPABILITIES
22313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/prctl.h>
23313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/capability.h>
24313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
25313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
26313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifdef USE_IDN
27313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <locale.h>
28313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <idna.h>
29313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
30313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
31313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <netinet/in.h>
32313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <arpa/inet.h>
33313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <linux/types.h>
34313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <linux/errqueue.h>
35313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
365df1daf326001b8d7d91a8b726ded17e09309952Lorenzo Colitti#ifdef ANDROID
375df1daf326001b8d7d91a8b726ded17e09309952Lorenzo Colitti#include <linux/icmp.h>
38924a10d5d9645d4e82fa4b9781f2d85b41ec74f1Lorenzo Colitti#include <sys/auxv.h>
395df1daf326001b8d7d91a8b726ded17e09309952Lorenzo Colitti#endif
405df1daf326001b8d7d91a8b726ded17e09309952Lorenzo Colitti
41313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include "SNAPSHOT.h"
42313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
43313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define	DEFDATALEN	(64 - 8)	/* default data length */
44313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
45313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define	MAXWAIT		10		/* max seconds to wait for response */
46313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define MININTERVAL	10		/* Minimal interpacket gap */
47313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define MINUSERINTERVAL	200		/* Minimal allowed interval for non-root */
48313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
49313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define SCHINT(a)	(((a) <= MININTERVAL) ? MININTERVAL : (a))
50313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
51313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* various options */
52313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern int options;
53313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define	F_FLOOD		0x001
54313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define	F_INTERVAL	0x002
55313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define	F_NUMERIC	0x004
56313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define	F_PINGFILLED	0x008
57313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define	F_QUIET		0x010
58313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define	F_RROUTE	0x020
59313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define	F_SO_DEBUG	0x040
60313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define	F_SO_DONTROUTE	0x080
61313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define	F_VERBOSE	0x100
62313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define	F_TIMESTAMP	0x200
63313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define	F_FLOWINFO	0x200
64313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define	F_SOURCEROUTE	0x400
65313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define	F_TCLASS	0x400
66313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define	F_FLOOD_POLL	0x800
67313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define	F_LATENCY	0x1000
68313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define	F_AUDIBLE	0x2000
69313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define	F_ADAPTIVE	0x4000
70313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define	F_STRICTSOURCE	0x8000
71313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define F_NOLOOP	0x10000
72313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define F_TTL		0x20000
73313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define F_MARK		0x40000
74313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define F_PTIMEOFDAY	0x80000
75313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define F_OUTSTANDING	0x100000
76313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
77313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/*
78313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * MAX_DUP_CHK is the number of bits in received table, i.e. the maximum
79313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * number of received sequence numbers we can keep track of.
80313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */
81313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define	MAX_DUP_CHK	0x10000
82313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
83313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if defined(__WORDSIZE) && __WORDSIZE == 64
84313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# define USE_BITMAP64
85313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
86313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
87313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifdef USE_BITMAP64
88313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittitypedef __u64	bitmap_t;
89313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# define BITMAP_SHIFT	6
90313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#else
91313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittitypedef __u32	bitmap_t;
92313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# define BITMAP_SHIFT	5
93313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
94313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
95313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if ((MAX_DUP_CHK >> (BITMAP_SHIFT + 3)) << (BITMAP_SHIFT + 3)) != MAX_DUP_CHK
96313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# error Please MAX_DUP_CHK and/or BITMAP_SHIFT
97313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
98313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
99313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistruct rcvd_table {
100313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	bitmap_t bitmap[MAX_DUP_CHK / (sizeof(bitmap_t) * 8)];
101313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti};
102313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
103313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern struct rcvd_table rcvd_tbl;
1047618e8104cac3bcc0ba509f4ba40644b665a3ac1Lorenzo Colittiextern int using_ping_socket;
105313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
106313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define	A(bit)	(rcvd_tbl.bitmap[(bit) >> BITMAP_SHIFT])	/* identify word in array */
107313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define	B(bit)	(((bitmap_t)1) << ((bit) & ((1 << BITMAP_SHIFT) - 1)))	/* identify bit in word */
108313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
109313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic inline void rcvd_set(__u16 seq)
110313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{
111313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	unsigned bit = seq % MAX_DUP_CHK;
112313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	A(bit) |= B(bit);
113313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}
114313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
115313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic inline void rcvd_clear(__u16 seq)
116313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{
117313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	unsigned bit = seq % MAX_DUP_CHK;
118313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	A(bit) &= ~B(bit);
119313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}
120313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
121313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic inline bitmap_t rcvd_test(__u16 seq)
122313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{
123313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	unsigned bit = seq % MAX_DUP_CHK;
124313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	return A(bit) & B(bit);
125313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}
126313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
127313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern u_char outpack[];
128313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern int maxpacket;
129313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
130313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern int datalen;
131313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern char *hostname;
132313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern int uid;
133313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern int ident;			/* process id to identify our packets */
134313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
135313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern int sndbuf;
136313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern int ttl;
137313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
138313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern long npackets;			/* max packets to transmit */
139313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern long nreceived;			/* # of packets we got back */
140313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern long nrepeats;			/* number of duplicates */
141313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern long ntransmitted;		/* sequence # for outbound packets = #sent */
142313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern long nchecksum;			/* replies with bad checksum */
143313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern long nerrors;			/* icmp errors */
144313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern int interval;			/* interval between packets (msec) */
145313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern int preload;
146313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern int deadline;			/* time to die */
147313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern int lingertime;
148313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern struct timeval start_time, cur_time;
149313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern volatile int exiting;
150313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern volatile int status_snapshot;
151313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern int confirm;
152313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern int confirm_flag;
153313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern int working_recverr;
154313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
155313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern volatile int in_pr_addr;		/* pr_addr() is executing */
156313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern jmp_buf pr_addr_jmp;
157313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
158313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifndef MSG_CONFIRM
159313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define MSG_CONFIRM 0
160313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
161313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
162313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
163313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* timing */
164313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern int timing;			/* flag to do timing */
165313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern long tmin;			/* minimum round trip time */
166313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern long tmax;			/* maximum round trip time */
167313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern long long tsum;			/* sum of all times, for doing average */
168313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern long long tsum2;
169313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern int rtt;
170313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern __u16 acked;
171313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern int pipesize;
172313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
173313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define COMMON_OPTIONS \
174313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitticase 'a': case 'U': case 'c': case 'd': \
175313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitticase 'f': case 'i': case 'w': case 'l': \
176313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitticase 'S': case 'n': case 'p': case 'q': \
177313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitticase 'r': case 's': case 'v': case 'L': \
178313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitticase 't': case 'A': case 'W': case 'B': case 'm': \
179313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitticase 'D': case 'O':
180313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
181313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define COMMON_OPTSTR "h?VQ:I:M:aUc:dfi:w:l:S:np:qrs:vLt:AW:Bm:DO"
182313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
183313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/*
184313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Write to stdout
185313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */
186313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic inline void write_stdout(const char *str, size_t len)
187313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{
188313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	size_t o = 0;
189313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	ssize_t cc;
190313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	do {
191313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		cc = write(STDOUT_FILENO, str + o, len - o);
192313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		o += cc;
193313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	} while (len > o || cc < 0);
194313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}
195313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
196313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/*
197313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * tvsub --
198313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *	Subtract 2 timeval structs:  out = out - in.  Out is assumed to
199313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * be >= in.
200313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */
201313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic inline void tvsub(struct timeval *out, struct timeval *in)
202313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{
203313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	if ((out->tv_usec -= in->tv_usec) < 0) {
204313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		--out->tv_sec;
205313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		out->tv_usec += 1000000;
206313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	}
207313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	out->tv_sec -= in->tv_sec;
208313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}
209313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
210313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic inline void set_signal(int signo, void (*handler)(int))
211313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{
212313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	struct sigaction sa;
213313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
214313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	memset(&sa, 0, sizeof(sa));
215313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
216313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	sa.sa_handler = (void (*)(int))handler;
217313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifdef SA_INTERRUPT
218313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	sa.sa_flags = SA_INTERRUPT;
219313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
220313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	sigaction(signo, &sa, NULL);
221313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}
222313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
223313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern int __schedule_exit(int next);
224313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
225313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic inline int schedule_exit(int next)
226313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{
227313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	if (npackets && ntransmitted >= npackets && !deadline)
228313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		next = __schedule_exit(next);
229313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	return next;
230313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}
231313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
232313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic inline int in_flight(void)
233313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{
234313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	__u16 diff = (__u16)ntransmitted - acked;
235313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	return (diff<=0x7FFF) ? diff : ntransmitted-nreceived-nerrors;
236313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}
237313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
238313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic inline void acknowledge(__u16 seq)
239313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{
240313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	__u16 diff = (__u16)ntransmitted - seq;
241313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	if (diff <= 0x7FFF) {
242313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		if ((int)diff+1 > pipesize)
243313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			pipesize = (int)diff+1;
244313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		if ((__s16)(seq - acked) > 0 ||
245313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		    (__u16)ntransmitted - acked > 0x7FFF)
246313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			acked = seq;
247313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	}
248313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}
249313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
250313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic inline void advance_ntransmitted(void)
251313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{
252313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	ntransmitted++;
253313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	/* Invalidate acked, if 16 bit seq overflows. */
254313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	if ((__u16)ntransmitted - acked > 0x7FFF)
255313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		acked = (__u16)ntransmitted + 1;
256313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}
257313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
258313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern void limit_capabilities(void);
259313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic int enable_capability_raw(void);
260313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic int disable_capability_raw(void);
261313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic int enable_capability_admin(void);
262313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic int disable_capability_admin(void);
263313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifdef CAPABILITIES
264313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern int modify_capability(cap_value_t, cap_flag_value_t);
265313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic inline int enable_capability_raw(void)		{ return modify_capability(CAP_NET_RAW,   CAP_SET);   };
266313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic inline int disable_capability_raw(void)		{ return modify_capability(CAP_NET_RAW,   CAP_CLEAR); };
267313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic inline int enable_capability_admin(void)		{ return modify_capability(CAP_NET_ADMIN, CAP_SET);   };
268313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic inline int disable_capability_admin(void)	{ return modify_capability(CAP_NET_ADMIN, CAP_CLEAR); };
269313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#else
270313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern int modify_capability(int);
271313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic inline int enable_capability_raw(void)		{ return modify_capability(1); };
272313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic inline int disable_capability_raw(void)		{ return modify_capability(0); };
273313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic inline int enable_capability_admin(void)		{ return modify_capability(1); };
274313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic inline int disable_capability_admin(void)	{ return modify_capability(0); };
275313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
276313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern void drop_capabilities(void);
277924a10d5d9645d4e82fa4b9781f2d85b41ec74f1Lorenzo Colittiextern void android_check_security(void);
278313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
279313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern int send_probe(void);
280313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern int receive_error_msg(void);
281313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern int parse_reply(struct msghdr *msg, int len, void *addr, struct timeval *);
282313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern void install_filter(void);
283ce2d2d04ca21aedab67bd41dd9f89063454ed463Lorenzo Colittiextern int is_ours(uint16_t id);
284313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
285313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern int pinger(void);
286313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern void sock_setbufs(int icmp_sock, int alloc);
2873d667ccb6c8aa805006cfbe2bc793a4ee1ae0047Lorenzo Colittiextern void sock_setmark(int icmp_sock);
288313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern void setup(int icmp_sock);
289313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern void main_loop(int icmp_sock, __u8 *buf, int buflen) __attribute__((noreturn));
290313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern void finish(void) __attribute__((noreturn));
291313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern void status(void);
292313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern void common_options(int ch);
293313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern int gather_statistics(__u8 *ptr, int icmplen,
294313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			     int cc, __u16 seq, int hops,
295313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			     int csfailed, struct timeval *tv, char *from,
296313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			     void (*pr_reply)(__u8 *ptr, int cc));
297313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern void print_timestamp(void);
298