From 77cade932c4c67e1c9e1e1cd1f16514735a9cfea Mon Sep 17 00:00:00 2001 From: guy Date: Wed, 23 Jul 2003 05:29:19 +0000 Subject: [PATCH] From Jesper Peterson : support for capturing from Endace DAG devices. --- CREDITS | 1 + FILES | 2 + INSTALL.txt | 5 +- Makefile.in | 12 +- config.h.in | 3 + configure | 266 ++++++++++++++++---------- configure.in | 66 ++++++- inet.c | 8 +- pcap-bpf.c | 41 +++- pcap-dag.c | 530 +++++++++++++++++++++++++++++++++++++++++++++++++++ pcap-dag.h | 18 ++ pcap-int.h | 9 +- pcap-linux.c | 51 ++++- pcap.c | 5 +- 14 files changed, 906 insertions(+), 111 deletions(-) create mode 100644 pcap-dag.c create mode 100644 pcap-dag.h diff --git a/CREDITS b/CREDITS index 03ea4cd..9965863 100644 --- a/CREDITS +++ b/CREDITS @@ -39,6 +39,7 @@ Additional people who have contributed patches: Jason R. Thorpe Javier Achirica Jefferson Ogata + Jesper Peterson John Bankier Jon Lindgren Kazushi Sugyo diff --git a/FILES b/FILES index fa1f553..27f7104 100644 --- a/FILES +++ b/FILES @@ -50,6 +50,8 @@ nlpid.h optimize.c pcap-bpf.c pcap-bpf.h +pcap-dag.c +pcap-dag.h pcap-dlpi.c pcap-enet.c pcap-int.h diff --git a/INSTALL.txt b/INSTALL.txt index ec2ae6f..4fd6cd0 100644 --- a/INSTALL.txt +++ b/INSTALL.txt @@ -1,4 +1,4 @@ -@(#) $Header: /tcpdump/master/libpcap/INSTALL.txt,v 1.5 2003-03-11 06:23:52 guy Exp $ (LBL) +@(#) $Header: /tcpdump/master/libpcap/INSTALL.txt,v 1.6 2003-07-23 05:29:19 guy Exp $ (LBL) To build libpcap, run "./configure" (a shell script). The configure script will determine your system attributes and generate an @@ -334,6 +334,9 @@ nlpid.h - OSI network layer protocol identifier definitions net - symlink to bpf/net optimize.c - BPF optimization routines pcap-bpf.c - BSD Packet Filter support +pcap-bpf.h - BPF definitions +pcap-dag.c - Endace DAG device capture support +pcap-dag.h - Endace DAG device capture support pcap-dlpi.c - Data Link Provider Interface support pcap-enet.c - enet support pcap-int.h - internal libpcap definitions diff --git a/Makefile.in b/Makefile.in index afc6d8f..bbf32db 100644 --- a/Makefile.in +++ b/Makefile.in @@ -17,7 +17,7 @@ # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. # -# @(#) $Header: /tcpdump/master/libpcap/Makefile.in,v 1.95 2003-02-21 03:19:19 guy Exp $ (LBL) +# @(#) $Header: /tcpdump/master/libpcap/Makefile.in,v 1.96 2003-07-23 05:29:20 guy Exp $ (LBL) # # Various configurable paths (remember to edit Makefile.in, not Makefile) @@ -44,7 +44,8 @@ VPATH = @srcdir@ CC = @CC@ CCOPT = @V_CCOPT@ INCLS = -I. @V_INCLS@ -DEFS = @DEFS@ +DEFS = @DEFS@ @V_DEFS@ +LIBS = @V_LIBS@ # Standard CFLAGS CFLAGS = $(CCOPT) $(INCLS) $(DEFS) @@ -71,16 +72,17 @@ YACC = @V_YACC@ PSRC = pcap-@V_PCAP@.c FSRC = fad-@V_FINDALLDEVS@.c +SSRC = @SSRC@ CSRC = pcap.c inet.c gencode.c optimize.c nametoaddr.c \ etherent.c savefile.c bpf_filter.c bpf_image.c bpf_dump.c GENSRC = scanner.c grammar.c version.c LIBOBJS = @LIBOBJS@ -SRC = $(PSRC) $(FSRC) $(CSRC) $(GENSRC) +SRC = $(PSRC) $(FSRC) $(CSRC) $(SSRC) $(GENSRC) # We would like to say "OBJ = $(SRC:.c=.o)" but Ultrix's make cannot # hack the extra indirection -OBJ = $(PSRC:.c=.o) $(FSRC:.c=.o) $(CSRC:.c=.o) $(GENSRC:.c=.o) # $(LIBOBJS) +OBJ = $(PSRC:.c=.o) $(FSRC:.c=.o) $(CSRC:.c=.o) $(SSRC:.c=.o) $(GENSRC:.c=.o) # $(LIBOBJS) HDR = pcap.h pcap-int.h pcap-namedb.h pcap-nit.h pcap-pf.h \ ethertype.h gencode.h gnuc.h GENHDR = \ @@ -98,7 +100,7 @@ all: libpcap.a libpcap.a: $(OBJ) @rm -f $@ - ar rc $@ $(OBJ) + ar rc $@ $(OBJ) $(LIBS) $(RANLIB) $@ scanner.c: $(srcdir)/scanner.l diff --git a/config.h.in b/config.h.in index 83800a8..c6cd78f 100644 --- a/config.h.in +++ b/config.h.in @@ -83,6 +83,9 @@ /* define if you have a /proc/net/dev */ #undef HAVE_PROC_NET_DEV +/* define if you have a DAG API */ +#undef HAVE_DAG_API + /* define on AIX to get certain functions */ #undef _SUN diff --git a/configure b/configure index eb6ed91..4fa6fee 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh -# From configure.in Revision: 1.98 +# From configure.in Revision: 1.99 @@ -72,6 +72,8 @@ ac_help="$ac_help --enable-optimizer-dbg build optimizer debugging code" ac_help="$ac_help --enable-yydebug build parser debugging code" +ac_help="$ac_help + --with-dag=DIR include DAG support from DIR" ac_help="$ac_help --without-flex don't use flex" ac_help="$ac_help @@ -634,7 +636,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:638: checking host system type" >&5 +echo "configure:640: checking host system type" >&5 host_alias=$host case "$host_alias" in @@ -655,7 +657,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$host" 1>&6 echo $ac_n "checking target system type""... $ac_c" 1>&6 -echo "configure:659: checking target system type" >&5 +echo "configure:661: checking target system type" >&5 target_alias=$target case "$target_alias" in @@ -673,7 +675,7 @@ target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$target" 1>&6 echo $ac_n "checking build system type""... $ac_c" 1>&6 -echo "configure:677: checking build system type" >&5 +echo "configure:679: checking build system type" >&5 build_alias=$build case "$build_alias" in @@ -721,7 +723,7 @@ fi # Extract the first word of "shlicc2", so it can be a program name with args. set dummy shlicc2; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:725: checking for $ac_word" >&5 +echo "configure:727: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_SHLICC2'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -762,7 +764,7 @@ fi # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:766: checking for $ac_word" >&5 +echo "configure:768: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -792,7 +794,7 @@ if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:796: checking for $ac_word" >&5 +echo "configure:798: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -843,7 +845,7 @@ fi # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:847: checking for $ac_word" >&5 +echo "configure:849: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -875,7 +877,7 @@ fi fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:879: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 +echo "configure:881: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. @@ -886,12 +888,12 @@ cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF -#line 890 "configure" +#line 892 "configure" #include "confdefs.h" main(){return(0);} EOF -if { (eval echo configure:895: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:897: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then @@ -917,12 +919,12 @@ if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:921: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:923: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:926: checking whether we are using GNU C" >&5 +echo "configure:928: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -931,7 +933,7 @@ else yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:935: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:937: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -950,7 +952,7 @@ ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:954: checking whether ${CC-cc} accepts -g" >&5 +echo "configure:956: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -987,7 +989,7 @@ fi V_CCOPT="-O2" else echo $ac_n "checking gcc version""... $ac_c" 1>&6 -echo "configure:991: checking gcc version" >&5 +echo "configure:993: checking gcc version" >&5 if eval "test \"`echo '$''{'ac_cv_lbl_gcc_vers'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1005,19 +1007,19 @@ fi fi else echo $ac_n "checking that $CC handles ansi prototypes""... $ac_c" 1>&6 -echo "configure:1009: checking that $CC handles ansi prototypes" >&5 +echo "configure:1011: checking that $CC handles ansi prototypes" >&5 if eval "test \"`echo '$''{'ac_cv_lbl_cc_ansi_prototypes'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { int frob(int, char *) ; return 0; } EOF -if { (eval echo configure:1021: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1023: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_lbl_cc_ansi_prototypes=yes else @@ -1035,21 +1037,21 @@ fi hpux*) echo $ac_n "checking for HP-UX ansi compiler ($CC -Aa -D_HPUX_SOURCE)""... $ac_c" 1>&6 -echo "configure:1039: checking for HP-UX ansi compiler ($CC -Aa -D_HPUX_SOURCE)" >&5 +echo "configure:1041: checking for HP-UX ansi compiler ($CC -Aa -D_HPUX_SOURCE)" >&5 savedcflags="$CFLAGS" CFLAGS="-Aa -D_HPUX_SOURCE $CFLAGS" if eval "test \"`echo '$''{'ac_cv_lbl_cc_hpux_cc_aa'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { int frob(int, char *) ; return 0; } EOF -if { (eval echo configure:1053: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1055: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_lbl_cc_hpux_cc_aa=yes else @@ -1093,12 +1095,12 @@ EOF ultrix*) echo $ac_n "checking that Ultrix $CC hacks const in prototypes""... $ac_c" 1>&6 -echo "configure:1097: checking that Ultrix $CC hacks const in prototypes" >&5 +echo "configure:1099: checking that Ultrix $CC hacks const in prototypes" >&5 if eval "test \"`echo '$''{'ac_cv_lbl_cc_const_proto'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { @@ -1106,7 +1108,7 @@ struct a { int b; }; void c(const struct a *) ; return 0; } EOF -if { (eval echo configure:1110: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1112: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_lbl_cc_const_proto=yes else @@ -1130,7 +1132,7 @@ EOF fi echo $ac_n "checking for inline""... $ac_c" 1>&6 -echo "configure:1134: checking for inline" >&5 +echo "configure:1136: checking for inline" >&5 if eval "test \"`echo '$''{'ac_cv_lbl_inline'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1140,7 +1142,7 @@ else for ac_lbl_inline in inline __inline__ __inline do cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1166: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_lbl_cc_inline=yes else @@ -1188,13 +1190,13 @@ EOF echo $ac_n "checking for __attribute__""... $ac_c" 1>&6 -echo "configure:1192: checking for __attribute__" >&5 +echo "configure:1194: checking for __attribute__" >&5 if eval "test \"`echo '$''{'ac_cv___attribute__'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -1211,7 +1213,7 @@ foo(void) ; return 0; } EOF -if { (eval echo configure:1215: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1217: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv___attribute__=yes else @@ -1233,12 +1235,12 @@ echo "$ac_t""$ac_cv___attribute__" 1>&6 echo $ac_n "checking for u_int8_t using $CC""... $ac_c" 1>&6 -echo "configure:1237: checking for u_int8_t using $CC" >&5 +echo "configure:1239: checking for u_int8_t using $CC" >&5 if eval "test \"`echo '$''{'ac_cv_lbl_have_u_int8_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1257: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_lbl_have_u_int8_t=yes else @@ -1271,12 +1273,12 @@ EOF fi echo $ac_n "checking for u_int16_t using $CC""... $ac_c" 1>&6 -echo "configure:1275: checking for u_int16_t using $CC" >&5 +echo "configure:1277: checking for u_int16_t using $CC" >&5 if eval "test \"`echo '$''{'ac_cv_lbl_have_u_int16_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1295: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_lbl_have_u_int16_t=yes else @@ -1309,12 +1311,12 @@ EOF fi echo $ac_n "checking for u_int32_t using $CC""... $ac_c" 1>&6 -echo "configure:1313: checking for u_int32_t using $CC" >&5 +echo "configure:1315: checking for u_int32_t using $CC" >&5 if eval "test \"`echo '$''{'ac_cv_lbl_have_u_int32_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1333: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_lbl_have_u_int32_t=yes else @@ -1348,7 +1350,7 @@ EOF fi echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:1352: checking how to run the C preprocessor" >&5 +echo "configure:1354: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -1363,13 +1365,13 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1373: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1375: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -1380,13 +1382,13 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1390: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1392: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -1397,13 +1399,13 @@ else rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1407: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1409: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -1431,17 +1433,17 @@ for ac_hdr in sys/ioccom.h sys/sockio.h ifaddrs.h limits.h netinet/if_ether.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:1435: checking for $ac_hdr" >&5 +echo "configure:1437: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1445: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1447: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -1470,12 +1472,12 @@ done if test "$GCC" = yes ; then echo $ac_n "checking for ANSI ioctl definitions""... $ac_c" 1>&6 -echo "configure:1474: checking for ANSI ioctl definitions" >&5 +echo "configure:1476: checking for ANSI ioctl definitions" >&5 if eval "test \"`echo '$''{'ac_cv_lbl_gcc_fixincludes'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1500: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_lbl_gcc_fixincludes=yes else @@ -1517,12 +1519,12 @@ fi for ac_func in ether_hostton strerror strlcpy do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:1521: checking for $ac_func" >&5 +echo "configure:1523: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1551: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -1571,7 +1573,7 @@ done echo $ac_n "checking if --disable-protochain option is specified""... $ac_c" 1>&6 -echo "configure:1575: checking if --disable-protochain option is specified" >&5 +echo "configure:1577: checking if --disable-protochain option is specified" >&5 # Check whether --enable-protochain or --disable-protochain was given. if test "${enable_protochain+set}" = set; then enableval="$enable_protochain" @@ -1602,7 +1604,7 @@ if test "${with_pcap+set}" = set; then fi echo $ac_n "checking packet capture type""... $ac_c" 1>&6 -echo "configure:1606: checking packet capture type" >&5 +echo "configure:1608: checking packet capture type" >&5 if test ! -z "$with_pcap" ; then V_PCAP="$withval" elif test -r /dev/bpf0 ; then @@ -1640,12 +1642,12 @@ fi echo "$ac_t""$V_PCAP" 1>&6 echo $ac_n "checking for getifaddrs""... $ac_c" 1>&6 -echo "configure:1644: checking for getifaddrs" >&5 +echo "configure:1646: checking for getifaddrs" >&5 if eval "test \"`echo '$''{'ac_cv_func_getifaddrs'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1674: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_getifaddrs=yes" else @@ -1706,12 +1708,12 @@ else # or it might be some other OS, with just SIOCGIFCONF. # echo $ac_n "checking whether we have SIOCGLIFCONF""... $ac_c" 1>&6 -echo "configure:1710: checking whether we have SIOCGLIFCONF" >&5 +echo "configure:1712: checking whether we have SIOCGLIFCONF" >&5 if eval "test \"`echo '$''{'ac_cv_lbl_have_siocglifconf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -1722,7 +1724,7 @@ int main() { ioctl(0, SIOCGLIFCONF, (char *)0); ; return 0; } EOF -if { (eval echo configure:1726: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1728: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_lbl_have_siocglifconf=yes else @@ -1764,7 +1766,7 @@ fi echo $ac_n "checking if --enable-ipv6 option is specified""... $ac_c" 1>&6 -echo "configure:1768: checking if --enable-ipv6 option is specified" >&5 +echo "configure:1770: checking if --enable-ipv6 option is specified" >&5 # Check whether --enable-ipv6 or --disable-ipv6 was given. if test "${enable_ipv6+set}" = set; then enableval="$enable_ipv6" @@ -1780,7 +1782,7 @@ fi echo "$ac_t""${enable_ipv6-no}" 1>&6 echo $ac_n "checking whether to build optimizer debugging code""... $ac_c" 1>&6 -echo "configure:1784: checking whether to build optimizer debugging code" >&5 +echo "configure:1786: checking whether to build optimizer debugging code" >&5 # Check whether --enable-optimizer-dbg or --disable-optimizer-dbg was given. if test "${enable_optimizer_dbg+set}" = set; then enableval="$enable_optimizer_dbg" @@ -1796,7 +1798,7 @@ fi echo "$ac_t""${enable_optimizer_dbg-no}" 1>&6 echo $ac_n "checking whether to build parser debugging code""... $ac_c" 1>&6 -echo "configure:1800: checking whether to build parser debugging code" >&5 +echo "configure:1802: checking whether to build parser debugging code" >&5 # Check whether --enable-yydebug or --disable-yydebug was given. if test "${enable_yydebug+set}" = set; then enableval="$enable_yydebug" @@ -1818,17 +1820,17 @@ dlpi) do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:1822: checking for $ac_hdr" >&5 +echo "configure:1824: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1832: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1834: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -1855,7 +1857,7 @@ fi done echo $ac_n "checking for /dev/dlpi device""... $ac_c" 1>&6 -echo "configure:1859: checking for /dev/dlpi device" >&5 +echo "configure:1861: checking for /dev/dlpi device" >&5 if test -c /dev/dlpi ; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF @@ -1866,7 +1868,7 @@ EOF echo "$ac_t""no" 1>&6 dir="/dev/dlpi" echo $ac_n "checking for $dir directory""... $ac_c" 1>&6 -echo "configure:1870: checking for $dir directory" >&5 +echo "configure:1872: checking for $dir directory" >&5 if test -d $dir ; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <&6 -echo "configure:1885: checking Linux kernel version" >&5 +echo "configure:1887: checking Linux kernel version" >&5 if test "$cross_compiling" = yes; then if eval "test \"`echo '$''{'ac_cv_linux_vers'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1906,12 +1908,12 @@ fi { echo "configure: error: version 2 or higher required; see the INSTALL doc for more info" 1>&2; exit 1; } fi echo $ac_n "checking if if_packet.h has tpacket_stats defined""... $ac_c" 1>&6 -echo "configure:1910: checking if if_packet.h has tpacket_stats defined" >&5 +echo "configure:1912: checking if if_packet.h has tpacket_stats defined" >&5 if eval "test \"`echo '$''{'ac_cv_lbl_tpacket_stats'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -1919,7 +1921,7 @@ int main() { struct tpacket_stats stats ; return 0; } EOF -if { (eval echo configure:1923: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1925: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_lbl_tpacket_stats=yes else @@ -1940,6 +1942,10 @@ EOF fi ;; +dag) + V_DEFS="$V_DEFS -DDAG_ONLY" + ;; + null) echo "configure: warning: cannot determine packet capture interface" 1>&2 echo "configure: warning: (see the INSTALL doc for more info)" 1>&2 @@ -1948,7 +1954,7 @@ null) esac echo $ac_n "checking whether we have /proc/net/dev""... $ac_c" 1>&6 -echo "configure:1952: checking whether we have /proc/net/dev" >&5 +echo "configure:1958: checking whether we have /proc/net/dev" >&5 if test -r /proc/net/dev ; then ac_cv_lbl_proc_net_dev=yes else @@ -1962,6 +1968,68 @@ EOF fi echo "$ac_t""$ac_cv_lbl_proc_net_dev" 1>&6 +# Check whether --with-dag or --without-dag was given. +if test "${with_dag+set}" = set; then + withval="$with_dag" + : +fi + +ac_cv_lbl_dag_api=no +if test "$with_dag" != no; then + + case "$V_PCAP" in + linux|bpf|dag) + ;; + *) + { echo "configure: error: DAG support only available with 'linux' 'bpf' and 'dag' packet capture types" 1>&2; exit 1; } + ;; + esac + + echo $ac_n "checking whether we have DAG API""... $ac_c" 1>&6 +echo "configure:1990: checking whether we have DAG API" >&5 + + if test -z "$with_dag" -o "$with_dag" = yes; then + dag_root=$srcdir/../dag + else + dag_root=$with_dag + fi + + if test -r "$dag_root/tools" -a -r "$dag_root/include"; then + dag_tools_dir="$dag_root/tools" + dag_include_dir="$dag_root/include" + else + dag_tools_dir="$dag_root" + dag_include_dir="$dag_root" + fi + + if test -r "$dag_include_dir/dagapi.h" -a -r "$dag_tools_dir/dagapi.o"; then + V_INCLS="$V_INCLS -I $dag_include_dir" + V_LIBS="$V_LIBS $dag_tools_dir/dagapi.o $dag_tools_dir/dagopts.o" + if test "$V_PCAP" != dag ; then + SSRC="pcap-dag.c" + fi + ac_cv_lbl_dag_api=yes + else + ac_cv_lbl_dag_api=no + fi + echo "$ac_t""$ac_cv_lbl_dag_api" 1>&6 + if test $ac_cv_lbl_dag_api = no; then + if test ! -z "$with_dag"; then + { echo "configure: error: DAG API not found under directory $dag_root; use --without-dag" 1>&2; exit 1; } + fi + else + cat >> confdefs.h <<\EOF +#define HAVE_DAG_API 1 +EOF + + fi +fi + +if test "$V_PCAP" = dag -a "$ac_cv_lbl_dag_api" = no; then + { echo "configure: error: Specifying the capture type as 'dag' requires the DAG API to be present; use --with-dag=DIR" 1>&2; exit 1; } +fi + + # Check whether --with-flex or --without-flex was given. if test "${with_flex+set}" = set; then withval="$with_flex" @@ -1982,7 +2050,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1986: checking for $ac_word" >&5 +echo "configure:2054: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_V_LEX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2016,7 +2084,7 @@ test -n "$V_LEX" || V_LEX="lex" if test "$V_LEX" = flex ; then # The -V flag was added in 2.4 echo $ac_n "checking for flex 2.4 or higher""... $ac_c" 1>&6 -echo "configure:2020: checking for flex 2.4 or higher" >&5 +echo "configure:2088: checking for flex 2.4 or higher" >&5 if eval "test \"`echo '$''{'ac_cv_lbl_flex_v24'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2042,7 +2110,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2046: checking for $ac_word" >&5 +echo "configure:2114: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_V_YACC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2089,7 +2157,7 @@ if test "$V_LEX" = lex ; then # Some versions of lex can't handle the definitions section of scanner.l . # Try lexing it and complain if it can't deal. echo $ac_n "checking for capable lex""... $ac_c" 1>&6 -echo "configure:2093: checking for capable lex" >&5 +echo "configure:2161: checking for capable lex" >&5 if eval "test \"`echo '$''{'tcpdump_cv_capable_lex'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2140,19 +2208,19 @@ EOF sinix*) echo $ac_n "checking if SINIX compiler defines sinix""... $ac_c" 1>&6 -echo "configure:2144: checking if SINIX compiler defines sinix" >&5 +echo "configure:2212: checking if SINIX compiler defines sinix" >&5 if eval "test \"`echo '$''{'ac_cv_cc_sinix_defined'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2224: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_cc_sinix_defined=yes else @@ -2184,7 +2252,7 @@ esac # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2188: checking for $ac_word" >&5 +echo "configure:2256: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2252,12 +2320,12 @@ EOF fi echo $ac_n "checking if sockaddr struct has sa_len member""... $ac_c" 1>&6 -echo "configure:2256: checking if sockaddr struct has sa_len member" >&5 +echo "configure:2324: checking if sockaddr struct has sa_len member" >&5 if eval "test \"`echo '$''{'ac_cv_lbl_sockaddr_has_sa_len'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -2266,7 +2334,7 @@ int main() { u_int i = sizeof(((struct sockaddr *)0)->sa_len) ; return 0; } EOF -if { (eval echo configure:2270: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2338: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_lbl_sockaddr_has_sa_len=yes else @@ -2287,12 +2355,12 @@ EOF fi echo $ac_n "checking if sockaddr_storage struct exists""... $ac_c" 1>&6 -echo "configure:2291: checking if sockaddr_storage struct exists" >&5 +echo "configure:2359: checking if sockaddr_storage struct exists" >&5 if eval "test \"`echo '$''{'ac_cv_lbl_has_sockaddr_storage'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -2301,7 +2369,7 @@ int main() { u_int i = sizeof (struct sockaddr_storage) ; return 0; } EOF -if { (eval echo configure:2305: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2373: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_lbl_has_sockaddr_storage=yes else @@ -2322,12 +2390,12 @@ EOF fi echo $ac_n "checking if dl_hp_ppa_info_t struct has dl_module_id_1 member""... $ac_c" 1>&6 -echo "configure:2326: checking if dl_hp_ppa_info_t struct has dl_module_id_1 member" >&5 +echo "configure:2394: checking if dl_hp_ppa_info_t struct has dl_module_id_1 member" >&5 if eval "test \"`echo '$''{'ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -2337,7 +2405,7 @@ int main() { u_int i = sizeof(((dl_hp_ppa_info_t *)0)->dl_module_id_1) ; return 0; } EOF -if { (eval echo configure:2341: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2409: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1=yes else @@ -2358,7 +2426,7 @@ EOF fi echo $ac_n "checking if unaligned accesses fail""... $ac_c" 1>&6 -echo "configure:2362: checking if unaligned accesses fail" >&5 +echo "configure:2430: checking if unaligned accesses fail" >&5 if eval "test \"`echo '$''{'ac_cv_lbl_unaligned_fail'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2463,6 +2531,9 @@ ln -s ${srcdir}/bpf/net net + + + # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: @@ -2475,7 +2546,7 @@ ln -s ${srcdir}/bpf/net net # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:2479: checking for a BSD compatible install" >&5 +echo "configure:2550: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2685,10 +2756,13 @@ s%@V_LEX@%$V_LEX%g s%@V_YACC@%$V_YACC%g s%@RANLIB@%$RANLIB%g s%@V_CCOPT@%$V_CCOPT%g +s%@V_DEFS@%$V_DEFS%g s%@V_INCLS@%$V_INCLS%g +s%@V_LIBS@%$V_LIBS%g s%@V_PCAP@%$V_PCAP%g s%@V_FINDALLDEVS@%$V_FINDALLDEVS%g s%@V_RANLIB@%$V_RANLIB%g +s%@SSRC@%$SSRC%g s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g s%@INSTALL_DATA@%$INSTALL_DATA%g diff --git a/configure.in b/configure.in index c425e2a..2ad269c 100644 --- a/configure.in +++ b/configure.in @@ -1,4 +1,4 @@ -dnl @(#) $Header: /tcpdump/master/libpcap/configure.in,v 1.98 2003-02-11 06:21:00 guy Exp $ (LBL) +dnl @(#) $Header: /tcpdump/master/libpcap/configure.in,v 1.99 2003-07-23 05:29:20 guy Exp $ (LBL) dnl dnl Copyright (c) 1994, 1995, 1996, 1997 dnl The Regents of the University of California. All rights reserved. @@ -6,12 +6,12 @@ dnl dnl Process this file with autoconf to produce a configure script. dnl -AC_REVISION($Revision: 1.98 $) +AC_REVISION($Revision: 1.99 $) AC_INIT(pcap.c) AC_CANONICAL_SYSTEM -AC_LBL_C_INIT(V_CCOPT, V_INCLS) +AC_LBL_C_INIT(V_CCOPT, V_INCLS, V_LIBS) AC_LBL_C_INLINE AC_C___ATTRIBUTE__ @@ -217,6 +217,10 @@ linux) AC_LBL_TPACKET_STATS ;; +dag) + V_DEFS="$V_DEFS -DDAG_ONLY" + ;; + null) AC_MSG_WARN(cannot determine packet capture interface) AC_MSG_WARN((see the INSTALL doc for more info)) @@ -235,6 +239,59 @@ if test $ac_cv_lbl_proc_net_dev = yes; then fi AC_MSG_RESULT($ac_cv_lbl_proc_net_dev) +AC_ARG_WITH(dag, [ --with-dag=DIR include DAG support from DIR]) +ac_cv_lbl_dag_api=no +if test "$with_dag" != no; then + + case "$V_PCAP" in + linux|bpf|dag) + ;; + *) + AC_MSG_ERROR(DAG support only available with 'linux' 'bpf' and 'dag' packet capture types) + ;; + esac + + AC_MSG_CHECKING(whether we have DAG API) + + if test -z "$with_dag" -o "$with_dag" = yes; then + dag_root=$srcdir/../dag + else + dag_root=$with_dag + fi + + if test -r "$dag_root/tools" -a -r "$dag_root/include"; then + dag_tools_dir="$dag_root/tools" + dag_include_dir="$dag_root/include" + else + dag_tools_dir="$dag_root" + dag_include_dir="$dag_root" + fi + + if test -r "$dag_include_dir/dagapi.h" -a -r "$dag_tools_dir/dagapi.o"; then + V_INCLS="$V_INCLS -I $dag_include_dir" + V_LIBS="$V_LIBS $dag_tools_dir/dagapi.o $dag_tools_dir/dagopts.o" + if test "$V_PCAP" != dag ; then + SSRC="pcap-dag.c" + fi + ac_cv_lbl_dag_api=yes + else + ac_cv_lbl_dag_api=no + fi + AC_MSG_RESULT($ac_cv_lbl_dag_api) + if test $ac_cv_lbl_dag_api = no; then + if test ! -z "$with_dag"; then + AC_MSG_ERROR(DAG API not found under directory $dag_root; use --without-dag) + fi + else + AC_DEFINE(HAVE_DAG_API, 1, [define if you have a DAG API]) + fi +fi + +if test "$V_PCAP" = dag -a "$ac_cv_lbl_dag_api" = no; then + AC_MSG_ERROR(Specifying the capture type as 'dag' requires the DAG API to be present; use --with-dag=DIR) +fi + + AC_LBL_LEX_AND_YACC(V_LEX, V_YACC, pcap_) if test "$V_LEX" = lex ; then # Some versions of lex can't handle the definitions section of scanner.l . @@ -310,12 +367,15 @@ rm -f net ln -s ${srcdir}/bpf/net net AC_SUBST(V_CCOPT) +AC_SUBST(V_DEFS) AC_SUBST(V_INCLS) +AC_SUBST(V_LIBS) AC_SUBST(V_LEX) AC_SUBST(V_PCAP) AC_SUBST(V_FINDALLDEVS) AC_SUBST(V_RANLIB) AC_SUBST(V_YACC) +AC_SUBST(SSRC) AC_PROG_INSTALL diff --git a/inet.c b/inet.c index ca7f3f6..6008e95 100644 --- a/inet.c +++ b/inet.c @@ -34,7 +34,7 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.55 2003-02-04 09:51:38 risso Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.56 2003-07-23 05:29:20 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -529,7 +529,11 @@ pcap_lookupnet(device, netp, maskp, errbuf) * has the network address and -mask "0.0.0.0" therefore catching * all traffic. Using NULL for the interface is the same as "any". */ - if (!device || strcmp(device, "any") == 0) { + if (!device || strcmp(device, "any") == 0 +#ifdef HAVE_DAG_API + || strstr(device, "dag") != NULL +#endif + ) { *netp = *maskp = 0; return 0; } diff --git a/pcap-bpf.c b/pcap-bpf.c index 4705f8e..39262f9 100644 --- a/pcap-bpf.c +++ b/pcap-bpf.c @@ -20,7 +20,7 @@ */ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.60 2003-04-17 06:35:34 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.61 2003-07-23 05:29:21 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -93,6 +93,10 @@ static int odmlockid = 0; #include "pcap-int.h" +#ifdef HAVE_DAG_API +#include "pcap-dag.h" +#endif /* HAVE_DAG_API */ + #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif @@ -104,6 +108,12 @@ pcap_stats(pcap_t *p, struct pcap_stat *ps) { struct bpf_stat s; +#ifdef HAVE_DAG_API + if (p->md.is_dag) { + return dag_stats(p, ps); + } +#endif /* HAVE_DAG_API */ + /* * "ps_recv" counts packets handed to the filter, not packets * that passed the filter. This includes packets later dropped @@ -135,6 +145,12 @@ pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) int n = 0; register u_char *bp, *ep; +#ifdef HAVE_DAG_API + if (p->md.is_dag) { + return dag_read(p, cnt, callback, user); + } +#endif /* HAVE_DAG_API */ + again: cc = p->cc; if (p->cc == 0) { @@ -447,6 +463,12 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, u_int v; pcap_t *p; +#ifdef HAVE_DAG_API + if (strstr(device, "dag")) { + return dag_open_live(device, snaplen, promisc, to_ms, ebuf); + } +#endif /* HAVE_DAG_API */ + #ifdef BIOCGDLTLIST bzero(&bdl, sizeof(bdl)); #endif @@ -719,12 +741,23 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, int pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) { +#ifdef HAVE_DAG_API + if (dag_platform_finddevs(alldevsp, errbuf) < 0) + return (-1); +#endif /* HAVE_DAG_API */ + return (0); } int pcap_setfilter(pcap_t *p, struct bpf_program *fp) { +#ifdef HAVE_DAG_API + if (p->md.is_dag) { + return dag_setfilter(p, fp); + } +#endif /* HAVE_DAG_API */ + /* * It looks that BPF code generated by gen_protochain() is not * compatible with some of kernel BPF code (for example BSD/OS 3.1). @@ -747,6 +780,12 @@ pcap_setfilter(pcap_t *p, struct bpf_program *fp) int pcap_set_datalink_platform(pcap_t *p, int dlt) { +#ifdef HAVE_DAG_API + if (p->md.is_dag) { + return dag_set_datalink_platform(p, dlt); + } +#endif /* HAVE_DAG_API */ + #ifdef BIOCSDLT if (ioctl(p->fd, BIOCSDLT, &dlt) == -1) { (void) snprintf(p->errbuf, sizeof(p->errbuf), diff --git a/pcap-dag.c b/pcap-dag.c new file mode 100644 index 0000000..4444f9c --- /dev/null +++ b/pcap-dag.c @@ -0,0 +1,530 @@ +/* + * pcap-dag.c: Packet capture interface for Endace DAG card. + * + * The functionality of this code attempts to mimic that of pcap-linux as much + * as possible. This code is compiled in several different ways depending on + * whether DAG_ONLY and HAVE_DAG_API are defined. If HAVE_DAG_API is not + * defined it should not get compiled in, otherwise if DAG_ONLY is defined then + * the 'dag_' function calls are renamed to 'pcap_' equivalents. If DAG_ONLY + * is not defined then nothing is altered - the dag_ functions will be + * called as required from their pcap-linux/bpf equivalents. + * + * Author: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com) + * + * Modifications: + * 2003 May - Jesper Peterson + * Code shuffled around to suit fad-xxx.c structure + * Added atexit() handler to stop DAG if application is too lazy + */ + +#ifndef lint +static const char rcsid[] = + "@(#) $Header: /tcpdump/master/libpcap/pcap-dag.c,v 1.1 2003-07-23 05:29:21 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include /* optionally get BSD define */ + +#include +#include +#include + +#include "pcap-int.h" + +#include +#include + +struct mbuf; /* Squelch compiler warnings on some platforms for */ +struct rtentry; /* declarations in */ +#include + +#include +#include + +#define MAX_DAG_SNAPLEN 2040 + +typedef struct pcap_dag_node { + struct pcap_dag_node *next; + pcap_t *p; +} pcap_dag_node_t; + +static pcap_dag_node_t *pcap_dags = NULL; +static int atexit_handler_installed = 0; + +#ifdef DAG_ONLY +/* This code is reguired when compiling for a DAG device only. */ +#include "pcap-dag.h" + +/* Replace dag function names with pcap equivalent. */ +#define dag_stats pcap_stats +#define dag_read pcap_read +#define dag_open_live pcap_open_live +#define dag_platform_finddevs pcap_platform_finddevs +#define dag_setfilter pcap_setfilter +#define dag_set_datalink_platform pcap_set_datalink_platform +#define dag_platform_close pcap_platform_close +#endif /* DAG_ONLY */ + +static void delete_pcap_dag(pcap_t *p) { + pcap_dag_node_t *curr = NULL, *prev = NULL; + + for (prev = NULL, curr = pcap_dags; + curr != NULL && curr->p != p; + prev = curr, curr = curr->next) { + /* empty */ + } + + if (curr != NULL && curr->p == p) { + if (prev != NULL) { + prev->next = curr->next; + } else { + pcap_dags = curr->next; + } + } +} + +/* + * Performs a graceful shutdown of the DAG card and frees dynamic memory held + * in the pcap_t structure. + */ + +void dag_platform_close(pcap_t *p) { + +#ifdef linux + if (p != NULL && p->md.is_dag && p->md.device != NULL) { + if(dag_stop(p->fd) < 0) + fprintf(stderr,"dag_stop %s: %s\n", p->md.device, strerror(errno)); + if(dag_close(p->fd) < 0) + fprintf(stderr,"dag_close %s: %s\n", p->md.device, strerror(errno)); + + free(p->md.device); + } +#else + if (p != NULL && p->md.is_dag) { + if(dag_stop(p->fd) < 0) + fprintf(stderr,"dag_stop: %s\n", strerror(errno)); + if(dag_close(p->fd) < 0) + fprintf(stderr,"dag_close: %s\n", strerror(errno)); + } +#endif + delete_pcap_dag(p); +} + +static void atexit_handler(void) { + while (pcap_dags != NULL) { + dag_platform_close(pcap_dags->p); + } +} + +static int new_pcap_dag(pcap_t *p) { + pcap_dag_node_t *node = NULL; + + if ((node = malloc(sizeof(pcap_dag_node_t))) == NULL) { + return -1; + } + + if (!atexit_handler_installed) { + atexit(atexit_handler); + atexit_handler_installed = 1; + } + + node->next = pcap_dags; + node->p = p; + + return 0; +} + +/* + * Get pointer to the ERF header for the next packet in the input + * stream. This function blocks until a packet becomes available. + */ +static dag_record_t *get_next_dag_header(pcap_t *p) { + register dag_record_t *record; + int rlen; + + if (p->md.dag_mem_top - p->md.dag_mem_bottom < dag_record_size) { + p->md.dag_mem_top = dag_offset(p->fd, &(p->md.dag_mem_bottom), 0); + } + + record = (dag_record_t *)(p->md.dag_mem_base + p->md.dag_mem_bottom); + rlen = ntohs(record->rlen); + while (p->md.dag_mem_top - p->md.dag_mem_bottom < rlen) { + p->md.dag_mem_top = dag_offset(p->fd, &(p->md.dag_mem_bottom), 0); + record = (dag_record_t *)(p->md.dag_mem_base + p->md.dag_mem_bottom); + rlen = ntohs(record->rlen); + } + + p->md.dag_mem_bottom += rlen; + + return record; +} + +/* Size of payload in ATM packets */ +#define ATM_CAPTURE_SIZE 48 + +/* Size of payload of Ethernet packet */ +#define ETHERNET_LENGTH(h) min(ntohs((h)->wlen) - 4, ntohs((h)->rlen) - dag_record_size - 2 - (ntohs((h)->wlen) & 0x3)) + +/* Size of HDLC packet */ +#define HDLC_LENGTH(h) min(ntohs((h)->wlen) - 4, ntohs((h)->rlen) - dag_record_size) + +#ifndef min +#define min(a, b) ((a) > (b) ? (b) : (a)) +#endif + +/* + * Swap byte ordering of unsigned long long on a big endian + * machine. + */ +static unsigned long long swapll(unsigned long long ull) { +#if (BYTE_ORDER == BIG_ENDIAN) + return ((ull & 0xff00000000000000LL) >> 56) | + ((ull & 0x00ff000000000000LL) >> 40) | + ((ull & 0x0000ff0000000000LL) >> 24) | + ((ull & 0x000000ff00000000LL) >> 8) | + ((ull & 0x00000000ff000000LL) << 8) | + ((ull & 0x0000000000ff0000LL) << 24) | + ((ull & 0x000000000000ff00LL) << 40) | + ((ull & 0x00000000000000ffLL) << 56) ; +#else + return ull; +#endif +} + +/* + * Read at most max_packets from the capture stream and call the callback + * for each of them. Returns the number of packets handled or -1 if an + * error occured. A blocking + */ +int dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) { + u_char *dp = NULL; + int packet_len = 0, caplen = 0; + struct pcap_pkthdr pcap_header; + + dag_record_t *header; + register unsigned long long ts; + + /* Receive a single packet from the kernel */ + header = get_next_dag_header(p); + dp = ((u_char *)header) + dag_record_size; + + switch(header->type) { + case TYPE_ATM: + packet_len = ATM_CAPTURE_SIZE; + caplen = ATM_CAPTURE_SIZE; + break; + case TYPE_ETH: + packet_len = ntohs(header->wlen); + caplen = ETHERNET_LENGTH(header); + dp += 2; + break; + case TYPE_HDLC_POS: + packet_len = ntohs(header->wlen); + caplen = HDLC_LENGTH(header); + break; + } + + if (caplen > p->snapshot) + caplen = p->snapshot; + + /* Run the packet filter if not using kernel filter */ + if (p->fcode.bf_insns) { + if (bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen) == 0) { + /* rejected by filter */ + return 0; + } + } + + /* convert between timestamp formats */ + ts = swapll(header->ts); + pcap_header.ts.tv_sec = ts >> 32; + ts = ((ts & 0xffffffffULL) * 1000 * 1000); + ts += (ts & 0x80000000ULL) << 1; /* rounding */ + pcap_header.ts.tv_usec = ts >> 32; + if (pcap_header.ts.tv_usec >= 1000000) { + pcap_header.ts.tv_usec -= 1000000; + pcap_header.ts.tv_sec += 1; + } + + /* Fill in our own header data */ + pcap_header.caplen = caplen; + pcap_header.len = packet_len; + + /* + * Count the packet. + */ + p->md.stat.ps_recv++; + + /* Call the user supplied callback function */ + callback(user, &pcap_header, dp); + + return 1; +} + +/* + * Get a handle for a live capture from the given DAG device. Passing a NULL + * device will result in a failure. The promisc flag is ignored because DAG + * cards are always promiscuous. The to_ms parameter is also ignored as it is + * not supported in hardware. + * + * See also pcap(3). + */ +pcap_t *dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf) { + char conf[30]; /* dag configure string */ + pcap_t *handle; + + if (device == NULL) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "device is NULL: %s", pcap_strerror(errno)); + return NULL; + } + /* Allocate a handle for this session. */ + + handle = malloc(sizeof(*handle)); + if (handle == NULL) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc %s: %s", device, pcap_strerror(errno)); + return NULL; + } + + /* Initialize some components of the pcap structure. */ + + memset(handle, 0, sizeof(*handle)); + + if (strstr(device, "/dev") == NULL) { + char * newDev = (char *)malloc(strlen(device) + 6); + newDev[0] = '\0'; + strcat(newDev, "/dev/"); + strcat(newDev,device); + device = newDev; + } + + /* setup device parameters */ + if((handle->fd = dag_open((char *)device)) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_open %s: %s", device, pcap_strerror(errno)); + return NULL; + } + + /* set the card snap length as specified by the specified snaplen parameter */ + if (snaplen > MAX_DAG_SNAPLEN) { + snaplen = MAX_DAG_SNAPLEN; + } + snprintf(conf, 30, "varlen slen=%d", (snaplen % 4) ? (snaplen + 3) & ~3 : snaplen); /* snap len has to be a multiple of 4 */ + fprintf(stderr, "Configuring DAG with '%s'.\n", conf); + if(dag_configure(handle->fd, conf) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE,"dag_configure %s: %s\n", device, pcap_strerror(errno)); + return NULL; + } + + if((handle->md.dag_mem_base = dag_mmap(handle->fd)) == MAP_FAILED) { + snprintf(ebuf, PCAP_ERRBUF_SIZE,"dag_mmap %s: %s\n", device, pcap_strerror(errno)); + return NULL; + } + + if(dag_start(handle->fd) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_start %s: %s\n", device, pcap_strerror(errno)); + return NULL; + } + + /* + * Important! You have to ensure bottom is properly + * initialized to zero on startup, it won't give you + * a compiler warning if you make this mistake! + */ + handle->md.dag_mem_bottom = 0; + handle->md.dag_mem_top = 0; + handle->md.is_dag = 1; + + handle->snapshot = snaplen; + /*handle->md.timeout = to_ms; */ + +#ifdef linux + if (device) { + handle->md.device = strdup(device); + } + + if (handle->md.device == NULL) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "str_dup %s: %s\n", device, pcap_strerror(errno)); + free(handle); + return NULL; + } +#endif + + /* set link type */ + + /* Check the type through a dagapi call. + */ + switch(dag_linktype(handle->fd)) { + case TYPE_HDLC_POS: + handle->linktype = DLT_CHDLC; + fprintf(stderr, "Set DAG linktype to %d (DLT_CHDLC)\n", handle->linktype); + break; + case TYPE_ETH: + handle->linktype = DLT_EN10MB; + fprintf(stderr, "Set DAG linktype to %d (DLT_EN10MB)\n", handle->linktype); + break; + case TYPE_ATM: + handle->linktype = DLT_ATM_RFC1483; + fprintf(stderr, "Set DAG linktype to %d (DLT_ATM_RFC1483)\n", handle->linktype); + break; + case TYPE_LEGACY: + handle->linktype = DLT_NULL; + fprintf(stderr, "Set DAG linktype to %d (DLT_NULL)\n", handle->linktype); + break; + default: + snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_open_live %s: unknown linktype %d\n", device, dag_linktype(handle->fd)); + return NULL; + } + + handle->bufsize = 0;/*handle->snapshot;*/ + + if (new_pcap_dag(handle) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "new_pcap_dag %s: %s\n", device, pcap_strerror(errno)); + return NULL; + } + + return handle; +} + +int dag_stats(pcap_t *p, struct pcap_stat *ps) { + /* This needs to be filled out correctly. Hopefully a dagapi call will + provide all necessary information. + */ + /*p->md.stat.ps_recv = 0;*/ + /*p->md.stat.ps_drop = 0;*/ + + *ps = p->md.stat; + + return 0; +} + +/* + * Get from "/proc/dag" all interfaces listed there; if they're + * already in the list of interfaces we have, that won't add another + * instance, but if they're not, that'll add them. + * + * We don't bother getting any addresses for them. + * + * We also don't fail if we couldn't open "/proc/dag"; we just leave + * the list of interfaces as is. + */ +int +dag_platform_finddevs(pcap_if_t **devlistp, char *errbuf) +{ + FILE *proc_dag_f; + char linebuf[512]; + int linenum; + unsigned char *p; + char name[512]; /* XXX - pick a size */ + char *q, *saveq; + struct ifreq ifrflags; + int ret = 0; + + /* Quick exit if /proc/dag not readable */ + proc_dag_f = fopen("/proc/dag", "r"); + if (proc_dag_f == NULL) + { + int i, fd; + char dev[16] = "dagx"; + + for (i = '0'; ret == 0 && i <= '9'; i++) { + dev[3] = i; + if (pcap_add_if(devlistp, dev, 0, NULL, errbuf) == -1) { + /* + * Failure. + */ + ret = -1; + } + } + + return (ret); + } + + for (linenum = 1; + fgets(linebuf, sizeof linebuf, proc_dag_f) != NULL; linenum++) { + + /* + * Skip the first two lines - they're headers. + */ + if (linenum <= 2) + continue; + + p = &linebuf[0]; + + if (*p == '\0' || *p == '\n' || *p != 'D') + continue; /* not a Dag line */ + + /* + * Get the interface name. + */ + q = &name[0]; + while (*p != '\0' && *p != ':') { + if (*p != ' ') + *q++ = tolower(*p++); + else + p++; + } + *q = '\0'; + + /* + * Add an entry for this interface, with no addresses. + */ + p[strlen(p) - 1] = '\0'; /* get rid of \n */ + if (pcap_add_if(devlistp, name, 0, strdup(p + 2), errbuf) == -1) { + /* + * Failure. + */ + ret = -1; + break; + } + } + if (ret != -1) { + /* + * Well, we didn't fail for any other reason; did we + * fail due to an error reading the file? + */ + if (ferror(proc_dag_f)) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "Error reading /proc/dag: %s", + pcap_strerror(errno)); + ret = -1; + } + } + + (void)fclose(proc_dag_f); + return (ret); +} + +/* + * Installs the gven bpf filter program in the given pcap structure. There is + * no attempt to store the filter in kernel memory as that is not supported + * with DAG cards. + */ +int dag_setfilter(pcap_t *p, struct bpf_program *fp) { + if (!p) + return -1; + if (!fp) { + strncpy(p->errbuf, "setfilter: No filter specified", + sizeof(p->errbuf)); + return -1; + } + + /* Make our private copy of the filter */ + + if (install_bpf_program(p, fp) < 0) { + snprintf(p->errbuf, sizeof(p->errbuf), + "malloc: %s", pcap_strerror(errno)); + return -1; + } + + p->md.use_bpf = 0; + + return (0); +} + +int +dag_set_datalink_platform(pcap_t *p, int dlt) +{ + return (0); +} diff --git a/pcap-dag.h b/pcap-dag.h new file mode 100644 index 0000000..b486907 --- /dev/null +++ b/pcap-dag.h @@ -0,0 +1,18 @@ +/* + * pcap-dag.c: Packet capture interface for Endace DAG card. + * + * The functionality of this code attempts to mimic that of pcap-linux as much + * as possible. This code is only needed when compiling in the DAG card code + * at the same time as another type of device. + * + * Author: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com) + * + * @(#) $Header: /tcpdump/master/libpcap/pcap-dag.h,v 1.1 2003-07-23 05:29:21 guy Exp $ (LBL) + */ + +int dag_stats(pcap_t *p, struct pcap_stat *ps); +int dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user); +pcap_t *dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf); +int dag_setfilter(pcap_t *p, struct bpf_program *fp); +void dag_platform_close(pcap_t *p); + diff --git a/pcap-int.h b/pcap-int.h index 3e5eacc..5d4e5da 100644 --- a/pcap-int.h +++ b/pcap-int.h @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.46 2003-04-10 06:07:08 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.47 2003-07-23 05:29:21 guy Exp $ (LBL) */ #ifndef pcap_int_h @@ -76,6 +76,13 @@ struct pcap_md { char *device; /* device name */ struct pcap *next; /* list of open promiscuous sock_packet pcaps */ #endif + +#ifdef HAVE_DAG_API + int is_dag; /* this is a dag card handle */ + void *dag_mem_base; /* DAG card memory base address */ + u_int dag_mem_bottom; /* DAG card current memory bottom pointer */ + u_int dag_mem_top; /* DAG card current memory top pointer */ +#endif }; struct pcap { diff --git a/pcap-linux.c b/pcap-linux.c index 895363c..efdd80c 100644 --- a/pcap-linux.c +++ b/pcap-linux.c @@ -24,9 +24,10 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ + #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.89 2003-04-09 07:19:49 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.90 2003-07-23 05:29:22 guy Exp $ (LBL)"; #endif /* @@ -79,6 +80,10 @@ static const char rcsid[] = #include "pcap-int.h" #include "sll.h" +#ifdef HAVE_DAG_API +#include "pcap-dag.h" +#endif /* HAVE_DAG_API */ + #include #include #include @@ -228,6 +233,12 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, int live_open_ok = 0; struct utsname utsname; +#ifdef HAVE_DAG_API + if (strstr(device, "dag")) { + return dag_open_live(device, snaplen, promisc, to_ms, ebuf); + } +#endif /* HAVE_DAG_API */ + /* Allocate a handle for this session. */ handle = malloc(sizeof(*handle)); @@ -403,6 +414,12 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, int pcap_read(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user) { +#ifdef HAVE_DAG_API + if (handle->md.is_dag) { + return dag_read(handle, max_packets, callback, user); + } +#endif /* HAVE_DAG_API */ + /* * Currently, on Linux only one packet is delivered per read, * so we don't loop. @@ -655,7 +672,15 @@ pcap_stats(pcap_t *handle, struct pcap_stat *stats) #ifdef HAVE_TPACKET_STATS struct tpacket_stats kstats; socklen_t len = sizeof (struct tpacket_stats); +#endif +#ifdef HAVE_DAG_API + if (handle->md.is_dag) { + return dag_stats(handle, stats); + } +#endif /* HAVE_DAG_API */ + +#ifdef HAVE_TPACKET_STATS /* * Try to get the packet counts from the kernel. */ @@ -748,6 +773,11 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) if (pcap_add_if(alldevsp, "any", 0, any_descr, errbuf) < 0) return (-1); +#ifdef HAVE_DAG_API + if (dag_platform_finddevs(alldevsp, errbuf) < 0) + return (-1); +#endif /* HAVE_DAG_API */ + return (0); } @@ -763,6 +793,12 @@ pcap_setfilter(pcap_t *handle, struct bpf_program *filter) int err = 0; #endif +#ifdef HAVE_DAG_API + if (handle->md.is_dag) { + return dag_setfilter(handle, filter); + } +#endif /* HAVE_DAG_API */ + if (!handle) return -1; if (!filter) { @@ -1428,6 +1464,13 @@ void pcap_close_linux( pcap_t *handle ) struct pcap *p, *prevp; struct ifreq ifr; +#ifdef HAVE_DAG_API + if (handle->md.is_dag) { + /* close actions will be done in dag_platform_close() */ + return; + } +#endif /* HAVE_DAG_API */ + if (handle->md.clear_promisc) { /* * We put the interface into promiscuous mode; take @@ -1950,5 +1993,11 @@ reset_kernel_filter(pcap_t *handle) int pcap_set_datalink_platform(pcap_t *p, int dlt) { +#ifdef HAVE_DAG_API + if (p->md.is_dag) { + return dag_set_datalink_platform(p, dlt); + } +#endif /* HAVE_DAG_API */ + return (0); } diff --git a/pcap.c b/pcap.c index 2b329e9..90bb3e1 100644 --- a/pcap.c +++ b/pcap.c @@ -33,7 +33,7 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.55 2003-06-07 10:26:04 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.56 2003-07-23 05:29:22 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -637,6 +637,9 @@ pcap_close(pcap_t *p) if (p->fd >= 0) { #ifdef linux pcap_close_linux(p); +#endif +#ifdef HAVE_DAG_API + dag_platform_close(p); #endif close(p->fd); }