diff options
author | guy <guy> | 2008-04-04 19:42:51 +0000 |
---|---|---|
committer | guy <guy> | 2008-04-04 19:42:51 +0000 |
commit | 90f8bdddc5eaf31d4ff5b7418eaf78f54365a936 (patch) | |
tree | c44ad002bcbaa8ad4852776aadf106c6910ccec8 | |
parent | ec31d1d0bc8266e69129847880b37155a9d91dfe (diff) | |
download | tcpdump-90f8bdddc5eaf31d4ff5b7418eaf78f54365a936.tar.gz |
Use the new libpcap API's if available; that means we can support "-B"
on all platforms in that case. Also, add a "-I" flag to turn on monitor
mode.
-rw-r--r-- | config.h.in | 3 | ||||
-rwxr-xr-x | configure | 108 | ||||
-rw-r--r-- | configure.in | 9 | ||||
-rw-r--r-- | interface.h | 4 | ||||
-rw-r--r-- | netdissect.h | 4 | ||||
-rw-r--r-- | tcpdump.c | 96 |
6 files changed, 200 insertions, 24 deletions
diff --git a/config.h.in b/config.h.in index a311bf00..71380248 100644 --- a/config.h.in +++ b/config.h.in @@ -190,6 +190,9 @@ /* Define to 1 if you have the `pcap_breakloop' function. */ #undef HAVE_PCAP_BREAKLOOP +/* Define to 1 if you have the `pcap_create' function. */ +#undef HAVE_PCAP_CREATE + /* Define to 1 if you have the `pcap_dump_flush' function. */ #undef HAVE_PCAP_DUMP_FLUSH @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 1.196.2.4 . +# From configure.in Revision: 1.196.2.5 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.59. # @@ -10862,6 +10862,112 @@ if test "$ac_cv_sockaddr_has_sa_len" = no; then missing_includes=yes fi +# +# Do we have the new open API? Check for pcap_create, and assume that, +# if we do, we also have pcap_activate() and the other new routines. + +for ac_func in pcap_create +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + diff --git a/configure.in b/configure.in index 1829ddcd..1907ad39 100644 --- a/configure.in +++ b/configure.in @@ -1,4 +1,4 @@ -dnl @(#) $Header: /tcpdump/master/tcpdump/configure.in,v 1.196.2.4 2008-03-13 18:40:01 guy Exp $ (LBL) +dnl @(#) $Header: /tcpdump/master/tcpdump/configure.in,v 1.196.2.5 2008-04-04 19:42:51 guy Exp $ (LBL) dnl dnl Copyright (c) 1994, 1995, 1996, 1997 dnl The Regents of the University of California. All rights reserved. @@ -6,7 +6,7 @@ dnl dnl Process this file with autoconf to produce a configure script. dnl -AC_REVISION($Revision: 1.196.2.4 $) +AC_REVISION($Revision: 1.196.2.5 $) AC_PREREQ(2.50) AC_INIT(tcpdump.c) @@ -707,6 +707,11 @@ if test "$ac_cv_sockaddr_has_sa_len" = no; then missing_includes=yes fi +# +# Do we have the new open API? Check for pcap_create, and assume that, +# if we do, we also have pcap_activate() and the other new routines. +AC_CHECK_FUNCS(pcap_create) + AC_CHECK_FUNCS(pcap_findalldevs pcap_dump_flush pcap_lib_version) if test $ac_cv_func_pcap_findalldevs = "yes" ; then dnl Check for Mac OS X, which may ship pcap.h from 0.6 but libpcap may diff --git a/interface.h b/interface.h index ded1e16d..1f031231 100644 --- a/interface.h +++ b/interface.h @@ -18,7 +18,7 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.280.2.3 2008-02-14 20:54:53 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.280.2.4 2008-04-04 19:42:52 guy Exp $ (LBL) */ #ifndef tcpdump_interface_h @@ -383,6 +383,8 @@ extern netdissect_options *gndo; #define Cflag gndo->ndo_Cflag #define Gflag gndo->ndo_Gflag #define Aflag gndo->ndo_Aflag +#define Bflag gndo->ndo_Bflag +#define Iflag gndo->ndo_Iflag #define suppress_default_print gndo->ndo_suppress_default_print #define packettype gndo->ndo_packettype #define tcpmd5secret gndo->ndo_tcpmd5secret diff --git a/netdissect.h b/netdissect.h index c63a940e..cd6f2f13 100644 --- a/netdissect.h +++ b/netdissect.h @@ -21,7 +21,7 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: /tcpdump/master/tcpdump/netdissect.h,v 1.23.2.1 2008-02-06 10:49:22 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/tcpdump/netdissect.h,v 1.23.2.2 2008-04-04 19:42:52 guy Exp $ (LBL) */ #ifndef netdissect_h @@ -102,6 +102,8 @@ struct netdissect_options { int ndo_Aflag; /* print packet only in ascii observing TAB, * LF, CR and SPACE as graphical chars */ + int ndo_Bflag; /* buffer size */ + int ndo_Iflag; /* rfmon (monitor) mode */ int ndo_Oflag; /* run filter code optimizer */ int ndo_dlt; /* if != -1, ask libpcap for the DLT it names*/ int ndo_pflag; /* don't go promiscuous */ @@ -30,7 +30,7 @@ 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"; static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.271.2.5 2008-01-29 10:50:28 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.271.2.6 2008-04-04 19:42:52 guy Exp $ (LBL)"; #endif /* @@ -349,13 +349,19 @@ show_dlts_and_exit(pcap_t *pd) * Set up flags that might or might not be supported depending on the * version of libpcap we're using. */ -#ifdef WIN32 +#if defined(HAVE_PCAP_CREATE) || defined(WIN32) #define B_FLAG "B:" #define B_FLAG_USAGE " [ -B size ]" -#else /* WIN32 */ +#else /* defined(HAVE_PCAP_CREATE) || defined(WIN32) */ #define B_FLAG #define B_FLAG_USAGE -#endif /* WIN32 */ +#endif /* defined(HAVE_PCAP_CREATE) || defined(WIN32) */ + +#ifdef HAVE_PCAP_CREATE +#define I_FLAG "I" +#else /* HAVE_PCAP_CREATE */ +#define I_FLAG +#endif /* HAVE_PCAP_CREATE */ #ifdef HAVE_PCAP_FINDALLDEVS #ifndef HAVE_PCAP_IF_T @@ -498,7 +504,6 @@ main(int argc, char **argv) #endif int status; #ifdef WIN32 - u_int UserBufferSize = 1000000; if(wsockinit() != 0) return 1; #endif /* WIN32 */ @@ -530,7 +535,7 @@ main(int argc, char **argv) opterr = 0; while ( - (op = getopt(argc, argv, "aA" B_FLAG "c:C:d" D_FLAG "eE:fF:G:i:KlLm:M:nNOpqr:Rs:StT:u" U_FLAG "vw:W:xXy:Yz:Z:")) != -1) + (op = getopt(argc, argv, "aA" B_FLAG "c:C:d" D_FLAG "eE:fF:G:i:" I_FLAG "KlLm:M:nNOpqr:Rs:StT:u" U_FLAG "vw:W:xXy:Yz:Z:")) != -1) switch (op) { case 'a': @@ -541,13 +546,13 @@ main(int argc, char **argv) ++Aflag; break; -#ifdef WIN32 +#if defined(HAVE_PCAP_CREATE) || defined(WIN32) case 'B': - UserBufferSize = atoi(optarg)*1024; - if (UserBufferSize < 0) + Bflag = atoi(optarg)*1024; + if (Bflag <= 0) error("invalid packet buffer size %s", optarg); break; -#endif /* WIN32 */ +#endif /* defined(HAVE_PCAP_CREATE) || defined(WIN32) */ case 'c': cnt = atoi(optarg); @@ -654,6 +659,12 @@ main(int argc, char **argv) device = optarg; break; +#ifdef HAVE_PCAP_CREATE + case 'I': + ++Iflag; + break; +#endif /* HAVE_PCAP_CREATE */ + case 'l': #ifdef WIN32 /* @@ -942,12 +953,58 @@ main(int argc, char **argv) fflush(stderr); #endif /* WIN32 */ +#ifdef HAVE_PCAP_CREATE + pd = pcap_create(device, ebuf); + if (pd == NULL) + error("%s", ebuf); + status = pcap_set_snaplen(pd, snaplen); + if (status != 0) + error("%s: pcap_set_snaplen failed: %s", + device, pcap_strerror(status)); + status = pcap_set_promisc(pd, !pflag); + if (status != 0) + error("%s: pcap_set_promisc failed: %s", + device, pcap_strerror(status)); + if (Iflag) { +status = pcap_can_set_rfmon(pd); +if (status < 0) { +if (status == PCAP_ERROR) +fprintf(stderr, "pcap_can_set_rfmon failed: %s\n", pcap_geterr(pd)); +else +fprintf(stderr, "pcap_can_set_rfmon failed: %s\n", pcap_strerror(status)); +} +else if (!status) +fprintf(stderr, "This isn't gonna work...\n"); + status = pcap_set_rfmon(pd, 1); + if (status != 0) + error("%s: pcap_set_rfmon failed: %s", + device, pcap_strerror(status)); + } + status = pcap_set_timeout(pd, 1000); + if (status != 0) + error("%s: pcap_set_timeout failed: %s", + device, pcap_strerror(status)); + if (Bflag != 0) { + status = pcap_set_buffer_size(pd, Bflag); + if (status != 0) + error("%s: pcap_set_buffer_size failed: %s", + device, pcap_strerror(status)); + } + status = pcap_activate(pd); + if (status != 0) { + if (status == PCAP_ERROR) + error("%s", pcap_geterr(pd)); + else + error("%s: %s", device, pcap_strerror(status)); + } +#else *ebuf = '\0'; pd = pcap_open_live(device, snaplen, !pflag, 1000, ebuf); if (pd == NULL) error("%s", ebuf); else if (*ebuf) warning("%s", ebuf); +#endif /* HAVE_PCAP_CREATE */ /* * Let user own process after socket has been opened. */ @@ -955,12 +1012,12 @@ main(int argc, char **argv) if (setgid(getgid()) != 0 || setuid(getuid()) != 0) fprintf(stderr, "Warning: setgid/setuid failed !\n"); #endif /* WIN32 */ -#ifdef WIN32 - if(UserBufferSize != 1000000) - if(pcap_setbuff(pd, UserBufferSize)==-1){ +#if !defined(HAVE_PCAP_CREATE) && defined(WIN32) + if(Bflag != 0) + if(pcap_setbuff(pd, Bflag)==-1){ error("%s", pcap_geterr(pd)); } -#endif /* WIN32 */ +#endif /* !defined(HAVE_PCAP_CREATE) && defined(WIN32) */ if (Lflag) show_dlts_and_exit(pd); if (gndo->ndo_dlt >= 0) { @@ -1599,13 +1656,15 @@ usage(void) #endif /* WIN32 */ #endif /* HAVE_PCAP_LIB_VERSION */ (void)fprintf(stderr, -"Usage: %s [-aAd" D_FLAG "efKlLnNOpqRStu" U_FLAG "vxX]" B_FLAG_USAGE " [-c count] [ -C file_size ]\n", program_name); +"Usage: %s [-aAd" D_FLAG "ef" I_FLAG "KlLnNOpqRStu" U_FLAG "vxX]" B_FLAG_USAGE " [ -c count ]\n", program_name); (void)fprintf(stderr, -"\t\t[ -E algo:secret ] [ -F file ] [ -G seconds ] [ -i interface ]\n"); +"\t\t[ -C file_size ] [ -E algo:secret ] [ -F file ] [ -G seconds ]\n"); (void)fprintf(stderr, -"\t\t[ -M secret ] [ -r file ] [ -s snaplen ] [ -T type ] [ -w file ]\n"); +"\t\t[ -i interface ] [ -M secret ] [ -r file ]\n"); (void)fprintf(stderr, -"\t\t[ -W filecount ] [ -y datalinktype ] [ -z command ] [ -Z user ]\n"); +"\t\t[ -s snaplen ] [ -T type ] [ -w file ] [ -W filecount ]\n"); + (void)fprintf(stderr, +"\t\t[ -y datalinktype ] [ -z command ] [ -Z user ]\n"); (void)fprintf(stderr, "\t\t[ expression ]\n"); exit(1); @@ -1648,4 +1707,3 @@ ndo_warning(netdissect_options *ndo _U_, const char *fmt, ...) (void)fputc('\n', stderr); } } - |