13340d773SGleb Smirnoff /* 23340d773SGleb Smirnoff * Copyright (c) 2002 - 2003 33340d773SGleb Smirnoff * NetGroup, Politecnico di Torino (Italy) 43340d773SGleb Smirnoff * All rights reserved. 53340d773SGleb Smirnoff * 63340d773SGleb Smirnoff * Redistribution and use in source and binary forms, with or without 73340d773SGleb Smirnoff * modification, are permitted provided that the following conditions 83340d773SGleb Smirnoff * are met: 93340d773SGleb Smirnoff * 103340d773SGleb Smirnoff * 1. Redistributions of source code must retain the above copyright 113340d773SGleb Smirnoff * notice, this list of conditions and the following disclaimer. 123340d773SGleb Smirnoff * 2. Redistributions in binary form must reproduce the above copyright 133340d773SGleb Smirnoff * notice, this list of conditions and the following disclaimer in the 143340d773SGleb Smirnoff * documentation and/or other materials provided with the distribution. 153340d773SGleb Smirnoff * 3. Neither the name of the Politecnico di Torino nor the names of its 163340d773SGleb Smirnoff * contributors may be used to endorse or promote products derived from 173340d773SGleb Smirnoff * this software without specific prior written permission. 183340d773SGleb Smirnoff * 193340d773SGleb Smirnoff * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 203340d773SGleb Smirnoff * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 213340d773SGleb Smirnoff * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 223340d773SGleb Smirnoff * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 233340d773SGleb Smirnoff * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 243340d773SGleb Smirnoff * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 253340d773SGleb Smirnoff * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 263340d773SGleb Smirnoff * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 273340d773SGleb Smirnoff * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 283340d773SGleb Smirnoff * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 293340d773SGleb Smirnoff * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 303340d773SGleb Smirnoff */ 313340d773SGleb Smirnoff 323340d773SGleb Smirnoff /* 333340d773SGleb Smirnoff * Include the appropriate OS header files on Windows and various flavors 343340d773SGleb Smirnoff * of UNIX, include various non-OS header files on Windows, and define 353340d773SGleb Smirnoff * various items as needed, to isolate most of netdissect's platform 363340d773SGleb Smirnoff * differences to this one file. 373340d773SGleb Smirnoff */ 383340d773SGleb Smirnoff 393340d773SGleb Smirnoff #ifndef netdissect_stdinc_h 403340d773SGleb Smirnoff #define netdissect_stdinc_h 413340d773SGleb Smirnoff 42*ee67461eSJoseph Mingrone #include "ftmacros.h" 43*ee67461eSJoseph Mingrone 443340d773SGleb Smirnoff #include <errno.h> 453340d773SGleb Smirnoff 46*ee67461eSJoseph Mingrone #include "compiler-tests.h" 47*ee67461eSJoseph Mingrone 48*ee67461eSJoseph Mingrone #include "varattrs.h" 49*ee67461eSJoseph Mingrone 50*ee67461eSJoseph Mingrone /* 51*ee67461eSJoseph Mingrone * If we're compiling with Visual Studio, make sure we have at least 52*ee67461eSJoseph Mingrone * VS 2015 or later, so we have sufficient C99 support. 53*ee67461eSJoseph Mingrone * 54*ee67461eSJoseph Mingrone * XXX - verify that we have at least C99 support on UN*Xes? 55*ee67461eSJoseph Mingrone * 56*ee67461eSJoseph Mingrone * What about MinGW or various DOS toolchains? We're currently assuming 57*ee67461eSJoseph Mingrone * sufficient C99 support there. 58*ee67461eSJoseph Mingrone */ 59*ee67461eSJoseph Mingrone #if defined(_MSC_VER) 60*ee67461eSJoseph Mingrone /* 61*ee67461eSJoseph Mingrone * Make sure we have VS 2015 or later. 62*ee67461eSJoseph Mingrone */ 63*ee67461eSJoseph Mingrone #if _MSC_VER < 1900 64*ee67461eSJoseph Mingrone #error "Building tcpdump requires VS 2015 or later" 65*ee67461eSJoseph Mingrone #endif 66*ee67461eSJoseph Mingrone #endif 67*ee67461eSJoseph Mingrone 68*ee67461eSJoseph Mingrone /* 69*ee67461eSJoseph Mingrone * Get the C99 types, and the PRI[doux]64 format strings, defined. 70*ee67461eSJoseph Mingrone */ 71*ee67461eSJoseph Mingrone #ifdef HAVE_PCAP_PCAP_INTTYPES_H 72*ee67461eSJoseph Mingrone /* 73*ee67461eSJoseph Mingrone * We have pcap/pcap-inttypes.h; use that, as it'll do all the 74*ee67461eSJoseph Mingrone * work, and won't cause problems if a file includes this file 75*ee67461eSJoseph Mingrone * and later includes a pcap header file that also includes 76*ee67461eSJoseph Mingrone * pcap/pcap-inttypes.h. 77*ee67461eSJoseph Mingrone */ 78*ee67461eSJoseph Mingrone #include <pcap/pcap-inttypes.h> 79*ee67461eSJoseph Mingrone #else 80*ee67461eSJoseph Mingrone /* 81*ee67461eSJoseph Mingrone * OK, we don't have pcap/pcap-inttypes.h, so we'll have to 82*ee67461eSJoseph Mingrone * do the work ourselves, but at least we don't have to 83*ee67461eSJoseph Mingrone * worry about other headers including it and causing 84*ee67461eSJoseph Mingrone * clashes. 85*ee67461eSJoseph Mingrone */ 86*ee67461eSJoseph Mingrone 87*ee67461eSJoseph Mingrone /* 88*ee67461eSJoseph Mingrone * Include <inttypes.h> to get the integer types and PRi[doux]64 values 89*ee67461eSJoseph Mingrone * defined. 90*ee67461eSJoseph Mingrone * 91*ee67461eSJoseph Mingrone * If the compiler is MSVC, we require VS 2015 or newer, so we 92*ee67461eSJoseph Mingrone * have <inttypes.h> - and support for %zu in the formatted 93*ee67461eSJoseph Mingrone * printing functions. 94*ee67461eSJoseph Mingrone * 95*ee67461eSJoseph Mingrone * If the compiler is MinGW, we assume we have <inttypes.h> - and 96*ee67461eSJoseph Mingrone * support for %zu in the formatted printing functions. 97*ee67461eSJoseph Mingrone * 98*ee67461eSJoseph Mingrone * If the target is UN*X, we assume we have a C99-or-later development 99*ee67461eSJoseph Mingrone * environment, and thus have <inttypes.h> - and support for %zu in 100*ee67461eSJoseph Mingrone * the formatted printing functions. 101*ee67461eSJoseph Mingrone * 102*ee67461eSJoseph Mingrone * If the target is MS-DOS, we assume we have <inttypes.h> - and support 103*ee67461eSJoseph Mingrone * for %zu in the formatted printing functions. 104*ee67461eSJoseph Mingrone */ 105*ee67461eSJoseph Mingrone #include <inttypes.h> 106*ee67461eSJoseph Mingrone 107*ee67461eSJoseph Mingrone #if defined(_MSC_VER) 108*ee67461eSJoseph Mingrone /* 109*ee67461eSJoseph Mingrone * Suppress definition of intN_t in bittypes.h, which might be included 110*ee67461eSJoseph Mingrone * by <pcap/pcap.h> in older versions of WinPcap. 111*ee67461eSJoseph Mingrone * (Yes, HAVE_U_INTn_T, as the definition guards are UN*X-oriented.) 112*ee67461eSJoseph Mingrone */ 113*ee67461eSJoseph Mingrone #define HAVE_U_INT8_T 114*ee67461eSJoseph Mingrone #define HAVE_U_INT16_T 115*ee67461eSJoseph Mingrone #define HAVE_U_INT32_T 116*ee67461eSJoseph Mingrone #define HAVE_U_INT64_T 117*ee67461eSJoseph Mingrone #endif 118*ee67461eSJoseph Mingrone #endif /* HAVE_PCAP_PCAP_INTTYPES_H */ 119*ee67461eSJoseph Mingrone 1203340d773SGleb Smirnoff #ifdef _WIN32 1213340d773SGleb Smirnoff 1223340d773SGleb Smirnoff /* 1233340d773SGleb Smirnoff * Includes and definitions for Windows. 1243340d773SGleb Smirnoff */ 1253340d773SGleb Smirnoff 1263340d773SGleb Smirnoff #include <stdio.h> 1273340d773SGleb Smirnoff #include <winsock2.h> 1283340d773SGleb Smirnoff #include <ws2tcpip.h> 1293340d773SGleb Smirnoff #include <time.h> 1303340d773SGleb Smirnoff #include <io.h> 1313340d773SGleb Smirnoff #include <fcntl.h> 1323340d773SGleb Smirnoff #include <sys/types.h> 1333340d773SGleb Smirnoff 134*ee67461eSJoseph Mingrone #ifdef _MSC_VER 135*ee67461eSJoseph Mingrone /* 136*ee67461eSJoseph Mingrone * Compiler is MSVC. 137*ee67461eSJoseph Mingrone * 138*ee67461eSJoseph Mingrone * We require VS 2015 or newer, so we have strtoll(). Use that for 139*ee67461eSJoseph Mingrone * strtoint64_t(). 140*ee67461eSJoseph Mingrone */ 141*ee67461eSJoseph Mingrone #define strtoint64_t strtoll 1423340d773SGleb Smirnoff 1433340d773SGleb Smirnoff /* 144*ee67461eSJoseph Mingrone * And we have LL as a suffix for constants, so use that. 1453340d773SGleb Smirnoff */ 146*ee67461eSJoseph Mingrone #define INT64_T_CONSTANT(constant) (constant##LL) 147*ee67461eSJoseph Mingrone #else 148*ee67461eSJoseph Mingrone /* 149*ee67461eSJoseph Mingrone * Non-Microsoft compiler. 150*ee67461eSJoseph Mingrone * 151*ee67461eSJoseph Mingrone * XXX - should we use strtoll or should we use _strtoi64()? 152*ee67461eSJoseph Mingrone */ 153*ee67461eSJoseph Mingrone #define strtoint64_t strtoll 154*ee67461eSJoseph Mingrone 155*ee67461eSJoseph Mingrone /* 156*ee67461eSJoseph Mingrone * Assume LL works. 157*ee67461eSJoseph Mingrone */ 158*ee67461eSJoseph Mingrone #define INT64_T_CONSTANT(constant) (constant##LL) 159*ee67461eSJoseph Mingrone #endif 1603340d773SGleb Smirnoff 1613340d773SGleb Smirnoff #ifdef _MSC_VER 162*ee67461eSJoseph Mingrone /* 163*ee67461eSJoseph Mingrone * Microsoft tries to avoid polluting the C namespace with UN*Xisms, 164*ee67461eSJoseph Mingrone * by adding a preceding underscore; we *want* the UN*Xisms, so add 165*ee67461eSJoseph Mingrone * #defines to let us use them. 166*ee67461eSJoseph Mingrone */ 167*ee67461eSJoseph Mingrone #define isatty _isatty 1683340d773SGleb Smirnoff #define stat _stat 169*ee67461eSJoseph Mingrone #define strdup _strdup 1703340d773SGleb Smirnoff #define open _open 1713340d773SGleb Smirnoff #define read _read 1723340d773SGleb Smirnoff #define close _close 1733340d773SGleb Smirnoff #define O_RDONLY _O_RDONLY 174*ee67461eSJoseph Mingrone 175*ee67461eSJoseph Mingrone /* 176*ee67461eSJoseph Mingrone * We define our_fstat64 as _fstati64, and define our_statb as 177*ee67461eSJoseph Mingrone * struct _stati64, so we get 64-bit file sizes. 178*ee67461eSJoseph Mingrone */ 179*ee67461eSJoseph Mingrone #define our_fstat _fstati64 180*ee67461eSJoseph Mingrone #define our_statb struct _stati64 181*ee67461eSJoseph Mingrone 182*ee67461eSJoseph Mingrone /* 183*ee67461eSJoseph Mingrone * If <crtdbg.h> has been included, and _DEBUG is defined, and 184*ee67461eSJoseph Mingrone * __STDC__ is zero, <crtdbg.h> will define strdup() to call 185*ee67461eSJoseph Mingrone * _strdup_dbg(). So if it's already defined, don't redefine 186*ee67461eSJoseph Mingrone * it. 187*ee67461eSJoseph Mingrone */ 188*ee67461eSJoseph Mingrone #ifndef strdup 189*ee67461eSJoseph Mingrone #define strdup _strdup 190*ee67461eSJoseph Mingrone #endif 191*ee67461eSJoseph Mingrone 192*ee67461eSJoseph Mingrone /* 193*ee67461eSJoseph Mingrone * Windows doesn't have ssize_t; routines such as _read() return int. 194*ee67461eSJoseph Mingrone */ 195*ee67461eSJoseph Mingrone typedef int ssize_t; 1963340d773SGleb Smirnoff #endif /* _MSC_VER */ 1973340d773SGleb Smirnoff 1983340d773SGleb Smirnoff /* 1993340d773SGleb Smirnoff * With MSVC, for C, __inline is used to make a function an inline. 2003340d773SGleb Smirnoff */ 2013340d773SGleb Smirnoff #ifdef _MSC_VER 2023340d773SGleb Smirnoff #define inline __inline 2033340d773SGleb Smirnoff #endif 2043340d773SGleb Smirnoff 205*ee67461eSJoseph Mingrone #if defined(AF_INET6) && !defined(HAVE_OS_IPV6_SUPPORT) 2063340d773SGleb Smirnoff #define HAVE_OS_IPV6_SUPPORT 2073340d773SGleb Smirnoff #endif 2083340d773SGleb Smirnoff 2093340d773SGleb Smirnoff #ifndef INET6_ADDRSTRLEN 2103340d773SGleb Smirnoff #define INET6_ADDRSTRLEN 46 2113340d773SGleb Smirnoff #endif 2123340d773SGleb Smirnoff 2133340d773SGleb Smirnoff /* It is in MSVC's <errno.h>, but not defined in MingW+Watcom. 2143340d773SGleb Smirnoff */ 2153340d773SGleb Smirnoff #ifndef EAFNOSUPPORT 2163340d773SGleb Smirnoff #define EAFNOSUPPORT WSAEAFNOSUPPORT 2173340d773SGleb Smirnoff #endif 2183340d773SGleb Smirnoff 2193340d773SGleb Smirnoff #ifndef caddr_t 2203340d773SGleb Smirnoff typedef char *caddr_t; 2213340d773SGleb Smirnoff #endif /* caddr_t */ 2223340d773SGleb Smirnoff 2233340d773SGleb Smirnoff #define MAXHOSTNAMELEN 64 2243340d773SGleb Smirnoff 2253340d773SGleb Smirnoff #else /* _WIN32 */ 2263340d773SGleb Smirnoff 2273340d773SGleb Smirnoff /* 2283340d773SGleb Smirnoff * Includes and definitions for various flavors of UN*X. 2293340d773SGleb Smirnoff */ 2303340d773SGleb Smirnoff 2313340d773SGleb Smirnoff #include <unistd.h> 2323340d773SGleb Smirnoff #include <netdb.h> 2333340d773SGleb Smirnoff #include <sys/param.h> 2343340d773SGleb Smirnoff #include <sys/types.h> /* concession to AIX */ 2353340d773SGleb Smirnoff #include <sys/time.h> 2363340d773SGleb Smirnoff #include <sys/socket.h> 2373340d773SGleb Smirnoff #include <netinet/in.h> 2383340d773SGleb Smirnoff 2393340d773SGleb Smirnoff #include <time.h> 2403340d773SGleb Smirnoff 2413340d773SGleb Smirnoff #include <arpa/inet.h> 2423340d773SGleb Smirnoff 243*ee67461eSJoseph Mingrone /* 244*ee67461eSJoseph Mingrone * We should have large file support enabled, if it's available, 245*ee67461eSJoseph Mingrone * so just use fstat as our_fstat and struct stat as our_statb. 246*ee67461eSJoseph Mingrone */ 247*ee67461eSJoseph Mingrone #define our_fstat fstat 248*ee67461eSJoseph Mingrone #define our_statb struct stat 2493340d773SGleb Smirnoff 2503340d773SGleb Smirnoff /* 251*ee67461eSJoseph Mingrone * Assume all UN*Xes have strtoll(), and use it for strtoint64_t(). 2523340d773SGleb Smirnoff */ 253*ee67461eSJoseph Mingrone #define strtoint64_t strtoll 254*ee67461eSJoseph Mingrone 255*ee67461eSJoseph Mingrone /* 256*ee67461eSJoseph Mingrone * Assume LL works. 257*ee67461eSJoseph Mingrone */ 258*ee67461eSJoseph Mingrone #define INT64_T_CONSTANT(constant) (constant##LL) 259*ee67461eSJoseph Mingrone #endif /* _WIN32 */ 260*ee67461eSJoseph Mingrone 261*ee67461eSJoseph Mingrone /* 262*ee67461eSJoseph Mingrone * Function attributes, for various compilers. 263*ee67461eSJoseph Mingrone */ 264*ee67461eSJoseph Mingrone #include "funcattrs.h" 2653340d773SGleb Smirnoff 2663340d773SGleb Smirnoff /* 2673340d773SGleb Smirnoff * fopen() read and write modes for text files and binary files. 2683340d773SGleb Smirnoff */ 2693340d773SGleb Smirnoff #if defined(_WIN32) || defined(MSDOS) 2703340d773SGleb Smirnoff #define FOPEN_READ_TXT "rt" 2713340d773SGleb Smirnoff #define FOPEN_READ_BIN "rb" 2723340d773SGleb Smirnoff #define FOPEN_WRITE_TXT "wt" 2733340d773SGleb Smirnoff #define FOPEN_WRITE_BIN "wb" 2743340d773SGleb Smirnoff #else 2753340d773SGleb Smirnoff #define FOPEN_READ_TXT "r" 2763340d773SGleb Smirnoff #define FOPEN_READ_BIN FOPEN_READ_TXT 2773340d773SGleb Smirnoff #define FOPEN_WRITE_TXT "w" 2783340d773SGleb Smirnoff #define FOPEN_WRITE_BIN FOPEN_WRITE_TXT 2793340d773SGleb Smirnoff #endif 2803340d773SGleb Smirnoff 2813340d773SGleb Smirnoff /* 2823340d773SGleb Smirnoff * Inline x86 assembler-language versions of ntoh[ls]() and hton[ls](), 2833340d773SGleb Smirnoff * defined if the OS doesn't provide them. These assume no more than 2843340d773SGleb Smirnoff * an 80386, so, for example, it avoids the bswap instruction added in 2853340d773SGleb Smirnoff * the 80486. 2863340d773SGleb Smirnoff * 287*ee67461eSJoseph Mingrone * (We don't use them on macOS; Apple provides their own, which *doesn't* 288*ee67461eSJoseph Mingrone * avoid the bswap instruction, as macOS only supports machines that 2893340d773SGleb Smirnoff * have it.) 2903340d773SGleb Smirnoff */ 2913340d773SGleb Smirnoff #if defined(__GNUC__) && defined(__i386__) && !defined(__APPLE__) && !defined(__ntohl) 2923340d773SGleb Smirnoff #undef ntohl 2933340d773SGleb Smirnoff #undef ntohs 2943340d773SGleb Smirnoff #undef htonl 2953340d773SGleb Smirnoff #undef htons 2963340d773SGleb Smirnoff 2973340d773SGleb Smirnoff static __inline__ unsigned long __ntohl (unsigned long x); 2983340d773SGleb Smirnoff static __inline__ unsigned short __ntohs (unsigned short x); 2993340d773SGleb Smirnoff 3003340d773SGleb Smirnoff #define ntohl(x) __ntohl(x) 3013340d773SGleb Smirnoff #define ntohs(x) __ntohs(x) 3023340d773SGleb Smirnoff #define htonl(x) __ntohl(x) 3033340d773SGleb Smirnoff #define htons(x) __ntohs(x) 3043340d773SGleb Smirnoff __ntohl(unsigned long x)3053340d773SGleb Smirnoff static __inline__ unsigned long __ntohl (unsigned long x) 3063340d773SGleb Smirnoff { 3073340d773SGleb Smirnoff __asm__ ("xchgb %b0, %h0\n\t" /* swap lower bytes */ 3083340d773SGleb Smirnoff "rorl $16, %0\n\t" /* swap words */ 3093340d773SGleb Smirnoff "xchgb %b0, %h0" /* swap higher bytes */ 3103340d773SGleb Smirnoff : "=q" (x) : "0" (x)); 3113340d773SGleb Smirnoff return (x); 3123340d773SGleb Smirnoff } 3133340d773SGleb Smirnoff __ntohs(unsigned short x)3143340d773SGleb Smirnoff static __inline__ unsigned short __ntohs (unsigned short x) 3153340d773SGleb Smirnoff { 3163340d773SGleb Smirnoff __asm__ ("xchgb %b0, %h0" /* swap bytes */ 3173340d773SGleb Smirnoff : "=q" (x) : "0" (x)); 3183340d773SGleb Smirnoff return (x); 3193340d773SGleb Smirnoff } 3203340d773SGleb Smirnoff #endif 3213340d773SGleb Smirnoff 3223340d773SGleb Smirnoff /* 3233340d773SGleb Smirnoff * If the OS doesn't define AF_INET6 and struct in6_addr: 3243340d773SGleb Smirnoff * 3253340d773SGleb Smirnoff * define AF_INET6, so we can use it internally as a "this is an 3263340d773SGleb Smirnoff * IPv6 address" indication; 3273340d773SGleb Smirnoff * 3283340d773SGleb Smirnoff * define struct in6_addr so that we can use it for IPv6 addresses. 3293340d773SGleb Smirnoff */ 3303340d773SGleb Smirnoff #ifndef HAVE_OS_IPV6_SUPPORT 3313340d773SGleb Smirnoff #ifndef AF_INET6 3323340d773SGleb Smirnoff #define AF_INET6 24 3333340d773SGleb Smirnoff 3343340d773SGleb Smirnoff struct in6_addr { 3353340d773SGleb Smirnoff union { 3363340d773SGleb Smirnoff __uint8_t __u6_addr8[16]; 3373340d773SGleb Smirnoff __uint16_t __u6_addr16[8]; 3383340d773SGleb Smirnoff __uint32_t __u6_addr32[4]; 3393340d773SGleb Smirnoff } __u6_addr; /* 128-bit IP6 address */ 3403340d773SGleb Smirnoff }; 3413340d773SGleb Smirnoff #endif 3423340d773SGleb Smirnoff #endif 3433340d773SGleb Smirnoff 3443340d773SGleb Smirnoff #ifndef NI_MAXHOST 3453340d773SGleb Smirnoff #define NI_MAXHOST 1025 3463340d773SGleb Smirnoff #endif 3473340d773SGleb Smirnoff 3483340d773SGleb Smirnoff #ifndef INET_ADDRSTRLEN 3493340d773SGleb Smirnoff #define INET_ADDRSTRLEN 16 3503340d773SGleb Smirnoff #endif 3513340d773SGleb Smirnoff 3523340d773SGleb Smirnoff #ifndef TRUE 3533340d773SGleb Smirnoff #define TRUE 1 3543340d773SGleb Smirnoff #endif 3553340d773SGleb Smirnoff 3563340d773SGleb Smirnoff #ifndef FALSE 3573340d773SGleb Smirnoff #define FALSE 0 3583340d773SGleb Smirnoff #endif 3593340d773SGleb Smirnoff 3603340d773SGleb Smirnoff /* 361*ee67461eSJoseph Mingrone * Statement attributes, for various compilers. 362*ee67461eSJoseph Mingrone * 363*ee67461eSJoseph Mingrone * This was introduced sufficiently recently that compilers implementing 364*ee67461eSJoseph Mingrone * it also implement __has_attribute() (for example, GCC 5.0 and later 365*ee67461eSJoseph Mingrone * have __has_attribute(), and the "fallthrough" attribute was introduced 366*ee67461eSJoseph Mingrone * in GCC 7). 367*ee67461eSJoseph Mingrone * 368*ee67461eSJoseph Mingrone * Unfortunately, Clang does this wrong - a statement 369*ee67461eSJoseph Mingrone * 370*ee67461eSJoseph Mingrone * __attribute__ ((fallthrough)); 371*ee67461eSJoseph Mingrone * 372*ee67461eSJoseph Mingrone * produces bogus -Wmissing-declaration "declaration does not declare 373*ee67461eSJoseph Mingrone * anything" warnings (dear Clang: that's not a declaration, it's an 374*ee67461eSJoseph Mingrone * empty statement). GCC, however, has no trouble with this. 3753340d773SGleb Smirnoff */ 376*ee67461eSJoseph Mingrone #if __has_attribute(fallthrough) && !defined(__clang__) 377*ee67461eSJoseph Mingrone # define ND_FALL_THROUGH __attribute__ ((fallthrough)) 3783340d773SGleb Smirnoff #else 379*ee67461eSJoseph Mingrone # define ND_FALL_THROUGH 380*ee67461eSJoseph Mingrone #endif /* __has_attribute(fallthrough) */ 3813340d773SGleb Smirnoff 3823340d773SGleb Smirnoff #endif /* netdissect_stdinc_h */ 383