1*05b00f60SXin Li /* 2*05b00f60SXin Li * Copyright (c) 2002 - 2003 3*05b00f60SXin Li * NetGroup, Politecnico di Torino (Italy) 4*05b00f60SXin Li * All rights reserved. 5*05b00f60SXin Li * 6*05b00f60SXin Li * Redistribution and use in source and binary forms, with or without 7*05b00f60SXin Li * modification, are permitted provided that the following conditions 8*05b00f60SXin Li * are met: 9*05b00f60SXin Li * 10*05b00f60SXin Li * 1. Redistributions of source code must retain the above copyright 11*05b00f60SXin Li * notice, this list of conditions and the following disclaimer. 12*05b00f60SXin Li * 2. Redistributions in binary form must reproduce the above copyright 13*05b00f60SXin Li * notice, this list of conditions and the following disclaimer in the 14*05b00f60SXin Li * documentation and/or other materials provided with the distribution. 15*05b00f60SXin Li * 3. Neither the name of the Politecnico di Torino nor the names of its 16*05b00f60SXin Li * contributors may be used to endorse or promote products derived from 17*05b00f60SXin Li * this software without specific prior written permission. 18*05b00f60SXin Li * 19*05b00f60SXin Li * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20*05b00f60SXin Li * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21*05b00f60SXin Li * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22*05b00f60SXin Li * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23*05b00f60SXin Li * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24*05b00f60SXin Li * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25*05b00f60SXin Li * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26*05b00f60SXin Li * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27*05b00f60SXin Li * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28*05b00f60SXin Li * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29*05b00f60SXin Li * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30*05b00f60SXin Li */ 31*05b00f60SXin Li 32*05b00f60SXin Li /* 33*05b00f60SXin Li * Include the appropriate OS header files on Windows and various flavors 34*05b00f60SXin Li * of UNIX, include various non-OS header files on Windows, and define 35*05b00f60SXin Li * various items as needed, to isolate most of netdissect's platform 36*05b00f60SXin Li * differences to this one file. 37*05b00f60SXin Li */ 38*05b00f60SXin Li 39*05b00f60SXin Li #ifndef netdissect_stdinc_h 40*05b00f60SXin Li #define netdissect_stdinc_h 41*05b00f60SXin Li 42*05b00f60SXin Li #include "ftmacros.h" 43*05b00f60SXin Li 44*05b00f60SXin Li #include <errno.h> 45*05b00f60SXin Li 46*05b00f60SXin Li #include "compiler-tests.h" 47*05b00f60SXin Li 48*05b00f60SXin Li #include "varattrs.h" 49*05b00f60SXin Li 50*05b00f60SXin Li /* 51*05b00f60SXin Li * If we're compiling with Visual Studio, make sure we have at least 52*05b00f60SXin Li * VS 2015 or later, so we have sufficient C99 support. 53*05b00f60SXin Li * 54*05b00f60SXin Li * XXX - verify that we have at least C99 support on UN*Xes? 55*05b00f60SXin Li * 56*05b00f60SXin Li * What about MinGW or various DOS toolchains? We're currently assuming 57*05b00f60SXin Li * sufficient C99 support there. 58*05b00f60SXin Li */ 59*05b00f60SXin Li #if defined(_MSC_VER) 60*05b00f60SXin Li /* 61*05b00f60SXin Li * Make sure we have VS 2015 or later. 62*05b00f60SXin Li */ 63*05b00f60SXin Li #if _MSC_VER < 1900 64*05b00f60SXin Li #error "Building tcpdump requires VS 2015 or later" 65*05b00f60SXin Li #endif 66*05b00f60SXin Li #endif 67*05b00f60SXin Li 68*05b00f60SXin Li /* 69*05b00f60SXin Li * Get the C99 types, and the PRI[doux]64 format strings, defined. 70*05b00f60SXin Li */ 71*05b00f60SXin Li #ifdef HAVE_PCAP_PCAP_INTTYPES_H 72*05b00f60SXin Li /* 73*05b00f60SXin Li * We have pcap/pcap-inttypes.h; use that, as it'll do all the 74*05b00f60SXin Li * work, and won't cause problems if a file includes this file 75*05b00f60SXin Li * and later includes a pcap header file that also includes 76*05b00f60SXin Li * pcap/pcap-inttypes.h. 77*05b00f60SXin Li */ 78*05b00f60SXin Li #include <pcap/pcap-inttypes.h> 79*05b00f60SXin Li #else 80*05b00f60SXin Li /* 81*05b00f60SXin Li * OK, we don't have pcap/pcap-inttypes.h, so we'll have to 82*05b00f60SXin Li * do the work ourselves, but at least we don't have to 83*05b00f60SXin Li * worry about other headers including it and causing 84*05b00f60SXin Li * clashes. 85*05b00f60SXin Li */ 86*05b00f60SXin Li 87*05b00f60SXin Li /* 88*05b00f60SXin Li * Include <inttypes.h> to get the integer types and PRi[doux]64 values 89*05b00f60SXin Li * defined. 90*05b00f60SXin Li * 91*05b00f60SXin Li * If the compiler is MSVC, we require VS 2015 or newer, so we 92*05b00f60SXin Li * have <inttypes.h> - and support for %zu in the formatted 93*05b00f60SXin Li * printing functions. 94*05b00f60SXin Li * 95*05b00f60SXin Li * If the compiler is MinGW, we assume we have <inttypes.h> - and 96*05b00f60SXin Li * support for %zu in the formatted printing functions. 97*05b00f60SXin Li * 98*05b00f60SXin Li * If the target is UN*X, we assume we have a C99-or-later development 99*05b00f60SXin Li * environment, and thus have <inttypes.h> - and support for %zu in 100*05b00f60SXin Li * the formatted printing functions. 101*05b00f60SXin Li * 102*05b00f60SXin Li * If the target is MS-DOS, we assume we have <inttypes.h> - and support 103*05b00f60SXin Li * for %zu in the formatted printing functions. 104*05b00f60SXin Li */ 105*05b00f60SXin Li #include <inttypes.h> 106*05b00f60SXin Li 107*05b00f60SXin Li #if defined(_MSC_VER) 108*05b00f60SXin Li /* 109*05b00f60SXin Li * Suppress definition of intN_t in bittypes.h, which might be included 110*05b00f60SXin Li * by <pcap/pcap.h> in older versions of WinPcap. 111*05b00f60SXin Li * (Yes, HAVE_U_INTn_T, as the definition guards are UN*X-oriented.) 112*05b00f60SXin Li */ 113*05b00f60SXin Li #define HAVE_U_INT8_T 114*05b00f60SXin Li #define HAVE_U_INT16_T 115*05b00f60SXin Li #define HAVE_U_INT32_T 116*05b00f60SXin Li #define HAVE_U_INT64_T 117*05b00f60SXin Li #endif 118*05b00f60SXin Li #endif /* HAVE_PCAP_PCAP_INTTYPES_H */ 119*05b00f60SXin Li 120*05b00f60SXin Li #ifdef _WIN32 121*05b00f60SXin Li 122*05b00f60SXin Li /* 123*05b00f60SXin Li * Includes and definitions for Windows. 124*05b00f60SXin Li */ 125*05b00f60SXin Li 126*05b00f60SXin Li #include <stdio.h> 127*05b00f60SXin Li #include <winsock2.h> 128*05b00f60SXin Li #include <ws2tcpip.h> 129*05b00f60SXin Li #include <time.h> 130*05b00f60SXin Li #include <io.h> 131*05b00f60SXin Li #include <fcntl.h> 132*05b00f60SXin Li #include <sys/types.h> 133*05b00f60SXin Li 134*05b00f60SXin Li #ifdef _MSC_VER 135*05b00f60SXin Li /* 136*05b00f60SXin Li * Compiler is MSVC. 137*05b00f60SXin Li * 138*05b00f60SXin Li * We require VS 2015 or newer, so we have strtoll(). Use that for 139*05b00f60SXin Li * strtoint64_t(). 140*05b00f60SXin Li */ 141*05b00f60SXin Li #define strtoint64_t strtoll 142*05b00f60SXin Li 143*05b00f60SXin Li /* 144*05b00f60SXin Li * And we have LL as a suffix for constants, so use that. 145*05b00f60SXin Li */ 146*05b00f60SXin Li #define INT64_T_CONSTANT(constant) (constant##LL) 147*05b00f60SXin Li #else 148*05b00f60SXin Li /* 149*05b00f60SXin Li * Non-Microsoft compiler. 150*05b00f60SXin Li * 151*05b00f60SXin Li * XXX - should we use strtoll or should we use _strtoi64()? 152*05b00f60SXin Li */ 153*05b00f60SXin Li #define strtoint64_t strtoll 154*05b00f60SXin Li 155*05b00f60SXin Li /* 156*05b00f60SXin Li * Assume LL works. 157*05b00f60SXin Li */ 158*05b00f60SXin Li #define INT64_T_CONSTANT(constant) (constant##LL) 159*05b00f60SXin Li #endif 160*05b00f60SXin Li 161*05b00f60SXin Li #ifdef _MSC_VER 162*05b00f60SXin Li /* 163*05b00f60SXin Li * Microsoft tries to avoid polluting the C namespace with UN*Xisms, 164*05b00f60SXin Li * by adding a preceding underscore; we *want* the UN*Xisms, so add 165*05b00f60SXin Li * #defines to let us use them. 166*05b00f60SXin Li */ 167*05b00f60SXin Li #define isatty _isatty 168*05b00f60SXin Li #define stat _stat 169*05b00f60SXin Li #define strdup _strdup 170*05b00f60SXin Li #define open _open 171*05b00f60SXin Li #define read _read 172*05b00f60SXin Li #define close _close 173*05b00f60SXin Li #define O_RDONLY _O_RDONLY 174*05b00f60SXin Li 175*05b00f60SXin Li /* 176*05b00f60SXin Li * We define our_fstat64 as _fstati64, and define our_statb as 177*05b00f60SXin Li * struct _stati64, so we get 64-bit file sizes. 178*05b00f60SXin Li */ 179*05b00f60SXin Li #define our_fstat _fstati64 180*05b00f60SXin Li #define our_statb struct _stati64 181*05b00f60SXin Li 182*05b00f60SXin Li /* 183*05b00f60SXin Li * If <crtdbg.h> has been included, and _DEBUG is defined, and 184*05b00f60SXin Li * __STDC__ is zero, <crtdbg.h> will define strdup() to call 185*05b00f60SXin Li * _strdup_dbg(). So if it's already defined, don't redefine 186*05b00f60SXin Li * it. 187*05b00f60SXin Li */ 188*05b00f60SXin Li #ifndef strdup 189*05b00f60SXin Li #define strdup _strdup 190*05b00f60SXin Li #endif 191*05b00f60SXin Li 192*05b00f60SXin Li /* 193*05b00f60SXin Li * Windows doesn't have ssize_t; routines such as _read() return int. 194*05b00f60SXin Li */ 195*05b00f60SXin Li typedef int ssize_t; 196*05b00f60SXin Li #endif /* _MSC_VER */ 197*05b00f60SXin Li 198*05b00f60SXin Li /* 199*05b00f60SXin Li * With MSVC, for C, __inline is used to make a function an inline. 200*05b00f60SXin Li */ 201*05b00f60SXin Li #ifdef _MSC_VER 202*05b00f60SXin Li #define inline __inline 203*05b00f60SXin Li #endif 204*05b00f60SXin Li 205*05b00f60SXin Li #if defined(AF_INET6) && !defined(HAVE_OS_IPV6_SUPPORT) 206*05b00f60SXin Li #define HAVE_OS_IPV6_SUPPORT 207*05b00f60SXin Li #endif 208*05b00f60SXin Li 209*05b00f60SXin Li #ifndef INET6_ADDRSTRLEN 210*05b00f60SXin Li #define INET6_ADDRSTRLEN 46 211*05b00f60SXin Li #endif 212*05b00f60SXin Li 213*05b00f60SXin Li /* It is in MSVC's <errno.h>, but not defined in MingW+Watcom. 214*05b00f60SXin Li */ 215*05b00f60SXin Li #ifndef EAFNOSUPPORT 216*05b00f60SXin Li #define EAFNOSUPPORT WSAEAFNOSUPPORT 217*05b00f60SXin Li #endif 218*05b00f60SXin Li 219*05b00f60SXin Li #ifndef caddr_t 220*05b00f60SXin Li typedef char *caddr_t; 221*05b00f60SXin Li #endif /* caddr_t */ 222*05b00f60SXin Li 223*05b00f60SXin Li #define MAXHOSTNAMELEN 64 224*05b00f60SXin Li 225*05b00f60SXin Li #else /* _WIN32 */ 226*05b00f60SXin Li 227*05b00f60SXin Li /* 228*05b00f60SXin Li * Includes and definitions for various flavors of UN*X. 229*05b00f60SXin Li */ 230*05b00f60SXin Li 231*05b00f60SXin Li #include <unistd.h> 232*05b00f60SXin Li #include <netdb.h> 233*05b00f60SXin Li #include <sys/param.h> 234*05b00f60SXin Li #include <sys/types.h> /* concession to AIX */ 235*05b00f60SXin Li #include <sys/time.h> 236*05b00f60SXin Li #include <sys/socket.h> 237*05b00f60SXin Li #include <netinet/in.h> 238*05b00f60SXin Li 239*05b00f60SXin Li #include <time.h> 240*05b00f60SXin Li 241*05b00f60SXin Li #include <arpa/inet.h> 242*05b00f60SXin Li 243*05b00f60SXin Li /* 244*05b00f60SXin Li * We should have large file support enabled, if it's available, 245*05b00f60SXin Li * so just use fstat as our_fstat and struct stat as our_statb. 246*05b00f60SXin Li */ 247*05b00f60SXin Li #define our_fstat fstat 248*05b00f60SXin Li #define our_statb struct stat 249*05b00f60SXin Li 250*05b00f60SXin Li /* 251*05b00f60SXin Li * Assume all UN*Xes have strtoll(), and use it for strtoint64_t(). 252*05b00f60SXin Li */ 253*05b00f60SXin Li #define strtoint64_t strtoll 254*05b00f60SXin Li 255*05b00f60SXin Li /* 256*05b00f60SXin Li * Assume LL works. 257*05b00f60SXin Li */ 258*05b00f60SXin Li #define INT64_T_CONSTANT(constant) (constant##LL) 259*05b00f60SXin Li #endif /* _WIN32 */ 260*05b00f60SXin Li 261*05b00f60SXin Li /* 262*05b00f60SXin Li * Function attributes, for various compilers. 263*05b00f60SXin Li */ 264*05b00f60SXin Li #include "funcattrs.h" 265*05b00f60SXin Li 266*05b00f60SXin Li /* 267*05b00f60SXin Li * fopen() read and write modes for text files and binary files. 268*05b00f60SXin Li */ 269*05b00f60SXin Li #if defined(_WIN32) || defined(MSDOS) 270*05b00f60SXin Li #define FOPEN_READ_TXT "rt" 271*05b00f60SXin Li #define FOPEN_READ_BIN "rb" 272*05b00f60SXin Li #define FOPEN_WRITE_TXT "wt" 273*05b00f60SXin Li #define FOPEN_WRITE_BIN "wb" 274*05b00f60SXin Li #else 275*05b00f60SXin Li #define FOPEN_READ_TXT "r" 276*05b00f60SXin Li #define FOPEN_READ_BIN FOPEN_READ_TXT 277*05b00f60SXin Li #define FOPEN_WRITE_TXT "w" 278*05b00f60SXin Li #define FOPEN_WRITE_BIN FOPEN_WRITE_TXT 279*05b00f60SXin Li #endif 280*05b00f60SXin Li 281*05b00f60SXin Li /* 282*05b00f60SXin Li * Inline x86 assembler-language versions of ntoh[ls]() and hton[ls](), 283*05b00f60SXin Li * defined if the OS doesn't provide them. These assume no more than 284*05b00f60SXin Li * an 80386, so, for example, it avoids the bswap instruction added in 285*05b00f60SXin Li * the 80486. 286*05b00f60SXin Li * 287*05b00f60SXin Li * (We don't use them on macOS; Apple provides their own, which *doesn't* 288*05b00f60SXin Li * avoid the bswap instruction, as macOS only supports machines that 289*05b00f60SXin Li * have it.) 290*05b00f60SXin Li */ 291*05b00f60SXin Li #if defined(__GNUC__) && defined(__i386__) && !defined(__APPLE__) && !defined(__ntohl) 292*05b00f60SXin Li #undef ntohl 293*05b00f60SXin Li #undef ntohs 294*05b00f60SXin Li #undef htonl 295*05b00f60SXin Li #undef htons 296*05b00f60SXin Li 297*05b00f60SXin Li static __inline__ unsigned long __ntohl (unsigned long x); 298*05b00f60SXin Li static __inline__ unsigned short __ntohs (unsigned short x); 299*05b00f60SXin Li 300*05b00f60SXin Li #define ntohl(x) __ntohl(x) 301*05b00f60SXin Li #define ntohs(x) __ntohs(x) 302*05b00f60SXin Li #define htonl(x) __ntohl(x) 303*05b00f60SXin Li #define htons(x) __ntohs(x) 304*05b00f60SXin Li __ntohl(unsigned long x)305*05b00f60SXin Li static __inline__ unsigned long __ntohl (unsigned long x) 306*05b00f60SXin Li { 307*05b00f60SXin Li __asm__ ("xchgb %b0, %h0\n\t" /* swap lower bytes */ 308*05b00f60SXin Li "rorl $16, %0\n\t" /* swap words */ 309*05b00f60SXin Li "xchgb %b0, %h0" /* swap higher bytes */ 310*05b00f60SXin Li : "=q" (x) : "0" (x)); 311*05b00f60SXin Li return (x); 312*05b00f60SXin Li } 313*05b00f60SXin Li __ntohs(unsigned short x)314*05b00f60SXin Li static __inline__ unsigned short __ntohs (unsigned short x) 315*05b00f60SXin Li { 316*05b00f60SXin Li __asm__ ("xchgb %b0, %h0" /* swap bytes */ 317*05b00f60SXin Li : "=q" (x) : "0" (x)); 318*05b00f60SXin Li return (x); 319*05b00f60SXin Li } 320*05b00f60SXin Li #endif 321*05b00f60SXin Li 322*05b00f60SXin Li /* 323*05b00f60SXin Li * If the OS doesn't define AF_INET6 and struct in6_addr: 324*05b00f60SXin Li * 325*05b00f60SXin Li * define AF_INET6, so we can use it internally as a "this is an 326*05b00f60SXin Li * IPv6 address" indication; 327*05b00f60SXin Li * 328*05b00f60SXin Li * define struct in6_addr so that we can use it for IPv6 addresses. 329*05b00f60SXin Li */ 330*05b00f60SXin Li #ifndef HAVE_OS_IPV6_SUPPORT 331*05b00f60SXin Li #ifndef AF_INET6 332*05b00f60SXin Li #define AF_INET6 24 333*05b00f60SXin Li 334*05b00f60SXin Li struct in6_addr { 335*05b00f60SXin Li union { 336*05b00f60SXin Li __uint8_t __u6_addr8[16]; 337*05b00f60SXin Li __uint16_t __u6_addr16[8]; 338*05b00f60SXin Li __uint32_t __u6_addr32[4]; 339*05b00f60SXin Li } __u6_addr; /* 128-bit IP6 address */ 340*05b00f60SXin Li }; 341*05b00f60SXin Li #endif 342*05b00f60SXin Li #endif 343*05b00f60SXin Li 344*05b00f60SXin Li #ifndef NI_MAXHOST 345*05b00f60SXin Li #define NI_MAXHOST 1025 346*05b00f60SXin Li #endif 347*05b00f60SXin Li 348*05b00f60SXin Li #ifndef INET_ADDRSTRLEN 349*05b00f60SXin Li #define INET_ADDRSTRLEN 16 350*05b00f60SXin Li #endif 351*05b00f60SXin Li 352*05b00f60SXin Li #ifndef TRUE 353*05b00f60SXin Li #define TRUE 1 354*05b00f60SXin Li #endif 355*05b00f60SXin Li 356*05b00f60SXin Li #ifndef FALSE 357*05b00f60SXin Li #define FALSE 0 358*05b00f60SXin Li #endif 359*05b00f60SXin Li 360*05b00f60SXin Li /* 361*05b00f60SXin Li * Statement attributes, for various compilers. 362*05b00f60SXin Li * 363*05b00f60SXin Li * This was introduced sufficiently recently that compilers implementing 364*05b00f60SXin Li * it also implement __has_attribute() (for example, GCC 5.0 and later 365*05b00f60SXin Li * have __has_attribute(), and the "fallthrough" attribute was introduced 366*05b00f60SXin Li * in GCC 7). 367*05b00f60SXin Li * 368*05b00f60SXin Li * Unfortunately, Clang does this wrong - a statement 369*05b00f60SXin Li * 370*05b00f60SXin Li * __attribute__ ((fallthrough)); 371*05b00f60SXin Li * 372*05b00f60SXin Li * produces bogus -Wmissing-declaration "declaration does not declare 373*05b00f60SXin Li * anything" warnings (dear Clang: that's not a declaration, it's an 374*05b00f60SXin Li * empty statement). GCC, however, has no trouble with this. 375*05b00f60SXin Li */ 376*05b00f60SXin Li #if __has_attribute(fallthrough) && !defined(__clang__) 377*05b00f60SXin Li # define ND_FALL_THROUGH __attribute__ ((fallthrough)) 378*05b00f60SXin Li #else 379*05b00f60SXin Li # define ND_FALL_THROUGH 380*05b00f60SXin Li #endif /* __has_attribute(fallthrough) */ 381*05b00f60SXin Li 382*05b00f60SXin Li #endif /* netdissect_stdinc_h */ 383