diff options
author | fenner <fenner@FreeBSD.org> | 2001-04-03 04:18:09 +0000 |
---|---|---|
committer | fenner <fenner@FreeBSD.org> | 2001-04-03 04:18:09 +0000 |
commit | a6bce8883c0f9dd7fee0eb03667f57b40b1d9dab (patch) | |
tree | 3549230334d9c115b8db8b950fb89d69f7b23d16 /contrib | |
parent | 6f08532b51656817ca97987b95e3b7422d6be2ae (diff) | |
download | FreeBSD-src-a6bce8883c0f9dd7fee0eb03667f57b40b1d9dab.zip FreeBSD-src-a6bce8883c0f9dd7fee0eb03667f57b40b1d9dab.tar.gz |
Virgin import of tcpdump.org libpcap v0.6.2
Diffstat (limited to 'contrib')
51 files changed, 6213 insertions, 1317 deletions
diff --git a/contrib/libpcap/.cvsignore b/contrib/libpcap/.cvsignore new file mode 100644 index 0000000..12a60dd --- /dev/null +++ b/contrib/libpcap/.cvsignore @@ -0,0 +1,10 @@ +config.log +config.cache +config.status +config.h +.devel +Makefile +scanner.c +grammar.c +tokdefs.h +version.c diff --git a/contrib/libpcap/CHANGES b/contrib/libpcap/CHANGES index 4d739c5..5793de0 100644 --- a/contrib/libpcap/CHANGES +++ b/contrib/libpcap/CHANGES @@ -1,11 +1,76 @@ -@(#) $Header: /tcpdump/master/libpcap/CHANGES,v 1.48 1999/10/30 23:50:43 itojun Exp $ (LBL) +@(#) $Header: /tcpdump/master/libpcap/CHANGES,v 1.55 2001/01/10 04:10:33 guy Exp $ (LBL) -Sun Oct 19 JST 1999 itojun@iijlab.net - * bring in KAME IPv6/IPsec bpf compiler. +Tuesday January 9, 2001. guy@alum.mit.edu. Summary for 0.6 release -Sometime in 1999 - * tcpdump.org imported LBL 0.4 + New Linux libpcap implementation, which, in 2.2 and later + kernels, uses PF_PACKET sockets and supports kernel packet + filtering (if compiled into the kernel), and supports the "any" + device for capturing on all interfaces. Cleans up promiscuous + mode better on pre-2.2 kernels, and has various other fixes + (handles 2.4 ARPHRD_IEEE802_TR, handles ISDN devices better, + doesn't show duplicate packets on loopback interface, etc.). + Fixed HP-UX libpcap implementation to correctly get the PPA for + an interface, to allow interfaces to be opened by interface name. + + libpcap savefiles have system-independent link-layer type values + in the header, rather than sometimes platform-dependent DLT_ + values, to make it easier to exchange capture files between + different OSes. + + Non-standard capture files produced by some Linux tcpdumps, e.g. + the one from Red Hat Linux 6.2 and later, can now be read. + + Updated autoconf stock files. + + Filter expressions can filter on VLAN IDs and various OSI + protocols, and work on Token Ring (with non-source-routed + packets). + + "pcap_open_dead()" added to allow compiling filter expressions + to pcap code without opening a capture device or capture file. + + Header files fixed to allow use in C++ programs. + + Removed dependancy on native headers for packet layout. + Removed Linux specific headers that were shipped. + + Security fixes: Strcpy replaced with strlcpy, sprintf replaced + with snprintf. + + Fixed bug that could cause subsequent "pcap_compile()"s to fail + erroneously after one compile failed. + + Assorted other bug fixes. + + README.aix and README.linux files added to describe + platform-specific issues. + + "getifaddrs()" rather than SIOCGIFCONF used, if available. + +v0.5 Sat Jun 10 11:09:15 PDT 2000 + +itojun@iijlab.net +- Brought in KAME IPv6/IPsec bpf compiler. +- Fixes for NetBSD. +- Support added for OpenBSD DLT_LOOP and BSD/OS DLT_C_HDLC (Cisco HDLC), + and changes to work around different BSDs having different DLT_ types + with the same numeric value. + +Assar Westerlund <assar@sics.se> +- Building outside the source code tree fixed. +- Changed to write out time stamps with 32-bit seconds and microseconds + fields, regardless of whether those fields are 32 bits or 64 bits in + the OS's native "struct timeval". +- Changed "pcap_lookupdev()" to dynamically grow the buffer into which + the list of interfaces is read as necessary in order to hold the + entire list. + +Greg Troxel <gdt@ir.bbn.com> +- Added a new "pcap_compile_nopcap()", which lets you compile a filter + expression into a BPF program without having an open live capture or + capture file. + v0.4 Sat Jul 25 12:40:09 PDT 1998 - Fix endian problem with DLT_NULL devices. From FreeBSD via Bill diff --git a/contrib/libpcap/CREDITS b/contrib/libpcap/CREDITS index a518ff5..5797237 100644 --- a/contrib/libpcap/CREDITS +++ b/contrib/libpcap/CREDITS @@ -1,15 +1,36 @@ -This file lists people who contributed to libpcap or tcpdump: - Bill Fenner <fenner@research.att.com> - Assar Westerlund <assar@sics.se> - Alexei <kuznet@ms2.inr.ac.ru> - Jun-ichiro itojun Hagino <itojun@iijlab.net> - Guy Harris <gharris@flashcom.net> - Torsten Landschoff <t.landschoff@gmx.net> - Michael Richardson <mcr@sandelman.ottawa.on.ca> +This file lists people who have contributed to libpcap: + +The current maintainers: + Bill Fenner <fenner@research.att.com> + Assar Westerlund <assar@sics.se> + Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> + Jun-ichiro itojun Hagino <itojun@iijlab.net> + Guy Harris <guy@alum.mit.edu> + Torsten Landschoff <torsten@debian.org> + Michael Richardson <mcr@sandelman.ottawa.on.ca> + Sebastian Krahmer <krahmer@cs.uni-potsdam.de> + +Additional people who have contributed patches: + + Arkadiusz Miskiewicz <misiek@pld.org.pl> + Fulvio Risso <risso@polito.it> + Charles M. Hannum <mycroft@netbsd.org> + Chris G. Demetriou <cgd@netbsd.org> + Darren Reed <darrenr@reed.wattle.id.au> + Greg Troxel <gdt@ir.bbn.com> + Jefferson Ogata <jogata@nodc.noaa.gov> + Juergen Schoenwaelder <schoenw@ibr.cs.tu-bs.de> + Lorenzo Cavallaro <sullivan@sikurezza.org> + Love Hörnquist-Åstrand <lha@stacken.kth.se> + Monroe Williams <monroe@pobox.com> + Olaf Kirch <okir@caldera.de> + Peter Jeremy <peter.jeremy@alcatel.com.au> + Rafal Maszkowski <rzm@icm.edu.pl> + Rick Jones <raj@cup.hp.com> + Tony Li <tli@jnx.com> + Uwe Girlich <Uwe.Girlich@philosys.de> The original LBL crew: Steve McCanne Craig Leres Van Jacobson - - diff --git a/contrib/libpcap/FILES b/contrib/libpcap/FILES index daad279..36141ca 100644 --- a/contrib/libpcap/FILES +++ b/contrib/libpcap/FILES @@ -1,15 +1,23 @@ CHANGES +CREDITS FILES INSTALL +LICENSE Makefile.in README -SUNOS4 +README.aix +README.linux +SUNOS4/nit_if.o.sparc +SUNOS4/nit_if.o.sun3 +SUNOS4/nit_if.o.sun4c.4.0.3c VERSION aclocal.m4 bpf/net/bpf.h bpf/net/bpf_filter.c +bpf_dump.c bpf_image.c config.guess +config.h.in config.sub configure configure.in @@ -20,14 +28,13 @@ gencode.h grammar.y inet.c install-sh -lbl/gnuc.h +lbl/os-osf4.h lbl/os-solaris2.h lbl/os-sunos4.h lbl/os-ultrix4.h -linux-include/netinet/if_ether.h -linux-include/netinet/ip_var.h mkdep nametoaddr.c +nlpid.h optimize.c pcap-bpf.c pcap-dlpi.c @@ -48,3 +55,4 @@ pcap.h ppp.h savefile.c scanner.l +sll.h diff --git a/contrib/libpcap/INSTALL b/contrib/libpcap/INSTALL index ee797f2..e8d8d96 100644 --- a/contrib/libpcap/INSTALL +++ b/contrib/libpcap/INSTALL @@ -1,13 +1,12 @@ -@(#) $Header: /tcpdump/master/libpcap/INSTALL,v 1.42.1.1 1999/10/07 23:46:40 mcr Exp $ (LBL) +@(#) $Header: /tcpdump/master/libpcap/INSTALL,v 1.46 2000/12/16 09:05:11 guy Exp $ (LBL) -To build libpcap, first customize any paths in Makefile.in, then run -"./configure" (a shell script). The configure script will determine -your system attributes and generate an appropriate Makefile from -Makefile.in. Next run "make". If everything goes well you can su to -root and run "make install", "make install-incl" and "make -install-man". However, you need not install libpcap if you just want to -build tcpdump; just make sure the tcpdump and libpcap directory trees -have the same parent directory. +To build libpcap, run "./configure" (a shell script). The configure +script will determine your system attributes and generate an +appropriate Makefile from Makefile.in. Next run "make". If everything +goes well you can su to root and run "make install". However, you need +not install libpcap if you just want to build tcpdump; just make sure +the tcpdump and libpcap directory trees have the same parent +directory. If configure says: @@ -34,18 +33,7 @@ You will need an ANSI C compiler to build libpcap. The configure script will abort if your compiler is not ANSI compliant. If this happens, use the GNU C compiler, available via anonymous ftp: - ftp://prep.ai.mit.edu/pub/gnu/gcc-*.tar.gz - -Note well: If you use gcc, you may need to run its "fixincludes" -script. Running fixincludes is not required with later versions of gcc -and in some cases (e.g. Solaris 2.5) causes problems when run. The -configure script will abort with: - - checking for ANSI ioctl definitions... yes - configure: error: see the INSTALL for more info - -if it detects if the fixincludes needs to be run. If the fixincludes -test in configure passes, you're probably ok. + ftp://ftp.gnu.org/pub/gnu/gcc/ If you use flex, you must use version 2.4.6 or higher. The configure script automatically detects the version of flex and will not use it @@ -122,11 +110,15 @@ If you get an error like: when using DLPI, look for the DL_ERROR_ACK error return values, usually in /usr/include/sys/dlpi.h, and find the corresponding value. -Under OSF, packet capture must be enabled before it can be used. For -instructions on how to enable packet filter support, see: +Under {DEC OSF/1, Digital UNIX, Tru64 UNIX}, packet capture must be +enabled before it can be used. For instructions on how to enable packet +filter support, see: ftp://ftp.digital.com/pub/Digital/dec-faq/Digital-UNIX +Look for the "How do I configure the Berkeley Packet Filter and capture +tcpdump traces?" item. + Once you enable packet filter support, your OSF system will support bpf natively. @@ -147,53 +139,76 @@ then you don't have the streams package. In addition, we believe you need to install the "9.X LAN and DLPI drivers cumulative" patch (PHNE_6855) to make the version 9 DLPI work with libpcap. -It's been reported that the DLPI streams package is standard starting -with HP-UX 10. +The DLPI streams package is standard starting with HP-UX 10. The HP implementation of DLPI is a little bit eccentric. Unlike Solaris, you must attach /dev/dlpi instead of the specific /dev/* -network pseudo device entry in order to capture packets. The ppa is +network pseudo device entry in order to capture packets. The PPA is based on the ifnet "index" number. Under HP-UX 9, it is necessary to read /dev/kmem and the kernel symbol file (/hp-ux). Under HP-UX 10, -dlpi can provide information for determining the ppa. It does not seem +DLPI can provide information for determining the PPA. It does not seem to be possible to trace the loopback interface. Unlike other DLPI implementations, PHYS implies MULTI and SAP and you get an error if you -try to enable more than one promiscous more than one promiscuous mode -at a time. Finally, testing shows that there can't be more than one -simultaneous dlpi user per network interface and you cannot capture -outbound packets. +try to enable more than one promiscuous mode at a time. + +It is impossible to capture outbound packets on HP-UX 9. To do so on +HP-UX 10, you will, apparently, need a late "LAN products cumulative +patch" (at one point, it was claimed that this would be PHNE_18173 for +s700/10.20; at another point, it was claimed that the required patches +were PHNE_20892, PHNE_20725 and PHCO_10947, or newer patches), and to do +so on HP-UX 11 you will, apparently, need the latest lancommon/DLPI +patches and the latest driver patch for the interface(s) in use on HP-UX +11 (at one point, it was claimed that patches PHNE_19766, PHNE_19826, +PHNE_20008, and PHNE_20735 did the trick). + +Furthermore, on HP-UX 10, you will need to turn on a kernel switch by +doing + + echo 'lanc_outbound_promisc_flag/W 1' | adb -w /stand/vmunix /dev/mem + +You would have to arrange that this happen on reboots; the right way to +do that would probably be to put it into an executable script file +"/sbin/init.d/outbound_promisc" and making +"/sbin/rc2.d/S350outbound_promisc" a symbolic link to that script. + +Finally, testing shows that there can't be more than one simultaneous +DLPI user per network interface. If you use Linux, this version of libpcap is known to compile and run -under Red Hat 4.0 with the 2.0.25 kernel. It may work with earlier 2.X -versions but is guaranteed not to work with 1.X kernels. Running more -than one libpcap program at a time can cause problems since promiscuous -mode is implemented by twiddlin the interface flags from the libpcap -application. Also, packet timestamps aren't very good. This appears to -be due to haphazard handling of the timestamp in the kernel. +under Red Hat 4.0 with the 2.0.25 kernel. It may work with earlier 2.X +versions but is guaranteed not to work with 1.X kernels. Running more +than one libpcap program at a time, on a system with a 2.0.X kernel, can +cause problems since promiscuous mode is implemented by twiddling the +interface flags from the libpcap application; the packet capture +mechanism in the 2.2 and later kernels doesn't have this problem. Also, +packet timestamps aren't very good. This appears to be due to haphazard +handling of the timestamp in the kernel. Note well: there is rumoured to be a version of tcpdump floating around -called 3.0.3 that includes libpcap and is supposed to support Linux. -You should be advised that the Network Research Group at LBNL never -generated a release with this version number. We note with interest -that a standard cracker trick to get people to install trojans is to -distribute bogus packages that have a version number higher than the -current release. We also note with annoyance that 90% of the Linux -related bug reports we get are due to changes made to unofficial -versions of our page. If you are having trouble but aren't using a -version that came from ftp.ee.lbl.gov, please try that before -submitting a bug report! +called 3.0.3 that includes libpcap and is supposed to support Linux. +You should be advised that neither the Network Research Group at LBNL +nor the Tcpdump Group ever generated a release with this version number. +The LBNL Network Research Group notes with interest that a standard +cracker trick to get people to install trojans is to distribute bogus +packages that have a version number higher than the current release. +They also noted with annoyance that 90% of the Linux related bug reports +they got are due to changes made to unofficial versions of their page. +If you are having trouble but aren't using a version that came from +tcpdump.org, please try that before submitting a bug report! + +On Linux, libpcap will not work if the kernel does not have the packet +socket option enabled; see the README.linux file for information about +this. If you use AIX, you may not be able to build libpcap from this release. -Although AIX 4 ships with tcpdump, it is an old version that predates libpcap. We do not have an AIX system in house so it's impossible for us to test AIX patches submitted to us. We are told that you must link against /lib/pse.exp, that you must use AIX cc or a GNU C compiler newer than 2.7.2 and that you may need to run strload before running a -libpcap application. Also, it may be necessary to run the configure -script as root in order for it to detect that bpf is available. Another -workaround is to use: +libpcap application. - ./configure --with-pcap=bpf +Read the README.aix file for information on installing libpcap and +configuring your system to be able to support libpcap. If you use NeXTSTEP, you will not be able to build libpcap from this release. We hope to support this operating system in some future @@ -215,7 +230,7 @@ Another workaround is to use flex and bison. If you use SCO, you might have trouble building libpcap from this release. We do not have a machine running SCO and have not had reports of anyone successfully building on it. Since SCO apparently supports -dlpi, it's possible the current version works. Meanwhile, sco provides +DLPI, it's possible the current version works. Meanwhile, SCO provides a tcpdump binary as part of their "Network/Security Tools" package: http://www.sco.com/technology/internet/goodies/#SECURITY @@ -236,7 +251,7 @@ a Sun4, your version of bison is broken. In any case version 1.16 or higher is recommended (1.14 is known to cause problems 1.16 is known to work). Either pick up a current version from: - ftp://prep.ai.mit.edu/pub/gnu/bison.tar.gz + ftp://ftp.gnu.org/pub/gnu/bison or hack around it by inserting the lines: @@ -303,7 +318,6 @@ inet.c - network routines install-sh - BSD style install script lbl/gnuc.h - gcc macros and defines lbl/os-*.h - os dependent defines and prototypes -linux-include/* - network include files missing on Linux mkdep - construct Makefile dependency list nametoaddr.c - hostname to address routines net - symlink to bpf/net diff --git a/contrib/libpcap/LICENSE b/contrib/libpcap/LICENSE new file mode 100644 index 0000000..dea5f7d --- /dev/null +++ b/contrib/libpcap/LICENSE @@ -0,0 +1,19 @@ +License: BSD + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not 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. diff --git a/contrib/libpcap/Makefile.in b/contrib/libpcap/Makefile.in index 2cb6feb..600087a 100644 --- a/contrib/libpcap/Makefile.in +++ b/contrib/libpcap/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.75 1999/10/30 05:33:45 itojun Exp $ (LBL) +# @(#) $Header: /tcpdump/master/libpcap/Makefile.in,v 1.87.2.1 2001/01/18 04:06:24 guy Exp $ (LBL) # # Various configurable paths (remember to edit Makefile.in, not Makefile) @@ -27,11 +27,11 @@ prefix = @prefix@ exec_prefix = @exec_prefix@ # Pathname of directory to install the include files -INCLDEST = @includedir@ +includedir = @includedir@ # Pathname of directory to install the library -LIBDEST = @libdir@ +libdir = @libdir@ # Pathname of directory to install the man page -MANDEST = @mandir@ +mandir = @mandir@ # VPATH srcdir = @srcdir@ @@ -50,7 +50,9 @@ DEFS = @DEFS@ CFLAGS = $(CCOPT) $(INCLS) $(DEFS) INSTALL = @INSTALL@ -RANLIB = @V_RANLIB@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +RANLIB = @RANLIB@ # # Flex and bison allow you to specify the prefixes of the global symbols @@ -69,14 +71,15 @@ YACC = @V_YACC@ PSRC = pcap-@V_PCAP@.c CSRC = pcap.c inet.c gencode.c optimize.c nametoaddr.c \ - etherent.c savefile.c bpf_filter.c bpf_image.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) $(CSRC) $(GENSRC) # We would like to say "OBJ = $(SRC:.c=.o)" but Ultrix's make cannot # hack the extra indirection -OBJ = $(PSRC:.c=.o) $(CSRC:.c=.o) $(GENSRC:.c=.o) +OBJ = $(PSRC:.c=.o) $(CSRC:.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 = \ @@ -118,42 +121,59 @@ grammar.o: grammar.c version.o: version.c $(CC) $(CFLAGS) -c version.c +snprintf.o: $(srcdir)/../tcpdump/missing/snprintf.c + $(CC) $(CFLAGS) -o $@ -c $(srcdir)/../tcpdump/missing/snprintf.c + version.c: $(srcdir)/VERSION @rm -f $@ sed -e 's/.*/char pcap_version[] = "&";/' $(srcdir)/VERSION > $@ -bpf_filter.o: $(srcdir)/bpf/net/bpf_filter.c - $(CC) $(CFLAGS) -c $(srcdir)/bpf/net/bpf_filter.c -o bpf_filter.o - -install: force - $(INSTALL) -m 444 -o bin -g bin libpcap.a $(DESTDIR)$(LIBDEST)/libpcap.a - $(RANLIB) $(DESTDIR)$(LIBDEST)/libpcap.a - -install-incl: force - $(INSTALL) -m 444 -o bin -g bin $(srcdir)/pcap.h \ - $(DESTDIR)$(INCLDEST)/pcap.h - $(INSTALL) -m 444 -o bin -g bin $(srcdir)/pcap-namedb.h \ - $(DESTDIR)$(INCLDEST)/pcap-namedb.h - $(INSTALL) -m 444 -o bin -g bin $(srcdir)/bpf/net/bpf.h \ - $(DESTDIR)$(INCLDEST)/net/bpf.h - -install-man: force - $(INSTALL) -m 444 -o bin -g bin $(srcdir)/pcap.3 \ - $(DESTDIR)$(MANDEST)/man3/pcap.3 +bpf_filter.c: $(srcdir)/bpf/net/bpf_filter.c + rm -f bpf_filter.c + ln -s $(srcdir)/bpf/net/bpf_filter.c bpf_filter.c + +bpf_filter.o: bpf_filter.c + $(CC) $(CFLAGS) -c bpf_filter.c + +install: + [ -d $(DESTDIR)$(libdir) ] || \ + (mkdir -p $(DESTDIR)$(libdir); chmod 755 $(DESTDIR)$(libdir)) + $(INSTALL_DATA) libpcap.a $(DESTDIR)$(libdir)/libpcap.a + $(RANLIB) $(DESTDIR)$(libdir)/libpcap.a + [ -d $(DESTDIR)$(includedir) ] || \ + (mkdir -p $(DESTDIR)$(includedir); chmod 755 $(DESTDIR)$(includedir)) + $(INSTALL_DATA) $(srcdir)/pcap.h $(DESTDIR)$(includedir)/pcap.h + $(INSTALL_DATA) $(srcdir)/pcap-namedb.h \ + $(DESTDIR)$(includedir)/pcap-namedb.h + [ -d $(DESTDIR)$(includedir)/net ] || \ + (mkdir -p $(DESTDIR)$(includedir)/net; chmod 755 $(DESTDIR)$(includedir)/net) + $(INSTALL_DATA) $(srcdir)/bpf/net/bpf.h \ + $(DESTDIR)$(includedir)/net/bpf.h + [ -d $(DESTDIR)$(mandir)/man3 ] || \ + (mkdir -p $(DESTDIR)$(mandir)/man3; chmod 755 $(DESTDIR)$(mandir)/man3) + $(INSTALL_DATA) $(srcdir)/pcap.3 \ + $(DESTDIR)$(mandir)/man3/pcap.3 + +uninstall: + rm -f $(DESTDIR)$(libdir)/libpcap.a + rm -f $(DESTDIR)$(includedir)/pcap.h + rm -f $(DESTDIR)$(includedir)/pcap-namedb.h + rm -f $(DESTDIR)$(includedir)/net/bpf.h + rm -f $(DESTDIR)$(mandir)/man3/pcap.3 clean: rm -f $(CLEANFILES) distclean: rm -f $(CLEANFILES) Makefile config.cache config.log config.status \ - gnuc.h os-proto.h net + config.h gnuc.h os-proto.h net bpf_filter.c stamp-h stamp-h.in tags: $(TAGFILES) ctags -wtd $(TAGFILES) -tar: force +tar: @cwd=`pwd` ; dir=`basename $$cwd` ; name=libpcap-`cat VERSION` ; \ - list="" ; tar="tar chFFf" ; \ + list="" ; tar="tar chf" ; \ for i in `cat FILES` ; do list="$$list $$name/$$i" ; done; \ echo \ "rm -f ../$$name; ln -s $$dir ../$$name" ; \ @@ -165,6 +185,5 @@ tar: force "rm -f ../$$name" ; \ rm -f ../$$name -force: /tmp -depend: $(GENSRC) force +depend: $(GENSRC) bpf_filter.c ./mkdep -c $(CC) $(DEFS) $(INCLS) $(SRC) diff --git a/contrib/libpcap/README b/contrib/libpcap/README index 20be06a..c4161cd 100644 --- a/contrib/libpcap/README +++ b/contrib/libpcap/README @@ -1,10 +1,24 @@ -@(#) $Header: /tcpdump/master/libpcap/README,v 1.18.1.1 1999/10/07 23:46:40 mcr Exp $ (LBL) +@(#) $Header: /tcpdump/master/libpcap/README,v 1.22 2000/07/13 06:24:14 guy Exp $ (LBL) -LIBPCAP 0.4 -Lawrence Berkeley National Laboratory -Network Research Group -libpcap@ee.lbl.gov -ftp://ftp.ee.lbl.gov/libpcap.tar.Z +LIBPCAP 0.5 +Now maintained by "The Tcpdump Group" +See www.tcpdump.org + +Please send inquiries/comments/reports to tcpdump-workers@tcpdump.org + +Anonymous CVS is available via: + cvs -d cvs.tcpdump.org:/tcpdump/master login + (password "anoncvs") + cvs -d cvs.tcpdump.org:/tcpdump/master checkout libpcap + +Version 0.5 of LIBPCAP can be retrived with the CVS tag "libpcap_0_5": + cvs -d cvs.tcpdump.org:/tcpdump/master checkout -r libpcap_0_5 libpcap + +Please send patches against the master copy to patches@tcpdump.org. + +formerly from Lawrence Berkeley National Laboratory + Network Research Group <libpcap@ee.lbl.gov> + ftp://ftp.ee.lbl.gov/libpcap.tar.Z (0.4) This directory contains source code for libpcap, a system-independent interface for user-level packet capture. libpcap provides a portable @@ -33,17 +47,19 @@ added overhead (especially, for selective filters). Ideally, libpcap would translate BPF filters into a filter program that is compatible with the underlying kernel subsystem, but this is not yet implemented. -BPF is standard in 4.4BSD, BSD/386, NetBSD, and FreeBSD. DEC OSF/1 +BPF is standard in 4.4BSD, BSD/OS, NetBSD, FreeBSD, and OpenBSD. DEC OSF/1 uses the packetfilter interface but has been extended to accept BPF filters (which libpcap utilizes). Also, you can add BPF filter support to Ultrix using the kernel source and/or object patches available in: ftp://gatekeeper.dec.com/pub/DEC/net/bpfext42.tar.Z. -Problems, bugs, questions, desirable enhancements, source code -contributions, etc., should be sent to the email address -"libpcap@ee.lbl.gov". +Problems, bugs, questions, desirable enhancements, etc. +should be sent to the address "tcpdump-workers@tcpdump.org". + +Source code contributions, etc. should be sent to the email address +"patches@tcpdump.org". + +Current versions can be found at www.tcpdump.org - - Steve McCanne - Craig Leres - Van Jacobson + - The TCPdump team diff --git a/contrib/libpcap/README.aix b/contrib/libpcap/README.aix new file mode 100644 index 0000000..c78a40b --- /dev/null +++ b/contrib/libpcap/README.aix @@ -0,0 +1,46 @@ +(1) To configure libpcap under AIX 4.x, you should use DLPI instead + of BPF, since IBM's version of BPF includes some undocumented + and unsupported changes to the original BPF. + + This can be done by specifying the flag: + + --with-pcap=dlpi + + to the "configure" script for libpcap. + +(2) Also, it is a good idea to have the latest version of the DLPI + driver on your system, since certain versions may be buggy and + cause your AIX system to crash. DLPI is included in the + fileset bos.rte.tty. I found that the DLPI driver that came with + AIX 4.3.2 was buggy, and had to upgrade to bos.rte.tty 4.3.2.4: + + lslpp -l bos.rte.tty + + bos.rte.tty 4.3.2.4 COMMITTED Base TTY Support and Commands + + Updates for AIX filesets can be obtained from: + ftp://service.software.ibm.com/aix/fixes/ + + These updates can be installed with the smit program. + +(3) After compiling libpcap, you need to make sure that the DLPI driver + is loaded. Type: + + strload -q -d dlpi + + If the result is: + dlpi: yes + + then the DLPI driver is loaded correctly. + + If it is: + dlpi: no + + Then you need to type: + strload -f /etc/dlpi.conf + + Check again with strload -q -d dlpi that the dlpi driver is loaded. + + Alternatively, you can uncomment the lines for DLPI in + /etc/pse.conf and reboot the machine; this way DLPI will always + be loaded when you boot your system. diff --git a/contrib/libpcap/README.linux b/contrib/libpcap/README.linux new file mode 100644 index 0000000..ecd00e8 --- /dev/null +++ b/contrib/libpcap/README.linux @@ -0,0 +1,70 @@ +In order for libpcap to be able to capture packets on a Linux system, +the "packet" protocol must be supported by your kernel. If it is not, +you may get error messages such as + + modprobe: can't locate module net-pf-17 + +in "/var/adm/messages", or may get messages such as + + socket: Address family not supported by protocol + +from applications using libpcap. + +You must configure the kernel with the CONFIG_PACKET option for this +protocol; the following note is from the Linux "Configure.help" file for +the 2.0[.x] kernel: + + Packet socket + CONFIG_PACKET + The Packet protocol is used by applications which communicate + directly with network devices without an intermediate network + protocol implemented in the kernel, e.g. tcpdump. If you want them + to work, choose Y. + + This driver is also available as a module called af_packet.o ( = + code which can be inserted in and removed from the running kernel + whenever you want). If you want to compile it as a module, say M + here and read Documentation/modules.txt; if you use modprobe or + kmod, you may also want to add "alias net-pf-17 af_packet" to + /etc/modules.conf. + +and the note for the 2.2[.x] kernel says: + + Packet socket + CONFIG_PACKET + The Packet protocol is used by applications which communicate + directly with network devices without an intermediate network + protocol implemented in the kernel, e.g. tcpdump. If you want them + to work, choose Y. This driver is also available as a module called + af_packet.o ( = code which can be inserted in and removed from the + running kernel whenever you want). If you want to compile it as a + module, say M here and read Documentation/modules.txt. You will + need to add 'alias net-pf-17 af_packet' to your /etc/conf.modules + file for the module version to function automatically. If unsure, + say Y. + +In addition, there is an option that, in 2.2 and later kernels, will +allow packet capture filters specified to programs such as tcpdump to be +executed in the kernel, so that packets that don't pass the filter won't +be copied from the kernel to the program, rather than having all packets +copied to the program and libpcap doing the filtering in user mode. + +Copying packets from the kernel to the program consumes a significant +amount of CPU, so filtering in the kernel can reduce the overhead of +capturing packets if a filter has been specified that discards a +significant number of packets. (If no filter is specified, it makes no +difference whether the filtering isn't performed in the kernel or isn't +performed in user mode. :-)) + +The option for this is the CONFIG_FILTER option; the "Configure.help" +file says: + + Socket filtering + CONFIG_FILTER + The Linux Socket Filter is derived from the Berkeley Packet Filter. + If you say Y here, user-space programs can attach a filter to any + socket and thereby tell the kernel that it should allow or disallow + certain types of data to get through the socket. Linux Socket + Filtering works on all socket types except TCP for now. See the text + file linux/Documentation/networking/filter.txt for more information. + If unsure, say N. diff --git a/contrib/libpcap/TODO b/contrib/libpcap/TODO new file mode 100644 index 0000000..e90b9d8 --- /dev/null +++ b/contrib/libpcap/TODO @@ -0,0 +1,38 @@ + TODO list for libpcap +======================= + +Important stuff (to be done before the next release) +--------------- + +General + +- configure should not be in the CVS. Most open source projects have an + autogen.sh script to run autoconf etc. after checkout. I think we + should stick to the standard. + +- The source files should be better documented. There is no official + design guideline what is done where. There should be a common coding + style (okay, you can guess that bye looking at the code) and a guideline + what needs to be documented. + +Linux kernel interface + +- Currently there is a race condition in that a socket is activated at the + same time when it is opened - before applying a filter. This has to + be corrected so that capture starts when pcap_read is called for the + first time. + +Less urgent items +----------------- + +- Better documentation and cleanup of the interface. I am seeing a few + problems at the first glance which needs fixing: + + pcap_lookupnet makes little to no sense with protocols != IPv4 + + not very suited for interactive programs (think ethereal). There should + be a way for the application to get a file descriptor which it has to + monitor and a callback in pcap which has to be called on activity + + too many functions. There are a lot of functions for everything which + violates the KISS principle. Why do we need pcap_strerror, pcap_perror + and pcap_geterr? + + the manpage has a brief description of each function but where is the + big picture? Seems like you need to buy UNP for that... diff --git a/contrib/libpcap/VERSION b/contrib/libpcap/VERSION index 2eb3c4f..5a2a580 100644 --- a/contrib/libpcap/VERSION +++ b/contrib/libpcap/VERSION @@ -1 +1 @@ -0.5 +0.6 diff --git a/contrib/libpcap/aclocal.m4 b/contrib/libpcap/aclocal.m4 index ef3d05f..d729741 100644 --- a/contrib/libpcap/aclocal.m4 +++ b/contrib/libpcap/aclocal.m4 @@ -1,4 +1,4 @@ -dnl @(#) $Header: /tcpdump/master/libpcap/aclocal.m4,v 1.66 1999/10/30 04:41:48 itojun Exp $ (LBL) +dnl @(#) $Header: /tcpdump/master/libpcap/aclocal.m4,v 1.71 2000/09/19 03:56:26 guy Exp $ (LBL) dnl dnl Copyright (c) 1995, 1996, 1997, 1998 dnl The Regents of the University of California. All rights reserved. @@ -118,7 +118,7 @@ AC_DEFUN(AC_LBL_C_INIT, fi CFLAGS="$savedcflags" V_CCOPT="-Aa $V_CCOPT" - AC_DEFINE(_HPUX_SOURCE) + AC_DEFINE(_HPUX_SOURCE,1,[needed on HP-UX]) ;; *) @@ -246,14 +246,14 @@ AC_DEFUN(AC_LBL_TYPE_SIGNAL, [AC_BEFORE([$0], [AC_LBL_LIBPCAP]) AC_TYPE_SIGNAL if test "$ac_cv_type_signal" = void ; then - AC_DEFINE(RETSIGVAL,) + AC_DEFINE(RETSIGVAL,[],[return value of signal handlers]) else - AC_DEFINE(RETSIGVAL,(0)) + AC_DEFINE(RETSIGVAL,(0),[return value of signal handlers]) fi case "$target_os" in irix*) - AC_DEFINE(_BSD_SIGNALS) + AC_DEFINE(_BSD_SIGNALS,1,[get BSD semantics on Irix]) ;; *) @@ -384,9 +384,9 @@ AC_DEFUN(AC_LBL_UNION_WAIT, ac_cv_lbl_union_wait=yes)) AC_MSG_RESULT($ac_cv_lbl_union_wait) if test $ac_cv_lbl_union_wait = yes ; then - AC_DEFINE(DECLWAITSTATUS,union wait) + AC_DEFINE(DECLWAITSTATUS,union wait,[type for wait]) else - AC_DEFINE(DECLWAITSTATUS,int) + AC_DEFINE(DECLWAITSTATUS,int,[type for wait]) fi]) dnl @@ -411,7 +411,41 @@ AC_DEFUN(AC_LBL_SOCKADDR_SA_LEN, ac_cv_lbl_sockaddr_has_sa_len=no)) AC_MSG_RESULT($ac_cv_lbl_sockaddr_has_sa_len) if test $ac_cv_lbl_sockaddr_has_sa_len = yes ; then - AC_DEFINE(HAVE_SOCKADDR_SA_LEN) + AC_DEFINE(HAVE_SOCKADDR_SA_LEN,1,[if struct sockaddr has sa_len]) + fi]) + +dnl +dnl Checks to see if the dl_hp_ppa_info_t struct has the HP-UX 11.00 +dnl dl_module_id_1 member +dnl +dnl usage: +dnl +dnl AC_LBL_HP_PPA_INFO_T_DL_MODULE_ID_1 +dnl +dnl results: +dnl +dnl HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1 (defined) +dnl +dnl NOTE: any compile failure means we conclude that it doesn't have +dnl that member, so if we don't have DLPI, don't have a <sys/dlpi_ext.h> +dnl header, or have one that doesn't declare a dl_hp_ppa_info_t type, +dnl we conclude it doesn't have that member (which is OK, as either we +dnl won't be using code that would use that member, or we wouldn't +dnl compile in any case). +dnl +AC_DEFUN(AC_LBL_HP_PPA_INFO_T_DL_MODULE_ID_1, + [AC_MSG_CHECKING(if dl_hp_ppa_info_t struct has dl_module_id_1 member) + AC_CACHE_VAL(ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1, + AC_TRY_COMPILE([ +# include <sys/types.h> +# include <sys/dlpi.h> +# include <sys/dlpi_ext.h>], + [u_int i = sizeof(((dl_hp_ppa_info_t *)0)->dl_module_id_1)], + ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1=yes, + ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1=no)) + AC_MSG_RESULT($ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1) + if test $ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1 = yes ; then + AC_DEFINE(HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1,1,[if ppa_info_t_dl_module_id exists]) fi]) dnl @@ -466,7 +500,7 @@ AC_DEFUN(AC_LBL_CHECK_TYPE, ac_cv_lbl_have_$1=no)) AC_MSG_RESULT($ac_cv_lbl_have_$1) if test $ac_cv_lbl_have_$1 = no ; then - AC_DEFINE($1, $2) + AC_DEFINE($1, $2, [if we have $1]) fi]) dnl @@ -485,7 +519,8 @@ AC_DEFUN(AC_LBL_UNALIGNED_ACCESS, AC_CACHE_VAL(ac_cv_lbl_unaligned_fail, [case "$target_cpu" in - alpha|hp*|mips|sparc) + # XXX: should also check that they don't do weird things (like on arm) + alpha*|arm*|hp*|mips|sparc) ac_cv_lbl_unaligned_fail=yes ;; @@ -534,7 +569,7 @@ EOF esac]) AC_MSG_RESULT($ac_cv_lbl_unaligned_fail) if test $ac_cv_lbl_unaligned_fail = yes ; then - AC_DEFINE(LBL_ALIGN) + AC_DEFINE(LBL_ALIGN,1,[if unaligned access fails]) fi]) dnl @@ -584,7 +619,7 @@ AC_DEFUN(AC_LBL_DEVEL, name="lbl/os-$os.h" if test -f $name ; then ln -s $name os-proto.h - AC_DEFINE(HAVE_OS_PROTO_H) + AC_DEFINE(HAVE_OS_PROTO_H,1,[if there's an os_proto.h]) else AC_MSG_WARN(can't find $name) fi @@ -704,3 +739,31 @@ AC_DEFUN(AC_LBL_LIBRARY_NET, [ # DLPI needs putmsg under HPUX so test for -lstr while we're at it AC_CHECK_LIB(str, putmsg) ]) + +dnl +dnl Test for __attribute__ +dnl + +AC_DEFUN(AC_C___ATTRIBUTE__, [ +AC_MSG_CHECKING(for __attribute__) +AC_CACHE_VAL(ac_cv___attribute__, [ +AC_TRY_COMPILE([ +#include <stdlib.h> +], +[ +static void foo(void) __attribute__ ((noreturn)); + +static void +foo(void) +{ + exit(1); +} +], +ac_cv___attribute__=yes, +ac_cv___attribute__=no)]) +if test "$ac_cv___attribute__" = "yes"; then + AC_DEFINE(HAVE___ATTRIBUTE__, 1, [define if your compiler has __attribute__]) +fi +AC_MSG_RESULT($ac_cv___attribute__) +]) + diff --git a/contrib/libpcap/bpf/net/bpf.h b/contrib/libpcap/bpf/net/bpf.h index 8a997aa..26abc79 100644 --- a/contrib/libpcap/bpf/net/bpf.h +++ b/contrib/libpcap/bpf/net/bpf.h @@ -37,7 +37,7 @@ * * @(#)bpf.h 7.1 (Berkeley) 5/7/91 * - * @(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf.h,v 1.37 1999/10/19 15:18:31 itojun Exp $ (LBL) + * @(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf.h,v 1.44 2000/12/21 10:29:24 guy Exp $ (LBL) */ #ifndef BPF_MAJOR_VERSION @@ -154,13 +154,24 @@ struct bpf_hdr { * will insist on inserting padding; hence, sizeof(struct bpf_hdr) won't work. * Only the kernel needs to know about it; applications use bh_hdrlen. */ -#ifdef KERNEL +#if defined(KERNEL) || defined(_KERNEL) #define SIZEOF_BPF_HDR 18 #endif /* * Data-link level type codes. */ + +/* + * These are the types that are the same on all platforms; on other + * platforms, a <net/bpf.h> should be supplied that defines the additional + * DLT_* codes appropriately for that platform (the BSDs, for example, + * should not just pick up this version of "bpf.h"; they should also define + * the additional DLT_* codes used by their kernels, as well as the values + * defined here - and, if the values they use for particular DLT_ types + * differ from those here, they should use their values, not the ones + * here). + */ #define DLT_NULL 0 /* no link-layer encapsulation */ #define DLT_EN10MB 1 /* Ethernet (10Mb) */ #define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ @@ -172,24 +183,100 @@ struct bpf_hdr { #define DLT_SLIP 8 /* Serial Line IP */ #define DLT_PPP 9 /* Point-to-point Protocol */ #define DLT_FDDI 10 /* FDDI */ -#ifdef __FreeBSD__ -#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */ -#endif -#ifdef __OpenBSD__ + +/* + * These are values from the traditional libpcap "bpf.h". + * Ports of this to particular platforms should replace these definitions + * with the ones appropriate to that platform, if the values are + * different on that platform. + */ #define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */ -#define DLT_LOOP 12 /* loopback */ -#endif -/* offset to avoid collision with BSD/OS values */ -#ifndef DLT_ATM_RFC1483 -#define DLT_ATM_RFC1483 100 /* LLC/SNAP encapsulated atm */ -#endif -#define DLT_RAW 101 /* raw IP */ -#define DLT_SLIP_BSDOS 102 /* BSD/OS Serial Line IP */ -#define DLT_PPP_BSDOS 103 /* BSD/OS Point-to-point Protocol */ -#define DLT_CHDLC 104 /* Cisco HDLC */ +#define DLT_RAW 12 /* raw IP */ + +/* + * These are values from BSD/OS's "bpf.h". + * These are not the same as the values from the traditional libpcap + * "bpf.h"; however, these values shouldn't be generated by any + * OS other than BSD/OS, so the correct values to use here are the + * BSD/OS values. + * + * Platforms that have already assigned these values to other + * DLT_ codes, however, should give these codes the values + * from that platform, so that programs that use these codes will + * continue to compile - even though they won't correctly read + * files of these types. + */ +#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ +#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ + +#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ + +/* + * This value is defined by NetBSD; other platforms should refrain from + * using it for other purposes, so that NetBSD savefiles with a link + * type of 50 can be read as this type on all platforms. + */ +#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ + +/* + * This value was defined by libpcap 0.5; platforms that have defined + * it with a different value should define it here with that value - + * a link type of 104 in a save file will be mapped to DLT_C_HDLC, + * whatever value that happens to be, so programs will correctly + * handle files with that link type regardless of the value of + * DLT_C_HDLC. + * + * The name DLT_C_HDLC was used by BSD/OS; we use that name for source + * compatibility with programs written for BSD/OS. + * + * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well, + * for source compatibility with programs written for libpcap 0.5. + */ +#define DLT_C_HDLC 104 /* Cisco HDLC */ +#define DLT_CHDLC DLT_C_HDLC + +/* + * Reserved for future use. + * Do not pick other numerical value for these unless you have also + * picked up the tcpdump.org top-of-CVS-tree version of "savefile.c", + * which will arrange that capture files for these DLT_ types have + * the same "network" value on all platforms, regardless of what + * value is chosen for their DLT_ type (thus allowing captures made + * on one platform to be read on other platforms, even if the two + * platforms don't use the same numerical values for all DLT_ types). + */ +#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ + +/* + * Values between 106 and 107 are used in capture file headers as + * link-layer types corresponding to DLT_ types that might differ + * between platforms; don't use those values for new DLT_ new types. + */ + +/* + * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except + * that the AF_ type in the link-layer header is in network byte order. + * + * OpenBSD defines it as 12, but that collides with DLT_RAW, so we + * define it as 108 here. If OpenBSD picks up this file, it should + * define DLT_LOOP as 12 in its version, as per the comment above - + * and should not use 108 for any purpose. + */ +#define DLT_LOOP 108 + +/* + * Values between 109 and 112 are used in capture file headers as + * link-layer types corresponding to DLT_ types that might differ + * between platforms; don't use those values for new DLT_ new types. + */ /* - * The instruction encondings. + * This is for Linux cooked sockets. + */ +#define DLT_LINUX_SLL 113 + +/* + * The instruction encodings. */ /* instruction classes */ #define BPF_CLASS(code) ((code) & 0x07) @@ -260,15 +347,29 @@ struct bpf_insn { #define BPF_STMT(code, k) { (u_short)(code), 0, 0, k } #define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k } -#ifdef KERNEL -extern u_int bpf_filter(); -extern void bpfattach(); +#if defined(BSD) && (defined(KERNEL) || defined(_KERNEL)) +/* + * Systems based on non-BSD kernels don't have ifnet's (or they don't mean + * anything if it is in <net/if.h>) and won't work like this. + */ +# if __STDC__ +extern void bpf_tap(struct ifnet *, u_char *, u_int); +extern void bpf_mtap(struct ifnet *, struct mbuf *); +extern void bpfattach(struct ifnet *, u_int, u_int); +extern void bpfilterattach(int); +# else extern void bpf_tap(); extern void bpf_mtap(); -#else +extern void bpfattach(); +extern void bpfilterattach(); +# endif /* __STDC__ */ +#endif /* BSD && (_KERNEL || KERNEL) */ #if __STDC__ +extern int bpf_validate(struct bpf_insn *, int); extern u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int); -#endif +#else +extern int bpf_validate(); +extern u_int bpf_filter(); #endif /* diff --git a/contrib/libpcap/bpf/net/bpf_filter.c b/contrib/libpcap/bpf/net/bpf_filter.c index f274542..d47503f 100644 --- a/contrib/libpcap/bpf/net/bpf_filter.c +++ b/contrib/libpcap/bpf/net/bpf_filter.c @@ -38,17 +38,30 @@ * @(#)bpf.c 7.5 (Berkeley) 7/15/91 */ -#if !(defined(lint) || defined(KERNEL)) +#if !(defined(lint) || defined(KERNEL) || defined(_KERNEL)) static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf_filter.c,v 1.33.1.1 1999/10/07 23:46:41 mcr Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf_filter.c,v 1.35 2000/10/23 19:32:21 fenner Exp $ (LBL)"; #endif #include <sys/param.h> #include <sys/types.h> #include <sys/time.h> + +#define SOLARIS (defined(sun) && (defined(__SVR4) || defined(__svr4__))) +#if defined(__hpux) || SOLARIS +# include <sys/sysmacros.h> +# include <sys/stream.h> +# define mbuf msgb +# define m_next b_cont +# define MLEN(m) ((m)->b_wptr - (m)->b_rptr) +# define mtod(m,t) ((t)(m)->b_rptr) +#else +# define MLEN(m) ((m)->m_len) +#endif + #include <net/bpf.h> -#ifndef KERNEL +#if !defined(KERNEL) && !defined(_KERNEL) #include <stdlib.h> #endif @@ -79,17 +92,19 @@ static const char rcsid[] = (u_int32)*((u_char *)p+3)<<0) #endif -#ifdef KERNEL +#if defined(KERNEL) || defined(_KERNEL) +# if !defined(__hpux) && !SOLARIS #include <sys/mbuf.h> -#define MINDEX(len, m, k) \ +# endif +#define MINDEX(len, _m, _k) \ { \ - len = m->m_len; \ - while (k >= len) { \ - k -= len; \ - m = m->m_next; \ - if (m == 0) \ + len = MLEN(m); \ + while ((_k) >= len) { \ + (_k) -= len; \ + (_m) = (_m)->m_next; \ + if ((_m) == 0) \ return 0; \ - len = m->m_len; \ + len = MLEN(m); \ } \ } @@ -109,7 +124,7 @@ m_xword(m, k, err) return EXTRACT_LONG(cp); } m0 = m->m_next; - if (m0 == 0 || m0->m_len + len - k < 4) + if (m0 == 0 || MLEN(m0) + len - k < 4) goto bad; *err = 0; np = mtod(m0, u_char *); @@ -159,6 +174,8 @@ m_xhalf(m, k, err) * Execute the filter program starting at pc on the packet p * wirelen is the length of the original packet * buflen is the amount of data present + * For the kernel, p is assumed to be a pointer to an mbuf if buflen is 0, + * in all other cases, p is a pointer to a buffer and buflen is its size. */ u_int bpf_filter(pc, p, wirelen, buflen) @@ -170,6 +187,17 @@ bpf_filter(pc, p, wirelen, buflen) register u_int32 A, X; register int k; int32 mem[BPF_MEMWORDS]; +#if defined(KERNEL) || defined(_KERNEL) + struct mbuf *m, *n; + int merr, len; + + if (buflen == 0) { + m = (struct mbuf *)p; + p = mtod(m, u_char *); + buflen = MLEN(m); + } else + m = NULL; +#endif if (pc == 0) /* @@ -184,7 +212,7 @@ bpf_filter(pc, p, wirelen, buflen) switch (pc->code) { default: -#ifdef KERNEL +#if defined(KERNEL) || defined(_KERNEL) return 0; #else abort(); @@ -198,12 +226,10 @@ bpf_filter(pc, p, wirelen, buflen) case BPF_LD|BPF_W|BPF_ABS: k = pc->k; if (k + sizeof(int32) > buflen) { -#ifdef KERNEL - int merr; - - if (buflen != 0) +#if defined(KERNEL) || defined(_KERNEL) + if (m == NULL) return 0; - A = m_xword((struct mbuf *)p, k, &merr); + A = m_xword(m, k, &merr); if (merr != 0) return 0; continue; @@ -217,12 +243,12 @@ bpf_filter(pc, p, wirelen, buflen) case BPF_LD|BPF_H|BPF_ABS: k = pc->k; if (k + sizeof(short) > buflen) { -#ifdef KERNEL - int merr; - - if (buflen != 0) +#if defined(KERNEL) || defined(_KERNEL) + if (m == NULL) + return 0; + A = m_xhalf(m, k, &merr); + if (merr != 0) return 0; - A = m_xhalf((struct mbuf *)p, k, &merr); continue; #else return 0; @@ -234,15 +260,12 @@ bpf_filter(pc, p, wirelen, buflen) case BPF_LD|BPF_B|BPF_ABS: k = pc->k; if (k >= buflen) { -#ifdef KERNEL - register struct mbuf *m; - register int len; - - if (buflen != 0) +#if defined(KERNEL) || defined(_KERNEL) + if (m == NULL) return 0; - m = (struct mbuf *)p; - MINDEX(len, m, k); - A = mtod(m, u_char *)[k]; + n = m; + MINDEX(len, n, k); + A = mtod(n, u_char *)[k]; continue; #else return 0; @@ -262,12 +285,10 @@ bpf_filter(pc, p, wirelen, buflen) case BPF_LD|BPF_W|BPF_IND: k = X + pc->k; if (k + sizeof(int32) > buflen) { -#ifdef KERNEL - int merr; - - if (buflen != 0) +#if defined(KERNEL) || defined(_KERNEL) + if (m == NULL) return 0; - A = m_xword((struct mbuf *)p, k, &merr); + A = m_xword(m, k, &merr); if (merr != 0) return 0; continue; @@ -281,12 +302,10 @@ bpf_filter(pc, p, wirelen, buflen) case BPF_LD|BPF_H|BPF_IND: k = X + pc->k; if (k + sizeof(short) > buflen) { -#ifdef KERNEL - int merr; - - if (buflen != 0) +#if defined(KERNEL) || defined(_KERNEL) + if (m == NULL) return 0; - A = m_xhalf((struct mbuf *)p, k, &merr); + A = m_xhalf(m, k, &merr); if (merr != 0) return 0; continue; @@ -300,15 +319,12 @@ bpf_filter(pc, p, wirelen, buflen) case BPF_LD|BPF_B|BPF_IND: k = X + pc->k; if (k >= buflen) { -#ifdef KERNEL - register struct mbuf *m; - register int len; - - if (buflen != 0) +#if defined(KERNEL) || defined(_KERNEL) + if (m == NULL) return 0; - m = (struct mbuf *)p; - MINDEX(len, m, k); - A = mtod(m, u_char *)[k]; + n = m; + MINDEX(len, n, k); + A = mtod(n, u_char *)[k]; continue; #else return 0; @@ -320,15 +336,12 @@ bpf_filter(pc, p, wirelen, buflen) case BPF_LDX|BPF_MSH|BPF_B: k = pc->k; if (k >= buflen) { -#ifdef KERNEL - register struct mbuf *m; - register int len; - - if (buflen != 0) +#if defined(KERNEL) || defined(_KERNEL) + if (m == NULL) return 0; - m = (struct mbuf *)p; - MINDEX(len, m, k); - X = (mtod(m, char *)[k] & 0xf) << 2; + n = m; + MINDEX(len, n, k); + X = (mtod(n, char *)[k] & 0xf) << 2; continue; #else return 0; @@ -478,7 +491,7 @@ bpf_filter(pc, p, wirelen, buflen) } } -#ifdef KERNEL + /* * Return true if the 'fcode' is a valid filter program. * The constraints are that each jump be forward and to a valid @@ -529,4 +542,3 @@ bpf_validate(f, len) } return BPF_CLASS(f[len - 1].code) == BPF_RET; } -#endif diff --git a/contrib/libpcap/bpf_dump.c b/contrib/libpcap/bpf_dump.c new file mode 100644 index 0000000..85e1c97 --- /dev/null +++ b/contrib/libpcap/bpf_dump.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 1992, 1993, 1994, 1995, 1996 + * 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 rcsid[] = + "@(#) $Header: /tcpdump/master/libpcap/bpf_dump.c,v 1.12 2000/06/26 04:17:05 assar Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <sys/time.h> + +#include <pcap.h> +#include <stdio.h> + +void +bpf_dump(struct bpf_program *p, int option) +{ + struct bpf_insn *insn; + int i; + int n = p->bf_len; + + insn = p->bf_insns; + if (option > 2) { + printf("%d\n", n); + for (i = 0; i < n; ++insn, ++i) { + printf("%u %u %u %u\n", insn->code, + insn->jt, insn->jf, insn->k); + } + return ; + } + if (option > 1) { + for (i = 0; i < n; ++insn, ++i) + printf("{ 0x%x, %d, %d, 0x%08x },\n", + insn->code, insn->jt, insn->jf, insn->k); + return; + } + for (i = 0; i < n; ++insn, ++i) { +#ifdef BDEBUG + extern int bids[]; + printf(bids[i] > 0 ? "[%02d]" : " -- ", bids[i] - 1); +#endif + puts(bpf_image(insn, i)); + } +} diff --git a/contrib/libpcap/bpf_image.c b/contrib/libpcap/bpf_image.c index 1cee698..1e178bf 100644 --- a/contrib/libpcap/bpf_image.c +++ b/contrib/libpcap/bpf_image.c @@ -21,7 +21,11 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/bpf_image.c,v 1.22.1.1 1999/10/07 23:46:40 mcr Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/bpf_image.c,v 1.24 2000/07/11 00:37:04 assar Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" #endif #include <sys/types.h> @@ -32,7 +36,6 @@ static const char rcsid[] = #include "pcap-int.h" -#include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif @@ -277,8 +280,8 @@ bpf_image(p, n) fmt = ""; break; } - (void)sprintf(operand, fmt, v); - (void)sprintf(image, + (void)snprintf(operand, sizeof operand, fmt, v); + (void)snprintf(image, sizeof image, (BPF_CLASS(p->code) == BPF_JMP && BPF_OP(p->code) != BPF_JA) ? "(%03d) %-8s %-16s jt %d\tjf %d" diff --git a/contrib/libpcap/config.guess b/contrib/libpcap/config.guess index e9e4455..980ea5b 100755 --- a/contrib/libpcap/config.guess +++ b/contrib/libpcap/config.guess @@ -1,7 +1,10 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc. -# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 +# Free Software Foundation, Inc. + +timestamp='2000-12-15' + # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or @@ -22,19 +25,97 @@ # the same distribution terms that you use for the rest of that program. # Written by Per Bothner <bothner@cygnus.com>. -# The master version of this file is at the FSF in /home/gd/gnu/lib. +# Please send patches to <config-patches@gnu.org>. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you -# don't specify an explicit system type (host/target name). +# don't specify an explicit build system type. # # Only a few systems have been added to this list; please add others # (but try to keep the structure clean). # +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <config-patches@gnu.org>." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 99, 2000 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + + +dummy=dummy-$$ +trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int dummy(){}" > $dummy.c + for c in cc gcc c89 ; do + ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 + if test $? = 0 ; then + CC_FOR_BUILD="$c"; break + fi + done + rm -f $dummy.c $dummy.o + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac + # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 8/24/94.) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then @@ -43,37 +124,162 @@ fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown -trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15 - # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # Netbsd (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # Determine the machine/vendor (is the vendor relevant). + case "${UNAME_MACHINE}" in + amiga) machine=m68k-unknown ;; + arm32) machine=arm-unknown ;; + atari*) machine=m68k-atari ;; + sun3*) machine=m68k-sun ;; + mac68k) machine=m68k-apple ;; + macppc) machine=powerpc-apple ;; + hp3[0-9][05]) machine=m68k-hp ;; + ibmrt|romp-ibm) machine=romp-ibm ;; + *) machine=${UNAME_MACHINE}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE}" in + i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k) + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//'` + cat <<EOF >$dummy.s + .data +\$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main +main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + esac + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix exit 0 ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit 0 ;; Amiga*:UNIX_System_V:4.0:*) - echo m68k-cbm-sysv4 + echo m68k-unknown-sysv4 exit 0;; - amiga:NetBSD:*:*) - echo m68k-cbm-netbsd${UNAME_RELEASE} - exit 0 ;; amiga:OpenBSD:*:*) - echo m68k-cbm-openbsd${UNAME_RELEASE} - exit 0 ;; + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + arc64:OpenBSD:*:*) + echo mips64el-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hkmips:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit 0;; - Pyramid*:OSx*:*:*|MIS*:OSx*:*:*) + SR2?01:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 @@ -81,9 +287,12 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in echo pyramid-pyramid-bsd fi exit 0 ;; - NILE:*:*:dcosx) + NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit 0 ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; @@ -108,26 +317,61 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit 0 ;; - atari*:NetBSD:*:*) - echo m68k-atari-netbsd${UNAME_RELEASE} - exit 0 ;; atari*:OpenBSD:*:*) - echo m68k-atari-openbsd${UNAME_RELEASE} - exit 0 ;; - sun3*:NetBSD:*:*) - echo m68k-sun-netbsd${UNAME_RELEASE} + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; sun3*:OpenBSD:*:*) - echo m68k-sun-openbsd${UNAME_RELEASE} - exit 0 ;; - mac68k:NetBSD:*:*) - echo m68k-apple-netbsd${UNAME_RELEASE} + echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mac68k:OpenBSD:*:*) - echo m68k-apple-openbsd${UNAME_RELEASE} + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} @@ -141,9 +385,17 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; mips:*:*:UMIPS | mips:*:*:RISCos) - sed 's/^ //' << EOF >dummy.c - int main (argc, argv) int argc; char **argv; { + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include <stdio.h> /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); @@ -158,10 +410,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in exit (-1); } EOF - ${CC-cc} dummy.c -o dummy \ - && ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ - && rm dummy.c dummy && exit 0 - rm -f dummy.c dummy + $CC_FOR_BUILD $dummy.c -o $dummy \ + && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy echo mips-mips-riscos${UNAME_RELEASE} exit 0 ;; Night_Hawk:Power_UNIX:*:*) @@ -179,15 +431,18 @@ EOF AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \ - -o ${TARGET_BINARY_INTERFACE}x = x ] ; then + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then echo m88k-dg-dgux${UNAME_RELEASE} - else + else echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} fi - else echo i586-dg-dgux${UNAME_RELEASE} - fi exit 0 ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 @@ -213,7 +468,7 @@ EOF exit 0 ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - sed 's/^ //' << EOF >dummy.c + sed 's/^ //' << EOF >$dummy.c #include <sys/systemcfg.h> main() @@ -224,8 +479,8 @@ EOF exit(0); } EOF - ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 - rm -f dummy.c dummy + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy echo rs6000-ibm-aix3.2.5 elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 @@ -234,7 +489,8 @@ EOF fi exit 0 ;; *:AIX:*:4) - if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'` + if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc @@ -246,13 +502,26 @@ EOF fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit 0 ;; + *:AIX:*:5) + case "`lsattr -El proc0 -a type -F value`" in + PowerPC*) IBM_ARCH=powerpc + IBM_MANUF=ibm ;; + Itanium) IBM_ARCH=ia64 + IBM_MANUF=unknown ;; + POWER*) IBM_ARCH=power + IBM_MANUF=ibm ;; + *) IBM_ARCH=powerpc + IBM_MANUF=ibm ;; + esac + echo ${IBM_ARCH}-${IBM_MANUF}-aix${UNAME_VERSION}.${UNAME_RELEASE} + exit 0 ;; *:AIX:*:*) echo rs6000-ibm-aix exit 0 ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit 0 ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit 0 ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) @@ -267,18 +536,71 @@ EOF hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit 0 ;; - 9000/[3478]??:HP-UX:*:*) + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1 ;; - 9000/8?? ) HP_ARCH=hppa1.0 ;; + 9000/[678][0-9][0-9]) + case "${HPUX_REV}" in + 11.[0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + esac ;; + esac + fi ;; + esac + if [ "${HP_ARCH}" = "" ]; then + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include <stdlib.h> + #include <unistd.h> + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy` + if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi + rm -f $dummy.c $dummy + fi ;; esac - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit 0 ;; 3050*:HI-UX:*:*) - sed 's/^ //' << EOF >dummy.c + sed 's/^ //' << EOF >$dummy.c #include <unistd.h> int main () @@ -303,8 +625,8 @@ EOF exit (0); } EOF - ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 - rm -f dummy.c dummy + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy echo unknown-hitachi-hiuxwe2 exit 0 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) @@ -313,6 +635,9 @@ EOF 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit 0 ;; + *9??*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit 0 ;; @@ -329,6 +654,9 @@ EOF parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit 0 ;; + hppa*:OpenBSD:*:*) + echo hppa-unknown-openbsd + exit 0 ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit 0 ;; @@ -359,101 +687,334 @@ EOF -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ exit 0 ;; CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3D:*:*:*) + echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY-2:*:*:*) echo cray2-cray-unicos exit 0 ;; F300:UNIX_System_V:*:*) - FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit 0 ;; F301:UNIX_System_V:*:*) echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'` exit 0 ;; - hp3[0-9][05]:NetBSD:*:*) - echo m68k-hp-netbsd${UNAME_RELEASE} - exit 0 ;; - hp3[0-9][05]:OpenBSD:*:*) - echo m68k-hp-openbsd${UNAME_RELEASE} + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; - i?86:BSD/386:*:* | *:BSD/OS:*:*) + i?86:BSD/386:*:* | i?86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; *:FreeBSD:*:*) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit 0 ;; - *:NetBSD:*:*) - echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - exit 0 ;; *:OpenBSD:*:*) echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` exit 0 ;; i*:CYGWIN*:*) - echo i386-pc-cygwin32 + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin exit 0 ;; p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin32 + echo powerpcle-unknown-cygwin exit 0 ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; *:GNU:*:*) - echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix exit 0 ;; *:Linux:*:*) + # The BFD linker knows what the default object file format is, so - # first see if it will tell us. - ld_help_string=`ld --help 2>&1` - if echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf_i.86"; then - echo "${UNAME_MACHINE}-pc-linux-gnu" ; exit 0 - elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i.86linux"; then - echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 - elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i.86coff"; then - echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 - elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68kelf"; then - echo "${UNAME_MACHINE}-unknown-linux-gnu" ; exit 0 - elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68klinux"; then - echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 - elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf32ppc"; then - echo "powerpc-unknown-linux-gnu" ; exit 0 - elif test "${UNAME_MACHINE}" = "alpha" ; then - echo alpha-unknown-linux-gnu ; exit 0 - elif test "${UNAME_MACHINE}" = "sparc" ; then - echo sparc-unknown-linux-gnu ; exit 0 + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + ld_supported_emulations=`cd /; ld --help 2>&1 \ + | sed -ne '/supported emulations:/!d + s/[ ][ ]*/ /g + s/.*supported emulations: *// + s/ .*// + p'` + case "$ld_supported_emulations" in + *ia64) + echo "${UNAME_MACHINE}-unknown-linux" + exit 0 + ;; + i?86linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 + ;; + elf_i?86) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + i?86coff) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 + ;; + sparclinux) + echo "${UNAME_MACHINE}-unknown-linux-gnuaout" + exit 0 + ;; + elf32_sparc) + echo "${UNAME_MACHINE}-unknown-linux-gnu" + exit 0 + ;; + armlinux) + echo "${UNAME_MACHINE}-unknown-linux-gnuaout" + exit 0 + ;; + elf32arm*) + echo "${UNAME_MACHINE}-unknown-linux-gnuoldld" + exit 0 + ;; + armelf_linux*) + echo "${UNAME_MACHINE}-unknown-linux-gnu" + exit 0 + ;; + m68klinux) + echo "${UNAME_MACHINE}-unknown-linux-gnuaout" + exit 0 + ;; + elf32ppc | elf32ppclinux) + # Determine Lib Version + cat >$dummy.c <<EOF +#include <features.h> +#if defined(__GLIBC__) +extern char __libc_version[]; +extern char __libc_release[]; +#endif +main(argc, argv) + int argc; + char *argv[]; +{ +#if defined(__GLIBC__) + printf("%s %s\n", __libc_version, __libc_release); +#else + printf("unkown\n"); +#endif + return 0; +} +EOF + LIBC="" + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null + if test "$?" = 0 ; then + ./$dummy | grep 1\.99 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f $dummy.c $dummy + echo powerpc-unknown-linux-gnu${LIBC} + exit 0 + ;; + shelf_linux) + echo "${UNAME_MACHINE}-unknown-linux-gnu" + exit 0 + ;; + esac + + if test "${UNAME_MACHINE}" = "alpha" ; then + cat <<EOF >$dummy.s + .data + \$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main + main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + LIBC="" + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + esac + + objdump --private-headers $dummy | \ + grep ld.so.1 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0 + elif test "${UNAME_MACHINE}" = "mips" ; then + cat >$dummy.c <<EOF +#ifdef __cplusplus +#include <stdio.h> /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif +#ifdef __MIPSEB__ + printf ("%s-unknown-linux-gnu\n", argv[1]); +#endif +#ifdef __MIPSEL__ + printf ("%sel-unknown-linux-gnu\n", argv[1]); +#endif + return 0; +} +EOF + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + elif test "${UNAME_MACHINE}" = "s390"; then + echo s390-ibm-linux && exit 0 + elif test "${UNAME_MACHINE}" = "x86_64"; then + echo x86_64-unknown-linux-gnu && exit 0 + elif test "${UNAME_MACHINE}" = "parisc" -o "${UNAME_MACHINE}" = "hppa"; then + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) + echo hppa1.1-unknown-linux-gnu + ;; + PA8*) + echo hppa2.0-unknown-linux-gnu + ;; + *) + echo hppa-unknown-linux-gnu + ;; + esac + exit 0 else - # Either a pre-BFD a.out linker (linux-gnuoldld) or one that does not give us - # useful --help. Gcc wants to distinguish between linux-gnuoldld and linux-gnuaout. - test ! -d /usr/lib/ldscripts/. \ + # Either a pre-BFD a.out linker (linux-gnuoldld) + # or one that does not give us useful --help. + # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. + # If ld does not provide *any* "supported emulations:" + # that means it is gnuoldld. + test -z "$ld_supported_emulations" \ && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 + + case "${UNAME_MACHINE}" in + i?86) + VENDOR=pc; + ;; + *) + VENDOR=unknown; + ;; + esac # Determine whether the default compiler is a.out or elf - cat >dummy.c <<EOF -main(argc, argv) -int argc; -char *argv[]; -{ + cat >$dummy.c <<EOF +#include <features.h> +#ifdef __cplusplus +#include <stdio.h> /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif #ifdef __ELF__ - printf ("%s-pc-linux-gnu\n", argv[1]); +# ifdef __GLIBC__ +# if __GLIBC__ >= 2 + printf ("%s-${VENDOR}-linux-gnu\n", argv[1]); +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif #else - printf ("%s-pc-linux-gnuaout\n", argv[1]); + printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]); #endif return 0; } EOF - ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0 - rm -f dummy.c dummy + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 fi ;; # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions # are messed up and put the nodename in both sysname and nodename. i?86:DYNIX/ptx:4*:*) echo i386-sequent-sysv4 exit 0 ;; + i?86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i?86:*:5:7*) + # Fixed at (any) Pentium or better + UNAME_MACHINE=i586 + if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then + echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} fi exit 0 ;; i?86:*:3.2:*) @@ -465,11 +1026,24 @@ EOF (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 + (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit 0 ;; + i?86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit 0 ;; @@ -489,7 +1063,7 @@ EOF exit 0 ;; M68*:*:R3V[567]*:*) test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; - 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` @@ -506,7 +1080,7 @@ EOF mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit 0 ;; - i?86:LynxOS:2.*:*) + i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit 0 ;; TSUNAMI:LynxOS:2.*:*) @@ -518,6 +1092,9 @@ EOF SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; @@ -529,6 +1106,10 @@ EOF echo ns32k-sni-sysv fi exit 0 ;; + PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says <Richard.M.Bartel@ccMail.Census.GOV> + echo i586-unisys-sysv4 + exit 0 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes <hewes@openmarket.com>. # How about differentiating between stratus architectures? -djm @@ -541,23 +1122,83 @@ EOF mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit 0 ;; - R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*) + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit 0 ;; - PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says <Richard.M.Bartel@ccMail.Census.GOV> - echo i586-unisys-sysv4 - exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + echo `uname -p`-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + if test "${UNAME_MACHINE}" = "x86pc"; then + UNAME_MACHINE=pc + fi + echo `uname -p`-${UNAME_MACHINE}-nto-qnx + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[KW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + i?86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 -cat >dummy.c <<EOF +cat >$dummy.c <<EOF #ifdef _SEQUENT_ # include <sys/types.h> # include <sys/utsname.h> @@ -595,7 +1236,10 @@ main () #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif @@ -655,8 +1299,8 @@ main () } EOF -${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0 -rm -f dummy.c dummy +$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0 +rm -f $dummy.c $dummy # Apollos put the system type in the environment. @@ -688,6 +1332,47 @@ then esac fi -#echo '(Unable to guess system type)' 1>&2 +cat >&2 <<EOF +$0: unable to guess system type + +The $version version of this script cannot recognize your system type. +Please download the most up to date version of the config scripts: + + ftp://ftp.gnu.org/pub/gnu/config/ + +If the version you run ($0) is already up to date, please +send the following data and any information you think might be +pertinent to <config-patches@gnu.org> in order to provide the needed +information to handle your system. + +config.guess version = $version + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/contrib/libpcap/config.h.in b/contrib/libpcap/config.h.in new file mode 100644 index 0000000..f012a9d --- /dev/null +++ b/contrib/libpcap/config.h.in @@ -0,0 +1,95 @@ +/* config.h.in. Generated automatically from configure.in by autoheader. */ + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define as __inline if that's what the C compiler calls it. */ +#undef inline + +/* Define if you have the ether_hostton function. */ +#undef HAVE_ETHER_HOSTTON + +/* Define if you have the freeifaddrs function. */ +#undef HAVE_FREEIFADDRS + +/* Define if you have the strerror function. */ +#undef HAVE_STRERROR + +/* Define if you have the strlcpy function. */ +#undef HAVE_STRLCPY + +/* Define if you have the <ifaddrs.h> header file. */ +#undef HAVE_IFADDRS_H + +/* Define if you have the <netinet/if_ether.h> header file. */ +#undef HAVE_NETINET_IF_ETHER_H + +/* Define if you have the <netpacket/packet.h> header file. */ +#undef HAVE_NETPACKET_PACKET_H + +/* Define if you have the <sys/bufmod.h> header file. */ +#undef HAVE_SYS_BUFMOD_H + +/* Define if you have the <sys/dlpi_ext.h> header file. */ +#undef HAVE_SYS_DLPI_EXT_H + +/* Define if you have the <sys/ioccom.h> header file. */ +#undef HAVE_SYS_IOCCOM_H + +/* Define if you have the <sys/sockio.h> header file. */ +#undef HAVE_SYS_SOCKIO_H + +/* needed on HP-UX */ +#undef _HPUX_SOURCE + +/* define if your compiler has __attribute__ */ +#undef HAVE___ATTRIBUTE__ + +/* if we have u_int8_t */ +#undef u_int8_t + +/* if we have u_int16_t */ +#undef u_int16_t + +/* if we have u_int32_t */ +#undef u_int32_t + +/* do not use protochain */ +#undef NO_PROTOCHAIN + +/* IPv6 */ +#undef INET6 + +/* define if you have a /dev/dlpi */ +#undef HAVE_DEV_DLPI + +/* /dev/dlpi directory */ +#undef PCAP_DEV_PREFIX + +/* define on AIX to get certain functions */ +#undef _SUN + +/* on HP-UX 9.x */ +#undef HAVE_HPUX9 + +/* on HP-UX 10.20 */ +#undef HAVE_HPUX10_20 + +/* on sinix */ +#undef sinix + +/* On solaris */ +#undef HAVE_SOLARIS + +/* if there's an os_proto.h */ +#undef HAVE_OS_PROTO_H + +/* if struct sockaddr has sa_len */ +#undef HAVE_SOCKADDR_SA_LEN + +/* if ppa_info_t_dl_module_id exists */ +#undef HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1 + +/* if unaligned access fails */ +#undef LBL_ALIGN + diff --git a/contrib/libpcap/config.sub b/contrib/libpcap/config.sub index 0432524..4849dfd 100755 --- a/contrib/libpcap/config.sub +++ b/contrib/libpcap/config.sub @@ -1,6 +1,10 @@ #! /bin/sh -# Configuration validation subroutine script, version 1.1. -# Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 +# Free Software Foundation, Inc. + +timestamp='2000-12-15' + # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. @@ -25,6 +29,8 @@ # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. +# Please send patches to <config-patches@gnu.org>. +# # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. @@ -45,30 +51,73 @@ # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. -if [ x$1 = x ] -then - echo Configuration name missing. 1>&2 - echo "Usage: $0 CPU-MFR-OPSYS" 1>&2 - echo "or $0 ALIAS" 1>&2 - echo where ALIAS is a recognized configuration type. 1>&2 - exit 1 -fi +me=`echo "$0" | sed -e 's,.*/,,'` -# First pass through any local machine types. -case $1 in - *local*) - echo $1 - exit 0 - ;; - *) - ;; +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <config-patches@gnu.org>." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 99, 2000 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in - linux-gnu*) + nto-qnx* | linux-gnu* | storm-chaos*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; @@ -94,15 +143,25 @@ case $os in -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple) + -apple | -axis) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; -hiux*) os=-hiuxwe2 ;; -sco5) - os=sco3.2v5 + os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) @@ -121,6 +180,9 @@ case $os in os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` @@ -143,25 +205,47 @@ case $os in -psos*) os=-psos ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. - tahoe | i860 | m68k | m68000 | m88k | ns32k | arm \ - | arme[lb] | pyramid \ - | tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \ - | alpha | we32k | ns16k | clipper | i370 | sh \ - | powerpc | powerpcle | 1750a | dsp16xx | mips64 | mipsel \ - | pdp11 | mips64el | mips64orion | mips64orionel \ - | sparc | sparclet | sparclite | sparc64) + tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc \ + | arm | arme[lb] | arm[bl]e | armv[2345] | armv[345][lb] | strongarm | xscale \ + | pyramid | mn10200 | mn10300 | tron | a29k \ + | 580 | i960 | h8300 \ + | x86 | ppcbe | mipsbe | mipsle | shbe | shle \ + | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \ + | hppa64 \ + | alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \ + | alphaev6[78] \ + | we32k | ns16k | clipper | i370 | sh | sh[34] \ + | powerpc | powerpcle \ + | 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \ + | mips64orion | mips64orionel | mipstx39 | mipstx39el \ + | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \ + | mips64vr5000 | miprs64vr5000el | mcore \ + | sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \ + | thumb | d10v | d30v | fr30 | avr) basic_machine=$basic_machine-unknown ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65 | pj | pjl) + ;; + # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. - i[3456]86) + i[234567]86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. @@ -170,23 +254,50 @@ case $basic_machine in exit 1 ;; # Recognize the basic CPU types with company name. - vax-* | tahoe-* | i[3456]86-* | i860-* | m68k-* | m68000-* | m88k-* \ - | sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \ - | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \ - | none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \ - | hppa-* | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \ - | pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \ - | pdp11-* | sh-* | powerpc-* | powerpcle-* | sparc64-* | mips64-* | mipsel-* \ - | mips64el-* | mips64orion-* | mips64orionel-* | f301-*) + # FIXME: clean up the formatting here. + vax-* | tahoe-* | i[234567]86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \ + | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | c[123]* \ + | arm-* | armbe-* | armle-* | armv*-* | strongarm-* | xscale-* \ + | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ + | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \ + | xmp-* | ymp-* \ + | x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* \ + | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \ + | hppa2.0n-* | hppa64-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \ + | alphaev6[78]-* \ + | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \ + | clipper-* | orion-* \ + | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ + | sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \ + | mips64el-* | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \ + | mipstx39-* | mipstx39el-* | mcore-* \ + | f30[01]-* | s390-* | sv1-* | t3e-* \ + | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \ + | thumb-* | v850-* | d30v-* | tic30-* | c30-* | fr30-* \ + | bs2000-* | tic54x-* | c54x-* | x86_64-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; alliant | fx80) basic_machine=fx80-alliant ;; @@ -202,20 +313,24 @@ case $basic_machine in os=-sysv ;; amiga | amiga-*) - basic_machine=m68k-cbm + basic_machine=m68k-unknown ;; - amigados) - basic_machine=m68k-cbm - os=-amigados + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos ;; amigaunix | amix) - basic_machine=m68k-cbm + basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; aux) basic_machine=m68k-apple os=-aux @@ -259,6 +374,9 @@ case $basic_machine in crds | unos) basic_machine=m68k-crds ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; da30 | da30-*) basic_machine=m68k-da30 ;; @@ -292,6 +410,10 @@ case $basic_machine in encore | umax | mmax) basic_machine=ns32k-encore ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; fx2800) basic_machine=i860-alliant ;; @@ -310,6 +432,14 @@ case $basic_machine in basic_machine=h8300-hitachi os=-hms ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; harris) basic_machine=m88k-harris os=-sysv3 @@ -325,13 +455,30 @@ case $basic_machine in basic_machine=m68k-hp os=-hpux ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; - hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7) + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) @@ -340,27 +487,54 @@ case $basic_machine in hppa-next) os=-nextstep3 ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; i370-ibm* | ibm*) basic_machine=i370-ibm - os=-mvs ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? - i[3456]86v32) + i[34567]86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; - i[3456]86v4*) + i[34567]86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; - i[3456]86v) + i[34567]86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; - i[3456]86sol2) + i[34567]86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + i386-go32 | go32) + basic_machine=i386-unknown + os=-go32 + ;; + i386-mingw32 | mingw32) + basic_machine=i386-unknown + os=-mingw32 + ;; + i[34567]86-pw32 | pw32) + basic_machine=i586-unknown + os=-pw32 + ;; iris | iris4d) basic_machine=mips-sgi case $os in @@ -389,16 +563,52 @@ case $basic_machine in miniframe) basic_machine=m68000-convergent ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mipsel*-linux*) + basic_machine=mipsel-unknown + os=-linux-gnu + ;; + mips*-linux*) + basic_machine=mips-unknown + os=-linux-gnu + ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + msdos) + basic_machine=i386-unknown + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos @@ -411,6 +621,10 @@ case $basic_machine in basic_machine=mips-sony os=-newsos ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; next | m*-next ) basic_machine=m68k-next case $os in @@ -436,9 +650,32 @@ case $basic_machine in basic_machine=i960-intel os=-nindy ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; np1) basic_machine=np1-gould ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 @@ -456,30 +693,28 @@ case $basic_machine in pc532 | pc532-*) basic_machine=ns32k-pc532 ;; - pentium | p5) - basic_machine=i586-intel + pentium | p5 | k5 | k6 | nexgen) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon) + basic_machine=i686-pc ;; - pentiumpro | p6) - basic_machine=i686-intel + pentiumii | pentium2) + basic_machine=i686-pc ;; - pentium-* | p5-*) + pentium-* | p5-* | k5-* | k6-* | nexgen-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; - pentiumpro-* | p6-*) + pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; - k5) - # We don't have specific support for AMD's K5 yet, so just call it a Pentium - basic_machine=i586-amd - ;; - nexen) - # We don't have specific support for Nexgen yet, so just call it a Pentium - basic_machine=i586-nexgen + pentiumii-* | pentium2-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; - power) basic_machine=rs6000-ibm + power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; @@ -494,12 +729,20 @@ case $basic_machine in ps2) basic_machine=i386-ibm ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; sequent) basic_machine=i386-sequent ;; @@ -507,6 +750,10 @@ case $basic_machine in basic_machine=sh-hitachi os=-hms ;; + sparclite-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; sps7) basic_machine=m68k-bull os=-sysv2 @@ -514,6 +761,13 @@ case $basic_machine in spur) basic_machine=spur-unknown ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; sun2) basic_machine=m68000-sun ;; @@ -554,10 +808,28 @@ case $basic_machine in sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; symmetry) basic_machine=i386-sequent os=-dynix ;; + t3e) + basic_machine=t3e-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; tower | tower-32) basic_machine=m68k-ncr ;; @@ -569,6 +841,10 @@ case $basic_machine in basic_machine=a29k-nyu os=-sym1 ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; vaxv) basic_machine=vax-dec os=-sysv @@ -577,7 +853,7 @@ case $basic_machine in basic_machine=vax-dec os=-vms ;; - vpp*|vx|vx-*) + vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) @@ -592,6 +868,14 @@ case $basic_machine in basic_machine=a29k-wrs os=-vxworks ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; xmp) basic_machine=xmp-cray os=-unicos @@ -599,6 +883,10 @@ case $basic_machine in xps | xps100) basic_machine=xps100-honeywell ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; none) basic_machine=none-none os=-none @@ -606,8 +894,21 @@ case $basic_machine in # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; mips) - basic_machine=mips-mips + if [ x$os = x-linux-gnu ]; then + basic_machine=mips-unknown + else + basic_machine=mips-mips + fi ;; romp) basic_machine=romp-ibm @@ -624,7 +925,10 @@ case $basic_machine in we32k) basic_machine=we32k-att ;; - sparc) + sh3 | sh4) + basic_machine=sh-unknown + ;; + sparc | sparcv9) basic_machine=sparc-sun ;; cydra) @@ -636,6 +940,16 @@ case $basic_machine in orion105) basic_machine=clipper-highlevel ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + c4x*) + basic_machine=c4x-none + os=-coff + ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 @@ -668,9 +982,12 @@ case $os in -solaris) os=-solaris2 ;; - -unixware* | svr4*) + -svr4*) os=-sysv4 ;; + -unixware*) + os=-sysv4.2uw + ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; @@ -681,17 +998,39 @@ case $os in -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ - | -amigados* | -msdos* | -newsos* | -unicos* | -aof* | -aos* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ - | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -cygwin32* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -linux-gnu* | -uxpv*) + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* | -storm-chaos*) # Remember, each alternative MUST END IN *, to match a version number. ;; + -qnx*) + case $basic_machine in + x86-* | i[34567]86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto*) + os=-nto-qnx + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; @@ -701,6 +1040,12 @@ case $os in -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; -osfrose*) os=-osfrose ;; @@ -716,12 +1061,18 @@ case $os in -acis*) os=-aos ;; + -386bsd) + os=-bsd + ;; -ctix* | -uts*) os=-sysv ;; -ns2 ) os=-nextstep2 ;; + -nsk*) + os=-nsk + ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` @@ -747,9 +1098,18 @@ case $os in # This must come after -sysvr4. -sysv*) ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; -xenix) os=-xenix ;; + -*mint | -*MiNT) + os=-mint + ;; -none) ;; *) @@ -775,6 +1135,9 @@ case $basic_machine in *-acorn) os=-riscix1.2 ;; + arm*-rebel) + os=-linux + ;; arm*-semi) os=-aout ;; @@ -796,15 +1159,36 @@ case $basic_machine in # default. # os=-sunos4 ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; + *-be) + os=-beos + ;; *-ibm) os=-aix ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; *-hp) os=-hpux ;; @@ -815,7 +1199,7 @@ case $basic_machine in os=-sysv ;; *-cbm) - os=-amigados + os=-amigaos ;; *-dg) os=-dgux @@ -865,9 +1249,21 @@ case $basic_machine in *-masscomp) os=-rtu ;; - f301-fujitsu) + f30[01]-fujitsu) os=-uxpv ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; *) os=-none ;; @@ -889,9 +1285,15 @@ case $basic_machine in -aix*) vendor=ibm ;; + -beos*) + vendor=be + ;; -hpux*) vendor=hp ;; + -mpeix*) + vendor=hp + ;; -hiux*) vendor=hitachi ;; @@ -907,7 +1309,7 @@ case $basic_machine in -genix*) vendor=ns ;; - -mvs*) + -mvs* | -opened*) vendor=ibm ;; -ptx*) @@ -919,9 +1321,26 @@ case $basic_machine in -aux*) vendor=apple ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -*MiNT) + vendor=atari + ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/contrib/libpcap/configure b/contrib/libpcap/configure index 11b289d..dea3a59 100755 --- a/contrib/libpcap/configure +++ b/contrib/libpcap/configure @@ -1,5 +1,40 @@ #! /bin/sh +# From configure.in Revision: 1.87.2.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf version 2.13 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. @@ -581,7 +616,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:585: checking host system type" >&5 +echo "configure:620: checking host system type" >&5 host_alias=$host case "$host_alias" in @@ -602,7 +637,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:606: checking target system type" >&5 +echo "configure:641: checking target system type" >&5 target_alias=$target case "$target_alias" in @@ -620,7 +655,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:624: checking build system type" >&5 +echo "configure:659: checking build system type" >&5 build_alias=$build case "$build_alias" in @@ -643,12 +678,6 @@ test "$host_alias" != "$target_alias" && program_prefix=${target_alias}- -umask 002 - -if test -z "$PWD" ; then - PWD=`pwd` -fi - @@ -674,7 +703,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:678: checking for $ac_word" >&5 +echo "configure:707: 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 @@ -715,7 +744,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:719: checking for $ac_word" >&5 +echo "configure:748: 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 @@ -745,7 +774,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:749: checking for $ac_word" >&5 +echo "configure:778: 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 @@ -796,7 +825,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:800: checking for $ac_word" >&5 +echo "configure:829: 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 @@ -828,7 +857,7 @@ fi fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:832: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 +echo "configure:861: 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. @@ -839,12 +868,12 @@ cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF -#line 843 "configure" +#line 872 "configure" #include "confdefs.h" main(){return(0);} EOF -if { (eval echo configure:848: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:877: \"$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 @@ -870,12 +899,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:874: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:903: 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:879: checking whether we are using GNU C" >&5 +echo "configure:908: 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 @@ -884,7 +913,7 @@ else yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:888: \"$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:917: \"$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 @@ -903,7 +932,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:907: checking whether ${CC-cc} accepts -g" >&5 +echo "configure:936: 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 @@ -940,7 +969,7 @@ fi V_CCOPT="-O2" else echo $ac_n "checking gcc version""... $ac_c" 1>&6 -echo "configure:944: checking gcc version" >&5 +echo "configure:973: 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 @@ -958,19 +987,19 @@ fi fi else echo $ac_n "checking that $CC handles ansi prototypes""... $ac_c" 1>&6 -echo "configure:962: checking that $CC handles ansi prototypes" >&5 +echo "configure:991: 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 <<EOF -#line 967 "configure" +#line 996 "configure" #include "confdefs.h" #include <sys/types.h> int main() { int frob(int, char *) ; return 0; } EOF -if { (eval echo configure:974: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1003: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_lbl_cc_ansi_prototypes=yes else @@ -988,21 +1017,21 @@ fi hpux*) echo $ac_n "checking for HP-UX ansi compiler ($CC -Aa -D_HPUX_SOURCE)""... $ac_c" 1>&6 -echo "configure:992: checking for HP-UX ansi compiler ($CC -Aa -D_HPUX_SOURCE)" >&5 +echo "configure:1021: 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 <<EOF -#line 999 "configure" +#line 1028 "configure" #include "confdefs.h" #include <sys/types.h> int main() { int frob(int, char *) ; return 0; } EOF -if { (eval echo configure:1006: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1035: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_lbl_cc_hpux_cc_aa=yes else @@ -1046,12 +1075,12 @@ EOF ultrix*) echo $ac_n "checking that Ultrix $CC hacks const in prototypes""... $ac_c" 1>&6 -echo "configure:1050: checking that Ultrix $CC hacks const in prototypes" >&5 +echo "configure:1079: 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 <<EOF -#line 1055 "configure" +#line 1084 "configure" #include "confdefs.h" #include <sys/types.h> int main() { @@ -1059,7 +1088,7 @@ struct a { int b; }; void c(const struct a *) ; return 0; } EOF -if { (eval echo configure:1063: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1092: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_lbl_cc_const_proto=yes else @@ -1082,9 +1111,209 @@ EOF esac fi +echo $ac_n "checking for inline""... $ac_c" 1>&6 +echo "configure:1116: checking for inline" >&5 +if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat > conftest.$ac_ext <<EOF +#line 1123 "configure" +#include "confdefs.h" + +int main() { +} $ac_kw foo() { +; return 0; } +EOF +if { (eval echo configure:1130: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_inline=$ac_kw; break +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* +done + +fi + +echo "$ac_t""$ac_cv_c_inline" 1>&6 +case "$ac_cv_c_inline" in + inline | yes) ;; + no) cat >> confdefs.h <<\EOF +#define inline +EOF + ;; + *) cat >> confdefs.h <<EOF +#define inline $ac_cv_c_inline +EOF + ;; +esac + + +echo $ac_n "checking for __attribute__""... $ac_c" 1>&6 +echo "configure:1157: 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 <<EOF +#line 1163 "configure" +#include "confdefs.h" + +#include <stdlib.h> + +int main() { + +static void foo(void) __attribute__ ((noreturn)); + +static void +foo(void) +{ + exit(1); +} + +; return 0; } +EOF +if { (eval echo configure:1180: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv___attribute__=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv___attribute__=no +fi +rm -f conftest* +fi + +if test "$ac_cv___attribute__" = "yes"; then + cat >> confdefs.h <<\EOF +#define HAVE___ATTRIBUTE__ 1 +EOF + +fi +echo "$ac_t""$ac_cv___attribute__" 1>&6 + + +echo $ac_n "checking for u_int8_t using $CC""... $ac_c" 1>&6 +echo "configure:1202: 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 <<EOF +#line 1207 "configure" +#include "confdefs.h" + +# include "confdefs.h" +# include <sys/types.h> +# if STDC_HEADERS +# include <stdlib.h> +# include <stddef.h> +# endif +int main() { +u_int8_t i +; return 0; } +EOF +if { (eval echo configure:1220: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_lbl_have_u_int8_t=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_lbl_have_u_int8_t=no +fi +rm -f conftest* +fi + + echo "$ac_t""$ac_cv_lbl_have_u_int8_t" 1>&6 + if test $ac_cv_lbl_have_u_int8_t = no ; then + cat >> confdefs.h <<\EOF +#define u_int8_t u_char +EOF + + fi +echo $ac_n "checking for u_int16_t using $CC""... $ac_c" 1>&6 +echo "configure:1240: 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 <<EOF +#line 1245 "configure" +#include "confdefs.h" + +# include "confdefs.h" +# include <sys/types.h> +# if STDC_HEADERS +# include <stdlib.h> +# include <stddef.h> +# endif +int main() { +u_int16_t i +; return 0; } +EOF +if { (eval echo configure:1258: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_lbl_have_u_int16_t=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_lbl_have_u_int16_t=no +fi +rm -f conftest* +fi + + echo "$ac_t""$ac_cv_lbl_have_u_int16_t" 1>&6 + if test $ac_cv_lbl_have_u_int16_t = no ; then + cat >> confdefs.h <<\EOF +#define u_int16_t u_short +EOF + + fi +echo $ac_n "checking for u_int32_t using $CC""... $ac_c" 1>&6 +echo "configure:1278: 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 <<EOF +#line 1283 "configure" +#include "confdefs.h" + +# include "confdefs.h" +# include <sys/types.h> +# if STDC_HEADERS +# include <stdlib.h> +# include <stddef.h> +# endif +int main() { +u_int32_t i +; return 0; } +EOF +if { (eval echo configure:1296: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_lbl_have_u_int32_t=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_lbl_have_u_int32_t=no +fi +rm -f conftest* +fi + + echo "$ac_t""$ac_cv_lbl_have_u_int32_t" 1>&6 + if test $ac_cv_lbl_have_u_int32_t = no ; then + cat >> confdefs.h <<\EOF +#define u_int32_t u_int +EOF + + fi echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:1088: checking how to run the C preprocessor" >&5 +echo "configure:1317: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -1099,13 +1328,13 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext <<EOF -#line 1103 "configure" +#line 1332 "configure" #include "confdefs.h" #include <assert.h> Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1109: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1338: \"$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 : @@ -1116,13 +1345,13 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext <<EOF -#line 1120 "configure" +#line 1349 "configure" #include "confdefs.h" #include <assert.h> Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1126: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1355: \"$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 : @@ -1133,13 +1362,13 @@ else rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext <<EOF -#line 1137 "configure" +#line 1366 "configure" #include "confdefs.h" #include <assert.h> Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1143: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1372: \"$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 : @@ -1163,21 +1392,21 @@ else fi echo "$ac_t""$CPP" 1>&6 -for ac_hdr in malloc.h sys/ioccom.h sys/sockio.h +for ac_hdr in sys/ioccom.h sys/sockio.h ifaddrs.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:1171: checking for $ac_hdr" >&5 +echo "configure:1400: 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 -#line 1176 "configure" +#line 1405 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1181: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1410: \"$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* @@ -1206,12 +1435,12 @@ done if test "$GCC" = yes ; then echo $ac_n "checking for ANSI ioctl definitions""... $ac_c" 1>&6 -echo "configure:1210: checking for ANSI ioctl definitions" >&5 +echo "configure:1439: 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 <<EOF -#line 1215 "configure" +#line 1444 "configure" #include "confdefs.h" /* * This generates a "duplicate case value" when fixincludes @@ -1230,7 +1459,7 @@ switch (0) { } ; return 0; } EOF -if { (eval echo configure:1234: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1463: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_lbl_gcc_fixincludes=yes else @@ -1250,15 +1479,15 @@ fi fi fi -for ac_func in ether_hostton strerror +for ac_func in ether_hostton strerror freeifaddrs strlcpy do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:1257: checking for $ac_func" >&5 +echo "configure:1486: 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 <<EOF -#line 1262 "configure" +#line 1491 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -1281,7 +1510,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:1285: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1514: \"$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 @@ -1307,7 +1536,7 @@ done echo $ac_n "checking if --disable-protochain option is specified""... $ac_c" 1>&6 -echo "configure:1311: checking if --disable-protochain option is specified" >&5 +echo "configure:1540: 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" @@ -1328,6 +1557,9 @@ EOF fi echo "$ac_t""${enable_protochain}" 1>&6 +if test -z "$with_pcap" && test "$cross_compiling" = yes; then + { echo "configure: error: pcap type not determined when cross-compiling; use --with-pcap=..." 1>&2; exit 1; } +fi # Check whether --with-pcap or --without-pcap was given. if test "${with_pcap+set}" = set; then withval="$with_pcap" @@ -1335,7 +1567,7 @@ if test "${with_pcap+set}" = set; then fi echo $ac_n "checking packet capture type""... $ac_c" 1>&6 -echo "configure:1339: checking packet capture type" >&5 +echo "configure:1571: checking packet capture type" >&5 if test ! -z "$with_pcap" ; then V_PCAP="$withval" elif test -r /dev/bpf0 ; then @@ -1366,7 +1598,7 @@ fi echo "$ac_t""$V_PCAP" 1>&6 echo $ac_n "checking if --enable-ipv6 option is specified""... $ac_c" 1>&6 -echo "configure:1370: checking if --enable-ipv6 option is specified" >&5 +echo "configure:1602: 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" @@ -1388,17 +1620,17 @@ dlpi) do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:1392: checking for $ac_hdr" >&5 +echo "configure:1624: 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 -#line 1397 "configure" +#line 1629 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1402: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1634: \"$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* @@ -1425,7 +1657,7 @@ fi done echo $ac_n "checking for /dev/dlpi device""... $ac_c" 1>&6 -echo "configure:1429: checking for /dev/dlpi device" >&5 +echo "configure:1661: checking for /dev/dlpi device" >&5 if test -c /dev/dlpi ; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF @@ -1436,7 +1668,7 @@ EOF echo "$ac_t""no" 1>&6 dir="/dev/dlpi" echo $ac_n "checking for $dir directory""... $ac_c" 1>&6 -echo "configure:1440: checking for $dir directory" >&5 +echo "configure:1672: checking for $dir directory" >&5 if test -d $dir ; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<EOF @@ -1450,21 +1682,21 @@ EOF ;; linux) - for ac_hdr in net/if_arp.h + for ac_hdr in netpacket/packet.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:1458: checking for $ac_hdr" >&5 +echo "configure:1690: 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 -#line 1463 "configure" +#line 1695 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1468: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1700: \"$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* @@ -1491,15 +1723,27 @@ fi done echo $ac_n "checking Linux kernel version""... $ac_c" 1>&6 -echo "configure:1495: checking Linux kernel version" >&5 - if eval "test \"`echo '$''{'ac_cv_linux_vers'+set}'`\" = set"; then +echo "configure:1727: 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 +else + ac_cv_linux_vers=unknown +fi + + else + if eval "test \"`echo '$''{'ac_cv_linux_vers'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_linux_vers=`uname -r 2>&1 | \ - sed -n -e '$s/.* //' -e '$s/\..*//p'` + sed -n -e '$s/.* //' -e '$s/\..*//p'` fi + fi echo "$ac_t""$ac_cv_linux_vers" 1>&6 + if test $ac_cv_linux_vers = unknown ; then + { echo "configure: error: cannot determine linux version when cross-compiling" 1>&2; exit 1; } + fi if test $ac_cv_linux_vers -lt 2 ; then { echo "configure: error: version 2 or higher required; see the INSTALL doc for more info" 1>&2; exit 1; } fi @@ -1532,7 +1776,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:1536: checking for $ac_word" >&5 +echo "configure:1780: 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 @@ -1566,7 +1810,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:1570: checking for flex 2.4 or higher" >&5 +echo "configure:1814: 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 @@ -1592,7 +1836,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:1596: checking for $ac_word" >&5 +echo "configure:1840: 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 @@ -1635,6 +1879,29 @@ test -n "$V_YACC" || V_YACC="yacc" V_LEX="$V_LEX -Ppcap_" V_YACC="$V_YACC -p pcap_" fi +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:1887: 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 + if lex -t scanner.l > /dev/null 2>&1; then + tcpdump_cv_capable_lex=yes + else + tcpdump_cv_capable_lex=insufficient + fi +fi + +echo "$ac_t""$tcpdump_cv_capable_lex" 1>&6 + if test $tcpdump_cv_capable_lex = insufficient ; then + { echo "configure: error: Your operating system's lex is insufficient to compile + libpcap. flex is a lex replacement that has many advantages, including + being able to compile libpcap. For more information, see + http://www.gnu.org/software/flex/flex.html ." 1>&2; exit 1; } + fi +fi case "$target_os" in @@ -1667,19 +1934,19 @@ EOF sinix*) echo $ac_n "checking if SINIX compiler defines sinix""... $ac_c" 1>&6 -echo "configure:1671: checking if SINIX compiler defines sinix" >&5 +echo "configure:1938: 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 <<EOF -#line 1676 "configure" +#line 1943 "configure" #include "confdefs.h" int main() { int i = sinix; ; return 0; } EOF -if { (eval echo configure:1683: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1950: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_cc_sinix_defined=yes else @@ -1706,47 +1973,38 @@ solaris*) EOF ;; - -linux*) - V_INCLS="$V_INCLS -Ilinux-include" - ;; esac -for ac_prog in ranlib -do -# Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 +# 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:1721: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_V_RANLIB'+set}'`\" = set"; then +echo "configure:1982: 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 - if test -n "$V_RANLIB"; then - ac_cv_prog_V_RANLIB="$V_RANLIB" # Let the user override the test. + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then - ac_cv_prog_V_RANLIB="$ac_prog" + ac_cv_prog_RANLIB="ranlib" break fi done IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" fi fi -V_RANLIB="$ac_cv_prog_V_RANLIB" -if test -n "$V_RANLIB"; then - echo "$ac_t""$V_RANLIB" 1>&6 +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 else echo "$ac_t""no" 1>&6 fi -test -n "$V_RANLIB" && break -done -test -n "$V_RANLIB" || V_RANLIB="@true" - rm -f os-proto.h if test "${LBL_CFLAGS+set}" = set; then @@ -1788,12 +2046,12 @@ EOF fi echo $ac_n "checking if sockaddr struct has sa_len member""... $ac_c" 1>&6 -echo "configure:1792: checking if sockaddr struct has sa_len member" >&5 +echo "configure:2050: 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 <<EOF -#line 1797 "configure" +#line 2055 "configure" #include "confdefs.h" # include <sys/types.h> @@ -1802,7 +2060,7 @@ int main() { u_int i = sizeof(((struct sockaddr *)0)->sa_len) ; return 0; } EOF -if { (eval echo configure:1806: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2064: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_lbl_sockaddr_has_sa_len=yes else @@ -1822,14 +2080,51 @@ 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:2085: 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 <<EOF +#line 2090 "configure" +#include "confdefs.h" + +# include <sys/types.h> +# include <sys/dlpi.h> +# include <sys/dlpi_ext.h> +int main() { +u_int i = sizeof(((dl_hp_ppa_info_t *)0)->dl_module_id_1) +; return 0; } +EOF +if { (eval echo configure:2100: \"$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 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1=no +fi +rm -f conftest* +fi + + echo "$ac_t""$ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1" 1>&6 + if test $ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1 = yes ; then + cat >> confdefs.h <<\EOF +#define HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1 1 +EOF + + fi + echo $ac_n "checking if unaligned accesses fail""... $ac_c" 1>&6 -echo "configure:1827: checking if unaligned accesses fail" >&5 +echo "configure:2121: 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 case "$target_cpu" in - alpha|hp*|mips|sparc) + # XXX: should also check that they don't do weird things (like on arm) + alpha*|arm*|hp*|mips|sparc) ac_cv_lbl_unaligned_fail=yes ;; @@ -1885,11 +2180,6 @@ EOF fi -if test -r ${srcdir}/lbl/gnuc.h ; then - rm -f gnuc.h - ln -s ${srcdir}/lbl/gnuc.h gnuc.h -fi - rm -f net ln -s ${srcdir}/bpf/net net @@ -1912,7 +2202,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:1916: checking for a BSD compatible install" >&5 +echo "configure:2206: 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 @@ -1965,6 +2255,8 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + trap '' 1 2 15 cat > confcache <<\EOF # This file is a shell script that caches the results of configure @@ -2028,19 +2320,7 @@ fi trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 -# Transform confdefs.h into DEFS. -# Protect against shell expansion while executing Makefile rules. -# Protect against Makefile macro expansion. -cat > conftest.defs <<\EOF -s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g -s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g -s%\[%\\&%g -s%\]%\\&%g -s%\$%$$%g -EOF -DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` -rm -f conftest.defs - +DEFS=-DHAVE_CONFIG_H # Without the "./", some shells look in PATH for config.status. : ${CONFIG_STATUS=./config.status} @@ -2078,7 +2358,7 @@ done ac_given_srcdir=$srcdir ac_given_INSTALL="$INSTALL" -trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +trap 'rm -fr `echo "Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS <<EOF @@ -2130,10 +2410,11 @@ s%@CC@%$CC%g s%@CPP@%$CPP%g s%@V_LEX@%$V_LEX%g s%@V_YACC@%$V_YACC%g -s%@V_RANLIB@%$V_RANLIB%g +s%@RANLIB@%$RANLIB%g s%@V_CCOPT@%$V_CCOPT%g s%@V_INCLS@%$V_INCLS%g s%@V_PCAP@%$V_PCAP%g +s%@V_RANLIB@%$V_RANLIB%g s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g s%@INSTALL_DATA@%$INSTALL_DATA%g @@ -2237,6 +2518,113 @@ s%@INSTALL@%$INSTALL%g fi; done rm -f conftest.s* +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +if test "${CONFIG_HEADERS+set}" != set; then +EOF +cat >> $CONFIG_STATUS <<EOF + CONFIG_HEADERS="config.h" +EOF +cat >> $CONFIG_STATUS <<\EOF +fi +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + cat $ac_file_inputs > conftest.in + +EOF + +# Transform confdefs.h into a sed script conftest.vals that substitutes +# the proper values into config.h.in to produce config.h. And first: +# Protect against being on the right side of a sed subst in config.status. +# Protect against being in an unquoted here document in config.status. +rm -f conftest.vals +cat > conftest.hdr <<\EOF +s/[\\&%]/\\&/g +s%[\\$`]%\\&%g +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp +s%ac_d%ac_u%gp +s%ac_u%ac_e%gp +EOF +sed -n -f conftest.hdr confdefs.h > conftest.vals +rm -f conftest.hdr + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >> conftest.vals <<\EOF +s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% +EOF + +# Break up conftest.vals because some shells have a limit on +# the size of here documents, and old seds have small limits too. + +rm -f conftest.tail +while : +do + ac_lines=`grep -c . conftest.vals` + # grep -c gives empty output for an empty file on some AIX systems. + if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi + # Write a limited-size here document to conftest.frag. + echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS + echo 'CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in +' >> $CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail + rm -f conftest.vals + mv conftest.tail conftest.vals +done +rm -f conftest.vals + +cat >> $CONFIG_STATUS <<\EOF + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + fi + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + EOF cat >> $CONFIG_STATUS <<EOF diff --git a/contrib/libpcap/configure.in b/contrib/libpcap/configure.in index 732e85f..c2dfc99 100755 --- a/contrib/libpcap/configure.in +++ b/contrib/libpcap/configure.in @@ -1,4 +1,4 @@ -dnl @(#) $Header: /tcpdump/master/libpcap/configure.in,v 1.71 1999/11/01 15:56:40 itojun Exp $ (LBL) +dnl @(#) $Header: /tcpdump/master/libpcap/configure.in,v 1.87.2.1 2001/01/17 18:21:54 guy Exp $ (LBL) dnl dnl Copyright (c) 1994, 1995, 1996, 1997 dnl The Regents of the University of California. All rights reserved. @@ -6,23 +6,30 @@ dnl dnl Process this file with autoconf to produce a configure script. dnl +AC_REVISION($Revision: 1.87.2.1 $) AC_INIT(pcap.c) AC_CANONICAL_SYSTEM -umask 002 - -if test -z "$PWD" ; then - PWD=`pwd` -fi - AC_LBL_C_INIT(V_CCOPT, V_INCLS) +AC_C_INLINE +AC_C___ATTRIBUTE__ -AC_CHECK_HEADERS(malloc.h sys/ioccom.h sys/sockio.h) +AC_LBL_CHECK_TYPE(u_int8_t, u_char) +AC_LBL_CHECK_TYPE(u_int16_t, u_short) +AC_LBL_CHECK_TYPE(u_int32_t, u_int) + +dnl +dnl libpcap doesn't itself use <sys/ioccom.h>; however, the test program +dnl in "AC_LBL_FIXINCLUDES" in "aclocal.m4" uses it, so we have to +dnl test for it and set "HAVE_SYS_IOCCOM_H" if we have it, otherwise +dnl "AC_LBL_FIXINCLUDES" won't work on some platforms such as Solaris. +dnl +AC_CHECK_HEADERS(sys/ioccom.h sys/sockio.h ifaddrs.h netinet/if_ether.h) AC_LBL_FIXINCLUDES -AC_CHECK_FUNCS(ether_hostton strerror) +AC_CHECK_FUNCS(ether_hostton strerror freeifaddrs strlcpy) dnl to pacify those who hate protochain insn AC_MSG_CHECKING(if --disable-protochain option is specified) @@ -34,7 +41,7 @@ x) enable_protochain=enabled ;; esac if test "$enable_protochain" = "disabled"; then - AC_DEFINE(NO_PROTOCHAIN) + AC_DEFINE(NO_PROTOCHAIN,1,[do not use protochain]) fi AC_MSG_RESULT(${enable_protochain}) @@ -44,6 +51,11 @@ dnl better way of testing since the device might be protected. So we dnl check in our normal order using -r and then check the for the /dev dnl guys again using -c. dnl +dnl XXX This could be done for cross-compiling, but for now it's not. +dnl +if test -z "$with_pcap" && test "$cross_compiling" = yes; then + AC_MSG_ERROR(pcap type not determined when cross-compiling; use --with-pcap=...) +fi AC_ARG_WITH(pcap, [ --with-pcap=TYPE use packet capture TYPE]) AC_MSG_CHECKING(packet capture type) if test ! -z "$with_pcap" ; then @@ -78,7 +90,7 @@ AC_MSG_RESULT($V_PCAP) AC_MSG_CHECKING(if --enable-ipv6 option is specified) AC_ARG_ENABLE(ipv6, [ --enable-ipv6 build IPv6-capable version]) if test "$enable_ipv6" = "yes"; then - AC_DEFINE(INET6) + AC_DEFINE(INET6,1,[IPv6]) fi AC_MSG_RESULT(${enable_ipv6-no}) @@ -89,14 +101,14 @@ dlpi) AC_MSG_CHECKING(for /dev/dlpi device) if test -c /dev/dlpi ; then AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_DEV_DLPI) + AC_DEFINE(HAVE_DEV_DLPI, 1, [define if you have a /dev/dlpi]) else AC_MSG_RESULT(no) dir="/dev/dlpi" AC_MSG_CHECKING(for $dir directory) if test -d $dir ; then AC_MSG_RESULT(yes) - AC_DEFINE_UNQUOTED(PCAP_DEV_PREFIX, "$dir") + AC_DEFINE_UNQUOTED(PCAP_DEV_PREFIX, "$dir", [/dev/dlpi directory]) else AC_MSG_RESULT(no) fi @@ -104,12 +116,20 @@ dlpi) ;; linux) - AC_CHECK_HEADERS(net/if_arp.h) + AC_CHECK_HEADERS(netpacket/packet.h) AC_MSG_CHECKING(Linux kernel version) - AC_CACHE_VAL(ac_cv_linux_vers, - ac_cv_linux_vers=`uname -r 2>&1 | \ - sed -n -e '$s/.* //' -e '$s/\..*//p'`) + if test "$cross_compiling" = yes; then + AC_CACHE_VAL(ac_cv_linux_vers, + ac_cv_linux_vers=unknown) + else + AC_CACHE_VAL(ac_cv_linux_vers, + ac_cv_linux_vers=`uname -r 2>&1 | \ + sed -n -e '$s/.* //' -e '$s/\..*//p'`) + fi AC_MSG_RESULT($ac_cv_linux_vers) + if test $ac_cv_linux_vers = unknown ; then + AC_MSG_ERROR(cannot determine linux version when cross-compiling) + fi if test $ac_cv_linux_vers -lt 2 ; then AC_MSG_ERROR(version 2 or higher required; see the INSTALL doc for more info) fi @@ -123,16 +143,32 @@ null) esac 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 . +# Try lexing it and complain if it can't deal. + AC_CACHE_CHECK([for capable lex], tcpdump_cv_capable_lex, + if lex -t scanner.l > /dev/null 2>&1; then + tcpdump_cv_capable_lex=yes + else + tcpdump_cv_capable_lex=insufficient + fi) + if test $tcpdump_cv_capable_lex = insufficient ; then + AC_MSG_ERROR([Your operating system's lex is insufficient to compile + libpcap. flex is a lex replacement that has many advantages, including + being able to compile libpcap. For more information, see + http://www.gnu.org/software/flex/flex.html .]) + fi +fi case "$target_os" in aix*) dnl Workaround to enable certain features - AC_DEFINE(_SUN) + AC_DEFINE(_SUN,1,[define on AIX to get certain functions]) ;; hpux9*) - AC_DEFINE(HAVE_HPUX9) + AC_DEFINE(HAVE_HPUX9,1,[on HP-UX 9.x]) ;; hpux10.0*) @@ -143,7 +179,7 @@ hpux10.1*) hpux*) dnl HPUX 10.20 and above is similar to HPUX 9... - AC_DEFINE(HAVE_HPUX10_20) + AC_DEFINE(HAVE_HPUX10_20,1,[on HP-UX 10.20]) ;; sinix*) @@ -156,31 +192,24 @@ sinix*) ac_cv_cc_sinix_defined=no)) AC_MSG_RESULT($ac_cv_cc_sinix_defined) if test $ac_cv_cc_sinix_defined = no ; then - AC_DEFINE(sinix) + AC_DEFINE(sinix,1,[on sinix]) fi ;; solaris*) - AC_DEFINE(HAVE_SOLARIS) - ;; - -linux*) - V_INCLS="$V_INCLS -Ilinux-include" + AC_DEFINE(HAVE_SOLARIS,1,[On solaris]) ;; esac -AC_CHECK_PROGS(V_RANLIB, ranlib, @true) +AC_PROG_RANLIB AC_LBL_DEVEL(V_CCOPT) AC_LBL_SOCKADDR_SA_LEN -AC_LBL_UNALIGNED_ACCESS +AC_LBL_HP_PPA_INFO_T_DL_MODULE_ID_1 -if test -r ${srcdir}/lbl/gnuc.h ; then - rm -f gnuc.h - ln -s ${srcdir}/lbl/gnuc.h gnuc.h -fi +AC_LBL_UNALIGNED_ACCESS rm -f net ln -s ${srcdir}/bpf/net net @@ -194,6 +223,8 @@ AC_SUBST(V_YACC) AC_PROG_INSTALL +AC_CONFIG_HEADER(config.h) + AC_OUTPUT(Makefile) if test -f .devel ; then diff --git a/contrib/libpcap/etherent.c b/contrib/libpcap/etherent.c index e00325e..fa5f0a9 100644 --- a/contrib/libpcap/etherent.c +++ b/contrib/libpcap/etherent.c @@ -21,7 +21,11 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/etherent.c,v 1.20.1.1 1999/10/07 23:46:40 mcr Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/etherent.c,v 1.21 2000/07/11 00:37:04 assar Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" #endif #include <sys/types.h> @@ -35,7 +39,6 @@ static const char rcsid[] = #include <pcap-namedb.h> -#include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif diff --git a/contrib/libpcap/ethertype.h b/contrib/libpcap/ethertype.h index f049ad8..42afe9b 100644 --- a/contrib/libpcap/ethertype.h +++ b/contrib/libpcap/ethertype.h @@ -18,11 +18,33 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: /tcpdump/master/libpcap/ethertype.h,v 1.7 1999/10/30 04:30:13 itojun Exp $ (LBL) + * @(#) $Header: /tcpdump/master/libpcap/ethertype.h,v 1.11 2000/10/22 04:15:55 guy Exp $ (LBL) */ -/* Types missing from some systems */ +/* + * Ethernet types. + * + * We wrap the declarations with #ifdef, so that if a file includes + * <netinet/if_ether.h>, which may declare some of these, we don't + * get a bunch of complaints from the C compiler about redefinitions + * of these values. + * + * We declare all of them here so that no file has to include + * <netinet/if_ether.h> if all it needs are ETHERTYPE_ values. + */ +#ifndef ETHERTYPE_PUP +#define ETHERTYPE_PUP 0x0200 /* PUP protocol */ +#endif +#ifndef ETHERTYPE_IP +#define ETHERTYPE_IP 0x0800 /* IP protocol */ +#endif +#ifndef ETHERTYPE_ARP +#define ETHERTYPE_ARP 0x0806 /* Addr. resolution protocol */ +#endif +#ifndef ETHERTYPE_REVARP +#define ETHERTYPE_REVARP 0x8035 /* reverse Addr. resolution protocol */ +#endif #ifndef ETHERTYPE_NS #define ETHERTYPE_NS 0x0600 #endif @@ -72,7 +94,10 @@ #define ETHERTYPE_AARP 0x80f3 #endif #ifndef ETHERTYPE_IPV6 -#define ETHERTYPE_IPV6 0x80f3 +#define ETHERTYPE_IPV6 0x86dd +#endif +#ifndef ETHERTYPE_8021Q +#define ETHERTYPE_8021Q 0x8100 #endif #ifndef ETHERTYPE_LOOPBACK #define ETHERTYPE_LOOPBACK 0x9000 diff --git a/contrib/libpcap/gencode.c b/contrib/libpcap/gencode.c index 6aa956b..1b9cafc 100644 --- a/contrib/libpcap/gencode.c +++ b/contrib/libpcap/gencode.c @@ -21,7 +21,11 @@ */ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.100.2.1 2000/03/01 14:12:54 itojun Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.140.2.1 2001/01/14 06:48:35 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" #endif #include <sys/types.h> @@ -31,37 +35,36 @@ static const char rcsid[] = #include <sys/param.h> #endif -#if __STDC__ struct mbuf; struct rtentry; -#endif - #include <net/if.h> #include <netinet/in.h> -#include <netinet/if_ether.h> #include <stdlib.h> +#include <string.h> #include <memory.h> #include <setjmp.h> -#if __STDC__ #include <stdarg.h> -#else -#include <varargs.h> -#endif #include "pcap-int.h" #include "ethertype.h" +#include "nlpid.h" #include "gencode.h" #include "ppp.h" +#include "sll.h" #include <pcap-namedb.h> #ifdef INET6 #include <netdb.h> #include <sys/socket.h> #endif /*INET6*/ -#include "gnuc.h" +#define LLC_SNAP_LSAP 0xaa +#define LLC_ISO_LSAP 0xfe + +#define ETHERMTU 1500 + #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif @@ -80,24 +83,16 @@ int pcap_fddipad; #endif /* VARARGS */ -__dead void -#if __STDC__ +void bpf_error(const char *fmt, ...) -#else -bpf_error(fmt, va_alist) - const char *fmt; - va_dcl -#endif + { va_list ap; -#if __STDC__ va_start(ap, fmt); -#else - va_start(ap); -#endif if (bpf_pcap != NULL) - (void)vsprintf(pcap_geterr(bpf_pcap), fmt, ap); + (void)vsnprintf(pcap_geterr(bpf_pcap), PCAP_ERRBUF_SIZE, + fmt, ap); va_end(ap); longjmp(top_ctx, 1); /* NOTREACHED */ @@ -136,24 +131,29 @@ static inline void syntax(void); static void backpatch(struct block *, struct block *); static void merge(struct block *, struct block *); static struct block *gen_cmp(u_int, u_int, bpf_int32); +static struct block *gen_cmp_gt(u_int, u_int, bpf_int32); static struct block *gen_mcmp(u_int, u_int, bpf_int32, bpf_u_int32); static struct block *gen_bcmp(u_int, u_int, const u_char *); static struct block *gen_uncond(int); static inline struct block *gen_true(void); static inline struct block *gen_false(void); static struct block *gen_linktype(int); +static struct block *gen_snap(bpf_u_int32, bpf_u_int32, u_int); static struct block *gen_hostop(bpf_u_int32, bpf_u_int32, int, int, u_int, u_int); #ifdef INET6 static struct block *gen_hostop6(struct in6_addr *, struct in6_addr *, int, int, u_int, u_int); #endif static struct block *gen_ehostop(const u_char *, int); static struct block *gen_fhostop(const u_char *, int); +static struct block *gen_thostop(const u_char *, int); static struct block *gen_dnhostop(bpf_u_int32, int, u_int); static struct block *gen_host(bpf_u_int32, bpf_u_int32, int, int); #ifdef INET6 static struct block *gen_host6(struct in6_addr *, struct in6_addr *, int, int); #endif +#ifndef INET6 static struct block *gen_gateway(const u_char *, bpf_u_int32 **, int, int); +#endif static struct block *gen_ipfrag(void); static struct block *gen_portatom(int, bpf_int32); #ifdef INET6 @@ -166,6 +166,7 @@ struct block *gen_portop6(int, int, int); static struct block *gen_port6(int, int, int); #endif static int lookup_proto(const char *, int); +static struct block *gen_protochain(int, int, int); static struct block *gen_proto(int, int, int); static struct slist *xfer_to_x(struct arth *); static struct slist *xfer_to_a(struct arth *); @@ -225,7 +226,7 @@ sdup(s) int n = strlen(s) + 1; char *cp = newchunk(n); - strcpy(cp, s); + strlcpy(cp, s, n); return (cp); } @@ -286,12 +287,19 @@ pcap_compile(pcap_t *p, struct bpf_program *program, root = NULL; bpf_pcap = p; if (setjmp(top_ctx)) { + lex_cleanup(); freechunks(); return (-1); } netmask = mask; + snaplen = pcap_snapshot(p); + if (snaplen == 0) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "snaplen of 0 rejects all packets"); + return -1; + } lex_init(buf ? buf : ""); init_linktype(pcap_datalink(p)); @@ -312,6 +320,7 @@ pcap_compile(pcap_t *p, struct bpf_program *program, program->bf_insns = icode_to_fcode(root, &len); program->bf_len = len; + lex_cleanup(); freechunks(); return (0); } @@ -325,43 +334,29 @@ pcap_compile_nopcap(int snaplen_arg, int linktype_arg, struct bpf_program *program, char *buf, int optimize, bpf_u_int32 mask) { - extern int n_errors; - int len; + pcap_t *p; + int ret; - n_errors = 0; - root = NULL; - bpf_pcap = NULL; - if (setjmp(top_ctx)) { - freechunks(); + p = pcap_open_dead(linktype_arg, snaplen_arg); + if (p == NULL) return (-1); - } - - netmask = mask; - - /* XXX needed? I don't grok the use of globals here. */ - snaplen = snaplen_arg; - - lex_init(buf ? buf : ""); - init_linktype(linktype_arg); - (void)pcap_parse(); - - if (n_errors) - syntax(); - - if (root == NULL) - root = gen_retblk(snaplen_arg); + ret = pcap_compile(p, program, buf, optimize, mask); + pcap_close(p); + return (ret); +} - if (optimize) { - bpf_optimize(&root); - if (root == NULL || - (root->s.code == (BPF_RET|BPF_K) && root->s.k == 0)) - bpf_error("expression rejects all packets"); +/* + * Clean up a "struct bpf_program" by freeing all the memory allocated + * in it. + */ +void +pcap_freecode(struct bpf_program *program) +{ + program->bf_len = 0; + if (program->bf_insns != NULL) { + free((char *)program->bf_insns); + program->bf_insns = NULL; } - program->bf_insns = icode_to_fcode(root, &len); - program->bf_len = len; - - freechunks(); - return (0); } /* @@ -465,6 +460,24 @@ gen_cmp(offset, size, v) } static struct block * +gen_cmp_gt(offset, size, v) + u_int offset, size; + bpf_int32 v; +{ + struct slist *s; + struct block *b; + + s = new_stmt(BPF_LD|BPF_ABS|size); + s->s.k = offset; + + b = new_block(JMP(BPF_JGT)); + b->stmts = s; + b->s.k = v; + + return b; +} + +static struct block * gen_mcmp(offset, size, v, mask) u_int offset, size; bpf_int32 v; @@ -558,12 +571,14 @@ init_linktype(type) return; case DLT_NULL: + case DLT_LOOP: off_linktype = 0; off_nl = 4; return; case DLT_PPP: - case DLT_CHDLC: + case DLT_C_HDLC: + case DLT_PPP_SERIAL: off_linktype = 2; off_nl = 4; return; @@ -578,6 +593,8 @@ init_linktype(type) * FDDI doesn't really have a link-level type field. * We assume that SSAP = SNAP is being used and pick * out the encapsulated Ethernet type. + * + * XXX - should we generate code to check for SNAP? */ off_linktype = 19; #ifdef PCAP_FDDIPAD @@ -590,6 +607,28 @@ init_linktype(type) return; case DLT_IEEE802: + /* + * Token Ring doesn't really have a link-level type field. + * We assume that SSAP = SNAP is being used and pick + * out the encapsulated Ethernet type. + * + * XXX - should we generate code to check for SNAP? + * + * XXX - the header is actually variable-length. + * Some various Linux patched versions gave 38 + * as "off_linktype" and 40 as "off_nl"; however, + * if a token ring packet has *no* routing + * information, i.e. is not source-routed, the correct + * values are 20 and 22, as they are in the vanilla code. + * + * A packet is source-routed iff the uppermost bit + * of the first byte of the source address, at an + * offset of 8, has the uppermost bit set. If the + * packet is source-routed, the total number of bytes + * of routing information is 2 plus bits 0x1F00 of + * the 16-bit value at an offset of 14 (shifted right + * 8 - figure out which byte that is). + */ off_linktype = 20; off_nl = 22; return; @@ -607,8 +646,18 @@ init_linktype(type) off_linktype = -1; off_nl = 0; return; + + case DLT_ATM_CLIP: /* Linux ATM defines this */ + off_linktype = 6; + off_nl = 8; + return; + + case DLT_LINUX_SLL: /* fake header for Linux cooked socket */ + off_linktype = 14; + off_nl = 16; + return; } - bpf_error("unknown data link type 0x%x", linktype); + bpf_error("unknown data link type %d", linktype); /* NOTREACHED */ } @@ -639,31 +688,132 @@ gen_false() return gen_uncond(0); } +/* + * Byte-swap a 32-bit number. + * ("htonl()" or "ntohl()" won't work - we want to byte-swap even on + * big-endian platforms.) + */ +#define SWAPLONG(y) \ +((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff)) + static struct block * gen_linktype(proto) register int proto; { struct block *b0, *b1; - /* If we're not using encapsulation and checking for IP, we're done */ - if (off_linktype == -1 && proto == ETHERTYPE_IP) + /* If we're not using encapsulation, we're done */ + if (off_linktype == -1) return gen_true(); switch (linktype) { + case DLT_EN10MB: + /* + * XXX - handle other LLC-encapsulated protocols here + * (IPX, OSI)? + */ + switch (proto) { + + case LLC_ISO_LSAP: + /* + * OSI protocols always use 802.2 encapsulation. + */ + b0 = gen_cmp_gt(off_linktype, BPF_H, ETHERMTU); + gen_not(b0); + b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32) + ((LLC_ISO_LSAP << 8) | LLC_ISO_LSAP)); + gen_and(b0, b1); + return b1; + + case ETHERTYPE_ATALK: + case ETHERTYPE_AARP: + /* + * EtherTalk (AppleTalk protocols on Ethernet link + * layer) may use 802.2 encapsulation. + */ + + /* + * Check for 802.2 encapsulation (EtherTalk phase 2?); + * we check for an Ethernet type field less than + * 1500, which means it's an 802.3 length field. + */ + b0 = gen_cmp_gt(off_linktype, BPF_H, ETHERMTU); + gen_not(b0); + + /* + * 802.2-encapsulated ETHERTYPE_ATALK packets are + * SNAP packets with an organization code of + * 0x080007 (Apple, for Appletalk) and a protocol + * type of ETHERTYPE_ATALK (Appletalk). + * + * 802.2-encapsulated ETHERTYPE_AARP packets are + * SNAP packets with an organization code of + * 0x000000 (encapsulated Ethernet) and a protocol + * type of ETHERTYPE_AARP (Appletalk ARP). + */ + if (proto == ETHERTYPE_ATALK) + b1 = gen_snap(0x080007, ETHERTYPE_ATALK, 14); + else /* proto == ETHERTYPE_AARP */ + b1 = gen_snap(0x000000, ETHERTYPE_AARP, 14); + gen_and(b0, b1); + + /* + * Check for Ethernet encapsulation (Ethertalk + * phase 1?); we just check for the Ethernet + * protocol type. + */ + b0 = gen_cmp(off_linktype, BPF_H, (bpf_int32)proto); + + gen_or(b0, b1); + return b1; + } + break; + case DLT_SLIP: return gen_false(); case DLT_PPP: - if (proto == ETHERTYPE_IP) + case DLT_PPP_SERIAL: + /* + * We use Ethernet protocol types inside libpcap; + * map them to the corresponding PPP protocol types. + */ + switch (proto) { + + case ETHERTYPE_IP: proto = PPP_IP; /* XXX was 0x21 */ + break; + #ifdef INET6 - else if (proto == ETHERTYPE_IPV6) + case ETHERTYPE_IPV6: proto = PPP_IPV6; + break; #endif + + case ETHERTYPE_DN: + proto = PPP_DECNET; + break; + + case ETHERTYPE_ATALK: + proto = PPP_APPLE; + break; + + case ETHERTYPE_NS: + proto = PPP_NS; + break; + + case LLC_ISO_LSAP: + proto = PPP_OSI; + break; + } break; case DLT_PPP_BSDOS: + /* + * We use Ethernet protocol types inside libpcap; + * map them to the corresponding PPP protocol types. + */ switch (proto) { case ETHERTYPE_IP: @@ -692,23 +842,104 @@ gen_linktype(proto) case ETHERTYPE_NS: proto = PPP_NS; break; + + case LLC_ISO_LSAP: + proto = PPP_OSI; + break; } break; case DLT_NULL: - /* XXX */ - if (proto == ETHERTYPE_IP) - return (gen_cmp(0, BPF_W, (bpf_int32)htonl(AF_INET))); + case DLT_LOOP: + /* + * For DLT_NULL, the link-layer header is a 32-bit + * word containing an AF_ value in *host* byte order. + * + * In addition, if we're reading a saved capture file, + * the host byte order in the capture may not be the + * same as the host byte order on this machine. + * + * For DLT_LOOP, the link-layer header is a 32-bit + * word containing an AF_ value in *network* byte order. + * + * XXX - AF_ values may, unfortunately, be platform- + * dependent; for example, FreeBSD's AF_INET6 is 24 + * whilst NetBSD's and OpenBSD's is 26. + * + * This means that, when reading a capture file, just + * checking for our AF_INET6 value won't work if the + * capture file came from another OS. + */ + switch (proto) { + + case ETHERTYPE_IP: + proto = AF_INET; + break; + #ifdef INET6 - else if (proto == ETHERTYPE_IPV6) - return (gen_cmp(0, BPF_W, (bpf_int32)htonl(AF_INET6))); + case ETHERTYPE_IPV6: + proto = AF_INET6; + break; #endif - else + + default: + /* + * Not a type on which we support filtering. + * XXX - support those that have AF_ values + * #defined on this platform, at least? + */ return gen_false(); + } + + if (linktype == DLT_NULL) { + /* + * The AF_ value is in host byte order, but + * the BPF interpreter will convert it to + * network byte order. + * + * If this is a save file, and it's from a + * machine with the opposite byte order to + * ours, we byte-swap the AF_ value. + * + * Then we run it through "htonl()", and + * generate code to compare against the result. + */ + if (bpf_pcap->sf.rfile != NULL && + bpf_pcap->sf.swapped) + proto = SWAPLONG(proto); + proto = htonl(proto); + } + return (gen_cmp(0, BPF_W, (bpf_int32)proto)); } return gen_cmp(off_linktype, BPF_H, (bpf_int32)proto); } +/* + * Check for an LLC SNAP packet with a given organization code and + * protocol type; we check the entire contents of the 802.2 LLC and + * snap headers, checking for DSAP and SSAP of SNAP and a control + * field of 0x03 in the LLC header, and for the specified organization + * code and protocol type in the SNAP header. + */ +static struct block * +gen_snap(orgcode, ptype, offset) + bpf_u_int32 orgcode; + bpf_u_int32 ptype; + u_int offset; +{ + u_char snapblock[8]; + + snapblock[0] = LLC_SNAP_LSAP; /* DSAP = SNAP */ + snapblock[1] = LLC_SNAP_LSAP; /* SSAP = SNAP */ + snapblock[2] = 0x03; /* control = UI */ + snapblock[3] = (orgcode >> 16); /* upper 8 bits of organization code */ + snapblock[4] = (orgcode >> 8); /* middle 8 bits of organization code */ + snapblock[5] = (orgcode >> 0); /* lower 8 bits of organization code */ + snapblock[6] = (ptype >> 8); /* upper 8 bits of protocol type */ + snapblock[7] = (ptype >> 0); /* lower 8 bits of protocol type */ + return gen_bcmp(offset, 8, snapblock); +} + static struct block * gen_hostop(addr, mask, dir, proto, src_off, dst_off) bpf_u_int32 addr; @@ -879,6 +1110,40 @@ gen_fhostop(eaddr, dir) } /* + * Like gen_ehostop, but for DLT_IEEE802 (Token Ring) + */ +static struct block * +gen_thostop(eaddr, dir) + register const u_char *eaddr; + register int dir; +{ + register struct block *b0, *b1; + + switch (dir) { + case Q_SRC: + return gen_bcmp(8, 6, eaddr); + + case Q_DST: + return gen_bcmp(2, 6, eaddr); + + case Q_AND: + b0 = gen_thostop(eaddr, Q_SRC); + b1 = gen_thostop(eaddr, Q_DST); + gen_and(b0, b1); + return b1; + + case Q_DEFAULT: + case Q_OR: + b0 = gen_thostop(eaddr, Q_SRC); + b1 = gen_thostop(eaddr, Q_DST); + gen_or(b0, b1); + return b1; + } + abort(); + /* NOTREACHED */ +} + +/* * This is quite tricky because there may be pad bytes in front of the * DECNET header, and then there are two possible data packet formats that * carry both src and dst addresses, plus 5 packet types in a format that @@ -933,6 +1198,9 @@ gen_dnhostop(addr, dir, base_off) gen_or(b0, b1); return b1; + case Q_ISO: + bpf_error("ISO host filtering not implemented"); + default: abort(); } @@ -979,10 +1247,12 @@ gen_host(addr, mask, proto, dir) case Q_DEFAULT: b0 = gen_host(addr, mask, Q_IP, dir); - b1 = gen_host(addr, mask, Q_ARP, dir); - gen_or(b0, b1); - b0 = gen_host(addr, mask, Q_RARP, dir); - gen_or(b1, b0); + if (off_linktype != -1) { + b1 = gen_host(addr, mask, Q_ARP, dir); + gen_or(b0, b1); + b0 = gen_host(addr, mask, Q_RARP, dir); + gen_or(b1, b0); + } return b0; case Q_IP: @@ -1018,6 +1288,9 @@ gen_host(addr, mask, proto, dir) case Q_ATALK: bpf_error("ATALK host filtering not implemented"); + case Q_AARP: + bpf_error("AARP host filtering not implemented"); + case Q_DECNET: return gen_dnhostop(addr, dir, off_nl); @@ -1047,6 +1320,18 @@ gen_host(addr, mask, proto, dir) case Q_ESP: bpf_error("'esp' modifier applied to host"); + case Q_ISO: + bpf_error("ISO host filtering not implemented"); + + case Q_ESIS: + bpf_error("'esis' modifier applied to host"); + + case Q_ISIS: + bpf_error("'isis' modifier applied to host"); + + case Q_CLNP: + bpf_error("'clnp' modifier applied to host"); + default: abort(); } @@ -1061,8 +1346,6 @@ gen_host6(addr, mask, proto, dir) int proto; int dir; { - struct block *b0, *b1; - switch (proto) { case Q_DEFAULT: @@ -1098,6 +1381,9 @@ gen_host6(addr, mask, proto, dir) case Q_ATALK: bpf_error("ATALK host filtering not implemented"); + case Q_AARP: + bpf_error("AARP host filtering not implemented"); + case Q_DECNET: bpf_error("'decnet' modifier applied to ip6 host"); @@ -1126,6 +1412,18 @@ gen_host6(addr, mask, proto, dir) case Q_ESP: bpf_error("'esp' modifier applied to host"); + case Q_ISO: + bpf_error("ISO host filtering not implemented"); + + case Q_ESIS: + bpf_error("'esis' modifier applied to host"); + + case Q_ISIS: + bpf_error("'isis' modifier applied to host"); + + case Q_CLNP: + bpf_error("'clnp' modifier applied to host"); + default: abort(); } @@ -1133,6 +1431,7 @@ gen_host6(addr, mask, proto, dir) } #endif /*INET6*/ +#ifndef INET6 static struct block * gen_gateway(eaddr, alist, proto, dir) const u_char *eaddr; @@ -1154,9 +1453,11 @@ gen_gateway(eaddr, alist, proto, dir) b0 = gen_ehostop(eaddr, Q_OR); else if (linktype == DLT_FDDI) b0 = gen_fhostop(eaddr, Q_OR); + else if (linktype == DLT_IEEE802) + b0 = gen_thostop(eaddr, Q_OR); else bpf_error( - "'gateway' supported only on ethernet or FDDI"); + "'gateway' supported only on ethernet, FDDI or token ring"); b1 = gen_host(**alist++, 0xffffffff, proto, Q_OR); while (*alist) { @@ -1171,12 +1472,16 @@ gen_gateway(eaddr, alist, proto, dir) bpf_error("illegal modifier of 'gateway'"); /* NOTREACHED */ } +#endif struct block * gen_proto_abbrev(proto) int proto; { - struct block *b0, *b1; +#ifdef INET6 + struct block *b0; +#endif + struct block *b1; switch (proto) { @@ -1200,8 +1505,12 @@ gen_proto_abbrev(proto) b1 = gen_proto(IPPROTO_ICMP, Q_IP, Q_DEFAULT); break; +#ifndef IPPROTO_IGMP +#define IPPROTO_IGMP 2 +#endif + case Q_IGMP: - b1 = gen_proto(2, Q_IP, Q_DEFAULT); + b1 = gen_proto(IPPROTO_IGMP, Q_IP, Q_DEFAULT); break; #ifndef IPPROTO_IGRP @@ -1209,7 +1518,6 @@ gen_proto_abbrev(proto) #endif case Q_IGRP: b1 = gen_proto(IPPROTO_IGRP, Q_IP, Q_DEFAULT); - gen_and(b0, b1); break; #ifndef IPPROTO_PIM @@ -1243,6 +1551,10 @@ gen_proto_abbrev(proto) b1 = gen_linktype(ETHERTYPE_ATALK); break; + case Q_AARP: + b1 = gen_linktype(ETHERTYPE_AARP); + break; + case Q_DECNET: b1 = gen_linktype(ETHERTYPE_DN); break; @@ -1298,6 +1610,22 @@ gen_proto_abbrev(proto) #endif break; + case Q_ISO: + b1 = gen_linktype(LLC_ISO_LSAP); + break; + + case Q_ESIS: + b1 = gen_proto(ISO9542_ESIS, Q_ISO, Q_DEFAULT); + break; + + case Q_ISIS: + b1 = gen_proto(ISO10589_ISIS, Q_ISO, Q_DEFAULT); + break; + + case Q_CLNP: + b1 = gen_proto(ISO8473_CLNP, Q_ISO, Q_DEFAULT); + break; + default: abort(); } @@ -1517,6 +1845,17 @@ lookup_proto(name, proto) bpf_error("unknown ether proto '%s'", name); break; + case Q_ISO: + if (strcmp(name, "esis") == 0) + v = ISO9542_ESIS; + else if (strcmp(name, "isis") == 0) + v = ISO10589_ISIS; + else if (strcmp(name, "clnp") == 0) + v = ISO8473_CLNP; + else + bpf_error("unknown osi proto '%s'", name); + break; + default: v = PROTO_UNDEF; break; @@ -1524,14 +1863,17 @@ lookup_proto(name, proto) return v; } +#if 0 struct stmt * gen_joinsp(s, n) struct stmt **s; int n; { + return NULL; } +#endif -struct block * +static struct block * gen_protochain(v, proto, dir) int v; int proto; @@ -1541,11 +1883,10 @@ gen_protochain(v, proto, dir) return gen_proto(v, proto, dir); #else struct block *b0, *b; - struct slist *s[100], *sp; + struct slist *s[100]; int fix2, fix3, fix4, fix5; int ahcheck, again, end; int i, max; - int reg1 = alloc_reg(); int reg2 = alloc_reg(); memset(s, 0, sizeof(s)); @@ -1667,15 +2008,22 @@ gen_protochain(v, proto, dir) /* * in short, - * A = P[X + 1]; - * X = X + (P[X] + 1) * 8; + * A = P[X]; + * X = X + (P[X + 1] + 1) * 8; */ /* A = X */ s[i] = new_stmt(BPF_MISC|BPF_TXA); i++; - /* MEM[reg1] = A */ + /* A = P[X + packet head] */ + s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); + s[i]->s.k = off_nl; + i++; + /* MEM[reg2] = A */ s[i] = new_stmt(BPF_ST); - s[i]->s.k = reg1; + s[i]->s.k = reg2; + i++; + /* A = X */ + s[i] = new_stmt(BPF_MISC|BPF_TXA); i++; /* A += 1 */ s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); @@ -1688,18 +2036,6 @@ gen_protochain(v, proto, dir) s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); s[i]->s.k = off_nl; i++; - /* MEM[reg2] = A */ - s[i] = new_stmt(BPF_ST); - s[i]->s.k = reg2; - i++; - /* X = MEM[reg1] */ - s[i] = new_stmt(BPF_LDX|BPF_MEM); - s[i]->s.k = reg1; - i++; - /* A = P[X + packet head] */ - s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); - s[i]->s.k = off_nl; - i++; /* A += 1 */ s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); s[i]->s.k = 1; @@ -1749,23 +2085,12 @@ gen_protochain(v, proto, dir) /* * in short, - * A = P[X + 1]; - * X = X + (P[X] + 2) * 4; + * A = P[X]; + * X = X + (P[X + 1] + 2) * 4; */ /* A = X */ s[i - 1]->s.jt = s[i] = new_stmt(BPF_MISC|BPF_TXA); i++; - /* MEM[reg1] = A */ - s[i] = new_stmt(BPF_ST); - s[i]->s.k = reg1; - i++; - /* A += 1 */ - s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); - s[i]->s.k = 1; - i++; - /* X = A */ - s[i] = new_stmt(BPF_MISC|BPF_TAX); - i++; /* A = P[X + packet head]; */ s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); s[i]->s.k = off_nl; @@ -1774,9 +2099,15 @@ gen_protochain(v, proto, dir) s[i] = new_stmt(BPF_ST); s[i]->s.k = reg2; i++; - /* X = MEM[reg1] */ - s[i] = new_stmt(BPF_LDX|BPF_MEM); - s[i]->s.k = reg1; + /* A = X */ + s[i - 1]->s.jt = s[i] = new_stmt(BPF_MISC|BPF_TXA); + i++; + /* A += 1 */ + s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); + s[i]->s.k = 1; + i++; + /* X = A */ + s[i] = new_stmt(BPF_MISC|BPF_TAX); i++; /* A = P[X + packet head] */ s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); @@ -1827,7 +2158,6 @@ gen_protochain(v, proto, dir) b->stmts = s[1]; /*remember, s[0] is dummy*/ b->s.k = v; - free_reg(reg1); free_reg(reg2); gen_and(b0, b); @@ -1866,6 +2196,12 @@ gen_proto(v, proto, dir) gen_and(b0, b1); return b1; + case Q_ISO: + b0 = gen_linktype(LLC_ISO_LSAP); + b1 = gen_cmp(off_nl + 3, BPF_B, (long)v); + gen_and(b0, b1); + return b1; + case Q_ARP: bpf_error("arp does not encapsulate another protocol"); /* NOTREACHED */ @@ -1962,8 +2298,10 @@ gen_scode(name, q) int dir = q.dir; int tproto; u_char *eaddr; - bpf_u_int32 mask, addr, **alist; -#ifdef INET6 + bpf_u_int32 mask, addr; +#ifndef INET6 + bpf_u_int32 **alist; +#else int tproto6; struct sockaddr_in *sin; struct sockaddr_in6 *sin6; @@ -2006,9 +2344,16 @@ gen_scode(name, q) "unknown FDDI host '%s'", name); return gen_fhostop(eaddr, dir); + case DLT_IEEE802: + eaddr = pcap_ether_hostton(name); + if (eaddr == NULL) + bpf_error( + "unknown token ring host '%s'", name); + return gen_thostop(eaddr, dir); + default: bpf_error( - "only ethernet/FDDI supports link-level host name"); + "only ethernet/FDDI/token ring supports link-level host name"); break; } } else if (proto == Q_DECNET) { @@ -2036,7 +2381,7 @@ gen_scode(name, q) return b; #else memset(&mask128, 0xff, sizeof(mask128)); - res0 = res = pcap_nametoaddr(name); + res0 = res = pcap_nametoaddrinfo(name); if (res == NULL) bpf_error("unknown host '%s'", name); b = tmp = NULL; @@ -2290,7 +2635,7 @@ gen_mcode6(s1, s2, masklen, q) if (s2) bpf_error("no mask %s supported", s2); - res = pcap_nametoaddr(s1); + res = pcap_nametoaddrinfo(s1); if (!res) bpf_error("invalid ip6 address %s", s1); if (res->ai_next) @@ -2342,6 +2687,9 @@ gen_ecode(eaddr, q) return gen_ehostop(eaddr, (int)q.dir); if (linktype == DLT_FDDI) return gen_fhostop(eaddr, (int)q.dir); + if (linktype == DLT_IEEE802) + return gen_thostop(eaddr, (int)q.dir); + bpf_error("ethernet addresses supported only on ethernet, FDDI or token ring"); } bpf_error("ethernet address used in non-ether expression"); /* NOTREACHED */ @@ -2670,6 +3018,9 @@ gen_greater(n) return gen_len(BPF_JGE, n); } +/* + * Actually, this is less than or equal. + */ struct block * gen_less(n) int n; @@ -2739,6 +3090,8 @@ gen_broadcast(proto) return gen_ehostop(ebroadcast, Q_DST); if (linktype == DLT_FDDI) return gen_fhostop(ebroadcast, Q_DST); + if (linktype == DLT_IEEE802) + return gen_thostop(ebroadcast, Q_DST); bpf_error("not a broadcast link"); break; @@ -2786,6 +3139,10 @@ gen_multicast(proto) b0->stmts = s; return b0; } + + /* TODO - check how token ring handles multicast */ + /* if (linktype == DLT_IEEE802) ... */ + /* Link not known to support multicasts */ break; @@ -2818,9 +3175,70 @@ gen_inbound(dir) { register struct block *b0; - b0 = gen_relation(BPF_JEQ, + /* + * Only some data link types support inbound/outbound qualifiers. + */ + switch (linktype) { + case DLT_SLIP: + case DLT_PPP: + b0 = gen_relation(BPF_JEQ, gen_load(Q_LINK, gen_loadi(0), 1), gen_loadi(0), dir); + break; + + default: + bpf_error("inbound/outbound not supported on linktype %d\n", + linktype); + b0 = NULL; + /* NOTREACHED */ + } + return (b0); +} + +/* + * support IEEE 802.1Q VLAN trunk over ethernet + */ +struct block * +gen_vlan(vlan_num) + int vlan_num; +{ + static u_int orig_linktype = -1, orig_nl = -1; + struct block *b0; + + /* + * Change the offsets to point to the type and data fields within + * the VLAN packet. This is somewhat of a kludge. + */ + if (orig_nl == (u_int)-1) { + orig_linktype = off_linktype; /* save original values */ + orig_nl = off_nl; + + switch (linktype) { + + case DLT_EN10MB: + off_linktype = 16; + off_nl = 18; + break; + + default: + bpf_error("no VLAN support for data link type %d", + linktype); + /*NOTREACHED*/ + } + } + + /* check for VLAN */ + b0 = gen_cmp(orig_linktype, BPF_H, (bpf_int32)ETHERTYPE_8021Q); + + /* If a specific VLAN is requested, check VLAN id */ + if (vlan_num >= 0) { + struct block *b1; + + b1 = gen_cmp(orig_nl, BPF_H, (bpf_int32)vlan_num); + gen_and(b0, b1); + b0 = b1; + } + return (b0); } diff --git a/contrib/libpcap/gencode.h b/contrib/libpcap/gencode.h index de80dfc..589c623 100644 --- a/contrib/libpcap/gencode.h +++ b/contrib/libpcap/gencode.h @@ -18,12 +18,9 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.37 1999/10/19 15:18:29 itojun Exp $ (LBL) + * @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.47 2000/11/04 10:09:55 guy Exp $ (LBL) */ -/*XXX*/ -#include "gnuc.h" - /* Address qualifiers. */ #define Q_HOST 1 @@ -61,6 +58,13 @@ #define Q_PIM 20 +#define Q_AARP 21 + +#define Q_ISO 22 +#define Q_ESIS 23 +#define Q_ISIS 24 +#define Q_CLNP 25 + /* Directional qualifiers. */ #define Q_SRC 1 @@ -176,11 +180,14 @@ struct block *gen_broadcast(int); struct block *gen_multicast(int); struct block *gen_inbound(int); +struct block *gen_vlan(int); + void bpf_optimize(struct block **); -#if __STDC__ -__dead void bpf_error(const char *, ...) - __attribute__((volatile, format (printf, 1, 2))); +void bpf_error(const char *, ...) +#if HAVE___ATTRIBUTE__ + __attribute__((noreturn, format (printf, 1, 2))) #endif +; void finish_parse(struct block *); char *sdup(const char *); @@ -188,6 +195,7 @@ char *sdup(const char *); struct bpf_insn *icode_to_fcode(struct block *, int *); int pcap_parse(void); void lex_init(char *); +void lex_cleanup(void); void sappend(struct slist *, struct slist *); /* XXX */ diff --git a/contrib/libpcap/grammar.y b/contrib/libpcap/grammar.y index 104056f..570d571 100644 --- a/contrib/libpcap/grammar.y +++ b/contrib/libpcap/grammar.y @@ -22,12 +22,17 @@ */ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.57 1999/10/19 15:18:30 itojun Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.64 2000/10/28 10:18:40 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" #endif #include <sys/types.h> #include <sys/time.h> #include <sys/socket.h> +#include <stdlib.h> #if __STDC__ struct mbuf; @@ -37,7 +42,6 @@ struct rtentry; #include <net/if.h> #include <netinet/in.h> -#include <netinet/if_ether.h> #include <stdio.h> @@ -46,7 +50,6 @@ struct rtentry; #include "gencode.h" #include <pcap-namedb.h> -#include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif @@ -104,7 +107,7 @@ pcap_parse() %token DST SRC HOST GATEWAY %token NET MASK PORT LESS GREATER PROTO PROTOCHAIN BYTE %token ARP RARP IP TCP UDP ICMP IGMP IGRP PIM -%token ATALK DECNET LAT SCA MOPRC MOPDL +%token ATALK AARP DECNET LAT SCA MOPRC MOPDL %token TK_BROADCAST TK_MULTICAST %token NUM INBOUND OUTBOUND %token LINK @@ -113,6 +116,8 @@ pcap_parse() %token LSH RSH %token LEN %token IPV6 ICMPV6 AH ESP +%token VLAN +%token ISO ESIS ISIS CLNP %type <s> ID %type <e> EID @@ -159,14 +164,7 @@ nid: ID { $$.b = gen_scode($1, $$.q = $<blk>0.q); } | HID { /* Decide how to parse HID based on proto */ $$.q = $<blk>0.q; - switch ($$.q.proto) { - case Q_DECNET: - $$.b = gen_ncode($1, 0, $$.q); - break; - default: - $$.b = gen_ncode($1, 0, $$.q); - break; - } + $$.b = gen_ncode($1, 0, $$.q); } | HID6 '/' NUM { #ifdef INET6 @@ -251,6 +249,7 @@ pname: LINK { $$ = Q_LINK; } | IGRP { $$ = Q_IGRP; } | PIM { $$ = Q_PIM; } | ATALK { $$ = Q_ATALK; } + | AARP { $$ = Q_AARP; } | DECNET { $$ = Q_DECNET; } | LAT { $$ = Q_LAT; } | SCA { $$ = Q_SCA; } @@ -260,6 +259,10 @@ pname: LINK { $$ = Q_LINK; } | ICMPV6 { $$ = Q_ICMPV6; } | AH { $$ = Q_AH; } | ESP { $$ = Q_ESP; } + | ISO { $$ = Q_ISO; } + | ESIS { $$ = Q_ESIS; } + | ISIS { $$ = Q_ISIS; } + | CLNP { $$ = Q_CLNP; } ; other: pqual TK_BROADCAST { $$ = gen_broadcast($1); } | pqual TK_MULTICAST { $$ = gen_multicast($1); } @@ -268,6 +271,8 @@ other: pqual TK_BROADCAST { $$ = gen_broadcast($1); } | BYTE NUM byteop NUM { $$ = gen_byteop($3, $2, $4); } | INBOUND { $$ = gen_inbound(0); } | OUTBOUND { $$ = gen_inbound(1); } + | VLAN pnum { $$ = gen_vlan($2); } + | VLAN { $$ = gen_vlan(-1); } ; relop: '>' { $$ = BPF_JGT; } | GEQ { $$ = BPF_JGE; } diff --git a/contrib/libpcap/inet.c b/contrib/libpcap/inet.c index feeed42..0b5b696 100644 --- a/contrib/libpcap/inet.c +++ b/contrib/libpcap/inet.c @@ -33,7 +33,11 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.26 2000/01/14 23:55:31 mcr Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.36 2000/09/20 15:10:29 torsten Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" #endif #include <sys/param.h> @@ -45,11 +49,8 @@ static const char rcsid[] = #endif #include <sys/time.h> /* concession to AIX */ -#if __STDC__ struct mbuf; struct rtentry; -#endif - #include <net/if.h> #include <netinet/in.h> @@ -60,10 +61,12 @@ struct rtentry; #include <stdlib.h> #include <string.h> #include <unistd.h> +#ifdef HAVE_IFADDRS_H +#include <ifaddrs.h> +#endif #include "pcap-int.h" -#include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif @@ -71,9 +74,12 @@ struct rtentry; /* Not all systems have IFF_LOOPBACK */ #ifdef IFF_LOOPBACK #define ISLOOPBACK(p) ((p)->ifr_flags & IFF_LOOPBACK) +#define ISLOOPBACK_IFA(p) ((p)->ifa_flags & IFF_LOOPBACK) #else #define ISLOOPBACK(p) ((p)->ifr_name[0] == 'l' && (p)->ifr_name[1] == 'o' && \ (isdigit((p)->ifr_name[2]) || (p)->ifr_name[2] == '\0')) +#define ISLOOPBACK_IFA(p) ((p)->ifa_name[0] == 'l' && (p)->ifa_name[1] == 'o' && \ + (isdigit((p)->ifa_name[2]) || (p)->ifa_name[2] == '\0')) #endif /* @@ -85,6 +91,59 @@ char * pcap_lookupdev(errbuf) register char *errbuf; { +#ifdef HAVE_IFADDRS_H + struct ifaddrs *ifap, *ifa, *mp; + int n, minunit; + char *cp; + static char device[IF_NAMESIZE + 1]; + + if (getifaddrs(&ifap) != 0) { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "getifaddrs: %s", pcap_strerror(errno)); + return NULL; + } + + mp = NULL; + minunit = 666; + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { + const char *endcp; + + if ((ifa->ifa_flags & IFF_UP) == 0 || ISLOOPBACK_IFA(ifa)) + continue; + + endcp = ifa->ifa_name + strlen(ifa->ifa_name); + for (cp = ifa->ifa_name; cp < endcp && !isdigit(*cp); ++cp) + continue; + + if (isdigit (*cp)) { + n = atoi(cp); + } else { + n = 0; + } + if (n < minunit) { + minunit = n; + mp = ifa; + } + } + if (mp == NULL) { + (void)strlcpy(errbuf, "no suitable device found", + PCAP_ERRBUF_SIZE); +#ifdef HAVE_FREEIFADDRS + freeifaddrs(ifap); +#else + free(ifap); +#endif + return (NULL); + } + + (void)strlcpy(device, mp->ifa_name, sizeof(device)); +#ifdef HAVE_FREEIFADDRS + freeifaddrs(ifap); +#else + free(ifap); +#endif + return (device); +#else register int fd, minunit, n; register char *cp; register struct ifreq *ifrp, *ifend, *ifnext, *mp; @@ -96,7 +155,8 @@ pcap_lookupdev(errbuf) fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { - (void)sprintf(errbuf, "socket: %s", pcap_strerror(errno)); + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "socket: %s", pcap_strerror(errno)); return (NULL); } @@ -106,17 +166,19 @@ pcap_lookupdev(errbuf) buf = malloc (buf_size); if (buf == NULL) { close (fd); - (void)sprintf(errbuf, "out of memory"); + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "out of memory"); return (NULL); } ifc.ifc_len = buf_size; ifc.ifc_buf = buf; memset (buf, 0, buf_size); - if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0) { + if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0 + && errno != EINVAL) { free (buf); - (void)sprintf(errbuf, "SIOCGIFCONF: %s", - pcap_strerror(errno)); + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "SIOCGIFCONF: %s", pcap_strerror(errno)); (void)close(fd); return (NULL); } @@ -132,6 +194,8 @@ pcap_lookupdev(errbuf) mp = NULL; minunit = 666; for (; ifrp < ifend; ifrp = ifnext) { + const char *endcp; + #ifdef HAVE_SOCKADDR_SA_LEN n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name); if (n < sizeof(*ifrp)) @@ -153,7 +217,8 @@ pcap_lookupdev(errbuf) if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) { if (errno == ENXIO) continue; - (void)sprintf(errbuf, "SIOCGIFFLAGS: %.*s: %s", + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "SIOCGIFFLAGS: %.*s: %s", (int)sizeof(ifr.ifr_name), ifr.ifr_name, pcap_strerror(errno)); (void)close(fd); @@ -165,9 +230,15 @@ pcap_lookupdev(errbuf) if ((ifr.ifr_flags & IFF_UP) == 0 || ISLOOPBACK(&ifr)) continue; - for (cp = ifrp->ifr_name; !isdigit(*cp); ++cp) + endcp = ifrp->ifr_name + strlen(ifrp->ifr_name); + for (cp = ifrp->ifr_name; cp < endcp && !isdigit(*cp); ++cp) continue; - n = atoi(cp); + + if (isdigit (*cp)) { + n = atoi(cp); + } else { + n = 0; + } if (n < minunit) { minunit = n; mp = ifrp; @@ -175,15 +246,16 @@ pcap_lookupdev(errbuf) } (void)close(fd); if (mp == NULL) { - (void)strcpy(errbuf, "no suitable device found"); + (void)strlcpy(errbuf, "no suitable device found", + PCAP_ERRBUF_SIZE); free(buf); return (NULL); } - (void)strncpy(device, mp->ifr_name, sizeof(device) - 1); - device[sizeof(device) - 1] = '\0'; + (void)strlcpy(device, mp->ifr_name, sizeof(device)); free(buf); return (device); +#endif } int @@ -196,9 +268,20 @@ pcap_lookupnet(device, netp, maskp, errbuf) register struct sockaddr_in *sin; struct ifreq ifr; + /* + * The pseudo-device "any" listens on all interfaces and therefore + * 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) { + *netp = *maskp = 0; + return 0; + } + fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { - (void)sprintf(errbuf, "socket: %s", pcap_strerror(errno)); + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "socket: %s", + pcap_strerror(errno)); return (-1); } memset(&ifr, 0, sizeof(ifr)); @@ -209,10 +292,11 @@ pcap_lookupnet(device, netp, maskp, errbuf) (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) { if (errno == EADDRNOTAVAIL) { - (void)sprintf(errbuf, "%s: no IPv4 address assigned", - device); + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "%s: no IPv4 address assigned", device); } else { - (void)sprintf(errbuf, "SIOCGIFADDR: %s: %s", + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "SIOCGIFADDR: %s: %s", device, pcap_strerror(errno)); } (void)close(fd); @@ -221,8 +305,8 @@ pcap_lookupnet(device, netp, maskp, errbuf) sin = (struct sockaddr_in *)&ifr.ifr_addr; *netp = sin->sin_addr.s_addr; if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) { - (void)sprintf(errbuf, "SIOCGIFNETMASK: %s: %s", - device, pcap_strerror(errno)); + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "SIOCGIFNETMASK: %s: %s", device, pcap_strerror(errno)); (void)close(fd); return (-1); } @@ -236,8 +320,8 @@ pcap_lookupnet(device, netp, maskp, errbuf) else if (IN_CLASSC(*netp)) *maskp = IN_CLASSC_NET; else { - (void)sprintf(errbuf, "inet class for 0x%x unknown", - *netp); + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + "inet class for 0x%x unknown", *netp); return (-1); } } diff --git a/contrib/libpcap/lbl/os-osf4.h b/contrib/libpcap/lbl/os-osf4.h new file mode 100644 index 0000000..abb207e --- /dev/null +++ b/contrib/libpcap/lbl/os-osf4.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (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. + * + * @(#) $Header: /tcpdump/master/libpcap/lbl/os-osf4.h,v 1.2 2000/12/22 11:51:33 guy Exp $ (LBL) + */ + +/* Prototypes missing in Digital UNIX 4.x */ +int snprintf(char *, size_t, const char *, ...); +int vsnprintf(char *, size_t, const char *, va_list); +int pfopen(char *, int); + diff --git a/contrib/libpcap/lbl/os-solaris2.h b/contrib/libpcap/lbl/os-solaris2.h index e6d1273..5de2c6e 100644 --- a/contrib/libpcap/lbl/os-solaris2.h +++ b/contrib/libpcap/lbl/os-solaris2.h @@ -18,37 +18,9 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: /tcpdump/master/libpcap/lbl/os-solaris2.h,v 1.18.1.1 1999/10/07 23:46:41 mcr Exp $ (LBL) + * @(#) $Header: /tcpdump/master/libpcap/lbl/os-solaris2.h,v 1.19 2000/10/11 04:02:52 guy Exp $ (LBL) */ /* Prototypes missing in SunOS 5 */ -int daemon(int, int); -int dn_expand(const u_char *, const u_char *, const u_char *, char *, int); -int dn_skipname(const u_char *, const u_char *); -int flock(int, int); -int getdtablesize(void); -int gethostname(char *, int); -int getpagesize(void); -char *getusershell(void); -char *getwd(char *); -int iruserok(u_int, int, char *, char *); -#ifdef __STDC__ -struct utmp; -void login(struct utmp *); -#endif -int logout(const char *); -int res_query(const char *, int, int, u_char *, int); -int setenv(const char *, const char *, int); -#if defined(_STDIO_H) && defined(HAVE_SETLINEBUF) -int setlinebuf(FILE *); -#endif -int sigblock(int); -int sigsetmask(int); char *strerror(int); int snprintf(char *, size_t, const char *, ...); -int strcasecmp(const char *, const char *); -void unsetenv(const char *); -#ifdef __STDC__ -struct timeval; -#endif -int utimes(const char *, struct timeval *); diff --git a/contrib/libpcap/llc.h b/contrib/libpcap/llc.h new file mode 100644 index 0000000..2800315 --- /dev/null +++ b/contrib/libpcap/llc.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 1993, 1994, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (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. + * + * @(#) $Header: /tcpdump/master/libpcap/llc.h,v 1.1 2001/01/14 21:26:53 guy Exp $ (LBL) + */ + +/* + * 802.2 LLC SAP values. + */ + +#ifndef LLCSAP_NULL +#define LLCSAP_NULL 0x00 +#endif +#ifndef LLCSAP_GLOBAL +#define LLCSAP_GLOBAL 0xff +#endif +#ifndef LLCSAP_8021B +#define LLCSAP_8021B_I 0x02 +#endif +#ifndef LLCSAP_8021B +#define LLCSAP_8021B_G 0x03 +#endif +#ifndef LLCSAP_IP +#define LLCSAP_IP 0x06 +#endif +#ifndef LLCSAP_PROWAYNM +#define LLCSAP_PROWAYNM 0x0e +#endif +#ifndef LLCSAP_8021D +#define LLCSAP_8021D 0x42 +#endif +#ifndef LLCSAP_RS511 +#define LLCSAP_RS511 0x4e +#endif +#ifndef LLCSAP_ISO8208 +#define LLCSAP_ISO8208 0x7e +#endif +#ifndef LLCSAP_PROWAY +#define LLCSAP_PROWAY 0x8e +#endif +#ifndef LLCSAP_SNAP +#define LLCSAP_SNAP 0xaa +#endif +#ifndef LLCSAP_ISONS +#define LLCSAP_ISONS 0xfe +#endif +#ifndef LLCSAP_IPX +#define LLCSAP_IPX 0xe0 +#endif diff --git a/contrib/libpcap/nametoaddr.c b/contrib/libpcap/nametoaddr.c index 3a5e3b6..e3c0ca5 100644 --- a/contrib/libpcap/nametoaddr.c +++ b/contrib/libpcap/nametoaddr.c @@ -24,7 +24,11 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.51 1999/11/25 08:25:35 itojun Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.57.2.1 2001/01/17 18:21:56 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" #endif #include <sys/param.h> @@ -32,14 +36,13 @@ static const char rcsid[] = #include <sys/socket.h> #include <sys/time.h> -#if __STDC__ struct mbuf; struct rtentry; -#endif - #include <net/if.h> #include <netinet/in.h> +#ifdef HAVE_NETINET_IF_ETHER_H #include <netinet/if_ether.h> +#endif #include <arpa/inet.h> #ifdef INET6 #include <netdb.h> @@ -58,7 +61,6 @@ struct rtentry; #include "gencode.h" #include <pcap-namedb.h> -#include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif @@ -74,7 +76,6 @@ static inline int xdtoi(int); * Convert host name to internet address. * Return 0 upon failure. */ -#ifndef INET6 bpf_u_int32 ** pcap_nametoaddr(const char *name) { @@ -98,9 +99,10 @@ pcap_nametoaddr(const char *name) else return 0; } -#else + +#ifdef INET6 struct addrinfo * -pcap_nametoaddr(const char *name) +pcap_nametoaddrinfo(const char *name) { struct addrinfo hints, *res; int error; @@ -329,7 +331,7 @@ pcap_ether_hostton(const char *name) register struct pcap_etherent *ep; register u_char *ap; static FILE *fp = NULL; - static init = 0; + static int init = 0; if (!init) { fp = fopen(PCAP_ETHERS_FILE, "r"); @@ -355,7 +357,16 @@ pcap_ether_hostton(const char *name) } #else -#if !defined(sgi) && !defined(__NetBSD__) +/* + * XXX - perhaps this should, instead, be declared in "lbl/os-XXX.h" files, + * for those OS versions that don't declare it, rather than being declared + * here? That way, for example, we could declare it on FreeBSD 2.x (which + * doesn't declare it), but not on FreeBSD 3.x (which declares it like + * this) or FreeBSD 4.x (which declares it with its first argument as + * "const char *", so no matter how we declare it here, it'll fail to + * compile on one of 3.x or 4.x). + */ +#if !defined(sgi) && !defined(__NetBSD__) && !defined(__FreeBSD__) extern int ether_hostton(char *, struct ether_addr *); #endif diff --git a/contrib/libpcap/nlpid.h b/contrib/libpcap/nlpid.h index c033da2..ef869da 100644 --- a/contrib/libpcap/nlpid.h +++ b/contrib/libpcap/nlpid.h @@ -15,7 +15,7 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header$ (Juniper) + * @(#) $Header: /tcpdump/master/libpcap/nlpid.h,v 1.1 2000/10/28 09:30:22 guy Exp $ (Juniper) */ /* Types missing from some systems */ diff --git a/contrib/libpcap/optimize.c b/contrib/libpcap/optimize.c index 928cc1c..bb3b6c9 100644 --- a/contrib/libpcap/optimize.c +++ b/contrib/libpcap/optimize.c @@ -22,7 +22,11 @@ */ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/optimize.c,v 1.61 1999/10/19 15:18:30 itojun Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/optimize.c,v 1.67 2000/11/19 13:37:20 itojun Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" #endif #include <sys/types.h> @@ -32,11 +36,12 @@ static const char rcsid[] = #include <stdlib.h> #include <memory.h> +#include <errno.h> + #include "pcap-int.h" #include "gencode.h" -#include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif @@ -1481,6 +1486,8 @@ opt_blks(root, do_stmts) init_val(); maxlevel = root->level; + + find_inedges(root); for (i = maxlevel; i >= 0; --i) for (p = levels[i]; p; p = p->link) opt_blk(p, do_stmts); @@ -1498,6 +1505,8 @@ opt_blks(root, do_stmts) opt_j(&p->ef); } } + + find_inedges(root); for (i = 1; i <= maxlevel; ++i) { for (p = levels[i]; p; p = p->link) { or_pullup(p); @@ -1577,7 +1586,6 @@ opt_loop(root, do_stmts) find_levels(root); find_dom(root); find_closure(root); - find_inedges(root); find_ud(root); find_edom(root); opt_blks(root, do_stmts); @@ -1777,6 +1785,20 @@ number_blks_r(p) /* * Return the number of stmts in the flowgraph reachable by 'p'. * The nodes should be unmarked before calling. + * + * Note that "stmts" means "instructions", and that this includes + * + * side-effect statements in 'p' (slength(p->stmts)); + * + * statements in the true branch from 'p' (count_stmts(JT(p))); + * + * statements in the false branch from 'p' (count_stmts(JF(p))); + * + * the conditional jump itself (1); + * + * an extra long jump if the true branch requires it (p->longjt); + * + * an extra long jump if the false branch requires it (p->longjf). */ static int count_stmts(p) @@ -1788,7 +1810,7 @@ count_stmts(p) return 0; Mark(p); n = count_stmts(JT(p)) + count_stmts(JF(p)); - return slength(p->stmts) + n + 1; + return slength(p->stmts) + n + 1 + p->longjt + p->longjf; } /* @@ -1864,7 +1886,7 @@ opt_init(root) */ maxval = 3 * max_stmts; vmap = (struct vmapinfo *)malloc(maxval * sizeof(*vmap)); - vnode_base = (struct valnode *)malloc(maxval * sizeof(*vmap)); + vnode_base = (struct valnode *)malloc(maxval * sizeof(*vnode_base)); } /* @@ -1936,7 +1958,7 @@ convert_code_r(p) dst->k = src->s.k; /* fill block-local relative jump */ - if (BPF_CLASS(src->s.code) != BPF_JMP || src->s.code == BPF_JMP|BPF_JA) { + if (BPF_CLASS(src->s.code) != BPF_JMP || src->s.code == (BPF_JMP|BPF_JA)) { #if 0 if (src->s.jt || src->s.jf) { bpf_error("illegal jmp destination"); @@ -2074,6 +2096,36 @@ icode_to_fcode(root, lenp) return fp; } +/* + * Make a copy of a BPF program and put it in the "fcode" member of + * a "pcap_t". + * + * If we fail to allocate memory for the copy, fill in the "errbuf" + * member of the "pcap_t" with an error message, and return -1; + * otherwise, return 0. + */ +int +install_bpf_program(pcap_t *p, struct bpf_program *fp) +{ + size_t prog_size; + + /* + * Free up any already installed program. + */ + pcap_freecode(&p->fcode); + + prog_size = sizeof(*fp->bf_insns) * fp->bf_len; + p->fcode.bf_len = fp->bf_len; + p->fcode.bf_insns = (struct bpf_insn *)malloc(prog_size); + if (p->fcode.bf_insns == NULL) { + snprintf(p->errbuf, sizeof(p->errbuf), + "malloc: %s", pcap_strerror(errno)); + return (-1); + } + memcpy(p->fcode.bf_insns, fp->bf_insns, prog_size); + return (0); +} + #ifdef BDEBUG static void opt_dump(root) diff --git a/contrib/libpcap/pcap-bpf.c b/contrib/libpcap/pcap-bpf.c index 9c9a554..fc56365 100644 --- a/contrib/libpcap/pcap-bpf.c +++ b/contrib/libpcap/pcap-bpf.c @@ -20,7 +20,11 @@ */ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.32 1999/10/19 15:18:30 itojun Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.44 2000/10/28 00:01:28 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" #endif #include <sys/param.h> /* optionally get BSD define */ @@ -42,7 +46,6 @@ static const char rcsid[] = #include "pcap-int.h" -#include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif @@ -55,7 +58,8 @@ pcap_stats(pcap_t *p, struct pcap_stat *ps) struct bpf_stat s; if (ioctl(p->fd, BIOCGSTATS, (caddr_t)&s) < 0) { - sprintf(p->errbuf, "BIOCGSTATS: %s", pcap_strerror(errno)); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGSTATS: %s", + pcap_strerror(errno)); return (-1); } @@ -99,7 +103,8 @@ pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) /* fall through */ #endif } - sprintf(p->errbuf, "read: %s", pcap_strerror(errno)); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read: %s", + pcap_strerror(errno)); return (-1); } bp = p->buffer; @@ -136,13 +141,13 @@ bpf_open(pcap_t *p, char *errbuf) { int fd; int n = 0; - char device[sizeof "/dev/bpf000"]; + char device[sizeof "/dev/bpf0000000000"]; /* * Go through all the minors and find one that isn't in use. */ do { - (void)sprintf(device, "/dev/bpf%d", n++); + (void)snprintf(device, sizeof(device), "/dev/bpf%d", n++); fd = open(device, O_RDONLY); } while (fd < 0 && errno == EBUSY); @@ -150,7 +155,8 @@ bpf_open(pcap_t *p, char *errbuf) * XXX better message for all minors used */ if (fd < 0) - sprintf(errbuf, "%s: %s", device, pcap_strerror(errno)); + snprintf(errbuf, PCAP_ERRBUF_SIZE, "(no devices found) %s: %s", + device, pcap_strerror(errno)); return (fd); } @@ -166,10 +172,11 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) p = (pcap_t *)malloc(sizeof(*p)); if (p == NULL) { - sprintf(ebuf, "malloc: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", + pcap_strerror(errno)); return (NULL); } - bzero(p, sizeof(*p)); + memset(p, 0, sizeof(*p)); fd = bpf_open(p, ebuf); if (fd < 0) goto bad; @@ -178,35 +185,65 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) p->snapshot = snaplen; if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) { - sprintf(ebuf, "BIOCVERSION: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCVERSION: %s", + pcap_strerror(errno)); goto bad; } if (bv.bv_major != BPF_MAJOR_VERSION || bv.bv_minor < BPF_MINOR_VERSION) { - sprintf(ebuf, "kernel bpf filter out of date"); + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "kernel bpf filter out of date"); goto bad; } - v = 32768; /* XXX this should be a user-accessible hook */ - /* Ignore the return value - this is because the call fails on - * BPF systems that don't have kernel malloc. And if the call - * fails, it's no big deal, we just continue to use the standard - * buffer size. + + /* + * Try finding a good size for the buffer; 32768 may be too + * big, so keep cutting it in half until we find a size + * that works, or run out of sizes to try. + * + * XXX - there should be a user-accessible hook to set the + * initial buffer size. */ - (void) ioctl(fd, BIOCSBLEN, (caddr_t)&v); + for (v = 32768; v != 0; v >>= 1) { + /* Ignore the return value - this is because the call fails + * on BPF systems that don't have kernel malloc. And if + * the call fails, it's no big deal, we just continue to + * use the standard buffer size. + */ + (void) ioctl(fd, BIOCSBLEN, (caddr_t)&v); + + (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); + if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) >= 0) + break; /* that size worked; we're done */ - (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); - if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0) { - sprintf(ebuf, "%s: %s", device, pcap_strerror(errno)); + if (errno != ENOBUFS) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSETIF: %s: %s", + device, pcap_strerror(errno)); + goto bad; + } + } + + if (v == 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "BIOCSBLEN: %s: No buffer size worked", device); goto bad; } + /* Get the data link layer type. */ if (ioctl(fd, BIOCGDLT, (caddr_t)&v) < 0) { - sprintf(ebuf, "BIOCGDLT: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGDLT: %s", + pcap_strerror(errno)); goto bad; } #ifdef __OpenBSD__ switch (v) { case DLT_LOOP: + /* + * XXX - DLT_LOOP has a network-byte-order, rather than + * a host-byte-order, AF_ value as the link-layer + * header; will the BPF code generator handle that + * correctly on little-endian machines? + */ v = DLT_NULL; break; } @@ -240,23 +277,83 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) to.tv_sec = to_ms / 1000; to.tv_usec = (to_ms * 1000) % 1000000; if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&to) < 0) { - sprintf(ebuf, "BIOCSRTIMEOUT: %s", - pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSRTIMEOUT: %s", + pcap_strerror(errno)); goto bad; } } + +#ifdef _AIX +#ifdef BIOCIMMEDIATE + /* + * Darren Reed notes that + * + * On AIX (4.2 at least), if BIOCIMMEDIATE is not set, the + * timeout appears to be ignored and it waits until the buffer + * is filled before returning. The result of not having it + * set is almost worse than useless if your BPF filter + * is reducing things to only a few packets (i.e. one every + * second or so). + * + * so we turn BIOCIMMEDIATE mode on if this is AIX. + * + * We don't turn it on for other platforms, as that means we + * get woken up for every packet, which may not be what we want; + * in the Winter 1993 USENIX paper on BPF, they say: + * + * Since a process might want to look at every packet on a + * network and the time between packets can be only a few + * microseconds, it is not possible to do a read system call + * per packet and BPF must collect the data from several + * packets and return it as a unit when the monitoring + * application does a read. + * + * which I infer is the reason for the timeout - it means we + * wait that amount of time, in the hopes that more packets + * will arrive and we'll get them all with one read. + * + * Setting BIOCIMMEDIATE mode on FreeBSD (and probably other + * BSDs) causes the timeout to be ignored. + * + * On the other hand, some platforms (e.g., Linux) don't support + * timeouts, they just hand stuff to you as soon as it arrives; + * if that doesn't cause a problem on those platforms, it may + * be OK to have BIOCIMMEDIATE mode on BSD as well. + * + * (Note, though, that applications may depend on the read + * completing, even if no packets have arrived, when the timeout + * expires, e.g. GUI applications that have to check for input + * while waiting for packets to arrive; a non-zero timeout + * prevents "select()" from working right on FreeBSD and + * possibly other BSDs, as the timer doesn't start until a + * "read()" is done, so the timer isn't in effect if the + * application is blocked on a "select()", and the "select()" + * doesn't get woken up for a BPF device until the buffer + * fills up.) + */ + v = 1; + if (ioctl(p->fd, BIOCIMMEDIATE, &v) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCIMMEDIATE: %s", + pcap_strerror(errno)); + goto bad; + } +#endif /* BIOCIMMEDIATE */ +#endif /* _AIX */ + if (promisc) /* set promiscuous mode, okay if it fails */ (void)ioctl(p->fd, BIOCPROMISC, NULL); if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) { - sprintf(ebuf, "BIOCGBLEN: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGBLEN: %s", + pcap_strerror(errno)); goto bad; } p->bufsize = v; p->buffer = (u_char *)malloc(p->bufsize); if (p->buffer == NULL) { - sprintf(ebuf, "malloc: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", + pcap_strerror(errno)); goto bad; } @@ -275,12 +372,15 @@ pcap_setfilter(pcap_t *p, struct bpf_program *fp) * compatible with some of kernel BPF code (for example BSD/OS 3.1). * Take a safer side for now. */ - if (no_optimize) - p->fcode = *fp; - else if (p->sf.rfile != NULL) - p->fcode = *fp; - else if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) { - sprintf(p->errbuf, "BIOCSETF: %s", pcap_strerror(errno)); + if (no_optimize) { + if (install_bpf_program(p, fp) < 0) + return (-1); + } else if (p->sf.rfile != NULL) { + if (install_bpf_program(p, fp) < 0) + return (-1); + } else if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s", + pcap_strerror(errno)); return (-1); } return (0); diff --git a/contrib/libpcap/pcap-dlpi.c b/contrib/libpcap/pcap-dlpi.c index 4692b9c..1a152bc 100644 --- a/contrib/libpcap/pcap-dlpi.c +++ b/contrib/libpcap/pcap-dlpi.c @@ -38,7 +38,11 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.52.1.1 1999/10/07 23:46:40 mcr Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.63 2000/11/22 05:32:55 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" #endif #include <sys/types.h> @@ -80,7 +84,6 @@ static const char rcsid[] = #include "pcap-int.h" -#include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif @@ -159,7 +162,8 @@ pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) cc = 0; continue; } - strcpy(p->errbuf, pcap_strerror(errno)); + strlcpy(p->errbuf, pcap_strerror(errno), + sizeof(p->errbuf)); return (-1); } cc = data.len; @@ -241,54 +245,101 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) p = (pcap_t *)malloc(sizeof(*p)); if (p == NULL) { - strcpy(ebuf, pcap_strerror(errno)); + strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); return (NULL); } memset(p, 0, sizeof(*p)); +#ifdef HAVE_DEV_DLPI /* - ** Determine device and ppa + ** Remove any "/dev/" on the front of the device. */ - cp = strpbrk(device, "0123456789"); + cp = strrchr(device, '/'); + if (cp == NULL) + cp = device; + else + cp++; + strlcpy(dname, cp, sizeof(dname)); + + /* + * Split the name into a device type and a unit number. + */ + cp = strpbrk(dname, "0123456789"); if (cp == NULL) { - sprintf(ebuf, "%s missing unit number", device); + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "%s missing unit number", device); goto bad; } ppa = strtol(cp, &eos, 10); if (*eos != '\0') { - sprintf(ebuf, "%s bad unit number", device); + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "%s bad unit number", device); goto bad; } + *cp = '\0'; - if (*device == '/') - strcpy(dname, device); - else - sprintf(dname, "%s/%s", PCAP_DEV_PREFIX, device); -#ifdef HAVE_DEV_DLPI - /* Map network device to /dev/dlpi unit */ + /* + * Use "/dev/dlpi" as the device. + * + * XXX - HP's DLPI Programmer's Guide for HP-UX 11.00 says that + * the "dl_mjr_num" field is for the "major number of interface + * driver"; that's the major of "/dev/dlpi" on the system on + * which I tried this, but there may be DLPI devices that + * use a different driver, in which case we may need to + * search "/dev" for the appropriate device with that major + * device number, rather than hardwiring "/dev/dlpi". + */ cp = "/dev/dlpi"; if ((p->fd = open(cp, O_RDWR)) < 0) { - sprintf(ebuf, "%s: %s", cp, pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "%s: %s", cp, pcap_strerror(errno)); goto bad; } - /* Map network interface to /dev/dlpi unit */ + + /* + * Get a table of all PPAs for that device, and search that + * table for the specified device type name and unit number. + */ ppa = get_dlpi_ppa(p->fd, dname, ppa, ebuf); if (ppa < 0) goto bad; #else + /* + ** Determine device and ppa + */ + cp = strpbrk(device, "0123456789"); + if (cp == NULL) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s missing unit number", + device); + goto bad; + } + ppa = strtol(cp, &eos, 10); + if (*eos != '\0') { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s bad unit number", device); + goto bad; + } + + if (*device == '/') + strlcpy(dname, device, sizeof(dname)); + else + snprintf(dname, sizeof(dname), "%s/%s", PCAP_DEV_PREFIX, + device); + /* Try device without unit number */ - strcpy(dname2, dname); + strlcpy(dname2, dname, sizeof(dname2)); cp = strchr(dname, *cp); *cp = '\0'; if ((p->fd = open(dname, O_RDWR)) < 0) { if (errno != ENOENT) { - sprintf(ebuf, "%s: %s", dname, pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s", dname, + pcap_strerror(errno)); goto bad; } /* Try again with unit number */ if ((p->fd = open(dname2, O_RDWR)) < 0) { - sprintf(ebuf, "%s: %s", dname2, pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s", dname2, + pcap_strerror(errno)); goto bad; } /* XXX Assume unit zero */ @@ -314,7 +365,14 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) ** using SINIX) */ #if !defined(HAVE_HPUX9) && !defined(HAVE_HPUX10_20) && !defined(sinix) +#ifdef _AIX + /* According to IBM's AIX Support Line, the dl_sap value + ** should not be less than 0x600 (1536) for standard ethernet + */ + if (dlbindreq(p->fd, 1537, ebuf) < 0 || +#else if (dlbindreq(p->fd, 0, ebuf) < 0 || +#endif dlbindack(p->fd, (char *)buf, ebuf) < 0) goto bad; #endif @@ -391,7 +449,8 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) break; default: - sprintf(ebuf, "unknown mac type 0x%lu", infop->dl_mac_type); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown mac type %lu", + infop->dl_mac_type); goto bad; } @@ -400,7 +459,8 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) ** This is a non standard SunOS hack to get the ethernet header. */ if (strioctl(p->fd, DLIOCRAW, 0, NULL) < 0) { - sprintf(ebuf, "DLIOCRAW: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "DLIOCRAW: %s", + pcap_strerror(errno)); goto bad; } #endif @@ -410,7 +470,8 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) ** Another non standard call to get the data nicely buffered */ if (ioctl(p->fd, I_PUSH, "bufmod") != 0) { - sprintf(ebuf, "I_PUSH bufmod: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "I_PUSH bufmod: %s", + pcap_strerror(errno)); goto bad; } @@ -437,7 +498,8 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) #endif if (ss > 0 && strioctl(p->fd, SBIOCSSNAP, sizeof(ss), (char *)&ss) != 0) { - sprintf(ebuf, "SBIOCSSNAP: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "SBIOCSSNAP: %s", + pcap_strerror(errno)); goto bad; } @@ -445,12 +507,14 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) ** Set up the bufmod flags */ if (strioctl(p->fd, SBIOCGFLAGS, sizeof(flag), (char *)&flag) < 0) { - sprintf(ebuf, "SBIOCGFLAGS: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "SBIOCGFLAGS: %s", + pcap_strerror(errno)); goto bad; } flag |= SB_NO_DROPS; if (strioctl(p->fd, SBIOCSFLAGS, sizeof(flag), (char *)&flag) != 0) { - sprintf(ebuf, "SBIOCSFLAGS: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "SBIOCSFLAGS: %s", + pcap_strerror(errno)); goto bad; } /* @@ -462,7 +526,8 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) to.tv_sec = to_ms / 1000; to.tv_usec = (to_ms * 1000) % 1000000; if (strioctl(p->fd, SBIOCSTIME, sizeof(to), (char *)&to) != 0) { - sprintf(ebuf, "SBIOCSTIME: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "SBIOCSTIME: %s", + pcap_strerror(errno)); goto bad; } } @@ -472,7 +537,8 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) ** As the last operation flush the read side. */ if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) { - sprintf(ebuf, "FLUSHR: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s", + pcap_strerror(errno)); goto bad; } /* Allocate data buffer */ @@ -489,7 +555,8 @@ int pcap_setfilter(pcap_t *p, struct bpf_program *fp) { - p->fcode = *fp; + if (install_bpf_program(p, fp) < 0) + return (-1); return (0); } @@ -505,7 +572,8 @@ send_request(int fd, char *ptr, int len, char *what, char *ebuf) flags = 0; if (putmsg(fd, &ctl, (struct strbuf *) NULL, flags) < 0) { - sprintf(ebuf, "send_request: putmsg \"%s\": %s", + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "send_request: putmsg \"%s\": %s", what, pcap_strerror(errno)); return (-1); } @@ -525,7 +593,7 @@ recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf) flags = 0; if (getmsg(fd, &ctl, (struct strbuf*)NULL, &flags) < 0) { - sprintf(ebuf, "recv_ack: %s getmsg: %s", + snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s getmsg: %s", what, pcap_strerror(errno)); return (-1); } @@ -547,37 +615,40 @@ recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf) switch (dlp->error_ack.dl_errno) { case DL_BADPPA: - sprintf(ebuf, "recv_ack: %s bad ppa (device unit)", - what); + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "recv_ack: %s bad ppa (device unit)", what); break; case DL_SYSERR: - sprintf(ebuf, "recv_ack: %s: %s", + snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s: %s", what, pcap_strerror(dlp->error_ack.dl_unix_errno)); break; case DL_UNSUPPORTED: - sprintf(ebuf, + snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s: Service not supplied by provider", what); break; default: - sprintf(ebuf, "recv_ack: %s error 0x%x", + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "recv_ack: %s error 0x%x", what, (bpf_u_int32)dlp->error_ack.dl_errno); break; } return (-1); default: - sprintf(ebuf, "recv_ack: %s unexpected primitive ack 0x%x ", + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "recv_ack: %s unexpected primitive ack 0x%x ", what, (bpf_u_int32)dlp->dl_primitive); return (-1); } if (ctl.len < size) { - sprintf(ebuf, "recv_ack: %s ack too small (%d < %d)", + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "recv_ack: %s ack too small (%d < %d)", what, ctl.len, size); return (-1); } @@ -709,29 +780,57 @@ get_release(bpf_u_int32 *majorp, bpf_u_int32 *minorp, bpf_u_int32 *microp) #ifdef DL_HP_PPA_ACK_OBS /* - * Under HP-UX 10, we can ask for the ppa + * Under HP-UX 10 and HP-UX 11, we can ask for the ppa */ -/* Determine ppa number that specifies ifname */ +/* + * Determine ppa number that specifies ifname. + * + * If the "dl_hp_ppa_info_t" doesn't have a "dl_module_id_1" member, + * the code that's used here is the old code for HP-UX 10.x. + * + * However, HP-UX 10.20, at least, appears to have such a member + * in its "dl_hp_ppa_info_t" structure, so the new code is used. + * The new code didn't work on an old 10.20 system on which Rick + * Jones of HP tried it, but with later patches installed, it + * worked - it appears that the older system had those members but + * didn't put anything in them, so, if the search by name fails, we + * do the old search. + * + * Rick suggests that making sure your system is "up on the latest + * lancommon/DLPI/driver patches" is probably a good idea; it'd fix + * that problem, as well as allowing libpcap to see packets sent + * from the system on which the libpcap application is being run. + * (On 10.20, in addition to getting the latest patches, you need + * to turn the kernel "lanc_outbound_promisc_flag" flag on with ADB; + * a posting to "comp.sys.hp.hpux" at + * + * http://www.deja.com/[ST_rn=ps]/getdoc.xp?AN=558092266 + * + * says that, to see the machine's outgoing traffic, you'd need to + * apply the right patches to your system, and also set that variable + * with: + +echo 'lanc_outbound_promisc_flag/W1' | /usr/bin/adb -w /stand/vmunix /dev/kmem + + * which could be put in, for example, "/sbin/init.d/lan". + * + * Setting the variable is not necessary on HP-UX 11.x. + */ static int get_dlpi_ppa(register int fd, register const char *device, register int unit, register char *ebuf) { register dl_hp_ppa_ack_t *ap; - register dl_hp_ppa_info_t *ip; + register dl_hp_ppa_info_t *ipstart, *ip; register int i; + char dname[100]; register u_long majdev; - dl_hp_ppa_req_t req; struct stat statbuf; + dl_hp_ppa_req_t req; bpf_u_int32 buf[MAXDLBUF]; - if (stat(device, &statbuf) < 0) { - sprintf(ebuf, "stat: %s: %s", device, pcap_strerror(errno)); - return (-1); - } - majdev = major(statbuf.st_rdev); - memset((char *)&req, 0, sizeof(req)); req.dl_primitive = DL_HP_PPA_REQ; @@ -741,20 +840,81 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit, return (-1); ap = (dl_hp_ppa_ack_t *)buf; - ip = (dl_hp_ppa_info_t *)((u_char *)ap + ap->dl_offset); + ipstart = (dl_hp_ppa_info_t *)((u_char *)ap + ap->dl_offset); + ip = ipstart; - for(i = 0; i < ap->dl_count; i++) { - if (ip->dl_mjr_num == majdev && ip->dl_instance_num == unit) - break; +#ifdef HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1 + /* + * The "dl_hp_ppa_info_t" structure has a "dl_module_id_1" + * member that should, in theory, contain the part of the + * name for the device that comes before the unit number, + * and should also have a "dl_module_id_2" member that may + * contain an alternate name (e.g., I think Ethernet devices + * have both "lan", for "lanN", and "snap", for "snapN", with + * the former being for Ethernet packets and the latter being + * for 802.3/802.2 packets). + * + * Search for the device that has the specified name and + * instance number. + */ + for (i = 0; i < ap->dl_count; i++) { + if ((strcmp(ip->dl_module_id_1, device) == 0 || + strcmp(ip->dl_module_id_2, device) == 0) && + ip->dl_instance_num == unit) + break; - ip = (dl_hp_ppa_info_t *)((u_char *)ip + ip->dl_next_offset); - } + ip = (dl_hp_ppa_info_t *)((u_char *)ipstart + ip->dl_next_offset); + } +#else + /* + * We don't have that member, so the search is impossible; make it + * look as if the search failed. + */ + i = ap->dl_count; +#endif + + if (i == ap->dl_count) { + /* + * Well, we didn't, or can't, find the device by name. + * + * HP-UX 10.20, whilst it has "dl_module_id_1" and + * "dl_module_id_2" fields in the "dl_hp_ppa_info_t", + * doesn't seem to fill them in unless the system is + * at a reasonably up-to-date patch level. + * + * Older HP-UX 10.x systems might not have those fields + * at all. + * + * Therefore, we'll search for the entry with the major + * device number of a device with the name "/dev/<dev><unit>", + * if such a device exists, as the old code did. + */ + snprintf(dname, sizeof(dname), "/dev/%s%d", device, unit); + if (stat(dname, &statbuf) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "stat: %s: %s", + dname, pcap_strerror(errno)); + return (-1); + } + majdev = major(statbuf.st_rdev); + + ip = ipstart; + + for (i = 0; i < ap->dl_count; i++) { + if (ip->dl_mjr_num == majdev && + ip->dl_instance_num == unit) + break; + + ip = (dl_hp_ppa_info_t *)((u_char *)ipstart + ip->dl_next_offset); + } + } if (i == ap->dl_count) { - sprintf(ebuf, "can't find PPA for %s", device); + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "can't find /dev/dlpi PPA for %s%d", device, unit); return (-1); } if (ip->dl_hdw_state == HDW_DEAD) { - sprintf(ebuf, "%s: hardware state: DOWN\n", device); + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "%s%d: hardware state: DOWN\n", device, unit); return (-1); } return ((int)ip->dl_ppa); @@ -783,23 +943,26 @@ get_dlpi_ppa(register int fd, register const char *ifname, register int unit, register int kd; void *addr; struct ifnet ifnet; - char if_name[sizeof(ifnet.if_name)], tifname[32]; + char if_name[sizeof(ifnet.if_name) + 1]; cp = strrchr(ifname, '/'); if (cp != NULL) ifname = cp + 1; if (nlist(path_vmunix, &nl) < 0) { - sprintf(ebuf, "nlist %s failed", path_vmunix); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "nlist %s failed", + path_vmunix); return (-1); } if (nl[NL_IFNET].n_value == 0) { - sprintf(ebuf, "could't find %s kernel symbol", + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "could't find %s kernel symbol", nl[NL_IFNET].n_name); return (-1); } kd = open("/dev/kmem", O_RDONLY); if (kd < 0) { - sprintf(ebuf, "kmem open: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "kmem open: %s", + pcap_strerror(errno)); return (-1); } if (dlpi_kread(kd, nl[NL_IFNET].n_value, @@ -811,17 +974,16 @@ get_dlpi_ppa(register int fd, register const char *ifname, register int unit, if (dlpi_kread(kd, (off_t)addr, &ifnet, sizeof(ifnet), ebuf) < 0 || dlpi_kread(kd, (off_t)ifnet.if_name, - if_name, sizeof(if_name), ebuf) < 0) { + if_name, sizeof(ifnet.if_name), ebuf) < 0) { (void)close(kd); return (-1); } - sprintf(tifname, "%.*s%d", - (int)sizeof(if_name), if_name, ifnet.if_unit); - if (strcmp(tifname, ifname) == 0) + if_name[sizeof(ifnet.if_name)] = '\0'; + if (strcmp(if_name, ifname) == 0 && ifnet.if_unit == unit) return (ifnet.if_index); } - sprintf(ebuf, "Can't find %s", ifname); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "Can't find %s", ifname); return (-1); } @@ -832,15 +994,18 @@ dlpi_kread(register int fd, register off_t addr, register int cc; if (lseek(fd, addr, SEEK_SET) < 0) { - sprintf(ebuf, "lseek: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "lseek: %s", + pcap_strerror(errno)); return (-1); } cc = read(fd, buf, len); if (cc < 0) { - sprintf(ebuf, "read: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "read: %s", + pcap_strerror(errno)); return (-1); } else if (cc != len) { - sprintf(ebuf, "short read (%d != %d)", cc, len); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "short read (%d != %d)", cc, + len); return (-1); } return (cc); diff --git a/contrib/libpcap/pcap-enet.c b/contrib/libpcap/pcap-enet.c index 3f4189b..be1ca76 100644 --- a/contrib/libpcap/pcap-enet.c +++ b/contrib/libpcap/pcap-enet.c @@ -6,6 +6,14 @@ * * Rayan Zachariassen, CA*Net */ +#ifndef lint +static const char rcsid[] = + "@(#) $Header: /tcpdump/master/libpcap/pcap-enet.c,v 1.5 2000/10/12 03:53:59 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include <sys/types.h> #include <sys/time.h> diff --git a/contrib/libpcap/pcap-int.h b/contrib/libpcap/pcap-int.h index 04e815a..fc4ab90 100644 --- a/contrib/libpcap/pcap-int.h +++ b/contrib/libpcap/pcap-int.h @@ -30,12 +30,16 @@ * 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.20 1999/11/21 01:10:20 assar Exp $ (LBL) + * @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.32 2000/12/21 10:29:23 guy Exp $ (LBL) */ #ifndef pcap_int_h #define pcap_int_h +#ifdef __cplusplus +extern "C" { +#endif + #include <pcap.h> /* @@ -44,6 +48,7 @@ struct pcap_sf { FILE *rfile; int swapped; + int hdrsize; int version_major; int version_minor; u_char *base; @@ -52,16 +57,21 @@ struct pcap_sf { struct pcap_md { struct pcap_stat stat; /*XXX*/ - int use_bpf; + int use_bpf; /* using kernel filter */ u_long TotPkts; /* can't oflow for 79 hrs on ether */ u_long TotAccepted; /* count accepted by filter */ u_long TotDrops; /* count of dropped packets */ long TotMissed; /* missed by i/f during this run */ long OrigMissed; /* missed by i/f before this run */ #ifdef linux - int pad; - int skip; - char *device; + int sock_packet; /* using Linux 2.0 compatible interface */ + int readlen; /* byte count to hand to "recvmsg()" */ + int timeout; /* timeout specified to pcap_open_live */ + int clear_promisc; /* must clear promiscuous mode when we close */ + int cooked; /* using SOCK_DGRAM rather than SOCK_RAW */ + int lo_ifindex; /* interface index of the loopback device */ + char *device; /* device name */ + struct pcap *next; /* list of open promiscuous sock_packet pcaps */ #endif }; @@ -110,6 +120,28 @@ struct pcap_timeval { /* * How a `pcap_pkthdr' is actually stored in the dumpfile. + * + * Do not change the format of this structure, in any way (this includes + * changes that only affect the length of fields in this structure), + * and do not make the time stamp anything other than seconds and + * microseconds (e.g., seconds and nanoseconds). Instead: + * + * introduce a new structure for the new format; + * + * send mail to "tcpdump-workers@tcpdump.org", requesting a new + * magic number for your new capture file format, and, when + * you get the new magic number, put it in "savefile.c"; + * + * use that magic number for save files with the changed record + * header; + * + * make the code in "savefile.c" capable of reading files with + * the old record header as well as files with the new record header + * (using the magic number to determine the header format). + * + * Then supply the changes to "patches@tcpdump.org", so that future + * versions of libpcap and programs that use it (such as tcpdump) will + * be able to read your new capture file format. */ struct pcap_sf_pkthdr { @@ -118,6 +150,25 @@ struct pcap_sf_pkthdr { bpf_u_int32 len; /* length this packet (off wire) */ }; +/* + * How a `pcap_pkthdr' is actually stored in dumpfiles written + * by some patched versions of libpcap (e.g. the ones in Red + * Hat Linux 6.1 and 6.2). + * + * Do not change the format of this structure, in any way (this includes + * changes that only affect the length of fields in this structure). + * Instead, introduce a new structure, as per the above. + */ + +struct pcap_sf_patched_pkthdr { + struct pcap_timeval ts; /* time stamp */ + bpf_u_int32 caplen; /* length of portion present */ + bpf_u_int32 len; /* length this packet (off wire) */ + int index; + unsigned short protocol; + unsigned char pkt_type; +}; + int yylex(void); #ifndef min @@ -128,11 +179,32 @@ int yylex(void); int pcap_offline_read(pcap_t *, int, pcap_handler, u_char *); int pcap_read(pcap_t *, int cnt, pcap_handler, u_char *); -/* Ultrix pads to make everything line up on a nice boundary */ -#if defined(ultrix) || defined(__alpha) || defined(__NetBSD__) +/* + * Ultrix, DEC OSF/1^H^H^H^H^H^H^H^H^HDigital UNIX^H^H^H^H^H^H^H^H^H^H^H^H + * Tru64 UNIX, and NetBSD pad to make everything line up on a nice boundary. + */ +#if defined(ultrix) || defined(__osf__) || defined(__NetBSD__) #define PCAP_FDDIPAD 3 #endif +#ifndef HAVE_STRLCPY +#define strlcpy(x, y, z) \ + (strncpy((x), (y), (z)), \ + ((z) <= 0 ? 0 : ((x)[(z) - 1] = '\0')), \ + strlen((y))) +#endif + +#ifdef linux +void pcap_close_linux(pcap_t *); +#endif + /* XXX */ extern int pcap_fddipad; + +int install_bpf_program(pcap_t *, struct bpf_program *); + +#ifdef __cplusplus +} +#endif + #endif diff --git a/contrib/libpcap/pcap-linux.c b/contrib/libpcap/pcap-linux.c index 17e0a3b..1199f8f 100644 --- a/contrib/libpcap/pcap-linux.c +++ b/contrib/libpcap/pcap-linux.c @@ -1,331 +1,1366 @@ /* - * Copyright (c) 1996, 1997 - * The Regents of the University of California. All rights reserved. + * pcap-linux.c: Packet capture interface to the Linux kernel * - * 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. + * Copyright (c) 2000 Torsten Landschoff <torsten@debian.org> + * Sebastian Krahmer <krahmer@cs.uni-potsdam.de> + * + * License: BSD + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. The names of the authors may not 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 rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.15.1.1 1999/10/07 23:46:40 mcr Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.51.2.3 2001/01/18 03:59:56 guy Exp $ (LBL)"; #endif -#include <sys/param.h> -#include <sys/ioctl.h> -#include <sys/socket.h> -#include <sys/time.h> +/* + * Known problems with 2.0[.x] kernels: + * + * - The loopback device gives every packet twice; on 2.2[.x] kernels, + * if we use PF_PACKET, we can filter out the transmitted version + * of the packet by using data in the "sockaddr_ll" returned by + * "recvfrom()", but, on 2.0[.x] kernels, we have to use + * PF_INET/SOCK_PACKET, which means "recvfrom()" supplies a + * "sockaddr_pkt" which doesn't give us enough information to let + * us do that. + * + * - We have to set the interface's IFF_PROMISC flag ourselves, if + * we're to run in promiscuous mode, which means we have to turn + * it off ourselves when we're done; the kernel doesn't keep track + * of how many sockets are listening promiscuously, which means + * it won't get turned off automatically when no sockets are + * listening promiscuously. We catch "pcap_close()" and, for + * interfaces we put into promiscuous mode, take them out of + * promiscuous mode - which isn't necessarily the right thing to + * do, if another socket also requested promiscuous mode between + * the time when we opened the socket and the time when we close + * the socket. + */ -#include <net/if.h> -#ifdef HAVE_NET_IF_ARP_H -#include <net/if_arp.h> -#else -#include <linux/if_arp.h> + +#ifdef HAVE_CONFIG_H +#include "config.h" #endif -#include <linux/if_ether.h> -#include <netinet/in.h> +#include "pcap-int.h" +#include "sll.h" #include <errno.h> -#include <malloc.h> -#include <stdio.h> #include <stdlib.h> -#include <string.h> #include <unistd.h> +#include <fcntl.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <sys/utsname.h> +#include <net/if.h> +#include <netinet/in.h> +#include <linux/if_ether.h> +#include <net/if_arp.h> -static struct ifreq saved_ifr; +#ifdef HAVE_NETPACKET_PACKET_H +# include <netpacket/packet.h> -#include "pcap-int.h" + /* + * We assume this means we really do have PF_PACKET sockets. + */ +# define HAVE_PF_PACKET_SOCKETS +#else + /* + * Oh, joy. Some Linux distributions have 2.2 or later kernels and + * libc5. On at least one of those systems (Slackware 4.0), it + * appears that "/usr/include/sys/socket.h" includes <linux/socket.h>, + * which means it picks up all the AF_, PF_, and SO_ definitions + * appropriate for the current kernel; however, it also appears that + * they did not see fit to provide a "/usr/include/netpacket/packet.h" + * file. + * + * However, you should be able to get the right definitions by including + * <linux/if_packet.h>. + * + * So if this system has PF_PACKET defined but doesn't have the + * <netpacket/packet.h> header file, we include <linux/if_packet.h> + * instead. + */ +# ifdef PF_PACKET +# include <linux/if_packet.h> -#include "gnuc.h" -#ifdef HAVE_OS_PROTO_H -#include "os-proto.h" + /* + * However, on at least some Linux distributions (for example, Red Hat + * 5.2), there's no <netpacket/packet.h> file, but PF_PACKET is defined + * if you include <sys/socket.h>, but <linux/if_packet.h> doesn't define + * any of the PF_PACKET stuff such as "struct sockaddr_ll" or any of + * the PACKET_xxx stuff. + * + * So we check whether PACKET_HOST is defined, and assume that we have + * PF_PACKET sockets only if it is defined. + */ +# ifdef PACKET_HOST +# define HAVE_PF_PACKET_SOCKETS +# endif /* PACKET_HOST */ +# endif /* PF_PACKET */ +#endif /* HAVE_NETPACKET_PACKET_H */ + +#ifdef SO_ATTACH_FILTER +#include <linux/types.h> +#include <linux/filter.h> #endif -void linux_restore_ifr(void); +#ifndef __GLIBC__ +typedef int socklen_t; +#endif -int -pcap_stats(pcap_t *p, struct pcap_stat *ps) +#ifndef MSG_TRUNC +#define MSG_TRUNC 0 +#endif + +#define MAX_LINKHEADER_SIZE 256 + +/* + * When capturing on all interfaces we use this as the buffer size. + * Should be bigger then all MTUs that occur in real life. + * 64kB should be enough for now. + */ +#define BIGGER_THAN_ALL_MTUS (64*1024) + +/* + * Prototypes for internal functions + */ +static int map_arphrd_to_dlt(int arptype ); +static int live_open_old(pcap_t *, char *, int, int, char *); +static int live_open_new(pcap_t *, char *, int, int, char *); +static int pcap_read_packet(pcap_t *, pcap_handler, u_char *); + +/* + * Wrap some ioctl calls + */ +#ifdef HAVE_PF_PACKET_SOCKETS +static int iface_get_id(int fd, const char *device, char *ebuf); +#endif +static int iface_get_mtu(int fd, const char *device, char *ebuf); +static int iface_get_arptype(int fd, const char *device, char *ebuf); +#ifdef HAVE_PF_PACKET_SOCKETS +static int iface_bind(int fd, int ifindex, char *ebuf); +#endif +static int iface_bind_old(int fd, const char *device, char *ebuf); + +#ifdef SO_ATTACH_FILTER +static int fix_program(pcap_t *handle, struct sock_fprog *fcode); +static int fix_offset(struct bpf_insn *p); +#endif + +/* + * Get a handle for a live capture from the given device. You can + * pass NULL as device to get all packages (without link level + * information of course). If you pass 1 as promisc the interface + * will be set to promiscous mode (XXX: I think this usage should + * be deprecated and functions be added to select that later allow + * modification of that values -- Torsten). + * + * See also pcap(3). + */ +pcap_t * +pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) { + /* Allocate a handle for this session. */ + + pcap_t *handle = malloc(sizeof(*handle)); + if (handle == NULL) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", + pcap_strerror(errno)); + return NULL; + } + + /* Initialize some components of the pcap structure. */ + + memset(handle, 0, sizeof(*handle)); + handle->snapshot = snaplen; + handle->md.timeout = to_ms; + + /* + * NULL and "any" are special devices which give us the hint to + * monitor all devices. + */ + if (!device || strcmp(device, "any") == 0) { + device = NULL; + handle->md.device = strdup("any"); + } else + handle->md.device = strdup(device); + + if (handle->md.device == NULL) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "strdup: %s", + pcap_strerror(errno) ); + free(handle); + return NULL; + } + + /* + * Current Linux kernels use the protocol family PF_PACKET to + * allow direct access to all packets on the network while + * older kernels had a special socket type SOCK_PACKET to + * implement this feature. + * While this old implementation is kind of obsolete we need + * to be compatible with older kernels for a while so we are + * trying both methods with the newer method preferred. + */ + + if (! (live_open_new(handle, device, promisc, to_ms, ebuf) || + live_open_old(handle, device, promisc, to_ms, ebuf)) ) + { + /* + * Both methods to open the packet socket failed. Tidy + * up and report our failure (ebuf is expected to be + * set by the functions above). + */ - *ps = p->md.stat; - return (0); + free(handle->md.device); + free(handle); + return NULL; + } + + return handle; } +/* + * 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. + */ int -pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) +pcap_read(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user) { - register int cc; - register int bufsize; - register int caplen; - register u_char *bp; - struct sockaddr from; - int fromlen; - - bp = p->buffer + p->offset; - bufsize = p->bufsize; - if (p->md.pad > 0) { - memset(bp, 0, p->md.pad); - bp += p->md.pad; - bufsize -= p->md.pad; - } + /* + * Currently, on Linux only one packet is delivered per read, + * so we don't loop. + */ + return pcap_read_packet(handle, callback, user); +} + +/* + * Read a packet from the socket calling the handler provided by + * the user. Returns the number of packets received or -1 if an + * error occured. + */ +static int +pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata) +{ + int offset; +#ifdef HAVE_PF_PACKET_SOCKETS + struct sockaddr_ll from; + struct sll_header *hdrp; +#else + struct sockaddr from; +#endif + socklen_t fromlen; + int packet_len, caplen; + struct pcap_pkthdr pcap_header; + +#ifdef HAVE_PF_PACKET_SOCKETS + /* + * If this is a cooked device, leave extra room for a + * fake packet header. + */ + if (handle->md.cooked) + offset = SLL_HDR_LEN; + else + offset = 0; +#else + /* + * This system doesn't have PF_PACKET sockets, so it doesn't + * support cooked devices. + */ + offset = 0; +#endif + + /* Receive a single packet from the kernel */ -again: do { fromlen = sizeof(from); - cc = recvfrom(p->fd, bp, bufsize, 0, &from, &fromlen); - if (cc < 0) { - /* Don't choke when we get ptraced */ - switch (errno) { + packet_len = recvfrom( + handle->fd, handle->buffer + offset + handle->offset, + handle->md.readlen - offset, MSG_TRUNC, + (struct sockaddr *) &from, &fromlen); + } while (packet_len == -1 && errno == EINTR); - case EINTR: - goto again; + /* Check if an error occured */ - case EWOULDBLOCK: - return (0); /* XXX */ - } - sprintf(p->errbuf, "read: %s", pcap_strerror(errno)); - return (-1); + if (packet_len == -1) { + if (errno == EAGAIN) + return 0; /* no packet there */ + else { + snprintf(handle->errbuf, sizeof(handle->errbuf), + "recvfrom: %s", pcap_strerror(errno)); + return -1; } - } while (strcmp(p->md.device, from.sa_data)); - - /* If we need have leading zero bytes, adjust count */ - cc += p->md.pad; - bp = p->buffer + p->offset; - - /* If we need to step over leading junk, adjust count and pointer */ - cc -= p->md.skip; - bp += p->md.skip; - - /* Captured length can't exceed our read buffer size */ - caplen = cc; - if (caplen > bufsize) - caplen = bufsize; - - /* Captured length can't exceed the snapshot length */ - if (caplen > p->snapshot) - caplen = p->snapshot; - - if (p->fcode.bf_insns == NULL || - bpf_filter(p->fcode.bf_insns, bp, cc, caplen)) { - struct pcap_pkthdr h; - - ++p->md.stat.ps_recv; - /* Get timestamp */ - if (ioctl(p->fd, SIOCGSTAMP, &h.ts) < 0) { - sprintf(p->errbuf, "SIOCGSTAMP: %s", - pcap_strerror(errno)); - return (-1); + } + +#ifdef HAVE_PF_PACKET_SOCKETS + /* + * If this is from the loopback device, reject outgoing packets; + * we'll see the packet as an incoming packet as well, and + * we don't want to see it twice. + * + * We can only do this if we're using PF_PACKET; the address + * returned for SOCK_PACKET is a "sockaddr_pkt" which lacks + * the relevant packet type information. + */ + if (!handle->md.sock_packet && + from.sll_ifindex == handle->md.lo_ifindex && + from.sll_pkttype == PACKET_OUTGOING) + return 0; +#endif + +#ifdef HAVE_PF_PACKET_SOCKETS + /* + * If this is a cooked device, fill in the fake packet header. + */ + if (handle->md.cooked) { + /* + * Add the length of the fake header to the length + * of packet data we read. + */ + packet_len += SLL_HDR_LEN; + + hdrp = (struct sll_header *)handle->buffer; + + /* + * Map the PACKET_ value to a LINUX_SLL_ value; we + * want the same numerical value to be used in + * the link-layer header even if the numerical values + * for the PACKET_ #defines change, so that programs + * that look at the packet type field will always be + * able to handle DLT_LINUX_SLL captures. + */ + switch (from.sll_pkttype) { + + case PACKET_HOST: + hdrp->sll_pkttype = htons(LINUX_SLL_HOST); + break; + + case PACKET_BROADCAST: + hdrp->sll_pkttype = htons(LINUX_SLL_BROADCAST); + break; + + case PACKET_MULTICAST: + hdrp->sll_pkttype = htons(LINUX_SLL_MULTICAST); + break; + + case PACKET_OTHERHOST: + hdrp->sll_pkttype = htons(LINUX_SLL_OTHERHOST); + break; + + case PACKET_OUTGOING: + hdrp->sll_pkttype = htons(LINUX_SLL_OUTGOING); + break; + + default: + hdrp->sll_pkttype = -1; + break; + } + + hdrp->sll_hatype = htons(from.sll_hatype); + hdrp->sll_halen = htons(from.sll_halen); + memcpy(hdrp->sll_addr, from.sll_addr, + (from.sll_halen > SLL_ADDRLEN) ? + SLL_ADDRLEN : + from.sll_halen); + hdrp->sll_protocol = from.sll_protocol; + } +#endif + + /* + * XXX: According to the kernel source we should get the real + * packet len if calling recvfrom with MSG_TRUNC set. It does + * not seem to work here :(, but it is supported by this code + * anyway. + * To be honest the code RELIES on that feature so this is really + * broken with 2.2.x kernels. + * I spend a day to figure out what's going on and I found out + * that the following is happening: + * + * The packet comes from a random interface and the packet_rcv + * hook is called with a clone of the packet. That code inserts + * the packet into the receive queue of the packet socket. + * If a filter is attached to that socket that filter is run + * first - and there lies the problem. The default filter always + * cuts the packet at the snaplen: + * + * # tcpdump -d + * (000) ret #68 + * + * So the packet filter cuts down the packet. The recvfrom call + * says "hey, it's only 68 bytes, it fits into the buffer" with + * the result that we don't get the real packet length. This + * is valid at least until kernel 2.2.17pre6. + * + * We currently handle this by making a copy of the filter + * program, fixing all "ret" instructions with non-zero + * operands to have an operand of 65535 so that the filter + * doesn't truncate the packet, and supplying that modified + * filter to the kernel. + */ + + caplen = packet_len; + if (caplen > handle->snapshot) + caplen = handle->snapshot; + + /* Run the packet filter if not using kernel filter */ + if (!handle->md.use_bpf && handle->fcode.bf_insns) { + if (bpf_filter(handle->fcode.bf_insns, handle->buffer, + packet_len, caplen) == 0) + { + /* rejected by filter */ + return 0; } - h.len = cc; - h.caplen = caplen; - (*callback)(user, &h, bp); - return (1); } - return (0); + + /* Fill in our own header data */ + + if (ioctl(handle->fd, SIOCGSTAMP, &pcap_header.ts) == -1) { + snprintf(handle->errbuf, sizeof(handle->errbuf), + "ioctl: %s", pcap_strerror(errno)); + return -1; + } + pcap_header.caplen = caplen; + pcap_header.len = packet_len; + + /* Call the user supplied callback function */ + handle->md.stat.ps_recv++; + callback(userdata, &pcap_header, handle->buffer + handle->offset); + + return 1; } -pcap_t * -pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) +/* + * Get the statistics for the given packet capture handle. + * FIXME: Currently does not report the number of dropped packets. + */ +int +pcap_stats(pcap_t *handle, struct pcap_stat *stats) { - register int fd, broadcast; - register pcap_t *p; - struct ifreq ifr; - struct sockaddr sa; - - p = (pcap_t *)malloc(sizeof(*p)); - if (p == NULL) { - sprintf(ebuf, "malloc: %s", pcap_strerror(errno)); - return (NULL); + *stats = handle->md.stat; + return 0; +} + +/* + * Attach the given BPF code to the packet capture device. + */ +int +pcap_setfilter(pcap_t *handle, struct bpf_program *filter) +{ +#ifdef SO_ATTACH_FILTER + struct sock_fprog fcode; + int can_filter_in_kernel; +#endif + + if (!handle) + return -1; + if (!filter) { + strncpy(handle->errbuf, "setfilter: No filter specified", + sizeof(handle->errbuf)); + return -1; } - memset(p, 0, sizeof(*p)); - fd = -1; - fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL)); - if (fd < 0) { - sprintf(ebuf, "socket: %s", pcap_strerror(errno)); - goto bad; + /* Make our private copy of the filter */ + + if (install_bpf_program(handle, filter) < 0) { + snprintf(handle->errbuf, sizeof(handle->errbuf), + "malloc: %s", pcap_strerror(errno)); + return -1; } - p->fd = fd; - - /* Bind to the interface name */ - memset(&sa, 0, sizeof(sa)); - sa.sa_family = AF_INET; - (void)strncpy(sa.sa_data, device, sizeof(sa.sa_data)); - if (bind(p->fd, &sa, sizeof(sa))) { - sprintf(ebuf, "bind: %s: %s", device, pcap_strerror(errno)); - goto bad; + + /* + * Run user level packet filter by default. Will be overriden if + * installing a kernel filter succeeds. + */ + handle->md.use_bpf = 0; + + /* + * If we're reading from a savefile, don't try to install + * a kernel filter. + */ + if (handle->sf.rfile != NULL) + return 0; + + /* Install kernel level filter if possible */ + +#ifdef SO_ATTACH_FILTER +#ifdef USHRT_MAX + if (handle->fcode.bf_len > USHRT_MAX) { + /* + * fcode.len is an unsigned short for current kernel. + * I have yet to see BPF-Code with that much + * instructions but still it is possible. So for the + * sake of correctness I added this check. + */ + fprintf(stderr, "Warning: Filter too complex for kernel\n"); + fcode.filter = NULL; + can_filter_in_kernel = 0; + } else +#endif /* USHRT_MAX */ + { + /* + * Oh joy, the Linux kernel uses struct sock_fprog instead + * of struct bpf_program and of course the length field is + * of different size. Pointed out by Sebastian + * + * Oh, and we also need to fix it up so that all "ret" + * instructions with non-zero operands have 65535 as the + * operand, and so that, if we're in cooked mode, all + * memory-reference instructions use special magic offsets + * in references to the link-layer header and assume that + * the link-layer payload begins at 0; "fix_program()" + * will do that. + */ + switch (fix_program(handle, &fcode)) { + + case -1: + default: + /* + * Fatal error; just quit. + * (The "default" case shouldn't happen; we + * return -1 for that reason.) + */ + return -1; + + case 0: + /* + * The program performed checks that we can't make + * work in the kernel. + */ + can_filter_in_kernel = 0; + break; + + case 1: + /* + * We have a filter that'll work in the kernel. + */ + can_filter_in_kernel = 1; + break; + } } - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); - if (ioctl(p->fd, SIOCGIFHWADDR, &ifr) < 0 ) { - sprintf(ebuf, "SIOCGIFHWADDR: %s", pcap_strerror(errno)); - goto bad; + if (can_filter_in_kernel) { + if (setsockopt(handle->fd, SOL_SOCKET, SO_ATTACH_FILTER, + &fcode, sizeof(fcode)) == 0) + { + /* Installation succeded - using kernel filter. */ + handle->md.use_bpf = 1; + } + else + { + /* + * Print a warning if we weren't able to install + * the filter for a reason other than "this kernel + * isn't configured to support socket filters. + */ + if (errno != ENOPROTOOPT && errno != EOPNOTSUPP) { + fprintf(stderr, + "Warning: Kernel filter failed: %s\n", + pcap_strerror(errno)); + } + } } - broadcast = 0; - switch (ifr.ifr_hwaddr.sa_family) { + /* + * Free up the copy of the filter that was made by "fix_program()". + */ + if (fcode.filter != NULL) + free(fcode.filter); +#endif /* SO_ATTACH_FILTER */ + + return 0; +} + +/* + * Linux uses the ARP hardware type to identify the type of an + * interface. pcap uses the DLT_xxx constants for this. This + * function maps the ARPHRD_xxx constant to an appropriate + * DLT_xxx constant. + * + * Returns -1 if unable to map the type; we print a message and, + * if we're using PF_PACKET/SOCK_RAW rather than PF_INET/SOCK_PACKET, + * we fall back on using PF_PACKET/SOCK_DGRAM. + */ +static int map_arphrd_to_dlt(int arptype) +{ + switch (arptype) { case ARPHRD_ETHER: case ARPHRD_METRICOM: - p->linktype = DLT_EN10MB; - p->offset = 2; - ++broadcast; - break; - - case ARPHRD_EETHER: - p->linktype = DLT_EN3MB; - ++broadcast; - break; - - case ARPHRD_AX25: - p->linktype = DLT_AX25; - ++broadcast; - break; - - case ARPHRD_PRONET: - p->linktype = DLT_PRONET; - break; - - case ARPHRD_CHAOS: - p->linktype = DLT_CHAOS; - break; - - case ARPHRD_IEEE802: - p->linktype = DLT_IEEE802; - ++broadcast; - break; - - case ARPHRD_ARCNET: - p->linktype = DLT_ARCNET; - ++broadcast; - break; - - case ARPHRD_SLIP: + case ARPHRD_LOOPBACK: return DLT_EN10MB; + case ARPHRD_EETHER: return DLT_EN3MB; + case ARPHRD_AX25: return DLT_AX25; + case ARPHRD_PRONET: return DLT_PRONET; + case ARPHRD_CHAOS: return DLT_CHAOS; +#ifndef ARPHRD_IEEE802_TR +#define ARPHRD_IEEE802_TR 800 /* From Linux 2.4 */ +#endif + case ARPHRD_IEEE802_TR: + case ARPHRD_IEEE802: return DLT_IEEE802; + case ARPHRD_ARCNET: return DLT_ARCNET; + case ARPHRD_FDDI: return DLT_FDDI; + +#ifndef ARPHRD_ATM /* FIXME: How to #include this? */ +#define ARPHRD_ATM 19 +#endif + case ARPHRD_ATM: return DLT_ATM_CLIP; + + case ARPHRD_PPP: + /* Not sure if this is correct for all tunnels, but it + * works for CIPE */ + case ARPHRD_TUNNEL: +#ifndef ARPHRD_SIT +#define ARPHRD_SIT 776 /* From Linux 2.2.14 */ +#endif + case ARPHRD_SIT: case ARPHRD_CSLIP: case ARPHRD_SLIP6: case ARPHRD_CSLIP6: - case ARPHRD_PPP: - p->linktype = DLT_RAW; - break; - - case ARPHRD_LOOPBACK: - p->linktype = DLT_NULL; - p->md.pad = 2; - p->md.skip = 12; - break; - -#ifdef ARPHRD_FDDI - /* Not all versions of the kernel has this define */ - case ARPHRD_FDDI: - p->linktype = DLT_FDDI; - ++broadcast; - break; + case ARPHRD_SLIP: return DLT_RAW; + } + + return -1; +} + +/* ===== Functions to interface to the newer kernels ================== */ + +/* + * Try to open a packet socket using the new kernel interface. + * Returns 0 on failure. + * FIXME: 0 uses to mean success (Sebastian) + */ +static int +live_open_new(pcap_t *handle, char *device, int promisc, + int to_ms, char *ebuf) +{ +#ifdef HAVE_PF_PACKET_SOCKETS + int sock_fd = -1, device_id, mtu, arptype; + struct packet_mreq mr; + + /* One shot loop used for error handling - bail out with break */ + + do { + /* + * Open a socket with protocol family packet. If a device is + * given we try to open it in raw mode otherwise we use + * the cooked interface. + */ + sock_fd = device ? + socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)) + : socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)); + + if (sock_fd == -1) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "socket: %s", + pcap_strerror(errno) ); + break; + } + + /* It seems the kernel supports the new interface. */ + handle->md.sock_packet = 0; + + /* + * Get the interface index of the loopback device. + * If the attempt fails, don't fail, just set the + * "md.lo_ifindex" to -1. + * + * XXX - can there be more than one device that loops + * packets back, i.e. devices other than "lo"? If so, + * we'd need to find them all, and have an array of + * indices for them, and check all of them in + * "pcap_read_packet()". + */ + handle->md.lo_ifindex = iface_get_id(sock_fd, "lo", ebuf); + + /* + * What kind of frames do we have to deal with? Fall back + * to cooked mode if we have an unknown interface type. + */ + + if (device) { + /* Assume for now we don't need cooked mode. */ + handle->md.cooked = 0; + + arptype = iface_get_arptype(sock_fd, device, ebuf); + if (arptype == -1) + break; + handle->linktype = map_arphrd_to_dlt(arptype); + if (handle->linktype == -1 || + (handle->linktype == DLT_EN10MB && + (strncmp("isdn", device, 4) == 0 || + strncmp("isdY", device, 4) == 0)) || + (handle->linktype == DLT_RAW && + (strncmp("ippp", device, 4) == 0))) { + /* + * Unknown interface type (-1), or an ISDN + * device (whose link-layer type we + * can only determine by using APIs + * that may be different on different + * kernels) - reopen in cooked mode. + * + * XXX - do that with DLT_RAW as well? + */ + if (close(sock_fd) == -1) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "close: %s", pcap_strerror(errno)); + break; + } + sock_fd = socket(PF_PACKET, SOCK_DGRAM, + htons(ETH_P_ALL)); + if (sock_fd == -1) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "socket: %s", pcap_strerror(errno)); + break; + } + handle->md.cooked = 1; + + if (handle->linktype == -1) { + /* + * Warn that we're falling back on + * cooked mode; we may want to + * update "map_arphrd_to_dlt()" + * to handle the new type. + */ + fprintf(stderr, + "Warning: arptype %d not " + "supported by libpcap - " + "falling back to cooked " + "socket\n", + arptype); + } + handle->linktype = DLT_LINUX_SLL; + } + + device_id = iface_get_id(sock_fd, device, ebuf); + if (device_id == -1) + break; + + if (iface_bind(sock_fd, device_id, ebuf) == -1) + break; + } else { + /* + * This is cooked mode. + */ + handle->md.cooked = 1; + handle->linktype = DLT_LINUX_SLL; + + /* + * XXX - squelch GCC complaints about + * uninitialized variables; if we can't + * select promiscuous mode on all interfaces, + * we should move the code below into the + * "if (device)" branch of the "if" and + * get rid of the next statement. + */ + device_id = -1; + } + + /* Select promiscuous mode on/off */ + +#ifdef SOL_PACKET + /* + * Hmm, how can we set promiscuous mode on all interfaces? + * I am not sure if that is possible at all. + */ + + if (device) { + memset(&mr, 0, sizeof(mr)); + mr.mr_ifindex = device_id; + mr.mr_type = promisc ? + PACKET_MR_PROMISC : PACKET_MR_ALLMULTI; + if (setsockopt(sock_fd, SOL_PACKET, + PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) == -1) + { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "setsockopt: %s", pcap_strerror(errno)); + break; + } + } #endif -#ifdef notdef - case ARPHRD_LOCALTLK: - case ARPHRD_NETROM: - case ARPHRD_APPLETLK: - case ARPHRD_DLCI: - case ARPHRD_RSRVD: - case ARPHRD_ADAPT: - case ARPHRD_TUNNEL: - case ARPHRD_TUNNEL6: - case ARPHRD_FRAD: - case ARPHRD_SKIP: - /* XXX currently do not know what to do with these... */ - abort(); + /* Compute the buffersize */ + + mtu = iface_get_mtu(sock_fd, device, ebuf); + if (mtu == -1) + break; + handle->bufsize = MAX_LINKHEADER_SIZE + mtu; + + /* Fill in the pcap structure */ + + handle->fd = sock_fd; + handle->offset = 0; + + handle->buffer = malloc(handle->bufsize); + if (!handle->buffer) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "malloc: %s", pcap_strerror(errno)); + break; + } + + /* + * This is a 2.2 or later kernel, as it has PF_PACKET; + * "recvfrom()", when passed the MSG_TRUNC flag, will + * return the actual length of the packet, not the + * number of bytes from the packet copied to userland, + * so we can safely pass it a byte count based on the + * snapshot length. + */ + handle->md.readlen = handle->snapshot; + return 1; + + } while(0); + + if (sock_fd != -1) + close(sock_fd); + return 0; +#else + strncpy(ebuf, + "New packet capturing interface not supported by build " + "environment", PCAP_ERRBUF_SIZE); + return 0; #endif +} - default: - sprintf(ebuf, "unknown physical layer type 0x%x", - ifr.ifr_hwaddr.sa_family); - goto bad; - } +#ifdef HAVE_PF_PACKET_SOCKETS +/* + * Return the index of the given device name. Fill ebuf and return + * -1 on failure. + */ +static int +iface_get_id(int fd, const char *device, char *ebuf) +{ + struct ifreq ifr; - /* Base the buffer size on the interface MTU */ memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); - if (ioctl(p->fd, SIOCGIFMTU, &ifr) < 0 ) { - sprintf(ebuf, "SIOCGIFMTU: %s", pcap_strerror(errno)); - goto bad; + + if (ioctl(fd, SIOCGIFINDEX, &ifr) == -1) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "ioctl: %s", pcap_strerror(errno)); + return -1; } - /* Leave room for link header (which is never large under linux...) */ - p->bufsize = ifr.ifr_mtu + 64; + return ifr.ifr_ifindex; +} - p->buffer = (u_char *)malloc(p->bufsize + p->offset); - if (p->buffer == NULL) { - sprintf(ebuf, "malloc: %s", pcap_strerror(errno)); - goto bad; +/* + * Bind the socket associated with FD to the given device. + */ +static int +iface_bind(int fd, int ifindex, char *ebuf) +{ + struct sockaddr_ll sll; + + memset(&sll, 0, sizeof(sll)); + sll.sll_family = AF_PACKET; + sll.sll_ifindex = ifindex; + sll.sll_protocol = htons(ETH_P_ALL); + + if (bind(fd, (struct sockaddr *) &sll, sizeof(sll)) == -1) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "bind: %s", pcap_strerror(errno)); + return -1; } - /* XXX */ - if (promisc && broadcast) { + return 0; +} + +#endif + + +/* ===== Functions to interface to the older kernels ================== */ + +/* + * With older kernels promiscuous mode is kind of interesting because we + * have to reset the interface before exiting. The problem can't really + * be solved without some daemon taking care of managing usage counts. + * If we put the interface into promiscuous mode, we set a flag indicating + * that we must take it out of that mode when the interface is closed, + * and, when closing the interface, if that flag is set we take it out + * of promiscuous mode. + */ + +/* + * List of pcaps for which we turned promiscuous mode on by hand. + * If there are any such pcaps, we arrange to call "pcap_close_all()" + * when we exit, and have it close all of them to turn promiscuous mode + * off. + */ +static struct pcap *pcaps_to_close; + +/* + * TRUE if we've already called "atexit()" to cause "pcap_close_all()" to + * be called on exit. + */ +static int did_atexit; + +static void pcap_close_all(void) +{ + struct pcap *handle; + + while ((handle = pcaps_to_close) != NULL) + pcap_close(handle); +} + +void pcap_close_linux( pcap_t *handle ) +{ + struct pcap *p, *prevp; + struct ifreq ifr; + + if (handle->md.clear_promisc) { + /* + * We put the interface into promiscuous mode; take + * it out of promiscuous mode. + * + * XXX - if somebody else wants it in promiscuous mode, + * this code cannot know that, so it'll take it out + * of promiscuous mode. That's not fixable in 2.0[.x] + * kernels. + */ memset(&ifr, 0, sizeof(ifr)); - strcpy(ifr.ifr_name, device); - if (ioctl(p->fd, SIOCGIFFLAGS, &ifr) < 0 ) { - sprintf(ebuf, "SIOCGIFFLAGS: %s", pcap_strerror(errno)); - goto bad; + strncpy(ifr.ifr_name, handle->md.device, sizeof(ifr.ifr_name)); + if (ioctl(handle->fd, SIOCGIFFLAGS, &ifr) == -1) { + fprintf(stderr, + "Can't restore interface flags (SIOCGIFFLAGS failed: %s).\n" + "Please adjust manually.\n" + "Hint: This can't happen with Linux >= 2.2.0.\n", + strerror(errno)); + } else { + if (ifr.ifr_flags & IFF_PROMISC) { + /* + * Promiscuous mode is currently on; turn it + * off. + */ + ifr.ifr_flags &= ~IFF_PROMISC; + if (ioctl(handle->fd, SIOCSIFFLAGS, &ifr) == -1) { + fprintf(stderr, + "Can't restore interface flags (SIOCSIFFLAGS failed: %s).\n" + "Please adjust manually.\n" + "Hint: This can't happen with Linux >= 2.2.0.\n", + strerror(errno)); + } + } + } + + /* + * Take this pcap out of the list of pcaps for which we + * have to take the interface out of promiscuous mode. + */ + for (p = pcaps_to_close, prevp = NULL; p != NULL; + prevp = p, p = p->md.next) { + if (p == handle) { + /* + * Found it. Remove it from the list. + */ + if (prevp == NULL) { + /* + * It was at the head of the list. + */ + pcaps_to_close = p->md.next; + } else { + /* + * It was in the middle of the list. + */ + prevp->md.next = p->md.next; + } + break; + } + } + } + if (handle->md.device != NULL) + free(handle->md.device); +} + +/* + * Try to open a packet socket using the old kernel interface. + * Returns 0 on failure. + * FIXME: 0 uses to mean success (Sebastian) + */ +static int +live_open_old(pcap_t *handle, char *device, int promisc, + int to_ms, char *ebuf) +{ + int sock_fd = -1, mtu, arptype; + struct utsname utsname; + struct ifreq ifr; + + do { + /* Open the socket */ + + sock_fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL)); + if (sock_fd == -1) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "socket: %s", pcap_strerror(errno)); + break; + } + + /* It worked - we are using the old interface */ + handle->md.sock_packet = 1; + + /* ...which means we get the link-layer header. */ + handle->md.cooked = 0; + + /* Bind to the given device */ + + if (!device) { + strncpy(ebuf, "pcap_open_live: The \"any\" device isn't supported on 2.0[.x]-kernel systems", + PCAP_ERRBUF_SIZE); + break; + } + if (iface_bind_old(sock_fd, device, ebuf) == -1) + break; + + /* Go to promisc mode */ + if (promisc) { + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); + if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr) == -1) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "ioctl: %s", pcap_strerror(errno)); + break; + } + if ((ifr.ifr_flags & IFF_PROMISC) == 0) { + /* + * Promiscuous mode isn't currently on, + * so turn it on, and remember that + * we should turn it off when the + * pcap_t is closed. + */ + + /* + * If we haven't already done so, arrange + * to have "pcap_close_all()" called when + * we exit. + */ + if (!did_atexit) { + if (atexit(pcap_close_all) == -1) { + /* + * "atexit()" failed; don't + * put the interface in + * promiscuous mode, just + * give up. + */ + strncpy(ebuf, "atexit failed", + PCAP_ERRBUF_SIZE); + break; + } + } + + ifr.ifr_flags |= IFF_PROMISC; + if (ioctl(sock_fd, SIOCSIFFLAGS, &ifr) == -1) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "ioctl: %s", + pcap_strerror(errno)); + break; + } + handle->md.clear_promisc = 1; + + /* + * Add this to the list of pcaps + * to close when we exit. + */ + handle->md.next = pcaps_to_close; + pcaps_to_close = handle; + } + } + + /* Compute the buffersize */ + + mtu = iface_get_mtu(sock_fd, device, ebuf); + if (mtu == -1) + break; + handle->bufsize = MAX_LINKHEADER_SIZE + mtu; + if (handle->bufsize < handle->snapshot) + handle->bufsize = handle->snapshot; + + /* All done - fill in the pcap handle */ + + arptype = iface_get_arptype(sock_fd, device, ebuf); + if (arptype == -1) + break; + + handle->fd = sock_fd; + handle->offset = 0; + handle->linktype = map_arphrd_to_dlt(arptype); + /* + * XXX - handle ISDN types here? We can't fall back on + * cooked sockets, so we'd have to figure out from the + * device name what type of link-layer encapsulation + * it's using, and map that to an appropriate DLT_ + * value, meaning we'd map "isdnN" devices to DLT_RAW + * (they supply raw IP packets with no link-layer + * header) and "isdY" devices to a new DLT_I4L_IP + * type that has only an Ethernet packet type as + * a link-layer header. + */ + if (handle->linktype == -1) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "interface type of %s not supported", device); + break; + } + handle->buffer = malloc(handle->bufsize); + if (!handle->buffer) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "malloc: %s", pcap_strerror(errno)); + break; } - saved_ifr = ifr; - ifr.ifr_flags |= IFF_PROMISC; - if (ioctl(p->fd, SIOCSIFFLAGS, &ifr) < 0 ) { - sprintf(ebuf, "SIOCSIFFLAGS: %s", pcap_strerror(errno)); - goto bad; + + /* + * This might be a 2.0[.x] kernel - check. + */ + if (uname(&utsname) < 0 || + strncmp(utsname.release, "2.0", 3) == 0) { + /* + * Either we couldn't find out what kernel release + * this is, or it's a 2.0[.x] kernel. + * + * In the 2.0[.x] kernel, a "recvfrom()" on + * a SOCK_PACKET socket, with MSG_TRUNC set, will + * return the number of bytes read, so if we pass + * a length based on the snapshot length, it'll + * return the number of bytes from the packet + * copied to userland, not the actual length + * of the packet. + * + * This means that, for example, the IP dissector + * in tcpdump will get handed a packet length less + * than the length in the IP header, and will + * complain about "truncated-ip". + * + * So we don't bother trying to copy from the + * kernel only the bytes in which we're interested, + * but instead copy them all, just as the older + * versions of libpcap for Linux did. + * + * Just one of many problems with packet capture + * on 2.0[.x] kernels; you really want a 2.2[.x] + * or later kernel if you want packet capture to + * work well. + */ + handle->md.readlen = handle->bufsize; + } else { + /* + * This is a 2.2[.x] or later kernel (although + * why we're using SOCK_PACKET on such a system + * is unknown to me). + * + * We can safely pass "recvfrom()" a byte count + * based on the snapshot length. + */ + handle->md.readlen = handle->snapshot; } - ifr.ifr_flags &= ~IFF_PROMISC; - atexit(linux_restore_ifr); + return 1; + + } while (0); + + if (sock_fd != -1) + close(sock_fd); + return 0; +} + +/* + * Bind the socket associated with FD to the given device using the + * interface of the old kernels. + */ +static int +iface_bind_old(int fd, const char *device, char *ebuf) +{ + struct sockaddr saddr; + + memset(&saddr, 0, sizeof(saddr)); + strncpy(saddr.sa_data, device, sizeof(saddr.sa_data)); + if (bind(fd, &saddr, sizeof(saddr)) == -1) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "bind: %s", pcap_strerror(errno)); + return -1; } - p->md.device = strdup(device); - if (p->md.device == NULL) { - sprintf(ebuf, "malloc: %s", pcap_strerror(errno)); - goto bad; + return 0; +} + + +/* ===== System calls available on all supported kernels ============== */ + +/* + * Query the kernel for the MTU of the given interface. + */ +static int +iface_get_mtu(int fd, const char *device, char *ebuf) +{ + struct ifreq ifr; + + if (!device) + return BIGGER_THAN_ALL_MTUS; + + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); + + if (ioctl(fd, SIOCGIFMTU, &ifr) == -1) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "ioctl: %s", pcap_strerror(errno)); + return -1; } - p->snapshot = snaplen; - - return (p); -bad: - if (fd >= 0) - (void)close(fd); - if (p->buffer != NULL) - free(p->buffer); - if (p->md.device != NULL) - free(p->md.device); - free(p); - return (NULL); + + return ifr.ifr_mtu; } -int -pcap_setfilter(pcap_t *p, struct bpf_program *fp) +/* + * Get the hardware type of the given interface as ARPHRD_xxx constant. + */ +static int +iface_get_arptype(int fd, const char *device, char *ebuf) { + struct ifreq ifr; - p->fcode = *fp; - return (0); + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); + + if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "ioctl: %s", pcap_strerror(errno)); + return -1; + } + + return ifr.ifr_hwaddr.sa_family; } -void -linux_restore_ifr(void) +#ifdef HAVE_PF_PACKET_SOCKETS +static int +fix_program(pcap_t *handle, struct sock_fprog *fcode) { - register int fd; + size_t prog_size; + register int i; + register struct bpf_insn *p; + struct bpf_insn *f; + int len; + + /* + * Make a copy of the filter, and modify that copy if + * necessary. + */ + prog_size = sizeof(*handle->fcode.bf_insns) * handle->fcode.bf_len; + len = handle->fcode.bf_len; + f = (struct bpf_insn *)malloc(prog_size); + if (f == NULL) { + snprintf(handle->errbuf, sizeof(handle->errbuf), + "malloc: %s", pcap_strerror(errno)); + return -1; + } + memcpy(f, handle->fcode.bf_insns, prog_size); + fcode->len = len; + fcode->filter = (struct sock_filter *) f; + + for (i = 0; i < len; ++i) { + p = &f[i]; + /* + * What type of instruction is this? + */ + switch (BPF_CLASS(p->code)) { + + case BPF_RET: + /* + * It's a return instruction; is the snapshot + * length a constant, rather than the contents + * of the accumulator? + */ + if (BPF_MODE(p->code) == BPF_K) { + /* + * Yes - if the value to be returned, + * i.e. the snapshot length, is anything + * other than 0, make it 65535, so that + * the packet is truncated by "recvfrom()", + * not by the filter. + * + * XXX - there's nothing we can easily do + * if it's getting the value from the + * accumulator; we'd have to insert + * code to force non-zero values to be + * 65535. + */ + if (p->k != 0) + p->k = 65535; + } + break; + + case BPF_LD: + case BPF_LDX: + /* + * It's a load instruction; is it loading + * from the packet? + */ + switch (BPF_MODE(p->code)) { - fd = socket(PF_INET, SOCK_PACKET, htons(0x0003)); - if (fd < 0) - fprintf(stderr, "linux socket: %s", pcap_strerror(errno)); - else if (ioctl(fd, SIOCSIFFLAGS, &saved_ifr) < 0) - fprintf(stderr, "linux SIOCSIFFLAGS: %s", pcap_strerror(errno)); + case BPF_ABS: + case BPF_IND: + case BPF_MSH: + /* + * Yes; are we in cooked mode? + */ + if (handle->md.cooked) { + /* + * Yes, so we need to fix this + * instruction. + */ + if (fix_offset(p) < 0) { + /* + * We failed to do so. + * Return 0, so our caller + * knows to punt to userland. + */ + return 0; + } + } + break; + } + break; + } + } + return 1; /* we succeeded */ +} + +static int +fix_offset(struct bpf_insn *p) +{ + /* + * What's the offset? + */ + if (p->k >= SLL_HDR_LEN) { + /* + * It's within the link-layer payload; that starts at an + * offset of 0, as far as the kernel packet filter is + * concerned, so subtract the length of the link-layer + * header. + */ + p->k -= SLL_HDR_LEN; + } else if (p->k == 14) { + /* + * It's the protocol field; map it to the special magic + * kernel offset for that field. + */ + p->k = SKF_AD_OFF + SKF_AD_PROTOCOL; + } else { + /* + * It's within the header, but it's not one of those + * fields; we can't do that in the kernel, so punt + * to userland. + */ + return -1; + } + return 0; } +#endif diff --git a/contrib/libpcap/pcap-namedb.h b/contrib/libpcap/pcap-namedb.h index 83ddec1..4833c4d 100644 --- a/contrib/libpcap/pcap-namedb.h +++ b/contrib/libpcap/pcap-namedb.h @@ -30,12 +30,16 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#) $Header: /tcpdump/master/libpcap/pcap-namedb.h,v 1.6 1999/10/19 15:18:31 itojun Exp $ (LBL) + * @(#) $Header: /tcpdump/master/libpcap/pcap-namedb.h,v 1.8 2000/07/29 07:36:43 guy Exp $ (LBL) */ #ifndef lib_pcap_ethers_h #define lib_pcap_ethers_h +#ifdef __cplusplus +extern "C" { +#endif + /* * As returned by the pcap_next_etherent() * XXX this stuff doesn't belong in this interface, but this @@ -54,10 +58,9 @@ struct pcap_etherent *pcap_next_etherent(FILE *); u_char *pcap_ether_hostton(const char*); u_char *pcap_ether_aton(const char *); -#ifndef INET6 bpf_u_int32 **pcap_nametoaddr(const char *); -#else -struct addrinfo *pcap_nametoaddr(const char *); +#ifdef INET6 +struct addrinfo *pcap_nametoaddrinfo(const char *); #endif bpf_u_int32 pcap_nametonetaddr(const char *); @@ -77,4 +80,8 @@ int __pcap_atodn(const char *, bpf_u_int32 *); int __pcap_atoin(const char *, bpf_u_int32 *); u_short __pcap_nametodnaddr(const char *); +#ifdef __cplusplus +} +#endif + #endif diff --git a/contrib/libpcap/pcap-nit.c b/contrib/libpcap/pcap-nit.c index 649af09..6be658d 100644 --- a/contrib/libpcap/pcap-nit.c +++ b/contrib/libpcap/pcap-nit.c @@ -20,7 +20,11 @@ */ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.31.1.1 1999/10/07 23:46:40 mcr Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.39 2000/10/28 00:01:29 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" #endif #include <sys/types.h> @@ -49,7 +53,6 @@ static const char rcsid[] = #include "pcap-int.h" -#include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif @@ -91,7 +94,7 @@ pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) if (cc < 0) { if (errno == EWOULDBLOCK) return (0); - sprintf(p->errbuf, "pcap_read: %s", + snprintf(p->errbuf, sizeof(p->errbuf), "pcap_read: %s", pcap_strerror(errno)); return (-1); } @@ -125,7 +128,8 @@ pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) continue; default: - sprintf(p->errbuf, "bad nit state %d", nh->nh_state); + snprintf(p->errbuf, sizeof(p->errbuf), + "bad nit state %d", nh->nh_state); return (-1); } ++p->md.stat.ps_recv; @@ -157,7 +161,7 @@ nit_setflags(int fd, int promisc, int to_ms, char *ebuf) { struct nit_ioc nioc; - bzero((char *)&nioc, sizeof(nioc)); + memset(&nioc, 0, sizeof(nioc)); nioc.nioc_bufspace = BUFSPACE; nioc.nioc_chunksize = CHUNKSIZE; nioc.nioc_typetomatch = NT_ALLTYPES; @@ -174,7 +178,8 @@ nit_setflags(int fd, int promisc, int to_ms, char *ebuf) nioc.nioc_flags |= NF_PROMISC; if (ioctl(fd, SIOCSNIT, &nioc) < 0) { - sprintf(ebuf, "SIOCSNIT: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCSNIT: %s", + pcap_strerror(errno)); return (-1); } return (0); @@ -189,7 +194,7 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) p = (pcap_t *)malloc(sizeof(*p)); if (p == NULL) { - strcpy(ebuf, pcap_strerror(errno)); + strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); return (NULL); } @@ -199,18 +204,19 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) */ snaplen = 96; - bzero(p, sizeof(*p)); + memset(p, 0, sizeof(*p)); p->fd = fd = socket(AF_NIT, SOCK_RAW, NITPROTO_RAW); if (fd < 0) { - sprintf(ebuf, "socket: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "socket: %s", pcap_strerror(errno)); goto bad; } snit.snit_family = AF_NIT; (void)strncpy(snit.snit_ifname, device, NITIFSIZ); if (bind(fd, (struct sockaddr *)&snit, sizeof(snit))) { - sprintf(ebuf, "bind: %s: %s", snit.snit_ifname, - pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "bind: %s: %s", snit.snit_ifname, pcap_strerror(errno)); goto bad; } p->snapshot = snaplen; @@ -224,7 +230,7 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) p->bufsize = BUFSPACE; p->buffer = (u_char *)malloc(p->bufsize); if (p->buffer == NULL) { - strcpy(ebuf, pcap_strerror(errno)); + strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); goto bad; } return (p); @@ -239,6 +245,7 @@ int pcap_setfilter(pcap_t *p, struct bpf_program *fp) { - p->fcode = *fp; + if (install_bpf_program(p, fp) < 0) + return (-1); return (0); } diff --git a/contrib/libpcap/pcap-null.c b/contrib/libpcap/pcap-null.c index c0146bb..a4116ad 100644 --- a/contrib/libpcap/pcap-null.c +++ b/contrib/libpcap/pcap-null.c @@ -20,14 +20,17 @@ */ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/pcap-null.c,v 1.7.1.1 1999/10/07 23:46:40 mcr Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/pcap-null.c,v 1.13 2000/10/28 00:01:29 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" #endif #include <sys/param.h> /* optionally get BSD define */ #include <string.h> -#include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif @@ -39,35 +42,33 @@ static char nosup[] = "live packet capture not supported on this system"; int pcap_stats(pcap_t *p, struct pcap_stat *ps) { - - (void)sprintf(p->errbuf, "pcap_stats: %s", nosup); + (void)snprintf(p->errbuf, sizeof(p->errbuf), "pcap_stats: %s", nosup); return (-1); } int pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) { - - (void)sprintf(p->errbuf, "pcap_read: %s", nosup); + (void)snprintf(p->errbuf, sizeof(p->errbuf), "pcap_read: %s", nosup); return (-1); } pcap_t * pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) { - - (void)strcpy(ebuf, nosup); + (void)strlcpy(ebuf, nosup, PCAP_ERRBUF_SIZE); return (NULL); } int pcap_setfilter(pcap_t *p, struct bpf_program *fp) { - if (p->sf.rfile == NULL) { - (void)sprintf(p->errbuf, "pcap_setfilter: %s", nosup); + (void)snprintf(p->errbuf, sizeof(p->errbuf), + "pcap_setfilter: %s", nosup); return (-1); } - p->fcode = *fp; + if (install_bpf_program(p, fp) < 0) + return (-1); return (0); } diff --git a/contrib/libpcap/pcap-pf.c b/contrib/libpcap/pcap-pf.c index d2f3a37..2dec908 100644 --- a/contrib/libpcap/pcap-pf.c +++ b/contrib/libpcap/pcap-pf.c @@ -24,7 +24,11 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.54.1.1 1999/10/07 23:46:40 mcr Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.62 2000/10/28 00:01:30 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" #endif #include <sys/types.h> @@ -35,11 +39,8 @@ static const char rcsid[] = #include <sys/ioctl.h> #include <net/pfilt.h> -#if __STDC__ struct mbuf; struct rtentry; -#endif - #include <net/if.h> #include <netinet/in.h> @@ -62,7 +63,6 @@ struct rtentry; #include "pcap-int.h" -#include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif @@ -108,7 +108,7 @@ pcap_read(pcap_t *pc, int cnt, pcap_handler callback, u_char *user) (void)lseek(pc->fd, 0L, SEEK_SET); goto again; } - sprintf(pc->errbuf, "pf read: %s", + snprintf(pc->errbuf, sizeof(pc->errbuf), "pf read: %s", pcap_strerror(errno)); return (-1); } @@ -127,7 +127,8 @@ pcap_read(pcap_t *pc, int cnt, pcap_handler callback, u_char *user) #endif while (cc > 0) { if (cc < sizeof(*sp)) { - sprintf(pc->errbuf, "pf short read (%d)", cc); + snprintf(pc->errbuf, sizeof(pc->errbuf), + "pf short read (%d)", cc); return (-1); } #ifdef LBL_ALIGN @@ -138,7 +139,8 @@ pcap_read(pcap_t *pc, int cnt, pcap_handler callback, u_char *user) #endif sp = (struct enstamp *)bp; if (sp->ens_stamplen != sizeof(*sp)) { - sprintf(pc->errbuf, "pf short stamplen (%d)", + snprintf(pc->errbuf, sizeof(pc->errbuf), + "pf short stamplen (%d)", sp->ens_stamplen); return (-1); } @@ -210,13 +212,14 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) p = (pcap_t *)malloc(sizeof(*p)); if (p == NULL) { - sprintf(ebuf, "pcap_open_live: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "pcap_open_live: %s", pcap_strerror(errno)); return (0); } - bzero((char *)p, sizeof(*p)); + memset(p, 0, sizeof(*p)); p->fd = pfopen(device, O_RDONLY); if (p->fd < 0) { - sprintf(ebuf, "pf open: %s: %s\n\ + snprintf(ebuf, PCAP_ERRBUF_SIZE, "pf open: %s: %s\n\ your system may not be properly configured; see \"man packetfilter(4)\"\n", device, pcap_strerror(errno)); goto bad; @@ -226,7 +229,8 @@ your system may not be properly configured; see \"man packetfilter(4)\"\n", if (promisc) enmode |= ENPROMISC; if (ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode) < 0) { - sprintf(ebuf, "EIOCMBIS: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCMBIS: %s", + pcap_strerror(errno)); goto bad; } #ifdef ENCOPYALL @@ -236,12 +240,14 @@ your system may not be properly configured; see \"man packetfilter(4)\"\n", #endif /* set the backlog */ if (ioctl(p->fd, EIOCSETW, (caddr_t)&backlog) < 0) { - sprintf(ebuf, "EIOCSETW: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCSETW: %s", + pcap_strerror(errno)); goto bad; } /* discover interface type */ if (ioctl(p->fd, EIOCDEVP, (caddr_t)&devparams) < 0) { - sprintf(ebuf, "EIOCDEVP: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCDEVP: %s", + pcap_strerror(errno)); goto bad; } /* HACK: to compile prior to Ultrix 4.2 */ @@ -282,16 +288,18 @@ your system may not be properly configured; see \"man packetfilter(4)\"\n", snaplen += pcap_fddipad; #endif if (ioctl(p->fd, EIOCTRUNCATE, (caddr_t)&snaplen) < 0) { - sprintf(ebuf, "EIOCTRUNCATE: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCTRUNCATE: %s", + pcap_strerror(errno)); goto bad; } p->snapshot = snaplen; /* accept all packets */ - bzero((char *)&Filter, sizeof(Filter)); + memset(&Filter, 0, sizeof(Filter)); Filter.enf_Priority = 37; /* anything > 2 */ Filter.enf_FilterLen = 0; /* means "always true" */ if (ioctl(p->fd, EIOCSETF, (caddr_t)&Filter) < 0) { - sprintf(ebuf, "EIOCSETF: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCSETF: %s", + pcap_strerror(errno)); goto bad; } @@ -300,7 +308,7 @@ your system may not be properly configured; see \"man packetfilter(4)\"\n", timeout.tv_sec = to_ms / 1000; timeout.tv_usec = (to_ms * 1000) % 1000000; if (ioctl(p->fd, EIOCSRTIMEOUT, (caddr_t)&timeout) < 0) { - sprintf(ebuf, "EIOCSRTIMEOUT: %s", + snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCSRTIMEOUT: %s", pcap_strerror(errno)); goto bad; } @@ -326,8 +334,8 @@ pcap_setfilter(pcap_t *p, struct bpf_program *fp) struct bpf_version bv; if (ioctl(p->fd, BIOCVERSION, (caddr_t)&bv) < 0) { - sprintf(p->errbuf, "BIOCVERSION: %s", - pcap_strerror(errno)); + snprintf(p->errbuf, sizeof(p->errbuf), + "BIOCVERSION: %s", pcap_strerror(errno)); return (-1); } else if (bv.bv_major != BPF_MAJOR_VERSION || @@ -339,8 +347,10 @@ pcap_setfilter(pcap_t *p, struct bpf_program *fp) /* don't give up, just be inefficient */ p->md.use_bpf = 0; } - } else - p->fcode = *fp; + } else { + if (install_bpf_program(p, fp) < 0) + return (-1); + } /*XXX this goes in tcpdump*/ if (p->md.use_bpf) diff --git a/contrib/libpcap/pcap-snit.c b/contrib/libpcap/pcap-snit.c index ec9b44d8..59cf3ac 100644 --- a/contrib/libpcap/pcap-snit.c +++ b/contrib/libpcap/pcap-snit.c @@ -25,7 +25,11 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.45.1.1 1999/10/07 23:46:40 mcr Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.54 2000/10/28 00:01:30 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" #endif #include <sys/types.h> @@ -56,16 +60,12 @@ static const char rcsid[] = #include <ctype.h> #include <errno.h> -#ifdef HAVE_MALLOC_H -#include <malloc.h> -#endif #include <stdio.h> #include <string.h> #include <unistd.h> #include "pcap-int.h" -#include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif @@ -110,7 +110,7 @@ pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) if (cc < 0) { if (errno == EWOULDBLOCK) return (0); - sprintf(p->errbuf, "pcap_read: %s", + snprintf(p->errbuf, sizeof(p->errbuf), "pcap_read: %s", pcap_strerror(errno)); return (-1); } @@ -182,7 +182,8 @@ nit_setflags(int fd, int promisc, int to_ms, char *ebuf) si.ic_len = sizeof(timeout); si.ic_dp = (char *)&timeout; if (ioctl(fd, I_STR, (char *)&si) < 0) { - sprintf(ebuf, "NIOCSTIME: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCSTIME: %s", + pcap_strerror(errno)); return (-1); } } @@ -193,7 +194,8 @@ nit_setflags(int fd, int promisc, int to_ms, char *ebuf) si.ic_len = sizeof(flags); si.ic_dp = (char *)&flags; if (ioctl(fd, I_STR, (char *)&si) < 0) { - sprintf(ebuf, "NIOCSFLAGS: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCSFLAGS: %s", + pcap_strerror(errno)); return (-1); } return (0); @@ -211,7 +213,7 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) p = (pcap_t *)malloc(sizeof(*p)); if (p == NULL) { - strcpy(ebuf, pcap_strerror(errno)); + strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); return (NULL); } @@ -221,20 +223,23 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) */ snaplen = 96; - bzero(p, sizeof(*p)); + memset(p, 0, sizeof(*p)); p->fd = fd = open(dev, O_RDONLY); if (fd < 0) { - sprintf(ebuf, "%s: %s", dev, pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s", dev, + pcap_strerror(errno)); goto bad; } /* arrange to get discrete messages from the STREAM and use NIT_BUF */ if (ioctl(fd, I_SRDOPT, (char *)RMSGD) < 0) { - sprintf(ebuf, "I_SRDOPT: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "I_SRDOPT: %s", + pcap_strerror(errno)); goto bad; } if (ioctl(fd, I_PUSH, "nbuf") < 0) { - sprintf(ebuf, "push nbuf: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "push nbuf: %s", + pcap_strerror(errno)); goto bad; } /* set the chunksize */ @@ -243,7 +248,8 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) si.ic_len = sizeof(chunksize); si.ic_dp = (char *)&chunksize; if (ioctl(fd, I_STR, (char *)&si) < 0) { - sprintf(ebuf, "NIOCSCHUNK: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCSCHUNK: %s", + pcap_strerror(errno)); goto bad; } @@ -254,7 +260,7 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) si.ic_len = sizeof(ifr); si.ic_dp = (char *)𝔦 if (ioctl(fd, I_STR, (char *)&si) < 0) { - sprintf(ebuf, "NIOCBIND: %s: %s", + snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCBIND: %s: %s", ifr.ifr_name, pcap_strerror(errno)); goto bad; } @@ -264,7 +270,8 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) si.ic_len = sizeof(snaplen); si.ic_dp = (char *)&snaplen; if (ioctl(fd, I_STR, (char *)&si) < 0) { - sprintf(ebuf, "NIOCSSNAP: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCSSNAP: %s", + pcap_strerror(errno)); goto bad; } p->snapshot = snaplen; @@ -280,7 +287,7 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) p->bufsize = BUFSPACE; p->buffer = (u_char *)malloc(p->bufsize); if (p->buffer == NULL) { - strcpy(ebuf, pcap_strerror(errno)); + strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); goto bad; } return (p); @@ -295,6 +302,7 @@ int pcap_setfilter(pcap_t *p, struct bpf_program *fp) { - p->fcode = *fp; + if (install_bpf_program(p, fp) < 0) + return (-1); return (0); } diff --git a/contrib/libpcap/pcap-snoop.c b/contrib/libpcap/pcap-snoop.c index 1999c1b..65ad273 100644 --- a/contrib/libpcap/pcap-snoop.c +++ b/contrib/libpcap/pcap-snoop.c @@ -20,7 +20,11 @@ */ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.20.1.1 1999/10/07 23:46:40 mcr Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.30 2000/10/28 00:01:30 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" #endif #include <sys/param.h> @@ -50,7 +54,6 @@ static const char rcsid[] = #include "pcap-int.h" -#include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif @@ -76,7 +79,8 @@ again: case EWOULDBLOCK: return (0); /* XXX */ } - sprintf(p->errbuf, "read: %s", pcap_strerror(errno)); + snprintf(p->errbuf, sizeof(p->errbuf), + "read: %s", pcap_strerror(errno)); return (-1); } sh = (struct snoopheader *)p->buffer; @@ -104,9 +108,10 @@ pcap_stats(pcap_t *p, struct pcap_stat *ps) struct rawstats rawstats; rs = &rawstats; - bzero((char *)rs, sizeof(*rs)); + memset(rs, 0, sizeof(*rs)); if (ioctl(p->fd, SIOCRAWSTATS, (char *)rs) < 0) { - sprintf(p->errbuf, "SIOCRAWSTATS: %s", pcap_strerror(errno)); + snprintf(p->errbuf, sizeof(p->errbuf), + "SIOCRAWSTATS: %s", pcap_strerror(errno)); return (-1); } @@ -126,44 +131,41 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) struct sockaddr_raw sr; struct snoopfilter sf; u_int v; + int ll_hdrlen; + int snooplen; pcap_t *p; + struct ifreq ifr; p = (pcap_t *)malloc(sizeof(*p)); if (p == NULL) { - sprintf(ebuf, "malloc: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", + pcap_strerror(errno)); return (NULL); } - bzero((char *)p, sizeof(*p)); + memset(p, 0, sizeof(*p)); fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP); if (fd < 0) { - sprintf(ebuf, "snoop socket: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "snoop socket: %s", + pcap_strerror(errno)); goto bad; } p->fd = fd; - bzero((char *)&sr, sizeof(sr)); + memset(&sr, 0, sizeof(sr)); sr.sr_family = AF_RAW; (void)strncpy(sr.sr_ifname, device, sizeof(sr.sr_ifname)); if (bind(fd, (struct sockaddr *)&sr, sizeof(sr))) { - sprintf(ebuf, "snoop bind: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "snoop bind: %s", + pcap_strerror(errno)); goto bad; } - bzero((char *)&sf, sizeof(sf)); + memset(&sf, 0, sizeof(sf)); if (ioctl(fd, SIOCADDSNOOP, &sf) < 0) { - sprintf(ebuf, "SIOCADDSNOOP: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCADDSNOOP: %s", + pcap_strerror(errno)); goto bad; } v = 64 * 1024; (void)setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&v, sizeof(v)); - if (ioctl(fd, SIOCSNOOPLEN, &snaplen) < 0) { - sprintf(ebuf, "SIOCSNOOPLEN: %s", pcap_strerror(errno)); - goto bad; - } - p->snapshot = snaplen; - v = 1; - if (ioctl(fd, SIOCSNOOPING, &v) < 0) { - sprintf(ebuf, "SIOCSNOOPING: %s", pcap_strerror(errno)); - goto bad; - } /* * XXX hack - map device name to link layer type */ @@ -176,27 +178,88 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) strncmp("ep", device, 2) == 0 || /* Challenge 8x10 Mbit EPLEX */ strncmp("vfe", device, 3) == 0 || /* Challenge VME 100Mbit */ strncmp("fa", device, 2) == 0 || - strncmp("qaa", device, 3) == 0) { + strncmp("qaa", device, 3) == 0 || + strncmp("el", device, 2) == 0) { p->linktype = DLT_EN10MB; p->offset = RAW_HDRPAD(sizeof(struct ether_header)); + ll_hdrlen = sizeof(struct ether_header); } else if (strncmp("ipg", device, 3) == 0 || strncmp("rns", device, 3) == 0 || /* O2/200/2000 FDDI */ strncmp("xpi", device, 3) == 0) { p->linktype = DLT_FDDI; p->offset = 3; /* XXX yeah? */ + ll_hdrlen = 13; } else if (strncmp("ppp", device, 3) == 0) { p->linktype = DLT_RAW; + ll_hdrlen = 0; /* DLT_RAW meaning "no PPP header, just the IP packet"? */ } else if (strncmp("lo", device, 2) == 0) { p->linktype = DLT_NULL; + ll_hdrlen = 4; /* is this just like BSD's loopback device? */ } else { - sprintf(ebuf, "snoop: unknown physical layer type"); + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "snoop: unknown physical layer type"); + goto bad; + } +#ifdef SIOCGIFMTU + /* + * XXX - IRIX appears to give you an error if you try to set the + * capture length to be greater than the MTU, so let's try to get + * the MTU first and, if that succeeds, trim the snap length + * to be no greater than the MTU. + */ + (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); + if (ioctl(fd, SIOCGIFMTU, (char *)&ifr) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCGIFMTU: %s", + pcap_strerror(errno)); + goto bad; + } + /* + * OK, we got it. + * + * XXX - some versions of IRIX 6.5 define "ifr_mtu" and have an + * "ifru_metric" member of the "ifr_ifru" union in an "ifreq" + * structure, others don't. + * + * I've no idea what's going on, so, if "ifr_mtu" isn't defined, + * we define it as "ifr_metric", as using that field appears to + * work on the versions that lack "ifr_mtu" (and, on those that + * don't lack it, "ifru_metric" and "ifru_mtu" are both "int" + * members of the "ifr_ifru" union, which suggests that they + * may be interchangeable in this case). + */ +#ifndef ifr_mtu +#define ifr_mtu ifr_metric +#endif + if (snaplen > ifr.ifr_mtu) + snaplen = ifr.ifr_mtu; +#endif + + /* + * The argument to SIOCSNOOPLEN is the number of link-layer + * payload bytes to capture - it doesn't count link-layer + * header bytes. + */ + snooplen = snaplen - ll_hdrlen; + if (snooplen < 0) + snooplen = 0; + if (ioctl(fd, SIOCSNOOPLEN, &snooplen) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPLEN: %s", + pcap_strerror(errno)); + goto bad; + } + p->snapshot = snaplen; + v = 1; + if (ioctl(fd, SIOCSNOOPING, &v) < 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPING: %s", + pcap_strerror(errno)); goto bad; } p->bufsize = 4096; /* XXX */ p->buffer = (u_char *)malloc(p->bufsize); if (p->buffer == NULL) { - sprintf(ebuf, "malloc: %s", pcap_strerror(errno)); + snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", + pcap_strerror(errno)); goto bad; } @@ -211,6 +274,7 @@ int pcap_setfilter(pcap_t *p, struct bpf_program *fp) { - p->fcode = *fp; + if (install_bpf_program(p, fp) < 0) + return (-1); return (0); } diff --git a/contrib/libpcap/pcap.3 b/contrib/libpcap/pcap.3 index c358c63..77fd072 100644 --- a/contrib/libpcap/pcap.3 +++ b/contrib/libpcap/pcap.3 @@ -1,3 +1,5 @@ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap.3,v 1.17.2.1 2001/01/18 04:42:11 guy Exp $ +.\" .\" Copyright (c) 1994, 1996, 1997 .\" The Regents of the University of California. All rights reserved. .\" @@ -17,7 +19,7 @@ .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" -.TH PCAP 3 "24 June 1998" +.TH PCAP 3 "3 January 2001" .SH NAME pcap \- Packet Capture library .SH SYNOPSIS @@ -30,6 +32,7 @@ pcap \- Packet Capture library pcap_t *pcap_open_live(char *device, int snaplen, .ti +8 int promisc, int to_ms, char *ebuf) +pcap_t *pcap_open_dead(int linktype, int snaplen) pcap_t *pcap_open_offline(char *fname, char *ebuf) pcap_dumper_t *pcap_dump_open(pcap_t *p, char *fname) .ft @@ -59,6 +62,7 @@ int pcap_compile(pcap_t *p, struct bpf_program *fp, .ti +8 char *str, int optimize, bpf_u_int32 netmask) int pcap_setfilter(pcap_t *p, struct bpf_program *fp) +void pcap_freecode(struct bpf_program *); .ft .LP .ft B @@ -91,25 +95,57 @@ on the network, even those destined for other hosts, are accessible through this mechanism. .PP .SH ROUTINES +NOTE: +.I errbuf +in +.B pcap_open_live(), +.B pcap_open_offline(), +.B pcap_lookupdev(), +and +.B pcap_lookupnet() +is assumed to be able to hold at least +.B PCAP_ERRBUF_SIZE +chars. +.PP .B pcap_open_live() is used to obtain a packet capture descriptor to look at packets on the network. .I device -is a string that specifies the network device to open. +is a string that specifies the network device to open; on Linux systems +with 2.2 or later kernels, a +.I device +argument of "any" or +.B NULL +can be used to capture packets from all interfaces. .I snaplen specifies the maximum number of bytes to capture. .I promisc specifies if the interface is to be put into promiscuous mode. (Note that even if this parameter is false, the interface -could well be in promiscuous mode for some other reason.) +could well be in promiscuous mode for some other reason.) For now, this +doesn't work on the "any" device; if an argument of "any" or NULL is +supplied, the +.I promisc +flag is ignored. .I to_ms -specifies the read timeout in milliseconds. +specifies the read timeout in milliseconds. The read timeout is used to +arrange that the read not necessarily return immediately when a packet +is seen, but that it wait for some amount of time to allow more packets +to arrive and to read multiple packets from the OS kernel in one +operation. Not all platforms support a read timeout; on platforms that +don't, the read timeout is ignored. .I ebuf is used to return error text and is only set when .B pcap_open_live() fails and returns .BR NULL . .PP +.B pcap_open_dead() +is used for creating a +.B pcap_t +structure to use when calling the other functions in libpcap. It is +typically used when just using libpcap for compiling BPF code. +.PP .B pcap_open_offline() is called to open a ``savefile'' for reading. .I fname @@ -156,7 +192,7 @@ If there is an error, .B NULL is returned and .I errbuf -is filled in with with an appropriate error message. +is filled in with an appropriate error message. .PP .B pcap_lookupnet() is used to determine the network number and mask @@ -169,21 +205,22 @@ and are .I bpf_u_int32 pointers. -A return of -1 indicates an error in which case +A return of \-1 indicates an error in which case .I errbuf -is filled in with with an appropriate error message. +is filled in with an appropriate error message. .PP .B pcap_dispatch() is used to collect and process packets. .I cnt -specifies the maximum number of packets to process before returning. A +specifies the maximum number of packets to process before returning. +This is not a minimum number; when reading a live capture, only one +bufferful of packets is read at a time, so fewer than .I cnt -of -1 processes all the packets received in one buffer. A +packets may be processed. A .I cnt -of 0 processes all packets until an error occurs, -.B EOF -is reached, or the read times out (when doing live reads and a non-zero -read timeout is specified). +of \-1 processes all the packets received in one buffer when reading a +live capture, or all the packets in the file when reading a +``savefile''. .I callback specifies a routine to be called with three arguments: a @@ -195,21 +232,69 @@ a pointer to the struct (which precede the actual network headers and data), and a .I u_char -pointer to the packet data. The number of packets read is returned. -Zero is returned when -.B EOF -is reached in a ``savefile.'' A return of -1 indicates +pointer to the packet data. +.PP +The number of packets read is returned. +0 is returned if no packets were read from a live capture (if, for +example, they were discarded because they didn't pass the packet filter, +or if, on platforms that support a read timeout that starts before any +packets arrive, the timeout expires before any packets arrive, or if the +file descriptor for the capture device is in non-blocking mode and no +packets were available to be read) or if no more packets are available +in a ``savefile.'' A return of \-1 indicates an error in which case .B pcap_perror() or -.BR pcap_geterr() +.B pcap_geterr() may be used to display the error text. .PP +.BR NOTE : +when reading a live capture, +.B pcap_dispatch() +will not necessarily return when the read times out; on some platforms, +the read timeout isn't supported, and, on other platforms, the timer +doesn't start until at least one packet arrives. This means that the +read timeout should +.B NOT +be used in, for example, an interactive application, to allow the packet +capture loop to ``poll'' for user input periodically, as there's no +guarantee that +.B pcap_dispatch() +will return after the timeout expires. +.PP +.B pcap_loop() +is similar to +.B pcap_dispatch() +except it keeps reading packets until +.I cnt +packets are processed or an error occurs. +It does +.B not +return when live read timeouts occur. +Rather, specifying a non-zero read timeout to +.B pcap_open_live() +and then calling +.B pcap_dispatch() +allows the reception and processing of any packets that arrive when the +timeout occurs. +A negative +.I cnt +causes +.B pcap_loop() +to loop forever (or at least until an error occurs). +.PP +.B pcap_next() +returns a +.I u_char +pointer to the next packet. +.PP .B pcap_dump() outputs a packet to the ``savefile'' opened with .BR pcap_dump_open() . Note that its calling arguments are suitable for use with -.BR pcap_dispatch() . +.B pcap_dispatch() +or +.BR pcap_loop() . .PP .B pcap_compile() is used to compile the string @@ -224,53 +309,51 @@ struct and is filled in by controls whether optimization on the resulting code is performed. .I netmask specifies the netmask of the local net. +A return of \-1 indicates an error in which case +.BR pcap_geterr() +may be used to display the error text. .PP .B pcap_compile_nopcap() is similar to .B pcap_compile() except that instead of passing a pcap structure, one passes the snaplen and linktype explicitly. It is intended to be used for -compiling filters for direct bpf usage, without necessarily having +compiling filters for direct BPF usage, without necessarily having called .BR pcap_open() . +A return of \-1 indicates an error; the error text is unavailable. +.RB ( pcap_compile_nopcap() +is a wrapper around +.BR pcap_open_dead() , +.BR pcap_compile() , +and +.BR pcap_close() ; +the latter three routines can be used directly in order to get the error +text for a compilation error.) +.B .PP .B pcap_setfilter() is used to specify a filter program. .I fp -is a pointer to an array of +is a pointer to a .I bpf_program struct, usually the result of a call to .BR pcap_compile() . .B \-1 -is returned on failure; +is returned on failure, in which case +.BR pcap_geterr() +may be used to display the error text; .B 0 is returned on success. .PP -.B pcap_loop() -is similar to -.B pcap_dispatch() -except it keeps reading packets until -.I cnt -packets are processed or an error occurs. -It does -.B not -return when live read timeouts occur. -Rather, specifying a non-zero read timeout to -.B pcap_open_live() -and then calling -.B pcap_dispatch() -allows the reception and processing of any packets that arrive when the -timeout occurs. -A negative -.I cnt -causes -.B pcap_loop() -to loop forever (or at least until an error occurs). -.PP -.B pcap_next() -returns a -.I u_char -pointer to the next packet. +.B pcap_freecode() +is used to free up allocated memory pointed to by a +.I bpf_program +struct generated by +.B pcap_compile() +when that BPF program is no longer needed, for example after it +has been made the filter program for a pcap structure by a call to +.BR pcap_setfilter() . .PP .B pcap_datalink() returns the link layer type, e.g. @@ -301,7 +384,7 @@ returns 0 and fills in a .B pcap_stat struct. The values represent packet statistics from the start of the run to the time of the call. If there is an error or the under lying -packet capture doesn't support packet statistics, -1 is returned and +packet capture doesn't support packet statistics, \-1 is returned and the error text can be obtained with .B pcap_perror() or @@ -318,6 +401,13 @@ prefixed by .PP .B pcap_geterr() returns the error text pertaining to the last pcap library error. +.BR NOTE : +the pointer it returns will no longer point to a valid error message +string after the +.B pcap_t +passed to it is closed; you must use or copy the string before closing +the +.BR pcap_t . .PP .B pcap_strerror() is provided in case @@ -335,15 +425,27 @@ closes the ``savefile.'' .SH SEE ALSO tcpdump(1), tcpslice(1) .SH AUTHORS +The original authors are: +.LP Van Jacobson, Craig Leres and Steven McCanne, all of the Lawrence Berkeley National Laboratory, University of California, Berkeley, CA. .LP -The current version is available via anonymous ftp: +The current version is available from "The Tcpdump Group"'s Web site at .LP .RS -.I ftp://ftp.ee.lbl.gov/libpcap.tar.Z +.I http://www.tcpdump.org/ .RE .SH BUGS -Please send bug reports to libpcap@ee.lbl.gov. +Please send problems, bugs, questions, desirable enhancements, etc. to: +.LP +.RS +tcpdump-workers@tcpdump.org +.RE +.LP +Please send source code contributions, etc. to: +.LP +.RS +patches@tcpdump.org +.RE diff --git a/contrib/libpcap/pcap.c b/contrib/libpcap/pcap.c index 3b857f6..9f32721 100644 --- a/contrib/libpcap/pcap.c +++ b/contrib/libpcap/pcap.c @@ -33,7 +33,11 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.29.1.1 1999/10/07 23:46:40 mcr Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.36 2000/12/16 10:43:31 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" #endif #include <sys/types.h> @@ -43,7 +47,6 @@ static const char rcsid[] = #include <string.h> #include <unistd.h> -#include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif @@ -180,27 +183,44 @@ pcap_strerror(int errnum) if ((unsigned int)errnum < sys_nerr) return ((char *)sys_errlist[errnum]); - (void)sprintf(ebuf, "Unknown error: %d", errnum); + (void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum); return(ebuf); #endif } +pcap_t * +pcap_open_dead(int linktype, int snaplen) +{ + pcap_t *p; + + p = malloc(sizeof(*p)); + if (p == NULL) + return NULL; + memset (p, 0, sizeof(*p)); + p->fd = -1; + p->snapshot = snaplen; + p->linktype = linktype; + return p; +} + void pcap_close(pcap_t *p) { /*XXX*/ - if (p->fd >= 0) + if (p->fd >= 0) { +#ifdef linux + pcap_close_linux(p); +#endif close(p->fd); + } if (p->sf.rfile != NULL) { - (void)fclose(p->sf.rfile); + if (p->sf.rfile != stdin) + (void)fclose(p->sf.rfile); if (p->sf.base != NULL) free(p->sf.base); } else if (p->buffer != NULL) free(p->buffer); -#ifdef linux - if (p->md.device != NULL) - free(p->md.device); -#endif + pcap_freecode(&p->fcode); free(p); } diff --git a/contrib/libpcap/pcap.h b/contrib/libpcap/pcap.h index 7316386..de92cfb 100644 --- a/contrib/libpcap/pcap.h +++ b/contrib/libpcap/pcap.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.h,v 1.22 1999/12/08 19:54:03 mcr Exp $ (LBL) + * @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.31 2000/10/28 00:01:31 guy Exp $ (LBL) */ #ifndef lib_pcap_h @@ -43,6 +43,10 @@ #include <stdio.h> +#ifdef __cplusplus +extern "C" { +#endif + #define PCAP_VERSION_MAJOR 2 #define PCAP_VERSION_MINOR 4 @@ -65,6 +69,34 @@ typedef struct pcap_dumper pcap_dumper_t; * of the flags used in the printout phases of tcpdump. * Many fields here are 32 bit ints so compilers won't insert unwanted * padding; these files need to be interchangeable across architectures. + * + * Do not change the layout of this structure, in any way (this includes + * changes that only affect the length of fields in this structure). + * + * Also, do not change the interpretation of any of the members of this + * structure, in any way (this includes using values other than + * LINKTYPE_ values, as defined in "savefile.c", in the "linktype" + * field). + * + * Instead: + * + * introduce a new structure for the new format, if the layout + * of the structure changed; + * + * send mail to "tcpdump-workers@tcpdump.org", requesting a new + * magic number for your new capture file format, and, when + * you get the new magic number, put it in "savefile.c"; + * + * use that magic number for save files with the changed file + * header; + * + * make the code in "savefile.c" capable of reading files with + * the old file header as well as files with the new file header + * (using the magic number to determine the header format). + * + * Then supply the changes to "patches@tcpdump.org", so that future + * versions of libpcap and programs that use it (such as tcpdump) will + * be able to read your new capture file format. */ struct pcap_file_header { bpf_u_int32 magic; @@ -73,7 +105,7 @@ struct pcap_file_header { bpf_int32 thiszone; /* gmt to local correction */ bpf_u_int32 sigfigs; /* accuracy of timestamps */ bpf_u_int32 snaplen; /* max length saved portion of each pkt */ - bpf_u_int32 linktype; /* data link type (DLT_*) */ + bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */ }; /* @@ -102,6 +134,7 @@ typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, char *pcap_lookupdev(char *); int pcap_lookupnet(char *, bpf_u_int32 *, bpf_u_int32 *, char *); pcap_t *pcap_open_live(char *, int, int, int, char *); +pcap_t *pcap_open_dead(int, int); pcap_t *pcap_open_offline(const char *, char *); void pcap_close(pcap_t *); int pcap_loop(pcap_t *, int, pcap_handler, u_char *); @@ -117,8 +150,7 @@ int pcap_compile(pcap_t *, struct bpf_program *, char *, int, bpf_u_int32); int pcap_compile_nopcap(int, int, struct bpf_program *, char *, int, bpf_u_int32); -/* XXX */ -int pcap_freecode(pcap_t *, struct bpf_program *); +void pcap_freecode(struct bpf_program *); int pcap_datalink(pcap_t *); int pcap_snapshot(pcap_t *); int pcap_is_swapped(pcap_t *); @@ -135,5 +167,12 @@ void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *); /* XXX this guy lives in the bpf tree */ u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int); +int bpf_validate(struct bpf_insn *f, int len); char *bpf_image(struct bpf_insn *, int); +void bpf_dump(struct bpf_program *, int); + +#ifdef __cplusplus +} +#endif + #endif diff --git a/contrib/libpcap/savefile.c b/contrib/libpcap/savefile.c index c92aef2..cc5b47e 100644 --- a/contrib/libpcap/savefile.c +++ b/contrib/libpcap/savefile.c @@ -30,7 +30,11 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.38 1999/11/21 01:11:58 assar Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.49 2000/12/21 10:29:23 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" #endif #include <sys/types.h> @@ -40,16 +44,17 @@ static const char rcsid[] = #include <memory.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <unistd.h> #include "pcap-int.h" -#include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif #define TCPDUMP_MAGIC 0xa1b2c3d4 +#define PATCHED_TCPDUMP_MAGIC 0xa1b2cd34 /* * We use the "receiver-makes-right" approach to byte order, @@ -71,6 +76,212 @@ static const char rcsid[] = #define SFERR_BADF 3 #define SFERR_EOF 4 /* not really an error, just a status */ +/* + * We don't write DLT_* values to the capture file header, because + * they're not the same on all platforms. + * + * Unfortunately, the various flavors of BSD have not always used the same + * numerical values for the same data types, and various patches to + * libpcap for non-BSD OSes have added their own DLT_* codes for link + * layer encapsulation types seen on those OSes, and those codes have had, + * in some cases, values that were also used, on other platforms, for other + * link layer encapsulation types. + * + * This means that capture files of a type whose numerical DLT_* code + * means different things on different BSDs, or with different versions + * of libpcap, can't always be read on systems other than those like + * the one running on the machine on which the capture was made. + * + * Instead, we define here a set of LINKTYPE_* codes, and map DLT_* codes + * to LINKTYPE_* codes when writing a savefile header, and map LINKTYPE_* + * codes to DLT_* codes when reading a savefile header. + * + * For those DLT_* codes that have, as far as we know, the same values on + * all platforms (DLT_NULL through DLT_FDDI), we define LINKTYPE_xxx as + * DLT_xxx; that way, captures of those types can still be read by + * versions of libpcap that map LINKTYPE_* values to DLT_* values, and + * captures of those types written by versions of libpcap that map DLT_ + * values to LINKTYPE_ values can still be read by older versions + * of libpcap. + * + * The other LINKTYPE_* codes are given values starting at 100, in the + * hopes that no DLT_* code will be given one of those values. + * + * In order to ensure that a given LINKTYPE_* code's value will refer to + * the same encapsulation type on all platforms, you should not allocate + * a new LINKTYPE_* value without consulting "tcpdump-workers@tcpdump.org". + * The tcpdump developers will allocate a value for you, and will not + * subsequently allocate it to anybody else; that value will be added to + * the "pcap.h" in the tcpdump.org CVS repository, so that a future + * libpcap release will include it. + * + * You should, if possible, also contribute patches to libpcap and tcpdump + * to handle the new encapsulation type, so that they can also be checked + * into the tcpdump.org CVS repository and so that they will appear in + * future libpcap and tcpdump releases. + */ +#define LINKTYPE_NULL DLT_NULL +#define LINKTYPE_ETHERNET DLT_EN10MB /* also for 100Mb and up */ +#define LINKTYPE_EXP_ETHERNET DLT_EN3MB /* 3Mb experimental Ethernet */ +#define LINKTYPE_AX25 DLT_AX25 +#define LINKTYPE_PRONET DLT_PRONET +#define LINKTYPE_CHAOS DLT_CHAOS +#define LINKTYPE_TOKEN_RING DLT_IEEE802 /* DLT_IEEE802 is used for Token Ring */ +#define LINKTYPE_ARCNET DLT_ARCNET +#define LINKTYPE_SLIP DLT_SLIP +#define LINKTYPE_PPP DLT_PPP +#define LINKTYPE_FDDI DLT_FDDI + +/* + * LINKTYPE_PPP is for use when there might, or might not, be an RFC 1662 + * PPP in HDLC-like framing header (with 0xff 0x03 before the PPP protocol + * field) at the beginning of the packet. + * + * This is for use when there is always such a header; the address field + * might be 0xff, for regular PPP, or it might be an address field for Cisco + * point-to-point with HDLC framing as per section 4.3.1 of RFC 1547 ("Cisco + * HDLC"). This is, for example, what you get with NetBSD's DLT_PPP_SERIAL. + * + * We give it the same value as NetBSD's DLT_PPP_SERIAL, in the hopes that + * nobody else will choose a DLT_ value of 50, and so that DLT_PPP_SERIAL + * captures will be written out with a link type that NetBSD's tcpdump + * can read. + */ +#define LINKTYPE_PPP_HDLC 50 /* PPP in HDLC-like framing */ + +#define LINKTYPE_ATM_RFC1483 100 /* LLC/SNAP-encapsulated ATM */ +#define LINKTYPE_RAW 101 /* raw IP */ +#define LINKTYPE_SLIP_BSDOS 102 /* BSD/OS SLIP BPF header */ +#define LINKTYPE_PPP_BSDOS 103 /* BSD/OS PPP BPF header */ +#define LINKTYPE_C_HDLC 104 /* Cisco HDLC */ +#define LINKTYPE_ATM_CLIP 106 /* Linux Classical IP over ATM */ + +/* + * Reserved for future use. + */ +#define LINKTYPE_IEEE802_11 105 /* IEEE 802.11 (wireless) */ +#define LINKTYPE_FR 107 /* BSD/OS Frame Relay */ +#define LINKTYPE_LOOP 108 /* OpenBSD loopback */ +#define LINKTYPE_ENC 109 /* OpenBSD IPSEC enc */ +#define LINKTYPE_LANE8023 110 /* ATM LANE + 802.3 */ +#define LINKTYPE_HIPPI 111 /* NetBSD HIPPI */ +#define LINKTYPE_HDLC 112 /* NetBSD HDLC framing */ + +#define LINKTYPE_LINUX_SLL 113 /* Linux cooked socket capture */ + +static struct linktype_map { + int dlt; + int linktype; +} map[] = { + /* + * These DLT_* codes have LINKTYPE_* codes with values identical + * to the values of the corresponding DLT_* code. + */ + { DLT_NULL, LINKTYPE_NULL }, + { DLT_EN10MB, LINKTYPE_ETHERNET }, + { DLT_EN3MB, LINKTYPE_EXP_ETHERNET }, + { DLT_AX25, LINKTYPE_AX25 }, + { DLT_PRONET, LINKTYPE_PRONET }, + { DLT_CHAOS, LINKTYPE_CHAOS }, + { DLT_IEEE802, LINKTYPE_TOKEN_RING }, + { DLT_ARCNET, LINKTYPE_ARCNET }, + { DLT_SLIP, LINKTYPE_SLIP }, + { DLT_PPP, LINKTYPE_PPP }, + { DLT_FDDI, LINKTYPE_FDDI }, + + /* + * These DLT_* codes have different values on different + * platforms; we map them to LINKTYPE_* codes that + * have values that should never be equal to any DLT_* + * code. + */ + { DLT_ATM_RFC1483, LINKTYPE_ATM_RFC1483 }, + { DLT_RAW, LINKTYPE_RAW }, + { DLT_SLIP_BSDOS, LINKTYPE_SLIP_BSDOS }, + { DLT_PPP_BSDOS, LINKTYPE_PPP_BSDOS }, + + /* BSD/OS Cisco HDLC */ + { DLT_C_HDLC, LINKTYPE_C_HDLC }, + + /* + * These DLT_* codes are not on all platforms, but, so far, + * there don't appear to be any platforms that define + * other codes with those values; we map them to + * different LINKTYPE_* values anyway, just in case. + */ + + /* Linux ATM Classical IP */ + { DLT_ATM_CLIP, LINKTYPE_ATM_CLIP }, + + /* NetBSD sync/async serial PPP (or Cisco HDLC) */ + { DLT_PPP_SERIAL, LINKTYPE_PPP_HDLC }, + + /* IEEE 802.11 wireless */ + { DLT_IEEE802_11, LINKTYPE_IEEE802_11 }, + + /* OpenBSD loopback */ + { DLT_LOOP, LINKTYPE_LOOP }, + + /* Linux cooked socket capture */ + { DLT_LINUX_SLL, LINKTYPE_LINUX_SLL }, + + /* + * Any platform that defines additional DLT_* codes should: + * + * request a LINKTYPE_* code and value from tcpdump.org, + * as per the above; + * + * add, in their version of libpcap, an entry to map + * those DLT_* codes to the corresponding LINKTYPE_* + * code; + * + * redefine, in their "net/bpf.h", any DLT_* values + * that collide with the values used by their additional + * DLT_* codes, to remove those collisions (but without + * making them collide with any of the LINKTYPE_* + * values equal to 50 or above; they should also avoid + * defining DLT_* values that collide with those + * LINKTYPE_* values, either). + */ + { -1, -1 } +}; + +static int +dlt_to_linktype(int dlt) +{ + int i; + + for (i = 0; map[i].dlt != -1; i++) { + if (map[i].dlt == dlt) + return (map[i].linktype); + } + + /* + * If we don't have a mapping for this DLT_ code, return an + * error; that means that the table above needs to have an + * entry added. + */ + return (-1); +} + +static int +linktype_to_dlt(int linktype) +{ + int i; + + for (i = 0; map[i].linktype != -1; i++) { + if (map[i].linktype == linktype) + return (map[i].dlt); + } + + /* + * If we don't have an entry for this link type, return + * the link type value; it may be a DLT_ value from an + * older version of libpcap. + */ + return linktype; +} + static int sf_write_header(FILE *fp, int linktype, int thiszone, int snaplen) { @@ -108,11 +319,12 @@ pcap_open_offline(const char *fname, char *errbuf) register pcap_t *p; register FILE *fp; struct pcap_file_header hdr; + bpf_u_int32 magic; int linklen; p = (pcap_t *)malloc(sizeof(*p)); if (p == NULL) { - strcpy(errbuf, "out of swap"); + strlcpy(errbuf, "out of swap", PCAP_ERRBUF_SIZE); return (NULL); } @@ -127,29 +339,44 @@ pcap_open_offline(const char *fname, char *errbuf) else { fp = fopen(fname, "r"); if (fp == NULL) { - sprintf(errbuf, "%s: %s", fname, pcap_strerror(errno)); + snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname, + pcap_strerror(errno)); goto bad; } } if (fread((char *)&hdr, sizeof(hdr), 1, fp) != 1) { - sprintf(errbuf, "fread: %s", pcap_strerror(errno)); + snprintf(errbuf, PCAP_ERRBUF_SIZE, "fread: %s", + pcap_strerror(errno)); goto bad; } - if (hdr.magic != TCPDUMP_MAGIC) { - if (SWAPLONG(hdr.magic) != TCPDUMP_MAGIC) { - sprintf(errbuf, "bad dump file format"); + magic = hdr.magic; + if (magic != TCPDUMP_MAGIC && magic != PATCHED_TCPDUMP_MAGIC) { + magic = SWAPLONG(magic); + if (magic != TCPDUMP_MAGIC && magic != PATCHED_TCPDUMP_MAGIC) { + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "bad dump file format"); goto bad; } p->sf.swapped = 1; swap_hdr(&hdr); } + if (magic == PATCHED_TCPDUMP_MAGIC) { + /* + * XXX - the patch that's in some versions of libpcap + * changes the packet header but not the magic number; + * we'd have to use some hacks^H^H^H^H^Hheuristics to + * detect that. + */ + p->sf.hdrsize = sizeof(struct pcap_sf_patched_pkthdr); + } else + p->sf.hdrsize = sizeof(struct pcap_sf_pkthdr); if (hdr.version_major < PCAP_VERSION_MAJOR) { - sprintf(errbuf, "archaic file format"); + snprintf(errbuf, PCAP_ERRBUF_SIZE, "archaic file format"); goto bad; } p->tzoff = hdr.thiszone; p->snapshot = hdr.snaplen; - p->linktype = hdr.linktype; + p->linktype = linktype_to_dlt(hdr.linktype); p->sf.rfile = fp; p->bufsize = hdr.snaplen; @@ -171,7 +398,13 @@ pcap_open_offline(const char *fname, char *errbuf) break; } + if (p->bufsize < 0) + p->bufsize = BPF_MAXBUFSIZE; p->sf.base = (u_char *)malloc(p->bufsize + BPF_ALIGNMENT); + if (p->sf.base == NULL) { + strlcpy(errbuf, "out of swap", PCAP_ERRBUF_SIZE); + goto bad; + } p->buffer = p->sf.base + BPF_ALIGNMENT - (linklen % BPF_ALIGNMENT); p->sf.version_major = hdr.version_major; p->sf.version_minor = hdr.version_minor; @@ -194,11 +427,17 @@ pcap_open_offline(const char *fname, char *errbuf) static int sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen) { - struct pcap_sf_pkthdr sf_hdr; + struct pcap_sf_patched_pkthdr sf_hdr; FILE *fp = p->sf.rfile; - /* read the stamp */ - if (fread(&sf_hdr, sizeof(struct pcap_sf_pkthdr), 1, fp) != 1) { + /* + * Read the packet header; the structure we use as a buffer + * is the longer structure for files generated by the patched + * libpcap, but if the file has the magic number for an + * unpatched libpcap we only read as many bytes as the regular + * header has. + */ + if (fread(&sf_hdr, p->sf.hdrsize, 1, fp) != 1) { /* probably an EOF, though could be a truncated packet */ return (1); } @@ -239,9 +478,11 @@ sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen) static int tsize = 0; if (hdr->caplen > 65535) { - sprintf(p->errbuf, "bogus savefile header"); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "bogus savefile header"); return (-1); } + if (tsize < hdr->caplen) { tsize = ((hdr->caplen + 1023) / 1024) * 1024; if (tp != NULL) @@ -249,12 +490,14 @@ sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen) tp = (u_char *)malloc(tsize); if (tp == NULL) { tsize = 0; - sprintf(p->errbuf, "BUFMOD hack malloc"); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "BUFMOD hack malloc"); return (-1); } } if (fread((char *)tp, hdr->caplen, 1, fp) != 1) { - sprintf(p->errbuf, "truncated dump file"); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "truncated dump file"); return (-1); } /* @@ -271,7 +514,8 @@ sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen) /* read the packet itself */ if (fread((char *)buf, hdr->caplen, 1, fp) != 1) { - sprintf(p->errbuf, "truncated dump file"); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "truncated dump file"); return (-1); } } @@ -336,17 +580,27 @@ pcap_dumper_t * pcap_dump_open(pcap_t *p, const char *fname) { FILE *f; + int linktype; + + linktype = dlt_to_linktype(p->linktype); + if (linktype == -1) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "%s: link-layer type %d isn't supported in savefiles", + fname, linktype); + return (NULL); + } + if (fname[0] == '-' && fname[1] == '\0') f = stdout; else { f = fopen(fname, "w"); if (f == NULL) { - sprintf(p->errbuf, "%s: %s", + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname, pcap_strerror(errno)); return (NULL); } } - (void)sf_write_header(f, p->linktype, p->tzoff, p->snapshot); + (void)sf_write_header(f, linktype, p->tzoff, p->snapshot); return ((pcap_dumper_t *)f); } diff --git a/contrib/libpcap/scanner.l b/contrib/libpcap/scanner.l index 6b973fb..b3f7ba1 100644 --- a/contrib/libpcap/scanner.l +++ b/contrib/libpcap/scanner.l @@ -22,7 +22,11 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.60 1999/11/17 04:09:58 assar Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.70 2000/10/28 10:18:40 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" #endif #include <sys/types.h> @@ -39,10 +43,13 @@ static const char rcsid[] = #ifdef INET6 #include <netdb.h> #include <sys/socket.h> +/* Workaround for AIX 4.3 */ +#if !defined(AI_NUMERICHOST) +#define AI_NUMERICHOST 0x04 +#endif #endif /*INET6*/ #include "tokdefs.h" -#include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif @@ -52,22 +59,10 @@ static inline int xdtoi(int); #ifdef FLEX_SCANNER #define YY_NO_UNPUT -#undef YY_INPUT -#define YY_INPUT(buf, result, max)\ - {\ - char *src = in_buffer;\ - int i;\ -\ - if (*src == 0)\ - result = YY_NULL;\ - else {\ - for (i = 0; *src && i < max; ++i)\ - buf[i] = *src++;\ - in_buffer += i;\ - result = i;\ - }\ - } +static YY_BUFFER_STATE in_buffer; #else +static char *in_buffer; + #undef getc #define getc(fp) (*in_buffer == 0 ? EOF : *in_buffer++) #endif @@ -75,8 +70,6 @@ static inline int xdtoi(int); #define yylval pcap_lval extern YYSTYPE yylval; -static char *in_buffer; - %} N ([0-9]+|(0X|0x)[0-9A-Fa-f]+) @@ -88,6 +81,7 @@ W ([0-9A-Fa-f][0-9A-Fa-f]?[0-9A-Fa-f]?[0-9A-Fa-f]?) %e 6000 %k 4000 %p 19000 +%n 2000 V680 {W}:{W}:{W}:{W}:{W}:{W}:{W}:{W} @@ -172,7 +166,7 @@ dst return DST; src return SRC; link|ether|ppp|slip return LINK; -fddi return LINK; +fddi|tr return LINK; arp return ARP; rarp return RARP; ip return IP; @@ -189,12 +183,20 @@ ah return AH; esp return ESP; atalk return ATALK; +aarp return AARP; decnet return DECNET; lat return LAT; sca return SCA; moprc return MOPRC; mopdl return MOPDL; +iso return ISO; +esis return ESIS; +es-is return ESIS; +isis return ISIS; +is-is return ISIS; +clnp return CLNP; + host return HOST; net return NET; mask return MASK; @@ -224,6 +226,8 @@ len|length return LEN; inbound return INBOUND; outbound return OUTBOUND; +vlan return VLAN; + [ \n\t] ; [+\-*/:\[\]!<>()&|=] return yytext[0]; ">=" return GEQ; @@ -264,7 +268,24 @@ void lex_init(buf) char *buf; { +#ifdef FLEX_SCANNER + in_buffer = yy_scan_string(buf); +#else in_buffer = buf; +#endif +} + +/* + * Do any cleanup necessary after parsing. + */ +void +lex_cleanup() +{ +#ifdef FLEX_SCANNER + if (in_buffer != NULL) + yy_delete_buffer(in_buffer); + in_buffer = NULL; +#endif } /* @@ -316,4 +337,3 @@ stoi(s) return n; } - diff --git a/contrib/libpcap/sll.h b/contrib/libpcap/sll.h new file mode 100644 index 0000000..4f2330c --- /dev/null +++ b/contrib/libpcap/sll.h @@ -0,0 +1,124 @@ +/*- + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. 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 BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#) $Header: /tcpdump/master/libpcap/sll.h,v 1.6 2000/12/23 07:50:19 guy Exp $ (LBL) + */ + +/* + * For captures on Linux cooked sockets, we construct a fake header + * that includes: + * + * a 2-byte "packet type" which is one of: + * + * LINUX_SLL_HOST packet was sent to us + * LINUX_SLL_BROADCAST packet was broadcast + * LINUX_SLL_MULTICAST packet was multicast + * LINUX_SLL_OTHERHOST packet was sent to somebody else + * LINUX_SLL_OUTGOING packet was sent *by* us; + * + * a 2-byte Ethernet protocol field; + * + * a 2-byte link-layer type; + * + * a 2-byte link-layer address length; + * + * an 8-byte source link-layer address, whose actual length is + * specified by the previous value. + * + * All fields except for the link-layer address are in network byte order. + * + * DO NOT change the layout of this structure, or change any of the + * LINUX_SLL_ values below. If you must change the link-layer header + * for a "cooked" Linux capture, introduce a new DLT_ type (ask + * "tcpdump-workers@tcpdump.org" for one, so that you don't give it a + * value that collides with a value already being used), and use the + * new header in captures of that type, so that programs that can + * handle DLT_LINUX_SLL captures will continue to handle them correctly + * without any change, and so that capture files with different headers + * can be told apart and programs that read them can dissect the + * packets in them. + */ + +/* + * A DLT_LINUX_SLL fake link-layer header. + */ +#define SLL_HDR_LEN 16 /* total header length */ +#define SLL_ADDRLEN 8 /* length of address field */ + +struct sll_header { + u_int16_t sll_pkttype; /* packet type */ + u_int16_t sll_hatype; /* link-layer address type */ + u_int16_t sll_halen; /* link-layer address length */ + u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */ + u_int16_t sll_protocol; /* protocol */ +}; + +/* + * The LINUX_SLL_ values for "sll_pkttype"; these correspond to the + * PACKET_ values on Linux, but are defined here so that they're + * available even on systems other than Linux, and so that they + * don't change even if the PACKET_ values change. + */ +#define LINUX_SLL_HOST 0 +#define LINUX_SLL_BROADCAST 1 +#define LINUX_SLL_MULTICAST 2 +#define LINUX_SLL_OTHERHOST 3 +#define LINUX_SLL_OUTGOING 4 + +/* + * The LINUX_SLL_ values for "sll_protocol"; these correspond to the + * ETH_P_ values on Linux, but are defined here so that they're + * available even on systems other than Linux. We assume, for now, + * that the ETH_P_ values won't change in Linux; if they do, then: + * + * if we don't translate them in "pcap-linux.c", capture files + * won't necessarily be readable if captured on a system that + * defines ETH_P_ values that don't match these values; + * + * if we do translate them in "pcap-linux.c", that makes life + * unpleasant for the BPF code generator, as the values you test + * for in the kernel aren't the values that you test for when + * reading a capture file, so the fixup code run on BPF programs + * handed to the kernel ends up having to do more work. + * + * Add other values here as necessary, for handling packet types that + * might show up on non-Ethernet, non-802.x networks. (Not all the ones + * in the Linux "if_ether.h" will, I suspect, actually show up in + * captures.) + */ +#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */ +#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */ |