diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/CMakeLists.txt | 42 | ||||
-rw-r--r-- | tests/can_set_rfmon_test.c | 92 | ||||
-rw-r--r-- | tests/capturetest.c | 67 | ||||
-rw-r--r-- | tests/filtertest.c | 115 | ||||
-rw-r--r-- | tests/findalldevstest.c | 56 | ||||
-rw-r--r-- | tests/opentest.c | 77 | ||||
-rw-r--r-- | tests/reactivatetest.c | 2 | ||||
-rw-r--r-- | tests/selpolltest.c | 73 | ||||
-rw-r--r-- | tests/valgrindtest.c | 90 |
9 files changed, 541 insertions, 73 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 000000000000..fc7919ed3808 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,42 @@ +cmake_minimum_required( VERSION 2.8.8 ) + +project( pcap_tests ) + +###################################### +# Register targets +###################################### + +if( MSVC ) + file(GLOB PROJECT_SOURCE_LIST_WIN32_C + ${pcap_SOURCE_DIR}/missing/getopt.c + ) +endif( MSVC ) + +ADD_EXECUTABLE (can_set_rfmon_test can_set_rfmon_test.c ${PROJECT_SOURCE_LIST_WIN32_C} ) +target_link_libraries ( can_set_rfmon_test pcap ) + +ADD_EXECUTABLE (capturetest capturetest.c ${PROJECT_SOURCE_LIST_WIN32_C} ) +target_link_libraries ( capturetest pcap ) + +ADD_EXECUTABLE (filtertest filtertest.c ${PROJECT_SOURCE_LIST_WIN32_C} ) +target_link_libraries ( filtertest pcap ) + +ADD_EXECUTABLE (indalldevstest findalldevstest.c ${PROJECT_SOURCE_LIST_WIN32_C} ) +target_link_libraries ( indalldevstest pcap ) + +ADD_EXECUTABLE (opentest opentest.c ${PROJECT_SOURCE_LIST_WIN32_C} ) +target_link_libraries ( opentest pcap ) + +#ADD_EXECUTABLE (pcap_compile_test pcap_compile_test.c ${PROJECT_SOURCE_LIST_WIN32_C} ) +#target_link_libraries ( pcap_compile_test pcap ) + +ADD_EXECUTABLE (reactivatetest reactivatetest.c ${PROJECT_SOURCE_LIST_WIN32_C} ) +target_link_libraries ( reactivatetest pcap ) + +if( NOT WIN32 ) + ADD_EXECUTABLE (selpolltest selpolltest.c ${PROJECT_SOURCE_LIST_WIN32_C} ) + target_link_libraries ( selpolltest pcap ) +endif() + +ADD_EXECUTABLE (valgrindtest valgrindtest.c ${PROJECT_SOURCE_LIST_WIN32_C} ) +target_link_libraries ( valgrindtest pcap ) diff --git a/tests/can_set_rfmon_test.c b/tests/can_set_rfmon_test.c new file mode 100644 index 000000000000..f1644e66b768 --- /dev/null +++ b/tests/can_set_rfmon_test.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000 + * 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: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#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 <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> + +#include <pcap.h> + +static const char *program_name; + +/* Forwards */ +static void error(const char *, ...); + +int +main(int argc, char **argv) +{ + const char *cp; + pcap_t *pd; + char ebuf[PCAP_ERRBUF_SIZE]; + int status; + + if ((cp = strrchr(argv[0], '/')) != NULL) + program_name = cp + 1; + else + program_name = argv[0]; + + if (argc != 2) { + fprintf(stderr, "Usage: %s <device>\n", program_name); + return 2; + } + + pd = pcap_create(argv[1], ebuf); + if (pd == NULL) + error("%s", ebuf); + status = pcap_can_set_rfmon(pd); + if (status < 0) { + if (status == PCAP_ERROR) + error("%s: pcap_can_set_rfmon failed: %s", argv[1], + pcap_geterr(pd)); + else + error("%s: pcap_can_set_rfmon failed: %s", argv[1], + pcap_statustostr(status)); + return 1; + } + printf("%s: Monitor mode %s be set\n", argv[1], status ? "can" : "cannot"); + return 0; +} + +/* VARARGS */ +static void +error(const char *fmt, ...) +{ + va_list ap; + + (void)fprintf(stderr, "%s: ", program_name); + va_start(ap, fmt); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + if (*fmt) { + fmt += strlen(fmt); + if (fmt[-1] != '\n') + (void)fputc('\n', stderr); + } + exit(1); + /* NOTREACHED */ +} diff --git a/tests/capturetest.c b/tests/capturetest.c index e70e69a514c1..14b1554b5189 100644 --- a/tests/capturetest.c +++ b/tests/capturetest.c @@ -20,7 +20,7 @@ */ #ifndef lint -static const char copyright[] = +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 @@ -30,29 +30,76 @@ The Regents of the University of California. All rights reserved.\n"; #include <string.h> #include <stdarg.h> #include <limits.h> +#ifdef _WIN32 +#include "getopt.h" +#else #include <unistd.h> +#endif #include <errno.h> #include <sys/types.h> -#include <sys/select.h> -#include <poll.h> #include <pcap.h> static char *program_name; +/* + * 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 + +#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) + /* + * Compiler with support for it, or GCC 2.5 and later, or Solaris Studio 12 + * (Sun C 5.9) and later, or IBM XL C 10.1 and later (do any earlier + * versions of XL C support this?), or HP aCC A.06.10 and later. + */ + #define PCAP_NORETURN __attribute((noreturn)) +#elif defined( _MSC_VER ) + #define PCAP_NORETURN __declspec(noreturn) +#else + #define PCAP_NORETURN +#endif + +#if __has_attribute(__format__) \ + || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)) \ + || (defined(__xlC__) && __xlC__ >= 0x0A01) \ + || (defined(__HP_aCC) && __HP_aCC >= 61000) + /* + * 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?), + * or HP aCC A.06.10 and later. + */ + #define PCAP_PRINTFLIKE(x,y) __attribute__((__format__(__printf__,x,y))) +#else + #define PCAP_PRINTFLIKE(x,y) +#endif + /* Forwards */ static void countme(u_char *, const struct pcap_pkthdr *, const u_char *); -static void usage(void) __attribute__((noreturn)); -static void error(const char *, ...); -static void warning(const char *, ...); +static void PCAP_NORETURN usage(void); +static void PCAP_NORETURN error(const char *, ...) PCAP_PRINTFLIKE(1, 2); +static void warning(const char *, ...) PCAP_PRINTFLIKE(1, 2); static char *copy_argv(char **); static pcap_t *pd; -extern int optind; -extern int opterr; -extern char *optarg; - int main(int argc, char **argv) { diff --git a/tests/filtertest.c b/tests/filtertest.c index d603376da64e..d4440eb06b3d 100644 --- a/tests/filtertest.c +++ b/tests/filtertest.c @@ -34,29 +34,81 @@ The Regents of the University of California. All rights reserved.\n"; #include <stdlib.h> #include <string.h> #include <stdarg.h> +#ifdef _WIN32 +#include "getopt.h" +#else #include <unistd.h> +#endif #include <fcntl.h> #include <errno.h> -#include <arpa/inet.h> +#ifdef _WIN32 + #include <winsock2.h> + typedef unsigned __int32 in_addr_t; +#else + #include <arpa/inet.h> +#endif #include <sys/types.h> #include <sys/stat.h> -#ifndef HAVE___ATTRIBUTE__ -#define __attribute__(x) +/* + * 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 + +#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) + /* + * Compiler with support for it, or GCC 2.5 and later, or Solaris Studio 12 + * (Sun C 5.9) and later, or IBM XL C 10.1 and later (do any earlier + * versions of XL C support this?), or HP aCC A.06.10 and later. + */ + #define PCAP_NORETURN __attribute((noreturn)) +#elif defined( _MSC_VER ) + #define PCAP_NORETURN __declspec(noreturn) +#else + #define PCAP_NORETURN +#endif + +#if __has_attribute(__format__) \ + || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)) \ + || (defined(__xlC__) && __xlC__ >= 0x0A01) \ + || (defined(__HP_aCC) && __HP_aCC >= 61000) + /* + * 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?), + * or HP aCC A.06.10 and later. + */ + #define PCAP_PRINTFLIKE(x,y) __attribute__((__format__(__printf__,x,y))) +#else + #define PCAP_PRINTFLIKE(x,y) #endif static char *program_name; /* Forwards */ -static void usage(void) __attribute__((noreturn)); -static void error(const char *, ...) - __attribute__((noreturn, format (printf, 1, 2))); -static void warn(const char *, ...) - __attribute__((format (printf, 1, 2))); +static void PCAP_NORETURN usage(void); +static void PCAP_NORETURN error(const char *, ...) PCAP_PRINTFLIKE(1, 2); +static void warn(const char *, ...) PCAP_PRINTFLIKE(1, 2); -extern int optind; -extern int opterr; -extern char *optarg; +#ifdef BDEBUG +int dflag; +#endif /* * On Windows, we need to open the file in binary mode, so that @@ -178,25 +230,36 @@ main(int argc, char **argv) { char *cp; int op; +#ifndef BDEBUG int dflag; +#endif char *infile; int Oflag; long snaplen; + char *p; int dlt; bpf_u_int32 netmask = PCAP_NETMASK_UNKNOWN; char *cmdbuf; pcap_t *pd; struct bpf_program fcode; -#ifdef WIN32 +#ifdef _WIN32 if(wsockinit() != 0) return 1; -#endif /* WIN32 */ +#endif /* _WIN32 */ +#ifndef BDEBUG dflag = 1; +#else + /* if optimizer debugging is enabled, output DOT graph + * `dflag=4' is equivalent to -dddd to follow -d/-dd/-ddd + * convention in tcpdump command line + */ + dflag = 4; +#endif infile = NULL; Oflag = 1; snaplen = 68; - + if ((cp = strrchr(argv[0], '/')) != NULL) program_name = cp + 1; else @@ -222,7 +285,7 @@ main(int argc, char **argv) in_addr_t addr; addr = inet_addr(optarg); - if (addr == INADDR_NONE) + if (addr == (in_addr_t)(-1)) error("invalid netmask %s", optarg); netmask = addr; break; @@ -252,9 +315,12 @@ main(int argc, char **argv) } dlt = pcap_datalink_name_to_val(argv[optind]); - if (dlt < 0) - error("invalid data link type %s", argv[optind]); - + if (dlt < 0) { + dlt = (int)strtol(argv[optind], &p, 10); + if (p == argv[optind] || *p != '\0') + error("invalid data link type %s", argv[optind]); + } + if (infile) cmdbuf = read_infile(infile); else @@ -266,8 +332,21 @@ main(int argc, char **argv) if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0) error("%s", pcap_geterr(pd)); + if (!bpf_validate(fcode.bf_insns, fcode.bf_len)) warn("Filter doesn't pass validation"); + +#ifdef BDEBUG + // replace line feed with space + for (cp = cmdbuf; *cp != '\0'; ++cp) { + if (*cp == '\r' || *cp == '\n') { + *cp = ' '; + } + } + // only show machine code if BDEBUG defined, since dflag > 3 + printf("machine codes for filter: %s\n", cmdbuf); +#endif + bpf_dump(&fcode, dflag); pcap_close(pd); exit(0); diff --git a/tests/findalldevstest.c b/tests/findalldevstest.c index ec7c95015c9e..5925bf6a8176 100644 --- a/tests/findalldevstest.c +++ b/tests/findalldevstest.c @@ -4,14 +4,18 @@ #include <stdlib.h> #include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <netdb.h> +#ifdef _WIN32 + #include <winsock2.h> +#else + #include <sys/socket.h> + #include <netinet/in.h> + #include <arpa/inet.h> + #include <netdb.h> +#endif #include <pcap.h> -static void ifprint(pcap_if_t *d); +static int ifprint(pcap_if_t *d); static char *iptos(bpf_u_int32 in); int main(int argc, char **argv) @@ -20,7 +24,8 @@ int main(int argc, char **argv) pcap_if_t *d; char *s; bpf_u_int32 net, mask; - + int exit_status = 0; + char errbuf[PCAP_ERRBUF_SIZE+1]; if (pcap_findalldevs(&alldevs, errbuf) == -1) { @@ -29,12 +34,14 @@ int main(int argc, char **argv) } for(d=alldevs;d;d=d->next) { - ifprint(d); + if (!ifprint(d)) + exit_status = 2; } if ( (s = pcap_lookupdev(errbuf)) == NULL) { fprintf(stderr,"Error in pcap_lookupdev: %s\n",errbuf); + exit_status = 2; } else { @@ -44,30 +51,47 @@ int main(int argc, char **argv) if (pcap_lookupnet(s, &net, &mask, errbuf) < 0) { fprintf(stderr,"Error in pcap_lookupnet: %s\n",errbuf); + exit_status = 2; } else { printf("Preferred device is on network: %s/%s\n",iptos(net), iptos(mask)); } - - exit(0); + + exit(exit_status); } -static void ifprint(pcap_if_t *d) +static int ifprint(pcap_if_t *d) { pcap_addr_t *a; #ifdef INET6 char ntop_buf[INET6_ADDRSTRLEN]; #endif + const char *sep; + int status = 1; /* success */ printf("%s\n",d->name); if (d->description) printf("\tDescription: %s\n",d->description); - printf("\tLoopback: %s\n",(d->flags & PCAP_IF_LOOPBACK)?"yes":"no"); + printf("\tFlags: "); + sep = ""; + if (d->flags & PCAP_IF_UP) { + printf("%sUP", sep); + sep = ", "; + } + if (d->flags & PCAP_IF_RUNNING) { + printf("%sRUNNING", sep); + sep = ", "; + } + if (d->flags & PCAP_IF_LOOPBACK) { + printf("%sLOOPBACK", sep); + sep = ", "; + } + printf("\n"); for(a=d->addresses;a;a=a->next) { - switch(a->addr->sa_family) - { + if (a->addr != NULL) + switch(a->addr->sa_family) { case AF_INET: printf("\tAddress Family: AF_INET\n"); if (a->addr) @@ -111,9 +135,15 @@ static void ifprint(pcap_if_t *d) default: printf("\tAddress Family: Unknown (%d)\n", a->addr->sa_family); break; + } + else + { + fprintf(stderr, "\tWarning: a->addr is NULL, skipping this address.\n"); + status = 0; } } printf("\n"); + return status; } /* From tcptraceroute */ diff --git a/tests/opentest.c b/tests/opentest.c index 0c91531018db..b6d634f0d901 100644 --- a/tests/opentest.c +++ b/tests/opentest.c @@ -20,7 +20,7 @@ */ #ifndef lint -static const char copyright[] = +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 @@ -30,21 +30,70 @@ The Regents of the University of California. All rights reserved.\n"; #include <stdlib.h> #include <string.h> #include <stdarg.h> +#ifdef _WIN32 +#include "getopt.h" +#else #include <unistd.h> +#endif #include <errno.h> #define MAXIMUM_SNAPLEN 65535 static char *program_name; -/* Forwards */ -static void usage(void) __attribute__((noreturn)); -static void error(const char *, ...); -static void warning(const char *, ...); +/* + * 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 -extern int optind; -extern int opterr; -extern char *optarg; +#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) + /* + * Compiler with support for it, or GCC 2.5 and later, or Solaris Studio 12 + * (Sun C 5.9) and later, or IBM XL C 10.1 and later (do any earlier + * versions of XL C support this?), or HP aCC A.06.10 and later. + */ + #define PCAP_NORETURN __attribute((noreturn)) +#elif defined( _MSC_VER ) + #define PCAP_NORETURN __declspec(noreturn) +#else + #define PCAP_NORETURN +#endif + +#if __has_attribute(__format__) \ + || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)) \ + || (defined(__xlC__) && __xlC__ >= 0x0A01) \ + || (defined(__HP_aCC) && __HP_aCC >= 61000) + /* + * 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?), + * or HP aCC A.06.10 and later. + */ + #define PCAP_PRINTFLIKE(x,y) __attribute__((__format__(__printf__,x,y))) +#else + #define PCAP_PRINTFLIKE(x,y) +#endif + +/* Forwards */ +static void PCAP_NORETURN usage(void); +static void PCAP_NORETURN error(const char *, ...) PCAP_PRINTFLIKE(1, 2); +static void warning(const char *, ...) PCAP_PRINTFLIKE(1, 2); int main(int argc, char **argv) @@ -113,10 +162,15 @@ main(int argc, char **argv) } } + if (device == NULL) { + device = pcap_lookupdev(ebuf); + if (device == NULL) + error("pcap_lookupdev failed: %s", ebuf); + } if (useactivate) { pd = pcap_create(device, ebuf); if (pd == NULL) - error("%s", ebuf); + error("%s: pcap_create failed: %s", device, ebuf); status = pcap_set_snaplen(pd, snaplen); if (status != 0) error("%s: pcap_set_snaplen failed: %s", @@ -157,7 +211,8 @@ main(int argc, char **argv) */ warning("%s: %s\n(%s)", device, pcap_statustostr(status), pcap_geterr(pd)); - } + } else + printf("%s opened successfully\n", device); } else { *ebuf = '\0'; pd = pcap_open_live(device, 65535, 0, 1000, ebuf); @@ -165,6 +220,8 @@ main(int argc, char **argv) error("%s", ebuf); else if (*ebuf) warning("%s", ebuf); + else + printf("%s opened successfully\n", device); } pcap_close(pd); exit(status < 0 ? 1 : 0); diff --git a/tests/reactivatetest.c b/tests/reactivatetest.c index 9031a64a619e..2e1b7b67adb7 100644 --- a/tests/reactivatetest.c +++ b/tests/reactivatetest.c @@ -20,7 +20,7 @@ */ #ifndef lint -static const char copyright[] = +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 diff --git a/tests/selpolltest.c b/tests/selpolltest.c index d94fb567fb20..4c1415b68354 100644 --- a/tests/selpolltest.c +++ b/tests/selpolltest.c @@ -20,11 +20,19 @@ */ #ifndef lint -static const char copyright[] = +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 +/* + * Tests how select() and poll() behave on the selectable file descriptor + * for a pcap_t. + * + * This would be significantly different on Windows, as it'd test + * how WaitForMultipleObjects() would work on the event handle for a + * pcap_t. + */ #include <pcap.h> #include <stdio.h> #include <stdlib.h> @@ -33,24 +41,73 @@ The Regents of the University of California. All rights reserved.\n"; #include <unistd.h> #include <errno.h> #include <sys/types.h> +#ifdef HAVE_SYS_SELECT_H #include <sys/select.h> +#else +#include <sys/time.h> /* older UN*Xes */ +#endif #include <poll.h> char *program_name; +/* + * 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 + +#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) + /* + * Compiler with support for it, or GCC 2.5 and later, or Solaris Studio 12 + * (Sun C 5.9) and later, or IBM XL C 10.1 and later (do any earlier + * versions of XL C support this?), or HP aCC A.06.10 and later. + */ + #define PCAP_NORETURN __attribute((noreturn)) +#elif defined( _MSC_VER ) + #define PCAP_NORETURN __declspec(noreturn) +#else + #define PCAP_NORETURN +#endif + +#if __has_attribute(__format__) \ + || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)) \ + || (defined(__xlC__) && __xlC__ >= 0x0A01) \ + || (defined(__HP_aCC) && __HP_aCC >= 61000) + /* + * 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?), + * or HP aCC A.06.10 and later. + */ + #define PCAP_PRINTFLIKE(x,y) __attribute__((__format__(__printf__,x,y))) +#else + #define PCAP_PRINTFLIKE(x,y) +#endif + /* Forwards */ static void countme(u_char *, const struct pcap_pkthdr *, const u_char *); -static void usage(void) __attribute__((noreturn)); -static void error(const char *, ...); -static void warning(const char *, ...); +static void PCAP_NORETURN usage(void); +static void PCAP_NORETURN error(const char *, ...) PCAP_PRINTFLIKE(1, 2); +static void warning(const char *, ...) PCAP_PRINTFLIKE(1, 2); static char *copy_argv(char **); static pcap_t *pd; -extern int optind; -extern int opterr; -extern char *optarg; - int main(int argc, char **argv) { diff --git a/tests/valgrindtest.c b/tests/valgrindtest.c index 1d883776b04e..011fe117b2cd 100644 --- a/tests/valgrindtest.c +++ b/tests/valgrindtest.c @@ -19,6 +19,30 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ +/* + * This doesn't actually test libpcap itself; it tests whether + * valgrind properly handles the APIs libpcap uses. If it doesn't, + * we end up getting patches submitted to "fix" references that + * valgrind claims are being made to uninitialized data, when, in + * fact, the OS isn't making any such references - or we get + * valgrind *not* detecting *actual* incorrect references. + * + * Both BPF and Linux socket filters aren't handled correctly + * by some versions of valgrind. See valgrind bug 318203 for + * Linux: + * + * https://bugs.kde.org/show_bug.cgi?id=318203 + * + * and valgrind bug 312989 for OS X: + * + * https://bugs.kde.org/show_bug.cgi?id=312989 + * + * The fixes for both of those are checked into the official valgrind + * repository. + * + * The unofficial FreeBSD port has similar issues to the official OS X + * port, for similar reasons. + */ #ifndef lint static const char copyright[] _U_ = "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\ @@ -72,22 +96,62 @@ The Regents of the University of California. All rights reserved.\n"; #endif #include <pcap.h> -#ifndef HAVE___ATTRIBUTE__ -#define __attribute__(x) -#endif static char *program_name; -/* Forwards */ -static void usage(void) __attribute__((noreturn)); -static void error(const char *, ...) - __attribute__((noreturn, format (printf, 1, 2))); -static void warning(const char *, ...) - __attribute__((format (printf, 1, 2))); +/* + * 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 -extern int optind; -extern int opterr; -extern char *optarg; +#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) + /* + * Compiler with support for it, or GCC 2.5 and later, or Solaris Studio 12 + * (Sun C 5.9) and later, or IBM XL C 10.1 and later (do any earlier + * versions of XL C support this?), or HP aCC A.06.10 and later. + */ + #define PCAP_NORETURN __attribute((noreturn)) +#elif defined( _MSC_VER ) + #define PCAP_NORETURN __declspec(noreturn) +#else + #define PCAP_NORETURN +#endif + +#if __has_attribute(__format__) \ + || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)) \ + || (defined(__xlC__) && __xlC__ >= 0x0A01) \ + || (defined(__HP_aCC) && __HP_aCC >= 61000) + /* + * 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?), + * or HP aCC A.06.10 and later. + */ + #define PCAP_PRINTFLIKE(x,y) __attribute__((__format__(__printf__,x,y))) +#else + #define PCAP_PRINTFLIKE(x,y) +#endif + +/* Forwards */ +static void PCAP_NORETURN usage(void); +static void PCAP_NORETURN error(const char *, ...) PCAP_PRINTFLIKE(1, 2); +static void warning(const char *, ...) PCAP_PRINTFLIKE(1, 2); /* * On Windows, we need to open the file in binary mode, so that @@ -231,7 +295,7 @@ main(int argc, char **argv) dorfmon = 0; useactivate = 0; infile = NULL; - + if ((cp = strrchr(argv[0], '/')) != NULL) program_name = cp + 1; else |