summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2018-01-21 17:57:20 -0800
committerGuy Harris <guy@alum.mit.edu>2018-01-21 17:57:20 -0800
commit45fc519a2ac35af5805204418c370136aa0db1f7 (patch)
tree4fb15d49aabe44730e7e042ee1a658de7040faa6
parentc29177f65837dfa7bc18daf7df872069811ab91e (diff)
downloadtcpdump-45fc519a2ac35af5805204418c370136aa0db1f7.tar.gz
Don't test for __attribute__ in the configure script.
Instead, use compiler test macros to check whether *particular* attributes are supported, and set various #defines appropriately, in header files. Rename the UNALIGNED structure attribute to ND_UNALIGNED, and ask whether we still need it.
-rw-r--r--CMakeLists.txt5
-rw-r--r--Makefile.in6
-rw-r--r--aclocal.m4113
-rw-r--r--cmakeconfig.h.in7
-rw-r--r--compiler-tests.h151
-rw-r--r--config.h.in7
-rwxr-xr-xconfigure144
-rw-r--r--configure.ac5
-rw-r--r--extract.h9
-rw-r--r--funcattrs.h16
-rw-r--r--ip6.h12
-rw-r--r--netdissect-stdinc.h58
-rw-r--r--netdissect.h4
-rw-r--r--print-bootp.c4
-rw-r--r--print-dccp.c10
-rw-r--r--tcp.h2
-rw-r--r--tcpdump.c16
-rw-r--r--varattrs.h59
18 files changed, 291 insertions, 337 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7c430f13..d92019d8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -63,11 +63,6 @@ include_directories(
if(MSVC)
add_definitions(-D__STDC__)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
- add_definitions("-D_U_=")
-elseif(CMAKE_COMPILER_IS_GNUCXX)
- add_definitions("-D_U_=__attribute__((unused))")
-else(MSVC)
- add_definitions("-D_U_=")
endif(MSVC)
if(MSVC)
diff --git a/Makefile.in b/Makefile.in
index 0f4f2c35..6842b60b 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -258,6 +258,7 @@ HDR = \
ascii_strcasecmp.h \
atm.h \
chdlc.h \
+ compiler-tests.h \
cpack.h \
ethertype.h \
extract.h \
@@ -277,6 +278,7 @@ HDR = \
mpls.h \
nameser.h \
netdissect.h \
+ netdissect-stdinc.h \
nfs.h \
nfsfh.h \
nlpid.h \
@@ -293,9 +295,9 @@ HDR = \
smb.h \
strtoaddr.h \
tcp.h \
- netdissect-stdinc.h \
timeval-operations.h \
- udp.h
+ udp.h \
+ varattrs.h
TAGHDR = \
/usr/include/arpa/tftp.h \
diff --git a/aclocal.m4 b/aclocal.m4
index 6af76f10..bd72a0a7 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1045,119 +1045,6 @@ dnl LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
dnl OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
dnl SUCH DAMAGE.
-dnl
-dnl Test for __attribute__
-dnl
-
-AC_DEFUN(AC_C___ATTRIBUTE__, [
-AC_MSG_CHECKING(for __attribute__)
-AC_CACHE_VAL(ac_cv___attribute__, [
-AC_COMPILE_IFELSE([
- AC_LANG_SOURCE([[
-#include <stdlib.h>
-
-static void foo(void) __attribute__ ((noreturn));
-
-static void
-foo(void)
-{
- exit(1);
-}
-
-int
-main(int argc, char **argv)
-{
- foo();
-}
- ]])],
-ac_cv___attribute__=yes,
-ac_cv___attribute__=no)])
-if test "$ac_cv___attribute__" = "yes"; then
- AC_DEFINE(HAVE___ATTRIBUTE__, 1, [define if your compiler has __attribute__])
-else
- #
- # We can't use __attribute__, so we can't use __attribute__((unused)),
- # so we define _U_ to an empty string.
- #
- V_DEFS="$V_DEFS -D_U_=\"\""
-fi
-AC_MSG_RESULT($ac_cv___attribute__)
-])
-
-
-dnl
-dnl Test whether __attribute__((unused)) can be used without warnings
-dnl
-
-AC_DEFUN(AC_C___ATTRIBUTE___UNUSED, [
-AC_MSG_CHECKING([whether __attribute__((unused)) can be used without warnings])
-AC_CACHE_VAL(ac_cv___attribute___unused, [
-save_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
-AC_COMPILE_IFELSE([
- AC_LANG_SOURCE([[
-#include <stdlib.h>
-#include <stdio.h>
-
-int
-main(int argc __attribute((unused)), char **argv __attribute((unused)))
-{
- printf("Hello, world!\n");
- return 0;
-}
- ]])],
-ac_cv___attribute___unused=yes,
-ac_cv___attribute___unused=no)])
-CFLAGS="$save_CFLAGS"
-if test "$ac_cv___attribute___unused" = "yes"; then
- V_DEFS="$V_DEFS -D_U_=\"__attribute__((unused))\""
-else
- V_DEFS="$V_DEFS -D_U_=\"\""
-fi
-AC_MSG_RESULT($ac_cv___attribute___unused)
-])
-
-dnl
-dnl Test whether __attribute__((fallthrough)) can be used without warnings
-dnl
-
-AC_DEFUN(AC_C___ATTRIBUTE___FALLTHROUGH, [
-AC_MSG_CHECKING([whether __attribute__((fallthrough)) can be used without warnings])
-AC_CACHE_VAL(ac_cv___attribute___fallthrough, [
-save_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
-AC_COMPILE_IFELSE([
- AC_LANG_SOURCE([[
-#include <stdio.h>
-
-int
-main(int argc, char **argv)
-{
- int x = 1;
- switch (x)
- {
- case 1:
- printf ("x == %d\n", x);
- __attribute__ ((fallthrough));
- case 2:
- printf ("x == %d\n", x);
- break;
- default:
- return 0;
- }
- return x;
-}
- ]])],
-ac_cv___attribute___fallthrough=yes,
-ac_cv___attribute___fallthrough=no)])
-CFLAGS="$save_CFLAGS"
-if test "$ac_cv___attribute___fallthrough" = "yes"; then
- AC_DEFINE(__ATTRIBUTE___FALLTHROUGH_OK, 1,
- [define if your compiler allows __attribute__((fallthrough)) without a warning])
-fi
-AC_MSG_RESULT($ac_cv___attribute___fallthrough)
-])
-
AC_DEFUN(AC_LBL_SSLEAY,
[
#
diff --git a/cmakeconfig.h.in b/cmakeconfig.h.in
index 3f0ff7de..6b6adc32 100644
--- a/cmakeconfig.h.in
+++ b/cmakeconfig.h.in
@@ -250,9 +250,6 @@
/* define if libpcap has yydebug */
#cmakedefine HAVE_YYDEBUG 1
-/* define if your compiler has __attribute__ */
-#cmakedefine HAVE___ATTRIBUTE__ 1
-
/* Define to 1 if netenet/dnetdb.h declares `dnet_htoa' */
#cmakedefine NETDNET_DNETDB_H_DECLARES_DNET_HTOA 1
@@ -298,10 +295,6 @@
/* define on AIX to get certain functions */
#cmakedefine _SUN 1
-/* define if your compiler allows __attribute__((fallthrough)) without a
- warning */
-#cmakedefine __ATTRIBUTE___FALLTHROUGH_OK 1
-
/* to handle Ultrix compilers that don't support const in prototypes */
#cmakedefine const 1
diff --git a/compiler-tests.h b/compiler-tests.h
new file mode 100644
index 00000000..47ec5739
--- /dev/null
+++ b/compiler-tests.h
@@ -0,0 +1,151 @@
+/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef nd_compiler_tests_h
+#define nd_compiler_tests_h
+
+/*
+ * This was introduced by Clang:
+ *
+ * http://clang.llvm.org/docs/LanguageExtensions.html#has-attribute
+ *
+ * in some version (which version?); it has been picked up by GCC 5.0.
+ */
+#ifndef __has_attribute
+ /*
+ * It's a macro, so you can check whether it's defined to check
+ * whether it's supported.
+ *
+ * If it's not, define it to always return 0, so that we move on to
+ * the fallback checks.
+ */
+ #define __has_attribute(x) 0
+#endif
+
+/*
+ * Note that the C90 spec's "6.8.1 Conditional inclusion" and the
+ * C99 spec's and C11 spec's "6.10.1 Conditional inclusion" say:
+ *
+ * Prior to evaluation, macro invocations in the list of preprocessing
+ * tokens that will become the controlling constant expression are
+ * replaced (except for those macro names modified by the defined unary
+ * operator), just as in normal text. If the token "defined" is
+ * generated as a result of this replacement process or use of the
+ * "defined" unary operator does not match one of the two specified
+ * forms prior to macro replacement, the behavior is undefined.
+ *
+ * so you shouldn't use defined() in a #define that's used in #if or
+ * #elif. Some versions of Clang, for example, will warn about this.
+ *
+ * Instead, we check whether the pre-defined macros for particular
+ * compilers are defined and, if not, define the "is this version XXX
+ * or a later version of this compiler" macros as 0.
+ */
+
+/*
+ * Check whether this is GCC major.minor or a later release, or some
+ * compiler that claims to be "just like GCC" of that version or a
+ * later release.
+ */
+
+#if ! defined(__GNUC__)
+#define ND_IS_AT_LEAST_GNUC_VERSION(major, minor) 0
+#else
+#define ND_IS_AT_LEAST_GNUC_VERSION(major, minor) \
+ (__GNUC__ > (major) || \
+ (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
+#endif
+
+/*
+ * Check whether this is Sun C/SunPro C/Oracle Studio major.minor
+ * or a later release.
+ *
+ * The version number in __SUNPRO_C is encoded in hex BCD, with the
+ * uppermost hex digit being the major version number, the next
+ * one or two hex digits being the minor version number, and
+ * the last digit being the patch version.
+ *
+ * It represents the *compiler* version, not the product version;
+ * see
+ *
+ * https://sourceforge.net/p/predef/wiki/Compilers/
+ *
+ * for a partial mapping, which we assume continues for later
+ * 12.x product releases.
+ */
+
+#if ! defined(__SUNPRO_C)
+#define ND_IS_AT_LEAST_SUNC_VERSION(major,minor) 0
+#else
+#define ND_SUNPRO_VERSION_TO_BCD(major, minor) \
+ (((minor) >= 10) ? \
+ (((major) << 12) | (((minor)/10) << 8) | (((minor)%10) << 4)) : \
+ (((major) << 8) | ((minor) << 4)))
+#define ND_IS_AT_LEAST_SUNC_VERSION(major,minor) \
+ (__SUNPRO_C >= ND_SUNPRO_VERSION_TO_BCD((major), (minor)))
+#endif
+
+/*
+ * Check whether this is IBM XL C major.minor or a later release.
+ *
+ * The version number in __xlC__ has the major version in the
+ * upper 8 bits and the minor version in the lower 8 bits.
+ */
+
+#if ! defined(__xlC__)
+#define ND_IS_AT_LEAST_XL_C_VERSION(major,minor) 0
+#else
+#define ND_IS_AT_LEAST_XL_C_VERSION(major, minor) \
+ (__xlC__ >= (((major) << 8) | (minor)))
+#endif
+
+/*
+ * Check whether this is HP aC++/HP C major.minor or a later release.
+ *
+ * The version number in __HP_aCC is encoded in zero-padded decimal BCD,
+ * with the "A." stripped off, the uppermost two decimal digits being
+ * the major version number, the next two decimal digits being the minor
+ * version number, and the last two decimal digits being the patch version.
+ * (Strip off the A., remove the . between the major and minor version
+ * number, and add two digits of patch.)
+ */
+
+#if ! defined(__HP_aCC)
+#define ND_IS_AT_LEAST_HP_C_VERSION(major,minor) 0
+#else
+#define ND_IS_AT_LEAST_HP_C_VERSION(major,minor) \
+ (__HP_aCC >= ((major)*10000 + (minor)*100))
+#endif
+
+#endif /* nd_funcattrs_h */
diff --git a/config.h.in b/config.h.in
index e0351163..6d6930b1 100644
--- a/config.h.in
+++ b/config.h.in
@@ -250,9 +250,6 @@
/* define if libpcap has yydebug */
#undef HAVE_YYDEBUG
-/* define if your compiler has __attribute__ */
-#undef HAVE___ATTRIBUTE__
-
/* Define to 1 if netenet/dnetdb.h declares `dnet_htoa' */
#undef NETDNET_DNETDB_H_DECLARES_DNET_HTOA
@@ -298,10 +295,6 @@
/* define on AIX to get certain functions */
#undef _SUN
-/* define if your compiler allows __attribute__((fallthrough)) without a
- warning */
-#undef __ATTRIBUTE___FALLTHROUGH_OK
-
/* to handle Ultrix compilers that don't support const in prototypes */
#undef const
diff --git a/configure b/configure
index 0c093913..aeeecb6c 100755
--- a/configure
+++ b/configure
@@ -3628,150 +3628,6 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __attribute__" >&5
-$as_echo_n "checking for __attribute__... " >&6; }
-if ${ac_cv___attribute__+:} false; then :
- $as_echo_n "(cached) " >&6
-else
-
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-
-#include <stdlib.h>
-
-static void foo(void) __attribute__ ((noreturn));
-
-static void
-foo(void)
-{
- exit(1);
-}
-
-int
-main(int argc, char **argv)
-{
- foo();
-}
-
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv___attribute__=yes
-else
- ac_cv___attribute__=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-if test "$ac_cv___attribute__" = "yes"; then
-
-$as_echo "#define HAVE___ATTRIBUTE__ 1" >>confdefs.h
-
-else
- #
- # We can't use __attribute__, so we can't use __attribute__((unused)),
- # so we define _U_ to an empty string.
- #
- V_DEFS="$V_DEFS -D_U_=\"\""
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv___attribute__" >&5
-$as_echo "$ac_cv___attribute__" >&6; }
-
-if test "$ac_cv___attribute__" = "yes"; then
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether __attribute__((unused)) can be used without warnings" >&5
-$as_echo_n "checking whether __attribute__((unused)) can be used without warnings... " >&6; }
-if ${ac_cv___attribute___unused+:} false; then :
- $as_echo_n "(cached) " >&6
-else
-
-save_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-
-#include <stdlib.h>
-#include <stdio.h>
-
-int
-main(int argc __attribute((unused)), char **argv __attribute((unused)))
-{
- printf("Hello, world!\n");
- return 0;
-}
-
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv___attribute___unused=yes
-else
- ac_cv___attribute___unused=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-CFLAGS="$save_CFLAGS"
-if test "$ac_cv___attribute___unused" = "yes"; then
- V_DEFS="$V_DEFS -D_U_=\"__attribute__((unused))\""
-else
- V_DEFS="$V_DEFS -D_U_=\"\""
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv___attribute___unused" >&5
-$as_echo "$ac_cv___attribute___unused" >&6; }
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether __attribute__((fallthrough)) can be used without warnings" >&5
-$as_echo_n "checking whether __attribute__((fallthrough)) can be used without warnings... " >&6; }
-if ${ac_cv___attribute___fallthrough+:} false; then :
- $as_echo_n "(cached) " >&6
-else
-
-save_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-
-#include <stdio.h>
-
-int
-main(int argc, char **argv)
-{
- int x = 1;
- switch (x)
- {
- case 1:
- printf ("x == %d\n", x);
- __attribute__ ((fallthrough));
- case 2:
- printf ("x == %d\n", x);
- break;
- default:
- return 0;
- }
- return x;
-}
-
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv___attribute___fallthrough=yes
-else
- ac_cv___attribute___fallthrough=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-CFLAGS="$save_CFLAGS"
-if test "$ac_cv___attribute___fallthrough" = "yes"; then
-
-$as_echo "#define __ATTRIBUTE___FALLTHROUGH_OK 1" >>confdefs.h
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv___attribute___fallthrough" >&5
-$as_echo "$ac_cv___attribute___fallthrough" >&6; }
-
-fi
-
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
diff --git a/configure.ac b/configure.ac
index 81ec675c..55dd3512 100644
--- a/configure.ac
+++ b/configure.ac
@@ -23,11 +23,6 @@ AC_LBL_C_INIT_BEFORE_CC(V_INCLS)
AC_PROG_CC_C99
AC_LBL_C_INIT(V_CCOPT, V_INCLS)
AC_LBL_C_INLINE
-AC_C___ATTRIBUTE__
-if test "$ac_cv___attribute__" = "yes"; then
- AC_C___ATTRIBUTE___UNUSED
- AC_C___ATTRIBUTE___FALLTHROUGH
-fi
AC_CHECK_HEADERS(fcntl.h rpc/rpc.h rpc/rpcent.h)
AC_CHECK_HEADERS(net/pfvar.h, , , [#include <sys/types.h>
diff --git a/extract.h b/extract.h
index 25bab1e2..713dd946 100644
--- a/extract.h
+++ b/extract.h
@@ -133,15 +133,16 @@ EXTRACT_IPV4_TO_HOST_ORDER(const void *p)
{
return ((uint32_t)ntohl(*(const uint32_t *)(p)));
}
-#elif defined(__GNUC__) && defined(HAVE___ATTRIBUTE__) && \
+#elif ND_IS_AT_LEAST_GNUC_VERSION(2,0) && \
(defined(__alpha) || defined(__alpha__) || \
defined(__mips) || defined(__mips__))
/*
* This is MIPS or Alpha, which don't natively handle unaligned loads,
* but which have instructions that can help when doing unaligned
- * loads, and this is a GCC-compatible compiler and we have __attribute__,
- * which we assume that mean we have __attribute__((packed)), which
- * we can use to convince the compiler to generate those instructions.
+ * loads, and this is GCC 2.0 or later or a compiler that claims to
+ * be GCC 2.0 or later, which we assume that mean we have
+ * __attribute__((packed)), which we can use to convince the compiler
+ * to generate those instructions.
*
* Declare packed structures containing a uint16_t and a uint32_t,
* cast the pointer to point to one of those, and fetch through it;
diff --git a/funcattrs.h b/funcattrs.h
index cb0678ea..7fdbf925 100644
--- a/funcattrs.h
+++ b/funcattrs.h
@@ -35,6 +35,8 @@
#ifndef lib_funcattrs_h
#define lib_funcattrs_h
+#include "compiler-tests.h"
+
/*
* Attributes to apply to functions and their arguments, using various
* compiler-specific extensions.
@@ -65,10 +67,10 @@
* declaration, as the MSVC version has to go before the declaration.)
*/
#if __has_attribute(noreturn) \
- || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)) \
- || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) \
- || (defined(__xlC__) && __xlC__ >= 0x0A01) \
- || (defined(__HP_aCC) && __HP_aCC >= 61000)
+ || ND_IS_AT_LEAST_GNUC_VERSION(2,5) \
+ || ND_IS_AT_LEAST_SUNC_VERSION(5,9) \
+ || ND_IS_AT_LEAST_XL_C_VERSION(10,1) \
+ || ND_IS_AT_LEAST_HP_C_VERSION(6,10)
/*
* Compiler with support for __attribute((noreturn)), or GCC 2.5 and
* later, or Solaris Studio 12 (Sun C 5.9) and later, or IBM XL C 10.1
@@ -109,9 +111,9 @@
* string".
*/
#if __has_attribute(__format__) \
- || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)) \
- || (defined(__xlC__) && __xlC__ >= 0x0A01) \
- || (defined(__HP_aCC) && __HP_aCC >= 61000)
+ || ND_IS_AT_LEAST_GNUC_VERSION(2,3) \
+ || ND_IS_AT_LEAST_XL_C_VERSION(10,1) \
+ || ND_IS_AT_LEAST_HP_C_VERSION(6,10)
/*
* Compiler with support for it, or GCC 2.3 and later, or IBM XL C 10.1
* and later (do any earlier versions of XL C support this?),
diff --git a/ip6.h b/ip6.h
index 9ed1499c..612f30cf 100644
--- a/ip6.h
+++ b/ip6.h
@@ -85,7 +85,7 @@ struct ip6_hdr {
} ip6_ctlun;
struct in6_addr ip6_src; /* source address */
struct in6_addr ip6_dst; /* destination address */
-} UNALIGNED;
+} ND_UNALIGNED;
#define ip6_vfc ip6_ctlun.ip6_un2_vfc
#define IP6_VERSION(ip6_hdr) ((EXTRACT_U_1((ip6_hdr)->ip6_vfc) & 0xf0) >> 4)
@@ -111,21 +111,21 @@ struct ip6_hdr {
struct ip6_ext {
nd_uint8_t ip6e_nxt;
nd_uint8_t ip6e_len;
-} UNALIGNED;
+} ND_UNALIGNED;
/* Hop-by-Hop options header */
struct ip6_hbh {
nd_uint8_t ip6h_nxt; /* next header */
nd_uint8_t ip6h_len; /* length in units of 8 octets */
/* followed by options */
-} UNALIGNED;
+} ND_UNALIGNED;
/* Destination options header */
struct ip6_dest {
nd_uint8_t ip6d_nxt; /* next header */
nd_uint8_t ip6d_len; /* length in units of 8 octets */
/* followed by options */
-} UNALIGNED;
+} ND_UNALIGNED;
/* http://www.iana.org/assignments/ipv6-parameters/ipv6-parameters.xhtml */
@@ -170,7 +170,7 @@ struct ip6_rthdr {
nd_uint8_t ip6r_type; /* routing type */
nd_uint8_t ip6r_segleft; /* segments left */
/* followed by routing type specific data */
-} UNALIGNED;
+} ND_UNALIGNED;
#define IPV6_RTHDR_TYPE_0 0
#define IPV6_RTHDR_TYPE_2 2
@@ -208,7 +208,7 @@ struct ip6_frag {
nd_uint8_t ip6f_reserved; /* reserved field */
nd_uint16_t ip6f_offlg; /* offset, reserved, and flag */
nd_uint32_t ip6f_ident; /* identification */
-} UNALIGNED;
+} ND_UNALIGNED;
#define IP6F_OFF_MASK 0xfff8 /* mask out offset from ip6f_offlg */
#define IP6F_RESERVED_MASK 0x0006 /* reserved bits in ip6f_offlg */
diff --git a/netdissect-stdinc.h b/netdissect-stdinc.h
index c7c53db4..a05e1cfe 100644
--- a/netdissect-stdinc.h
+++ b/netdissect-stdinc.h
@@ -41,6 +41,10 @@
#include <errno.h>
+#include "compiler-tests.h"
+
+#include "varattrs.h"
+
/*
* Get the C99 types, and the PRI[doux]64 format strings, defined.
*/
@@ -273,25 +277,16 @@ typedef char* caddr_t;
#endif /* _WIN32 */
-#ifndef HAVE___ATTRIBUTE__
-#define __attribute__(x)
-#endif
-
/*
* Used to declare a structure unaligned, so that the C compiler,
* if necessary, generates code that doesn't assume alignment.
* This is required because there is no guarantee that the packet
* data we get from libpcap/WinPcap is properly aligned.
*
- * This assumes that, for all compilers that support __attribute__:
- *
- * 1) they support __attribute__((packed));
- *
- * 2) for all instruction set architectures requiring strict
- * alignment, declaring a structure with that attribute
- * causes the compiler to generate code that handles
- * misaligned 2-byte, 4-byte, and 8-byte integral
- * quantities.
+ * This assumes that, for all compilers that support __attribute__((packed)),
+ * for all instruction set architectures requiring strict alignment, declaring
+ * a structure with that attribute causes the compiler to generate code that
+ * handles misaligned 2-byte, 4-byte, and 8-byte integral quantities.
*
* It does not (yet) handle compilers where you can get the compiler
* to generate code of that sort by some other means.
@@ -307,11 +302,28 @@ typedef char* caddr_t;
*
* Note: this also requires that padding be put into the structure,
* at least for compilers where it's implemented as __attribute__((packed)).
+ *
+ * XXX - now that we're using nd_ types that are just arrays of bytes, is
+ * this still necessary? Are there any compilers that align structures,
+ * none of whose members require more than byte alignment, on more than
+ * one-byte boundaries, and assume a structure is aligned on such a
+ * boundary? (I have vague memories of either m68k or ARM compilers
+ * aligning on at least 2-byte boundaries.)
*/
-#if !(defined(_MSC_VER) && defined(UNALIGNED))
-/* MSVC may have its own macro defined with the same name and purpose. */
-#undef UNALIGNED
-#define UNALIGNED __attribute__((packed))
+#if ND_IS_AT_LEAST_GNUC_VERSION(2,0) || \
+ ND_IS_AT_LEAST_XL_C_VERSION(6,0)
+ /*
+ * GCC 2.0 or later, or a compiler that claims to be GCC 2.0 or later,
+ * or IBM XL C 6.0 or later.
+ *
+ * Use __attribute__((packed)).
+ */
+ #define ND_UNALIGNED __attribute__((packed))
+#else
+ /*
+ * Nothing.
+ */
+ #define ND_UNALIGNED
#endif
/*
@@ -477,10 +489,18 @@ struct in6_addr {
*/
#include "funcattrs.h"
-#ifdef __ATTRIBUTE___FALLTHROUGH_OK
+/*
+ * Statement attributes, for various compilers.
+ *
+ * This was introduced sufficiently recently that compilers implementing
+ * it also implement __has_attribute() (for example, GCC 5.0 and later
+ * have __has_attribute(), and the "fallthrough" attribute was introduced
+ * in GCC 7).
+ */
+#if __has_attribute(fallthrough)
# define ND_FALL_THROUGH __attribute__ ((fallthrough))
#else
# define ND_FALL_THROUGH
-#endif /* __ATTRIBUTE___FALLTHROUGH_OK */
+#endif /* __has_attribute(fallthrough) */
#endif /* netdissect_stdinc_h */
diff --git a/netdissect.h b/netdissect.h
index 60d62728..42f82b68 100644
--- a/netdissect.h
+++ b/netdissect.h
@@ -30,10 +30,6 @@
#endif
#include <sys/types.h>
-#ifndef HAVE___ATTRIBUTE__
-#define __attribute__(x)
-#endif
-
/*
* Data types corresponding to multi-byte integral values within data
* structures. These are defined as arrays of octets, so that they're
diff --git a/print-bootp.c b/print-bootp.c
index 0059cfa0..f5a9a44e 100644
--- a/print-bootp.c
+++ b/print-bootp.c
@@ -72,7 +72,7 @@ struct bootp {
nd_byte bp_sname[64]; /* server host name */
nd_byte bp_file[128]; /* boot file name */
nd_byte bp_vend[64]; /* vendor-specific area */
-} UNALIGNED;
+} ND_UNALIGNED;
#define BOOTPREPLY 2
#define BOOTPREQUEST 1
@@ -247,7 +247,7 @@ struct cmu_vend {
struct in_addr v_ins1, v_ins2; /* IEN-116 name servers */
struct in_addr v_ts1, v_ts2; /* Time servers */
nd_byte v_unused[24]; /* currently unused */
-} UNALIGNED;
+} ND_UNALIGNED;
/* v_flags values */
diff --git a/print-dccp.c b/print-dccp.c
index e98b1d7c..7c092a8a 100644
--- a/print-dccp.c
+++ b/print-dccp.c
@@ -51,7 +51,7 @@ struct dccp_hdr {
nd_uint16_t dccph_checksum;
nd_uint8_t dccph_xtr;
nd_uint24_t dccph_seq;
-} UNALIGNED;
+} ND_UNALIGNED;
/**
* struct dccp_hdr_ext - generic part of DCCP packet header, with a 48-bit
@@ -76,7 +76,7 @@ struct dccp_hdr_ext {
nd_uint8_t dccph_xtr;
nd_uint8_t reserved;
nd_uint48_t dccph_seq;
-} UNALIGNED;
+} ND_UNALIGNED;
#define DCCPH_CCVAL(dh) ((EXTRACT_U_1((dh)->dccph_ccval_cscov) >> 4) & 0xF)
#define DCCPH_CSCOV(dh) (EXTRACT_U_1((dh)->dccph_ccval_cscov) & 0xF)
@@ -91,7 +91,7 @@ struct dccp_hdr_ext {
*/
struct dccp_hdr_request {
nd_uint32_t dccph_req_service;
-} UNALIGNED;
+} ND_UNALIGNED;
/**
* struct dccp_hdr_response - Conection initiation response header
@@ -102,7 +102,7 @@ struct dccp_hdr_request {
struct dccp_hdr_response {
nd_uint64_t dccph_resp_ack; /* always 8 bytes, first 2 reserved */
nd_uint32_t dccph_resp_service;
-} UNALIGNED;
+} ND_UNALIGNED;
/**
* struct dccp_hdr_reset - Unconditionally shut down a connection
@@ -116,7 +116,7 @@ struct dccp_hdr_reset {
nd_uint8_t dccph_reset_data1;
nd_uint8_t dccph_reset_data2;
nd_uint8_t dccph_reset_data3;
-} UNALIGNED;
+} ND_UNALIGNED;
enum dccp_pkt_type {
DCCP_PKT_REQUEST = 0,
diff --git a/tcp.h b/tcp.h
index a6916052..33452043 100644
--- a/tcp.h
+++ b/tcp.h
@@ -47,7 +47,7 @@ struct tcphdr {
nd_uint16_t th_win; /* window */
nd_uint16_t th_sum; /* checksum */
nd_uint16_t th_urp; /* urgent pointer */
-} UNALIGNED;
+} ND_UNALIGNED;
#define TH_OFF(th) ((EXTRACT_U_1((th)->th_offx2) & 0xf0) >> 4)
diff --git a/tcpdump.c b/tcpdump.c
index 86c4c150..ddd5551d 100644
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -25,12 +25,6 @@
* Seth Webster <swebster@sst.ll.mit.edu>
*/
-#ifndef lint
-static const char copyright[] _U_ =
- "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
-The Regents of the University of California. All rights reserved.\n";
-#endif
-
/*
* tcpdump - dump traffic on a network
*
@@ -57,6 +51,16 @@ The Regents of the University of California. All rights reserved.\n";
#include "netdissect-stdinc.h"
+/*
+ * This must appear after including netdissect-stdinc.h, so that _U_ is
+ * defined.
+ */
+#ifndef lint
+static const char copyright[] _U_ =
+ "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
+The Regents of the University of California. All rights reserved.\n";
+#endif
+
#include <sys/stat.h>
#ifdef HAVE_FCNTL_H
diff --git a/varattrs.h b/varattrs.h
new file mode 100644
index 00000000..b3c16891
--- /dev/null
+++ b/varattrs.h
@@ -0,0 +1,59 @@
+/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef varattrs_h
+#define varattrs_h
+
+#include "compiler-tests.h"
+
+/*
+ * Attributes to apply to variables, using various compiler-specific
+ * extensions.
+ */
+
+#if __has_attribute(unused) \
+ || ND_IS_AT_LEAST_GNUC_VERSION(2,0)
+ /*
+ * Compiler with support for __attribute__((unused)), or GCC 2.0 and
+ * later, so it supports __attribute__((unused)).
+ */
+ #define _U_ __attribute__((unused))
+#else
+ /*
+ * We don't know of any way to mark a variable as unused.
+ */
+ #define _U_
+#endif
+
+#endif