1 /*
2  * Copyright 2004-2009 Rob Beverly
3  * Copyright 2015-2021 The Regents of the University of California
4  * All rights reserved.
5  *
6  * This file is part of Spoofer.
7  *
8  * Spoofer is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * Spoofer is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with Spoofer.  If not, see <http://www.gnu.org/licenses/>.
20  *
21  * Additional permission under GNU GPL version 3 section 7
22  *
23  * If you modify this Program, or any covered work, by linking or combining
24  * it with OpenSSL (or a modified version of that library), containing
25  * parts covered by the terms of the OpenSSL license, the licensors of
26  * this Program grant you additional permission to convey the resulting
27  * work. Corresponding Source for a non-source form of such a combination
28  * shall include the source code for the parts of OpenSSL used as well as
29  * that of the covered work.
30  */
31 
32 /****************************************************************************
33    Program:     $Id: spoof.h,v 1.144 2021/04/28 17:39:07 kkeys Exp $
34    Date:        $Date: 2021/04/28 17:39:07 $
35    Description: spoofer header
36                 Should be included after system and third-party headers,
37                 but before any other spoofer headers.
38 ****************************************************************************/
39 
40 #include "config.h"
41 
42 #ifdef HAVE_PTHREAD
43 # include <pthread.h>
44 #endif
45 
46 #ifndef COMMON_SPOOF_H
47 #define COMMON_SPOOF_H 1
48 
49 // #pragma GCC diagnostic push
50 // #pragma GCC diagnostic ignored "-Wshadow"
51 #include "spoofer.pb.h"
52 // #pragma GCC diagnostic pop
53 
54 #ifdef _WIN32
55   #define NOGDI // prevents <wingdi.h> from polluting our namespace
56   #include <winsock2.h>
57   #include <ws2tcpip.h>
58   #include <unistd.h>
59   #include <stdint.h>
60   #undef HAVE_NETINET_IP_H
61   #undef HAVE_IN_ADDR_T
62   #if _WIN32_WINNT >= _WIN32_WINNT_VISTA  // Vista does have these functions
63     #define HAVE_INET_PTON
64     #define HAVE_INET_NTOP
65     // Fix the missing "const" in the Windows declaration of inet_ntop().
66     #define inet_ntop(f, a, b, s) \
67       (inet_ntop)(f, const_cast<void*>(static_cast<const void*>(a)), b, s)
68   #endif
69   typedef SOCKET socket_t; // SOCKET is defined by winsock (an unsigned integer)
70   // INVALID_SOCKET is defined by winsock (maximum value of its type)
71   // closesocket() is defined by winsock (close() does not work on sockets)
72   #define SEND_RET_T int  // return type of send()/sendto()
73   #define SEND_LEN_T int  // type of length parameter of send()/sendto()
74 #else
75   #include <sys/types.h>
76   #ifndef __FAVOR_BSD
77     #define  __FAVOR_BSD
78   #endif
79   #include <unistd.h>
80   #include <sys/socket.h>
81   #include <netinet/in.h>
82   #include <arpa/inet.h>
83   #include <netinet/in_systm.h>
84   #include <netinet/ip.h>
85   #ifdef HAVE_NETINET_IP6_H
86     #include <netinet/ip6.h>
87   #endif
88   #include <netdb.h>
89   // Winsock compatibility
90   typedef int socket_t;
91   #define INVALID_SOCKET -1
92   #define closesocket(fd) close(fd)
93   #define SEND_RET_T ssize_t  // return type of send()/sendto()
94   #define SEND_LEN_T size_t   // type of length parameter of send()/sendto()
95 #endif
96 
97 /* The UDP header layout is an universal standard, not OS-specific, so it makes
98  * more sense to define our own copy than to depend on differently-named
99  * definitions provided by the host OS. */
100 struct udphdr
101 {
102   uint16_t uh_sport;           /* source port */
103   uint16_t uh_dport;           /* destination port */
104   uint16_t uh_ulen;            /* udp length */
105   uint16_t uh_sum;             /* udp checksum */
106 };
107 
108 #include <cstdio>
109 #include <stdlib.h>
110 #include <strings.h>
111 #include <string.h>
112 #include <sys/types.h>
113 #include <time.h>
114 #include <errno.h>
115 #include <climits> // INT_MAX, etc
116 #ifdef HAVE_LIBSSL
117 #pragma GCC diagnostic push
118 #pragma GCC diagnostic ignored "-Wpragmas" // gag warning about next pragma
119 #pragma GCC diagnostic ignored "-Wdocumentation" // gag warnings in ssl headers
120 #include <openssl/err.h>
121 #include <openssl/ssl.h>
122 #pragma GCC diagnostic pop
123 #endif
124 
125 #include "port.h"  // after system headers
126 #include "safe_int.h"
127 #include "messages.h"
128 
129 #define VERBOSE 0
130 //#define REGRESS 1
131 #ifdef REGRESS
132 #undef VERSION
133 #define VERSION 99
134 #endif
135 
136 #define BUFSIZE 1500
137 #define SMALLBUF 80
138 #define BIGBUF 9000
139 #define MAXMSGSIZE 4096
140 #define LISTENQ 1024
141 
142 #define TTL_OUT 64
143 #define SRC_PORT 5353
144 #define CLIENT_TIMEOUT 60
145 
146 #define TEST_SERVER "192.172.226.236"
147 #define TEST_SERVER6 "2001:48d0:101:501::236"
148 #define TEST_SERVER_HOST "spoofer-test-ctrl.caida.org"
149 #define TEST_SERVER6_HOST "spoofer-test-ctrl.caida.org"
150 #define TEST_REPORT_HOST "spoofer-test.caida.org"
151 
152 #define PROD_SERVER "192.172.226.242"
153 #define PROD_SERVER6 "2001:48d0:101:501::242"
154 #define PROD_SERVER_HOST "spoofer-ctrl.caida.org"
155 #define PROD_SERVER6_HOST "spoofer-ctrl.caida.org"
156 #define PROD_REPORT_HOST "spoofer.caida.org"
157 
158 #if 0
159 // testing
160  #define SERVER TEST_SERVER
161  #define SERVER6 TEST_SERVER6
162  #define REPORT_HOST TEST_REPORT_HOST
163 #else
164 // production
165  #define SERVER PROD_SERVER
166  #define SERVER6 PROD_SERVER6
167  #define REPORT_HOST PROD_REPORT_HOST
168 #endif
169 
170 extern const std::string *pbs_magic;
171 
172 #if 0
173   #define SERV_PORT 5353
174   #define REPORT_PORT_SSL 4443
175   #define REPORT_PORT_CLEAR 8080
176   #define ICMP_DIVERT_PORT 3002
177   #define UDP_DIVERT_PORT 3003
178 #else
179   #define SERV_PORT 53
180   #define REPORT_PORT_SSL 443
181   #define REPORT_PORT_CLEAR 80
182   #define ICMP_DIVERT_PORT 2002
183   #define UDP_DIVERT_PORT 2003
184 #endif
185 
186 #ifndef FALSE
187  #define FALSE 0
188  #define TRUE !FALSE
189 #endif
190 
191 #ifndef HAVE_NETINET_IP_H
192 /*
193  * Structure of an internet header, naked of options.
194  */
195 struct ip {
196 #ifdef _IP_VHL
197         u_char  ip_vhl;                 /* version << 4 | header length >> 2 */
198 #else
199 	/* Note: the base type of ip_hl and ip_v must be an 8-bit type, since
200 	 * some compilers (at least mxe/mingw gcc 5.1.0) allocate the full
201 	 * size of the base type. */
202 #ifdef HAVE_BIG_ENDIAN
203         u_char  ip_v:4,                 /* version */
204                 ip_hl:4;                /* header length */
205 #else
206         u_char  ip_hl:4,                /* header length */
207                 ip_v:4;                 /* version */
208 #endif
209 #endif /* not _IP_VHL */
210         u_char  ip_tos;                 /* type of service */
211         u_short ip_len;                 /* total length */
212         u_short ip_id;                  /* identification */
213         u_short ip_off;                 /* fragment offset field */
214 #define IP_RF 0x8000                    /* reserved fragment flag */
215 #define IP_DF 0x4000                    /* dont fragment flag */
216 #define IP_MF 0x2000                    /* more fragments flag */
217 #define IP_OFFMASK 0x1fff               /* mask for fragmenting bits */
218         u_char  ip_ttl;                 /* time to live */
219         u_char  ip_p;                   /* protocol */
220         u_short ip_sum;                 /* checksum */
221         struct  in_addr ip_src,ip_dst;  /* source and dest address */
222 };
223 #endif /* HAVE_NETINET_IP_H */
224 
225 STATIC_ASSERT(sizeof(struct ip) == 20, struct_ip_is_not_20_bytes);
226 
227 enum IPv { IPv0 = 0 /* unknown */, IPv4 = 4, IPv6 = 6 };
228 
229 #ifdef HAVE_SA_FAMILY_T
230 typedef sa_family_t family_t;
231 #else
232 typedef uint16_t family_t;
233 #endif
234 
235 #ifndef HAVE_NETINET_IP6_H
236 /* RFC 3542 */
237 struct ip6_hdr {
238     union {
239         struct ip6_hdrctl {
240             uint32_t ip6_un1_flow; /* 4 bits version, 8 bits TC, 20 bits
241                                       flow-ID */
242             uint16_t ip6_un1_plen; /* payload length */
243             uint8_t  ip6_un1_nxt;  /* next header */
244             uint8_t  ip6_un1_hlim; /* hop limit */
245         } ip6_un1;
246         uint8_t ip6_un2_vfc;     /* 4 bits version, top 4 bits
247                                     tclass */
248     } ip6_ctlun;
249     struct in6_addr ip6_src;   /* source address */
250     struct in6_addr ip6_dst;   /* destination address */
251 };
252 
253 #define ip6_vfc   ip6_ctlun.ip6_un2_vfc
254 #define ip6_flow  ip6_ctlun.ip6_un1.ip6_un1_flow
255 #define ip6_plen  ip6_ctlun.ip6_un1.ip6_un1_plen
256 #define ip6_nxt   ip6_ctlun.ip6_un1.ip6_un1_nxt
257 #define ip6_hlim  ip6_ctlun.ip6_un1.ip6_un1_hlim
258 #define ip6_hops  ip6_ctlun.ip6_un1.ip6_un1_hlim
259 
260 #endif /* HAVE_NETINET_IP6_H */
261 
262 STATIC_ASSERT(sizeof(struct ip6_hdr) == 40, struct_ip6_hdr_is_not_40_bytes);
263 
264 #ifndef HAVE_INET_PTON
265 int inet_pton(int af, const char *src, void *dst);
266 #endif
267 #ifndef HAVE_INET_NTOP
268 const char *inet_ntop(int af, const void *src, char *dst, size_t cnt);
269 #endif
270 
271 #ifndef HAVE_STRUCT_SOCKADDR_IN6
272 struct in6_addr
273 {
274   uint8_t 	  s6_addr[16];
275 };
276 
277 struct sockaddr_in6
278 {
279   sa_family_t	  sin6_family;		/* AF_INET6 */
280   in_port_t	  sin6_port;		/* Port number. */
281   uint32_t	  sin6_flowinfo;	/* Traffic class and flow inf. */
282   struct in6_addr sin6_addr;		/* IPv6 address. */
283   uint32_t	  sin6_scope_id;	/* Set of interfaces for a scope. */
284 };
285 #endif
286 
287 #ifndef IP_DF
288  #define IP_DF 0x4000
289 #endif
290 
291 #ifndef AF_INET6
292  #define AF_INET6 10
293 #endif
294 
295 // helpers to cast [const] sockaddr* to [const] sockaddr_{in,in6}
296 #pragma GCC diagnostic push
297 #pragma GCC diagnostic ignored "-Wcast-align"
sa_in(sockaddr * sa)298 static inline sockaddr_in *sa_in(sockaddr *sa)
299     { return (reinterpret_cast<sockaddr_in *>(sa)); }
300 
sa_in(const sockaddr * sa)301 static inline const sockaddr_in *sa_in(const sockaddr *sa)
302     { return (reinterpret_cast<const sockaddr_in *>(sa)); }
303 
sa_in6(sockaddr * sa)304 static inline sockaddr_in6 *sa_in6(sockaddr *sa)
305     { return (reinterpret_cast<sockaddr_in6 *>(sa)); }
306 
sa_in6(const sockaddr * sa)307 static inline const sockaddr_in6 *sa_in6(const sockaddr *sa)
308     { return (reinterpret_cast<const sockaddr_in6 *>(sa)); }
309 #pragma GCC diagnostic pop
310 
311 // get a ref to the port part of a sockaddr_{in,in6} (in network order)
sa_port(sockaddr * sa)312 static inline uint16_t &sa_port(sockaddr *sa)
313 {
314     static uint16_t zero = 0;
315     if (sa->sa_family == AF_INET)
316         return (sa_in(sa))->sin_port;
317     if (sa->sa_family == AF_INET6)
318         return (sa_in6(sa))->sin6_port;
319     return zero; // shouldn't happen
320 }
321 
322 // get the port part of a const sockaddr_{in,in6} (in network order)
sa_port(const sockaddr * sa)323 static inline uint16_t sa_port(const sockaddr *sa)
324 {
325     if (sa->sa_family == AF_INET)
326         return (sa_in(sa))->sin_port;
327     if (sa->sa_family == AF_INET6)
328         return (sa_in6(sa))->sin6_port;
329     return 0; // shouldn't happen
330 }
331 
332 /* get a pointer to the IP address part of a sockaddr_{in,in6} */
sa_ipaddr(sockaddr * sa)333 static inline char *sa_ipaddr(sockaddr *sa)
334 {
335     if (sa->sa_family == AF_INET)
336         return reinterpret_cast<char *>(&(sa_in(sa))->sin_addr);
337     if (sa->sa_family == AF_INET6)
338         return reinterpret_cast<char *>(&(sa_in6(sa))->sin6_addr);
339     return nullptr;
340 }
341 
342 /* get a pointer to the IP address part of a const sockaddr_{in,in6} */
sa_ipaddr(const sockaddr * sa)343 static inline const char *sa_ipaddr(const sockaddr *sa)
344 {
345     if (sa->sa_family == AF_INET)
346         return reinterpret_cast<const char *>(&(sa_in(sa))->sin_addr);
347     if (sa->sa_family == AF_INET6)
348         return reinterpret_cast<const char *>(&(sa_in6(sa))->sin6_addr);
349     return nullptr;
350 }
351 
352 // get the size of a const sockaddr_{in,in6}
sa_len(const sockaddr * sa)353 static inline uint16_t sa_len(const sockaddr *sa)
354 {
355     if (sa->sa_family == AF_INET)
356         return sizeof(struct sockaddr_in);
357     if (sa->sa_family == AF_INET6)
358         return sizeof(struct sockaddr_in6);
359     return 0;
360 }
361 
addrlen(const family_t & family)362 static inline unsigned int addrlen(const family_t &family)
363 {
364     return
365 	(family == AF_INET6) ? IPV6ADDRLEN :
366 	(family == AF_INET) ? IPV4ADDRLEN :
367 	0;
368 }
369 
familytoipv(const family_t & family)370 static inline IPv familytoipv(const family_t &family)
371 {
372     return
373 	(family == AF_INET6) ? IPv6 :
374 	(family == AF_INET) ? IPv4 :
375 	IPv0;
376 }
377 
ipvtofamily(const IPv & ipv)378 static inline family_t ipvtofamily(const IPv &ipv) {
379     return
380 	(ipv == IPv6) ? AF_INET6 :
381 	(ipv == IPv4) ? AF_INET :
382 	0;
383 }
384 
385 
386 /* get pointer to address within an old-style right-aligned address buffer */
387 #define right_addr(family, addr) \
388     (((unsigned char*)addr) + IPV6ADDRLEN - addrlen(family))
389 
390 
391 /* prettyprint */
392 #define NIPQUAD(addr) \
393   ((unsigned char *)&addr)[0], \
394   ((unsigned char *)&addr)[1], \
395   ((unsigned char *)&addr)[2], \
396   ((unsigned char *)&addr)[3]
397 
398 // nptohl(p) is Like ntohl(*p), but does not require p to be aligned.
399 #define nptohl(p) \
400     (static_cast<uint32_t>( \
401 	(((const uint8_t*)p)[0] << 24) | \
402 	(((const uint8_t*)p)[1] << 16) | \
403 	(((const uint8_t*)p)[2] << 8) | \
404 	(((const uint8_t*)p)[3])))
405 
406 // htonpl(p,n) is like *p = htonl(n), but does not require p to be aligned.
407 #define htonpl(p, n) \
408     do { \
409 	(((uint8_t*)p))[0] = (uint8_t)((n >> 24) & 0xFF); \
410 	(((uint8_t*)p))[1] = (uint8_t)((n >> 16) & 0xFF); \
411 	(((uint8_t*)p))[2] = (uint8_t)((n >> 8) & 0xFF); \
412 	(((uint8_t*)p))[3] = (uint8_t)(n & 0xFF); \
413     } while (0)
414 
415 // nptohs(p) is Like ntohs(*p), but does not require p to be aligned.
416 #define nptohs(p) \
417     (static_cast<uint16_t>( \
418 	(((const uint8_t*)p)[0] << 8) | \
419 	(((const uint8_t*)p)[1])));
420 
421 // Interpret ptr as a pointer to type, and return a pointer to ptr->field.
422 // *ptr does not need to be aligned.
423 #define ua_field(type, ptr, field) \
424     (((const uint8_t*)ptr) + offsetof(type, field))
425 
426 /* error messages */
427 #define tracefunc() \
428     do { \
429 	if (verbosity >= DEVELOP) \
430 	    fprintf(stdout, "\t>> %s:%s():%d\n", __FILE__, __FUNCTION__, __LINE__); \
431     } while (0)
432 
433 // printf with a prefix and newline.  We use an internal buffer so that writes
434 // (up to a certain size) will be atomic.
435 #define pprintf(prefix, ...) \
436     do { \
437 	int n1 = snprintf(nullptr, 0, "*** %s: ", prefix); \
438 	int n2 = snprintf(nullptr, 0, __VA_ARGS__); \
439 	if (n1 < 0 || n2 < 0) break; \
440 	char *ppbuf = new char[safe_int<size_t>(n1+n2+2)]; \
441 	sprintf(ppbuf, "*** %s: ", prefix); \
442 	sprintf(ppbuf+n1, __VA_ARGS__); \
443 	sprintf(ppbuf+n1+n2, "\n"); \
444 	fputs(ppbuf, stdout); \
445 	delete[] ppbuf; \
446     } while (0)
447 
448 #define info(...)   pprintf("Info", __VA_ARGS__)    // not displayed in gui
449 #define notice(...) pprintf("Notice", __VA_ARGS__)  // displayed in gui
450 #define warn(...)   pprintf("Warning", __VA_ARGS__) // displayed in gui
451 #define severe(...) pprintf("Error", __VA_ARGS__)   // displayed in gui
452 
453 #define debug(level, ...) \
454     do { if (verbosity >= level) fprintf(stdout, __VA_ARGS__); } while (0)
455 
456 enum debugLevel {OFF, LOW, HIGH, DEVELOP};
457 extern int verbosity;
458 
459 typedef void Sigfunc(int);
460 
461 // A mutex object that does nothing if HAVE_PTHREAD is not defined.
462 class OptMutex {
463 #ifdef HAVE_PTHREAD
464     pthread_mutex_t mutex;
465 public:
OptMutex()466     OptMutex() : mutex() { pthread_mutex_init(&mutex, nullptr); }
lock()467     void lock() { pthread_mutex_lock(&mutex); }
unlock()468     void unlock() { pthread_mutex_unlock(&mutex); }
469 #else
470 public:
471     void lock() {}
472     void unlock() {}
473 #endif
474 };
475 
476 // RAII-style scoped mutex wrapper (similar to C++11 std::lock_guard), plus
477 // unlock() to manually unlock early (like C++11 std::unique_lock)
478 class LockGuard {
479     LockGuard(const LockGuard&) NO_METHOD;
480     OptMutex &m;
481     bool locked;
482 public:
LockGuard(OptMutex & mutex)483     LockGuard(OptMutex &mutex) : m(mutex), locked(true) { m.lock(); }
~LockGuard()484     ~LockGuard() { if (locked) m.unlock(); }
unlock()485     void unlock() { m.unlock(); locked = false; }
486 };
487 
488 /* net.cc */
489 
490 static const char * const probeStatusStr[] =
491     { "UNTRIED", "SENDFAIL", "UNCONFIRMED", "REWRITTEN", "CONFIRMED" };
492 enum ProbeStatus { UNTRIED, SENDFAIL, UNCONFIRMED, REWRITTEN, CONFIRMED };
493 
494 extern int spoof_layer[];
495 typedef struct probe_info probe_info_t;
496 const char *sock_errmsg(int err, char *buf = nullptr, size_t buflen = 0);
497 const char *sock_last_errmsg(char *buf = nullptr, size_t buflen = 0);
498 
499 // Convenient shorthand for using sock_last_errmsg() with a buffer, for thread
500 // safety.
501 class SockLastErrmsg {
502     char buf[256];
503 public:
SockLastErrmsg()504     SockLastErrmsg() { sock_last_errmsg(buf, sizeof(buf)); }
operator()505     const char *operator()() { return buf; }
506 };
507 
508 #ifdef HAVE_LIBSSL
509 void ssl_err(const char *str);
510 void ssl_io_error(SSL *ssl, int ret, const char *str);
511 #endif
512 void dump_ifaces();
513 size_t craftPacket(uint32_t *, const void *, size_t,
514     const sockaddr *, const sockaddr *, u_char, unsigned short) ATR_NONNULL();
515 void craftProbe(probe_t *probe, bool spoof, const SpooferSpoofSchedule::Item *item) ATR_NONNULL();
516 unsigned short in_cksum(const void *, size_t);
517 char * genSequence(char *, int) ATR_NONNULL();
518 Sigfunc *Signal(int signo, Sigfunc *func);
519 void sig_chld(int signo);
520 size_t Readn(socket_t fd, void *ptr, size_t nbytes, time_t timeout) ATR_NONNULL();
521 void Writen(socket_t fd, const void *ptr, size_t nbytes) ATR_NONNULL();
522 ssize_t Readline(socket_t fd, void *ptr, size_t maxlen) ATR_NONNULL();
523 ssize_t readn(socket_t fd, void *vptr, size_t n, time_t wait) ATR_NONNULL();
524 socket_t newSocket(family_t, int, int);
525 int getSockTTL(family_t family, socket_t sock, int *val) ATR_NONNULL();
526 int setSockTTL(family_t family, socket_t sock, int val);
527 int optSocketHDRINCL(socket_t);
528 struct probe_info *new_probe_info(int proto, bool spoof, socket_t sock,
529     sockaddr *src_sa, const sockaddr *dst_sa, bool ingress = false) ATR_NONNULL((5));
530 #ifdef HAVE_PCAP
531 bool init_sniffer(struct probe_info *pinfo, size_t payload_len);
532 struct probe_info *pkt_captured(probe_info *pinfo,
533     const struct pcap_pkthdr *phdr, const u_char *data);
534 const u_char *get_ip_packet(/*const*/ struct probe_info *pinfo,
535     const struct pcap_pkthdr *phdr, const u_char *data);
536 #endif
537 int socketSend(socket_t, const void *, size_t, struct probe_info *) ATR_NONNULL();
538 int socketSendSpoof(socket_t, socket_t, const void *, size_t, struct probe_info *) ATR_NONNULL();
539 enum ProbeStatus free_probe_info(struct probe_info *pinfo, bool skipSniffing = false) ATR_NONNULL();
540 bool initSockets(bool spoof, IPv ipv, socket_t& spoofsock, socket_t& udpsock,
541     const sockaddr *src, const sockaddr *dst);
542 const char *getSockErr(socket_t sock, char *buf = nullptr, size_t buflen = 0);
543 bool closeSocket(socket_t &sock, IPv ipv);
544 const char *sa_ntop(const sockaddr *sa, char *dst = nullptr, size_t len = INET6_ADDRSTRLEN+1) ATR_NONNULL((1));
545 
546 // Convenient shorthand for using sa_ntop() with a buffer, for thread safety.
547 class ntopBuf {
548     char pbuf[INET6_ADDRSTRLEN+1];
549 public:
ntopBuf(const sockaddr * sa)550     ntopBuf(const sockaddr *sa) { sa_ntop(sa, pbuf, sizeof(pbuf)); }
operator()551     const char *operator()() { return pbuf; }
552 };
553 
554 /* util.cc */
555 void spoofer_rand_stir();
556 unsigned long spoofer_rand(unsigned long max);
557 void binDump(const void *msg, size_t len, int pretty, const char *prefix = nullptr) ATR_NONNULL((1));
558 void win_init(void);
559 void msleep(unsigned int msec);
560 void spoofSleep(void);
561 
562 #ifdef _WIN32
563 int spoofer_snprintf(char *buf, size_t size, const char *fmt, ...) FORMAT_PRINTF(3, 4);
564 #undef snprintf // in case WinPcap's pcap.h defined it
565 #define snprintf spoofer_snprintf // replace Windows' broken snprintf()
566 #endif
567 int is_interactive(void);
568 NORETURN void exitpause(int status);
569 NORETURN void fatal(const char *, ...) FORMAT_PRINTF(1, 2);
570 NORETURN void pfatal(const char *, ...) FORMAT_PRINTF(1, 2);
571 void streamSetup(void);
572 char *timestring(void); // Uses static buffer - not threadsafe!
573 uint32_t n6ton4(const unsigned char *addr) ATR_PURE ATR_NONNULL();
574 uint32_t n6toh4(const unsigned char *addr) ATR_PURE ATR_NONNULL();
575 int n4ton6(const uint32_t ip, unsigned char *addr) ATR_PURE ATR_NONNULL();
576 int h4ton6(const uint32_t ip, unsigned char *addr) ATR_PURE ATR_NONNULL();
577 int n6tohexstring(const unsigned char *addr, char *res) ATR_NONNULL();
578 int isIPv4(const unsigned char *addr) ATR_PURE ATR_NONNULL();
579 int isIPv6(const unsigned char *addr) ATR_PURE ATR_NONNULL();
580 char *printIPv6(const unsigned char *a) ATR_NONNULL();
581 int isIPv6Equal(const unsigned char *a1, const unsigned char *a2) ATR_PURE ATR_NONNULL();
582 const char *strstrPortable(const char *a, const char *b, size_t n) ATR_PURE ATR_NONNULL();
583 
584 // example:   printf("time: %s\n", gmTimeStr()());
585 class gmTimeStr {
586     char buf[40]; // each gmTimeStr object has its own buffer
587 public:
588     gmTimeStr(const time_t *tp = nullptr) {
589 	time_t t;
590 	if (!tp) { time(&t); tp = &t; }
591 	strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", gmtime(tp));
592     }
operator()593     const char *operator()() { return buf; }
594 };
595 
596 /* spoofer_pb_enum.cc */
597 template<class T>
598 struct EnumName {
599     const T id;
600     const char * const name;
601 };
602 
603 template<class T>
604 struct EnumNames : public std::vector<EnumName<T> > {
605     // Note: we avoid initializer_list because clang 3.2 doesn't implement it
EnumNamesEnumNames606     EnumNames(const EnumName<T> *first, const EnumName<T> *last) :
607 	std::vector<EnumName<T> >(first, last) {}
608 
609     // Return the name for an id.
fromIdEnumNames610     const char *fromId(T id) const {
611 	static char buf[32];
612 	for (auto entry : *this) {
613 	    if (id == entry.id)
614 		return entry.name; // success
615 	}
616 	sprintf(buf, "unknown(%d)", id);
617 	return buf; // failure
618     }
619 
620     // Look up the id for a name.
toIdEnumNames621     bool toId(const char *name, T &id) const {
622 	for (auto entry : *this) {
623 	    if (strcasecmp(name, entry.name) == 0) {
624 		id = entry.id;
625 		return true; // success
626 	    }
627 	}
628 	return false; // failure
629     }
630 };
631 
632 extern const EnumNames<SpooferSpoofReport_Item_Status> names_SpoofReport_Item_Status;
633 extern const EnumNames<SpooferResultSummary::Result> names_ResultSummary_Result;
634 extern const EnumNames<SpooferTestType> names_TestType;
635 extern const EnumNames<SpooferReportStatus> names_ReportStatus;
636 
637 /* messages.cc */
638 const char *pb_ntop(family_t family, const std::string &addr, char *buf, size_t buflen);
639 const char *pb_ntop(family_t family, const std::string &addr);
640 void printServerMsg(const SpooferServerMsg &msg, IPv ipv, time_t ts = 0);
641 void printClientMsg(const SpooferClientMsg &msg, IPv ipv, time_t ts = 0);
642 #if 0
643 char *msg_type_name(uint8_t typ);
644 void printAddressList(struct in_addr *iplist, int num);
645 void printMsg(unsigned char *, int);
646 spoof_msg_t *readMsg(int sock, unsigned char **message, enum msg_types);
647 void defaultMsg(spoof_msg_t *msg);
648 int errorRequest(unsigned char *);
649 int helloRequest(unsigned char *);
650 int reportRequest(unsigned char *msg, unsigned char *seqno,
651     unsigned char *src_addr, unsigned char *dst_addr, int nat, int ipv6);
652 int doneRequest(unsigned char *msg);
653 int probeRequest(unsigned char *msg, int v6);
654 int readProbeList(unsigned char *buf, test_t **testlistptr);
655 int traceFilterRequest(unsigned char *msg);
656 #endif
657 
658 #include "spoofer_stdio.h"
659 
660 #endif // COMMON_SPOOF_H
661