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