libpcap-0.5/./ 40755 263 461 0 7136054727 11537 5ustar mcrtcpdumplibpcap-0.5/./CVS/ 40755 263 461 0 7136054731 12165 5ustar mcrtcpdumplibpcap-0.5/./CVS/Root100644 263 461 61 7136054711 13063 0ustar mcrtcpdump:pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master libpcap-0.5/./CVS/Repository100644 263 461 10 7136054711 14311 0ustar mcrtcpdumplibpcap libpcap-0.5/./CVS/Entries100644 263 461 5217 7136054731 13623 0ustar mcrtcpdump/.cvsignore/1.1/Tue Oct 19 15:20:43 1999//Tlibpcap_0_5rel2 /CHANGES/1.48.2.1/Sat Jun 10 18:47:37 2000//Tlibpcap_0_5rel2 /CREDITS/1.1/Mon Jan 24 23:57:55 2000//Tlibpcap_0_5rel2 /FILES/1.1.1.1.2.1/Tue Jul 11 01:26:56 2000//Tlibpcap_0_5rel2 /INSTALL/1.42.1.1.2.1/Sun Jun 11 16:39:20 2000//Tlibpcap_0_5rel2 /Makefile.in/1.75/Sat Oct 30 05:33:45 1999//Tlibpcap_0_5rel2 /README/1.18.1.1.2.2/Thu Jul 13 05:46:33 2000//Tlibpcap_0_5rel2 /VERSION/1.1.1.1.2.1/Tue Jan 25 02:25:51 2000//Tlibpcap_0_5rel2 /aclocal.m4/1.66/Sat Oct 30 04:41:48 1999//Tlibpcap_0_5rel2 /bpf_image.c/1.22.1.1/Thu Oct 7 23:46:40 1999//Tlibpcap_0_5rel2 /config.guess/1.1.1.1/Thu Oct 7 23:46:40 1999//Tlibpcap_0_5rel2 /config.sub/1.1.1.1/Thu Oct 7 23:46:40 1999//Tlibpcap_0_5rel2 /configure/1.5/Mon Nov 1 15:56:40 1999//Tlibpcap_0_5rel2 /configure.in/1.71/Mon Nov 1 15:56:40 1999//Tlibpcap_0_5rel2 /etherent.c/1.20.1.1/Thu Oct 7 23:46:40 1999//Tlibpcap_0_5rel2 /ethertype.h/1.7.2.1/Thu Jun 29 15:45:21 2000//Tlibpcap_0_5rel2 /gencode.c/1.100.2.1/Wed Mar 1 14:12:54 2000//Tlibpcap_0_5rel2 /gencode.h/1.37/Tue Oct 19 15:18:29 1999//Tlibpcap_0_5rel2 /grammar.y/1.57/Tue Oct 19 15:18:30 1999//Tlibpcap_0_5rel2 /inet.c/1.24.2.1/Fri Jan 14 18:00:50 2000//Tlibpcap_0_5rel2 /install-sh/1.1.1.1/Thu Oct 7 23:46:40 1999//Tlibpcap_0_5rel2 /mkdep/1.1.1.1/Thu Oct 7 23:46:40 1999//Tlibpcap_0_5rel2 /nametoaddr.c/1.51/Thu Nov 25 08:25:35 1999//Tlibpcap_0_5rel2 /optimize.c/1.61/Tue Oct 19 15:18:30 1999//Tlibpcap_0_5rel2 /pcap-bpf.c/1.32/Tue Oct 19 15:18:30 1999//Tlibpcap_0_5rel2 /pcap-dlpi.c/1.52.1.1/Thu Oct 7 23:46:40 1999//Tlibpcap_0_5rel2 /pcap-enet.c/1.1.1.1/Thu Oct 7 23:46:40 1999//Tlibpcap_0_5rel2 /pcap-int.h/1.20/Sun Nov 21 01:10:20 1999//Tlibpcap_0_5rel2 /pcap-linux.c/1.15.1.1/Thu Oct 7 23:46:40 1999//Tlibpcap_0_5rel2 /pcap-namedb.h/1.6/Tue Oct 19 15:18:31 1999//Tlibpcap_0_5rel2 /pcap-nit.c/1.31.1.1/Thu Oct 7 23:46:40 1999//Tlibpcap_0_5rel2 /pcap-nit.h/1.2.1.1/Thu Oct 7 23:46:40 1999//Tlibpcap_0_5rel2 /pcap-null.c/1.7.1.1/Thu Oct 7 23:46:40 1999//Tlibpcap_0_5rel2 /pcap-pf.c/1.54.1.1/Thu Oct 7 23:46:40 1999//Tlibpcap_0_5rel2 /pcap-pf.h/1.2.1.1/Thu Oct 7 23:46:40 1999//Tlibpcap_0_5rel2 /pcap-snit.c/1.45.1.1/Thu Oct 7 23:46:40 1999//Tlibpcap_0_5rel2 /pcap-snoop.c/1.20.1.1/Thu Oct 7 23:46:40 1999//Tlibpcap_0_5rel2 /pcap.3/1.2.2.2/Thu Jul 13 05:46:33 2000//Tlibpcap_0_5rel2 /pcap.c/1.29.1.1/Thu Oct 7 23:46:40 1999//Tlibpcap_0_5rel2 /pcap.h/1.22/Wed Dec 8 19:54:03 1999//Tlibpcap_0_5rel2 /ppp.h/1.8/Tue Oct 19 15:18:31 1999//Tlibpcap_0_5rel2 /savefile.c/1.38/Sun Nov 21 01:11:58 1999//Tlibpcap_0_5rel2 /scanner.l/1.60/Wed Nov 17 04:09:58 1999//Tlibpcap_0_5rel2 D/SUNOS4//// D/bpf//// D/lbl//// D/linux-include//// libpcap-0.5/./CVS/Tag100644 263 461 21 7136054717 12655 0ustar mcrtcpdumpNlibpcap_0_5rel2 libpcap-0.5/./SUNOS4/ 40755 263 461 0 7136054721 12524 5ustar mcrtcpdumplibpcap-0.5/./SUNOS4/CVS/ 40755 263 461 0 7136054721 13157 5ustar mcrtcpdumplibpcap-0.5/./SUNOS4/CVS/Root100644 263 461 61 7136054720 14056 0ustar mcrtcpdump:pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master libpcap-0.5/./SUNOS4/CVS/Repository100644 263 461 17 7136054720 15313 0ustar mcrtcpdumplibpcap/SUNOS4 libpcap-0.5/./SUNOS4/CVS/Entries100644 263 461 332 7136054721 14566 0ustar mcrtcpdump/nit_if.o.sparc/1.1.1.1/Thu Oct 7 23:46:41 1999/-ko/Tlibpcap_0_5rel2 /nit_if.o.sun3/1.1.1.1/Thu Oct 7 23:46:41 1999/-ko/Tlibpcap_0_5rel2 /nit_if.o.sun4c.4.0.3c/1.1.1.1/Thu Oct 7 23:46:41 1999/-ko/Tlibpcap_0_5rel2 D libpcap-0.5/./SUNOS4/CVS/Tag100644 263 461 21 7136054721 13643 0ustar mcrtcpdumpNlibpcap_0_5rel2 libpcap-0.5/./SUNOS4/nit_if.o.sparc100644 263 461 12134 6777230341 15405 0ustar mcrtcpdump X`㿠.`>``@ " ` & @2`20  ?^(4Ѐ"Y?`@"! `6 ` @ 2  ?D(4Ѐ4 ?=(4@" `6` @ "    '   '`@'@&@'`& & 8'`'`'`'`@'` ` - ` . 07@c7`  7` `&` @@@ 㿠 $@    " " @`" @"2@2@ '& @ 㿠` ` H`!``B` " `  @` @ /@` @`0@.@-)` ``!  @@2 @6    0@@@ 㿠 `  ` 0a 2 ` 2  ` *`  9&@!` F `  ` +0` o0` 0a " ` ` + @ ` `4@&"`` ,  ,  & ` @ 2'` ` -  &` * & `  "`"`  `2` @ "`` , & " `` @ "`` -` & '`` '``+ & `  ` `#`, & ` '`` " ``:` '`` + &  @ "}`"%``d4a 4   ,`   06@/`6 /`@6  &@Z`  ` %`*` O& 㿠 " @2  " @ 2   ' 2  @"  " " ' @2@ `" @@`2 ` '`@2` " `2 `@2 ` '`@c2```'`  "J   `"   "  "  @2@  4'  *   "  %%&  "   %&  " @%`&@ ` @@ @ q 㿠 " &@(   @ 7 / @2 -` %&& @   & @&㿠@ 㿘'   "  @ 2 ' @@  2 @(#)nit_if.c 1.24 88/02/09 Copyr 1987 Sun Micro껀.snitsnit_close nonexistent instance  | Lx&   $, 0 p t%x x& 6xH58466L *XP9(9D6   <| #8 l 5|   8 @  , L  H  H t L 5D4 HLT \p x 0| L " .: F LR 0^hqz@ #.6=AI \\ck H~@  h| $_phz_hostnamelen_snit_close_snit_cpmsg_snit_ioctl_snit_minfo_snit_winit_snit_rinit_boottime_mclfree_m_freem_mclgetx_nisoftc_pidhash_freeproc_hostname_bcopy_proc_whichqs_freeb_m_cpytoc_ifnet_time_tick_rawintrq_allocb_linkb_lbolt_snit_put_domainnamelen_mfree_ifpromisc_canput_nproc_hz_dupmsg_cp_mblks_to_mbufs_panic_flushq_free_mbuffed_mblk_domainname_zombproc_ifunit_procNPROC_allproc_avenrun_snit_open_snit_info_snit_intr_qs_m_want_mbstat_tz_freemsg_qreply_etherbroadcastaddr_sccsid.mullibpcap-0.5/./SUNOS4/nit_if.o.sun3100644 263 461 10253 6777230341 15165 0ustar mcrtcpdump H@NVH< f.~(|` m R(M*TJf fFxp`Jgp`~.(|`mn xp`(M*TJfHxHx NPO&@Jf  xp`r ӫ*k +K*(+n n!M n!M8BB+GBB HxHxNPO&@Jg: k| $k 405| 5|. rӫHS n/( h P PNPO LF@RYajr{  _cp_mblks_to_mbufs_sccsid_lbolt_qs_snit_winit_nproc_whichqs_avenrun_domainnamelen_hostnamelen_snit_cpmsg_rawintrq_hostname_tz_canput_nisoftc_boottime_mclgetx_snit_close_etherbroadcastaddr_snit_info_snit_minfo_m_want_ifunit_tick_procNPROC_phz_free_mbuffed_mblk_snit_open_pidhash_bcopy_qreply_domainname_mfree_dupmsg_freemsg_allocb_m_freem_hz_snit_ioctl_snit_rinit_mclfree_freeproc_proc_flushq_time_panic_snit_put_ifnet_allproc_zombproc_mbstat_snit_intr_linkb_m_cpytoc_freeb_ifpromisclibpcap-0.5/./SUNOS4/nit_if.o.sun4c.4.0.3c100644 263 461 12253 6777230341 16137 0ustar mcrtcpdump L`㿠.`>``@ " ` & @2`2"  ?S(4Ѐ"N?`@" `& `4 ?<(4@2` @ 2  ?-(4В  '   '`@'@&@'`& & 8'`'`'`'`@'` ` - ` . 07@c7`  7` `&` @@@ 㿠 $@    " " @`" @"2@2@ '& @ 㿠` ` H`!``B` " `  @` @ /@` @`0@.@-)` ``!  @@2 @6    0@@@ 㿠 `  ` 0a 2 ` 2 ` *`  9&@` `4@&"`` ,  ,  & ` @ 2'` ` -  &` * & `  "`"`  `2` @ "`` , & " `` @ "`` -` y& '`` '``+ n& `  ` `#`, c& ` '`` " ``:` '`` + &  @ "K`"%``d4a 4   ,`   06@/`6 /`@6  &@(`  ` %`*` & ` x `  ` ]0` 0` 0a "=` ` + @ 㿠 " @2  " @ 2   ' 2  @2 ' ?#" "` @2@ `" @@`2 ` '`@2` " `2 `@2 `  '`@i2`` '` "P   "    "  `"  @2@ :'  ,`  `" %% 3 %&  "   %& `"  %&@ ` @@ @ k 㿠 " &@(   @ 7 / @2 -` %&& @   & @&㿠@ 㿘'   "  @ 2 ' @@  2 @(#) $Header: nit_if.c,v 1.4 90/03/20 18:18:19 leres Exp $ sun4c (LBL)@(#)nit_if.c 1.24++ 88/02/09 Copyr 1987 Sun Micro껀.snitsnit_close nonexistent instance  | L&8    D H%L \&L7\t6d7p+4h:x:7l<7T X  hh #L X p6   < <  0 P  L  L p H 6@  ll l |  " .: lF R |^hqz@l #.6=AI `\ck r L@  P  8&+_phz_hostnamelen_snit_close_snit_cpmsg_snit_ioctl_snit_minfo_snit_winit_snit_rinit_boottime_mclfree_m_freem_mclgetx_nisoftc_pidhash_freeproc_hostname_bcopy_proc_whichqs_freeb_m_cpytoc_ifnet_time_tick_rawintrq_allocb_linkb_lbolt_snit_put_domainnamelen_mfree_ifpromisc_canput_nproc_hz_dupmsg_cp_mblks_to_mbufs_panic_flushq_rcsid_free_mbuffed_mblk_domainname_zombproc_ifunit_procNPROC_allproc_avenrun_snit_open_snit_info_snit_intr_qs_m_want_mbstat_tz_freemsg_qreply_etherbroadcastaddr_sccsid.mullibpcap-0.5/./.cvsignore100644 263 461 127 7003106113 13570 0ustar mcrtcpdumpconfig.log config.cache config.status Makefile scanner.c grammar.c tokdefs.h version.c libpcap-0.5/./CHANGES100644 263 461 23111 7120506511 12627 0ustar mcrtcpdump@(#) $Header: /tcpdump/master/libpcap/CHANGES,v 1.48.2.1 2000/06/10 18:47:37 assar Exp $ (LBL) 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 - 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 - 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 Fenner (fenner@parc.xerox.com) - Fix alignment problem with FDDI under DLPI. This was causing core dumps under Solaris. - Added configure options to disable flex and bison. Resulted from a bug report by barnett@grymoire.crd.ge.com (Bruce Barnett). Also added options to disable gcc and to force a particular packet capture type. - Added support for Fore ATM interfaces (qaa and fa) under IRIX. Thanks to John Hawkinson (jhawk@mit.edu) - Change Linux PPP and SLIP to use DLT_RAW since the kernel does not supply any "link layer" data. - Change Linux to use SIOCGIFHWADDR ioctl to determine link layer type. Thanks to Thomas Sailer (sailer@ife.ee.ethz.ch) - Change IRIX PPP to use DLT_RAW since the kernel does not supply any "link layer" data. - Modified to support the new BSD/OS 2.1 PPP and SLIP link layer header formats. - Added some new SGI snoop interface types. Thanks to Steve Alexander (sca@refugee.engr.sgi.com) - Fixes for HP-UX 10.20 (which is similar to HP-UX 9). Thanks to Richard Allen (ra@hp.is) and Steinar Haug (sthaug@nethelp.no) - Fddi supports broadcast as reported by Jeff Macdonald (jeff@iacnet.com). Also correct ieee802 and arcnet. - Determine Linux pcap buffer size at run time or else it might not be big enough for some interface types (e.g. FDDI). Thanks to Jes Sorensen (Jes.Sorensen@cern.ch) - Fix some linux alignment problems. - Document promisc argument to pcap_open_live(). Reported by Ian Marsh (ianm@sics.se) - Support Metricom radio packets under Linux. Thanks to Kevin Lai (laik@gunpowder.stanford.edu) - Bind to interface name under Linux to avoid packets from multiple interfaces on multi-homed hosts. Thanks to Kevin Lai (laik@gunpowder.stanford.edu) - Change L_SET to SEEK_SET for HP-UX. Thanks to Roland Roberts (rroberts@muller.com) - Fixed an uninitialized memory reference found by Kent Vander Velden (graphix@iastate.edu) - Fixed lex pattern for IDs to allow leading digits. As reported by Theo de Raadt (deraadt@cvs.openbsd.org) - Fixed Linux include file problems when using GNU libc. - Ifdef ARPHRD_FDDI since not all versions of the Linux kernel have it. Reported reported by Eric Jacksch (jacksch@tenebris.ca) - Fixed bug in pcap_dispatch() that kept it from returning on packet timeouts. - Changed ISLOOPBACK() macro when IFF_LOOPBACK isn't available to check for "lo" followed by an eos or digit (newer versions of Linux apparently call the loopback "lo" instead of "lo0"). - Fixed Linux networking include files to use ints instead of longs to avoid problems with 64 bit longs on the alpha. Thanks to Cristian Gafton (gafton@redhat.com) v0.3 Sat Nov 30 20:56:27 PST 1996 - Added Linux support. - Fixed savefile bugs. - Solaris x86 fix from Tim Rylance (t.rylance@elsevier.nl) - Add support for bpf kernel port filters. - Remove duplicate atalk protocol table entry. Thanks to Christian Hopps (chopps@water.emich.edu) - Fixed pcap_lookupdev() to ignore nonexistent devices. This was reported to happen under BSD/OS by David Vincenzetti (vince@cryptonet.it) - Avoid solaris compiler warnings. Thanks to Bruce Barnett (barnett@grymoire.crd.ge.com) v0.2.1 Sun Jul 14 03:02:26 PDT 1996 - Fixes for HP-UX 10. Thanks in part to to Thomas Wolfram (wolf@prz.tu-berlin.de) and Rick Jones (raj@hpisrdq.cup.hp.com) - Added support for SINIX. Thanks to Andrej Borsenkow (borsenkow.msk@sni.de) - Fixes for AIX (although this system is not yet supported). Thanks to John Hawkinson (jhawk@mit.edu) - Use autoconf's idea of the top level directory in install targets. Thanks to John Hawkinson. - Add missing autoconf packet capture result message. Thanks to Bill Fenner (fenner@parc.xerox.com) - Fixed padding problems in the pf module. - Fixed some more alignment problems on the alpha. - Added explicit netmask support. Thanks to Steve Nuchia (steve@research.oknet.com) - Fixed to handle raw ip addresses such as 0.0.0.1 without "left justifing" - Add "sca" keyword (for DEC cluster services) as suggested by Terry Kennedy (terry@spcvxa.spc.edu) - Add "atalk" keyword as suggested by John Hawkinson. - Add "igrp" keyword. - Fixed HID definition in grammar.y to be a string, not a value. - Use $CC when checking gcc version. Thanks to Carl Lindberg (carl_lindberg@blacksmith.com) - Removed obsolete reference to pcap_immediate() from the man page. Michael Stolarchuk (mts@terminator.rs.itd.umich.edu) - DLT_NULL has a 4 byte family header. Thanks to Jeffrey Honig (jch@bsdi.com) v0.2 Sun Jun 23 02:28:42 PDT 1996 - Add support for HP-UX. Resulted from code contributed by Tom Murray (tmurray@hpindck.cup.hp.com) and Philippe-Andri Prindeville (philipp@res.enst.fr) - Update INSTALL with a reminder to install include files. Thanks to Mark Andrews (mandrews@aw.sgi.com) - Fix bpf compiler alignment bug on the alpha. - Use autoconf to detect architectures that can't handle misaligned accesses. - Added loopback support for snoop. Resulted from report Steve Alexander (sca@engr.sgi.com) v0.1 Fri Apr 28 18:11:03 PDT 1995 - Fixed compiler and optimizer bugs. The BPF filter engine uses unsigned comparison operators, while the code generator and optimizer assumed signed semantics in several places. Thanks to Charlie Slater (cslater@imatek.com) for pointing this out. - Removed FDDI ifdef's, they aren't really needed. Resulted from report by Gary Veum (veum@boa.gsfc.nasa.gov). - Add pcap-null.c which allows offline use of libpcap on systems that don't support live package capture. This feature resulting from a request from Jan van Oorschot (j.p.m.voorschot@et.tudelft.nl). - Make bpf_compile() reentrant. Fix thanks to Pascal Hennequin (Pascal.Hennequin@hugo.int-evry.fr). - Port to GNU autoconf. - Fix pcap-dlpi.c to work with isdn. Resulted from report by Flemming Johansen (fsj@csd.cri.dk). - Handle multi-digit interface unit numbers (aka ppa's) under dlpi. Resulted from report by Daniel Ehrlich (ehrlich@cse.psu.edu). - Fix pcap-dlpi.c to work in non-promiscuous mode. Resulted from report by Jeff Murphy (jcmurphy@acsu.buffalo.edu). - Add support for "long jumps". Thanks to Jeffrey Mogul (mogul@pa.dec.com). - Fix minor problems when compiling with BDEBUG as noticed by Scott Bertilson (scott@unet.umn.edu). - Declare sys_errlist "const char *const" to avoid problems under FreeBSD. Resulted from report by jher@eden.com. v0.0.6 Fri Apr 28 04:07:13 PDT 1995 - Add missing variable declaration missing from 0.0.6 v0.0.5 Fri Apr 28 00:22:21 PDT 1995 - Workaround for problems when pcap_read() returns 0 due to the timeout expiring. v0.0.4 Thu Apr 20 20:41:48 PDT 1995 - Change configuration to not use gcc v2 flags with gcc v1. - Fixed a bug in pcap_next(); if pcap_dispatch() returns 0, pcap_next() should also return 0. Thanks to Richard Stevens (rstevens@noao.edu). - Fixed configure to test for snoop before dlpi to avoid problems under IRIX 5. Thanks to J. Eric Townsend (jet@abulafia.genmagic.com). - Hack around deficiency in Ultrix's make. - Fix two bugs related to the Solaris pre-5.3.2 bufmod bug; handle savefiles that have more than snapshot bytes of data in them (so we can read old savefiles) and avoid writing such files. - Added checkioctl which is used with gcc to check that the "fixincludes" script has been run. v0.0.3 Tue Oct 18 18:13:46 PDT 1994 - Fixed configure to test for snoop before dlpi to avoid problems under IRIX 5. Thanks to J. Eric Townsend (jet@abulafia.genmagic.com). v0.0.2 Wed Oct 12 20:56:37 PDT 1994 - Implement timeout in the dlpi pcap_open_live(). Thanks to Richard Stevens. - Determine pcap link type from dlpi media type. Resulted from report by Mahesh Jethanandani (mahesh@npix.com). v0.0.1 Fri Jun 24 14:50:57 PDT 1994 - Fixed bug in nit_setflags() in pcap-snit.c. The streams ioctl timeout wasn't being initialized sometimes resulting in an "NIOCSFLAGS: Invalid argument" error under OSF/1. Reported by Matt Day (mday@artisoft.com) and Danny Mitzel (dmitzel@whitney.hitc.com). - Turn on FDDI support by default. v0.0 Mon Jun 20 19:20:16 PDT 1994 - Initial release. - Fixed bug with greater/less keywords, reported by Mark Andrews (mandrews@alias.com). - Fix bug where '|' was defined as BPF_AND instead of BPF_OR, reported by Elan Amir (elan@leeb.cs.berkeley.edu). - Machines with little-endian byte ordering are supported thanks to Jeff Mogul. - Add hack for version 2.3 savefiles which don't have caplen and len swapped thanks to Vern Paxson. - Added "&&" and "||" aliases for "and" and "or" thanks to Vern Paxson. - Added length, inbound and outbound keywords. libpcap-0.5/./CREDITS100644 263 461 637 7043163403 12627 0ustar mcrtcpdumpThis file lists people who contributed to libpcap or tcpdump: Bill Fenner Assar Westerlund Alexei Jun-ichiro itojun Hagino Guy Harris Torsten Landschoff Michael Richardson The original LBL crew: Steve McCanne Craig Leres Van Jacobson libpcap-0.5/./FILES100644 263 461 1107 7132473740 12414 0ustar mcrtcpdumpCHANGES CREDITS FILES INSTALL Makefile.in README SUNOS4 VERSION aclocal.m4 bpf/net/bpf.h bpf/net/bpf_filter.c bpf_image.c config.sub configure configure.in etherent.c ethertype.h gencode.c gencode.h grammar.y inet.c install-sh lbl/gnuc.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 optimize.c pcap-bpf.c pcap-dlpi.c pcap-enet.c pcap-int.h pcap-linux.c pcap-namedb.h pcap-nit.c pcap-nit.h pcap-null.c pcap-pf.c pcap-pf.h pcap-snit.c pcap-snoop.c pcap.3 pcap.c pcap.h ppp.h savefile.c scanner.l libpcap-0.5/./INSTALL100644 263 461 32700 7120740270 12673 0ustar mcrtcpdump@(#) $Header: /tcpdump/master/libpcap/INSTALL,v 1.42.1.1.2.1 2000/06/11 16:39:20 mcr 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. If configure says: configure: warning: cannot determine packet capture interface configure: warning: (see INSTALL for more info) then your system either does not support packet capture or your system does support packet capture but libpcap does not support that particular type. (If you have HP-UX, see below.) If your system uses a packet capture not supported by libpcap, please send us patches; don't forget to include an autoconf fragment suitable for use in configure.in. It is possible to override the default packet capture type, although the circumstance where this works are limited. For example if you have installed bpf under SunOS 4 and wish to build a snit libpcap: ./configure --with-pcap=snit Another example is to force a supported packet capture type in the case where the configure scripts fails to detect it. 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. 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 unless it is new enough. You can use "flex -V" to see what version you have (unless it's really old). The current version of flex is available via anonymous ftp: ftp://ftp.ee.lbl.gov/flex-*.tar.Z As of this writing, the current version is 2.5.4. If you use bison, you must use flex (and visa versa). The configure script automatically falls back to lex and yacc if both flex and bison are not found. Sometimes the stock C compiler does not interact well with flex and bison. The list of problems includes undefined references for alloca. You can get around this by installing gcc or manually disabling flex and bison with: ./configure --without-flex --without-bison If your system only has AT&T lex, this is okay unless your libpcap program uses other lex/yacc generated code. (Although it's possible to map the yy* identifiers with a script, we use flex and bison so we don't feel this is necessary.) Some systems support the Berkeley Packet Filter natively; for example out of the box OSF and BSD/OS have bpf. If your system does not support bpf, you will need to pick up: ftp://ftp.ee.lbl.gov/bpf-*.tar.Z Note well: you MUST have kernel source for your operating system in order to install bpf. An exception is SunOS 4; the bpf distribution includes replacement kernel objects for some of the standard SunOS 4 network device drivers. See the bpf INSTALL document for more information. If you use Solaris, there is a bug with bufmod(7) that is fixed in Solaris 2.3.2 (aka SunOS 5.3.2). Setting a snapshot length with the broken bufmod(7) results in data be truncated from the FRONT of the packet instead of the end. The work around is to not set a snapshot length but this results in performance problems since the entire packet is copied to user space. If you must run an older version of Solaris, there is a patch available from Sun; ask for bugid 1149065. After installing the patch, use "setenv BUFMOD_FIXED" to enable use of bufmod(7). However, we recommend you run a more current release of Solaris. If you use the SPARCompiler, you must be careful to not use the /usr/ucb/cc interface. If you do, you will get bogus warnings and perhaps errors. Either make sure your path has /opt/SUNWspro/bin before /usr/ucb or else: setenv CC /opt/SUNWspro/bin/cc before running configure. (You might have to do a "make distclean" if you already ran configure once). Also note that "make depend" won't work; while all of the known universe uses -M, the SPARCompiler uses -xM to generate makefile dependencies. If you are trying to do packet capture with a FORE ATM card, you may or may not be able to. They usually only release their driver in object code so unless their driver supports packet capture, there's not much libpcap can do. If you get an error like: tcpdump: recv_ack: bind error 0x??? 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: ftp://ftp.digital.com/pub/Digital/dec-faq/Digital-UNIX Once you enable packet filter support, your OSF system will support bpf natively. Under Ultrix, 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/ultrix If you use HP-UX, you must have at least version 9 and either the version of cc that supports ANSI C (cc -Aa) or else use the GNU C compiler. You must also buy the optional streams package. If you don't have: /usr/include/sys/dlpi.h /usr/include/sys/dlpi_ext.h 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 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 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 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. 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. 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. 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! 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: ./configure --with-pcap=bpf 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 release of libpcap. If you use SINIX, you should be able to build libpcap from this release. It is known to compile and run on SINIX-Y/N 5.42 with the C-DS V1.0 or V1.1 compiler. But note that in some releases of SINIX, yacc emits incorrect code; if grammar.y fails to compile, change every occurence of: #ifdef YYDEBUG to: #if YYDEBUG 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 a tcpdump binary as part of their "Network/Security Tools" package: http://www.sco.com/technology/internet/goodies/#SECURITY There is also a README that explains how to enable packet capture. If you use UnixWare, you will not be able to build libpcap from this release. We hope to support this operating system in some future release of libpcap. Meanwhile, there appears to be an UnixWare port of libpcap 0.0 (and tcpdump 3.0) in: ftp://ftp1.freebird.org/pub/mirror/freebird/internet/systools/ UnixWare appears to use a hacked version of DLPI. If linking tcpdump fails with "Undefined: _alloca" when using bison on 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 or hack around it by inserting the lines: #ifdef __GNUC__ #define alloca __builtin_alloca #else #ifdef sparc #include #else char *alloca (); #endif #endif right after the (100 line!) GNU license comment in bison.simple, remove grammar.[co] and fire up make again. If you use SunOS 4, your kernel must support streams NIT. If you run a libpcap program and it dies with: /dev/nit: No such device You must add streams NIT support to your kernel configuration, run config and boot the new kernel. If you are running a version of SunOS earlier than 4.1, you will need to replace the Sun supplied /sys/sun{3,4,4c}/OBJ/nit_if.o with the appropriate version from this distribution's SUNOS4 subdirectory and build a new kernel: nit_if.o.sun3-sunos4 (any flavor of sun3) nit_if.o.sun4c-sunos4.0.3c (SS1, SS1+, IPC, SLC, etc.) nit_if.o.sun4-sunos4 (Sun4's not covered by nit_if.o.sun4c-sunos4.0.3c) These nit replacements fix a bug that makes nit essentially unusable in pre-SunOS 4.1. In addition, our sun4c-sunos4.0.3c nit gives you timestamps to the resolution of the SS-1 clock (1 us) rather than the lousy 20ms timestamps Sun gives you (tcpdump will print out the full timestamp resolution if it finds it's running on a SS-1). FILES ----- CHANGES - description of differences between releases FILES - list of files exported as part of the distribution INSTALL - this file Makefile.in - compilation rules (input to the configure script) README - description of distribution SUNOS4 - pre-SunOS 4.1 replacement kernel nit modules VERSION - version of this release aclocal.m4 - autoconf macros bpf/net - copies of bpf_filter.c and bpf.h bpf_filter.c - symlink to bpf/net/bpf_filter.c bpf_image.c - bpf disassembly routine config.guess - autoconf support config.sub - autoconf support configure - configure script (run this first) configure.in - configure script source etherent.c - /etc/ethers support routines ethertype.h - ethernet protocol types and names definitions gencode.c - bpf code generation routines gencode.h - bpf code generation definitions grammar.y - filter string grammar 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 optimize.c - bpf optimization routines pcap-bpf.c - BSD Packet Filter support pcap-dlpi.c - Data Link Provider Interface support pcap-enet.c - enet support pcap-int.h - internal libpcap definitions pcap-namedb.h - public libpcap name database definitions pcap-nit.c - Network Interface Tap support pcap-nit.h - Network Interface Tap definitions pcap-null.c - dummy monitor support (allows offline use of libpcap) pcap-pf.c - Packet Filter support pcap-pf.h - Packet Filter definitions pcap-snit.c - Streams based Network Interface Tap support pcap-snoop.c - Snoop network monitoring support pcap.3 - manual entry pcap.c - pcap utility routines pcap.h - public libpcap definitions ppp.h - Point to Point Protocol definitions savefile.c - offline support scanner.l - filter string scanner libpcap-0.5/./Makefile.in100644 263 461 11632 7006501471 13711 0ustar mcrtcpdump# Copyright (c) 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. # # @(#) $Header: /tcpdump/master/libpcap/Makefile.in,v 1.75 1999/10/30 05:33:45 itojun Exp $ (LBL) # # Various configurable paths (remember to edit Makefile.in, not Makefile) # # Top level hierarchy prefix = @prefix@ exec_prefix = @exec_prefix@ # Pathname of directory to install the include files INCLDEST = @includedir@ # Pathname of directory to install the library LIBDEST = @libdir@ # Pathname of directory to install the man page MANDEST = @mandir@ # VPATH srcdir = @srcdir@ VPATH = @srcdir@ # # You shouldn't need to edit anything below. # CC = @CC@ CCOPT = @V_CCOPT@ INCLS = -I. @V_INCLS@ DEFS = @DEFS@ # Standard CFLAGS CFLAGS = $(CCOPT) $(INCLS) $(DEFS) INSTALL = @INSTALL@ RANLIB = @V_RANLIB@ # # Flex and bison allow you to specify the prefixes of the global symbols # used by the generated parser. This allows programs to use lex/yacc # and link against libpcap. If you don't have flex or bison, get them. # LEX = @V_LEX@ YACC = @V_YACC@ # Explicitly define compilation rule since SunOS 4's make doesn't like gcc. # Also, gcc does not remove the .o before forking 'as', which can be a # problem if you don't own the file but can write to the directory. .c.o: @rm -f $@ $(CC) $(CFLAGS) -c $(srcdir)/$*.c 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 GENSRC = scanner.c grammar.c version.c 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) HDR = pcap.h pcap-int.h pcap-namedb.h pcap-nit.h pcap-pf.h \ ethertype.h gencode.h gnuc.h GENHDR = \ tokdefs.h TAGHDR = \ bpf/net/bpf.h TAGFILES = \ $(SRC) $(HDR) $(TAGHDR) CLEANFILES = $(OBJ) libpcap.a $(GENSRC) $(GENHDR) lex.yy.c all: libpcap.a libpcap.a: $(OBJ) @rm -f $@ ar rc $@ $(OBJ) $(RANLIB) $@ scanner.c: $(srcdir)/scanner.l @rm -f $@ $(LEX) -t $< > $$$$.$@; mv $$$$.$@ $@ scanner.o: scanner.c tokdefs.h $(CC) $(CFLAGS) -c scanner.c tokdefs.h: grammar.c grammar.c: $(srcdir)/grammar.y @rm -f grammar.c tokdefs.h $(YACC) -d $< mv y.tab.c grammar.c mv y.tab.h tokdefs.h grammar.o: grammar.c @rm -f $@ $(CC) $(CFLAGS) -Dyylval=pcap_lval -c grammar.c version.o: version.c $(CC) $(CFLAGS) -c version.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 clean: rm -f $(CLEANFILES) distclean: rm -f $(CLEANFILES) Makefile config.cache config.log config.status \ gnuc.h os-proto.h net tags: $(TAGFILES) ctags -wtd $(TAGFILES) tar: force @cwd=`pwd` ; dir=`basename $$cwd` ; name=libpcap-`cat VERSION` ; \ list="" ; tar="tar chFFf" ; \ for i in `cat FILES` ; do list="$$list $$name/$$i" ; done; \ echo \ "rm -f ../$$name; ln -s $$dir ../$$name" ; \ rm -f ../$$name; ln -s $$dir ../$$name ; \ echo \ "(cd .. ; $$tar - [lots of files]) | compress > /tmp/$$name.tar.Z" ; \ (cd .. ; $$tar - $$list) | compress > /tmp/$$name.tar.Z ; \ echo \ "rm -f ../$$name" ; \ rm -f ../$$name force: /tmp depend: $(GENSRC) force ./mkdep -c $(CC) $(DEFS) $(INCLS) $(SRC) libpcap-0.5/./README100644 263 461 4611 7133253671 12512 0ustar mcrtcpdump@(#) $Header: /tcpdump/master/libpcap/README,v 1.18.1.1.2.2 2000/07/13 05:46:33 gharris Exp $ (LBL) LIBPCAP 0.5 Now maintained by "The Tcpdump Group" Send patches to patches@tcpdump.org See www.tcpdump.org formerly from Lawrence Berkeley National Laboratory Network Research Group 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 framework for low-level network monitoring. Applications include network statistics collection, security monitoring, network debugging, etc. Since almost every system vendor provides a different interface for packet capture, and since we've developed several tools that require this functionality, we've created this system-independent API to ease in porting and to alleviate the need for several system-dependent packet capture modules in each application. Note well: this interface is new and is likely to change. The libpcap interface supports a filtering mechanism based on the architecture in the BSD packet filter. BPF is described in the 1993 Winter Usenix paper ``The BSD Packet Filter: A New Architecture for User-level Packet Capture''. A compressed postscript version is in: ftp://ftp.ee.lbl.gov/papers/bpf-usenix93.ps.Z. Although most packet capture interfaces support in-kernel filtering, libpcap utilizes in-kernel filtering only for the BPF interface. On systems that don't have BPF, all packets are read into user-space and the BPF filters are evaluated in the libpcap library, incurring 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/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, 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 - The TCPdump team libpcap-0.5/./VERSION100644 263 461 4 7043204657 12612 0ustar mcrtcpdump0.5 libpcap-0.5/./aclocal.m4100644 263 461 44773 7006473414 13525 0ustar mcrtcpdumpdnl @(#) $Header: /tcpdump/master/libpcap/aclocal.m4,v 1.66 1999/10/30 04:41:48 itojun Exp $ (LBL) dnl dnl Copyright (c) 1995, 1996, 1997, 1998 dnl The Regents of the University of California. All rights reserved. dnl dnl Redistribution and use in source and binary forms, with or without dnl modification, are permitted provided that: (1) source code distributions dnl retain the above copyright notice and this paragraph in its entirety, (2) dnl distributions including binary code include the above copyright notice and dnl this paragraph in its entirety in the documentation or other materials dnl provided with the distribution, and (3) all advertising materials mentioning dnl features or use of this software display the following acknowledgement: dnl ``This product includes software developed by the University of California, dnl Lawrence Berkeley Laboratory and its contributors.'' Neither the name of dnl the University nor the names of its contributors may be used to endorse dnl or promote products derived from this software without specific prior dnl written permission. dnl THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED dnl WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF dnl MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. dnl dnl LBL autoconf macros dnl dnl dnl Determine which compiler we're using (cc or gcc) dnl If using gcc, determine the version number dnl If using cc, require that it support ansi prototypes dnl If using gcc, use -O2 (otherwise use -O) dnl If using cc, explicitly specify /usr/local/include dnl dnl usage: dnl dnl AC_LBL_C_INIT(copt, incls) dnl dnl results: dnl dnl $1 (copt set) dnl $2 (incls set) dnl CC dnl LDFLAGS dnl ac_cv_lbl_gcc_vers dnl LBL_CFLAGS dnl AC_DEFUN(AC_LBL_C_INIT, [AC_PREREQ(2.12) AC_BEFORE([$0], [AC_PROG_CC]) AC_BEFORE([$0], [AC_LBL_FIXINCLUDES]) AC_BEFORE([$0], [AC_LBL_DEVEL]) AC_ARG_WITH(gcc, [ --without-gcc don't use gcc]) $1="-O" $2="" if test "${srcdir}" != "." ; then $2="-I\$(srcdir)" fi if test "${CFLAGS+set}" = set; then LBL_CFLAGS="$CFLAGS" fi if test -z "$CC" ; then case "$target_os" in bsdi*) AC_CHECK_PROG(SHLICC2, shlicc2, yes, no) if test $SHLICC2 = yes ; then CC=shlicc2 export CC fi ;; esac fi if test -z "$CC" -a "$with_gcc" = no ; then CC=cc export CC fi AC_PROG_CC if test "$GCC" = yes ; then if test "$SHLICC2" = yes ; then ac_cv_lbl_gcc_vers=2 $1="-O2" else AC_MSG_CHECKING(gcc version) AC_CACHE_VAL(ac_cv_lbl_gcc_vers, ac_cv_lbl_gcc_vers=`$CC -v 2>&1 | \ sed -e '/^gcc version /!d' \ -e 's/^gcc version //' \ -e 's/ .*//' -e 's/^[[[^0-9]]]*//' \ -e 's/\..*//'`) AC_MSG_RESULT($ac_cv_lbl_gcc_vers) if test $ac_cv_lbl_gcc_vers -gt 1 ; then $1="-O2" fi fi else AC_MSG_CHECKING(that $CC handles ansi prototypes) AC_CACHE_VAL(ac_cv_lbl_cc_ansi_prototypes, AC_TRY_COMPILE( [#include ], [int frob(int, char *)], ac_cv_lbl_cc_ansi_prototypes=yes, ac_cv_lbl_cc_ansi_prototypes=no)) AC_MSG_RESULT($ac_cv_lbl_cc_ansi_prototypes) if test $ac_cv_lbl_cc_ansi_prototypes = no ; then case "$target_os" in hpux*) AC_MSG_CHECKING(for HP-UX ansi compiler ($CC -Aa -D_HPUX_SOURCE)) savedcflags="$CFLAGS" CFLAGS="-Aa -D_HPUX_SOURCE $CFLAGS" AC_CACHE_VAL(ac_cv_lbl_cc_hpux_cc_aa, AC_TRY_COMPILE( [#include ], [int frob(int, char *)], ac_cv_lbl_cc_hpux_cc_aa=yes, ac_cv_lbl_cc_hpux_cc_aa=no)) AC_MSG_RESULT($ac_cv_lbl_cc_hpux_cc_aa) if test $ac_cv_lbl_cc_hpux_cc_aa = no ; then AC_MSG_ERROR(see the INSTALL doc for more info) fi CFLAGS="$savedcflags" V_CCOPT="-Aa $V_CCOPT" AC_DEFINE(_HPUX_SOURCE) ;; *) AC_MSG_ERROR(see the INSTALL doc for more info) ;; esac fi $2="$$2 -I/usr/local/include" LDFLAGS="$LDFLAGS -L/usr/local/lib" case "$target_os" in irix*) V_CCOPT="$V_CCOPT -xansi -signed -g3" ;; osf*) V_CCOPT="$V_CCOPT -std1 -g3" ;; ultrix*) AC_MSG_CHECKING(that Ultrix $CC hacks const in prototypes) AC_CACHE_VAL(ac_cv_lbl_cc_const_proto, AC_TRY_COMPILE( [#include ], [struct a { int b; }; void c(const struct a *)], ac_cv_lbl_cc_const_proto=yes, ac_cv_lbl_cc_const_proto=no)) AC_MSG_RESULT($ac_cv_lbl_cc_const_proto) if test $ac_cv_lbl_cc_const_proto = no ; then AC_DEFINE(const,) fi ;; esac fi ]) dnl dnl Use pfopen.c if available and pfopen() not in standard libraries dnl Require libpcap dnl Look for libpcap in .. dnl Use the installed libpcap if there is no local version dnl dnl usage: dnl dnl AC_LBL_LIBPCAP(pcapdep, incls) dnl dnl results: dnl dnl $1 (pcapdep set) dnl $2 (incls appended) dnl LIBS dnl LBL_LIBS dnl AC_DEFUN(AC_LBL_LIBPCAP, [AC_REQUIRE([AC_LBL_LIBRARY_NET]) dnl dnl save a copy before locating libpcap.a dnl LBL_LIBS="$LIBS" pfopen=/usr/examples/packetfilter/pfopen.c if test -f $pfopen ; then AC_CHECK_FUNCS(pfopen) if test $ac_cv_func_pfopen = "no" ; then AC_MSG_RESULT(Using $pfopen) LIBS="$LIBS $pfopen" fi fi AC_MSG_CHECKING(for local pcap library) libpcap=FAIL lastdir=FAIL places=`ls .. | sed -e 's,/$,,' -e 's,^,../,' | \ egrep '/libpcap-[[0-9]]*\.[[0-9]]*(\.[[0-9]]*)?([[ab]][[0-9]]*)?$'` for dir in $places ../libpcap libpcap ; do basedir=`echo $dir | sed -e 's/[[ab]][[0-9]]*$//'` if test $lastdir = $basedir ; then dnl skip alphas when an actual release is present continue; fi lastdir=$dir if test -r $dir/pcap.c ; then libpcap=$dir/libpcap.a d=$dir dnl continue and select the last one that exists fi done if test $libpcap = FAIL ; then AC_MSG_RESULT(not found) AC_CHECK_LIB(pcap, main, libpcap="-lpcap") if test $libpcap = FAIL ; then AC_MSG_ERROR(see the INSTALL doc for more info) fi else $1=$libpcap $2="-I$d $$2" AC_MSG_RESULT($libpcap) fi LIBS="$libpcap $LIBS" case "$target_os" in aix*) pseexe="/lib/pse.exp" AC_MSG_CHECKING(for $pseexe) if test -f $pseexe ; then AC_MSG_RESULT(yes) LIBS="$LIBS -I:$pseexe" fi ;; esac]) dnl dnl Define RETSIGTYPE and RETSIGVAL dnl dnl usage: dnl dnl AC_LBL_TYPE_SIGNAL dnl dnl results: dnl dnl RETSIGTYPE (defined) dnl RETSIGVAL (defined) dnl 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,) else AC_DEFINE(RETSIGVAL,(0)) fi case "$target_os" in irix*) AC_DEFINE(_BSD_SIGNALS) ;; *) dnl prefer sigset() to sigaction() AC_CHECK_FUNCS(sigset) if test $ac_cv_func_sigset = no ; then AC_CHECK_FUNCS(sigaction) fi ;; esac]) dnl dnl If using gcc, make sure we have ANSI ioctl definitions dnl dnl usage: dnl dnl AC_LBL_FIXINCLUDES dnl AC_DEFUN(AC_LBL_FIXINCLUDES, [if test "$GCC" = yes ; then AC_MSG_CHECKING(for ANSI ioctl definitions) AC_CACHE_VAL(ac_cv_lbl_gcc_fixincludes, AC_TRY_COMPILE( [/* * This generates a "duplicate case value" when fixincludes * has not be run. */ # include # include # include # ifdef HAVE_SYS_IOCCOM_H # include # endif], [switch (0) { case _IO('A', 1):; case _IO('B', 1):; }], ac_cv_lbl_gcc_fixincludes=yes, ac_cv_lbl_gcc_fixincludes=no)) AC_MSG_RESULT($ac_cv_lbl_gcc_fixincludes) if test $ac_cv_lbl_gcc_fixincludes = no ; then # Don't cache failure unset ac_cv_lbl_gcc_fixincludes AC_MSG_ERROR(see the INSTALL for more info) fi fi]) dnl dnl Check for flex, default to lex dnl Require flex 2.4 or higher dnl Check for bison, default to yacc dnl Default to lex/yacc if both flex and bison are not available dnl Define the yy prefix string if using flex and bison dnl dnl usage: dnl dnl AC_LBL_LEX_AND_YACC(lex, yacc, yyprefix) dnl dnl results: dnl dnl $1 (lex set) dnl $2 (yacc appended) dnl $3 (optional flex and bison -P prefix) dnl AC_DEFUN(AC_LBL_LEX_AND_YACC, [AC_ARG_WITH(flex, [ --without-flex don't use flex]) AC_ARG_WITH(bison, [ --without-bison don't use bison]) if test "$with_flex" = no ; then $1=lex else AC_CHECK_PROGS($1, flex, lex) fi if test "$$1" = flex ; then # The -V flag was added in 2.4 AC_MSG_CHECKING(for flex 2.4 or higher) AC_CACHE_VAL(ac_cv_lbl_flex_v24, if flex -V >/dev/null 2>&1; then ac_cv_lbl_flex_v24=yes else ac_cv_lbl_flex_v24=no fi) AC_MSG_RESULT($ac_cv_lbl_flex_v24) if test $ac_cv_lbl_flex_v24 = no ; then s="2.4 or higher required" AC_MSG_WARN(ignoring obsolete flex executable ($s)) $1=lex fi fi if test "$with_bison" = no ; then $2=yacc else AC_CHECK_PROGS($2, bison, yacc) fi if test "$$2" = bison ; then $2="$$2 -y" fi if test "$$1" != lex -a "$$2" = yacc -o "$$1" = lex -a "$$2" != yacc ; then AC_MSG_WARN(don't have both flex and bison; reverting to lex/yacc) $1=lex $2=yacc fi if test "$$1" = flex -a -n "$3" ; then $1="$$1 -P$3" $2="$$2 -p $3" fi]) dnl dnl Checks to see if union wait is used with WEXITSTATUS() dnl dnl usage: dnl dnl AC_LBL_UNION_WAIT dnl dnl results: dnl dnl DECLWAITSTATUS (defined) dnl AC_DEFUN(AC_LBL_UNION_WAIT, [AC_MSG_CHECKING(if union wait is used) AC_CACHE_VAL(ac_cv_lbl_union_wait, AC_TRY_COMPILE([ # include # include ], [int status; u_int i = WEXITSTATUS(status); u_int j = waitpid(0, &status, 0);], ac_cv_lbl_union_wait=no, 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) else AC_DEFINE(DECLWAITSTATUS,int) fi]) dnl dnl Checks to see if the sockaddr struct has the 4.4 BSD sa_len member dnl dnl usage: dnl dnl AC_LBL_SOCKADDR_SA_LEN dnl dnl results: dnl dnl HAVE_SOCKADDR_SA_LEN (defined) dnl AC_DEFUN(AC_LBL_SOCKADDR_SA_LEN, [AC_MSG_CHECKING(if sockaddr struct has sa_len member) AC_CACHE_VAL(ac_cv_lbl_sockaddr_has_sa_len, AC_TRY_COMPILE([ # include # include ], [u_int i = sizeof(((struct sockaddr *)0)->sa_len)], ac_cv_lbl_sockaddr_has_sa_len=yes, 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) fi]) dnl dnl Checks to see if -R is used dnl dnl usage: dnl dnl AC_LBL_HAVE_RUN_PATH dnl dnl results: dnl dnl ac_cv_lbl_have_run_path (yes or no) dnl AC_DEFUN(AC_LBL_HAVE_RUN_PATH, [AC_MSG_CHECKING(for ${CC-cc} -R) AC_CACHE_VAL(ac_cv_lbl_have_run_path, [echo 'main(){}' > conftest.c ${CC-cc} -o conftest conftest.c -R/a1/b2/c3 >conftest.out 2>&1 if test ! -s conftest.out ; then ac_cv_lbl_have_run_path=yes else ac_cv_lbl_have_run_path=no fi rm -f conftest*]) AC_MSG_RESULT($ac_cv_lbl_have_run_path) ]) dnl dnl Due to the stupid way it's implemented, AC_CHECK_TYPE is nearly useless. dnl dnl usage: dnl dnl AC_LBL_CHECK_TYPE dnl dnl results: dnl dnl int32_t (defined) dnl u_int32_t (defined) dnl AC_DEFUN(AC_LBL_CHECK_TYPE, [AC_MSG_CHECKING(for $1 using $CC) AC_CACHE_VAL(ac_cv_lbl_have_$1, AC_TRY_COMPILE([ # include "confdefs.h" # include # if STDC_HEADERS # include # include # endif], [$1 i], ac_cv_lbl_have_$1=yes, 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) fi]) dnl dnl Checks to see if unaligned memory accesses fail dnl dnl usage: dnl dnl AC_LBL_UNALIGNED_ACCESS dnl dnl results: dnl dnl LBL_ALIGN (DEFINED) dnl AC_DEFUN(AC_LBL_UNALIGNED_ACCESS, [AC_MSG_CHECKING(if unaligned accesses fail) AC_CACHE_VAL(ac_cv_lbl_unaligned_fail, [case "$target_cpu" in alpha|hp*|mips|sparc) ac_cv_lbl_unaligned_fail=yes ;; *) cat >conftest.c < # include # include unsigned char a[[5]] = { 1, 2, 3, 4, 5 }; main() { unsigned int i; pid_t pid; int status; /* avoid "core dumped" message */ pid = fork(); if (pid < 0) exit(2); if (pid > 0) { /* parent */ pid = waitpid(pid, &status, 0); if (pid < 0) exit(3); exit(!WIFEXITED(status)); } /* child */ i = *(unsigned int *)&a[[1]]; printf("%d\n", i); exit(0); } EOF ${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS \ conftest.c $LIBS >/dev/null 2>&1 if test ! -x conftest ; then dnl failed to compile for some reason ac_cv_lbl_unaligned_fail=yes else ./conftest >conftest.out if test ! -s conftest.out ; then ac_cv_lbl_unaligned_fail=yes else ac_cv_lbl_unaligned_fail=no fi fi rm -f conftest* core core.conftest ;; esac]) AC_MSG_RESULT($ac_cv_lbl_unaligned_fail) if test $ac_cv_lbl_unaligned_fail = yes ; then AC_DEFINE(LBL_ALIGN) fi]) dnl dnl If using gcc and the file .devel exists: dnl Compile with -g (if supported) and -Wall dnl If using gcc 2, do extra prototype checking dnl If an os prototype include exists, symlink os-proto.h to it dnl dnl usage: dnl dnl AC_LBL_DEVEL(copt) dnl dnl results: dnl dnl $1 (copt appended) dnl HAVE_OS_PROTO_H (defined) dnl os-proto.h (symlinked) dnl AC_DEFUN(AC_LBL_DEVEL, [rm -f os-proto.h if test "${LBL_CFLAGS+set}" = set; then $1="$$1 ${LBL_CFLAGS}" fi if test -f .devel ; then if test "$GCC" = yes ; then if test "${LBL_CFLAGS+set}" != set; then if test "$ac_cv_prog_cc_g" = yes ; then $1="-g $$1" fi $1="$$1 -Wall" if test $ac_cv_lbl_gcc_vers -gt 1 ; then $1="$$1 -Wmissing-prototypes -Wstrict-prototypes" fi fi else case "$target_os" in irix6*) V_CCOPT="$V_CCOPT -n32" ;; *) ;; esac fi os=`echo $target_os | sed -e 's/\([[0-9]][[0-9]]*\)[[^0-9]].*$/\1/'` name="lbl/os-$os.h" if test -f $name ; then ln -s $name os-proto.h AC_DEFINE(HAVE_OS_PROTO_H) else AC_MSG_WARN(can't find $name) fi fi]) dnl dnl Improved version of AC_CHECK_LIB dnl dnl Thanks to John Hawkinson (jhawk@mit.edu) dnl dnl usage: dnl dnl AC_LBL_CHECK_LIB(LIBRARY, FUNCTION [, ACTION-IF-FOUND [, dnl ACTION-IF-NOT-FOUND [, OTHER-LIBRARIES]]]) dnl dnl results: dnl dnl LIBS dnl define(AC_LBL_CHECK_LIB, [AC_MSG_CHECKING([for $2 in -l$1]) dnl Use a cache variable name containing both the library and function name, dnl because the test really is for library $1 defining function $2, not dnl just for library $1. Separate tests with the same $1 and different $2's dnl may have different results. ac_lib_var=`echo $1['_']$2['_']$5 | sed 'y%./+- %__p__%'` AC_CACHE_VAL(ac_cv_lbl_lib_$ac_lib_var, [ac_save_LIBS="$LIBS" LIBS="-l$1 $5 $LIBS" AC_TRY_LINK(dnl ifelse([$2], [main], , dnl Avoid conflicting decl of main. [/* Override any gcc2 internal prototype to avoid an error. */ ]ifelse(AC_LANG, CPLUSPLUS, [#ifdef __cplusplus extern "C" #endif ])dnl [/* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $2(); ]), [$2()], eval "ac_cv_lbl_lib_$ac_lib_var=yes", eval "ac_cv_lbl_lib_$ac_lib_var=no") LIBS="$ac_save_LIBS" ])dnl if eval "test \"`echo '$ac_cv_lbl_lib_'$ac_lib_var`\" = yes"; then AC_MSG_RESULT(yes) ifelse([$3], , [changequote(, )dnl ac_tr_lib=HAVE_LIB`echo $1 | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` changequote([, ])dnl AC_DEFINE_UNQUOTED($ac_tr_lib) LIBS="-l$1 $LIBS" ], [$3]) else AC_MSG_RESULT(no) ifelse([$4], , , [$4 ])dnl fi ]) dnl dnl AC_LBL_LIBRARY_NET dnl dnl This test is for network applications that need socket() and dnl gethostbyname() -ish functions. Under Solaris, those applications dnl need to link with "-lsocket -lnsl". Under IRIX, they need to link dnl with "-lnsl" but should *not* link with "-lsocket" because dnl libsocket.a breaks a number of things (for instance: dnl gethostbyname() under IRIX 5.2, and snoop sockets under most dnl versions of IRIX). dnl dnl Unfortunately, many application developers are not aware of this, dnl and mistakenly write tests that cause -lsocket to be used under dnl IRIX. It is also easy to write tests that cause -lnsl to be used dnl under operating systems where neither are necessary (or useful), dnl such as SunOS 4.1.4, which uses -lnsl for TLI. dnl dnl This test exists so that every application developer does not test dnl this in a different, and subtly broken fashion. dnl It has been argued that this test should be broken up into two dnl seperate tests, one for the resolver libraries, and one for the dnl libraries necessary for using Sockets API. Unfortunately, the two dnl are carefully intertwined and allowing the autoconf user to use dnl them independantly potentially results in unfortunate ordering dnl dependancies -- as such, such component macros would have to dnl carefully use indirection and be aware if the other components were dnl executed. Since other autoconf macros do not go to this trouble, dnl and almost no applications use sockets without the resolver, this dnl complexity has not been implemented. dnl dnl The check for libresolv is in case you are attempting to link dnl statically and happen to have a libresolv.a lying around (and no dnl libnsl.a). dnl AC_DEFUN(AC_LBL_LIBRARY_NET, [ # Most operating systems have gethostbyname() in the default searched # libraries (i.e. libc): AC_CHECK_FUNC(gethostbyname, , # Some OSes (eg. Solaris) place it in libnsl: AC_LBL_CHECK_LIB(nsl, gethostbyname, , # Some strange OSes (SINIX) have it in libsocket: AC_LBL_CHECK_LIB(socket, gethostbyname, , # Unfortunately libsocket sometimes depends on libnsl. # AC_CHECK_LIB's API is essentially broken so the # following ugliness is necessary: AC_LBL_CHECK_LIB(socket, gethostbyname, LIBS="-lsocket -lnsl $LIBS", AC_CHECK_LIB(resolv, gethostbyname), -lnsl)))) AC_CHECK_FUNC(socket, , AC_CHECK_LIB(socket, socket, , AC_LBL_CHECK_LIB(socket, socket, LIBS="-lsocket -lnsl $LIBS", , -lnsl))) # DLPI needs putmsg under HPUX so test for -lstr while we're at it AC_CHECK_LIB(str, putmsg) ]) libpcap-0.5/./bpf_image.c100644 263 461 11525 6777230340 13732 0ustar mcrtcpdump/* * Copyright (c) 1990, 1991, 1992, 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_image.c,v 1.22.1.1 1999/10/07 23:46:40 mcr Exp $ (LBL)"; #endif #include #include #include #include #include "pcap-int.h" #include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif char * bpf_image(p, n) struct bpf_insn *p; int n; { int v; char *fmt, *op; static char image[256]; char operand[64]; v = p->k; switch (p->code) { default: op = "unimp"; fmt = "0x%x"; v = p->code; break; case BPF_RET|BPF_K: op = "ret"; fmt = "#%d"; break; case BPF_RET|BPF_A: op = "ret"; fmt = ""; break; case BPF_LD|BPF_W|BPF_ABS: op = "ld"; fmt = "[%d]"; break; case BPF_LD|BPF_H|BPF_ABS: op = "ldh"; fmt = "[%d]"; break; case BPF_LD|BPF_B|BPF_ABS: op = "ldb"; fmt = "[%d]"; break; case BPF_LD|BPF_W|BPF_LEN: op = "ld"; fmt = "#pktlen"; break; case BPF_LD|BPF_W|BPF_IND: op = "ld"; fmt = "[x + %d]"; break; case BPF_LD|BPF_H|BPF_IND: op = "ldh"; fmt = "[x + %d]"; break; case BPF_LD|BPF_B|BPF_IND: op = "ldb"; fmt = "[x + %d]"; break; case BPF_LD|BPF_IMM: op = "ld"; fmt = "#0x%x"; break; case BPF_LDX|BPF_IMM: op = "ldx"; fmt = "#0x%x"; break; case BPF_LDX|BPF_MSH|BPF_B: op = "ldxb"; fmt = "4*([%d]&0xf)"; break; case BPF_LD|BPF_MEM: op = "ld"; fmt = "M[%d]"; break; case BPF_LDX|BPF_MEM: op = "ldx"; fmt = "M[%d]"; break; case BPF_ST: op = "st"; fmt = "M[%d]"; break; case BPF_STX: op = "stx"; fmt = "M[%d]"; break; case BPF_JMP|BPF_JA: op = "ja"; fmt = "%d"; v = n + 1 + p->k; break; case BPF_JMP|BPF_JGT|BPF_K: op = "jgt"; fmt = "#0x%x"; break; case BPF_JMP|BPF_JGE|BPF_K: op = "jge"; fmt = "#0x%x"; break; case BPF_JMP|BPF_JEQ|BPF_K: op = "jeq"; fmt = "#0x%x"; break; case BPF_JMP|BPF_JSET|BPF_K: op = "jset"; fmt = "#0x%x"; break; case BPF_JMP|BPF_JGT|BPF_X: op = "jgt"; fmt = "x"; break; case BPF_JMP|BPF_JGE|BPF_X: op = "jge"; fmt = "x"; break; case BPF_JMP|BPF_JEQ|BPF_X: op = "jeq"; fmt = "x"; break; case BPF_JMP|BPF_JSET|BPF_X: op = "jset"; fmt = "x"; break; case BPF_ALU|BPF_ADD|BPF_X: op = "add"; fmt = "x"; break; case BPF_ALU|BPF_SUB|BPF_X: op = "sub"; fmt = "x"; break; case BPF_ALU|BPF_MUL|BPF_X: op = "mul"; fmt = "x"; break; case BPF_ALU|BPF_DIV|BPF_X: op = "div"; fmt = "x"; break; case BPF_ALU|BPF_AND|BPF_X: op = "and"; fmt = "x"; break; case BPF_ALU|BPF_OR|BPF_X: op = "or"; fmt = "x"; break; case BPF_ALU|BPF_LSH|BPF_X: op = "lsh"; fmt = "x"; break; case BPF_ALU|BPF_RSH|BPF_X: op = "rsh"; fmt = "x"; break; case BPF_ALU|BPF_ADD|BPF_K: op = "add"; fmt = "#%d"; break; case BPF_ALU|BPF_SUB|BPF_K: op = "sub"; fmt = "#%d"; break; case BPF_ALU|BPF_MUL|BPF_K: op = "mul"; fmt = "#%d"; break; case BPF_ALU|BPF_DIV|BPF_K: op = "div"; fmt = "#%d"; break; case BPF_ALU|BPF_AND|BPF_K: op = "and"; fmt = "#0x%x"; break; case BPF_ALU|BPF_OR|BPF_K: op = "or"; fmt = "#0x%x"; break; case BPF_ALU|BPF_LSH|BPF_K: op = "lsh"; fmt = "#%d"; break; case BPF_ALU|BPF_RSH|BPF_K: op = "rsh"; fmt = "#%d"; break; case BPF_ALU|BPF_NEG: op = "neg"; fmt = ""; break; case BPF_MISC|BPF_TAX: op = "tax"; fmt = ""; break; case BPF_MISC|BPF_TXA: op = "txa"; fmt = ""; break; } (void)sprintf(operand, fmt, v); (void)sprintf(image, (BPF_CLASS(p->code) == BPF_JMP && BPF_OP(p->code) != BPF_JA) ? "(%03d) %-8s %-16s jt %d\tjf %d" : "(%03d) %-8s %s", n, op, operand, n + 1 + p->jt, n + 1 + p->jf); return image; } libpcap-0.5/./config.guess100755 263 461 47622 6777230340 14204 0ustar mcrtcpdump#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc. # # 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 # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Written by Per Bothner . # The master version of this file is at the FSF in /home/gd/gnu/lib. # # 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). # # Only a few systems have been added to this list; please add others # (but try to keep the structure clean). # # 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 PATH=$PATH:/.attbin ; export PATH 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_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 alpha:OSF1:*:*) # 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]//'` exit 0 ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit 0 ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-cbm-sysv4 exit 0;; amiga:NetBSD:*:*) echo m68k-cbm-netbsd${UNAME_RELEASE} exit 0 ;; amiga:OpenBSD:*:*) echo m68k-cbm-openbsd${UNAME_RELEASE} exit 0 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit 0;; Pyramid*:OSx*:*:*|MIS*: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 else echo pyramid-pyramid-bsd fi exit 0 ;; NILE:*:*:dcosx) echo pyramid-pyramid-svr4 exit 0 ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; i86pc:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit 0 ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} 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} exit 0 ;; sun3*:OpenBSD:*:*) echo m68k-sun-openbsd${UNAME_RELEASE} exit 0 ;; mac68k:NetBSD:*:*) echo m68k-apple-netbsd${UNAME_RELEASE} exit 0 ;; mac68k:OpenBSD:*:*) echo m68k-apple-openbsd${UNAME_RELEASE} exit 0 ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit 0 ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit 0 ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit 0 ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit 0 ;; mips:*:*:UMIPS | mips:*:*:RISCos) sed 's/^ //' << EOF >dummy.c int main (argc, argv) int argc; char **argv; { #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif 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 echo mips-mips-riscos${UNAME_RELEASE} exit 0 ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit 0 ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit 0 ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit 0 ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit 0 ;; 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 echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit 0 ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit 0 ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit 0 ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit 0 ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit 0 ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit 0 ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i?86:AIX:*:*) echo i386-ibm-aix exit 0 ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then sed 's/^ //' << EOF >dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF ${CC-cc} 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 else echo rs6000-ibm-aix3.2 fi exit 0 ;; *:AIX:*:4) if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=4.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} 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 echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit 0 ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit 0 ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit 0 ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit 0 ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit 0 ;; 9000/[3478]??:HP-UX:*:*) 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 ;; 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 #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF ${CC-cc} 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:*:* ) echo hppa1.1-hp-bsd exit 0 ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit 0 ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit 0 ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit 0 ;; i?86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit 0 ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit 0 ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit 0 ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit 0 ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit 0 ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit 0 ;; CRAY*X-MP:*:*:*) echo xmp-cray-unicos exit 0 ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} exit 0 ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ exit 0 ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} 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_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} exit 0 ;; i?86:BSD/386:*:* | *:BSD/OS:*:*) echo ${UNAME_MACHINE}-pc-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 exit 0 ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin32 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,/.*$,,'` 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 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/. \ && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 # Determine whether the default compiler is a.out or elf cat >dummy.c </dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0 rm -f dummy.c dummy 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:*:4.*:* | i?86:SYSTEM_V:4.*:*) if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} fi exit 0 ;; i?86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit 0 ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit 0 ;; paragon:*:*:*) echo i860-intel-osf1 exit 0 ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit 0 ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv 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) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4.3${OS_REL} && exit 0 /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4 && exit 0 ;; m68*:LynxOS:2.*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit 0 ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit 0 ;; i?86:LynxOS:2.*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit 0 ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit 0 ;; rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit 0 ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit 0 ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit 0 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit 0 ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit 0 ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit 0 ;; R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*) 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 echo i586-unisys-sysv4 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 < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #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); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) #if !defined (ultrix) printf ("vax-dec-bsd\n"); exit (0); #else printf ("vax-dec-ultrix\n"); exit (0); #endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF ${CC-cc} 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. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit 0 ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; c34*) echo c34-convex-bsd exit 0 ;; c38*) echo c38-convex-bsd exit 0 ;; c4*) echo c4-convex-bsd exit 0 ;; esac fi #echo '(Unable to guess system type)' 1>&2 exit 1 libpcap-0.5/./config.sub100755 263 461 45444 6777230340 13647 0ustar mcrtcpdump#! /bin/sh # Configuration validation subroutine script, version 1.1. # Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. # 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. # # 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 # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # 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. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # 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 # First pass through any local machine types. case $1 in *local*) echo $1 exit 0 ;; *) ;; 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*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple) os= basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco5) os=sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; 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) basic_machine=$basic_machine-unknown ;; # 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) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 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-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-cbm ;; amigados) basic_machine=m68k-cbm os=-amigados ;; amigaunix | amix) basic_machine=m68k-cbm os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | ymp) basic_machine=ymp-cray os=-unicos ;; cray2) basic_machine=cray2-cray os=-unicos ;; [ctj]90-cray) basic_machine=c90-cray os=-unicos ;; crds | unos) basic_machine=m68k-crds ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; 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) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; i370-ibm* | ibm*) basic_machine=i370-ibm os=-mvs ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i[3456]86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i[3456]86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i[3456]86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i[3456]86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; miniframe) basic_machine=m68000-convergent ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; np1) basic_machine=np1-gould ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pentium | p5) basic_machine=i586-intel ;; pentiumpro | p6) basic_machine=i686-intel ;; pentium-* | p5-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-*) 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 ;; pn) basic_machine=pn-gould ;; power) basic_machine=rs6000-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; symmetry) basic_machine=i386-sequent os=-dynix ;; tower | tower-32) basic_machine=m68k-ncr ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; xmp) basic_machine=xmp-cray os=-unicos ;; xps | xps100) basic_machine=xps100-honeywell ;; none) basic_machine=none-none os=-none ;; # 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. mips) basic_machine=mips-mips ;; romp) basic_machine=romp-ibm ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sparc) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -unixware* | svr4*) os=-sysv4 ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -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* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -cygwin32* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -linux-gnu* | -uxpv*) # Remember, each alternative MUST END IN *, to match a version number. ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -ctix* | -uts*) os=-sysv ;; -ns2 ) os=-nextstep2 ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -xenix) os=-xenix ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in *-acorn) os=-riscix1.2 ;; arm*-semi) os=-aout ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-ibm) os=-aix ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigados ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f301-fujitsu) os=-uxpv ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -aix*) vendor=ibm ;; -hpux*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs*) vendor=ibm ;; -ptx*) vendor=sequent ;; -vxsim* | -vxworks*) vendor=wrs ;; -aux*) vendor=apple ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os libpcap-0.5/./configure100755 263 461 201032 7007334070 13566 0ustar mcrtcpdump#! /bin/sh # 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. # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # Defaults: ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: ac_help="$ac_help --without-gcc don't use gcc" ac_help="$ac_help --disable-protochain disable \"protochain\" insn" ac_help="$ac_help --with-pcap=TYPE use packet capture TYPE" ac_help="$ac_help --enable-ipv6 build IPv6-capable version" ac_help="$ac_help --without-flex don't use flex" ac_help="$ac_help --without-bison don't use bison" # Initialize some variables set by options. # The variables have the same names as the options, with # dashes changed to underlines. build=NONE cache_file=./config.cache exec_prefix=NONE host=NONE no_create= nonopt=NONE no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= target=NONE verbose= x_includes=NONE x_libraries=NONE bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. ac_max_here_lines=12 ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi case "$ac_option" in -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) ac_optarg= ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case "$ac_option" in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir="$ac_optarg" ;; -build | --build | --buil | --bui | --bu) ac_prev=build ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build="$ac_optarg" ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file="$ac_optarg" ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir="$ac_optarg" ;; -disable-* | --disable-*) ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` eval "enable_${ac_feature}=no" ;; -enable-* | --enable-*) ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "enable_${ac_feature}='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix="$ac_optarg" ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he) # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat << EOF Usage: configure [options] [host] Options: [defaults in brackets after descriptions] Configuration: --cache-file=FILE cache test results in FILE --help print this message --no-create do not create output files --quiet, --silent do not print \`checking...' messages --version print the version of autoconf that created configure Directory and file names: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [same as prefix] --bindir=DIR user executables in DIR [EPREFIX/bin] --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] --libexecdir=DIR program executables in DIR [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data in DIR [PREFIX/share] --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data in DIR [PREFIX/com] --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] --libdir=DIR object code libraries in DIR [EPREFIX/lib] --includedir=DIR C header files in DIR [PREFIX/include] --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] --infodir=DIR info documentation in DIR [PREFIX/info] --mandir=DIR man documentation in DIR [PREFIX/man] --srcdir=DIR find the sources in DIR [configure dir or ..] --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names EOF cat << EOF Host type: --build=BUILD configure for building on BUILD [BUILD=HOST] --host=HOST configure for HOST [guessed] --target=TARGET configure for TARGET [TARGET=HOST] Features and packages: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR EOF if test -n "$ac_help"; then echo "--enable and --with options recognized:$ac_help" fi exit 0 ;; -host | --host | --hos | --ho) ac_prev=host ;; -host=* | --host=* | --hos=* | --ho=*) host="$ac_optarg" ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir="$ac_optarg" ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir="$ac_optarg" ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir="$ac_optarg" ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir="$ac_optarg" ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir="$ac_optarg" ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir="$ac_optarg" ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir="$ac_optarg" ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix="$ac_optarg" ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix="$ac_optarg" ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix="$ac_optarg" ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name="$ac_optarg" ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir="$ac_optarg" ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir="$ac_optarg" ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site="$ac_optarg" ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir="$ac_optarg" ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir="$ac_optarg" ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) echo "configure generated by autoconf version 2.13" exit 0 ;; -with-* | --with-*) ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "with_${ac_package}='$ac_optarg'" ;; -without-* | --without-*) ac_package=`echo $ac_option|sed -e 's/-*without-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` eval "with_${ac_package}=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes="$ac_optarg" ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries="$ac_optarg" ;; -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } ;; *) if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then echo "configure: warning: $ac_option: invalid host type" 1>&2 fi if test "x$nonopt" != xNONE; then { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } fi nonopt="$ac_option" ;; esac done if test -n "$ac_prev"; then { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } fi trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 # File descriptor usage: # 0 standard input # 1 file creation # 2 errors and warnings # 3 some systems may open it to /dev/tty # 4 used on the Kubota Titan # 6 checking for... messages and results # 5 compiler messages saved in config.log if test "$silent" = yes; then exec 6>/dev/null else exec 6>&1 fi exec 5>./config.log echo "\ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. " 1>&5 # Strip out --no-create and --no-recursion so they do not pile up. # Also quote any args containing shell metacharacters. ac_configure_args= for ac_arg do case "$ac_arg" in -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ac_configure_args="$ac_configure_args '$ac_arg'" ;; *) ac_configure_args="$ac_configure_args $ac_arg" ;; esac done # NLS nuisances. # Only set these to C if already set. These must not be set unconditionally # because not all systems understand e.g. LANG=C (notably SCO). # Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! # Non-C LC_CTYPE values break the ctype check. if test "${LANG+set}" = set; then LANG=C; export LANG; fi if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo > confdefs.h # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. ac_unique_file=pcap.c # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_prog=$0 ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } else { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } fi fi srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then echo "loading site script $ac_site_file" . "$ac_site_file" fi done if test -r "$cache_file"; then echo "loading cache $cache_file" . $cache_file else echo "creating cache $cache_file" > $cache_file fi ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross ac_exeext= ac_objext=o if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then ac_n= ac_c=' ' ac_t=' ' else ac_n=-n ac_c= ac_t= fi else ac_n= ac_c='\c' ac_t= fi ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f $ac_dir/install.sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break fi done if test -z "$ac_aux_dir"; then { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } fi ac_config_guess=$ac_aux_dir/config.guess ac_config_sub=$ac_aux_dir/config.sub ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. # Do some error checking and defaulting for the host and target type. # The inputs are: # configure --host=HOST --target=TARGET --build=BUILD NONOPT # # The rules are: # 1. You are not allowed to specify --host, --target, and nonopt at the # same time. # 2. Host defaults to nonopt. # 3. If nonopt is not specified, then host defaults to the current host, # as determined by config.guess. # 4. Target and build default to nonopt. # 5. If nonopt is not specified, then target and build default to host. # The aliases save the names the user supplied, while $host etc. # will get canonicalized. case $host---$target---$nonopt in NONE---*---* | *---NONE---* | *---*---NONE) ;; *) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; esac # Make sure we can run config.sub. if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : 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 host_alias=$host case "$host_alias" in NONE) case $nonopt in NONE) if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } fi ;; *) host_alias=$nonopt ;; esac ;; esac host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` 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 target_alias=$target case "$target_alias" in NONE) case $nonopt in NONE) target_alias=$host_alias ;; *) target_alias=$nonopt ;; esac ;; esac target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias` target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` 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 build_alias=$build case "$build_alias" in NONE) case $nonopt in NONE) build_alias=$host_alias ;; *) build_alias=$nonopt ;; esac ;; esac build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$build" 1>&6 test "$host_alias" != "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- umask 002 if test -z "$PWD" ; then PWD=`pwd` fi # Check whether --with-gcc or --without-gcc was given. if test "${with_gcc+set}" = set; then withval="$with_gcc" : fi V_CCOPT="-O" V_INCLS="" if test "${srcdir}" != "." ; then V_INCLS="-I\$(srcdir)" fi if test "${CFLAGS+set}" = set; then LBL_CFLAGS="$CFLAGS" fi if test -z "$CC" ; then case "$target_os" in bsdi*) # 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 if eval "test \"`echo '$''{'ac_cv_prog_SHLICC2'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$SHLICC2"; then ac_cv_prog_SHLICC2="$SHLICC2" # 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_SHLICC2="yes" break fi done IFS="$ac_save_ifs" test -z "$ac_cv_prog_SHLICC2" && ac_cv_prog_SHLICC2="no" fi fi SHLICC2="$ac_cv_prog_SHLICC2" if test -n "$SHLICC2"; then echo "$ac_t""$SHLICC2" 1>&6 else echo "$ac_t""no" 1>&6 fi if test $SHLICC2 = yes ; then CC=shlicc2 export CC fi ;; esac fi if test -z "$CC" -a "$with_gcc" = no ; then CC=cc export CC 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 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # 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_CC="gcc" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi 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 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_prog_rejected=no ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" break fi done IFS="$ac_save_ifs" if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# -gt 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift set dummy "$ac_dir/$ac_word" "$@" shift ac_cv_prog_CC="$@" fi fi fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then case "`uname -s`" in *win32* | *WIN32*) # 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 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # 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_CC="cl" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi ;; esac fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } 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 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF #line 843 "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 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 ac_cv_prog_cc_cross=no else ac_cv_prog_cc_cross=yes fi else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 ac_cv_prog_cc_works=no fi rm -fr conftest* ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 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 "$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 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no fi fi echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes else GCC= fi 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 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then ac_cv_prog_cc_g=yes else ac_cv_prog_cc_g=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 if test "$ac_test_CFLAGS" = set; then CFLAGS="$ac_save_CFLAGS" elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi if test "$GCC" = yes ; then if test "$SHLICC2" = yes ; then ac_cv_lbl_gcc_vers=2 V_CCOPT="-O2" else echo $ac_n "checking gcc version""... $ac_c" 1>&6 echo "configure:944: 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 ac_cv_lbl_gcc_vers=`$CC -v 2>&1 | \ sed -e '/^gcc version /!d' \ -e 's/^gcc version //' \ -e 's/ .*//' -e 's/^[^0-9]*//' \ -e 's/\..*//'` fi echo "$ac_t""$ac_cv_lbl_gcc_vers" 1>&6 if test $ac_cv_lbl_gcc_vers -gt 1 ; then V_CCOPT="-O2" 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 if eval "test \"`echo '$''{'ac_cv_lbl_cc_ansi_prototypes'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { int frob(int, char *) ; return 0; } EOF if { (eval echo configure:974: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_lbl_cc_ansi_prototypes=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_lbl_cc_ansi_prototypes=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_lbl_cc_ansi_prototypes" 1>&6 if test $ac_cv_lbl_cc_ansi_prototypes = no ; then case "$target_os" in 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 savedcflags="$CFLAGS" CFLAGS="-Aa -D_HPUX_SOURCE $CFLAGS" if eval "test \"`echo '$''{'ac_cv_lbl_cc_hpux_cc_aa'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { int frob(int, char *) ; return 0; } EOF if { (eval echo configure:1006: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_lbl_cc_hpux_cc_aa=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_lbl_cc_hpux_cc_aa=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_lbl_cc_hpux_cc_aa" 1>&6 if test $ac_cv_lbl_cc_hpux_cc_aa = no ; then { echo "configure: error: see the INSTALL doc for more info" 1>&2; exit 1; } fi CFLAGS="$savedcflags" V_CCOPT="-Aa $V_CCOPT" cat >> confdefs.h <<\EOF #define _HPUX_SOURCE 1 EOF ;; *) { echo "configure: error: see the INSTALL doc for more info" 1>&2; exit 1; } ;; esac fi V_INCLS="$V_INCLS -I/usr/local/include" LDFLAGS="$LDFLAGS -L/usr/local/lib" case "$target_os" in irix*) V_CCOPT="$V_CCOPT -xansi -signed -g3" ;; osf*) V_CCOPT="$V_CCOPT -std1 -g3" ;; 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 if eval "test \"`echo '$''{'ac_cv_lbl_cc_const_proto'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { 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 rm -rf conftest* ac_cv_lbl_cc_const_proto=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_lbl_cc_const_proto=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_lbl_cc_const_proto" 1>&6 if test $ac_cv_lbl_cc_const_proto = no ; then cat >> confdefs.h <<\EOF #define const EOF fi ;; esac 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 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # This must be in double quotes, not single quotes, because CPP may get # substituted into the Makefile and "${CC-cc}" will confuse make. CPP="${CC-cc} -E" # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1109: \"$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 : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1126: \"$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 : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1143: \"$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 : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP=/lib/cpp fi rm -f conftest* fi rm -f conftest* fi rm -f conftest* ac_cv_prog_CPP="$CPP" fi CPP="$ac_cv_prog_CPP" else ac_cv_prog_CPP="$CPP" fi echo "$ac_t""$CPP" 1>&6 for ac_hdr in malloc.h sys/ioccom.h sys/sockio.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 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1181: \"$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* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi 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 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 < # include # include # ifdef HAVE_SYS_IOCCOM_H # include # endif int main() { switch (0) { case _IO('A', 1):; case _IO('B', 1):; } ; return 0; } EOF if { (eval echo configure:1234: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_lbl_gcc_fixincludes=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_lbl_gcc_fixincludes=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_lbl_gcc_fixincludes" 1>&6 if test $ac_cv_lbl_gcc_fixincludes = no ; then # Don't cache failure unset ac_cv_lbl_gcc_fixincludes { echo "configure: error: see the INSTALL for more info" 1>&2; exit 1; } fi fi for ac_func in ether_hostton strerror do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:1257: 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 < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:1285: \"$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 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi 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 # Check whether --enable-protochain or --disable-protochain was given. if test "${enable_protochain+set}" = set; then enableval="$enable_protochain" : fi case "x$enable_protochain" in xyes) enable_protochain=enabled ;; xno) enable_protochain=disabled ;; x) enable_protochain=enabled ;; esac if test "$enable_protochain" = "disabled"; then cat >> confdefs.h <<\EOF #define NO_PROTOCHAIN 1 EOF fi echo "$ac_t""${enable_protochain}" 1>&6 # Check whether --with-pcap or --without-pcap was given. if test "${with_pcap+set}" = set; then withval="$with_pcap" : fi echo $ac_n "checking packet capture type""... $ac_c" 1>&6 echo "configure:1339: checking packet capture type" >&5 if test ! -z "$with_pcap" ; then V_PCAP="$withval" elif test -r /dev/bpf0 ; then V_PCAP=bpf elif test -r /usr/include/net/pfilt.h ; then V_PCAP=pf elif test -r /dev/enet ; then V_PCAP=enet elif test -r /dev/nit ; then V_PCAP=snit elif test -r /usr/include/sys/net/nit.h ; then V_PCAP=nit elif test -r /usr/include/net/raw.h ; then V_PCAP=snoop elif test -r /usr/include/sys/dlpi.h ; then V_PCAP=dlpi elif test -r /usr/include/linux/socket.h ; then V_PCAP=linux elif test -c /dev/bpf0 ; then # check again in case not readable V_PCAP=bpf elif test -c /dev/enet ; then # check again in case not readable V_PCAP=enet elif test -c /dev/nit ; then # check again in case not readable V_PCAP=snit else V_PCAP=null 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 # Check whether --enable-ipv6 or --disable-ipv6 was given. if test "${enable_ipv6+set}" = set; then enableval="$enable_ipv6" : fi if test "$enable_ipv6" = "yes"; then cat >> confdefs.h <<\EOF #define INET6 1 EOF fi echo "$ac_t""${enable_ipv6-no}" 1>&6 case "$V_PCAP" in dlpi) for ac_hdr in sys/bufmod.h sys/dlpi_ext.h 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 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1402: \"$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* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done echo $ac_n "checking for /dev/dlpi device""... $ac_c" 1>&6 echo "configure:1429: checking for /dev/dlpi device" >&5 if test -c /dev/dlpi ; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_DEV_DLPI 1 EOF else 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 if test -d $dir ; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <&6 fi fi ;; linux) for ac_hdr in net/if_arp.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 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1468: \"$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* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 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 $ac_n "(cached) $ac_c" 1>&6 else ac_cv_linux_vers=`uname -r 2>&1 | \ sed -n -e '$s/.* //' -e '$s/\..*//p'` fi echo "$ac_t""$ac_cv_linux_vers" 1>&6 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 ;; null) echo "configure: warning: cannot determine packet capture interface" 1>&2 echo "configure: warning: (see the INSTALL doc for more info)" 1>&2 ;; esac # Check whether --with-flex or --without-flex was given. if test "${with_flex+set}" = set; then withval="$with_flex" : fi # Check whether --with-bison or --without-bison was given. if test "${with_bison+set}" = set; then withval="$with_bison" : fi if test "$with_flex" = no ; then V_LEX=lex else for ac_prog in flex 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 if eval "test \"`echo '$''{'ac_cv_prog_V_LEX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$V_LEX"; then ac_cv_prog_V_LEX="$V_LEX" # 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_LEX="$ac_prog" break fi done IFS="$ac_save_ifs" fi fi V_LEX="$ac_cv_prog_V_LEX" if test -n "$V_LEX"; then echo "$ac_t""$V_LEX" 1>&6 else echo "$ac_t""no" 1>&6 fi test -n "$V_LEX" && break done test -n "$V_LEX" || V_LEX="lex" fi 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 if eval "test \"`echo '$''{'ac_cv_lbl_flex_v24'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if flex -V >/dev/null 2>&1; then ac_cv_lbl_flex_v24=yes else ac_cv_lbl_flex_v24=no fi fi echo "$ac_t""$ac_cv_lbl_flex_v24" 1>&6 if test $ac_cv_lbl_flex_v24 = no ; then s="2.4 or higher required" echo "configure: warning: ignoring obsolete flex executable ($s)" 1>&2 V_LEX=lex fi fi if test "$with_bison" = no ; then V_YACC=yacc else for ac_prog in bison 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 if eval "test \"`echo '$''{'ac_cv_prog_V_YACC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$V_YACC"; then ac_cv_prog_V_YACC="$V_YACC" # 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_YACC="$ac_prog" break fi done IFS="$ac_save_ifs" fi fi V_YACC="$ac_cv_prog_V_YACC" if test -n "$V_YACC"; then echo "$ac_t""$V_YACC" 1>&6 else echo "$ac_t""no" 1>&6 fi test -n "$V_YACC" && break done test -n "$V_YACC" || V_YACC="yacc" fi if test "$V_YACC" = bison ; then V_YACC="$V_YACC -y" fi if test "$V_LEX" != lex -a "$V_YACC" = yacc -o "$V_LEX" = lex -a "$V_YACC" != yacc ; then echo "configure: warning: don't have both flex and bison; reverting to lex/yacc" 1>&2 V_LEX=lex V_YACC=yacc fi if test "$V_LEX" = flex -a -n "pcap_" ; then V_LEX="$V_LEX -Ppcap_" V_YACC="$V_YACC -p pcap_" fi case "$target_os" in aix*) cat >> confdefs.h <<\EOF #define _SUN 1 EOF ;; hpux9*) cat >> confdefs.h <<\EOF #define HAVE_HPUX9 1 EOF ;; hpux10.0*) ;; hpux10.1*) ;; hpux*) cat >> confdefs.h <<\EOF #define HAVE_HPUX10_20 1 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 if eval "test \"`echo '$''{'ac_cv_cc_sinix_defined'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_cc_sinix_defined=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_cc_sinix_defined=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_cc_sinix_defined" 1>&6 if test $ac_cv_cc_sinix_defined = no ; then cat >> confdefs.h <<\EOF #define sinix 1 EOF fi ;; solaris*) cat >> confdefs.h <<\EOF #define HAVE_SOLARIS 1 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 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 $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. 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" break fi done IFS="$ac_save_ifs" fi fi V_RANLIB="$ac_cv_prog_V_RANLIB" if test -n "$V_RANLIB"; then echo "$ac_t""$V_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 V_CCOPT="$V_CCOPT ${LBL_CFLAGS}" fi if test -f .devel ; then if test "$GCC" = yes ; then if test "${LBL_CFLAGS+set}" != set; then if test "$ac_cv_prog_cc_g" = yes ; then V_CCOPT="-g $V_CCOPT" fi V_CCOPT="$V_CCOPT -Wall" if test $ac_cv_lbl_gcc_vers -gt 1 ; then V_CCOPT="$V_CCOPT -Wmissing-prototypes -Wstrict-prototypes" fi fi else case "$target_os" in irix6*) V_CCOPT="$V_CCOPT -n32" ;; *) ;; esac fi os=`echo $target_os | sed -e 's/\([0-9][0-9]*\)[^0-9].*$/\1/'` name="lbl/os-$os.h" if test -f $name ; then ln -s $name os-proto.h cat >> confdefs.h <<\EOF #define HAVE_OS_PROTO_H 1 EOF else echo "configure: warning: can't find $name" 1>&2 fi 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 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 < # include 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 rm -rf conftest* ac_cv_lbl_sockaddr_has_sa_len=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_lbl_sockaddr_has_sa_len=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_lbl_sockaddr_has_sa_len" 1>&6 if test $ac_cv_lbl_sockaddr_has_sa_len = yes ; then cat >> confdefs.h <<\EOF #define HAVE_SOCKADDR_SA_LEN 1 EOF fi echo $ac_n "checking if unaligned accesses fail""... $ac_c" 1>&6 echo "configure:1827: 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) ac_cv_lbl_unaligned_fail=yes ;; *) cat >conftest.c < # include # include unsigned char a[5] = { 1, 2, 3, 4, 5 }; main() { unsigned int i; pid_t pid; int status; /* avoid "core dumped" message */ pid = fork(); if (pid < 0) exit(2); if (pid > 0) { /* parent */ pid = waitpid(pid, &status, 0); if (pid < 0) exit(3); exit(!WIFEXITED(status)); } /* child */ i = *(unsigned int *)&a[1]; printf("%d\n", i); exit(0); } EOF ${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS \ conftest.c $LIBS >/dev/null 2>&1 if test ! -x conftest ; then ac_cv_lbl_unaligned_fail=yes else ./conftest >conftest.out if test ! -s conftest.out ; then ac_cv_lbl_unaligned_fail=yes else ac_cv_lbl_unaligned_fail=no fi fi rm -f conftest* core core.conftest ;; esac fi echo "$ac_t""$ac_cv_lbl_unaligned_fail" 1>&6 if test $ac_cv_lbl_unaligned_fail = yes ; then cat >> confdefs.h <<\EOF #define LBL_ALIGN 1 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 # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # 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 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" for ac_dir in $PATH; do # Account for people who put trailing slashes in PATH elements. case "$ac_dir/" in /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do if test -f $ac_dir/$ac_prog; then if test $ac_prog = install && grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : else ac_cv_path_install="$ac_dir/$ac_prog -c" break 2 fi fi done ;; esac done IFS="$ac_save_IFS" fi if test "${ac_cv_path_install+set}" = set; then INSTALL="$ac_cv_path_install" else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL="$ac_install_sh" fi fi echo "$ac_t""$INSTALL" 1>&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' 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 # tests run on this system so they can be shared between configure # scripts and configure runs. It is not useful on other systems. # If it contains results you don't want to keep, you may remove or edit it. # # By default, configure uses ./config.cache as the cache file, # creating it if it does not exist already. You can give configure # the --cache-file=FILE option to use a different cache file; that is # what configure does when it calls configure scripts in # subdirectories, so they share the cache. # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # EOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote substitution # turns \\\\ into \\, and sed turns \\ into \). sed -n \ -e "s/'/'\\\\''/g" \ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' ;; esac >> confcache if cmp -s $cache_file confcache; then : else if test -w $cache_file; then echo "updating cache $cache_file" cat confcache > $cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Any assignment to VPATH causes Sun make to only execute # the first set of double-colon rules, so remove it if not needed. # If there is a colon in the path, we need to keep it. if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' 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 # Without the "./", some shells look in PATH for config.status. : ${CONFIG_STATUS=./config.status} echo creating $CONFIG_STATUS rm -f $CONFIG_STATUS cat > $CONFIG_STATUS </dev/null | sed 1q`: # # $0 $ac_configure_args # # Compiler output produced by configure, useful for debugging # configure, is in ./config.log if it exists. ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) echo "$CONFIG_STATUS generated by autoconf version 2.13" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; *) echo "\$ac_cs_usage"; exit 1 ;; esac done ac_given_srcdir=$srcdir ac_given_INSTALL="$INSTALL" trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF $ac_vpsub $extrasub s%@SHELL@%$SHELL%g s%@CFLAGS@%$CFLAGS%g s%@CPPFLAGS@%$CPPFLAGS%g s%@CXXFLAGS@%$CXXFLAGS%g s%@FFLAGS@%$FFLAGS%g s%@DEFS@%$DEFS%g s%@LDFLAGS@%$LDFLAGS%g s%@LIBS@%$LIBS%g s%@exec_prefix@%$exec_prefix%g s%@prefix@%$prefix%g s%@program_transform_name@%$program_transform_name%g s%@bindir@%$bindir%g s%@sbindir@%$sbindir%g s%@libexecdir@%$libexecdir%g s%@datadir@%$datadir%g s%@sysconfdir@%$sysconfdir%g s%@sharedstatedir@%$sharedstatedir%g s%@localstatedir@%$localstatedir%g s%@libdir@%$libdir%g s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g s%@host@%$host%g s%@host_alias@%$host_alias%g s%@host_cpu@%$host_cpu%g s%@host_vendor@%$host_vendor%g s%@host_os@%$host_os%g s%@target@%$target%g s%@target_alias@%$target_alias%g s%@target_cpu@%$target_cpu%g s%@target_vendor@%$target_vendor%g s%@target_os@%$target_os%g s%@build@%$build%g s%@build_alias@%$build_alias%g s%@build_cpu@%$build_cpu%g s%@build_vendor@%$build_vendor%g s%@build_os@%$build_os%g s%@SHLICC2@%$SHLICC2%g 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%@V_CCOPT@%$V_CCOPT%g s%@V_INCLS@%$V_INCLS%g s%@V_PCAP@%$V_PCAP%g s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g s%@INSTALL_DATA@%$INSTALL_DATA%g CEOF EOF cat >> $CONFIG_STATUS <<\EOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. ac_file=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_cmds # Line after last line for current file. ac_more_lines=: ac_sed_cmds="" while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file else sed "${ac_end}q" conftest.subs > conftest.s$ac_file fi if test ! -s conftest.s$ac_file; then ac_more_lines=false rm -f conftest.s$ac_file else if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f conftest.s$ac_file" else ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" fi ac_file=`expr $ac_file + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_cmds` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; 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 # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. # 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" ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" # A "../" for each directory in $ac_dir_suffix. ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` else ac_dir_suffix= ac_dots= fi case "$ac_given_srcdir" in .) srcdir=. if test -z "$ac_dots"; then top_srcdir=. else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; *) # Relative path. srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" top_srcdir="$ac_dots$ac_given_srcdir" ;; esac case "$ac_given_INSTALL" in [/$]*) INSTALL="$ac_given_INSTALL" ;; *) INSTALL="$ac_dots$ac_given_INSTALL" ;; esac echo creating "$ac_file" rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g s%@INSTALL@%$INSTALL%g " $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file fi; done rm -f conftest.s* EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF exit 0 EOF chmod +x $CONFIG_STATUS rm -fr confdefs* $ac_clean_files test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 if test -f .devel ; then make depend fi exit 0 libpcap-0.5/./configure.in100644 263 461 10372 7007334070 14155 0ustar mcrtcpdumpdnl @(#) $Header: /tcpdump/master/libpcap/configure.in,v 1.71 1999/11/01 15:56:40 itojun Exp $ (LBL) dnl dnl Copyright (c) 1994, 1995, 1996, 1997 dnl The Regents of the University of California. All rights reserved. dnl dnl Process this file with autoconf to produce a configure script. dnl 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_CHECK_HEADERS(malloc.h sys/ioccom.h sys/sockio.h) AC_LBL_FIXINCLUDES AC_CHECK_FUNCS(ether_hostton strerror) dnl to pacify those who hate protochain insn AC_MSG_CHECKING(if --disable-protochain option is specified) AC_ARG_ENABLE(protochain, [ --disable-protochain disable \"protochain\" insn]) case "x$enable_protochain" in xyes) enable_protochain=enabled ;; xno) enable_protochain=disabled ;; x) enable_protochain=enabled ;; esac if test "$enable_protochain" = "disabled"; then AC_DEFINE(NO_PROTOCHAIN) fi AC_MSG_RESULT(${enable_protochain}) dnl dnl Not all versions of test support -c (character special) but it's a 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 AC_ARG_WITH(pcap, [ --with-pcap=TYPE use packet capture TYPE]) AC_MSG_CHECKING(packet capture type) if test ! -z "$with_pcap" ; then V_PCAP="$withval" elif test -r /dev/bpf0 ; then V_PCAP=bpf elif test -r /usr/include/net/pfilt.h ; then V_PCAP=pf elif test -r /dev/enet ; then V_PCAP=enet elif test -r /dev/nit ; then V_PCAP=snit elif test -r /usr/include/sys/net/nit.h ; then V_PCAP=nit elif test -r /usr/include/net/raw.h ; then V_PCAP=snoop elif test -r /usr/include/sys/dlpi.h ; then V_PCAP=dlpi elif test -r /usr/include/linux/socket.h ; then V_PCAP=linux elif test -c /dev/bpf0 ; then # check again in case not readable V_PCAP=bpf elif test -c /dev/enet ; then # check again in case not readable V_PCAP=enet elif test -c /dev/nit ; then # check again in case not readable V_PCAP=snit else V_PCAP=null fi 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) fi AC_MSG_RESULT(${enable_ipv6-no}) case "$V_PCAP" in dlpi) AC_CHECK_HEADERS(sys/bufmod.h sys/dlpi_ext.h) AC_MSG_CHECKING(for /dev/dlpi device) if test -c /dev/dlpi ; then AC_MSG_RESULT(yes) AC_DEFINE(HAVE_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") else AC_MSG_RESULT(no) fi fi ;; linux) AC_CHECK_HEADERS(net/if_arp.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'`) AC_MSG_RESULT($ac_cv_linux_vers) 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 ;; null) AC_MSG_WARN(cannot determine packet capture interface) AC_MSG_WARN((see the INSTALL doc for more info)) ;; esac AC_LBL_LEX_AND_YACC(V_LEX, V_YACC, pcap_) case "$target_os" in aix*) dnl Workaround to enable certain features AC_DEFINE(_SUN) ;; hpux9*) AC_DEFINE(HAVE_HPUX9) ;; hpux10.0*) ;; hpux10.1*) ;; hpux*) dnl HPUX 10.20 and above is similar to HPUX 9... AC_DEFINE(HAVE_HPUX10_20) ;; sinix*) AC_MSG_CHECKING(if SINIX compiler defines sinix) AC_CACHE_VAL(ac_cv_cc_sinix_defined, AC_TRY_COMPILE( [], [int i = sinix;], ac_cv_cc_sinix_defined=yes, 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) fi ;; solaris*) AC_DEFINE(HAVE_SOLARIS) ;; linux*) V_INCLS="$V_INCLS -Ilinux-include" ;; esac AC_CHECK_PROGS(V_RANLIB, ranlib, @true) AC_LBL_DEVEL(V_CCOPT) AC_LBL_SOCKADDR_SA_LEN AC_LBL_UNALIGNED_ACCESS 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 AC_SUBST(V_CCOPT) AC_SUBST(V_INCLS) AC_SUBST(V_LEX) AC_SUBST(V_PCAP) AC_SUBST(V_RANLIB) AC_SUBST(V_YACC) AC_PROG_INSTALL AC_OUTPUT(Makefile) if test -f .devel ; then make depend fi exit 0 libpcap-0.5/./etherent.c100644 263 461 6373 6777230340 13624 0ustar mcrtcpdump/* * Copyright (c) 1990, 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/etherent.c,v 1.20.1.1 1999/10/07 23:46:40 mcr Exp $ (LBL)"; #endif #include #include #include #include #include #include "pcap-int.h" #include #include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif static inline int xdtoi(int); static inline int skip_space(FILE *); static inline int skip_line(FILE *); /* Hex digit to integer. */ static inline int xdtoi(c) register int c; { if (isdigit(c)) return c - '0'; else if (islower(c)) return c - 'a' + 10; else return c - 'A' + 10; } static inline int skip_space(f) FILE *f; { int c; do { c = getc(f); } while (isspace(c) && c != '\n'); return c; } static inline int skip_line(f) FILE *f; { int c; do c = getc(f); while (c != '\n' && c != EOF); return c; } struct pcap_etherent * pcap_next_etherent(FILE *fp) { register int c, d, i; char *bp; static struct pcap_etherent e; memset((char *)&e, 0, sizeof(e)); do { /* Find addr */ c = skip_space(fp); if (c == '\n') continue; /* If this is a comment, or first thing on line cannot be etehrnet address, skip the line. */ if (!isxdigit(c)) { c = skip_line(fp); continue; } /* must be the start of an address */ for (i = 0; i < 6; i += 1) { d = xdtoi(c); c = getc(fp); if (isxdigit(c)) { d <<= 4; d |= xdtoi(c); c = getc(fp); } e.addr[i] = d; if (c != ':') break; c = getc(fp); } if (c == EOF) break; /* Must be whitespace */ if (!isspace(c)) { c = skip_line(fp); continue; } c = skip_space(fp); /* hit end of line... */ if (c == '\n') continue; if (c == '#') { c = skip_line(fp); continue; } /* pick up name */ bp = e.name; /* Use 'd' to prevent buffer overflow. */ d = sizeof(e.name) - 1; do { *bp++ = c; c = getc(fp); } while (!isspace(c) && c != EOF && --d > 0); *bp = '\0'; /* Eat trailing junk */ if (c != '\n') (void)skip_line(fp); return &e; } while (c != EOF); return (NULL); } libpcap-0.5/./ethertype.h100644 263 461 4612 7126667421 14021 0ustar mcrtcpdump/* * Copyright (c) 1993, 1994, 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. * * @(#) $Header: /tcpdump/master/libpcap/ethertype.h,v 1.7.2.1 2000/06/29 15:45:21 itojun Exp $ (LBL) */ /* Types missing from some systems */ #ifndef ETHERTYPE_NS #define ETHERTYPE_NS 0x0600 #endif #ifndef ETHERTYPE_SPRITE #define ETHERTYPE_SPRITE 0x0500 #endif #ifndef ETHERTYPE_TRAIL #define ETHERTYPE_TRAIL 0x1000 #endif #ifndef ETHERTYPE_MOPDL #define ETHERTYPE_MOPDL 0x6001 #endif #ifndef ETHERTYPE_MOPRC #define ETHERTYPE_MOPRC 0x6002 #endif #ifndef ETHERTYPE_DN #define ETHERTYPE_DN 0x6003 #endif #ifndef ETHERTYPE_LAT #define ETHERTYPE_LAT 0x6004 #endif #ifndef ETHERTYPE_SCA #define ETHERTYPE_SCA 0x6007 #endif #ifndef ETHERTYPE_REVARP #define ETHERTYPE_REVARP 0x8035 #endif #ifndef ETHERTYPE_LANBRIDGE #define ETHERTYPE_LANBRIDGE 0x8038 #endif #ifndef ETHERTYPE_DECDNS #define ETHERTYPE_DECDNS 0x803c #endif #ifndef ETHERTYPE_DECDTS #define ETHERTYPE_DECDTS 0x803e #endif #ifndef ETHERTYPE_VEXP #define ETHERTYPE_VEXP 0x805b #endif #ifndef ETHERTYPE_VPROD #define ETHERTYPE_VPROD 0x805c #endif #ifndef ETHERTYPE_ATALK #define ETHERTYPE_ATALK 0x809b #endif #ifndef ETHERTYPE_AARP #define ETHERTYPE_AARP 0x80f3 #endif #ifndef ETHERTYPE_IPV6 #define ETHERTYPE_IPV6 0x86dd #endif #ifndef ETHERTYPE_LOOPBACK #define ETHERTYPE_LOOPBACK 0x9000 #endif libpcap-0.5/./gencode.c100644 263 461 154023 7057222546 13447 0ustar mcrtcpdump/*#define CHASE_CHAIN*/ /* * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998 * 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/gencode.c,v 1.100.2.1 2000/03/01 14:12:54 itojun Exp $ (LBL)"; #endif #include #include #include #ifdef __NetBSD__ #include #endif #if __STDC__ struct mbuf; struct rtentry; #endif #include #include #include #include #include #include #if __STDC__ #include #else #include #endif #include "pcap-int.h" #include "ethertype.h" #include "gencode.h" #include "ppp.h" #include #ifdef INET6 #include #include #endif /*INET6*/ #include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif #define JMP(c) ((c)|BPF_JMP|BPF_K) /* Locals */ static jmp_buf top_ctx; static pcap_t *bpf_pcap; /* XXX */ #ifdef PCAP_FDDIPAD int pcap_fddipad = PCAP_FDDIPAD; #else int pcap_fddipad; #endif /* VARARGS */ __dead void #if __STDC__ 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); va_end(ap); longjmp(top_ctx, 1); /* NOTREACHED */ } static void init_linktype(int); static int alloc_reg(void); static void free_reg(int); static struct block *root; /* * We divy out chunks of memory rather than call malloc each time so * we don't have to worry about leaking memory. It's probably * not a big deal if all this memory was wasted but it this ever * goes into a library that would probably not be a good idea. */ #define NCHUNKS 16 #define CHUNK0SIZE 1024 struct chunk { u_int n_left; void *m; }; static struct chunk chunks[NCHUNKS]; static int cur_chunk; static void *newchunk(u_int); static void freechunks(void); static inline struct block *new_block(int); static inline struct slist *new_stmt(int); static struct block *gen_retblk(int); 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_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_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_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 static struct block *gen_gateway(const u_char *, bpf_u_int32 **, int, int); static struct block *gen_ipfrag(void); static struct block *gen_portatom(int, bpf_int32); #ifdef INET6 static struct block *gen_portatom6(int, bpf_int32); #endif struct block *gen_portop(int, int, int); static struct block *gen_port(int, int, int); #ifdef INET6 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_proto(int, int, int); static struct slist *xfer_to_x(struct arth *); static struct slist *xfer_to_a(struct arth *); static struct block *gen_len(int, int); static void * newchunk(n) u_int n; { struct chunk *cp; int k, size; #ifndef __NetBSD__ /* XXX Round up to nearest long. */ n = (n + sizeof(long) - 1) & ~(sizeof(long) - 1); #else /* XXX Round up to structure boundary. */ n = ALIGN(n); #endif cp = &chunks[cur_chunk]; if (n > cp->n_left) { ++cp, k = ++cur_chunk; if (k >= NCHUNKS) bpf_error("out of memory"); size = CHUNK0SIZE << k; cp->m = (void *)malloc(size); memset((char *)cp->m, 0, size); cp->n_left = size; if (n > size) bpf_error("out of memory"); } cp->n_left -= n; return (void *)((char *)cp->m + cp->n_left); } static void freechunks() { int i; cur_chunk = 0; for (i = 0; i < NCHUNKS; ++i) if (chunks[i].m != NULL) { free(chunks[i].m); chunks[i].m = NULL; } } /* * A strdup whose allocations are freed after code generation is over. */ char * sdup(s) register const char *s; { int n = strlen(s) + 1; char *cp = newchunk(n); strcpy(cp, s); return (cp); } static inline struct block * new_block(code) int code; { struct block *p; p = (struct block *)newchunk(sizeof(*p)); p->s.code = code; p->head = p; return p; } static inline struct slist * new_stmt(code) int code; { struct slist *p; p = (struct slist *)newchunk(sizeof(*p)); p->s.code = code; return p; } static struct block * gen_retblk(v) int v; { struct block *b = new_block(BPF_RET|BPF_K); b->s.k = v; return b; } static inline void syntax() { bpf_error("syntax error in filter expression"); } static bpf_u_int32 netmask; static int snaplen; int no_optimize; int pcap_compile(pcap_t *p, struct bpf_program *program, char *buf, int optimize, bpf_u_int32 mask) { extern int n_errors; int len; no_optimize = 0; n_errors = 0; root = NULL; bpf_pcap = p; if (setjmp(top_ctx)) { freechunks(); return (-1); } netmask = mask; snaplen = pcap_snapshot(p); lex_init(buf ? buf : ""); init_linktype(pcap_datalink(p)); (void)pcap_parse(); if (n_errors) syntax(); if (root == NULL) root = gen_retblk(snaplen); if (optimize && !no_optimize) { bpf_optimize(&root); if (root == NULL || (root->s.code == (BPF_RET|BPF_K) && root->s.k == 0)) bpf_error("expression rejects all packets"); } program->bf_insns = icode_to_fcode(root, &len); program->bf_len = len; freechunks(); return (0); } /* * entry point for using the compiler with no pcap open * pass in all the stuff that is needed explicitly instead. */ int 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; n_errors = 0; root = NULL; bpf_pcap = NULL; if (setjmp(top_ctx)) { freechunks(); 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); 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"); } program->bf_insns = icode_to_fcode(root, &len); program->bf_len = len; freechunks(); return (0); } /* * Backpatch the blocks in 'list' to 'target'. The 'sense' field indicates * which of the jt and jf fields has been resolved and which is a pointer * back to another unresolved block (or nil). At least one of the fields * in each block is already resolved. */ static void backpatch(list, target) struct block *list, *target; { struct block *next; while (list) { if (!list->sense) { next = JT(list); JT(list) = target; } else { next = JF(list); JF(list) = target; } list = next; } } /* * Merge the lists in b0 and b1, using the 'sense' field to indicate * which of jt and jf is the link. */ static void merge(b0, b1) struct block *b0, *b1; { register struct block **p = &b0; /* Find end of list. */ while (*p) p = !((*p)->sense) ? &JT(*p) : &JF(*p); /* Concatenate the lists. */ *p = b1; } void finish_parse(p) struct block *p; { backpatch(p, gen_retblk(snaplen)); p->sense = !p->sense; backpatch(p, gen_retblk(0)); root = p->head; } void gen_and(b0, b1) struct block *b0, *b1; { backpatch(b0, b1->head); b0->sense = !b0->sense; b1->sense = !b1->sense; merge(b1, b0); b1->sense = !b1->sense; b1->head = b0->head; } void gen_or(b0, b1) struct block *b0, *b1; { b0->sense = !b0->sense; backpatch(b0, b1->head); b0->sense = !b0->sense; merge(b1, b0); b1->head = b0->head; } void gen_not(b) struct block *b; { b->sense = !b->sense; } static struct block * gen_cmp(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_JEQ)); 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; bpf_u_int32 mask; { struct block *b = gen_cmp(offset, size, v); struct slist *s; if (mask != 0xffffffff) { s = new_stmt(BPF_ALU|BPF_AND|BPF_K); s->s.k = mask; b->stmts->next = s; } return b; } static struct block * gen_bcmp(offset, size, v) register u_int offset, size; register const u_char *v; { register struct block *b, *tmp; b = NULL; while (size >= 4) { register const u_char *p = &v[size - 4]; bpf_int32 w = ((bpf_int32)p[0] << 24) | ((bpf_int32)p[1] << 16) | ((bpf_int32)p[2] << 8) | p[3]; tmp = gen_cmp(offset + size - 4, BPF_W, w); if (b != NULL) gen_and(b, tmp); b = tmp; size -= 4; } while (size >= 2) { register const u_char *p = &v[size - 2]; bpf_int32 w = ((bpf_int32)p[0] << 8) | p[1]; tmp = gen_cmp(offset + size - 2, BPF_H, w); if (b != NULL) gen_and(b, tmp); b = tmp; size -= 2; } if (size > 0) { tmp = gen_cmp(offset, BPF_B, (bpf_int32)v[0]); if (b != NULL) gen_and(b, tmp); b = tmp; } return b; } /* * Various code constructs need to know the layout of the data link * layer. These variables give the necessary offsets. off_linktype * is set to -1 for no encapsulation, in which case, IP is assumed. */ static u_int off_linktype; static u_int off_nl; static int linktype; static void init_linktype(type) int type; { linktype = type; switch (type) { case DLT_EN10MB: off_linktype = 12; off_nl = 14; return; case DLT_SLIP: /* * SLIP doesn't have a link level type. The 16 byte * header is hacked into our SLIP driver. */ off_linktype = -1; off_nl = 16; return; case DLT_SLIP_BSDOS: /* XXX this may be the same as the DLT_PPP_BSDOS case */ off_linktype = -1; /* XXX end */ off_nl = 24; return; case DLT_NULL: off_linktype = 0; off_nl = 4; return; case DLT_PPP: case DLT_CHDLC: off_linktype = 2; off_nl = 4; return; case DLT_PPP_BSDOS: off_linktype = 5; off_nl = 24; return; case DLT_FDDI: /* * 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. */ off_linktype = 19; #ifdef PCAP_FDDIPAD off_linktype += pcap_fddipad; #endif off_nl = 21; #ifdef PCAP_FDDIPAD off_nl += pcap_fddipad; #endif return; case DLT_IEEE802: off_linktype = 20; off_nl = 22; return; case DLT_ATM_RFC1483: /* * assume routed, non-ISO PDUs * (i.e., LLC = 0xAA-AA-03, OUT = 0x00-00-00) */ off_linktype = 6; off_nl = 8; return; case DLT_RAW: off_linktype = -1; off_nl = 0; return; } bpf_error("unknown data link type 0x%x", linktype); /* NOTREACHED */ } static struct block * gen_uncond(rsense) int rsense; { struct block *b; struct slist *s; s = new_stmt(BPF_LD|BPF_IMM); s->s.k = !rsense; b = new_block(JMP(BPF_JEQ)); b->stmts = s; return b; } static inline struct block * gen_true() { return gen_uncond(1); } static inline struct block * gen_false() { return gen_uncond(0); } 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) return gen_true(); switch (linktype) { case DLT_SLIP: return gen_false(); case DLT_PPP: if (proto == ETHERTYPE_IP) proto = PPP_IP; /* XXX was 0x21 */ #ifdef INET6 else if (proto == ETHERTYPE_IPV6) proto = PPP_IPV6; #endif break; case DLT_PPP_BSDOS: switch (proto) { case ETHERTYPE_IP: b0 = gen_cmp(off_linktype, BPF_H, PPP_IP); b1 = gen_cmp(off_linktype, BPF_H, PPP_VJC); gen_or(b0, b1); b0 = gen_cmp(off_linktype, BPF_H, PPP_VJNC); gen_or(b1, b0); return b0; #ifdef INET6 case ETHERTYPE_IPV6: proto = PPP_IPV6; /* more to go? */ break; #endif case ETHERTYPE_DN: proto = PPP_DECNET; break; case ETHERTYPE_ATALK: proto = PPP_APPLE; break; case ETHERTYPE_NS: proto = PPP_NS; break; } break; case DLT_NULL: /* XXX */ if (proto == ETHERTYPE_IP) return (gen_cmp(0, BPF_W, (bpf_int32)htonl(AF_INET))); #ifdef INET6 else if (proto == ETHERTYPE_IPV6) return (gen_cmp(0, BPF_W, (bpf_int32)htonl(AF_INET6))); #endif else return gen_false(); } return gen_cmp(off_linktype, BPF_H, (bpf_int32)proto); } static struct block * gen_hostop(addr, mask, dir, proto, src_off, dst_off) bpf_u_int32 addr; bpf_u_int32 mask; int dir, proto; u_int src_off, dst_off; { struct block *b0, *b1; u_int offset; switch (dir) { case Q_SRC: offset = src_off; break; case Q_DST: offset = dst_off; break; case Q_AND: b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off); b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off); gen_and(b0, b1); return b1; case Q_OR: case Q_DEFAULT: b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off); b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off); gen_or(b0, b1); return b1; default: abort(); } b0 = gen_linktype(proto); b1 = gen_mcmp(offset, BPF_W, (bpf_int32)addr, mask); gen_and(b0, b1); return b1; } #ifdef INET6 static struct block * gen_hostop6(addr, mask, dir, proto, src_off, dst_off) struct in6_addr *addr; struct in6_addr *mask; int dir, proto; u_int src_off, dst_off; { struct block *b0, *b1; u_int offset; u_int32_t *a, *m; switch (dir) { case Q_SRC: offset = src_off; break; case Q_DST: offset = dst_off; break; case Q_AND: b0 = gen_hostop6(addr, mask, Q_SRC, proto, src_off, dst_off); b1 = gen_hostop6(addr, mask, Q_DST, proto, src_off, dst_off); gen_and(b0, b1); return b1; case Q_OR: case Q_DEFAULT: b0 = gen_hostop6(addr, mask, Q_SRC, proto, src_off, dst_off); b1 = gen_hostop6(addr, mask, Q_DST, proto, src_off, dst_off); gen_or(b0, b1); return b1; default: abort(); } /* this order is important */ a = (u_int32_t *)addr; m = (u_int32_t *)mask; b1 = gen_mcmp(offset + 12, BPF_W, ntohl(a[3]), ntohl(m[3])); b0 = gen_mcmp(offset + 8, BPF_W, ntohl(a[2]), ntohl(m[2])); gen_and(b0, b1); b0 = gen_mcmp(offset + 4, BPF_W, ntohl(a[1]), ntohl(m[1])); gen_and(b0, b1); b0 = gen_mcmp(offset + 0, BPF_W, ntohl(a[0]), ntohl(m[0])); gen_and(b0, b1); b0 = gen_linktype(proto); gen_and(b0, b1); return b1; } #endif /*INET6*/ static struct block * gen_ehostop(eaddr, dir) register const u_char *eaddr; register int dir; { register struct block *b0, *b1; switch (dir) { case Q_SRC: return gen_bcmp(6, 6, eaddr); case Q_DST: return gen_bcmp(0, 6, eaddr); case Q_AND: b0 = gen_ehostop(eaddr, Q_SRC); b1 = gen_ehostop(eaddr, Q_DST); gen_and(b0, b1); return b1; case Q_DEFAULT: case Q_OR: b0 = gen_ehostop(eaddr, Q_SRC); b1 = gen_ehostop(eaddr, Q_DST); gen_or(b0, b1); return b1; } abort(); /* NOTREACHED */ } /* * Like gen_ehostop, but for DLT_FDDI */ static struct block * gen_fhostop(eaddr, dir) register const u_char *eaddr; register int dir; { struct block *b0, *b1; switch (dir) { case Q_SRC: #ifdef PCAP_FDDIPAD return gen_bcmp(6 + 1 + pcap_fddipad, 6, eaddr); #else return gen_bcmp(6 + 1, 6, eaddr); #endif case Q_DST: #ifdef PCAP_FDDIPAD return gen_bcmp(0 + 1 + pcap_fddipad, 6, eaddr); #else return gen_bcmp(0 + 1, 6, eaddr); #endif case Q_AND: b0 = gen_fhostop(eaddr, Q_SRC); b1 = gen_fhostop(eaddr, Q_DST); gen_and(b0, b1); return b1; case Q_DEFAULT: case Q_OR: b0 = gen_fhostop(eaddr, Q_SRC); b1 = gen_fhostop(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 * carries only the src node, plus 2 types that use a different format and * also carry just the src node. * * Yuck. * * Instead of doing those all right, we just look for data packets with * 0 or 1 bytes of padding. If you want to look at other packets, that * will require a lot more hacking. * * To add support for filtering on DECNET "areas" (network numbers) * one would want to add a "mask" argument to this routine. That would * make the filter even more inefficient, although one could be clever * and not generate masking instructions if the mask is 0xFFFF. */ static struct block * gen_dnhostop(addr, dir, base_off) bpf_u_int32 addr; int dir; u_int base_off; { struct block *b0, *b1, *b2, *tmp; u_int offset_lh; /* offset if long header is received */ u_int offset_sh; /* offset if short header is received */ switch (dir) { case Q_DST: offset_sh = 1; /* follows flags */ offset_lh = 7; /* flgs,darea,dsubarea,HIORD */ break; case Q_SRC: offset_sh = 3; /* follows flags, dstnode */ offset_lh = 15; /* flgs,darea,dsubarea,did,sarea,ssub,HIORD */ break; case Q_AND: /* Inefficient because we do our Calvinball dance twice */ b0 = gen_dnhostop(addr, Q_SRC, base_off); b1 = gen_dnhostop(addr, Q_DST, base_off); gen_and(b0, b1); return b1; case Q_OR: case Q_DEFAULT: /* Inefficient because we do our Calvinball dance twice */ b0 = gen_dnhostop(addr, Q_SRC, base_off); b1 = gen_dnhostop(addr, Q_DST, base_off); gen_or(b0, b1); return b1; default: abort(); } b0 = gen_linktype(ETHERTYPE_DN); /* Check for pad = 1, long header case */ tmp = gen_mcmp(base_off + 2, BPF_H, (bpf_int32)ntohs(0x0681), (bpf_int32)ntohs(0x07FF)); b1 = gen_cmp(base_off + 2 + 1 + offset_lh, BPF_H, (bpf_int32)ntohs(addr)); gen_and(tmp, b1); /* Check for pad = 0, long header case */ tmp = gen_mcmp(base_off + 2, BPF_B, (bpf_int32)0x06, (bpf_int32)0x7); b2 = gen_cmp(base_off + 2 + offset_lh, BPF_H, (bpf_int32)ntohs(addr)); gen_and(tmp, b2); gen_or(b2, b1); /* Check for pad = 1, short header case */ tmp = gen_mcmp(base_off + 2, BPF_H, (bpf_int32)ntohs(0x0281), (bpf_int32)ntohs(0x07FF)); b2 = gen_cmp(base_off + 2 + 1 + offset_sh, BPF_H, (bpf_int32)ntohs(addr)); gen_and(tmp, b2); gen_or(b2, b1); /* Check for pad = 0, short header case */ tmp = gen_mcmp(base_off + 2, BPF_B, (bpf_int32)0x02, (bpf_int32)0x7); b2 = gen_cmp(base_off + 2 + offset_sh, BPF_H, (bpf_int32)ntohs(addr)); gen_and(tmp, b2); gen_or(b2, b1); /* Combine with test for linktype */ gen_and(b0, b1); return b1; } static struct block * gen_host(addr, mask, proto, dir) bpf_u_int32 addr; bpf_u_int32 mask; int proto; int dir; { struct block *b0, *b1; switch (proto) { 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); return b0; case Q_IP: return gen_hostop(addr, mask, dir, ETHERTYPE_IP, off_nl + 12, off_nl + 16); case Q_RARP: return gen_hostop(addr, mask, dir, ETHERTYPE_REVARP, off_nl + 14, off_nl + 24); case Q_ARP: return gen_hostop(addr, mask, dir, ETHERTYPE_ARP, off_nl + 14, off_nl + 24); case Q_TCP: bpf_error("'tcp' modifier applied to host"); case Q_UDP: bpf_error("'udp' modifier applied to host"); case Q_ICMP: bpf_error("'icmp' modifier applied to host"); case Q_IGMP: bpf_error("'igmp' modifier applied to host"); case Q_IGRP: bpf_error("'igrp' modifier applied to host"); case Q_PIM: bpf_error("'pim' modifier applied to host"); case Q_ATALK: bpf_error("ATALK host filtering not implemented"); case Q_DECNET: return gen_dnhostop(addr, dir, off_nl); case Q_SCA: bpf_error("SCA host filtering not implemented"); case Q_LAT: bpf_error("LAT host filtering not implemented"); case Q_MOPDL: bpf_error("MOPDL host filtering not implemented"); case Q_MOPRC: bpf_error("MOPRC host filtering not implemented"); #ifdef INET6 case Q_IPV6: bpf_error("'ip6' modifier applied to ip host"); case Q_ICMPV6: bpf_error("'icmp6' modifier applied to host"); #endif /* INET6 */ case Q_AH: bpf_error("'ah' modifier applied to host"); case Q_ESP: bpf_error("'esp' modifier applied to host"); default: abort(); } /* NOTREACHED */ } #ifdef INET6 static struct block * gen_host6(addr, mask, proto, dir) struct in6_addr *addr; struct in6_addr *mask; int proto; int dir; { struct block *b0, *b1; switch (proto) { case Q_DEFAULT: return gen_host6(addr, mask, Q_IPV6, dir); case Q_IP: bpf_error("'ip' modifier applied to ip6 host"); case Q_RARP: bpf_error("'rarp' modifier applied to ip6 host"); case Q_ARP: bpf_error("'arp' modifier applied to ip6 host"); case Q_TCP: bpf_error("'tcp' modifier applied to host"); case Q_UDP: bpf_error("'udp' modifier applied to host"); case Q_ICMP: bpf_error("'icmp' modifier applied to host"); case Q_IGMP: bpf_error("'igmp' modifier applied to host"); case Q_IGRP: bpf_error("'igrp' modifier applied to host"); case Q_PIM: bpf_error("'pim' modifier applied to host"); case Q_ATALK: bpf_error("ATALK host filtering not implemented"); case Q_DECNET: bpf_error("'decnet' modifier applied to ip6 host"); case Q_SCA: bpf_error("SCA host filtering not implemented"); case Q_LAT: bpf_error("LAT host filtering not implemented"); case Q_MOPDL: bpf_error("MOPDL host filtering not implemented"); case Q_MOPRC: bpf_error("MOPRC host filtering not implemented"); case Q_IPV6: return gen_hostop6(addr, mask, dir, ETHERTYPE_IPV6, off_nl + 8, off_nl + 24); case Q_ICMPV6: bpf_error("'icmp6' modifier applied to host"); case Q_AH: bpf_error("'ah' modifier applied to host"); case Q_ESP: bpf_error("'esp' modifier applied to host"); default: abort(); } /* NOTREACHED */ } #endif /*INET6*/ static struct block * gen_gateway(eaddr, alist, proto, dir) const u_char *eaddr; bpf_u_int32 **alist; int proto; int dir; { struct block *b0, *b1, *tmp; if (dir != 0) bpf_error("direction applied to 'gateway'"); switch (proto) { case Q_DEFAULT: case Q_IP: case Q_ARP: case Q_RARP: if (linktype == DLT_EN10MB) b0 = gen_ehostop(eaddr, Q_OR); else if (linktype == DLT_FDDI) b0 = gen_fhostop(eaddr, Q_OR); else bpf_error( "'gateway' supported only on ethernet or FDDI"); b1 = gen_host(**alist++, 0xffffffff, proto, Q_OR); while (*alist) { tmp = gen_host(**alist++, 0xffffffff, proto, Q_OR); gen_or(b1, tmp); b1 = tmp; } gen_not(b1); gen_and(b0, b1); return b1; } bpf_error("illegal modifier of 'gateway'"); /* NOTREACHED */ } struct block * gen_proto_abbrev(proto) int proto; { struct block *b0, *b1; switch (proto) { case Q_TCP: b1 = gen_proto(IPPROTO_TCP, Q_IP, Q_DEFAULT); #ifdef INET6 b0 = gen_proto(IPPROTO_TCP, Q_IPV6, Q_DEFAULT); gen_or(b0, b1); #endif break; case Q_UDP: b1 = gen_proto(IPPROTO_UDP, Q_IP, Q_DEFAULT); #ifdef INET6 b0 = gen_proto(IPPROTO_UDP, Q_IPV6, Q_DEFAULT); gen_or(b0, b1); #endif break; case Q_ICMP: b1 = gen_proto(IPPROTO_ICMP, Q_IP, Q_DEFAULT); break; case Q_IGMP: b1 = gen_proto(2, Q_IP, Q_DEFAULT); break; #ifndef IPPROTO_IGRP #define IPPROTO_IGRP 9 #endif case Q_IGRP: b1 = gen_proto(IPPROTO_IGRP, Q_IP, Q_DEFAULT); gen_and(b0, b1); break; #ifndef IPPROTO_PIM #define IPPROTO_PIM 103 #endif case Q_PIM: b1 = gen_proto(IPPROTO_PIM, Q_IP, Q_DEFAULT); #ifdef INET6 b0 = gen_proto(IPPROTO_PIM, Q_IPV6, Q_DEFAULT); gen_or(b0, b1); #endif break; case Q_IP: b1 = gen_linktype(ETHERTYPE_IP); break; case Q_ARP: b1 = gen_linktype(ETHERTYPE_ARP); break; case Q_RARP: b1 = gen_linktype(ETHERTYPE_REVARP); break; case Q_LINK: bpf_error("link layer applied in wrong context"); case Q_ATALK: b1 = gen_linktype(ETHERTYPE_ATALK); break; case Q_DECNET: b1 = gen_linktype(ETHERTYPE_DN); break; case Q_SCA: b1 = gen_linktype(ETHERTYPE_SCA); break; case Q_LAT: b1 = gen_linktype(ETHERTYPE_LAT); break; case Q_MOPDL: b1 = gen_linktype(ETHERTYPE_MOPDL); break; case Q_MOPRC: b1 = gen_linktype(ETHERTYPE_MOPRC); break; #ifdef INET6 case Q_IPV6: b1 = gen_linktype(ETHERTYPE_IPV6); break; #ifndef IPPROTO_ICMPV6 #define IPPROTO_ICMPV6 58 #endif case Q_ICMPV6: b1 = gen_proto(IPPROTO_ICMPV6, Q_IPV6, Q_DEFAULT); break; #endif /* INET6 */ #ifndef IPPROTO_AH #define IPPROTO_AH 51 #endif case Q_AH: b1 = gen_proto(IPPROTO_AH, Q_IP, Q_DEFAULT); #ifdef INET6 b0 = gen_proto(IPPROTO_AH, Q_IPV6, Q_DEFAULT); gen_or(b0, b1); #endif break; #ifndef IPPROTO_ESP #define IPPROTO_ESP 50 #endif case Q_ESP: b1 = gen_proto(IPPROTO_ESP, Q_IP, Q_DEFAULT); #ifdef INET6 b0 = gen_proto(IPPROTO_ESP, Q_IPV6, Q_DEFAULT); gen_or(b0, b1); #endif break; default: abort(); } return b1; } static struct block * gen_ipfrag() { struct slist *s; struct block *b; /* not ip frag */ s = new_stmt(BPF_LD|BPF_H|BPF_ABS); s->s.k = off_nl + 6; b = new_block(JMP(BPF_JSET)); b->s.k = 0x1fff; b->stmts = s; gen_not(b); return b; } static struct block * gen_portatom(off, v) int off; bpf_int32 v; { struct slist *s; struct block *b; s = new_stmt(BPF_LDX|BPF_MSH|BPF_B); s->s.k = off_nl; s->next = new_stmt(BPF_LD|BPF_IND|BPF_H); s->next->s.k = off_nl + off; b = new_block(JMP(BPF_JEQ)); b->stmts = s; b->s.k = v; return b; } #ifdef INET6 static struct block * gen_portatom6(off, v) int off; bpf_int32 v; { return gen_cmp(off_nl + 40 + off, BPF_H, v); } #endif/*INET6*/ struct block * gen_portop(port, proto, dir) int port, proto, dir; { struct block *b0, *b1, *tmp; /* ip proto 'proto' */ tmp = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)proto); b0 = gen_ipfrag(); gen_and(tmp, b0); switch (dir) { case Q_SRC: b1 = gen_portatom(0, (bpf_int32)port); break; case Q_DST: b1 = gen_portatom(2, (bpf_int32)port); break; case Q_OR: case Q_DEFAULT: tmp = gen_portatom(0, (bpf_int32)port); b1 = gen_portatom(2, (bpf_int32)port); gen_or(tmp, b1); break; case Q_AND: tmp = gen_portatom(0, (bpf_int32)port); b1 = gen_portatom(2, (bpf_int32)port); gen_and(tmp, b1); break; default: abort(); } gen_and(b0, b1); return b1; } static struct block * gen_port(port, ip_proto, dir) int port; int ip_proto; int dir; { struct block *b0, *b1, *tmp; /* ether proto ip */ b0 = gen_linktype(ETHERTYPE_IP); switch (ip_proto) { case IPPROTO_UDP: case IPPROTO_TCP: b1 = gen_portop(port, ip_proto, dir); break; case PROTO_UNDEF: tmp = gen_portop(port, IPPROTO_TCP, dir); b1 = gen_portop(port, IPPROTO_UDP, dir); gen_or(tmp, b1); break; default: abort(); } gen_and(b0, b1); return b1; } #ifdef INET6 struct block * gen_portop6(port, proto, dir) int port, proto, dir; { struct block *b0, *b1, *tmp; /* ip proto 'proto' */ b0 = gen_cmp(off_nl + 6, BPF_B, (bpf_int32)proto); switch (dir) { case Q_SRC: b1 = gen_portatom6(0, (bpf_int32)port); break; case Q_DST: b1 = gen_portatom6(2, (bpf_int32)port); break; case Q_OR: case Q_DEFAULT: tmp = gen_portatom6(0, (bpf_int32)port); b1 = gen_portatom6(2, (bpf_int32)port); gen_or(tmp, b1); break; case Q_AND: tmp = gen_portatom6(0, (bpf_int32)port); b1 = gen_portatom6(2, (bpf_int32)port); gen_and(tmp, b1); break; default: abort(); } gen_and(b0, b1); return b1; } static struct block * gen_port6(port, ip_proto, dir) int port; int ip_proto; int dir; { struct block *b0, *b1, *tmp; /* ether proto ip */ b0 = gen_linktype(ETHERTYPE_IPV6); switch (ip_proto) { case IPPROTO_UDP: case IPPROTO_TCP: b1 = gen_portop6(port, ip_proto, dir); break; case PROTO_UNDEF: tmp = gen_portop6(port, IPPROTO_TCP, dir); b1 = gen_portop6(port, IPPROTO_UDP, dir); gen_or(tmp, b1); break; default: abort(); } gen_and(b0, b1); return b1; } #endif /* INET6 */ static int lookup_proto(name, proto) register const char *name; register int proto; { register int v; switch (proto) { case Q_DEFAULT: case Q_IP: v = pcap_nametoproto(name); if (v == PROTO_UNDEF) bpf_error("unknown ip proto '%s'", name); break; case Q_LINK: /* XXX should look up h/w protocol type based on linktype */ v = pcap_nametoeproto(name); if (v == PROTO_UNDEF) bpf_error("unknown ether proto '%s'", name); break; default: v = PROTO_UNDEF; break; } return v; } struct stmt * gen_joinsp(s, n) struct stmt **s; int n; { } struct block * gen_protochain(v, proto, dir) int v; int proto; int dir; { #ifdef NO_PROTOCHAIN return gen_proto(v, proto, dir); #else struct block *b0, *b; struct slist *s[100], *sp; 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)); fix2 = fix3 = fix4 = fix5 = 0; switch (proto) { case Q_IP: case Q_IPV6: break; case Q_DEFAULT: b0 = gen_protochain(v, Q_IP, dir); b = gen_protochain(v, Q_IPV6, dir); gen_or(b0, b); return b; default: bpf_error("bad protocol applied for 'protochain'"); /*NOTREACHED*/ } no_optimize = 1; /*this code is not compatible with optimzer yet */ /* * s[0] is a dummy entry to protect other BPF insn from damaged * by s[fix] = foo with uninitialized variable "fix". It is somewhat * hard to find interdependency made by jump table fixup. */ i = 0; s[i] = new_stmt(0); /*dummy*/ i++; switch (proto) { case Q_IP: b0 = gen_linktype(ETHERTYPE_IP); /* A = ip->ip_p */ s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B); s[i]->s.k = off_nl + 9; i++; /* X = ip->ip_hl << 2 */ s[i] = new_stmt(BPF_LDX|BPF_MSH|BPF_B); s[i]->s.k = off_nl; i++; break; #ifdef INET6 case Q_IPV6: b0 = gen_linktype(ETHERTYPE_IPV6); /* A = ip6->ip_nxt */ s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B); s[i]->s.k = off_nl + 6; i++; /* X = sizeof(struct ip6_hdr) */ s[i] = new_stmt(BPF_LDX|BPF_IMM); s[i]->s.k = 40; i++; break; #endif default: bpf_error("unsupported proto to gen_protochain"); /*NOTREACHED*/ } /* again: if (A == v) goto end; else fall through; */ again = i; s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); s[i]->s.k = v; s[i]->s.jt = NULL; /*later*/ s[i]->s.jf = NULL; /*update in next stmt*/ fix5 = i; i++; #ifndef IPPROTO_NONE #define IPPROTO_NONE 59 #endif /* if (A == IPPROTO_NONE) goto end */ s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); s[i]->s.jt = NULL; /*later*/ s[i]->s.jf = NULL; /*update in next stmt*/ s[i]->s.k = IPPROTO_NONE; s[fix5]->s.jf = s[i]; fix2 = i; i++; #ifdef INET6 if (proto == Q_IPV6) { int v6start, v6end, v6advance, j; v6start = i; /* if (A == IPPROTO_HOPOPTS) goto v6advance */ s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); s[i]->s.jt = NULL; /*later*/ s[i]->s.jf = NULL; /*update in next stmt*/ s[i]->s.k = IPPROTO_HOPOPTS; s[fix2]->s.jf = s[i]; i++; /* if (A == IPPROTO_DSTOPTS) goto v6advance */ s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); s[i]->s.jt = NULL; /*later*/ s[i]->s.jf = NULL; /*update in next stmt*/ s[i]->s.k = IPPROTO_DSTOPTS; i++; /* if (A == IPPROTO_ROUTING) goto v6advance */ s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); s[i]->s.jt = NULL; /*later*/ s[i]->s.jf = NULL; /*update in next stmt*/ s[i]->s.k = IPPROTO_ROUTING; i++; /* if (A == IPPROTO_FRAGMENT) goto v6advance; else goto ahcheck; */ s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); s[i]->s.jt = NULL; /*later*/ s[i]->s.jf = NULL; /*later*/ s[i]->s.k = IPPROTO_FRAGMENT; fix3 = i; v6end = i; i++; /* v6advance: */ v6advance = i; /* * in short, * A = P[X + 1]; * X = X + (P[X] + 1) * 8; */ /* A = X */ 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; 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; i++; /* A *= 8 */ s[i] = new_stmt(BPF_ALU|BPF_MUL|BPF_K); s[i]->s.k = 8; i++; /* X = A; */ s[i] = new_stmt(BPF_MISC|BPF_TAX); i++; /* A = MEM[reg2] */ s[i] = new_stmt(BPF_LD|BPF_MEM); s[i]->s.k = reg2; i++; /* goto again; (must use BPF_JA for backward jump) */ s[i] = new_stmt(BPF_JMP|BPF_JA); s[i]->s.k = again - i - 1; s[i - 1]->s.jf = s[i]; i++; /* fixup */ for (j = v6start; j <= v6end; j++) s[j]->s.jt = s[v6advance]; } else #endif { /* nop */ s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); s[i]->s.k = 0; s[fix2]->s.jf = s[i]; i++; } /* ahcheck: */ ahcheck = i; /* if (A == IPPROTO_AH) then fall through; else goto end; */ s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); s[i]->s.jt = NULL; /*later*/ s[i]->s.jf = NULL; /*later*/ s[i]->s.k = IPPROTO_AH; if (fix3) s[fix3]->s.jf = s[ahcheck]; fix4 = i; i++; /* * in short, * A = P[X + 1]; * X = X + (P[X] + 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; 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 += 2 */ s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); s[i]->s.k = 2; i++; /* A *= 4 */ s[i] = new_stmt(BPF_ALU|BPF_MUL|BPF_K); s[i]->s.k = 4; i++; /* X = A; */ s[i] = new_stmt(BPF_MISC|BPF_TAX); i++; /* A = MEM[reg2] */ s[i] = new_stmt(BPF_LD|BPF_MEM); s[i]->s.k = reg2; i++; /* goto again; (must use BPF_JA for backward jump) */ s[i] = new_stmt(BPF_JMP|BPF_JA); s[i]->s.k = again - i - 1; i++; /* end: nop */ end = i; s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); s[i]->s.k = 0; s[fix2]->s.jt = s[end]; s[fix4]->s.jf = s[end]; s[fix5]->s.jt = s[end]; i++; /* * make slist chain */ max = i; for (i = 0; i < max - 1; i++) s[i]->next = s[i + 1]; s[max - 1]->next = NULL; /* * emit final check */ b = new_block(JMP(BPF_JEQ)); b->stmts = s[1]; /*remember, s[0] is dummy*/ b->s.k = v; free_reg(reg1); free_reg(reg2); gen_and(b0, b); return b; #endif } static struct block * gen_proto(v, proto, dir) int v; int proto; int dir; { struct block *b0, *b1; if (dir != Q_DEFAULT) bpf_error("direction applied to 'proto'"); switch (proto) { case Q_DEFAULT: #ifdef INET6 b0 = gen_proto(v, Q_IP, dir); b1 = gen_proto(v, Q_IPV6, dir); gen_or(b0, b1); return b1; #else /*FALLTHROUGH*/ #endif case Q_IP: b0 = gen_linktype(ETHERTYPE_IP); #ifndef CHASE_CHAIN b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)v); #else b1 = gen_protochain(v, Q_IP); #endif gen_and(b0, b1); return b1; case Q_ARP: bpf_error("arp does not encapsulate another protocol"); /* NOTREACHED */ case Q_RARP: bpf_error("rarp does not encapsulate another protocol"); /* NOTREACHED */ case Q_ATALK: bpf_error("atalk encapsulation is not specifiable"); /* NOTREACHED */ case Q_DECNET: bpf_error("decnet encapsulation is not specifiable"); /* NOTREACHED */ case Q_SCA: bpf_error("sca does not encapsulate another protocol"); /* NOTREACHED */ case Q_LAT: bpf_error("lat does not encapsulate another protocol"); /* NOTREACHED */ case Q_MOPRC: bpf_error("moprc does not encapsulate another protocol"); /* NOTREACHED */ case Q_MOPDL: bpf_error("mopdl does not encapsulate another protocol"); /* NOTREACHED */ case Q_LINK: return gen_linktype(v); case Q_UDP: bpf_error("'udp proto' is bogus"); /* NOTREACHED */ case Q_TCP: bpf_error("'tcp proto' is bogus"); /* NOTREACHED */ case Q_ICMP: bpf_error("'icmp proto' is bogus"); /* NOTREACHED */ case Q_IGMP: bpf_error("'igmp proto' is bogus"); /* NOTREACHED */ case Q_IGRP: bpf_error("'igrp proto' is bogus"); /* NOTREACHED */ case Q_PIM: bpf_error("'pim proto' is bogus"); /* NOTREACHED */ #ifdef INET6 case Q_IPV6: b0 = gen_linktype(ETHERTYPE_IPV6); #ifndef CHASE_CHAIN b1 = gen_cmp(off_nl + 6, BPF_B, (bpf_int32)v); #else b1 = gen_protochain(v, Q_IPV6); #endif gen_and(b0, b1); return b1; case Q_ICMPV6: bpf_error("'icmp6 proto' is bogus"); #endif /* INET6 */ case Q_AH: bpf_error("'ah proto' is bogus"); case Q_ESP: bpf_error("'ah proto' is bogus"); default: abort(); /* NOTREACHED */ } /* NOTREACHED */ } struct block * gen_scode(name, q) register const char *name; struct qual q; { int proto = q.proto; int dir = q.dir; int tproto; u_char *eaddr; bpf_u_int32 mask, addr, **alist; #ifdef INET6 int tproto6; struct sockaddr_in *sin; struct sockaddr_in6 *sin6; struct addrinfo *res, *res0; struct in6_addr mask128; #endif /*INET6*/ struct block *b, *tmp; int port, real_proto; switch (q.addr) { case Q_NET: addr = pcap_nametonetaddr(name); if (addr == 0) bpf_error("unknown network '%s'", name); /* Left justify network addr and calculate its network mask */ mask = 0xffffffff; while (addr && (addr & 0xff000000) == 0) { addr <<= 8; mask <<= 8; } return gen_host(addr, mask, proto, dir); case Q_DEFAULT: case Q_HOST: if (proto == Q_LINK) { switch (linktype) { case DLT_EN10MB: eaddr = pcap_ether_hostton(name); if (eaddr == NULL) bpf_error( "unknown ether host '%s'", name); return gen_ehostop(eaddr, dir); case DLT_FDDI: eaddr = pcap_ether_hostton(name); if (eaddr == NULL) bpf_error( "unknown FDDI host '%s'", name); return gen_fhostop(eaddr, dir); default: bpf_error( "only ethernet/FDDI supports link-level host name"); break; } } else if (proto == Q_DECNET) { unsigned short dn_addr = __pcap_nametodnaddr(name); /* * I don't think DECNET hosts can be multihomed, so * there is no need to build up a list of addresses */ return (gen_host(dn_addr, 0, proto, dir)); } else { #ifndef INET6 alist = pcap_nametoaddr(name); if (alist == NULL || *alist == NULL) bpf_error("unknown host '%s'", name); tproto = proto; if (off_linktype == -1 && tproto == Q_DEFAULT) tproto = Q_IP; b = gen_host(**alist++, 0xffffffff, tproto, dir); while (*alist) { tmp = gen_host(**alist++, 0xffffffff, tproto, dir); gen_or(b, tmp); b = tmp; } return b; #else memset(&mask128, 0xff, sizeof(mask128)); res0 = res = pcap_nametoaddr(name); if (res == NULL) bpf_error("unknown host '%s'", name); b = tmp = NULL; tproto = tproto6 = proto; if (off_linktype == -1 && tproto == Q_DEFAULT) { tproto = Q_IP; tproto6 = Q_IPV6; } for (res = res0; res; res = res->ai_next) { switch (res->ai_family) { case AF_INET: if (tproto == Q_IPV6) continue; sin = (struct sockaddr_in *) res->ai_addr; tmp = gen_host(ntohl(sin->sin_addr.s_addr), 0xffffffff, tproto, dir); break; case AF_INET6: if (tproto6 == Q_IP) continue; sin6 = (struct sockaddr_in6 *) res->ai_addr; tmp = gen_host6(&sin6->sin6_addr, &mask128, tproto6, dir); break; } if (b) gen_or(b, tmp); b = tmp; } freeaddrinfo(res0); if (b == NULL) { bpf_error("unknown host '%s'%s", name, (proto == Q_DEFAULT) ? "" : " for specified address family"); } return b; #endif /*INET6*/ } case Q_PORT: if (proto != Q_DEFAULT && proto != Q_UDP && proto != Q_TCP) bpf_error("illegal qualifier of 'port'"); if (pcap_nametoport(name, &port, &real_proto) == 0) bpf_error("unknown port '%s'", name); if (proto == Q_UDP) { if (real_proto == IPPROTO_TCP) bpf_error("port '%s' is tcp", name); else /* override PROTO_UNDEF */ real_proto = IPPROTO_UDP; } if (proto == Q_TCP) { if (real_proto == IPPROTO_UDP) bpf_error("port '%s' is udp", name); else /* override PROTO_UNDEF */ real_proto = IPPROTO_TCP; } #ifndef INET6 return gen_port(port, real_proto, dir); #else { struct block *b; b = gen_port(port, real_proto, dir); gen_or(gen_port6(port, real_proto, dir), b); return b; } #endif /* INET6 */ case Q_GATEWAY: #ifndef INET6 eaddr = pcap_ether_hostton(name); if (eaddr == NULL) bpf_error("unknown ether host: %s", name); alist = pcap_nametoaddr(name); if (alist == NULL || *alist == NULL) bpf_error("unknown host '%s'", name); return gen_gateway(eaddr, alist, proto, dir); #else bpf_error("'gateway' not supported in this configuration"); #endif /*INET6*/ case Q_PROTO: real_proto = lookup_proto(name, proto); if (real_proto >= 0) return gen_proto(real_proto, proto, dir); else bpf_error("unknown protocol: %s", name); case Q_PROTOCHAIN: real_proto = lookup_proto(name, proto); if (real_proto >= 0) return gen_protochain(real_proto, proto, dir); else bpf_error("unknown protocol: %s", name); case Q_UNDEF: syntax(); /* NOTREACHED */ } abort(); /* NOTREACHED */ } struct block * gen_mcode(s1, s2, masklen, q) register const char *s1, *s2; register int masklen; struct qual q; { register int nlen, mlen; bpf_u_int32 n, m; nlen = __pcap_atoin(s1, &n); /* Promote short ipaddr */ n <<= 32 - nlen; if (s2 != NULL) { mlen = __pcap_atoin(s2, &m); /* Promote short ipaddr */ m <<= 32 - mlen; if ((n & ~m) != 0) bpf_error("non-network bits set in \"%s mask %s\"", s1, s2); } else { /* Convert mask len to mask */ if (masklen > 32) bpf_error("mask length must be <= 32"); m = 0xffffffff << (32 - masklen); if ((n & ~m) != 0) bpf_error("non-network bits set in \"%s/%d\"", s1, masklen); } switch (q.addr) { case Q_NET: return gen_host(n, m, q.proto, q.dir); default: bpf_error("Mask syntax for networks only"); /* NOTREACHED */ } } struct block * gen_ncode(s, v, q) register const char *s; bpf_u_int32 v; struct qual q; { bpf_u_int32 mask; int proto = q.proto; int dir = q.dir; register int vlen; if (s == NULL) vlen = 32; else if (q.proto == Q_DECNET) vlen = __pcap_atodn(s, &v); else vlen = __pcap_atoin(s, &v); switch (q.addr) { case Q_DEFAULT: case Q_HOST: case Q_NET: if (proto == Q_DECNET) return gen_host(v, 0, proto, dir); else if (proto == Q_LINK) { bpf_error("illegal link layer address"); } else { mask = 0xffffffff; if (s == NULL && q.addr == Q_NET) { /* Promote short net number */ while (v && (v & 0xff000000) == 0) { v <<= 8; mask <<= 8; } } else { /* Promote short ipaddr */ v <<= 32 - vlen; mask <<= 32 - vlen; } return gen_host(v, mask, proto, dir); } case Q_PORT: if (proto == Q_UDP) proto = IPPROTO_UDP; else if (proto == Q_TCP) proto = IPPROTO_TCP; else if (proto == Q_DEFAULT) proto = PROTO_UNDEF; else bpf_error("illegal qualifier of 'port'"); #ifndef INET6 return gen_port((int)v, proto, dir); #else { struct block *b; b = gen_port((int)v, proto, dir); gen_or(gen_port6((int)v, proto, dir), b); return b; } #endif /* INET6 */ case Q_GATEWAY: bpf_error("'gateway' requires a name"); /* NOTREACHED */ case Q_PROTO: return gen_proto((int)v, proto, dir); case Q_PROTOCHAIN: return gen_protochain((int)v, proto, dir); case Q_UNDEF: syntax(); /* NOTREACHED */ default: abort(); /* NOTREACHED */ } /* NOTREACHED */ } #ifdef INET6 struct block * gen_mcode6(s1, s2, masklen, q) register const char *s1, *s2; register int masklen; struct qual q; { struct addrinfo *res; struct in6_addr *addr; struct in6_addr mask; struct block *b; u_int32_t *a, *m; if (s2) bpf_error("no mask %s supported", s2); res = pcap_nametoaddr(s1); if (!res) bpf_error("invalid ip6 address %s", s1); if (res->ai_next) bpf_error("%s resolved to multiple address", s1); addr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr; if (sizeof(mask) * 8 < masklen) bpf_error("mask length must be <= %u", (unsigned int)(sizeof(mask) * 8)); memset(&mask, 0xff, masklen / 8); if (masklen % 8) { mask.s6_addr[masklen / 8] = (0xff << (8 - masklen % 8)) & 0xff; } a = (u_int32_t *)addr; m = (u_int32_t *)&mask; if ((a[0] & ~m[0]) || (a[1] & ~m[1]) || (a[2] & ~m[2]) || (a[3] & ~m[3])) { bpf_error("non-network bits set in \"%s/%d\"", s1, masklen); } switch (q.addr) { case Q_DEFAULT: case Q_HOST: if (masklen != 128) bpf_error("Mask syntax for networks only"); /* FALLTHROUGH */ case Q_NET: b = gen_host6(addr, &mask, q.proto, q.dir); freeaddrinfo(res); return b; default: bpf_error("invalid qualifier against IPv6 address"); /* NOTREACHED */ } } #endif /*INET6*/ struct block * gen_ecode(eaddr, q) register const u_char *eaddr; struct qual q; { if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) { if (linktype == DLT_EN10MB) return gen_ehostop(eaddr, (int)q.dir); if (linktype == DLT_FDDI) return gen_fhostop(eaddr, (int)q.dir); } bpf_error("ethernet address used in non-ether expression"); /* NOTREACHED */ } void sappend(s0, s1) struct slist *s0, *s1; { /* * This is definitely not the best way to do this, but the * lists will rarely get long. */ while (s0->next) s0 = s0->next; s0->next = s1; } static struct slist * xfer_to_x(a) struct arth *a; { struct slist *s; s = new_stmt(BPF_LDX|BPF_MEM); s->s.k = a->regno; return s; } static struct slist * xfer_to_a(a) struct arth *a; { struct slist *s; s = new_stmt(BPF_LD|BPF_MEM); s->s.k = a->regno; return s; } struct arth * gen_load(proto, index, size) int proto; struct arth *index; int size; { struct slist *s, *tmp; struct block *b; int regno = alloc_reg(); free_reg(index->regno); switch (size) { default: bpf_error("data size must be 1, 2, or 4"); case 1: size = BPF_B; break; case 2: size = BPF_H; break; case 4: size = BPF_W; break; } switch (proto) { default: bpf_error("unsupported index operation"); case Q_LINK: s = xfer_to_x(index); tmp = new_stmt(BPF_LD|BPF_IND|size); sappend(s, tmp); sappend(index->s, s); break; case Q_IP: case Q_ARP: case Q_RARP: case Q_ATALK: case Q_DECNET: case Q_SCA: case Q_LAT: case Q_MOPRC: case Q_MOPDL: #ifdef INET6 case Q_IPV6: #endif /* XXX Note that we assume a fixed link header here. */ s = xfer_to_x(index); tmp = new_stmt(BPF_LD|BPF_IND|size); tmp->s.k = off_nl; sappend(s, tmp); sappend(index->s, s); b = gen_proto_abbrev(proto); if (index->b) gen_and(index->b, b); index->b = b; break; case Q_TCP: case Q_UDP: case Q_ICMP: case Q_IGMP: case Q_IGRP: case Q_PIM: s = new_stmt(BPF_LDX|BPF_MSH|BPF_B); s->s.k = off_nl; sappend(s, xfer_to_a(index)); sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X)); sappend(s, new_stmt(BPF_MISC|BPF_TAX)); sappend(s, tmp = new_stmt(BPF_LD|BPF_IND|size)); tmp->s.k = off_nl; sappend(index->s, s); gen_and(gen_proto_abbrev(proto), b = gen_ipfrag()); if (index->b) gen_and(index->b, b); #ifdef INET6 gen_and(gen_proto_abbrev(Q_IP), b); #endif index->b = b; break; #ifdef INET6 case Q_ICMPV6: bpf_error("IPv6 upper-layer protocol is not supported by proto[x]"); /*NOTREACHED*/ #endif } index->regno = regno; s = new_stmt(BPF_ST); s->s.k = regno; sappend(index->s, s); return index; } struct block * gen_relation(code, a0, a1, reversed) int code; struct arth *a0, *a1; int reversed; { struct slist *s0, *s1, *s2; struct block *b, *tmp; s0 = xfer_to_x(a1); s1 = xfer_to_a(a0); s2 = new_stmt(BPF_ALU|BPF_SUB|BPF_X); b = new_block(JMP(code)); if (code == BPF_JGT || code == BPF_JGE) { reversed = !reversed; b->s.k = 0x80000000; } if (reversed) gen_not(b); sappend(s1, s2); sappend(s0, s1); sappend(a1->s, s0); sappend(a0->s, a1->s); b->stmts = a0->s; free_reg(a0->regno); free_reg(a1->regno); /* 'and' together protocol checks */ if (a0->b) { if (a1->b) { gen_and(a0->b, tmp = a1->b); } else tmp = a0->b; } else tmp = a1->b; if (tmp) gen_and(tmp, b); return b; } struct arth * gen_loadlen() { int regno = alloc_reg(); struct arth *a = (struct arth *)newchunk(sizeof(*a)); struct slist *s; s = new_stmt(BPF_LD|BPF_LEN); s->next = new_stmt(BPF_ST); s->next->s.k = regno; a->s = s; a->regno = regno; return a; } struct arth * gen_loadi(val) int val; { struct arth *a; struct slist *s; int reg; a = (struct arth *)newchunk(sizeof(*a)); reg = alloc_reg(); s = new_stmt(BPF_LD|BPF_IMM); s->s.k = val; s->next = new_stmt(BPF_ST); s->next->s.k = reg; a->s = s; a->regno = reg; return a; } struct arth * gen_neg(a) struct arth *a; { struct slist *s; s = xfer_to_a(a); sappend(a->s, s); s = new_stmt(BPF_ALU|BPF_NEG); s->s.k = 0; sappend(a->s, s); s = new_stmt(BPF_ST); s->s.k = a->regno; sappend(a->s, s); return a; } struct arth * gen_arth(code, a0, a1) int code; struct arth *a0, *a1; { struct slist *s0, *s1, *s2; s0 = xfer_to_x(a1); s1 = xfer_to_a(a0); s2 = new_stmt(BPF_ALU|BPF_X|code); sappend(s1, s2); sappend(s0, s1); sappend(a1->s, s0); sappend(a0->s, a1->s); free_reg(a1->regno); s0 = new_stmt(BPF_ST); a0->regno = s0->s.k = alloc_reg(); sappend(a0->s, s0); return a0; } /* * Here we handle simple allocation of the scratch registers. * If too many registers are alloc'd, the allocator punts. */ static int regused[BPF_MEMWORDS]; static int curreg; /* * Return the next free register. */ static int alloc_reg() { int n = BPF_MEMWORDS; while (--n >= 0) { if (regused[curreg]) curreg = (curreg + 1) % BPF_MEMWORDS; else { regused[curreg] = 1; return curreg; } } bpf_error("too many registers needed to evaluate expression"); /* NOTREACHED */ } /* * Return a register to the table so it can * be used later. */ static void free_reg(n) int n; { regused[n] = 0; } static struct block * gen_len(jmp, n) int jmp, n; { struct slist *s; struct block *b; s = new_stmt(BPF_LD|BPF_LEN); b = new_block(JMP(jmp)); b->stmts = s; b->s.k = n; return b; } struct block * gen_greater(n) int n; { return gen_len(BPF_JGE, n); } struct block * gen_less(n) int n; { struct block *b; b = gen_len(BPF_JGT, n); gen_not(b); return b; } struct block * gen_byteop(op, idx, val) int op, idx, val; { struct block *b; struct slist *s; switch (op) { default: abort(); case '=': return gen_cmp((u_int)idx, BPF_B, (bpf_int32)val); case '<': b = gen_cmp((u_int)idx, BPF_B, (bpf_int32)val); b->s.code = JMP(BPF_JGE); gen_not(b); return b; case '>': b = gen_cmp((u_int)idx, BPF_B, (bpf_int32)val); b->s.code = JMP(BPF_JGT); return b; case '|': s = new_stmt(BPF_ALU|BPF_OR|BPF_K); break; case '&': s = new_stmt(BPF_ALU|BPF_AND|BPF_K); break; } s->s.k = val; b = new_block(JMP(BPF_JEQ)); b->stmts = s; gen_not(b); return b; } struct block * gen_broadcast(proto) int proto; { bpf_u_int32 hostmask; struct block *b0, *b1, *b2; static u_char ebroadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; switch (proto) { case Q_DEFAULT: case Q_LINK: if (linktype == DLT_EN10MB) return gen_ehostop(ebroadcast, Q_DST); if (linktype == DLT_FDDI) return gen_fhostop(ebroadcast, Q_DST); bpf_error("not a broadcast link"); break; case Q_IP: b0 = gen_linktype(ETHERTYPE_IP); hostmask = ~netmask; b1 = gen_mcmp(off_nl + 16, BPF_W, (bpf_int32)0, hostmask); b2 = gen_mcmp(off_nl + 16, BPF_W, (bpf_int32)(~0 & hostmask), hostmask); gen_or(b1, b2); gen_and(b0, b2); return b2; } bpf_error("only ether/ip broadcast filters supported"); } struct block * gen_multicast(proto) int proto; { register struct block *b0, *b1; register struct slist *s; switch (proto) { case Q_DEFAULT: case Q_LINK: if (linktype == DLT_EN10MB) { /* ether[0] & 1 != 0 */ s = new_stmt(BPF_LD|BPF_B|BPF_ABS); s->s.k = 0; b0 = new_block(JMP(BPF_JSET)); b0->s.k = 1; b0->stmts = s; return b0; } if (linktype == DLT_FDDI) { /* XXX TEST THIS: MIGHT NOT PORT PROPERLY XXX */ /* fddi[1] & 1 != 0 */ s = new_stmt(BPF_LD|BPF_B|BPF_ABS); s->s.k = 1; b0 = new_block(JMP(BPF_JSET)); b0->s.k = 1; b0->stmts = s; return b0; } /* Link not known to support multicasts */ break; case Q_IP: b0 = gen_linktype(ETHERTYPE_IP); b1 = gen_cmp(off_nl + 16, BPF_B, (bpf_int32)224); b1->s.code = JMP(BPF_JGE); gen_and(b0, b1); return b1; #ifdef INET6 case Q_IPV6: b0 = gen_linktype(ETHERTYPE_IPV6); b1 = gen_cmp(off_nl + 24, BPF_B, (bpf_int32)255); gen_and(b0, b1); return b1; #endif /* INET6 */ } bpf_error("only IP multicast filters supported on ethernet/FDDI"); } /* * generate command for inbound/outbound. It's here so we can * make it link-type specific. 'dir' = 0 implies "inbound", * = 1 implies "outbound". */ struct block * gen_inbound(dir) int dir; { register struct block *b0; b0 = gen_relation(BPF_JEQ, gen_load(Q_LINK, gen_loadi(0), 1), gen_loadi(0), dir); return (b0); } libpcap-0.5/./gencode.h100644 263 461 11626 7003105705 13421 0ustar mcrtcpdump/* * Copyright (c) 1990, 1991, 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. * * @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.37 1999/10/19 15:18:29 itojun Exp $ (LBL) */ /*XXX*/ #include "gnuc.h" /* Address qualifiers. */ #define Q_HOST 1 #define Q_NET 2 #define Q_PORT 3 #define Q_GATEWAY 4 #define Q_PROTO 5 #define Q_PROTOCHAIN 6 /* Protocol qualifiers. */ #define Q_LINK 1 #define Q_IP 2 #define Q_ARP 3 #define Q_RARP 4 #define Q_TCP 5 #define Q_UDP 6 #define Q_ICMP 7 #define Q_IGMP 8 #define Q_IGRP 9 #define Q_ATALK 10 #define Q_DECNET 11 #define Q_LAT 12 #define Q_SCA 13 #define Q_MOPRC 14 #define Q_MOPDL 15 #define Q_IPV6 16 #define Q_ICMPV6 17 #define Q_AH 18 #define Q_ESP 19 #define Q_PIM 20 /* Directional qualifiers. */ #define Q_SRC 1 #define Q_DST 2 #define Q_OR 3 #define Q_AND 4 #define Q_DEFAULT 0 #define Q_UNDEF 255 struct slist; struct stmt { int code; struct slist *jt; /*only for relative jump in block*/ struct slist *jf; /*only for relative jump in block*/ bpf_int32 k; }; struct slist { struct stmt s; struct slist *next; }; /* * A bit vector to represent definition sets. We assume TOT_REGISTERS * is smaller than 8*sizeof(atomset). */ typedef bpf_u_int32 atomset; #define ATOMMASK(n) (1 << (n)) #define ATOMELEM(d, n) (d & ATOMMASK(n)) /* * An unbounded set. */ typedef bpf_u_int32 *uset; /* * Total number of atomic entities, including accumulator (A) and index (X). * We treat all these guys similarly during flow analysis. */ #define N_ATOMS (BPF_MEMWORDS+2) struct edge { int id; int code; uset edom; struct block *succ; struct block *pred; struct edge *next; /* link list of incoming edges for a node */ }; struct block { int id; struct slist *stmts; /* side effect stmts */ struct stmt s; /* branch stmt */ int mark; int longjt; /* jt branch requires long jump */ int longjf; /* jf branch requires long jump */ int level; int offset; int sense; struct edge et; struct edge ef; struct block *head; struct block *link; /* link field used by optimizer */ uset dom; uset closure; struct edge *in_edges; atomset def, kill; atomset in_use; atomset out_use; int oval; int val[N_ATOMS]; }; struct arth { struct block *b; /* protocol checks */ struct slist *s; /* stmt list */ int regno; /* virtual register number of result */ }; struct qual { unsigned char addr; unsigned char proto; unsigned char dir; unsigned char pad; }; struct arth *gen_loadi(int); struct arth *gen_load(int, struct arth *, int); struct arth *gen_loadlen(void); struct arth *gen_neg(struct arth *); struct arth *gen_arth(int, struct arth *, struct arth *); void gen_and(struct block *, struct block *); void gen_or(struct block *, struct block *); void gen_not(struct block *); struct block *gen_scode(const char *, struct qual); struct block *gen_ecode(const u_char *, struct qual); struct block *gen_mcode(const char *, const char *, int, struct qual); #ifdef INET6 struct block *gen_mcode6(const char *, const char *, int, struct qual); #endif struct block *gen_ncode(const char *, bpf_u_int32, struct qual); struct block *gen_proto_abbrev(int); struct block *gen_relation(int, struct arth *, struct arth *, int); struct block *gen_less(int); struct block *gen_greater(int); struct block *gen_byteop(int, int, int); struct block *gen_broadcast(int); struct block *gen_multicast(int); struct block *gen_inbound(int); void bpf_optimize(struct block **); #if __STDC__ __dead void bpf_error(const char *, ...) __attribute__((volatile, format (printf, 1, 2))); #endif void finish_parse(struct block *); char *sdup(const char *); struct bpf_insn *icode_to_fcode(struct block *, int *); int pcap_parse(void); void lex_init(char *); void sappend(struct slist *, struct slist *); /* XXX */ #define JT(b) ((b)->et.succ) #define JF(b) ((b)->ef.succ) extern int no_optimize; libpcap-0.5/./grammar.y100644 263 461 17307 7003105706 13467 0ustar mcrtcpdump%{ /* * Copyright (c) 1988, 1989, 1990, 1991, 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/grammar.y,v 1.57 1999/10/19 15:18:30 itojun Exp $ (LBL)"; #endif #include #include #include #if __STDC__ struct mbuf; struct rtentry; #endif #include #include #include #include #include "pcap-int.h" #include "gencode.h" #include #include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif #define QSET(q, p, d, a) (q).proto = (p),\ (q).dir = (d),\ (q).addr = (a) int n_errors = 0; static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF }; static void yyerror(char *msg) { ++n_errors; bpf_error("%s", msg); /* NOTREACHED */ } #ifndef YYBISON int yyparse(void); int pcap_parse() { return (yyparse()); } #endif %} %union { int i; bpf_u_int32 h; u_char *e; char *s; struct stmt *stmt; struct arth *a; struct { struct qual q; struct block *b; } blk; struct block *rblk; } %type expr id nid pid term rterm qid %type head %type pqual dqual aqual ndaqual %type arth narth %type byteop pname pnum relop irelop %type and or paren not null prog %type other %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 TK_BROADCAST TK_MULTICAST %token NUM INBOUND OUTBOUND %token LINK %token GEQ LEQ NEQ %token ID EID HID HID6 %token LSH RSH %token LEN %token IPV6 ICMPV6 AH ESP %type ID %type EID %type HID HID6 %type NUM %left OR AND %nonassoc '!' %left '|' %left '&' %left LSH RSH %left '+' '-' %left '*' '/' %nonassoc UMINUS %% prog: null expr { finish_parse($2.b); } | null ; null: /* null */ { $$.q = qerr; } ; expr: term | expr and term { gen_and($1.b, $3.b); $$ = $3; } | expr and id { gen_and($1.b, $3.b); $$ = $3; } | expr or term { gen_or($1.b, $3.b); $$ = $3; } | expr or id { gen_or($1.b, $3.b); $$ = $3; } ; and: AND { $$ = $0; } ; or: OR { $$ = $0; } ; id: nid | pnum { $$.b = gen_ncode(NULL, (bpf_u_int32)$1, $$.q = $0.q); } | paren pid ')' { $$ = $2; } ; nid: ID { $$.b = gen_scode($1, $$.q = $0.q); } | HID '/' NUM { $$.b = gen_mcode($1, NULL, $3, $$.q = $0.q); } | HID MASK HID { $$.b = gen_mcode($1, $3, 0, $$.q = $0.q); } | HID { /* Decide how to parse HID based on proto */ $$.q = $0.q; switch ($$.q.proto) { case Q_DECNET: $$.b = gen_ncode($1, 0, $$.q); break; default: $$.b = gen_ncode($1, 0, $$.q); break; } } | HID6 '/' NUM { #ifdef INET6 $$.b = gen_mcode6($1, NULL, $3, $$.q = $0.q); #else bpf_error("'ip6addr/prefixlen' not supported " "in this configuration"); #endif /*INET6*/ } | HID6 { #ifdef INET6 $$.b = gen_mcode6($1, 0, 128, $$.q = $0.q); #else bpf_error("'ip6addr' not supported " "in this configuration"); #endif /*INET6*/ } | EID { $$.b = gen_ecode($1, $$.q = $0.q); } | not id { gen_not($2.b); $$ = $2; } ; not: '!' { $$ = $0; } ; paren: '(' { $$ = $0; } ; pid: nid | qid and id { gen_and($1.b, $3.b); $$ = $3; } | qid or id { gen_or($1.b, $3.b); $$ = $3; } ; qid: pnum { $$.b = gen_ncode(NULL, (bpf_u_int32)$1, $$.q = $0.q); } | pid ; term: rterm | not term { gen_not($2.b); $$ = $2; } ; head: pqual dqual aqual { QSET($$.q, $1, $2, $3); } | pqual dqual { QSET($$.q, $1, $2, Q_DEFAULT); } | pqual aqual { QSET($$.q, $1, Q_DEFAULT, $2); } | pqual PROTO { QSET($$.q, $1, Q_DEFAULT, Q_PROTO); } | pqual PROTOCHAIN { QSET($$.q, $1, Q_DEFAULT, Q_PROTOCHAIN); } | pqual ndaqual { QSET($$.q, $1, Q_DEFAULT, $2); } ; rterm: head id { $$ = $2; } | paren expr ')' { $$.b = $2.b; $$.q = $1.q; } | pname { $$.b = gen_proto_abbrev($1); $$.q = qerr; } | arth relop arth { $$.b = gen_relation($2, $1, $3, 0); $$.q = qerr; } | arth irelop arth { $$.b = gen_relation($2, $1, $3, 1); $$.q = qerr; } | other { $$.b = $1; $$.q = qerr; } ; /* protocol level qualifiers */ pqual: pname | { $$ = Q_DEFAULT; } ; /* 'direction' qualifiers */ dqual: SRC { $$ = Q_SRC; } | DST { $$ = Q_DST; } | SRC OR DST { $$ = Q_OR; } | DST OR SRC { $$ = Q_OR; } | SRC AND DST { $$ = Q_AND; } | DST AND SRC { $$ = Q_AND; } ; /* address type qualifiers */ aqual: HOST { $$ = Q_HOST; } | NET { $$ = Q_NET; } | PORT { $$ = Q_PORT; } ; /* non-directional address type qualifiers */ ndaqual: GATEWAY { $$ = Q_GATEWAY; } ; pname: LINK { $$ = Q_LINK; } | IP { $$ = Q_IP; } | ARP { $$ = Q_ARP; } | RARP { $$ = Q_RARP; } | TCP { $$ = Q_TCP; } | UDP { $$ = Q_UDP; } | ICMP { $$ = Q_ICMP; } | IGMP { $$ = Q_IGMP; } | IGRP { $$ = Q_IGRP; } | PIM { $$ = Q_PIM; } | ATALK { $$ = Q_ATALK; } | DECNET { $$ = Q_DECNET; } | LAT { $$ = Q_LAT; } | SCA { $$ = Q_SCA; } | MOPDL { $$ = Q_MOPDL; } | MOPRC { $$ = Q_MOPRC; } | IPV6 { $$ = Q_IPV6; } | ICMPV6 { $$ = Q_ICMPV6; } | AH { $$ = Q_AH; } | ESP { $$ = Q_ESP; } ; other: pqual TK_BROADCAST { $$ = gen_broadcast($1); } | pqual TK_MULTICAST { $$ = gen_multicast($1); } | LESS NUM { $$ = gen_less($2); } | GREATER NUM { $$ = gen_greater($2); } | BYTE NUM byteop NUM { $$ = gen_byteop($3, $2, $4); } | INBOUND { $$ = gen_inbound(0); } | OUTBOUND { $$ = gen_inbound(1); } ; relop: '>' { $$ = BPF_JGT; } | GEQ { $$ = BPF_JGE; } | '=' { $$ = BPF_JEQ; } ; irelop: LEQ { $$ = BPF_JGT; } | '<' { $$ = BPF_JGE; } | NEQ { $$ = BPF_JEQ; } ; arth: pnum { $$ = gen_loadi($1); } | narth ; narth: pname '[' arth ']' { $$ = gen_load($1, $3, 1); } | pname '[' arth ':' NUM ']' { $$ = gen_load($1, $3, $5); } | arth '+' arth { $$ = gen_arth(BPF_ADD, $1, $3); } | arth '-' arth { $$ = gen_arth(BPF_SUB, $1, $3); } | arth '*' arth { $$ = gen_arth(BPF_MUL, $1, $3); } | arth '/' arth { $$ = gen_arth(BPF_DIV, $1, $3); } | arth '&' arth { $$ = gen_arth(BPF_AND, $1, $3); } | arth '|' arth { $$ = gen_arth(BPF_OR, $1, $3); } | arth LSH arth { $$ = gen_arth(BPF_LSH, $1, $3); } | arth RSH arth { $$ = gen_arth(BPF_RSH, $1, $3); } | '-' arth %prec UMINUS { $$ = gen_neg($2); } | paren narth ')' { $$ = $2; } | LEN { $$ = gen_loadlen(); } ; byteop: '&' { $$ = '&'; } | '|' { $$ = '|'; } | '<' { $$ = '<'; } | '>' { $$ = '>'; } | '=' { $$ = '='; } ; pnum: NUM | paren pnum ')' { $$ = $2; } ; %% libpcap-0.5/./inet.c100644 263 461 15202 7037662122 12751 0ustar mcrtcpdump/* * Copyright (c) 1994, 1995, 1996, 1997, 1998 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the Computer Systems * Engineering Group at Lawrence Berkeley Laboratory. * 4. Neither the name of the University nor of the Laboratory may be used * to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef lint static const char rcsid[] = "@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.24.2.1 2000/01/14 18:00:50 mcr Exp $ (LBL)"; #endif #include #include #include #include #ifdef HAVE_SYS_SOCKIO_H #include #endif #include /* concession to AIX */ #if __STDC__ struct mbuf; struct rtentry; #endif #include #include #include #include #include #include #include #include #include #include "pcap-int.h" #include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif /* Not all systems have IFF_LOOPBACK */ #ifdef IFF_LOOPBACK #define ISLOOPBACK(p) ((p)->ifr_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')) #endif /* * Return the name of a network interface attached to the system, or NULL * if none can be found. The interface must be configured up; the * lowest unit number is preferred; loopback is ignored. */ char * pcap_lookupdev(errbuf) register char *errbuf; { register int fd, minunit, n; register char *cp; register struct ifreq *ifrp, *ifend, *ifnext, *mp; struct ifconf ifc; char *buf; struct ifreq ifr; static char device[sizeof(ifrp->ifr_name) + 1]; unsigned buf_size; fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { (void)sprintf(errbuf, "socket: %s", pcap_strerror(errno)); return (NULL); } buf_size = 8192; for (;;) { buf = malloc (buf_size); if (buf == NULL) { close (fd); (void)sprintf(errbuf, "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) { free (buf); (void)sprintf(errbuf, "SIOCGIFCONF: %s", pcap_strerror(errno)); (void)close(fd); return (NULL); } if (ifc.ifc_len < buf_size) break; free (buf); buf_size *= 2; } ifrp = (struct ifreq *)buf; ifend = (struct ifreq *)(buf + ifc.ifc_len); mp = NULL; minunit = 666; for (; ifrp < ifend; ifrp = ifnext) { #ifdef HAVE_SOCKADDR_SA_LEN n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name); if (n < sizeof(*ifrp)) ifnext = ifrp + 1; else ifnext = (struct ifreq *)((char *)ifrp + n); if (ifrp->ifr_addr.sa_family != AF_INET) continue; #else ifnext = ifrp + 1; #endif /* * Need a template to preserve address info that is * used below to locate the next entry. (Otherwise, * SIOCGIFFLAGS stomps over it because the requests * are returned in a union.) */ strncpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name)); if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) { if (errno == ENXIO) continue; (void)sprintf(errbuf, "SIOCGIFFLAGS: %.*s: %s", (int)sizeof(ifr.ifr_name), ifr.ifr_name, pcap_strerror(errno)); (void)close(fd); free (buf); return (NULL); } /* Must be up and not the loopback */ if ((ifr.ifr_flags & IFF_UP) == 0 || ISLOOPBACK(&ifr)) continue; for (cp = ifrp->ifr_name; !isdigit(*cp); ++cp) continue; n = atoi(cp); if (n < minunit) { minunit = n; mp = ifrp; } } free(buf); (void)close(fd); if (mp == NULL) { (void)strcpy(errbuf, "no suitable device found"); return (NULL); } (void)strncpy(device, mp->ifr_name, sizeof(device) - 1); device[sizeof(device) - 1] = '\0'; return (device); } int pcap_lookupnet(device, netp, maskp, errbuf) register char *device; register bpf_u_int32 *netp, *maskp; register char *errbuf; { register int fd; register struct sockaddr_in *sin; struct ifreq ifr; fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { (void)sprintf(errbuf, "socket: %s", pcap_strerror(errno)); return (-1); } memset(&ifr, 0, sizeof(ifr)); #ifdef linux /* XXX Work around Linux kernel bug */ ifr.ifr_addr.sa_family = AF_INET; #endif (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); } else { (void)sprintf(errbuf, "SIOCGIFADDR: %s: %s", device, pcap_strerror(errno)); } (void)close(fd); return (-1); } 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)close(fd); return (-1); } (void)close(fd); *maskp = sin->sin_addr.s_addr; if (*maskp == 0) { if (IN_CLASSA(*netp)) *maskp = IN_CLASSA_NET; else if (IN_CLASSB(*netp)) *maskp = IN_CLASSB_NET; else if (IN_CLASSC(*netp)) *maskp = IN_CLASSC_NET; else { (void)sprintf(errbuf, "inet class for 0x%x unknown", *netp); return (-1); } } *netp &= *maskp; return (0); } libpcap-0.5/./install-sh100755 263 461 12721 6777230340 13660 0ustar mcrtcpdump#! /bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 libpcap-0.5/./mkdep100755 263 461 4456 6777230340 12670 0ustar mcrtcpdump#!/bin/sh - # # Copyright (c) 1994, 1996 # The Regents of the University of California. All rights reserved. # # Redistribution and use in source and binary forms are permitted # provided that this notice is preserved and that due credit is given # to the University of California at Berkeley. The name of the University # may not be used to endorse or promote products derived from this # software without specific prior written permission. This software # is provided ``as is'' without express or implied warranty. # # @(#)mkdep.sh 5.11 (Berkeley) 5/5/88 # PATH=/bin:/usr/bin:/usr/ucb:/usr/local:/usr/local/bin export PATH MAKE=Makefile # default makefile name is "Makefile" CC=cc # default C compiler is "cc" while : do case "$1" in # -c allows you to specify the C compiler -c) CC=$2 shift; shift ;; # -f allows you to select a makefile name -f) MAKE=$2 shift; shift ;; # the -p flag produces "program: program.c" style dependencies # so .o's don't get produced -p) SED='s;\.o;;' shift ;; *) break ;; esac done if [ $# = 0 ] ; then echo 'usage: mkdep [-p] [-c cc] [-f makefile] [flags] file ...' exit 1 fi if [ ! -w $MAKE ]; then echo "mkdep: no writeable file \"$MAKE\"" exit 1 fi TMP=/tmp/mkdep$$ trap 'rm -f $TMP ; exit 1' 1 2 3 13 15 cp $MAKE ${MAKE}.bak sed -e '/DO NOT DELETE THIS LINE/,$d' < $MAKE > $TMP cat << _EOF_ >> $TMP # DO NOT DELETE THIS LINE -- mkdep uses it. # DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. _EOF_ # If your compiler doesn't have -M, add it. If you can't, the next two # lines will try and replace the "cc -M". The real problem is that this # hack can't deal with anything that requires a search path, and doesn't # even try for anything using bracket (<>) syntax. # # egrep '^#include[ ]*".*"' /dev/null $* | # sed -e 's/:[^"]*"\([^"]*\)".*/: \1/' -e 's/\.c/.o/' | # XXX this doesn't work with things like "-DDECLWAITSTATUS=union\ wait" $CC -M $* | sed " s; \./; ;g $SED" | awk '{ if ($1 != prev) { if (rec != "") print rec; rec = $0; prev = $1; } else { if (length(rec $2) > 78) { print rec; rec = $0; } else rec = rec " " $2 } } END { print rec }' >> $TMP cat << _EOF_ >> $TMP # IF YOU PUT ANYTHING HERE IT WILL GO AWAY _EOF_ # copy to preserve permissions cp $TMP $MAKE rm -f ${MAKE}.bak $TMP exit 0 libpcap-0.5/./nametoaddr.c100644 263 461 17770 7017171177 14147 0ustar mcrtcpdump/* * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998 * 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. * * Name to id translation routines used by the scanner. * These functions are not time critical. */ #ifndef lint static const char rcsid[] = "@(#) $Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.51 1999/11/25 08:25:35 itojun Exp $ (LBL)"; #endif #include #include /* concession to AIX */ #include #include #if __STDC__ struct mbuf; struct rtentry; #endif #include #include #include #include #ifdef INET6 #include #include #endif /*INET6*/ #include #include #include #include #include #include #include "pcap-int.h" #include "gencode.h" #include #include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif #ifndef NTOHL #define NTOHL(x) (x) = ntohl(x) #define NTOHS(x) (x) = ntohs(x) #endif 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) { #ifndef h_addr static bpf_u_int32 *hlist[2]; #endif bpf_u_int32 **p; struct hostent *hp; if ((hp = gethostbyname(name)) != NULL) { #ifndef h_addr hlist[0] = (bpf_u_int32 *)hp->h_addr; NTOHL(hp->h_addr); return hlist; #else for (p = (bpf_u_int32 **)hp->h_addr_list; *p; ++p) NTOHL(**p); return (bpf_u_int32 **)hp->h_addr_list; #endif } else return 0; } #else struct addrinfo * pcap_nametoaddr(const char *name) { struct addrinfo hints, *res; int error; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; /*not really*/ error = getaddrinfo(name, NULL, &hints, &res); if (error) return NULL; else return res; } #endif /*INET6*/ /* * Convert net name to internet address. * Return 0 upon failure. */ bpf_u_int32 pcap_nametonetaddr(const char *name) { struct netent *np; if ((np = getnetbyname(name)) != NULL) return np->n_net; else return 0; } /* * Convert a port name to its port and protocol numbers. * We assume only TCP or UDP. * Return 0 upon failure. */ int pcap_nametoport(const char *name, int *port, int *proto) { struct servent *sp; char *other; sp = getservbyname(name, (char *)0); if (sp != NULL) { NTOHS(sp->s_port); *port = sp->s_port; *proto = pcap_nametoproto(sp->s_proto); /* * We need to check /etc/services for ambiguous entries. * If we find the ambiguous entry, and it has the * same port number, change the proto to PROTO_UNDEF * so both TCP and UDP will be checked. */ if (*proto == IPPROTO_TCP) other = "udp"; else other = "tcp"; sp = getservbyname(name, other); if (sp != 0) { NTOHS(sp->s_port); #ifdef notdef if (*port != sp->s_port) /* Can't handle ambiguous names that refer to different port numbers. */ warning("ambiguous port %s in /etc/services", name); #endif *proto = PROTO_UNDEF; } return 1; } #if defined(ultrix) || defined(__osf__) /* Special hack in case NFS isn't in /etc/services */ if (strcmp(name, "nfs") == 0) { *port = 2049; *proto = PROTO_UNDEF; return 1; } #endif return 0; } int pcap_nametoproto(const char *str) { struct protoent *p; p = getprotobyname(str); if (p != 0) return p->p_proto; else return PROTO_UNDEF; } #include "ethertype.h" struct eproto { char *s; u_short p; }; /* Static data base of ether protocol types. */ struct eproto eproto_db[] = { { "pup", ETHERTYPE_PUP }, { "xns", ETHERTYPE_NS }, { "ip", ETHERTYPE_IP }, #ifdef INET6 { "ip6", ETHERTYPE_IPV6 }, #endif { "arp", ETHERTYPE_ARP }, { "rarp", ETHERTYPE_REVARP }, { "sprite", ETHERTYPE_SPRITE }, { "mopdl", ETHERTYPE_MOPDL }, { "moprc", ETHERTYPE_MOPRC }, { "decnet", ETHERTYPE_DN }, { "lat", ETHERTYPE_LAT }, { "sca", ETHERTYPE_SCA }, { "lanbridge", ETHERTYPE_LANBRIDGE }, { "vexp", ETHERTYPE_VEXP }, { "vprod", ETHERTYPE_VPROD }, { "atalk", ETHERTYPE_ATALK }, { "atalkarp", ETHERTYPE_AARP }, { "loopback", ETHERTYPE_LOOPBACK }, { "decdts", ETHERTYPE_DECDTS }, { "decdns", ETHERTYPE_DECDNS }, { (char *)0, 0 } }; int pcap_nametoeproto(const char *s) { struct eproto *p = eproto_db; while (p->s != 0) { if (strcmp(p->s, s) == 0) return p->p; p += 1; } return PROTO_UNDEF; } /* Hex digit to integer. */ static inline int xdtoi(c) register int c; { if (isdigit(c)) return c - '0'; else if (islower(c)) return c - 'a' + 10; else return c - 'A' + 10; } int __pcap_atoin(const char *s, bpf_u_int32 *addr) { u_int n; int len; *addr = 0; len = 0; while (1) { n = 0; while (*s && *s != '.') n = n * 10 + *s++ - '0'; *addr <<= 8; *addr |= n & 0xff; len += 8; if (*s == '\0') return len; ++s; } /* NOTREACHED */ } int __pcap_atodn(const char *s, bpf_u_int32 *addr) { #define AREASHIFT 10 #define AREAMASK 0176000 #define NODEMASK 01777 u_int node, area; if (sscanf((char *)s, "%d.%d", &area, &node) != 2) bpf_error("malformed decnet address '%s'", s); *addr = (area << AREASHIFT) & AREAMASK; *addr |= (node & NODEMASK); return(32); } /* * Convert 's' which has the form "xx:xx:xx:xx:xx:xx" into a new * ethernet address. Assumes 's' is well formed. */ u_char * pcap_ether_aton(const char *s) { register u_char *ep, *e; register u_int d; e = ep = (u_char *)malloc(6); while (*s) { if (*s == ':') s += 1; d = xdtoi(*s++); if (isxdigit(*s)) { d <<= 4; d |= xdtoi(*s++); } *ep++ = d; } return (e); } #ifndef HAVE_ETHER_HOSTTON /* Roll our own */ u_char * pcap_ether_hostton(const char *name) { register struct pcap_etherent *ep; register u_char *ap; static FILE *fp = NULL; static init = 0; if (!init) { fp = fopen(PCAP_ETHERS_FILE, "r"); ++init; if (fp == NULL) return (NULL); } else if (fp == NULL) return (NULL); else rewind(fp); while ((ep = pcap_next_etherent(fp)) != NULL) { if (strcmp(ep->name, name) == 0) { ap = (u_char *)malloc(6); if (ap != NULL) { memcpy(ap, ep->addr, 6); return (ap); } break; } } return (NULL); } #else #if !defined(sgi) && !defined(__NetBSD__) extern int ether_hostton(char *, struct ether_addr *); #endif /* Use the os supplied routines */ u_char * pcap_ether_hostton(const char *name) { register u_char *ap; u_char a[6]; ap = NULL; if (ether_hostton((char *)name, (struct ether_addr *)a) == 0) { ap = (u_char *)malloc(6); if (ap != NULL) memcpy((char *)ap, (char *)a, 6); } return (ap); } #endif u_short __pcap_nametodnaddr(const char *name) { #ifdef DECNETLIB struct nodeent *getnodebyname(); struct nodeent *nep; unsigned short res; nep = getnodebyname(name); if (nep == ((struct nodeent *)0)) bpf_error("unknown decnet host name '%s'\n", name); memcpy((char *)&res, (char *)nep->n_addr, sizeof(unsigned short)); return(res); #else bpf_error("decnet name support not included, '%s' cannot be translated\n", name); #endif } libpcap-0.5/./bpf/ 40755 263 461 0 7136054723 12302 5ustar mcrtcpdumplibpcap-0.5/./bpf/CVS/ 40755 263 461 0 7136054731 12734 5ustar mcrtcpdumplibpcap-0.5/./bpf/CVS/Root100644 263 461 61 7136054722 13634 0ustar mcrtcpdump:pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master libpcap-0.5/./bpf/CVS/Repository100644 263 461 14 7136054722 15066 0ustar mcrtcpdumplibpcap/bpf libpcap-0.5/./bpf/CVS/Entries100644 263 461 12 7136054731 14316 0ustar mcrtcpdumpD/net//// libpcap-0.5/./bpf/CVS/Tag100644 263 461 21 7136054722 13420 0ustar mcrtcpdumpTlibpcap_0_5rel2 libpcap-0.5/./bpf/net/ 40755 263 461 0 7136054724 13071 5ustar mcrtcpdumplibpcap-0.5/./bpf/net/CVS/ 40755 263 461 0 7136054724 13524 5ustar mcrtcpdumplibpcap-0.5/./bpf/net/CVS/Root100644 263 461 61 7136054723 14423 0ustar mcrtcpdump:pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master libpcap-0.5/./bpf/net/CVS/Repository100644 263 461 20 7136054723 15652 0ustar mcrtcpdumplibpcap/bpf/net libpcap-0.5/./bpf/net/CVS/Entries100644 263 461 173 7136054724 15136 0ustar mcrtcpdump/bpf.h/1.37/Tue Oct 19 15:18:31 1999//Tlibpcap_0_5rel2 /bpf_filter.c/1.33.1.1/Thu Oct 7 23:46:41 1999//Tlibpcap_0_5rel2 D libpcap-0.5/./bpf/net/CVS/Tag100644 263 461 21 7136054724 14210 0ustar mcrtcpdumpNlibpcap_0_5rel2 libpcap-0.5/./bpf/net/bpf.h100644 263 461 21257 7003105707 14124 0ustar mcrtcpdump/*- * 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. * * @(#)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) */ #ifndef BPF_MAJOR_VERSION /* BSD style release date */ #define BPF_RELEASE 199606 typedef int bpf_int32; typedef u_int bpf_u_int32; /* * Alignment macros. BPF_WORDALIGN rounds up to the next * even multiple of BPF_ALIGNMENT. */ #ifndef __NetBSD__ #define BPF_ALIGNMENT sizeof(bpf_int32) #else #define BPF_ALIGNMENT sizeof(long) #endif #define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1)) #define BPF_MAXINSNS 512 #define BPF_MAXBUFSIZE 0x8000 #define BPF_MINBUFSIZE 32 /* * Structure for BIOCSETF. */ struct bpf_program { u_int bf_len; struct bpf_insn *bf_insns; }; /* * Struct returned by BIOCGSTATS. */ struct bpf_stat { u_int bs_recv; /* number of packets received */ u_int bs_drop; /* number of packets dropped */ }; /* * Struct return by BIOCVERSION. This represents the version number of * the filter language described by the instruction encodings below. * bpf understands a program iff kernel_major == filter_major && * kernel_minor >= filter_minor, that is, if the value returned by the * running kernel has the same major number and a minor number equal * equal to or less than the filter being downloaded. Otherwise, the * results are undefined, meaning an error may be returned or packets * may be accepted haphazardly. * It has nothing to do with the source code version. */ struct bpf_version { u_short bv_major; u_short bv_minor; }; /* Current version number of filter architecture. */ #define BPF_MAJOR_VERSION 1 #define BPF_MINOR_VERSION 1 /* * BPF ioctls * * The first set is for compatibility with Sun's pcc style * header files. If your using gcc, we assume that you * have run fixincludes so the latter set should work. */ #if (defined(sun) || defined(ibm032)) && !defined(__GNUC__) #define BIOCGBLEN _IOR(B,102, u_int) #define BIOCSBLEN _IOWR(B,102, u_int) #define BIOCSETF _IOW(B,103, struct bpf_program) #define BIOCFLUSH _IO(B,104) #define BIOCPROMISC _IO(B,105) #define BIOCGDLT _IOR(B,106, u_int) #define BIOCGETIF _IOR(B,107, struct ifreq) #define BIOCSETIF _IOW(B,108, struct ifreq) #define BIOCSRTIMEOUT _IOW(B,109, struct timeval) #define BIOCGRTIMEOUT _IOR(B,110, struct timeval) #define BIOCGSTATS _IOR(B,111, struct bpf_stat) #define BIOCIMMEDIATE _IOW(B,112, u_int) #define BIOCVERSION _IOR(B,113, struct bpf_version) #define BIOCSTCPF _IOW(B,114, struct bpf_program) #define BIOCSUDPF _IOW(B,115, struct bpf_program) #else #define BIOCGBLEN _IOR('B',102, u_int) #define BIOCSBLEN _IOWR('B',102, u_int) #define BIOCSETF _IOW('B',103, struct bpf_program) #define BIOCFLUSH _IO('B',104) #define BIOCPROMISC _IO('B',105) #define BIOCGDLT _IOR('B',106, u_int) #define BIOCGETIF _IOR('B',107, struct ifreq) #define BIOCSETIF _IOW('B',108, struct ifreq) #define BIOCSRTIMEOUT _IOW('B',109, struct timeval) #define BIOCGRTIMEOUT _IOR('B',110, struct timeval) #define BIOCGSTATS _IOR('B',111, struct bpf_stat) #define BIOCIMMEDIATE _IOW('B',112, u_int) #define BIOCVERSION _IOR('B',113, struct bpf_version) #define BIOCSTCPF _IOW('B',114, struct bpf_program) #define BIOCSUDPF _IOW('B',115, struct bpf_program) #endif /* * Structure prepended to each packet. */ struct bpf_hdr { struct timeval bh_tstamp; /* time stamp */ bpf_u_int32 bh_caplen; /* length of captured portion */ bpf_u_int32 bh_datalen; /* original length of packet */ u_short bh_hdrlen; /* length of bpf header (this struct plus alignment padding) */ }; /* * Because the structure above is not a multiple of 4 bytes, some compilers * 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 #define SIZEOF_BPF_HDR 18 #endif /* * Data-link level type codes. */ #define DLT_NULL 0 /* no link-layer encapsulation */ #define DLT_EN10MB 1 /* Ethernet (10Mb) */ #define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ #define DLT_AX25 3 /* Amateur Radio AX.25 */ #define DLT_PRONET 4 /* Proteon ProNET Token Ring */ #define DLT_CHAOS 5 /* Chaos */ #define DLT_IEEE802 6 /* IEEE 802 Networks */ #define DLT_ARCNET 7 /* ARCNET */ #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__ #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 */ /* * The instruction encondings. */ /* instruction classes */ #define BPF_CLASS(code) ((code) & 0x07) #define BPF_LD 0x00 #define BPF_LDX 0x01 #define BPF_ST 0x02 #define BPF_STX 0x03 #define BPF_ALU 0x04 #define BPF_JMP 0x05 #define BPF_RET 0x06 #define BPF_MISC 0x07 /* ld/ldx fields */ #define BPF_SIZE(code) ((code) & 0x18) #define BPF_W 0x00 #define BPF_H 0x08 #define BPF_B 0x10 #define BPF_MODE(code) ((code) & 0xe0) #define BPF_IMM 0x00 #define BPF_ABS 0x20 #define BPF_IND 0x40 #define BPF_MEM 0x60 #define BPF_LEN 0x80 #define BPF_MSH 0xa0 /* alu/jmp fields */ #define BPF_OP(code) ((code) & 0xf0) #define BPF_ADD 0x00 #define BPF_SUB 0x10 #define BPF_MUL 0x20 #define BPF_DIV 0x30 #define BPF_OR 0x40 #define BPF_AND 0x50 #define BPF_LSH 0x60 #define BPF_RSH 0x70 #define BPF_NEG 0x80 #define BPF_JA 0x00 #define BPF_JEQ 0x10 #define BPF_JGT 0x20 #define BPF_JGE 0x30 #define BPF_JSET 0x40 #define BPF_SRC(code) ((code) & 0x08) #define BPF_K 0x00 #define BPF_X 0x08 /* ret - BPF_K and BPF_X also apply */ #define BPF_RVAL(code) ((code) & 0x18) #define BPF_A 0x10 /* misc */ #define BPF_MISCOP(code) ((code) & 0xf8) #define BPF_TAX 0x00 #define BPF_TXA 0x80 /* * The instruction data structure. */ struct bpf_insn { u_short code; u_char jt; u_char jf; bpf_int32 k; }; /* * Macros for insn array initializers. */ #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(); extern void bpf_tap(); extern void bpf_mtap(); #else #if __STDC__ extern u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int); #endif #endif /* * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST). */ #define BPF_MEMWORDS 16 #endif libpcap-0.5/./bpf/net/bpf_filter.c100644 263 461 25111 6777230341 15467 0ustar mcrtcpdump/*- * 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. * * @(#)bpf.c 7.5 (Berkeley) 7/15/91 */ #if !(defined(lint) || 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)"; #endif #include #include #include #include #ifndef KERNEL #include #endif #define int32 bpf_int32 #define u_int32 bpf_u_int32 #ifndef LBL_ALIGN #if defined(sparc) || defined(mips) || defined(ibm032) || \ defined(__alpha) || defined(__hpux) #define LBL_ALIGN #endif #endif #ifndef LBL_ALIGN #include #define EXTRACT_SHORT(p) ((u_short)ntohs(*(u_short *)p)) #define EXTRACT_LONG(p) (ntohl(*(u_int32 *)p)) #else #define EXTRACT_SHORT(p)\ ((u_short)\ ((u_short)*((u_char *)p+0)<<8|\ (u_short)*((u_char *)p+1)<<0)) #define EXTRACT_LONG(p)\ ((u_int32)*((u_char *)p+0)<<24|\ (u_int32)*((u_char *)p+1)<<16|\ (u_int32)*((u_char *)p+2)<<8|\ (u_int32)*((u_char *)p+3)<<0) #endif #ifdef KERNEL #include #define MINDEX(len, m, k) \ { \ len = m->m_len; \ while (k >= len) { \ k -= len; \ m = m->m_next; \ if (m == 0) \ return 0; \ len = m->m_len; \ } \ } static int m_xword(m, k, err) register struct mbuf *m; register int k, *err; { register int len; register u_char *cp, *np; register struct mbuf *m0; MINDEX(len, m, k); cp = mtod(m, u_char *) + k; if (len - k >= 4) { *err = 0; return EXTRACT_LONG(cp); } m0 = m->m_next; if (m0 == 0 || m0->m_len + len - k < 4) goto bad; *err = 0; np = mtod(m0, u_char *); switch (len - k) { case 1: return (cp[0] << 24) | (np[0] << 16) | (np[1] << 8) | np[2]; case 2: return (cp[0] << 24) | (cp[1] << 16) | (np[0] << 8) | np[1]; default: return (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | np[0]; } bad: *err = 1; return 0; } static int m_xhalf(m, k, err) register struct mbuf *m; register int k, *err; { register int len; register u_char *cp; register struct mbuf *m0; MINDEX(len, m, k); cp = mtod(m, u_char *) + k; if (len - k >= 2) { *err = 0; return EXTRACT_SHORT(cp); } m0 = m->m_next; if (m0 == 0) goto bad; *err = 0; return (cp[0] << 8) | mtod(m0, u_char *)[0]; bad: *err = 1; return 0; } #endif /* * 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 */ u_int bpf_filter(pc, p, wirelen, buflen) register struct bpf_insn *pc; register u_char *p; u_int wirelen; register u_int buflen; { register u_int32 A, X; register int k; int32 mem[BPF_MEMWORDS]; if (pc == 0) /* * No filter means accept all. */ return (u_int)-1; A = 0; X = 0; --pc; while (1) { ++pc; switch (pc->code) { default: #ifdef KERNEL return 0; #else abort(); #endif case BPF_RET|BPF_K: return (u_int)pc->k; case BPF_RET|BPF_A: return (u_int)A; case BPF_LD|BPF_W|BPF_ABS: k = pc->k; if (k + sizeof(int32) > buflen) { #ifdef KERNEL int merr; if (buflen != 0) return 0; A = m_xword((struct mbuf *)p, k, &merr); if (merr != 0) return 0; continue; #else return 0; #endif } A = EXTRACT_LONG(&p[k]); continue; case BPF_LD|BPF_H|BPF_ABS: k = pc->k; if (k + sizeof(short) > buflen) { #ifdef KERNEL int merr; if (buflen != 0) return 0; A = m_xhalf((struct mbuf *)p, k, &merr); continue; #else return 0; #endif } A = EXTRACT_SHORT(&p[k]); continue; 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) return 0; m = (struct mbuf *)p; MINDEX(len, m, k); A = mtod(m, u_char *)[k]; continue; #else return 0; #endif } A = p[k]; continue; case BPF_LD|BPF_W|BPF_LEN: A = wirelen; continue; case BPF_LDX|BPF_W|BPF_LEN: X = wirelen; continue; case BPF_LD|BPF_W|BPF_IND: k = X + pc->k; if (k + sizeof(int32) > buflen) { #ifdef KERNEL int merr; if (buflen != 0) return 0; A = m_xword((struct mbuf *)p, k, &merr); if (merr != 0) return 0; continue; #else return 0; #endif } A = EXTRACT_LONG(&p[k]); continue; case BPF_LD|BPF_H|BPF_IND: k = X + pc->k; if (k + sizeof(short) > buflen) { #ifdef KERNEL int merr; if (buflen != 0) return 0; A = m_xhalf((struct mbuf *)p, k, &merr); if (merr != 0) return 0; continue; #else return 0; #endif } A = EXTRACT_SHORT(&p[k]); continue; 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) return 0; m = (struct mbuf *)p; MINDEX(len, m, k); A = mtod(m, u_char *)[k]; continue; #else return 0; #endif } A = p[k]; continue; 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) return 0; m = (struct mbuf *)p; MINDEX(len, m, k); X = (mtod(m, char *)[k] & 0xf) << 2; continue; #else return 0; #endif } X = (p[pc->k] & 0xf) << 2; continue; case BPF_LD|BPF_IMM: A = pc->k; continue; case BPF_LDX|BPF_IMM: X = pc->k; continue; case BPF_LD|BPF_MEM: A = mem[pc->k]; continue; case BPF_LDX|BPF_MEM: X = mem[pc->k]; continue; case BPF_ST: mem[pc->k] = A; continue; case BPF_STX: mem[pc->k] = X; continue; case BPF_JMP|BPF_JA: pc += pc->k; continue; case BPF_JMP|BPF_JGT|BPF_K: pc += (A > pc->k) ? pc->jt : pc->jf; continue; case BPF_JMP|BPF_JGE|BPF_K: pc += (A >= pc->k) ? pc->jt : pc->jf; continue; case BPF_JMP|BPF_JEQ|BPF_K: pc += (A == pc->k) ? pc->jt : pc->jf; continue; case BPF_JMP|BPF_JSET|BPF_K: pc += (A & pc->k) ? pc->jt : pc->jf; continue; case BPF_JMP|BPF_JGT|BPF_X: pc += (A > X) ? pc->jt : pc->jf; continue; case BPF_JMP|BPF_JGE|BPF_X: pc += (A >= X) ? pc->jt : pc->jf; continue; case BPF_JMP|BPF_JEQ|BPF_X: pc += (A == X) ? pc->jt : pc->jf; continue; case BPF_JMP|BPF_JSET|BPF_X: pc += (A & X) ? pc->jt : pc->jf; continue; case BPF_ALU|BPF_ADD|BPF_X: A += X; continue; case BPF_ALU|BPF_SUB|BPF_X: A -= X; continue; case BPF_ALU|BPF_MUL|BPF_X: A *= X; continue; case BPF_ALU|BPF_DIV|BPF_X: if (X == 0) return 0; A /= X; continue; case BPF_ALU|BPF_AND|BPF_X: A &= X; continue; case BPF_ALU|BPF_OR|BPF_X: A |= X; continue; case BPF_ALU|BPF_LSH|BPF_X: A <<= X; continue; case BPF_ALU|BPF_RSH|BPF_X: A >>= X; continue; case BPF_ALU|BPF_ADD|BPF_K: A += pc->k; continue; case BPF_ALU|BPF_SUB|BPF_K: A -= pc->k; continue; case BPF_ALU|BPF_MUL|BPF_K: A *= pc->k; continue; case BPF_ALU|BPF_DIV|BPF_K: A /= pc->k; continue; case BPF_ALU|BPF_AND|BPF_K: A &= pc->k; continue; case BPF_ALU|BPF_OR|BPF_K: A |= pc->k; continue; case BPF_ALU|BPF_LSH|BPF_K: A <<= pc->k; continue; case BPF_ALU|BPF_RSH|BPF_K: A >>= pc->k; continue; case BPF_ALU|BPF_NEG: A = -A; continue; case BPF_MISC|BPF_TAX: X = A; continue; case BPF_MISC|BPF_TXA: A = X; continue; } } } #ifdef KERNEL /* * Return true if the 'fcode' is a valid filter program. * The constraints are that each jump be forward and to a valid * code. The code must terminate with either an accept or reject. * 'valid' is an array for use by the routine (it must be at least * 'len' bytes long). * * The kernel needs to be able to verify an application's filter code. * Otherwise, a bogus program could easily crash the system. */ int bpf_validate(f, len) struct bpf_insn *f; int len; { register int i; register struct bpf_insn *p; for (i = 0; i < len; ++i) { /* * Check that that jumps are forward, and within * the code block. */ p = &f[i]; if (BPF_CLASS(p->code) == BPF_JMP) { register int from = i + 1; if (BPF_OP(p->code) == BPF_JA) { if (from + p->k >= (unsigned)len) return 0; } else if (from + p->jt >= len || from + p->jf >= len) return 0; } /* * Check that memory operations use valid addresses. */ if ((BPF_CLASS(p->code) == BPF_ST || (BPF_CLASS(p->code) == BPF_LD && (p->code & 0xe0) == BPF_MEM)) && (p->k >= BPF_MEMWORDS || p->k < 0)) return 0; /* * Check for constant division by 0. */ if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0) return 0; } return BPF_CLASS(f[len - 1].code) == BPF_RET; } #endif libpcap-0.5/./optimize.c100644 263 461 123002 7003105706 13661 0ustar mcrtcpdump/* * Copyright (c) 1988, 1989, 1990, 1991, 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. * * Optimization module for tcpdump intermediate representation. */ #ifndef lint static const char rcsid[] = "@(#) $Header: /tcpdump/master/libpcap/optimize.c,v 1.61 1999/10/19 15:18:30 itojun Exp $ (LBL)"; #endif #include #include #include #include #include #include "pcap-int.h" #include "gencode.h" #include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif #ifdef BDEBUG extern int dflag; #endif #define A_ATOM BPF_MEMWORDS #define X_ATOM (BPF_MEMWORDS+1) #define NOP -1 /* * This define is used to represent *both* the accumulator and * x register in use-def computations. * Currently, the use-def code assumes only one definition per instruction. */ #define AX_ATOM N_ATOMS /* * A flag to indicate that further optimization is needed. * Iterative passes are continued until a given pass yields no * branch movement. */ static int done; /* * A block is marked if only if its mark equals the current mark. * Rather than traverse the code array, marking each item, 'cur_mark' is * incremented. This automatically makes each element unmarked. */ static int cur_mark; #define isMarked(p) ((p)->mark == cur_mark) #define unMarkAll() cur_mark += 1 #define Mark(p) ((p)->mark = cur_mark) static void opt_init(struct block *); static void opt_cleanup(void); static void make_marks(struct block *); static void mark_code(struct block *); static void intern_blocks(struct block *); static int eq_slist(struct slist *, struct slist *); static void find_levels_r(struct block *); static void find_levels(struct block *); static void find_dom(struct block *); static void propedom(struct edge *); static void find_edom(struct block *); static void find_closure(struct block *); static int atomuse(struct stmt *); static int atomdef(struct stmt *); static void compute_local_ud(struct block *); static void find_ud(struct block *); static void init_val(void); static int F(int, int, int); static inline void vstore(struct stmt *, int *, int, int); static void opt_blk(struct block *, int); static int use_conflict(struct block *, struct block *); static void opt_j(struct edge *); static void or_pullup(struct block *); static void and_pullup(struct block *); static void opt_blks(struct block *, int); static inline void link_inedge(struct edge *, struct block *); static void find_inedges(struct block *); static void opt_root(struct block **); static void opt_loop(struct block *, int); static void fold_op(struct stmt *, int, int); static inline struct slist *this_op(struct slist *); static void opt_not(struct block *); static void opt_peep(struct block *); static void opt_stmt(struct stmt *, int[], int); static void deadstmt(struct stmt *, struct stmt *[]); static void opt_deadstores(struct block *); static void opt_blk(struct block *, int); static int use_conflict(struct block *, struct block *); static void opt_j(struct edge *); static struct block *fold_edge(struct block *, struct edge *); static inline int eq_blk(struct block *, struct block *); static int slength(struct slist *); static int count_blocks(struct block *); static void number_blks_r(struct block *); static int count_stmts(struct block *); static int convert_code_r(struct block *); #ifdef BDEBUG static void opt_dump(struct block *); #endif static int n_blocks; struct block **blocks; static int n_edges; struct edge **edges; /* * A bit vector set representation of the dominators. * We round up the set size to the next power of two. */ static int nodewords; static int edgewords; struct block **levels; bpf_u_int32 *space; #define BITS_PER_WORD (8*sizeof(bpf_u_int32)) /* * True if a is in uset {p} */ #define SET_MEMBER(p, a) \ ((p)[(unsigned)(a) / BITS_PER_WORD] & (1 << ((unsigned)(a) % BITS_PER_WORD))) /* * Add 'a' to uset p. */ #define SET_INSERT(p, a) \ (p)[(unsigned)(a) / BITS_PER_WORD] |= (1 << ((unsigned)(a) % BITS_PER_WORD)) /* * Delete 'a' from uset p. */ #define SET_DELETE(p, a) \ (p)[(unsigned)(a) / BITS_PER_WORD] &= ~(1 << ((unsigned)(a) % BITS_PER_WORD)) /* * a := a intersect b */ #define SET_INTERSECT(a, b, n)\ {\ register bpf_u_int32 *_x = a, *_y = b;\ register int _n = n;\ while (--_n >= 0) *_x++ &= *_y++;\ } /* * a := a - b */ #define SET_SUBTRACT(a, b, n)\ {\ register bpf_u_int32 *_x = a, *_y = b;\ register int _n = n;\ while (--_n >= 0) *_x++ &=~ *_y++;\ } /* * a := a union b */ #define SET_UNION(a, b, n)\ {\ register bpf_u_int32 *_x = a, *_y = b;\ register int _n = n;\ while (--_n >= 0) *_x++ |= *_y++;\ } static uset all_dom_sets; static uset all_closure_sets; static uset all_edge_sets; #ifndef MAX #define MAX(a,b) ((a)>(b)?(a):(b)) #endif static void find_levels_r(b) struct block *b; { int level; if (isMarked(b)) return; Mark(b); b->link = 0; if (JT(b)) { find_levels_r(JT(b)); find_levels_r(JF(b)); level = MAX(JT(b)->level, JF(b)->level) + 1; } else level = 0; b->level = level; b->link = levels[level]; levels[level] = b; } /* * Level graph. The levels go from 0 at the leaves to * N_LEVELS at the root. The levels[] array points to the * first node of the level list, whose elements are linked * with the 'link' field of the struct block. */ static void find_levels(root) struct block *root; { memset((char *)levels, 0, n_blocks * sizeof(*levels)); unMarkAll(); find_levels_r(root); } /* * Find dominator relationships. * Assumes graph has been leveled. */ static void find_dom(root) struct block *root; { int i; struct block *b; bpf_u_int32 *x; /* * Initialize sets to contain all nodes. */ x = all_dom_sets; i = n_blocks * nodewords; while (--i >= 0) *x++ = ~0; /* Root starts off empty. */ for (i = nodewords; --i >= 0;) root->dom[i] = 0; /* root->level is the highest level no found. */ for (i = root->level; i >= 0; --i) { for (b = levels[i]; b; b = b->link) { SET_INSERT(b->dom, b->id); if (JT(b) == 0) continue; SET_INTERSECT(JT(b)->dom, b->dom, nodewords); SET_INTERSECT(JF(b)->dom, b->dom, nodewords); } } } static void propedom(ep) struct edge *ep; { SET_INSERT(ep->edom, ep->id); if (ep->succ) { SET_INTERSECT(ep->succ->et.edom, ep->edom, edgewords); SET_INTERSECT(ep->succ->ef.edom, ep->edom, edgewords); } } /* * Compute edge dominators. * Assumes graph has been leveled and predecessors established. */ static void find_edom(root) struct block *root; { int i; uset x; struct block *b; x = all_edge_sets; for (i = n_edges * edgewords; --i >= 0; ) x[i] = ~0; /* root->level is the highest level no found. */ memset(root->et.edom, 0, edgewords * sizeof(*(uset)0)); memset(root->ef.edom, 0, edgewords * sizeof(*(uset)0)); for (i = root->level; i >= 0; --i) { for (b = levels[i]; b != 0; b = b->link) { propedom(&b->et); propedom(&b->ef); } } } /* * Find the backwards transitive closure of the flow graph. These sets * are backwards in the sense that we find the set of nodes that reach * a given node, not the set of nodes that can be reached by a node. * * Assumes graph has been leveled. */ static void find_closure(root) struct block *root; { int i; struct block *b; /* * Initialize sets to contain no nodes. */ memset((char *)all_closure_sets, 0, n_blocks * nodewords * sizeof(*all_closure_sets)); /* root->level is the highest level no found. */ for (i = root->level; i >= 0; --i) { for (b = levels[i]; b; b = b->link) { SET_INSERT(b->closure, b->id); if (JT(b) == 0) continue; SET_UNION(JT(b)->closure, b->closure, nodewords); SET_UNION(JF(b)->closure, b->closure, nodewords); } } } /* * Return the register number that is used by s. If A and X are both * used, return AX_ATOM. If no register is used, return -1. * * The implementation should probably change to an array access. */ static int atomuse(s) struct stmt *s; { register int c = s->code; if (c == NOP) return -1; switch (BPF_CLASS(c)) { case BPF_RET: return (BPF_RVAL(c) == BPF_A) ? A_ATOM : (BPF_RVAL(c) == BPF_X) ? X_ATOM : -1; case BPF_LD: case BPF_LDX: return (BPF_MODE(c) == BPF_IND) ? X_ATOM : (BPF_MODE(c) == BPF_MEM) ? s->k : -1; case BPF_ST: return A_ATOM; case BPF_STX: return X_ATOM; case BPF_JMP: case BPF_ALU: if (BPF_SRC(c) == BPF_X) return AX_ATOM; return A_ATOM; case BPF_MISC: return BPF_MISCOP(c) == BPF_TXA ? X_ATOM : A_ATOM; } abort(); /* NOTREACHED */ } /* * Return the register number that is defined by 's'. We assume that * a single stmt cannot define more than one register. If no register * is defined, return -1. * * The implementation should probably change to an array access. */ static int atomdef(s) struct stmt *s; { if (s->code == NOP) return -1; switch (BPF_CLASS(s->code)) { case BPF_LD: case BPF_ALU: return A_ATOM; case BPF_LDX: return X_ATOM; case BPF_ST: case BPF_STX: return s->k; case BPF_MISC: return BPF_MISCOP(s->code) == BPF_TAX ? X_ATOM : A_ATOM; } return -1; } static void compute_local_ud(b) struct block *b; { struct slist *s; atomset def = 0, use = 0, kill = 0; int atom; for (s = b->stmts; s; s = s->next) { if (s->s.code == NOP) continue; atom = atomuse(&s->s); if (atom >= 0) { if (atom == AX_ATOM) { if (!ATOMELEM(def, X_ATOM)) use |= ATOMMASK(X_ATOM); if (!ATOMELEM(def, A_ATOM)) use |= ATOMMASK(A_ATOM); } else if (atom < N_ATOMS) { if (!ATOMELEM(def, atom)) use |= ATOMMASK(atom); } else abort(); } atom = atomdef(&s->s); if (atom >= 0) { if (!ATOMELEM(use, atom)) kill |= ATOMMASK(atom); def |= ATOMMASK(atom); } } if (!ATOMELEM(def, A_ATOM) && BPF_CLASS(b->s.code) == BPF_JMP) use |= ATOMMASK(A_ATOM); b->def = def; b->kill = kill; b->in_use = use; } /* * Assume graph is already leveled. */ static void find_ud(root) struct block *root; { int i, maxlevel; struct block *p; /* * root->level is the highest level no found; * count down from there. */ maxlevel = root->level; for (i = maxlevel; i >= 0; --i) for (p = levels[i]; p; p = p->link) { compute_local_ud(p); p->out_use = 0; } for (i = 1; i <= maxlevel; ++i) { for (p = levels[i]; p; p = p->link) { p->out_use |= JT(p)->in_use | JF(p)->in_use; p->in_use |= p->out_use &~ p->kill; } } } /* * These data structures are used in a Cocke and Shwarz style * value numbering scheme. Since the flowgraph is acyclic, * exit values can be propagated from a node's predecessors * provided it is uniquely defined. */ struct valnode { int code; int v0, v1; int val; struct valnode *next; }; #define MODULUS 213 static struct valnode *hashtbl[MODULUS]; static int curval; static int maxval; /* Integer constants mapped with the load immediate opcode. */ #define K(i) F(BPF_LD|BPF_IMM|BPF_W, i, 0L) struct vmapinfo { int is_const; bpf_int32 const_val; }; struct vmapinfo *vmap; struct valnode *vnode_base; struct valnode *next_vnode; static void init_val() { curval = 0; next_vnode = vnode_base; memset((char *)vmap, 0, maxval * sizeof(*vmap)); memset((char *)hashtbl, 0, sizeof hashtbl); } /* Because we really don't have an IR, this stuff is a little messy. */ static int F(code, v0, v1) int code; int v0, v1; { u_int hash; int val; struct valnode *p; hash = (u_int)code ^ (v0 << 4) ^ (v1 << 8); hash %= MODULUS; for (p = hashtbl[hash]; p; p = p->next) if (p->code == code && p->v0 == v0 && p->v1 == v1) return p->val; val = ++curval; if (BPF_MODE(code) == BPF_IMM && (BPF_CLASS(code) == BPF_LD || BPF_CLASS(code) == BPF_LDX)) { vmap[val].const_val = v0; vmap[val].is_const = 1; } p = next_vnode++; p->val = val; p->code = code; p->v0 = v0; p->v1 = v1; p->next = hashtbl[hash]; hashtbl[hash] = p; return val; } static inline void vstore(s, valp, newval, alter) struct stmt *s; int *valp; int newval; int alter; { if (alter && *valp == newval) s->code = NOP; else *valp = newval; } static void fold_op(s, v0, v1) struct stmt *s; int v0, v1; { bpf_int32 a, b; a = vmap[v0].const_val; b = vmap[v1].const_val; switch (BPF_OP(s->code)) { case BPF_ADD: a += b; break; case BPF_SUB: a -= b; break; case BPF_MUL: a *= b; break; case BPF_DIV: if (b == 0) bpf_error("division by zero"); a /= b; break; case BPF_AND: a &= b; break; case BPF_OR: a |= b; break; case BPF_LSH: a <<= b; break; case BPF_RSH: a >>= b; break; case BPF_NEG: a = -a; break; default: abort(); } s->k = a; s->code = BPF_LD|BPF_IMM; done = 0; } static inline struct slist * this_op(s) struct slist *s; { while (s != 0 && s->s.code == NOP) s = s->next; return s; } static void opt_not(b) struct block *b; { struct block *tmp = JT(b); JT(b) = JF(b); JF(b) = tmp; } static void opt_peep(b) struct block *b; { struct slist *s; struct slist *next, *last; int val; s = b->stmts; if (s == 0) return; last = s; while (1) { s = this_op(s); if (s == 0) break; next = this_op(s->next); if (next == 0) break; last = next; /* * st M[k] --> st M[k] * ldx M[k] tax */ if (s->s.code == BPF_ST && next->s.code == (BPF_LDX|BPF_MEM) && s->s.k == next->s.k) { done = 0; next->s.code = BPF_MISC|BPF_TAX; } /* * ld #k --> ldx #k * tax txa */ if (s->s.code == (BPF_LD|BPF_IMM) && next->s.code == (BPF_MISC|BPF_TAX)) { s->s.code = BPF_LDX|BPF_IMM; next->s.code = BPF_MISC|BPF_TXA; done = 0; } /* * This is an ugly special case, but it happens * when you say tcp[k] or udp[k] where k is a constant. */ if (s->s.code == (BPF_LD|BPF_IMM)) { struct slist *add, *tax, *ild; /* * Check that X isn't used on exit from this * block (which the optimizer might cause). * We know the code generator won't generate * any local dependencies. */ if (ATOMELEM(b->out_use, X_ATOM)) break; if (next->s.code != (BPF_LDX|BPF_MSH|BPF_B)) add = next; else add = this_op(next->next); if (add == 0 || add->s.code != (BPF_ALU|BPF_ADD|BPF_X)) break; tax = this_op(add->next); if (tax == 0 || tax->s.code != (BPF_MISC|BPF_TAX)) break; ild = this_op(tax->next); if (ild == 0 || BPF_CLASS(ild->s.code) != BPF_LD || BPF_MODE(ild->s.code) != BPF_IND) break; /* * XXX We need to check that X is not * subsequently used. We know we can eliminate the * accumulator modifications since it is defined * by the last stmt of this sequence. * * We want to turn this sequence: * * (004) ldi #0x2 {s} * (005) ldxms [14] {next} -- optional * (006) addx {add} * (007) tax {tax} * (008) ild [x+0] {ild} * * into this sequence: * * (004) nop * (005) ldxms [14] * (006) nop * (007) nop * (008) ild [x+2] * */ ild->s.k += s->s.k; s->s.code = NOP; add->s.code = NOP; tax->s.code = NOP; done = 0; } s = next; } /* * If we have a subtract to do a comparison, and the X register * is a known constant, we can merge this value into the * comparison. */ if (last->s.code == (BPF_ALU|BPF_SUB|BPF_X) && !ATOMELEM(b->out_use, A_ATOM)) { val = b->val[X_ATOM]; if (vmap[val].is_const) { int op; b->s.k += vmap[val].const_val; op = BPF_OP(b->s.code); if (op == BPF_JGT || op == BPF_JGE) { struct block *t = JT(b); JT(b) = JF(b); JF(b) = t; b->s.k += 0x80000000; } last->s.code = NOP; done = 0; } else if (b->s.k == 0) { /* * sub x -> nop * j #0 j x */ last->s.code = NOP; b->s.code = BPF_CLASS(b->s.code) | BPF_OP(b->s.code) | BPF_X; done = 0; } } /* * Likewise, a constant subtract can be simplified. */ else if (last->s.code == (BPF_ALU|BPF_SUB|BPF_K) && !ATOMELEM(b->out_use, A_ATOM)) { int op; b->s.k += last->s.k; last->s.code = NOP; op = BPF_OP(b->s.code); if (op == BPF_JGT || op == BPF_JGE) { struct block *t = JT(b); JT(b) = JF(b); JF(b) = t; b->s.k += 0x80000000; } done = 0; } /* * and #k nop * jeq #0 -> jset #k */ if (last->s.code == (BPF_ALU|BPF_AND|BPF_K) && !ATOMELEM(b->out_use, A_ATOM) && b->s.k == 0) { b->s.k = last->s.k; b->s.code = BPF_JMP|BPF_K|BPF_JSET; last->s.code = NOP; done = 0; opt_not(b); } /* * If the accumulator is a known constant, we can compute the * comparison result. */ val = b->val[A_ATOM]; if (vmap[val].is_const && BPF_SRC(b->s.code) == BPF_K) { bpf_int32 v = vmap[val].const_val; switch (BPF_OP(b->s.code)) { case BPF_JEQ: v = v == b->s.k; break; case BPF_JGT: v = (unsigned)v > b->s.k; break; case BPF_JGE: v = (unsigned)v >= b->s.k; break; case BPF_JSET: v &= b->s.k; break; default: abort(); } if (JF(b) != JT(b)) done = 0; if (v) JF(b) = JT(b); else JT(b) = JF(b); } } /* * Compute the symbolic value of expression of 's', and update * anything it defines in the value table 'val'. If 'alter' is true, * do various optimizations. This code would be cleaner if symbolic * evaluation and code transformations weren't folded together. */ static void opt_stmt(s, val, alter) struct stmt *s; int val[]; int alter; { int op; int v; switch (s->code) { case BPF_LD|BPF_ABS|BPF_W: case BPF_LD|BPF_ABS|BPF_H: case BPF_LD|BPF_ABS|BPF_B: v = F(s->code, s->k, 0L); vstore(s, &val[A_ATOM], v, alter); break; case BPF_LD|BPF_IND|BPF_W: case BPF_LD|BPF_IND|BPF_H: case BPF_LD|BPF_IND|BPF_B: v = val[X_ATOM]; if (alter && vmap[v].is_const) { s->code = BPF_LD|BPF_ABS|BPF_SIZE(s->code); s->k += vmap[v].const_val; v = F(s->code, s->k, 0L); done = 0; } else v = F(s->code, s->k, v); vstore(s, &val[A_ATOM], v, alter); break; case BPF_LD|BPF_LEN: v = F(s->code, 0L, 0L); vstore(s, &val[A_ATOM], v, alter); break; case BPF_LD|BPF_IMM: v = K(s->k); vstore(s, &val[A_ATOM], v, alter); break; case BPF_LDX|BPF_IMM: v = K(s->k); vstore(s, &val[X_ATOM], v, alter); break; case BPF_LDX|BPF_MSH|BPF_B: v = F(s->code, s->k, 0L); vstore(s, &val[X_ATOM], v, alter); break; case BPF_ALU|BPF_NEG: if (alter && vmap[val[A_ATOM]].is_const) { s->code = BPF_LD|BPF_IMM; s->k = -vmap[val[A_ATOM]].const_val; val[A_ATOM] = K(s->k); } else val[A_ATOM] = F(s->code, val[A_ATOM], 0L); break; case BPF_ALU|BPF_ADD|BPF_K: case BPF_ALU|BPF_SUB|BPF_K: case BPF_ALU|BPF_MUL|BPF_K: case BPF_ALU|BPF_DIV|BPF_K: case BPF_ALU|BPF_AND|BPF_K: case BPF_ALU|BPF_OR|BPF_K: case BPF_ALU|BPF_LSH|BPF_K: case BPF_ALU|BPF_RSH|BPF_K: op = BPF_OP(s->code); if (alter) { if (s->k == 0) { if (op == BPF_ADD || op == BPF_SUB || op == BPF_LSH || op == BPF_RSH || op == BPF_OR) { s->code = NOP; break; } if (op == BPF_MUL || op == BPF_AND) { s->code = BPF_LD|BPF_IMM; val[A_ATOM] = K(s->k); break; } } if (vmap[val[A_ATOM]].is_const) { fold_op(s, val[A_ATOM], K(s->k)); val[A_ATOM] = K(s->k); break; } } val[A_ATOM] = F(s->code, val[A_ATOM], K(s->k)); break; case BPF_ALU|BPF_ADD|BPF_X: case BPF_ALU|BPF_SUB|BPF_X: case BPF_ALU|BPF_MUL|BPF_X: case BPF_ALU|BPF_DIV|BPF_X: case BPF_ALU|BPF_AND|BPF_X: case BPF_ALU|BPF_OR|BPF_X: case BPF_ALU|BPF_LSH|BPF_X: case BPF_ALU|BPF_RSH|BPF_X: op = BPF_OP(s->code); if (alter && vmap[val[X_ATOM]].is_const) { if (vmap[val[A_ATOM]].is_const) { fold_op(s, val[A_ATOM], val[X_ATOM]); val[A_ATOM] = K(s->k); } else { s->code = BPF_ALU|BPF_K|op; s->k = vmap[val[X_ATOM]].const_val; done = 0; val[A_ATOM] = F(s->code, val[A_ATOM], K(s->k)); } break; } /* * Check if we're doing something to an accumulator * that is 0, and simplify. This may not seem like * much of a simplification but it could open up further * optimizations. * XXX We could also check for mul by 1, and -1, etc. */ if (alter && vmap[val[A_ATOM]].is_const && vmap[val[A_ATOM]].const_val == 0) { if (op == BPF_ADD || op == BPF_OR || op == BPF_LSH || op == BPF_RSH || op == BPF_SUB) { s->code = BPF_MISC|BPF_TXA; vstore(s, &val[A_ATOM], val[X_ATOM], alter); break; } else if (op == BPF_MUL || op == BPF_DIV || op == BPF_AND) { s->code = BPF_LD|BPF_IMM; s->k = 0; vstore(s, &val[A_ATOM], K(s->k), alter); break; } else if (op == BPF_NEG) { s->code = NOP; break; } } val[A_ATOM] = F(s->code, val[A_ATOM], val[X_ATOM]); break; case BPF_MISC|BPF_TXA: vstore(s, &val[A_ATOM], val[X_ATOM], alter); break; case BPF_LD|BPF_MEM: v = val[s->k]; if (alter && vmap[v].is_const) { s->code = BPF_LD|BPF_IMM; s->k = vmap[v].const_val; done = 0; } vstore(s, &val[A_ATOM], v, alter); break; case BPF_MISC|BPF_TAX: vstore(s, &val[X_ATOM], val[A_ATOM], alter); break; case BPF_LDX|BPF_MEM: v = val[s->k]; if (alter && vmap[v].is_const) { s->code = BPF_LDX|BPF_IMM; s->k = vmap[v].const_val; done = 0; } vstore(s, &val[X_ATOM], v, alter); break; case BPF_ST: vstore(s, &val[s->k], val[A_ATOM], alter); break; case BPF_STX: vstore(s, &val[s->k], val[X_ATOM], alter); break; } } static void deadstmt(s, last) register struct stmt *s; register struct stmt *last[]; { register int atom; atom = atomuse(s); if (atom >= 0) { if (atom == AX_ATOM) { last[X_ATOM] = 0; last[A_ATOM] = 0; } else last[atom] = 0; } atom = atomdef(s); if (atom >= 0) { if (last[atom]) { done = 0; last[atom]->code = NOP; } last[atom] = s; } } static void opt_deadstores(b) register struct block *b; { register struct slist *s; register int atom; struct stmt *last[N_ATOMS]; memset((char *)last, 0, sizeof last); for (s = b->stmts; s != 0; s = s->next) deadstmt(&s->s, last); deadstmt(&b->s, last); for (atom = 0; atom < N_ATOMS; ++atom) if (last[atom] && !ATOMELEM(b->out_use, atom)) { last[atom]->code = NOP; done = 0; } } static void opt_blk(b, do_stmts) struct block *b; int do_stmts; { struct slist *s; struct edge *p; int i; bpf_int32 aval; #if 0 for (s = b->stmts; s && s->next; s = s->next) if (BPF_CLASS(s->s.code) == BPF_JMP) { do_stmts = 0; break; } #endif /* * Initialize the atom values. * If we have no predecessors, everything is undefined. * Otherwise, we inherent our values from our predecessors. * If any register has an ambiguous value (i.e. control paths are * merging) give it the undefined value of 0. */ p = b->in_edges; if (p == 0) memset((char *)b->val, 0, sizeof(b->val)); else { memcpy((char *)b->val, (char *)p->pred->val, sizeof(b->val)); while ((p = p->next) != NULL) { for (i = 0; i < N_ATOMS; ++i) if (b->val[i] != p->pred->val[i]) b->val[i] = 0; } } aval = b->val[A_ATOM]; for (s = b->stmts; s; s = s->next) opt_stmt(&s->s, b->val, do_stmts); /* * This is a special case: if we don't use anything from this * block, and we load the accumulator with value that is * already there, or if this block is a return, * eliminate all the statements. */ if (do_stmts && ((b->out_use == 0 && aval != 0 &&b->val[A_ATOM] == aval) || BPF_CLASS(b->s.code) == BPF_RET)) { if (b->stmts != 0) { b->stmts = 0; done = 0; } } else { opt_peep(b); opt_deadstores(b); } /* * Set up values for branch optimizer. */ if (BPF_SRC(b->s.code) == BPF_K) b->oval = K(b->s.k); else b->oval = b->val[X_ATOM]; b->et.code = b->s.code; b->ef.code = -b->s.code; } /* * Return true if any register that is used on exit from 'succ', has * an exit value that is different from the corresponding exit value * from 'b'. */ static int use_conflict(b, succ) struct block *b, *succ; { int atom; atomset use = succ->out_use; if (use == 0) return 0; for (atom = 0; atom < N_ATOMS; ++atom) if (ATOMELEM(use, atom)) if (b->val[atom] != succ->val[atom]) return 1; return 0; } static struct block * fold_edge(child, ep) struct block *child; struct edge *ep; { int sense; int aval0, aval1, oval0, oval1; int code = ep->code; if (code < 0) { code = -code; sense = 0; } else sense = 1; if (child->s.code != code) return 0; aval0 = child->val[A_ATOM]; oval0 = child->oval; aval1 = ep->pred->val[A_ATOM]; oval1 = ep->pred->oval; if (aval0 != aval1) return 0; if (oval0 == oval1) /* * The operands are identical, so the * result is true if a true branch was * taken to get here, otherwise false. */ return sense ? JT(child) : JF(child); if (sense && code == (BPF_JMP|BPF_JEQ|BPF_K)) /* * At this point, we only know the comparison if we * came down the true branch, and it was an equality * comparison with a constant. We rely on the fact that * distinct constants have distinct value numbers. */ return JF(child); return 0; } static void opt_j(ep) struct edge *ep; { register int i, k; register struct block *target; if (JT(ep->succ) == 0) return; if (JT(ep->succ) == JF(ep->succ)) { /* * Common branch targets can be eliminated, provided * there is no data dependency. */ if (!use_conflict(ep->pred, ep->succ->et.succ)) { done = 0; ep->succ = JT(ep->succ); } } /* * For each edge dominator that matches the successor of this * edge, promote the edge successor to the its grandchild. * * XXX We violate the set abstraction here in favor a reasonably * efficient loop. */ top: for (i = 0; i < edgewords; ++i) { register bpf_u_int32 x = ep->edom[i]; while (x != 0) { k = ffs(x) - 1; x &=~ (1 << k); k += i * BITS_PER_WORD; target = fold_edge(ep->succ, edges[k]); /* * Check that there is no data dependency between * nodes that will be violated if we move the edge. */ if (target != 0 && !use_conflict(ep->pred, target)) { done = 0; ep->succ = target; if (JT(target) != 0) /* * Start over unless we hit a leaf. */ goto top; return; } } } } static void or_pullup(b) struct block *b; { int val, at_top; struct block *pull; struct block **diffp, **samep; struct edge *ep; ep = b->in_edges; if (ep == 0) return; /* * Make sure each predecessor loads the same value. * XXX why? */ val = ep->pred->val[A_ATOM]; for (ep = ep->next; ep != 0; ep = ep->next) if (val != ep->pred->val[A_ATOM]) return; if (JT(b->in_edges->pred) == b) diffp = &JT(b->in_edges->pred); else diffp = &JF(b->in_edges->pred); at_top = 1; while (1) { if (*diffp == 0) return; if (JT(*diffp) != JT(b)) return; if (!SET_MEMBER((*diffp)->dom, b->id)) return; if ((*diffp)->val[A_ATOM] != val) break; diffp = &JF(*diffp); at_top = 0; } samep = &JF(*diffp); while (1) { if (*samep == 0) return; if (JT(*samep) != JT(b)) return; if (!SET_MEMBER((*samep)->dom, b->id)) return; if ((*samep)->val[A_ATOM] == val) break; /* XXX Need to check that there are no data dependencies between dp0 and dp1. Currently, the code generator will not produce such dependencies. */ samep = &JF(*samep); } #ifdef notdef /* XXX This doesn't cover everything. */ for (i = 0; i < N_ATOMS; ++i) if ((*samep)->val[i] != pred->val[i]) return; #endif /* Pull up the node. */ pull = *samep; *samep = JF(pull); JF(pull) = *diffp; /* * At the top of the chain, each predecessor needs to point at the * pulled up node. Inside the chain, there is only one predecessor * to worry about. */ if (at_top) { for (ep = b->in_edges; ep != 0; ep = ep->next) { if (JT(ep->pred) == b) JT(ep->pred) = pull; else JF(ep->pred) = pull; } } else *diffp = pull; done = 0; } static void and_pullup(b) struct block *b; { int val, at_top; struct block *pull; struct block **diffp, **samep; struct edge *ep; ep = b->in_edges; if (ep == 0) return; /* * Make sure each predecessor loads the same value. */ val = ep->pred->val[A_ATOM]; for (ep = ep->next; ep != 0; ep = ep->next) if (val != ep->pred->val[A_ATOM]) return; if (JT(b->in_edges->pred) == b) diffp = &JT(b->in_edges->pred); else diffp = &JF(b->in_edges->pred); at_top = 1; while (1) { if (*diffp == 0) return; if (JF(*diffp) != JF(b)) return; if (!SET_MEMBER((*diffp)->dom, b->id)) return; if ((*diffp)->val[A_ATOM] != val) break; diffp = &JT(*diffp); at_top = 0; } samep = &JT(*diffp); while (1) { if (*samep == 0) return; if (JF(*samep) != JF(b)) return; if (!SET_MEMBER((*samep)->dom, b->id)) return; if ((*samep)->val[A_ATOM] == val) break; /* XXX Need to check that there are no data dependencies between diffp and samep. Currently, the code generator will not produce such dependencies. */ samep = &JT(*samep); } #ifdef notdef /* XXX This doesn't cover everything. */ for (i = 0; i < N_ATOMS; ++i) if ((*samep)->val[i] != pred->val[i]) return; #endif /* Pull up the node. */ pull = *samep; *samep = JT(pull); JT(pull) = *diffp; /* * At the top of the chain, each predecessor needs to point at the * pulled up node. Inside the chain, there is only one predecessor * to worry about. */ if (at_top) { for (ep = b->in_edges; ep != 0; ep = ep->next) { if (JT(ep->pred) == b) JT(ep->pred) = pull; else JF(ep->pred) = pull; } } else *diffp = pull; done = 0; } static void opt_blks(root, do_stmts) struct block *root; int do_stmts; { int i, maxlevel; struct block *p; init_val(); maxlevel = root->level; for (i = maxlevel; i >= 0; --i) for (p = levels[i]; p; p = p->link) opt_blk(p, do_stmts); if (do_stmts) /* * No point trying to move branches; it can't possibly * make a difference at this point. */ return; for (i = 1; i <= maxlevel; ++i) { for (p = levels[i]; p; p = p->link) { opt_j(&p->et); opt_j(&p->ef); } } for (i = 1; i <= maxlevel; ++i) { for (p = levels[i]; p; p = p->link) { or_pullup(p); and_pullup(p); } } } static inline void link_inedge(parent, child) struct edge *parent; struct block *child; { parent->next = child->in_edges; child->in_edges = parent; } static void find_inedges(root) struct block *root; { int i; struct block *b; for (i = 0; i < n_blocks; ++i) blocks[i]->in_edges = 0; /* * Traverse the graph, adding each edge to the predecessor * list of its successors. Skip the leaves (i.e. level 0). */ for (i = root->level; i > 0; --i) { for (b = levels[i]; b != 0; b = b->link) { link_inedge(&b->et, JT(b)); link_inedge(&b->ef, JF(b)); } } } static void opt_root(b) struct block **b; { struct slist *tmp, *s; s = (*b)->stmts; (*b)->stmts = 0; while (BPF_CLASS((*b)->s.code) == BPF_JMP && JT(*b) == JF(*b)) *b = JT(*b); tmp = (*b)->stmts; if (tmp != 0) sappend(s, tmp); (*b)->stmts = s; /* * If the root node is a return, then there is no * point executing any statements (since the bpf machine * has no side effects). */ if (BPF_CLASS((*b)->s.code) == BPF_RET) (*b)->stmts = 0; } static void opt_loop(root, do_stmts) struct block *root; int do_stmts; { #ifdef BDEBUG if (dflag > 1) opt_dump(root); #endif do { done = 1; find_levels(root); find_dom(root); find_closure(root); find_inedges(root); find_ud(root); find_edom(root); opt_blks(root, do_stmts); #ifdef BDEBUG if (dflag > 1) opt_dump(root); #endif } while (!done); } /* * Optimize the filter code in its dag representation. */ void bpf_optimize(rootp) struct block **rootp; { struct block *root; root = *rootp; opt_init(root); opt_loop(root, 0); opt_loop(root, 1); intern_blocks(root); opt_root(rootp); opt_cleanup(); } static void make_marks(p) struct block *p; { if (!isMarked(p)) { Mark(p); if (BPF_CLASS(p->s.code) != BPF_RET) { make_marks(JT(p)); make_marks(JF(p)); } } } /* * Mark code array such that isMarked(i) is true * only for nodes that are alive. */ static void mark_code(p) struct block *p; { cur_mark += 1; make_marks(p); } /* * True iff the two stmt lists load the same value from the packet into * the accumulator. */ static int eq_slist(x, y) struct slist *x, *y; { while (1) { while (x && x->s.code == NOP) x = x->next; while (y && y->s.code == NOP) y = y->next; if (x == 0) return y == 0; if (y == 0) return x == 0; if (x->s.code != y->s.code || x->s.k != y->s.k) return 0; x = x->next; y = y->next; } } static inline int eq_blk(b0, b1) struct block *b0, *b1; { if (b0->s.code == b1->s.code && b0->s.k == b1->s.k && b0->et.succ == b1->et.succ && b0->ef.succ == b1->ef.succ) return eq_slist(b0->stmts, b1->stmts); return 0; } static void intern_blocks(root) struct block *root; { struct block *p; int i, j; int done; top: done = 1; for (i = 0; i < n_blocks; ++i) blocks[i]->link = 0; mark_code(root); for (i = n_blocks - 1; --i >= 0; ) { if (!isMarked(blocks[i])) continue; for (j = i + 1; j < n_blocks; ++j) { if (!isMarked(blocks[j])) continue; if (eq_blk(blocks[i], blocks[j])) { blocks[i]->link = blocks[j]->link ? blocks[j]->link : blocks[j]; break; } } } for (i = 0; i < n_blocks; ++i) { p = blocks[i]; if (JT(p) == 0) continue; if (JT(p)->link) { done = 0; JT(p) = JT(p)->link; } if (JF(p)->link) { done = 0; JF(p) = JF(p)->link; } } if (!done) goto top; } static void opt_cleanup() { free((void *)vnode_base); free((void *)vmap); free((void *)edges); free((void *)space); free((void *)levels); free((void *)blocks); } /* * Return the number of stmts in 's'. */ static int slength(s) struct slist *s; { int n = 0; for (; s; s = s->next) if (s->s.code != NOP) ++n; return n; } /* * Return the number of nodes reachable by 'p'. * All nodes should be initially unmarked. */ static int count_blocks(p) struct block *p; { if (p == 0 || isMarked(p)) return 0; Mark(p); return count_blocks(JT(p)) + count_blocks(JF(p)) + 1; } /* * Do a depth first search on the flow graph, numbering the * the basic blocks, and entering them into the 'blocks' array.` */ static void number_blks_r(p) struct block *p; { int n; if (p == 0 || isMarked(p)) return; Mark(p); n = n_blocks++; p->id = n; blocks[n] = p; number_blks_r(JT(p)); number_blks_r(JF(p)); } /* * Return the number of stmts in the flowgraph reachable by 'p'. * The nodes should be unmarked before calling. */ static int count_stmts(p) struct block *p; { int n; if (p == 0 || isMarked(p)) return 0; Mark(p); n = count_stmts(JT(p)) + count_stmts(JF(p)); return slength(p->stmts) + n + 1; } /* * Allocate memory. All allocation is done before optimization * is begun. A linear bound on the size of all data structures is computed * from the total number of blocks and/or statements. */ static void opt_init(root) struct block *root; { bpf_u_int32 *p; int i, n, max_stmts; /* * First, count the blocks, so we can malloc an array to map * block number to block. Then, put the blocks into the array. */ unMarkAll(); n = count_blocks(root); blocks = (struct block **)malloc(n * sizeof(*blocks)); unMarkAll(); n_blocks = 0; number_blks_r(root); n_edges = 2 * n_blocks; edges = (struct edge **)malloc(n_edges * sizeof(*edges)); /* * The number of levels is bounded by the number of nodes. */ levels = (struct block **)malloc(n_blocks * sizeof(*levels)); edgewords = n_edges / (8 * sizeof(bpf_u_int32)) + 1; nodewords = n_blocks / (8 * sizeof(bpf_u_int32)) + 1; /* XXX */ space = (bpf_u_int32 *)malloc(2 * n_blocks * nodewords * sizeof(*space) + n_edges * edgewords * sizeof(*space)); p = space; all_dom_sets = p; for (i = 0; i < n; ++i) { blocks[i]->dom = p; p += nodewords; } all_closure_sets = p; for (i = 0; i < n; ++i) { blocks[i]->closure = p; p += nodewords; } all_edge_sets = p; for (i = 0; i < n; ++i) { register struct block *b = blocks[i]; b->et.edom = p; p += edgewords; b->ef.edom = p; p += edgewords; b->et.id = i; edges[i] = &b->et; b->ef.id = n_blocks + i; edges[n_blocks + i] = &b->ef; b->et.pred = b; b->ef.pred = b; } max_stmts = 0; for (i = 0; i < n; ++i) max_stmts += slength(blocks[i]->stmts) + 1; /* * We allocate at most 3 value numbers per statement, * so this is an upper bound on the number of valnodes * we'll need. */ maxval = 3 * max_stmts; vmap = (struct vmapinfo *)malloc(maxval * sizeof(*vmap)); vnode_base = (struct valnode *)malloc(maxval * sizeof(*vmap)); } /* * Some pointers used to convert the basic block form of the code, * into the array form that BPF requires. 'fstart' will point to * the malloc'd array while 'ftail' is used during the recursive traversal. */ static struct bpf_insn *fstart; static struct bpf_insn *ftail; #ifdef BDEBUG int bids[1000]; #endif /* * Returns true if successful. Returns false if a branch has * an offset that is too large. If so, we have marked that * branch so that on a subsequent iteration, it will be treated * properly. */ static int convert_code_r(p) struct block *p; { struct bpf_insn *dst; struct slist *src; int slen; u_int off; int extrajmps; /* number of extra jumps inserted */ struct slist **offset = NULL; if (p == 0 || isMarked(p)) return (1); Mark(p); if (convert_code_r(JF(p)) == 0) return (0); if (convert_code_r(JT(p)) == 0) return (0); slen = slength(p->stmts); dst = ftail -= (slen + 1 + p->longjt + p->longjf); /* inflate length by any extra jumps */ p->offset = dst - fstart; /* generate offset[] for convenience */ if (slen) { offset = (struct slist **)calloc(sizeof(struct slist *), slen); if (!offset) { bpf_error("not enough core"); /*NOTREACHED*/ } } src = p->stmts; for (off = 0; off < slen && src; off++) { #if 0 printf("off=%d src=%x\n", off, src); #endif offset[off] = src; src = src->next; } off = 0; for (src = p->stmts; src; src = src->next) { if (src->s.code == NOP) continue; dst->code = (u_short)src->s.code; 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 0 if (src->s.jt || src->s.jf) { bpf_error("illegal jmp destination"); /*NOTREACHED*/ } #endif goto filled; } if (off == slen - 2) /*???*/ goto filled; { int i; int jt, jf; char *ljerr = "%s for block-local relative jump: off=%d"; #if 0 printf("code=%x off=%d %x %x\n", src->s.code, off, src->s.jt, src->s.jf); #endif if (!src->s.jt || !src->s.jf) { bpf_error(ljerr, "no jmp destination", off); /*NOTREACHED*/ } jt = jf = 0; for (i = 0; i < slen; i++) { if (offset[i] == src->s.jt) { if (jt) { bpf_error(ljerr, "multiple matches", off); /*NOTREACHED*/ } dst->jt = i - off - 1; jt++; } if (offset[i] == src->s.jf) { if (jf) { bpf_error(ljerr, "multiple matches", off); /*NOTREACHED*/ } dst->jf = i - off - 1; jf++; } } if (!jt || !jf) { bpf_error(ljerr, "no destination found", off); /*NOTREACHED*/ } } filled: ++dst; ++off; } if (offset) free(offset); #ifdef BDEBUG bids[dst - fstart] = p->id + 1; #endif dst->code = (u_short)p->s.code; dst->k = p->s.k; if (JT(p)) { extrajmps = 0; off = JT(p)->offset - (p->offset + slen) - 1; if (off >= 256) { /* offset too large for branch, must add a jump */ if (p->longjt == 0) { /* mark this instruction and retry */ p->longjt++; return(0); } /* branch if T to following jump */ dst->jt = extrajmps; extrajmps++; dst[extrajmps].code = BPF_JMP|BPF_JA; dst[extrajmps].k = off - extrajmps; } else dst->jt = off; off = JF(p)->offset - (p->offset + slen) - 1; if (off >= 256) { /* offset too large for branch, must add a jump */ if (p->longjf == 0) { /* mark this instruction and retry */ p->longjf++; return(0); } /* branch if F to following jump */ /* if two jumps are inserted, F goes to second one */ dst->jf = extrajmps; extrajmps++; dst[extrajmps].code = BPF_JMP|BPF_JA; dst[extrajmps].k = off - extrajmps; } else dst->jf = off; } return (1); } /* * Convert flowgraph intermediate representation to the * BPF array representation. Set *lenp to the number of instructions. */ struct bpf_insn * icode_to_fcode(root, lenp) struct block *root; int *lenp; { int n; struct bpf_insn *fp; /* * Loop doing convert_codr_r() until no branches remain * with too-large offsets. */ while (1) { unMarkAll(); n = *lenp = count_stmts(root); fp = (struct bpf_insn *)malloc(sizeof(*fp) * n); memset((char *)fp, 0, sizeof(*fp) * n); fstart = fp; ftail = fp + n; unMarkAll(); if (convert_code_r(root)) break; free(fp); } return fp; } #ifdef BDEBUG static void opt_dump(root) struct block *root; { struct bpf_program f; memset(bids, 0, sizeof bids); f.bf_insns = icode_to_fcode(root, &f.bf_len); bpf_dump(&f, 1); putchar('\n'); free((char *)f.bf_insns); } #endif libpcap-0.5/./pcap-bpf.c100644 263 461 15117 7003105706 13500 0ustar mcrtcpdump/* * Copyright (c) 1993, 1994, 1995, 1996, 1998 * 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/pcap-bpf.c,v 1.32 1999/10/19 15:18:30 itojun Exp $ (LBL)"; #endif #include /* optionally get BSD define */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pcap-int.h" #include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif #include "gencode.h" int 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)); return (-1); } ps->ps_recv = s.bs_recv; ps->ps_drop = s.bs_drop; return (0); } int pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) { int cc; int n = 0; register u_char *bp, *ep; again: cc = p->cc; if (p->cc == 0) { cc = read(p->fd, (char *)p->buffer, p->bufsize); if (cc < 0) { /* Don't choke when we get ptraced */ switch (errno) { case EINTR: goto again; case EWOULDBLOCK: return (0); #if defined(sun) && !defined(BSD) /* * Due to a SunOS bug, after 2^31 bytes, the kernel * file offset overflows and read fails with EINVAL. * The lseek() to 0 will fix things. */ case EINVAL: if (lseek(p->fd, 0L, SEEK_CUR) + p->bufsize < 0) { (void)lseek(p->fd, 0L, SEEK_SET); goto again; } /* fall through */ #endif } sprintf(p->errbuf, "read: %s", pcap_strerror(errno)); return (-1); } bp = p->buffer; } else bp = p->bp; /* * Loop through each packet. */ #define bhp ((struct bpf_hdr *)bp) ep = bp + cc; while (bp < ep) { register int caplen, hdrlen; caplen = bhp->bh_caplen; hdrlen = bhp->bh_hdrlen; /* * XXX A bpf_hdr matches a pcap_pkthdr. */ (*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen); bp += BPF_WORDALIGN(caplen + hdrlen); if (++n >= cnt && cnt > 0) { p->bp = bp; p->cc = ep - bp; return (n); } } #undef bhp p->cc = 0; return (n); } static inline int bpf_open(pcap_t *p, char *errbuf) { int fd; int n = 0; char device[sizeof "/dev/bpf000"]; /* * Go through all the minors and find one that isn't in use. */ do { (void)sprintf(device, "/dev/bpf%d", n++); fd = open(device, O_RDONLY); } while (fd < 0 && errno == EBUSY); /* * XXX better message for all minors used */ if (fd < 0) sprintf(errbuf, "%s: %s", device, pcap_strerror(errno)); return (fd); } pcap_t * pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) { int fd; struct ifreq ifr; struct bpf_version bv; u_int v; pcap_t *p; p = (pcap_t *)malloc(sizeof(*p)); if (p == NULL) { sprintf(ebuf, "malloc: %s", pcap_strerror(errno)); return (NULL); } bzero(p, sizeof(*p)); fd = bpf_open(p, ebuf); if (fd < 0) goto bad; p->fd = fd; p->snapshot = snaplen; if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) { sprintf(ebuf, "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"); 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. */ (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) { sprintf(ebuf, "%s: %s", device, pcap_strerror(errno)); goto bad; } /* Get the data link layer type. */ if (ioctl(fd, BIOCGDLT, (caddr_t)&v) < 0) { sprintf(ebuf, "BIOCGDLT: %s", pcap_strerror(errno)); goto bad; } #ifdef __OpenBSD__ switch (v) { case DLT_LOOP: v = DLT_NULL; break; } #endif #if _BSDI_VERSION - 0 >= 199510 /* The SLIP and PPP link layer header changed in BSD/OS 2.1 */ switch (v) { case DLT_SLIP: v = DLT_SLIP_BSDOS; break; case DLT_PPP: v = DLT_PPP_BSDOS; break; case 11: /*DLT_FR*/ v = DLT_RAW; /*XXX*/ break; case 12: /*DLT_C_HDLC*/ v = DLT_CHDLC; break; } #endif p->linktype = v; /* set timeout */ if (to_ms != 0) { struct timeval to; 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)); goto bad; } } 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)); goto bad; } p->bufsize = v; p->buffer = (u_char *)malloc(p->bufsize); if (p->buffer == NULL) { sprintf(ebuf, "malloc: %s", pcap_strerror(errno)); goto bad; } return (p); bad: (void)close(fd); free(p); return (NULL); } int pcap_setfilter(pcap_t *p, struct bpf_program *fp) { /* * It looks that BPF code generated by gen_protochain() is not * 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)); return (-1); } return (0); } libpcap-0.5/./pcap-dlpi.c100644 263 461 46002 6777230340 13670 0ustar mcrtcpdump/* * 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. * * This code contributed by Atanu Ghosh (atanu@cs.ucl.ac.uk), * University College London. */ /* * Packet capture routine for dlpi under SunOS 5 * * Notes: * * - Apparently the DLIOCRAW ioctl() is specific to SunOS. * * - There is a bug in bufmod(7) such that setting the snapshot * length results in data being left of the front of the packet. * * - It might be desirable to use pfmod(7) to filter packets in the * kernel. */ #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)"; #endif #include #include #ifdef HAVE_SYS_BUFMOD_H #include #endif #include #ifdef HAVE_SYS_DLPI_EXT_H #include #endif #ifdef HAVE_HPUX9 #include #endif #ifdef DL_HP_PPA_ACK_OBS #include #endif #include #if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H) #include #endif #ifdef HAVE_HPUX9 #include #endif #include #ifdef HAVE_HPUX9 #include #endif #include #include #include #include #include #include #include #include #include "pcap-int.h" #include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif #ifndef PCAP_DEV_PREFIX #define PCAP_DEV_PREFIX "/dev" #endif #define MAXDLBUF 8192 /* Forwards */ static int dlattachreq(int, bpf_u_int32, char *); static int dlbindack(int, char *, char *); static int dlbindreq(int, bpf_u_int32, char *); static int dlinfoack(int, char *, char *); static int dlinforeq(int, char *); static int dlokack(int, const char *, char *, char *); static int recv_ack(int, int, const char *, char *, char *); static int dlpromisconreq(int, bpf_u_int32, char *); #if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H) static char *get_release(bpf_u_int32 *, bpf_u_int32 *, bpf_u_int32 *); #endif static int send_request(int, char *, int, char *, char *); #ifdef HAVE_SYS_BUFMOD_H static int strioctl(int, int, int, char *); #endif #ifdef HAVE_HPUX9 static int dlpi_kread(int, off_t, void *, u_int, char *); #endif #ifdef HAVE_DEV_DLPI static int get_dlpi_ppa(int, const char *, int, char *); #endif int pcap_stats(pcap_t *p, struct pcap_stat *ps) { *ps = p->md.stat; return (0); } /* XXX Needed by HP-UX (at least) */ static bpf_u_int32 ctlbuf[MAXDLBUF]; static struct strbuf ctl = { MAXDLBUF, 0, (char *)ctlbuf }; int pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) { register int cc, n, caplen, origlen; register u_char *bp, *ep, *pk; register struct bpf_insn *fcode; #ifdef HAVE_SYS_BUFMOD_H register struct sb_hdr *sbp; #ifdef LBL_ALIGN struct sb_hdr sbhdr; #endif #endif int flags; struct strbuf data; struct pcap_pkthdr pkthdr; flags = 0; cc = p->cc; if (cc == 0) { data.buf = (char *)p->buffer + p->offset; data.maxlen = MAXDLBUF; data.len = 0; do { if (getmsg(p->fd, &ctl, &data, &flags) < 0) { /* Don't choke when we get ptraced */ if (errno == EINTR) { cc = 0; continue; } strcpy(p->errbuf, pcap_strerror(errno)); return (-1); } cc = data.len; } while (cc == 0); bp = p->buffer + p->offset; } else bp = p->bp; /* Loop through packets */ fcode = p->fcode.bf_insns; ep = bp + cc; n = 0; #ifdef HAVE_SYS_BUFMOD_H while (bp < ep) { #ifdef LBL_ALIGN if ((long)bp & 3) { sbp = &sbhdr; memcpy(sbp, bp, sizeof(*sbp)); } else #endif sbp = (struct sb_hdr *)bp; p->md.stat.ps_drop += sbp->sbh_drops; pk = bp + sizeof(*sbp); bp += sbp->sbh_totlen; origlen = sbp->sbh_origlen; caplen = sbp->sbh_msglen; #else origlen = cc; caplen = min(p->snapshot, cc); pk = bp; bp += caplen; #endif ++p->md.stat.ps_recv; if (bpf_filter(fcode, pk, origlen, caplen)) { #ifdef HAVE_SYS_BUFMOD_H pkthdr.ts = sbp->sbh_timestamp; #else (void)gettimeofday(&pkthdr.ts, NULL); #endif pkthdr.len = origlen; pkthdr.caplen = caplen; /* Insure caplen does not exceed snapshot */ if (pkthdr.caplen > p->snapshot) pkthdr.caplen = p->snapshot; (*callback)(user, &pkthdr, pk); if (++n >= cnt && cnt >= 0) { p->cc = ep - bp; p->bp = bp; return (n); } } #ifdef HAVE_SYS_BUFMOD_H } #endif p->cc = 0; return (n); } pcap_t * pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) { register char *cp; char *eos; register pcap_t *p; register int ppa; register dl_info_ack_t *infop; #ifdef HAVE_SYS_BUFMOD_H bpf_u_int32 ss, flag; #ifdef HAVE_SOLARIS register char *release; bpf_u_int32 osmajor, osminor, osmicro; #endif #endif bpf_u_int32 buf[MAXDLBUF]; char dname[100]; #ifndef HAVE_DEV_DLPI char dname2[100]; #endif p = (pcap_t *)malloc(sizeof(*p)); if (p == NULL) { strcpy(ebuf, pcap_strerror(errno)); return (NULL); } memset(p, 0, sizeof(*p)); /* ** Determine device and ppa */ cp = strpbrk(device, "0123456789"); if (cp == NULL) { sprintf(ebuf, "%s missing unit number", device); goto bad; } ppa = strtol(cp, &eos, 10); if (*eos != '\0') { sprintf(ebuf, "%s bad unit number", device); goto bad; } 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 */ cp = "/dev/dlpi"; if ((p->fd = open(cp, O_RDWR)) < 0) { sprintf(ebuf, "%s: %s", cp, pcap_strerror(errno)); goto bad; } /* Map network interface to /dev/dlpi unit */ ppa = get_dlpi_ppa(p->fd, dname, ppa, ebuf); if (ppa < 0) goto bad; #else /* Try device without unit number */ strcpy(dname2, dname); 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)); goto bad; } /* Try again with unit number */ if ((p->fd = open(dname2, O_RDWR)) < 0) { sprintf(ebuf, "%s: %s", dname2, pcap_strerror(errno)); goto bad; } /* XXX Assume unit zero */ ppa = 0; } #endif p->snapshot = snaplen; /* ** Attach if "style 2" provider */ if (dlinforeq(p->fd, ebuf) < 0 || dlinfoack(p->fd, (char *)buf, ebuf) < 0) goto bad; infop = &((union DL_primitives *)buf)->info_ack; if (infop->dl_provider_style == DL_STYLE2 && (dlattachreq(p->fd, ppa, ebuf) < 0 || dlokack(p->fd, "attach", (char *)buf, ebuf) < 0)) goto bad; /* ** Bind (defer if using HP-UX 9 or HP-UX 10.20, totally skip if ** using SINIX) */ #if !defined(HAVE_HPUX9) && !defined(HAVE_HPUX10_20) && !defined(sinix) if (dlbindreq(p->fd, 0, ebuf) < 0 || dlbindack(p->fd, (char *)buf, ebuf) < 0) goto bad; #endif if (promisc) { /* ** Enable promiscuous */ if (dlpromisconreq(p->fd, DL_PROMISC_PHYS, ebuf) < 0 || dlokack(p->fd, "promisc_phys", (char *)buf, ebuf) < 0) goto bad; /* ** Try to enable multicast (you would have thought ** promiscuous would be sufficient). (Skip if using ** HP-UX or SINIX) */ #if !defined(__hpux) && !defined(sinix) if (dlpromisconreq(p->fd, DL_PROMISC_MULTI, ebuf) < 0 || dlokack(p->fd, "promisc_multi", (char *)buf, ebuf) < 0) fprintf(stderr, "WARNING: DL_PROMISC_MULTI failed (%s)\n", ebuf); #endif } /* ** Try to enable sap (when not in promiscuous mode when using ** using HP-UX and never under SINIX) */ #ifndef sinix if ( #ifdef __hpux !promisc && #endif (dlpromisconreq(p->fd, DL_PROMISC_SAP, ebuf) < 0 || dlokack(p->fd, "promisc_sap", (char *)buf, ebuf) < 0)) { /* Not fatal if promisc since the DL_PROMISC_PHYS worked */ if (promisc) fprintf(stderr, "WARNING: DL_PROMISC_SAP failed (%s)\n", ebuf); else goto bad; } #endif /* ** HP-UX 9 and HP-UX 10.20 must bind after setting promiscuous ** options) */ #if defined(HAVE_HPUX9) || defined(HAVE_HPUX10_20) if (dlbindreq(p->fd, 0, ebuf) < 0 || dlbindack(p->fd, (char *)buf, ebuf) < 0) goto bad; #endif /* ** Determine link type */ if (dlinforeq(p->fd, ebuf) < 0 || dlinfoack(p->fd, (char *)buf, ebuf) < 0) goto bad; infop = &((union DL_primitives *)buf)->info_ack; switch (infop->dl_mac_type) { case DL_CSMACD: case DL_ETHER: p->linktype = DLT_EN10MB; p->offset = 2; break; case DL_FDDI: p->linktype = DLT_FDDI; p->offset = 3; break; default: sprintf(ebuf, "unknown mac type 0x%lu", infop->dl_mac_type); goto bad; } #ifdef DLIOCRAW /* ** 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)); goto bad; } #endif #ifdef HAVE_SYS_BUFMOD_H /* ** 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)); goto bad; } /* ** Now that the bufmod is pushed lets configure it. ** ** There is a bug in bufmod(7). When dealing with messages of ** less than snaplen size it strips data from the beginning not ** the end. ** ** This bug is supposed to be fixed in 5.3.2. Also, there is a ** patch available. Ask for bugid 1149065. */ ss = snaplen; #ifdef HAVE_SOLARIS release = get_release(&osmajor, &osminor, &osmicro); if (osmajor == 5 && (osminor <= 2 || (osminor == 3 && osmicro < 2)) && getenv("BUFMOD_FIXED") == NULL) { fprintf(stderr, "WARNING: bufmod is broken in SunOS %s; ignoring snaplen.\n", release); ss = 0; } #endif if (ss > 0 && strioctl(p->fd, SBIOCSSNAP, sizeof(ss), (char *)&ss) != 0) { sprintf(ebuf, "SBIOCSSNAP: %s", pcap_strerror(errno)); goto bad; } /* ** Set up the bufmod flags */ if (strioctl(p->fd, SBIOCGFLAGS, sizeof(flag), (char *)&flag) < 0) { sprintf(ebuf, "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)); goto bad; } /* ** Set up the bufmod timeout */ if (to_ms != 0) { struct timeval to; 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)); goto bad; } } #endif /* ** As the last operation flush the read side. */ if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) { sprintf(ebuf, "FLUSHR: %s", pcap_strerror(errno)); goto bad; } /* Allocate data buffer */ p->bufsize = MAXDLBUF * sizeof(bpf_u_int32); p->buffer = (u_char *)malloc(p->bufsize + p->offset); return (p); bad: free(p); return (NULL); } int pcap_setfilter(pcap_t *p, struct bpf_program *fp) { p->fcode = *fp; return (0); } static int send_request(int fd, char *ptr, int len, char *what, char *ebuf) { struct strbuf ctl; int flags; ctl.maxlen = 0; ctl.len = len; ctl.buf = ptr; flags = 0; if (putmsg(fd, &ctl, (struct strbuf *) NULL, flags) < 0) { sprintf(ebuf, "send_request: putmsg \"%s\": %s", what, pcap_strerror(errno)); return (-1); } return (0); } static int recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf) { union DL_primitives *dlp; struct strbuf ctl; int flags; ctl.maxlen = MAXDLBUF; ctl.len = 0; ctl.buf = bufp; flags = 0; if (getmsg(fd, &ctl, (struct strbuf*)NULL, &flags) < 0) { sprintf(ebuf, "recv_ack: %s getmsg: %s", what, pcap_strerror(errno)); return (-1); } dlp = (union DL_primitives *) ctl.buf; switch (dlp->dl_primitive) { case DL_INFO_ACK: case DL_BIND_ACK: case DL_OK_ACK: #ifdef DL_HP_PPA_ACK case DL_HP_PPA_ACK: #endif /* These are OK */ break; case DL_ERROR_ACK: switch (dlp->error_ack.dl_errno) { case DL_BADPPA: sprintf(ebuf, "recv_ack: %s bad ppa (device unit)", what); break; case DL_SYSERR: sprintf(ebuf, "recv_ack: %s: %s", what, pcap_strerror(dlp->error_ack.dl_unix_errno)); break; case DL_UNSUPPORTED: sprintf(ebuf, "recv_ack: %s: Service not supplied by provider", what); break; default: sprintf(ebuf, "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 ", what, (bpf_u_int32)dlp->dl_primitive); return (-1); } if (ctl.len < size) { sprintf(ebuf, "recv_ack: %s ack too small (%d < %d)", what, ctl.len, size); return (-1); } return (ctl.len); } static int dlattachreq(int fd, bpf_u_int32 ppa, char *ebuf) { dl_attach_req_t req; req.dl_primitive = DL_ATTACH_REQ; req.dl_ppa = ppa; return (send_request(fd, (char *)&req, sizeof(req), "attach", ebuf)); } static int dlbindreq(int fd, bpf_u_int32 sap, char *ebuf) { dl_bind_req_t req; memset((char *)&req, 0, sizeof(req)); req.dl_primitive = DL_BIND_REQ; #ifdef DL_HP_RAWDLS req.dl_max_conind = 1; /* XXX magic number */ /* 22 is INSAP as per the HP-UX DLPI Programmer's Guide */ req.dl_sap = 22; req.dl_service_mode = DL_HP_RAWDLS; #else req.dl_sap = sap; #ifdef DL_CLDLS req.dl_service_mode = DL_CLDLS; #endif #endif return (send_request(fd, (char *)&req, sizeof(req), "bind", ebuf)); } static int dlbindack(int fd, char *bufp, char *ebuf) { return (recv_ack(fd, DL_BIND_ACK_SIZE, "bind", bufp, ebuf)); } static int dlpromisconreq(int fd, bpf_u_int32 level, char *ebuf) { dl_promiscon_req_t req; req.dl_primitive = DL_PROMISCON_REQ; req.dl_level = level; return (send_request(fd, (char *)&req, sizeof(req), "promiscon", ebuf)); } static int dlokack(int fd, const char *what, char *bufp, char *ebuf) { return (recv_ack(fd, DL_OK_ACK_SIZE, what, bufp, ebuf)); } static int dlinforeq(int fd, char *ebuf) { dl_info_req_t req; req.dl_primitive = DL_INFO_REQ; return (send_request(fd, (char *)&req, sizeof(req), "info", ebuf)); } static int dlinfoack(int fd, char *bufp, char *ebuf) { return (recv_ack(fd, DL_INFO_ACK_SIZE, "info", bufp, ebuf)); } #ifdef HAVE_SYS_BUFMOD_H static int strioctl(int fd, int cmd, int len, char *dp) { struct strioctl str; int rc; str.ic_cmd = cmd; str.ic_timout = -1; str.ic_len = len; str.ic_dp = dp; rc = ioctl(fd, I_STR, &str); if (rc < 0) return (rc); else return (str.ic_len); } #endif #if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H) static char * get_release(bpf_u_int32 *majorp, bpf_u_int32 *minorp, bpf_u_int32 *microp) { char *cp; static char buf[32]; *majorp = 0; *minorp = 0; *microp = 0; if (sysinfo(SI_RELEASE, buf, sizeof(buf)) < 0) return ("?"); cp = buf; if (!isdigit(*cp)) return (buf); *majorp = strtol(cp, &cp, 10); if (*cp++ != '.') return (buf); *minorp = strtol(cp, &cp, 10); if (*cp++ != '.') return (buf); *microp = strtol(cp, &cp, 10); return (buf); } #endif #ifdef DL_HP_PPA_ACK_OBS /* * Under HP-UX 10, we can ask for the ppa */ /* Determine ppa number that specifies ifname */ 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 int i; register u_long majdev; dl_hp_ppa_req_t req; struct stat statbuf; 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; memset((char *)buf, 0, sizeof(buf)); if (send_request(fd, (char *)&req, sizeof(req), "hpppa", ebuf) < 0 || recv_ack(fd, DL_HP_PPA_ACK_SIZE, "hpppa", (char *)buf, ebuf) < 0) return (-1); ap = (dl_hp_ppa_ack_t *)buf; ip = (dl_hp_ppa_info_t *)((u_char *)ap + ap->dl_offset); 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 *)ip + ip->dl_next_offset); } if (i == ap->dl_count) { sprintf(ebuf, "can't find PPA for %s", device); return (-1); } if (ip->dl_hdw_state == HDW_DEAD) { sprintf(ebuf, "%s: hardware state: DOWN\n", device); return (-1); } return ((int)ip->dl_ppa); } #endif #ifdef HAVE_HPUX9 /* * Under HP-UX 9, there is no good way to determine the ppa. * So punt and read it from /dev/kmem. */ static struct nlist nl[] = { #define NL_IFNET 0 { "ifnet" }, { "" } }; static char path_vmunix[] = "/hp-ux"; /* Determine ppa number that specifies ifname */ static int get_dlpi_ppa(register int fd, register const char *ifname, register int unit, register char *ebuf) { register const char *cp; register int kd; void *addr; struct ifnet ifnet; char if_name[sizeof(ifnet.if_name)], tifname[32]; cp = strrchr(ifname, '/'); if (cp != NULL) ifname = cp + 1; if (nlist(path_vmunix, &nl) < 0) { sprintf(ebuf, "nlist %s failed", path_vmunix); return (-1); } if (nl[NL_IFNET].n_value == 0) { sprintf(ebuf, "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)); return (-1); } if (dlpi_kread(kd, nl[NL_IFNET].n_value, &addr, sizeof(addr), ebuf) < 0) { close(kd); return (-1); } for (; addr != NULL; addr = ifnet.if_next) { 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) { (void)close(kd); return (-1); } sprintf(tifname, "%.*s%d", (int)sizeof(if_name), if_name, ifnet.if_unit); if (strcmp(tifname, ifname) == 0) return (ifnet.if_index); } sprintf(ebuf, "Can't find %s", ifname); return (-1); } static int dlpi_kread(register int fd, register off_t addr, register void *buf, register u_int len, register char *ebuf) { register int cc; if (lseek(fd, addr, SEEK_SET) < 0) { sprintf(ebuf, "lseek: %s", pcap_strerror(errno)); return (-1); } cc = read(fd, buf, len); if (cc < 0) { sprintf(ebuf, "read: %s", pcap_strerror(errno)); return (-1); } else if (cc != len) { sprintf(ebuf, "short read (%d != %d)", cc, len); return (-1); } return (cc); } #endif libpcap-0.5/./pcap-enet.c100644 263 461 11307 6777230340 13673 0ustar mcrtcpdump/* * Stanford Enetfilter subroutines for tcpdump * * Based on the MERIT NNstat etherifrt.c and the Ultrix pcap-pf.c * subroutines. * * Rayan Zachariassen, CA*Net */ #include #include #include #include #include #include #include #include #include #include #include #include #include "interface.h" struct packet_header { #ifdef IBMRTPC struct LengthWords length; struct tap_header tap; #endif /* IBMRTPC */ u_char packet[8] }; extern int errno; #define BUFSPACE (4*1024) /* Forwards */ static void efReadError(int, char *); void readloop(int cnt, int if_fd, struct bpf_program *fp, printfunc printit) { #ifdef IBMRTPC register struct packet_header *ph; register u_char *bp; register int inc; #else /* !IBMRTPC */ static struct timeval tv = { 0 }; #endif /* IBMRTPC */ register int cc, caplen; register struct bpf_insn *fcode = fp->bf_insns; union { struct packet_header hdr; u_char p[BUFSPACE]; u_short s; } buf; while (1) { if ((cc = read(if_fd, (char *)buf.p, sizeof(buf))) < 0) efReadError(if_fd, "reader"); #ifdef IBMRTPC /* * Loop through each packet. */ bp = buf.p; while (cc > 0) { ph = (struct packet_header *)bp; caplen = ph->tap.th_wirelen > snaplen ? snaplen : ph->tap .th_wirelen ; if (bpf_filter(fcode, (char *)ph->packet, ph->tap.th_wirelen, caplen)) { if (cnt >= 0 && --cnt < 0) goto out; (*printit)((char *)ph->packet, (struct timeval *)ph->tap.th_timestamp, ph->tap.th_wirelen, caplen); } inc = ph->length.PacketOffset; cc -= inc; bp += inc; } #else /* !IBMRTPC */ caplen = cc > snaplen ? snaplen : cc ; if (bpf_filter(fcode, buf.hdr.packet, cc, caplen)) { if (cnt >= 0 && --cnt < 0) goto out; (*printit)(buf.hdr.packet, &tv, cc, caplen); } #endif /* IBMRTPC */ } out: wrapup(if_fd); } /* Call ONLY if read() has returned an error on packet filter */ static void efReadError(int fid, char *msg) { if (errno == EINVAL) { /* read MAXINT bytes already! */ if (lseek(fid, 0, 0) < 0) { perror("tcpdump: efReadError/lseek"); exit(-1); } else return; } else { (void) fprintf(stderr, "tcpdump: "); perror(msg); exit(-1); } } void wrapup(int fd) { #ifdef IBMRTPC struct enstats es; if (ioctl(fd, EIOSTATS, &es) == -1) { perror("tcpdump: enet ioctl EIOSTATS error"); exit(-1); } fprintf(stderr, "%d packets queued", es.enStat_Rcnt); if (es.enStat_Rdrops > 0) fprintf(stderr, ", %d dropped", es.enStat_Rdrops); if (es.enStat_Reads > 0) fprintf(stderr, ", %d tcpdump %s", es.enStat_Reads, es.enStat_Reads > 1 ? "reads" : "read"); if (es.enStat_MaxRead > 1) fprintf(stderr, ", %d packets in largest read", es.enStat_MaxRead); putc('\n', stderr); #endif /* IBMRTPC */ close(fd); } int initdevice(char *device, int pflag, int *linktype) { struct eniocb ctl; struct enfilter filter; u_int maxwaiting; int if_fd; #ifdef IBMRTPC GETENETDEVICE(0, O_RDONLY, &if_fd); #else /* !IBMRTPC */ if_fd = open("/dev/enet", O_RDONLY, 0); #endif /* IBMRTPC */ if (if_fd == -1) { perror("tcpdump: enet open error"); error( "your system may not be properly configured; see \"man enet(4)\""); exit(-1); } /* Get operating parameters. */ if (ioctl(if_fd, EIOCGETP, (char *)&ctl) == -1) { perror("tcpdump: enet ioctl EIOCGETP error"); exit(-1); } /* Set operating parameters. */ #ifdef IBMRTPC ctl.en_rtout = 1 * ctl.en_hz; ctl.en_tr_etherhead = 1; ctl.en_tap_network = 1; ctl.en_multi_packet = 1; ctl.en_maxlen = BUFSPACE; #else /* !IBMRTPC */ ctl.en_rtout = 64; /* randomly picked value for HZ */ #endif /* IBMRTPC */ if (ioctl(if_fd, EIOCSETP, &ctl) == -1) { perror("tcpdump: enet ioctl EIOCSETP error"); exit(-1); } /* Flush the receive queue, since we've changed the operating parameters and we otherwise might receive data without headers. */ if (ioctl(if_fd, EIOCFLUSH) == -1) { perror("tcpdump: enet ioctl EIOCFLUSH error"); exit(-1); } /* Set the receive queue depth to its maximum. */ maxwaiting = ctl.en_maxwaiting; if (ioctl(if_fd, EIOCSETW, &maxwaiting) == -1) { perror("tcpdump: enet ioctl EIOCSETW error"); exit(-1); } #ifdef IBMRTPC /* Clear statistics. */ if (ioctl(if_fd, EIOCLRSTAT, 0) == -1) { perror("tcpdump: enet ioctl EIOCLRSTAT error"); exit(-1); } #endif /* IBMRTPC */ /* Set the filter (accept all packets). */ filter.enf_Priority = 3; filter.enf_FilterLen = 0; if (ioctl(if_fd, EIOCSETF, &filter) == -1) { perror("tcpdump: enet ioctl EIOCSETF error"); exit(-1); } /* * "enetfilter" supports only ethernets. */ *linktype = DLT_EN10MB; return(if_fd); } libpcap-0.5/./pcap-int.h100644 263 461 7503 7015643174 13521 0ustar mcrtcpdump/* * Copyright (c) 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 the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the Computer Systems * Engineering Group at Lawrence Berkeley Laboratory. * 4. Neither the name of the University nor of the Laboratory may be used * to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.20 1999/11/21 01:10:20 assar Exp $ (LBL) */ #ifndef pcap_int_h #define pcap_int_h #include /* * Savefile */ struct pcap_sf { FILE *rfile; int swapped; int version_major; int version_minor; u_char *base; }; struct pcap_md { struct pcap_stat stat; /*XXX*/ int use_bpf; 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; #endif }; struct pcap { int fd; int snapshot; int linktype; int tzoff; /* timezone offset */ int offset; /* offset for proper alignment */ struct pcap_sf sf; struct pcap_md md; /* * Read buffer. */ int bufsize; u_char *buffer; u_char *bp; int cc; /* * Place holder for pcap_next(). */ u_char *pkt; /* * Placeholder for filter code if bpf not in kernel. */ struct bpf_program fcode; char errbuf[PCAP_ERRBUF_SIZE]; }; /* * This is a timeval as stored in disk in a dumpfile. * It has to use the same types everywhere, independent of the actual * `struct timeval' */ struct pcap_timeval { bpf_int32 tv_sec; /* seconds */ bpf_int32 tv_usec; /* microseconds */ }; /* * How a `pcap_pkthdr' is actually stored in the dumpfile. */ struct pcap_sf_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 yylex(void); #ifndef min #define min(a, b) ((a) > (b) ? (b) : (a)) #endif /* XXX should these be in pcap.h? */ 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__) #define PCAP_FDDIPAD 3 #endif /* XXX */ extern int pcap_fddipad; #endif libpcap-0.5/./pcap-linux.c100644 263 461 16523 6777230340 14104 0ustar mcrtcpdump/* * Copyright (c) 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. */ #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)"; #endif #include #include #include #include #include #ifdef HAVE_NET_IF_ARP_H #include #else #include #endif #include #include #include #include #include #include #include #include static struct ifreq saved_ifr; #include "pcap-int.h" #include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif void linux_restore_ifr(void); int pcap_stats(pcap_t *p, struct pcap_stat *ps) { *ps = p->md.stat; return (0); } int pcap_read(pcap_t *p, int cnt, 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; } 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) { case EINTR: goto again; case EWOULDBLOCK: return (0); /* XXX */ } sprintf(p->errbuf, "read: %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); } h.len = cc; h.caplen = caplen; (*callback)(user, &h, bp); return (1); } return (0); } pcap_t * pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) { 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); } 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; } 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; } 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; } broadcast = 0; switch (ifr.ifr_hwaddr.sa_family) { 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_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; #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(); #endif default: sprintf(ebuf, "unknown physical layer type 0x%x", ifr.ifr_hwaddr.sa_family); goto bad; } /* 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; } /* Leave room for link header (which is never large under linux...) */ p->bufsize = ifr.ifr_mtu + 64; p->buffer = (u_char *)malloc(p->bufsize + p->offset); if (p->buffer == NULL) { sprintf(ebuf, "malloc: %s", pcap_strerror(errno)); goto bad; } /* XXX */ if (promisc && broadcast) { 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; } saved_ifr = ifr; ifr.ifr_flags |= IFF_PROMISC; if (ioctl(p->fd, SIOCSIFFLAGS, &ifr) < 0 ) { sprintf(ebuf, "SIOCSIFFLAGS: %s", pcap_strerror(errno)); goto bad; } ifr.ifr_flags &= ~IFF_PROMISC; atexit(linux_restore_ifr); } p->md.device = strdup(device); if (p->md.device == NULL) { sprintf(ebuf, "malloc: %s", pcap_strerror(errno)); goto bad; } 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); } int pcap_setfilter(pcap_t *p, struct bpf_program *fp) { p->fcode = *fp; return (0); } void linux_restore_ifr(void) { register int fd; 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)); } libpcap-0.5/./pcap-namedb.h100644 263 461 6277 7003105707 14154 0ustar mcrtcpdump/* * Copyright (c) 1994, 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 the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the Computer Systems * Engineering Group at Lawrence Berkeley Laboratory. * 4. Neither the name of the University nor of the Laboratory may be used * to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#) $Header: /tcpdump/master/libpcap/pcap-namedb.h,v 1.6 1999/10/19 15:18:31 itojun Exp $ (LBL) */ #ifndef lib_pcap_ethers_h #define lib_pcap_ethers_h /* * As returned by the pcap_next_etherent() * XXX this stuff doesn't belong in this interface, but this * library already must do name to address translation, so * on systems that don't have support for /etc/ethers, we * export these hooks since they'll */ struct pcap_etherent { u_char addr[6]; char name[122]; }; #ifndef PCAP_ETHERS_FILE #define PCAP_ETHERS_FILE "/etc/ethers" #endif 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 *); #endif bpf_u_int32 pcap_nametonetaddr(const char *); int pcap_nametoport(const char *, int *, int *); int pcap_nametoproto(const char *); int pcap_nametoeproto(const char *); /* * If a protocol is unknown, PROTO_UNDEF is returned. * Also, pcap_nametoport() returns the protocol along with the port number. * If there are ambiguous entried in /etc/services (i.e. domain * can be either tcp or udp) PROTO_UNDEF is returned. */ #define PROTO_UNDEF -1 /* XXX move these to pcap-int.h? */ int __pcap_atodn(const char *, bpf_u_int32 *); int __pcap_atoin(const char *, bpf_u_int32 *); u_short __pcap_nametodnaddr(const char *); #endif libpcap-0.5/./pcap-nit.c100644 263 461 13055 6777230340 13534 0ustar mcrtcpdump/* * Copyright (c) 1990, 1991, 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/pcap-nit.c,v 1.31.1.1 1999/10/07 23:46:40 mcr Exp $ (LBL)"; #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pcap-int.h" #include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif /* * The chunk size for NIT. This is the amount of buffering * done for read calls. */ #define CHUNKSIZE (2*1024) /* * The total buffer space used by NIT. */ #define BUFSPACE (4*CHUNKSIZE) /* Forwards */ static int nit_setflags(int, int, int, char *); int pcap_stats(pcap_t *p, struct pcap_stat *ps) { *ps = p->md.stat; return (0); } int pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) { register int cc, n; register struct bpf_insn *fcode = p->fcode.bf_insns; register u_char *bp, *cp, *ep; register struct nit_hdr *nh; register int caplen; cc = p->cc; if (cc == 0) { cc = read(p->fd, (char *)p->buffer, p->bufsize); if (cc < 0) { if (errno == EWOULDBLOCK) return (0); sprintf(p->errbuf, "pcap_read: %s", pcap_strerror(errno)); return (-1); } bp = p->buffer; } else bp = p->bp; /* * Loop through each packet. The increment expression * rounds up to the next int boundary past the end of * the previous packet. */ n = 0; ep = bp + cc; while (bp < ep) { nh = (struct nit_hdr *)bp; cp = bp + sizeof(*nh); switch (nh->nh_state) { case NIT_CATCH: break; case NIT_NOMBUF: case NIT_NOCLUSTER: case NIT_NOSPACE: p->md.stat.ps_drop = nh->nh_dropped; continue; case NIT_SEQNO: continue; default: sprintf(p->errbuf, "bad nit state %d", nh->nh_state); return (-1); } ++p->md.stat.ps_recv; bp += ((sizeof(struct nit_hdr) + nh->nh_datalen + sizeof(int) - 1) & ~(sizeof(int) - 1)); caplen = nh->nh_wirelen; if (caplen > p->snapshot) caplen = p->snapshot; if (bpf_filter(fcode, cp, nh->nh_wirelen, caplen)) { struct pcap_pkthdr h; h.ts = nh->nh_timestamp; h.len = nh->nh_wirelen; h.caplen = caplen; (*callback)(user, &h, cp); if (++n >= cnt && cnt >= 0) { p->cc = ep - bp; p->bp = bp; return (n); } } } p->cc = 0; return (n); } static int nit_setflags(int fd, int promisc, int to_ms, char *ebuf) { struct nit_ioc nioc; bzero((char *)&nioc, sizeof(nioc)); nioc.nioc_bufspace = BUFSPACE; nioc.nioc_chunksize = CHUNKSIZE; nioc.nioc_typetomatch = NT_ALLTYPES; nioc.nioc_snaplen = p->snapshot; nioc.nioc_bufalign = sizeof(int); nioc.nioc_bufoffset = 0; if (to_ms != 0) { nioc.nioc_flags |= NF_TIMEOUT; nioc.nioc_timeout.tv_sec = to_ms / 1000; nioc.nioc_timeout.tv_usec = (to_ms * 1000) % 1000000; } if (promisc) nioc.nioc_flags |= NF_PROMISC; if (ioctl(fd, SIOCSNIT, &nioc) < 0) { sprintf(ebuf, "SIOCSNIT: %s", pcap_strerror(errno)); return (-1); } return (0); } pcap_t * pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) { int fd; struct sockaddr_nit snit; register pcap_t *p; p = (pcap_t *)malloc(sizeof(*p)); if (p == NULL) { strcpy(ebuf, pcap_strerror(errno)); return (NULL); } if (snaplen < 96) /* * NIT requires a snapshot length of at least 96. */ snaplen = 96; bzero(p, sizeof(*p)); p->fd = fd = socket(AF_NIT, SOCK_RAW, NITPROTO_RAW); if (fd < 0) { sprintf(ebuf, "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)); goto bad; } p->snapshot = snaplen; nit_setflags(p->fd, promisc, to_ms, ebuf); /* * NIT supports only ethernets. */ p->linktype = DLT_EN10MB; p->bufsize = BUFSPACE; p->buffer = (u_char *)malloc(p->bufsize); if (p->buffer == NULL) { strcpy(ebuf, pcap_strerror(errno)); goto bad; } return (p); bad: if (fd >= 0) close(fd); free(p); return (NULL); } int pcap_setfilter(pcap_t *p, struct bpf_program *fp) { p->fcode = *fp; return (0); } libpcap-0.5/./pcap-nit.h100644 263 461 1712 6777230340 13516 0ustar mcrtcpdump/* * Copyright (c) 1990, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Lawrence Berkeley Laboratory, * Berkeley, CA. The name of the University 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * @(#) $Header: /tcpdump/master/libpcap/pcap-nit.h,v 1.2.1.1 1999/10/07 23:46:40 mcr Exp $ (LBL) */ libpcap-0.5/./pcap-null.c100644 263 461 4164 6777230340 13675 0ustar mcrtcpdump/* * Copyright (c) 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/pcap-null.c,v 1.7.1.1 1999/10/07 23:46:40 mcr Exp $ (LBL)"; #endif #include /* optionally get BSD define */ #include #include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif #include "pcap-int.h" 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); return (-1); } int pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) { (void)sprintf(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); 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); return (-1); } p->fcode = *fp; return (0); } libpcap-0.5/./pcap-pf.c100644 263 461 21452 6777230340 13347 0ustar mcrtcpdump/* * Copyright (c) 1990, 1991, 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. * * packet filter subroutines for tcpdump * Extraction/creation by Jeffrey Mogul, DECWRL */ #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)"; #endif #include #include #include #include #include #include #include #if __STDC__ struct mbuf; struct rtentry; #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pcap-int.h" #include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif /* * BUFSPACE is the size in bytes of the packet read buffer. Most tcpdump * applications aren't going to need more than 200 bytes of packet header * and the read shouldn't return more packets than packetfilter's internal * queue limit (bounded at 256). */ #define BUFSPACE (200 * 256) int pcap_read(pcap_t *pc, int cnt, pcap_handler callback, u_char *user) { register u_char *p, *bp; struct bpf_insn *fcode; register int cc, n, buflen, inc; register struct enstamp *sp; #ifdef LBL_ALIGN struct enstamp stamp; #endif #ifdef PCAP_FDDIPAD register int pad; #endif fcode = pc->md.use_bpf ? NULL : pc->fcode.bf_insns; again: cc = pc->cc; if (cc == 0) { cc = read(pc->fd, (char *)pc->buffer + pc->offset, pc->bufsize); if (cc < 0) { if (errno == EWOULDBLOCK) return (0); if (errno == EINVAL && lseek(pc->fd, 0L, SEEK_CUR) + pc->bufsize < 0) { /* * Due to a kernel bug, after 2^31 bytes, * the kernel file offset overflows and * read fails with EINVAL. The lseek() * to 0 will fix things. */ (void)lseek(pc->fd, 0L, SEEK_SET); goto again; } sprintf(pc->errbuf, "pf read: %s", pcap_strerror(errno)); return (-1); } bp = pc->buffer + pc->offset; } else bp = pc->bp; /* * Loop through each packet. */ n = 0; #ifdef PCAP_FDDIPAD if (pc->linktype == DLT_FDDI) pad = pcap_fddipad; else pad = 0; #endif while (cc > 0) { if (cc < sizeof(*sp)) { sprintf(pc->errbuf, "pf short read (%d)", cc); return (-1); } #ifdef LBL_ALIGN if ((long)bp & 3) { sp = &stamp; memcpy((char *)sp, (char *)bp, sizeof(*sp)); } else #endif sp = (struct enstamp *)bp; if (sp->ens_stamplen != sizeof(*sp)) { sprintf(pc->errbuf, "pf short stamplen (%d)", sp->ens_stamplen); return (-1); } p = bp + sp->ens_stamplen; buflen = sp->ens_count; if (buflen > pc->snapshot) buflen = pc->snapshot; /* Calculate inc before possible pad update */ inc = ENALIGN(buflen + sp->ens_stamplen); cc -= inc; bp += inc; #ifdef PCAP_FDDIPAD p += pad; buflen -= pad; #endif pc->md.TotPkts++; pc->md.TotDrops += sp->ens_dropped; pc->md.TotMissed = sp->ens_ifoverflows; if (pc->md.OrigMissed < 0) pc->md.OrigMissed = pc->md.TotMissed; /* * Short-circuit evaluation: if using BPF filter * in kernel, no need to do it now. */ if (fcode == NULL || bpf_filter(fcode, p, sp->ens_count, buflen)) { struct pcap_pkthdr h; pc->md.TotAccepted++; h.ts = sp->ens_tstamp; #ifdef PCAP_FDDIPAD h.len = sp->ens_count - pad; #else h.len = sp->ens_count; #endif h.caplen = buflen; (*callback)(user, &h, p); if (++n >= cnt && cnt > 0) { pc->cc = cc; pc->bp = bp; return (n); } } } pc->cc = 0; return (n); } int pcap_stats(pcap_t *p, struct pcap_stat *ps) { ps->ps_recv = p->md.TotAccepted; ps->ps_drop = p->md.TotDrops; ps->ps_ifdrop = p->md.TotMissed - p->md.OrigMissed; return (0); } pcap_t * pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) { pcap_t *p; short enmode; int backlog = -1; /* request the most */ struct enfilter Filter; struct endevp devparams; p = (pcap_t *)malloc(sizeof(*p)); if (p == NULL) { sprintf(ebuf, "pcap_open_live: %s", pcap_strerror(errno)); return (0); } bzero((char *)p, sizeof(*p)); p->fd = pfopen(device, O_RDONLY); if (p->fd < 0) { sprintf(ebuf, "pf open: %s: %s\n\ your system may not be properly configured; see \"man packetfilter(4)\"\n", device, pcap_strerror(errno)); goto bad; } p->md.OrigMissed = -1; enmode = ENTSTAMP|ENBATCH|ENNONEXCL; if (promisc) enmode |= ENPROMISC; if (ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode) < 0) { sprintf(ebuf, "EIOCMBIS: %s", pcap_strerror(errno)); goto bad; } #ifdef ENCOPYALL /* Try to set COPYALL mode so that we see packets to ourself */ enmode = ENCOPYALL; (void)ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode);/* OK if this fails */ #endif /* set the backlog */ if (ioctl(p->fd, EIOCSETW, (caddr_t)&backlog) < 0) { sprintf(ebuf, "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)); goto bad; } /* HACK: to compile prior to Ultrix 4.2 */ #ifndef ENDT_FDDI #define ENDT_FDDI 4 #endif switch (devparams.end_dev_type) { case ENDT_10MB: p->linktype = DLT_EN10MB; p->offset = 2; break; case ENDT_FDDI: p->linktype = DLT_FDDI; break; default: /* * XXX * Currently, the Ultrix packet filter supports only * Ethernet and FDDI. Eventually, support for SLIP and PPP * (and possibly others: T1?) should be added. */ #ifdef notdef warning( "Packet filter data-link type %d unknown, assuming Ethernet", devparams.end_dev_type); #endif p->linktype = DLT_EN10MB; p->offset = 2; break; } /* set truncation */ #ifdef PCAP_FDDIPAD if (p->linktype == DLT_FDDI) /* packetfilter includes the padding in the snapshot */ snaplen += pcap_fddipad; #endif if (ioctl(p->fd, EIOCTRUNCATE, (caddr_t)&snaplen) < 0) { sprintf(ebuf, "EIOCTRUNCATE: %s", pcap_strerror(errno)); goto bad; } p->snapshot = snaplen; /* accept all packets */ bzero((char *)&Filter, 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)); goto bad; } if (to_ms != 0) { struct timeval timeout; 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", pcap_strerror(errno)); goto bad; } } p->bufsize = BUFSPACE; p->buffer = (u_char*)malloc(p->bufsize + p->offset); return (p); bad: free(p); return (NULL); } int pcap_setfilter(pcap_t *p, struct bpf_program *fp) { /* * See if BIOCSETF works. If it does, the kernel supports * BPF-style filters, and we do not need to do post-filtering. */ p->md.use_bpf = (ioctl(p->fd, BIOCSETF, (caddr_t)fp) >= 0); if (p->md.use_bpf) { struct bpf_version bv; if (ioctl(p->fd, BIOCVERSION, (caddr_t)&bv) < 0) { sprintf(p->errbuf, "BIOCVERSION: %s", pcap_strerror(errno)); return (-1); } else if (bv.bv_major != BPF_MAJOR_VERSION || bv.bv_minor < BPF_MINOR_VERSION) { fprintf(stderr, "requires bpf language %d.%d or higher; kernel is %d.%d", BPF_MAJOR_VERSION, BPF_MINOR_VERSION, bv.bv_major, bv.bv_minor); /* don't give up, just be inefficient */ p->md.use_bpf = 0; } } else p->fcode = *fp; /*XXX this goes in tcpdump*/ if (p->md.use_bpf) fprintf(stderr, "tcpdump: Using kernel BPF filter\n"); else fprintf(stderr, "tcpdump: Filtering in user process\n"); return (0); } libpcap-0.5/./pcap-pf.h100644 263 461 1711 6777230340 13330 0ustar mcrtcpdump/* * Copyright (c) 1990, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Lawrence Berkeley Laboratory, * Berkeley, CA. The name of the University 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * @(#) $Header: /tcpdump/master/libpcap/pcap-pf.h,v 1.2.1.1 1999/10/07 23:46:40 mcr Exp $ (LBL) */ libpcap-0.5/./pcap-snit.c100644 263 461 16151 6777230340 13717 0ustar mcrtcpdump/* * Copyright (c) 1990, 1991, 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. * * Modifications made to accommodate the new SunOS4.0 NIT facility by * Micky Liu, micky@cunixc.cc.columbia.edu, Columbia University in May, 1989. * This module now handles the STREAMS based NIT. */ #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)"; #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_MALLOC_H #include #endif #include #include #include #include "pcap-int.h" #include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif /* * The chunk size for NIT. This is the amount of buffering * done for read calls. */ #define CHUNKSIZE (2*1024) /* * The total buffer space used by NIT. */ #define BUFSPACE (4*CHUNKSIZE) /* Forwards */ static int nit_setflags(int, int, int, char *); int pcap_stats(pcap_t *p, struct pcap_stat *ps) { *ps = p->md.stat; return (0); } int pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) { register int cc, n; register struct bpf_insn *fcode = p->fcode.bf_insns; register u_char *bp, *cp, *ep; register struct nit_bufhdr *hdrp; register struct nit_iftime *ntp; register struct nit_iflen *nlp; register struct nit_ifdrops *ndp; register int caplen; cc = p->cc; if (cc == 0) { cc = read(p->fd, (char *)p->buffer, p->bufsize); if (cc < 0) { if (errno == EWOULDBLOCK) return (0); sprintf(p->errbuf, "pcap_read: %s", pcap_strerror(errno)); return (-1); } bp = p->buffer; } else bp = p->bp; /* * loop through each snapshot in the chunk */ n = 0; ep = bp + cc; while (bp < ep) { ++p->md.stat.ps_recv; cp = bp; /* get past NIT buffer */ hdrp = (struct nit_bufhdr *)cp; cp += sizeof(*hdrp); /* get past NIT timer */ ntp = (struct nit_iftime *)cp; cp += sizeof(*ntp); ndp = (struct nit_ifdrops *)cp; p->md.stat.ps_drop = ndp->nh_drops; cp += sizeof *ndp; /* get past packet len */ nlp = (struct nit_iflen *)cp; cp += sizeof(*nlp); /* next snapshot */ bp += hdrp->nhb_totlen; caplen = nlp->nh_pktlen; if (caplen > p->snapshot) caplen = p->snapshot; if (bpf_filter(fcode, cp, nlp->nh_pktlen, caplen)) { struct pcap_pkthdr h; h.ts = ntp->nh_timestamp; h.len = nlp->nh_pktlen; h.caplen = caplen; (*callback)(user, &h, cp); if (++n >= cnt && cnt >= 0) { p->cc = ep - bp; p->bp = bp; return (n); } } } p->cc = 0; return (n); } static int nit_setflags(int fd, int promisc, int to_ms, char *ebuf) { bpf_u_int32 flags; struct strioctl si; struct timeval timeout; si.ic_timout = INFTIM; if (to_ms != 0) { timeout.tv_sec = to_ms / 1000; timeout.tv_usec = (to_ms * 1000) % 1000000; si.ic_cmd = NIOCSTIME; 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)); return (-1); } } flags = NI_TIMESTAMP | NI_LEN | NI_DROPS; if (promisc) flags |= NI_PROMISC; si.ic_cmd = NIOCSFLAGS; 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)); return (-1); } return (0); } pcap_t * pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) { struct strioctl si; /* struct for ioctl() */ struct ifreq ifr; /* interface request struct */ int chunksize = CHUNKSIZE; int fd; static char dev[] = "/dev/nit"; register pcap_t *p; p = (pcap_t *)malloc(sizeof(*p)); if (p == NULL) { strcpy(ebuf, pcap_strerror(errno)); return (NULL); } if (snaplen < 96) /* * NIT requires a snapshot length of at least 96. */ snaplen = 96; bzero(p, sizeof(*p)); p->fd = fd = open(dev, O_RDONLY); if (fd < 0) { sprintf(ebuf, "%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)); goto bad; } if (ioctl(fd, I_PUSH, "nbuf") < 0) { sprintf(ebuf, "push nbuf: %s", pcap_strerror(errno)); goto bad; } /* set the chunksize */ si.ic_cmd = NIOCSCHUNK; si.ic_timout = INFTIM; 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)); goto bad; } /* request the interface */ strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = ' '; si.ic_cmd = NIOCBIND; si.ic_len = sizeof(ifr); si.ic_dp = (char *)𝔦 if (ioctl(fd, I_STR, (char *)&si) < 0) { sprintf(ebuf, "NIOCBIND: %s: %s", ifr.ifr_name, pcap_strerror(errno)); goto bad; } /* set the snapshot length */ si.ic_cmd = NIOCSSNAP; 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)); goto bad; } p->snapshot = snaplen; if (nit_setflags(p->fd, promisc, to_ms, ebuf) < 0) goto bad; (void)ioctl(fd, I_FLUSH, (char *)FLUSHR); /* * NIT supports only ethernets. */ p->linktype = DLT_EN10MB; p->bufsize = BUFSPACE; p->buffer = (u_char *)malloc(p->bufsize); if (p->buffer == NULL) { strcpy(ebuf, pcap_strerror(errno)); goto bad; } return (p); bad: if (fd >= 0) close(fd); free(p); return (NULL); } int pcap_setfilter(pcap_t *p, struct bpf_program *fp) { p->fcode = *fp; return (0); } libpcap-0.5/./pcap-snoop.c100644 263 461 13607 6777230340 14103 0ustar mcrtcpdump/* * 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. */ #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)"; #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pcap-int.h" #include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif int pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) { int cc; register struct snoopheader *sh; register int datalen; register int caplen; register u_char *cp; again: cc = read(p->fd, (char *)p->buffer, p->bufsize); if (cc < 0) { /* Don't choke when we get ptraced */ switch (errno) { case EINTR: goto again; case EWOULDBLOCK: return (0); /* XXX */ } sprintf(p->errbuf, "read: %s", pcap_strerror(errno)); return (-1); } sh = (struct snoopheader *)p->buffer; datalen = sh->snoop_packetlen; caplen = (datalen < p->snapshot) ? datalen : p->snapshot; cp = (u_char *)(sh + 1) + p->offset; /* XXX */ if (p->fcode.bf_insns == NULL || bpf_filter(p->fcode.bf_insns, cp, datalen, caplen)) { struct pcap_pkthdr h; ++p->md.stat.ps_recv; h.ts = sh->snoop_timestamp; h.len = datalen; h.caplen = caplen; (*callback)(user, &h, cp); return (1); } return (0); } int pcap_stats(pcap_t *p, struct pcap_stat *ps) { register struct rawstats *rs; struct rawstats rawstats; rs = &rawstats; bzero((char *)rs, sizeof(*rs)); if (ioctl(p->fd, SIOCRAWSTATS, (char *)rs) < 0) { sprintf(p->errbuf, "SIOCRAWSTATS: %s", pcap_strerror(errno)); return (-1); } p->md.stat.ps_drop = rs->rs_snoop.ss_ifdrops + rs->rs_snoop.ss_sbdrops + rs->rs_drain.ds_ifdrops + rs->rs_drain.ds_sbdrops; *ps = p->md.stat; return (0); } /* XXX can't disable promiscuous */ pcap_t * pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) { int fd; struct sockaddr_raw sr; struct snoopfilter sf; u_int v; pcap_t *p; p = (pcap_t *)malloc(sizeof(*p)); if (p == NULL) { sprintf(ebuf, "malloc: %s", pcap_strerror(errno)); return (NULL); } bzero((char *)p, sizeof(*p)); fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP); if (fd < 0) { sprintf(ebuf, "snoop socket: %s", pcap_strerror(errno)); goto bad; } p->fd = fd; bzero((char *)&sr, 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)); goto bad; } bzero((char *)&sf, sizeof(sf)); if (ioctl(fd, SIOCADDSNOOP, &sf) < 0) { sprintf(ebuf, "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 */ if (strncmp("et", device, 2) == 0 || /* Challenge 10 Mbit */ strncmp("ec", device, 2) == 0 || /* Indigo/Indy 10 Mbit, O2 10/100 */ strncmp("ef", device, 2) == 0 || /* O200/2000 10/100 Mbit */ strncmp("gfe", device, 3) == 0 || /* GIO 100 Mbit */ strncmp("fxp", device, 3) == 0 || /* Challenge VME Enet */ 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) { p->linktype = DLT_EN10MB; p->offset = RAW_HDRPAD(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? */ } else if (strncmp("ppp", device, 3) == 0) { p->linktype = DLT_RAW; } else if (strncmp("lo", device, 2) == 0) { p->linktype = DLT_NULL; } else { sprintf(ebuf, "snoop: unknown physical layer type"); goto bad; } p->bufsize = 4096; /* XXX */ p->buffer = (u_char *)malloc(p->bufsize); if (p->buffer == NULL) { sprintf(ebuf, "malloc: %s", pcap_strerror(errno)); goto bad; } return (p); bad: (void)close(fd); free(p); return (NULL); } int pcap_setfilter(pcap_t *p, struct bpf_program *fp) { p->fcode = *fp; return (0); } libpcap-0.5/./pcap.3100644 263 461 21440 7133253671 12660 0ustar mcrtcpdump.\" Copyright (c) 1994, 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. .\" .TH PCAP 3 "24 June 1998" .SH NAME pcap \- Packet Capture library .SH SYNOPSIS .nf .ft B #include .ft .LP .ft B pcap_t *pcap_open_live(char *device, int snaplen, .ti +8 int promisc, int to_ms, char *ebuf) pcap_t *pcap_open_offline(char *fname, char *ebuf) pcap_dumper_t *pcap_dump_open(pcap_t *p, char *fname) .ft .LP .ft B char errbuf[PCAP_ERRBUF_SIZE]; char *pcap_lookupdev(char *errbuf) int pcap_lookupnet(char *device, bpf_u_int32 *netp, .ti +8 bpf_u_int32 *maskp, char *errbuf) .ft .LP .ft B int pcap_dispatch(pcap_t *p, int cnt, .ti +8 pcap_handler callback, u_char *user) int pcap_loop(pcap_t *p, int cnt, .ti +8 pcap_handler callback, u_char *user) void pcap_dump(u_char *user, struct pcap_pkthdr *h, .ti +8 u_char *sp) .ft .LP .ft B 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) .ft .LP .ft B u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h) .ft .LP .ft B int pcap_datalink(pcap_t *p) int pcap_snapshot(pcap_t *p) int pcap_is_swapped(pcap_t *p) int pcap_major_version(pcap_t *p) int pcap_minor_version(pcap_t *p) int pcap_stats(pcap_t *p, struct pcap_stat *ps) FILE *pcap_file(pcap_t *p) int pcap_fileno(pcap_t *p) void pcap_perror(pcap_t *p, char *prefix) char *pcap_geterr(pcap_t *p) char *pcap_strerror(int error) .ft .LP .ft B void pcap_close(pcap_t *p) void pcap_dump_close(pcap_dumper_t *p) .ft .fi .SH DESCRIPTION The Packet Capture library provides a high level interface to packet capture systems. All packets on the network, even those destined for other hosts, are accessible through this mechanism. .PP .SH ROUTINES .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. .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.) .I to_ms specifies the read timeout in milliseconds. .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_offline() is called to open a ``savefile'' for reading. .I fname specifies the name of the file to open. The file has the same format as those used by .B tcpdump(1) and .BR tcpslice(1) . The name "-" in a synonym for .BR stdin . .I ebuf is used to return error text and is only set when .B pcap_open_offline() fails and returns .BR NULL . .PP .B pcap_dump_open() is called to open a ``savefile'' for writing. The name "-" in a synonym for .BR stdout . .B NULL is returned on failure. .I p is a .I pcap struct as returned by .B pcap_open_offline() or .BR pcap_open_live() . .I fname specifies the name of the file to open. If .B NULL is returned, .B pcap_geterr() can be used to get the error text. .PP .B pcap_lookupdev() returns a pointer to a network device suitable for use with .B pcap_open_live() and .BR pcap_lookupnet() . If there is an error, .B NULL is returned and .I errbuf is filled in with with an appropriate error message. .PP .B pcap_lookupnet() is used to determine the network number and mask associated with the network device .BR device . Both .I netp and .I maskp are .I bpf_u_int32 pointers. A return of -1 indicates an error in which case .I errbuf is filled in with 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 .I cnt of -1 processes all the packets received in one buffer. 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). .I callback specifies a routine to be called with three arguments: a .I u_char pointer which is passed in from .BR pcap_dispatch() , a pointer to the .I pcap_pkthdr 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 an error in which case .B pcap_perror() or .BR pcap_geterr() may be used to display the error text. .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() . .PP .B pcap_compile() is used to compile the string .I str into a filter program. .I program is a pointer to a .I bpf_program struct and is filled in by .BR pcap_compile() . .I optimize controls whether optimization on the resulting code is performed. .I netmask specifies the netmask of the local net. .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 called .BR pcap_open() . .PP .B pcap_setfilter() is used to specify a filter program. .I fp is a pointer to an array of .I bpf_program struct, usually the result of a call to .BR pcap_compile() . .B \-1 is returned on failure; .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. .PP .B pcap_datalink() returns the link layer type, e.g. .BR DLT_EN10MB . .PP .B pcap_snapshot() returns the snapshot length specified when .B pcap_open_live was called. .PP .B pcap_is_swapped() returns true if the current ``savefile'' uses a different byte order than the current system. .PP .B pcap_major_version() returns the major number of the version of the pcap used to write the savefile. .PP .B pcap_minor_version() returns the minor number of the version of the pcap used to write the savefile. .PP .B pcap_file() returns the name of the ``savefile.'' .PP .B int pcap_stats() 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 the error text can be obtained with .B pcap_perror() or .BR pcap_geterr() . .PP .B pcap_fileno() returns the file descriptor number of the ``savefile.'' .PP .B pcap_perror() prints the text of the last pcap library error on .BR stderr , prefixed by .IR prefix . .PP .B pcap_geterr() returns the error text pertaining to the last pcap library error. .PP .B pcap_strerror() is provided in case .BR strerror (1) isn't available. .PP .B pcap_close() closes the files associated with .I p and deallocates resources. .PP .B pcap_dump_close() closes the ``savefile.'' .PP .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 from "The Tcpdump Group"'s Web site at .LP .RS .I http://www.tcpdump.org/ .RE .SH BUGS 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 libpcap-0.5/./pcap.c100644 263 461 10711 6777230340 12740 0ustar mcrtcpdump/* * Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the Computer Systems * Engineering Group at Lawrence Berkeley Laboratory. * 4. Neither the name of the University nor of the Laboratory may be used * to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef 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)"; #endif #include #include #include #include #include #include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif #include "pcap-int.h" int pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user) { if (p->sf.rfile != NULL) return (pcap_offline_read(p, cnt, callback, user)); return (pcap_read(p, cnt, callback, user)); } int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user) { register int n; for (;;) { if (p->sf.rfile != NULL) n = pcap_offline_read(p, cnt, callback, user); else { /* * XXX keep reading until we get something * (or an error occurs) */ do { n = pcap_read(p, cnt, callback, user); } while (n == 0); } if (n <= 0) return (n); if (cnt > 0) { cnt -= n; if (cnt <= 0) return (0); } } } struct singleton { struct pcap_pkthdr *hdr; const u_char *pkt; }; static void pcap_oneshot(u_char *userData, const struct pcap_pkthdr *h, const u_char *pkt) { struct singleton *sp = (struct singleton *)userData; *sp->hdr = *h; sp->pkt = pkt; } const u_char * pcap_next(pcap_t *p, struct pcap_pkthdr *h) { struct singleton s; s.hdr = h; if (pcap_dispatch(p, 1, pcap_oneshot, (u_char*)&s) <= 0) return (0); return (s.pkt); } int pcap_datalink(pcap_t *p) { return (p->linktype); } int pcap_snapshot(pcap_t *p) { return (p->snapshot); } int pcap_is_swapped(pcap_t *p) { return (p->sf.swapped); } int pcap_major_version(pcap_t *p) { return (p->sf.version_major); } int pcap_minor_version(pcap_t *p) { return (p->sf.version_minor); } FILE * pcap_file(pcap_t *p) { return (p->sf.rfile); } int pcap_fileno(pcap_t *p) { return (p->fd); } void pcap_perror(pcap_t *p, char *prefix) { fprintf(stderr, "%s: %s\n", prefix, p->errbuf); } char * pcap_geterr(pcap_t *p) { return (p->errbuf); } /* * Not all systems have strerror(). */ char * pcap_strerror(int errnum) { #ifdef HAVE_STRERROR return (strerror(errnum)); #else extern int sys_nerr; extern const char *const sys_errlist[]; static char ebuf[20]; if ((unsigned int)errnum < sys_nerr) return ((char *)sys_errlist[errnum]); (void)sprintf(ebuf, "Unknown error: %d", errnum); return(ebuf); #endif } void pcap_close(pcap_t *p) { /*XXX*/ if (p->fd >= 0) close(p->fd); if (p->sf.rfile != NULL) { (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 free(p); } libpcap-0.5/./pcap.h100644 263 461 11640 7023533533 12742 0ustar mcrtcpdump/* * Copyright (c) 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the Computer Systems * Engineering Group at Lawrence Berkeley Laboratory. * 4. Neither the name of the University nor of the Laboratory may be used * to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.22 1999/12/08 19:54:03 mcr Exp $ (LBL) */ #ifndef lib_pcap_h #define lib_pcap_h #include #include #include #include #define PCAP_VERSION_MAJOR 2 #define PCAP_VERSION_MINOR 4 #define PCAP_ERRBUF_SIZE 256 /* * Compatibility for systems that have a bpf.h that * predates the bpf typedefs for 64-bit support. */ #if BPF_RELEASE - 0 < 199406 typedef int bpf_int32; typedef u_int bpf_u_int32; #endif typedef struct pcap pcap_t; typedef struct pcap_dumper pcap_dumper_t; /* * The first record in the file contains saved values for some * 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. */ struct pcap_file_header { bpf_u_int32 magic; u_short version_major; u_short version_minor; 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_*) */ }; /* * Each packet in the dump file is prepended with this generic header. * This gets around the problem of different headers for different * packet interfaces. */ struct pcap_pkthdr { struct timeval ts; /* time stamp */ bpf_u_int32 caplen; /* length of portion present */ bpf_u_int32 len; /* length this packet (off wire) */ }; /* * As returned by the pcap_stats() */ struct pcap_stat { u_int ps_recv; /* number of packets received */ u_int ps_drop; /* number of packets dropped */ u_int ps_ifdrop; /* drops by interface XXX not yet supported */ }; typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, const u_char *); 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_offline(const char *, char *); void pcap_close(pcap_t *); int pcap_loop(pcap_t *, int, pcap_handler, u_char *); int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *); const u_char* pcap_next(pcap_t *, struct pcap_pkthdr *); int pcap_stats(pcap_t *, struct pcap_stat *); int pcap_setfilter(pcap_t *, struct bpf_program *); void pcap_perror(pcap_t *, char *); char *pcap_strerror(int); char *pcap_geterr(pcap_t *); 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 *); int pcap_datalink(pcap_t *); int pcap_snapshot(pcap_t *); int pcap_is_swapped(pcap_t *); int pcap_major_version(pcap_t *); int pcap_minor_version(pcap_t *); /* XXX */ FILE *pcap_file(pcap_t *); int pcap_fileno(pcap_t *); pcap_dumper_t *pcap_dump_open(pcap_t *, const char *); void pcap_dump_close(pcap_dumper_t *); 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); char *bpf_image(struct bpf_insn *, int); #endif libpcap-0.5/./ppp.h100644 263 461 4716 7003105707 12600 0ustar mcrtcpdump/* @(#) $Header: /tcpdump/master/libpcap/ppp.h,v 1.8 1999/10/19 15:18:31 itojun Exp $ (LBL) */ /* * Point to Point Protocol (PPP) RFC1331 * * Copyright 1989 by Carnegie Mellon. * * Permission to use, copy, modify, and distribute this program for any * purpose and without fee is hereby granted, provided that this copyright * and permission notice appear on all copies and supporting documentation, * the name of Carnegie Mellon not be used in advertising or publicity * pertaining to distribution of the program without specific prior * permission, and notice be given in supporting documentation that copying * and distribution is by permission of Carnegie Mellon and Stanford * University. Carnegie Mellon makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. */ #define PPP_ADDRESS 0xff /* The address byte value */ #define PPP_CONTROL 0x03 /* The control byte value */ /* Protocol numbers */ #define PPP_IP 0x0021 /* Raw IP */ #define PPP_OSI 0x0023 /* OSI Network Layer */ #define PPP_NS 0x0025 /* Xerox NS IDP */ #define PPP_DECNET 0x0027 /* DECnet Phase IV */ #define PPP_APPLE 0x0029 /* Appletalk */ #define PPP_IPX 0x002b /* Novell IPX */ #define PPP_VJC 0x002d /* Van Jacobson Compressed TCP/IP */ #define PPP_VJNC 0x002f /* Van Jacobson Uncompressed TCP/IP */ #define PPP_BRPDU 0x0031 /* Bridging PDU */ #define PPP_STII 0x0033 /* Stream Protocol (ST-II) */ #define PPP_VINES 0x0035 /* Banyan Vines */ #define PPP_IPV6 0x0057 /* Internet Protocol version 6 */ #define PPP_HELLO 0x0201 /* 802.1d Hello Packets */ #define PPP_LUXCOM 0x0231 /* Luxcom */ #define PPP_SNS 0x0233 /* Sigma Network Systems */ #define PPP_IPCP 0x8021 /* IP Control Protocol */ #define PPP_OSICP 0x8023 /* OSI Network Layer Control Protocol */ #define PPP_NSCP 0x8025 /* Xerox NS IDP Control Protocol */ #define PPP_DECNETCP 0x8027 /* DECnet Control Protocol */ #define PPP_APPLECP 0x8029 /* Appletalk Control Protocol */ #define PPP_IPXCP 0x802b /* Novell IPX Control Protocol */ #define PPP_STIICP 0x8033 /* Strean Protocol Control Protocol */ #define PPP_VINESCP 0x8035 /* Banyan Vines Control Protocol */ #define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */ #define PPP_LCP 0xc021 /* Link Control Protocol */ #define PPP_PAP 0xc023 /* Password Authentication Protocol */ #define PPP_LQM 0xc025 /* Link Quality Monitoring */ #define PPP_CHAP 0xc223 /* Challenge Handshake Authentication Protocol */ libpcap-0.5/./savefile.c100644 263 461 22720 7015643336 13615 0ustar mcrtcpdump/* * 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. * * savefile.c - supports offline use of tcpdump * Extraction/creation by Jeffrey Mogul, DECWRL * Modified by Steve McCanne, LBL. * * Used to save the received packet headers, after filtering, to * a file, and then read them later. * The first record in the file contains saved values for the machine * dependent values so we can print the dump file on any architecture. */ #ifndef lint static const char rcsid[] = "@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.38 1999/11/21 01:11:58 assar Exp $ (LBL)"; #endif #include #include #include #include #include #include #include #include "pcap-int.h" #include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif #define TCPDUMP_MAGIC 0xa1b2c3d4 /* * We use the "receiver-makes-right" approach to byte order, * because time is at a premium when we are writing the file. * In other words, the pcap_file_header and pcap_pkthdr, * records are written in host byte order. * Note that the packets are always written in network byte order. * * ntoh[ls] aren't sufficient because we might need to swap on a big-endian * machine (if the file was written in little-end order). */ #define SWAPLONG(y) \ ((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff)) #define SWAPSHORT(y) \ ( (((y)&0xff)<<8) | ((u_short)((y)&0xff00)>>8) ) #define SFERR_TRUNC 1 #define SFERR_BADVERSION 2 #define SFERR_BADF 3 #define SFERR_EOF 4 /* not really an error, just a status */ static int sf_write_header(FILE *fp, int linktype, int thiszone, int snaplen) { struct pcap_file_header hdr; hdr.magic = TCPDUMP_MAGIC; hdr.version_major = PCAP_VERSION_MAJOR; hdr.version_minor = PCAP_VERSION_MINOR; hdr.thiszone = thiszone; hdr.snaplen = snaplen; hdr.sigfigs = 0; hdr.linktype = linktype; if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1) return (-1); return (0); } static void swap_hdr(struct pcap_file_header *hp) { hp->version_major = SWAPSHORT(hp->version_major); hp->version_minor = SWAPSHORT(hp->version_minor); hp->thiszone = SWAPLONG(hp->thiszone); hp->sigfigs = SWAPLONG(hp->sigfigs); hp->snaplen = SWAPLONG(hp->snaplen); hp->linktype = SWAPLONG(hp->linktype); } pcap_t * pcap_open_offline(const char *fname, char *errbuf) { register pcap_t *p; register FILE *fp; struct pcap_file_header hdr; int linklen; p = (pcap_t *)malloc(sizeof(*p)); if (p == NULL) { strcpy(errbuf, "out of swap"); return (NULL); } memset((char *)p, 0, sizeof(*p)); /* * Set this field so we don't close stdin in pcap_close! */ p->fd = -1; if (fname[0] == '-' && fname[1] == '\0') fp = stdin; else { fp = fopen(fname, "r"); if (fp == NULL) { sprintf(errbuf, "%s: %s", fname, pcap_strerror(errno)); goto bad; } } if (fread((char *)&hdr, sizeof(hdr), 1, fp) != 1) { sprintf(errbuf, "fread: %s", pcap_strerror(errno)); goto bad; } if (hdr.magic != TCPDUMP_MAGIC) { if (SWAPLONG(hdr.magic) != TCPDUMP_MAGIC) { sprintf(errbuf, "bad dump file format"); goto bad; } p->sf.swapped = 1; swap_hdr(&hdr); } if (hdr.version_major < PCAP_VERSION_MAJOR) { sprintf(errbuf, "archaic file format"); goto bad; } p->tzoff = hdr.thiszone; p->snapshot = hdr.snaplen; p->linktype = hdr.linktype; p->sf.rfile = fp; p->bufsize = hdr.snaplen; /* Align link header as required for proper data alignment */ /* XXX should handle all types */ switch (p->linktype) { case DLT_EN10MB: linklen = 14; break; case DLT_FDDI: linklen = 13 + 8; /* fddi_header + llc */ break; case DLT_NULL: default: linklen = 0; break; } p->sf.base = (u_char *)malloc(p->bufsize + BPF_ALIGNMENT); p->buffer = p->sf.base + BPF_ALIGNMENT - (linklen % BPF_ALIGNMENT); p->sf.version_major = hdr.version_major; p->sf.version_minor = hdr.version_minor; #ifdef PCAP_FDDIPAD /* XXX padding only needed for kernel fcode */ pcap_fddipad = 0; #endif return (p); bad: free(p); return (NULL); } /* * Read sf_readfile and return the next packet. Return the header in hdr * and the contents in buf. Return 0 on success, SFERR_EOF if there were * no more packets, and SFERR_TRUNC if a partial packet was encountered. */ static int sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen) { struct pcap_sf_pkthdr sf_hdr; FILE *fp = p->sf.rfile; /* read the stamp */ if (fread(&sf_hdr, sizeof(struct pcap_sf_pkthdr), 1, fp) != 1) { /* probably an EOF, though could be a truncated packet */ return (1); } if (p->sf.swapped) { /* these were written in opposite byte order */ hdr->caplen = SWAPLONG(sf_hdr.caplen); hdr->len = SWAPLONG(sf_hdr.len); hdr->ts.tv_sec = SWAPLONG(sf_hdr.ts.tv_sec); hdr->ts.tv_usec = SWAPLONG(sf_hdr.ts.tv_usec); } else { hdr->caplen = sf_hdr.caplen; hdr->len = sf_hdr.len; hdr->ts.tv_sec = sf_hdr.ts.tv_sec; hdr->ts.tv_usec = sf_hdr.ts.tv_usec; } /* * We interchanged the caplen and len fields at version 2.3, * in order to match the bpf header layout. But unfortunately * some files were written with version 2.3 in their headers * but without the interchanged fields. */ if (p->sf.version_minor < 3 || (p->sf.version_minor == 3 && hdr->caplen > hdr->len)) { int t = hdr->caplen; hdr->caplen = hdr->len; hdr->len = t; } if (hdr->caplen > buflen) { /* * This can happen due to Solaris 2.3 systems tripping * over the BUFMOD problem and not setting the snapshot * correctly in the savefile header. If the caplen isn't * grossly wrong, try to salvage. */ static u_char *tp = NULL; static int tsize = 0; if (hdr->caplen > 65535) { sprintf(p->errbuf, "bogus savefile header"); return (-1); } if (tsize < hdr->caplen) { tsize = ((hdr->caplen + 1023) / 1024) * 1024; if (tp != NULL) free((u_char *)tp); tp = (u_char *)malloc(tsize); if (tp == NULL) { tsize = 0; sprintf(p->errbuf, "BUFMOD hack malloc"); return (-1); } } if (fread((char *)tp, hdr->caplen, 1, fp) != 1) { sprintf(p->errbuf, "truncated dump file"); return (-1); } /* * We can only keep up to buflen bytes. Since caplen > buflen * is exactly how we got here, we know we can only keep the * first buflen bytes and must drop the remainder. Adjust * caplen accordingly, so we don't get confused later as * to how many bytes we have to play with. */ hdr->caplen = buflen; memcpy((char *)buf, (char *)tp, buflen); } else { /* read the packet itself */ if (fread((char *)buf, hdr->caplen, 1, fp) != 1) { sprintf(p->errbuf, "truncated dump file"); return (-1); } } return (0); } /* * Print out packets stored in the file initialized by sf_read_init(). * If cnt > 0, return after 'cnt' packets, otherwise continue until eof. */ int pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) { struct bpf_insn *fcode = p->fcode.bf_insns; int status = 0; int n = 0; while (status == 0) { struct pcap_pkthdr h; status = sf_next_packet(p, &h, p->buffer, p->bufsize); if (status) { if (status == 1) return (0); return (status); } if (fcode == NULL || bpf_filter(fcode, p->buffer, h.len, h.caplen)) { (*callback)(user, &h, p->buffer); if (++n >= cnt && cnt > 0) break; } } /*XXX this breaks semantics tcpslice expects */ return (n); } /* * Output a packet to the initialized dump file. */ void pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) { register FILE *f; struct pcap_sf_pkthdr sf_hdr; f = (FILE *)user; sf_hdr.ts.tv_sec = h->ts.tv_sec; sf_hdr.ts.tv_usec = h->ts.tv_usec; sf_hdr.caplen = h->caplen; sf_hdr.len = h->len; /* XXX we should check the return status */ (void)fwrite(&sf_hdr, sizeof(sf_hdr), 1, f); (void)fwrite((char *)sp, h->caplen, 1, f); } /* * Initialize so that sf_write() will output to the file named 'fname'. */ pcap_dumper_t * pcap_dump_open(pcap_t *p, const char *fname) { FILE *f; if (fname[0] == '-' && fname[1] == '\0') f = stdout; else { f = fopen(fname, "w"); if (f == NULL) { sprintf(p->errbuf, "%s: %s", fname, pcap_strerror(errno)); return (NULL); } } (void)sf_write_header(f, p->linktype, p->tzoff, p->snapshot); return ((pcap_dumper_t *)f); } void pcap_dump_close(pcap_dumper_t *p) { #ifdef notyet if (ferror((FILE *)p)) return-an-error; /* XXX should check return from fclose() too */ #endif (void)fclose((FILE *)p); } libpcap-0.5/./scanner.l100644 263 461 16670 7014425226 13463 0ustar mcrtcpdump%{ /* * Copyright (c) 1988, 1989, 1990, 1991, 1992, 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. */ #ifndef lint static const char rcsid[] = "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.60 1999/11/17 04:09:58 assar Exp $ (LBL)"; #endif #include #include #include #include #include #include "pcap-int.h" #include "gencode.h" #include #ifdef INET6 #include #include #endif /*INET6*/ #include "tokdefs.h" #include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif static int stoi(char *); 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;\ }\ } #else #undef getc #define getc(fp) (*in_buffer == 0 ? EOF : *in_buffer++) #endif #define yylval pcap_lval extern YYSTYPE yylval; static char *in_buffer; %} N ([0-9]+|(0X|0x)[0-9A-Fa-f]+) B ([0-9A-Fa-f][0-9A-Fa-f]?) W ([0-9A-Fa-f][0-9A-Fa-f]?[0-9A-Fa-f]?[0-9A-Fa-f]?) %a 15000 %o 17000 %e 6000 %k 4000 %p 19000 V680 {W}:{W}:{W}:{W}:{W}:{W}:{W}:{W} V670 ::{W}:{W}:{W}:{W}:{W}:{W}:{W} V671 {W}::{W}:{W}:{W}:{W}:{W}:{W} V672 {W}:{W}::{W}:{W}:{W}:{W}:{W} V673 {W}:{W}:{W}::{W}:{W}:{W}:{W} V674 {W}:{W}:{W}:{W}::{W}:{W}:{W} V675 {W}:{W}:{W}:{W}:{W}::{W}:{W} V676 {W}:{W}:{W}:{W}:{W}:{W}::{W} V677 {W}:{W}:{W}:{W}:{W}:{W}:{W}:: V660 ::{W}:{W}:{W}:{W}:{W}:{W} V661 {W}::{W}:{W}:{W}:{W}:{W} V662 {W}:{W}::{W}:{W}:{W}:{W} V663 {W}:{W}:{W}::{W}:{W}:{W} V664 {W}:{W}:{W}:{W}::{W}:{W} V665 {W}:{W}:{W}:{W}:{W}::{W} V666 {W}:{W}:{W}:{W}:{W}:{W}:: V650 ::{W}:{W}:{W}:{W}:{W} V651 {W}::{W}:{W}:{W}:{W} V652 {W}:{W}::{W}:{W}:{W} V653 {W}:{W}:{W}::{W}:{W} V654 {W}:{W}:{W}:{W}::{W} V655 {W}:{W}:{W}:{W}:{W}:: V640 ::{W}:{W}:{W}:{W} V641 {W}::{W}:{W}:{W} V642 {W}:{W}::{W}:{W} V643 {W}:{W}:{W}::{W} V644 {W}:{W}:{W}:{W}:: V630 ::{W}:{W}:{W} V631 {W}::{W}:{W} V632 {W}:{W}::{W} V633 {W}:{W}:{W}:: V620 ::{W}:{W} V621 {W}::{W} V622 {W}:{W}:: V610 ::{W} V611 {W}:: V600 :: V6604 {W}:{W}:{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} V6504 ::{W}:{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} V6514 {W}::{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} V6524 {W}:{W}::{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} V6534 {W}:{W}:{W}::{W}:{W}:{N}\.{N}\.{N}\.{N} V6544 {W}:{W}:{W}:{W}::{W}:{N}\.{N}\.{N}\.{N} V6554 {W}:{W}:{W}:{W}:{W}::{N}\.{N}\.{N}\.{N} V6404 ::{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} V6414 {W}::{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} V6424 {W}:{W}::{W}:{W}:{N}\.{N}\.{N}\.{N} V6434 {W}:{W}:{W}::{W}:{N}\.{N}\.{N}\.{N} V6444 {W}:{W}:{W}:{W}::{N}\.{N}\.{N}\.{N} V6304 ::{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} V6314 {W}::{W}:{W}:{N}\.{N}\.{N}\.{N} V6324 {W}:{W}::{W}:{N}\.{N}\.{N}\.{N} V6334 {W}:{W}:{W}::{N}\.{N}\.{N}\.{N} V6204 ::{W}:{W}:{N}\.{N}\.{N}\.{N} V6214 {W}::{W}:{N}\.{N}\.{N}\.{N} V6224 {W}:{W}::{N}\.{N}\.{N}\.{N} V6104 ::{W}:{N}\.{N}\.{N}\.{N} V6114 {W}::{N}\.{N}\.{N}\.{N} V6004 ::{N}\.{N}\.{N}\.{N} V6 ({V680}|{V670}|{V671}|{V672}|{V673}|{V674}|{V675}|{V676}|{V677}|{V660}|{V661}|{V662}|{V663}|{V664}|{V665}|{V666}|{V650}|{V651}|{V652}|{V653}|{V654}|{V655}|{V640}|{V641}|{V642}|{V643}|{V644}|{V630}|{V631}|{V632}|{V633}|{V620}|{V621}|{V622}|{V610}|{V611}|{V600}|{V6604}|{V6504}|{V6514}|{V6524}|{V6534}|{V6544}|{V6554}|{V6404}|{V6414}|{V6424}|{V6434}|{V6444}|{V6304}|{V6314}|{V6324}|{V6334}|{V6204}|{V6214}|{V6224}|{V6104}|{V6114}|{V6004}) %% dst return DST; src return SRC; link|ether|ppp|slip return LINK; fddi return LINK; arp return ARP; rarp return RARP; ip return IP; tcp return TCP; udp return UDP; icmp return ICMP; igmp return IGMP; igrp return IGRP; pim return PIM; ip6 return IPV6; icmp6 return ICMPV6; ah return AH; esp return ESP; atalk return ATALK; decnet return DECNET; lat return LAT; sca return SCA; moprc return MOPRC; mopdl return MOPDL; host return HOST; net return NET; mask return MASK; port return PORT; proto return PROTO; protochain { #ifdef NO_PROTOCHAIN bpf_error("%s not supported", yytext); #else return PROTOCHAIN; #endif } gateway return GATEWAY; less return LESS; greater return GREATER; byte return BYTE; broadcast return TK_BROADCAST; multicast return TK_MULTICAST; and|"&&" return AND; or|"||" return OR; not return '!'; len|length return LEN; inbound return INBOUND; outbound return OUTBOUND; [ \n\t] ; [+\-*/:\[\]!<>()&|=] return yytext[0]; ">=" return GEQ; "<=" return LEQ; "!=" return NEQ; "==" return '='; "<<" return LSH; ">>" return RSH; {N} { yylval.i = stoi((char *)yytext); return NUM; } ({N}\.{N})|({N}\.{N}\.{N})|({N}\.{N}\.{N}\.{N}) { yylval.s = sdup((char *)yytext); return HID; } {B}:{B}:{B}:{B}:{B}:{B} { yylval.e = pcap_ether_aton((char *)yytext); return EID; } {V6} { #ifdef INET6 struct addrinfo hints, *res; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET6; hints.ai_flags = AI_NUMERICHOST; if (getaddrinfo(yytext, NULL, &hints, &res)) bpf_error("bogus IPv6 address %s", yytext); else { yylval.e = sdup((char *)yytext); return HID6; } #else bpf_error("IPv6 address %s not supported", yytext); #endif /*INET6*/ } {B}:+({B}:+)+ { bpf_error("bogus ethernet address %s", yytext); } [A-Za-z0-9][-_.A-Za-z0-9]*[.A-Za-z0-9] { yylval.s = sdup((char *)yytext); return ID; } "\\"[^ !()\n\t]+ { yylval.s = sdup((char *)yytext + 1); return ID; } [^ \[\]\t\n\-_.A-Za-z0-9!<>()&|=]+i { bpf_error("illegal token: %s\n", yytext); } . { bpf_error("illegal char '%c'", *yytext); } %% void lex_init(buf) char *buf; { in_buffer = buf; } /* * Also define a yywrap. Note that if we're using flex, it will * define a macro to map this identifier to pcap_wrap. */ int yywrap() { return 1; } /* Hex digit to integer. */ static inline int xdtoi(c) register int c; { if (isdigit(c)) return c - '0'; else if (islower(c)) return c - 'a' + 10; else return c - 'A' + 10; } /* * Convert string to integer. Just like atoi(), but checks for * preceding 0x or 0 and uses hex or octal instead of decimal. */ static int stoi(s) char *s; { int base = 10; int n = 0; if (*s == '0') { if (s[1] == 'x' || s[1] == 'X') { s += 2; base = 16; } else { base = 8; s += 1; } } while (*s) n = n * base + xdtoi(*s++); return n; } libpcap-0.5/./lbl/ 40755 263 461 0 7136054726 12307 5ustar mcrtcpdumplibpcap-0.5/./lbl/CVS/ 40755 263 461 0 7136054726 12742 5ustar mcrtcpdumplibpcap-0.5/./lbl/CVS/Root100644 263 461 61 7136054725 13641 0ustar mcrtcpdump:pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master libpcap-0.5/./lbl/CVS/Repository100644 263 461 14 7136054725 15073 0ustar mcrtcpdumplibpcap/lbl libpcap-0.5/./lbl/CVS/Entries100644 263 461 403 7136054726 14350 0ustar mcrtcpdump/gnuc.h/1.3.1.1/Thu Oct 7 23:46:41 1999//Tlibpcap_0_5rel2 /os-solaris2.h/1.18.1.1/Thu Oct 7 23:46:41 1999//Tlibpcap_0_5rel2 /os-sunos4.h/1.32.1.1/Thu Oct 7 23:46:41 1999//Tlibpcap_0_5rel2 /os-ultrix4.h/1.19.1.1/Thu Oct 7 23:46:41 1999//Tlibpcap_0_5rel2 D libpcap-0.5/./lbl/CVS/Tag100644 263 461 21 7136054726 13426 0ustar mcrtcpdumpNlibpcap_0_5rel2 libpcap-0.5/./lbl/os-sunos4.h100644 263 461 14175 6777230341 14456 0ustar mcrtcpdump/* * Copyright (c) 1989, 1990, 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. * * @(#) $Header: /tcpdump/master/libpcap/lbl/os-sunos4.h,v 1.32.1.1 1999/10/07 23:46:41 mcr Exp $ (LBL) */ /* Prototypes missing in SunOS 4 */ #ifdef FILE int _filbuf(FILE *); int _flsbuf(u_char, FILE *); int fclose(FILE *); int fflush(FILE *); int fgetc(FILE *); int fprintf(FILE *, const char *, ...); int fputc(int, FILE *); int fputs(const char *, FILE *); u_int fread(void *, u_int, u_int, FILE *); int fseek(FILE *, long, int); u_int fwrite(const void *, u_int, u_int, FILE *); int pclose(FILE *); void rewind(FILE *); void setbuf(FILE *, char *); int setlinebuf(FILE *); int ungetc(int, FILE *); int vfprintf(FILE *, const char *, ...); int vprintf(const char *, ...); #endif #if __GNUC__ <= 1 int read(int, char *, u_int); int write(int, char *, u_int); #endif long a64l(const char *); #ifdef __STDC__ struct sockaddr; #endif int accept(int, struct sockaddr *, int *); int bind(int, struct sockaddr *, int); int bcmp(const void *, const void *, u_int); void bcopy(const void *, void *, u_int); void bzero(void *, int); int chroot(const char *); int close(int); void closelog(void); int connect(int, struct sockaddr *, int); char *crypt(const char *, const char *); int daemon(int, int); int fchmod(int, int); int fchown(int, int, int); void endgrent(void); void endpwent(void); void endservent(void); #ifdef __STDC__ struct ether_addr; #endif struct ether_addr *ether_aton(const char *); int flock(int, int); #ifdef __STDC__ struct stat; #endif int fstat(int, struct stat *); #ifdef __STDC__ struct statfs; #endif int fstatfs(int, struct statfs *); int fsync(int); #ifdef __STDC__ struct timeb; #endif int ftime(struct timeb *); int ftruncate(int, off_t); int getdtablesize(void); long gethostid(void); int gethostname(char *, int); int getopt(int, char * const *, const char *); int getpagesize(void); char *getpass(char *); int getpeername(int, struct sockaddr *, int *); int getpriority(int, int); #ifdef __STDC__ struct rlimit; #endif int getrlimit(int, struct rlimit *); int getsockname(int, struct sockaddr *, int *); int getsockopt(int, int, int, char *, int *); #ifdef __STDC__ struct timeval; struct timezone; #endif int gettimeofday(struct timeval *, struct timezone *); char *getusershell(void); char *getwd(char *); int initgroups(const char *, int); int ioctl(int, int, caddr_t); int iruserok(u_long, int, char *, char *); int isatty(int); int killpg(int, int); int listen(int, int); #ifdef __STDC__ struct utmp; #endif void login(struct utmp *); int logout(const char *); off_t lseek(int, off_t, int); int lstat(const char *, struct stat *); int mkstemp(char *); char *mktemp(char *); int munmap(caddr_t, int); void openlog(const char *, int, int); void perror(const char *); int printf(const char *, ...); int puts(const char *); long random(void); int readlink(const char *, char *, int); #ifdef __STDC__ struct iovec; #endif int readv(int, struct iovec *, int); int recv(int, char *, u_int, int); int recvfrom(int, char *, u_int, int, struct sockaddr *, int *); int rename(const char *, const char *); int rcmd(char **, u_short, char *, char *, char *, int *); int rresvport(int *); int send(int, char *, u_int, int); int sendto(int, char *, u_int, int, struct sockaddr *, int); int setenv(const char *, const char *, int); int seteuid(int); int setpriority(int, int, int); int select(int, fd_set *, fd_set *, fd_set *, struct timeval *); int setpgrp(int, int); void setpwent(void); int setrlimit(int, struct rlimit *); void setservent(int); int setsockopt(int, int, int, char *, int); int shutdown(int, int); int sigblock(int); void (*signal (int, void (*) (int))) (int); int sigpause(int); int sigsetmask(int); #ifdef __STDC__ struct sigvec; #endif int sigvec(int, struct sigvec *, struct sigvec*); int snprintf(char *, size_t, const char *, ...); int socket(int, int, int); int socketpair(int, int, int, int *); int symlink(const char *, const char *); void srandom(int); int sscanf(char *, const char *, ...); int stat(const char *, struct stat *); int statfs(char *, struct statfs *); char *strerror(int); int strcasecmp(const char *, const char *); #ifdef __STDC__ struct tm; #endif int strftime(char *, int, char *, struct tm *); int strncasecmp(const char *, const char *, int); long strtol(const char *, char **, int); void sync(void); void syslog(int, const char *, ...); int system(const char *); long tell(int); time_t time(time_t *); char *timezone(int, int); int tolower(int); int toupper(int); int truncate(char *, off_t); void unsetenv(const char *); int vfork(void); int vsprintf(char *, const char *, ...); int writev(int, struct iovec *, int); #ifdef __STDC__ struct rusage; #endif int utimes(const char *, struct timeval *); #if __GNUC__ <= 1 int wait(int *); pid_t wait3(int *, int, struct rusage *); #endif /* Ugly signal hacking */ #ifdef SIG_ERR #undef SIG_ERR #define SIG_ERR (void (*)(int))-1 #undef SIG_DFL #define SIG_DFL (void (*)(int))0 #undef SIG_IGN #define SIG_IGN (void (*)(int))1 #ifdef KERNEL #undef SIG_CATCH #define SIG_CATCH (void (*)(int))2 #endif #undef SIG_HOLD #define SIG_HOLD (void (*)(int))3 #endif libpcap-0.5/./lbl/gnuc.h100644 263 461 1361 6777230341 13511 0ustar mcrtcpdump/* @(#) $Header: /tcpdump/master/libpcap/lbl/Attic/gnuc.h,v 1.3.1.1 1999/10/07 23:46:41 mcr Exp $ (LBL) */ /* Define __P() macro, if necessary */ #ifndef __P #if __STDC__ #define __P(protos) protos #else #define __P(protos) () #endif #endif /* inline foo */ #ifdef __GNUC__ #define inline __inline #else #define inline #endif /* * Handle new and old "dead" routine prototypes * * For example: * * __dead void foo(void) __attribute__((volatile)); * */ #ifdef __GNUC__ #ifndef __dead #define __dead volatile #endif #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) #ifndef __attribute__ #define __attribute__(args) #endif #endif #else #ifndef __dead #define __dead #endif #ifndef __attribute__ #define __attribute__(args) #endif #endif libpcap-0.5/./lbl/os-solaris2.h100644 263 461 4234 6777230341 14734 0ustar mcrtcpdump/* * 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-solaris2.h,v 1.18.1.1 1999/10/07 23:46:41 mcr 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 *); libpcap-0.5/./lbl/os-ultrix4.h100644 263 461 3357 6777230341 14616 0ustar mcrtcpdump/* * Copyright (c) 1990, 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. * * @(#) $Header: /tcpdump/master/libpcap/lbl/os-ultrix4.h,v 1.19.1.1 1999/10/07 23:46:41 mcr Exp $ (LBL) */ /* Prototypes missing in Ultrix 4 */ int bcmp(const char *, const char *, u_int); void bcopy(const void *, void *, u_int); void bzero(void *, u_int); void endservent(void); int getopt(int, char * const *, const char *); #ifdef __STDC__ struct timeval; struct timezone; #endif int gettimeofday(struct timeval *, struct timezone *); int ioctl(int, int, caddr_t); int pfopen(char *, int); int setlinebuf(FILE *); int socket(int, int, int); int strcasecmp(const char *, const char *); libpcap-0.5/./linux-include/ 40755 263 461 0 7136054730 14311 5ustar mcrtcpdumplibpcap-0.5/./linux-include/CVS/ 40755 263 461 0 7136054731 14745 5ustar mcrtcpdumplibpcap-0.5/./linux-include/CVS/Root100644 263 461 61 7136054727 15652 0ustar mcrtcpdump:pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master libpcap-0.5/./linux-include/CVS/Repository100644 263 461 26 7136054727 17107 0ustar mcrtcpdumplibpcap/linux-include libpcap-0.5/./linux-include/CVS/Entries100644 263 461 16 7136054731 16333 0ustar mcrtcpdumpD/netinet//// libpcap-0.5/./linux-include/CVS/Tag100644 263 461 21 7136054727 15436 0ustar mcrtcpdumpTlibpcap_0_5rel2 libpcap-0.5/./linux-include/netinet/ 40755 263 461 0 7136054731 15760 5ustar mcrtcpdumplibpcap-0.5/./linux-include/netinet/CVS/ 40755 263 461 0 7136054731 16413 5ustar mcrtcpdumplibpcap-0.5/./linux-include/netinet/CVS/Root100644 263 461 61 7136054730 17312 0ustar mcrtcpdump:pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master libpcap-0.5/./linux-include/netinet/CVS/Repository100644 263 461 36 7136054730 20550 0ustar mcrtcpdumplibpcap/linux-include/netinet libpcap-0.5/./linux-include/netinet/CVS/Entries100644 263 461 176 7136054731 20030 0ustar mcrtcpdump/if_ether.h/1.1.1.1/Thu Oct 7 23:46:41 1999//Tlibpcap_0_5rel2 /ip_var.h/1.1.1.1/Thu Oct 7 23:46:41 1999//Tlibpcap_0_5rel2 D libpcap-0.5/./linux-include/netinet/CVS/Tag100644 263 461 21 7136054731 17077 0ustar mcrtcpdumpNlibpcap_0_5rel2 libpcap-0.5/./linux-include/netinet/if_ether.h100644 263 461 6403 6777230341 20021 0ustar mcrtcpdump/* * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the 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. * * @(#)if_ether.h 8.3 (Berkeley) 5/2/95 */ #include /* * Ethernet address - 6 octets */ struct ether_addr { u_char ether_addr_octet[6]; }; /* * Structure of a 10Mb/s Ethernet header. */ struct ether_header { u_char ether_dhost[6]; u_char ether_shost[6]; u_short ether_type; }; #define ETHERTYPE_PUP 0x0200 /* PUP protocol */ #define ETHERTYPE_IP 0x0800 /* IP protocol */ #define ETHERTYPE_ARP 0x0806 /* Addr. resolution protocol */ #define ETHERTYPE_REVARP 0x8035 /* reverse Addr. resolution protocol */ /* * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have * (type-ETHERTYPE_TRAIL)*512 bytes of data followed * by an ETHER type (as given above) and then the (variable-length) header. */ #define ETHERTYPE_TRAIL 0x1000 /* Trailer packet */ #define ETHERTYPE_NTRAILER 16 #define ETHERMTU 1500 #define ETHERMIN (60-14) /* * Ethernet Address Resolution Protocol. * * See RFC 826 for protocol description. Structure below is adapted * to resolving internet addresses. Field names used correspond to * RFC 826. */ struct ether_arp { struct arphdr ea_hdr; /* fixed-size header */ u_char arp_sha[6]; /* sender hardware address */ u_char arp_spa[4]; /* sender protocol address */ u_char arp_tha[6]; /* target hardware address */ u_char arp_tpa[4]; /* target protocol address */ }; #define arp_hrd ea_hdr.ar_hrd #define arp_pro ea_hdr.ar_pro #define arp_hln ea_hdr.ar_hln #define arp_pln ea_hdr.ar_pln #define arp_op ea_hdr.ar_op libpcap-0.5/./linux-include/netinet/ip_var.h100644 263 461 15653 6777230341 17543 0ustar mcrtcpdump/* * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the 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. * * @(#)ip_var.h 8.2 (Berkeley) 1/9/95 */ #include /* * Overlay for ip header used by other protocols (tcp, udp). */ struct ipovly { caddr_t ih_next, ih_prev; /* for protocol sequence q's */ u_char ih_x1; /* (unused) */ u_char ih_pr; /* protocol */ short ih_len; /* protocol length */ struct in_addr ih_src; /* source internet address */ struct in_addr ih_dst; /* destination internet address */ }; /* * Ip reassembly queue structure. Each fragment * being reassembled is attached to one of these structures. * They are timed out after ipq_ttl drops to 0, and may also * be reclaimed if memory becomes tight. */ struct ipq { struct ipq *next,*prev; /* to other reass headers */ u_char ipq_ttl; /* time for reass q to live */ u_char ipq_p; /* protocol of this fragment */ u_short ipq_id; /* sequence id for reassembly */ struct ipasfrag *ipq_next,*ipq_prev; /* to ip headers of fragments */ struct in_addr ipq_src,ipq_dst; }; /* * Ip header, when holding a fragment. * * Note: ipf_next must be at same offset as ipq_next above */ struct ipasfrag { #if BYTE_ORDER == LITTLE_ENDIAN u_char ip_hl:4, ip_v:4; #endif #if BYTE_ORDER == BIG_ENDIAN u_char ip_v:4, ip_hl:4; #endif u_char ipf_mff; /* XXX overlays ip_tos: use low bit * to avoid destroying tos; * copied from (ip_off&IP_MF) */ short ip_len; u_short ip_id; short ip_off; u_char ip_ttl; u_char ip_p; u_short ip_sum; struct ipasfrag *ipf_next; /* next fragment */ struct ipasfrag *ipf_prev; /* previous fragment */ }; /* * Structure stored in mbuf in inpcb.ip_options * and passed to ip_output when ip options are in use. * The actual length of the options (including ipopt_dst) * is in m_len. */ #define MAX_IPOPTLEN 40 struct ipoption { struct in_addr ipopt_dst; /* first-hop dst if source routed */ char ipopt_list[MAX_IPOPTLEN]; /* options proper */ }; struct ipstat { n_long ips_total; /* total packets received */ n_long ips_badsum; /* checksum bad */ n_long ips_tooshort; /* packet too short */ n_long ips_toosmall; /* not enough data */ n_long ips_badhlen; /* ip header length < data size */ n_long ips_badlen; /* ip length < ip header length */ n_long ips_fragments; /* fragments received */ n_long ips_fragdropped; /* frags dropped (dups, out of space) */ n_long ips_fragtimeout; /* fragments timed out */ n_long ips_forward; /* packets forwarded */ n_long ips_cantforward; /* packets rcvd for unreachable dest */ n_long ips_redirectsent; /* packets forwarded on same net */ n_long ips_noproto; /* unknown or unsupported protocol */ n_long ips_delivered; /* datagrams delivered to upper level*/ n_long ips_localout; /* total ip packets generated here */ n_long ips_odropped; /* lost packets due to nobufs, etc. */ n_long ips_reassembled; /* total packets reassembled ok */ n_long ips_fragmented; /* datagrams sucessfully fragmented */ n_long ips_ofragments; /* output fragments created */ n_long ips_cantfrag; /* don't fragment flag was set, etc. */ n_long ips_badoptions; /* error in option processing */ n_long ips_noroute; /* packets discarded due to no route */ n_long ips_badvers; /* ip version != 4 */ n_long ips_rawout; /* total raw ip packets generated */ }; #ifdef KERNEL /* flags passed to ip_output as last parameter */ #define IP_FORWARDING 0x1 /* most of ip header exists */ #define IP_RAWOUTPUT 0x2 /* raw ip header exists */ #define IP_ROUTETOIF SO_DONTROUTE /* bypass routing tables */ #define IP_ALLOWBROADCAST SO_BROADCAST /* can send broadcast packets */ struct ipstat ipstat; struct ipq ipq; /* ip reass. queue */ u_short ip_id; /* ip packet ctr, for ids */ int ip_defttl; /* default IP ttl */ int in_control __P((struct socket *, n_long, caddr_t, struct ifnet *)); int ip_ctloutput __P((int, struct socket *, int, int, struct mbuf **)); void ip_deq __P((struct ipasfrag *)); int ip_dooptions __P((struct mbuf *)); void ip_drain __P((void)); void ip_enq __P((struct ipasfrag *, struct ipasfrag *)); void ip_forward __P((struct mbuf *, int)); void ip_freef __P((struct ipq *)); void ip_freemoptions __P((struct ip_moptions *)); int ip_getmoptions __P((int, struct ip_moptions *, struct mbuf **)); void ip_init __P((void)); int ip_mforward __P((struct mbuf *, struct ifnet *)); int ip_optcopy __P((struct ip *, struct ip *)); int ip_output __P((struct mbuf *, struct mbuf *, struct route *, int, struct ip_moptions *)); int ip_pcbopts __P((struct mbuf **, struct mbuf *)); struct ip * ip_reass __P((struct ipasfrag *, struct ipq *)); struct in_ifaddr * ip_rtaddr __P((struct in_addr)); int ip_setmoptions __P((int, struct ip_moptions **, struct mbuf *)); void ip_slowtimo __P((void)); struct mbuf * ip_srcroute __P((void)); void ip_stripoptions __P((struct mbuf *, struct mbuf *)); int ip_sysctl __P((int *, n_long, void *, size_t *, void *, size_t)); void ipintr __P((void)); int rip_ctloutput __P((int, struct socket *, int, int, struct mbuf **)); void rip_init __P((void)); void rip_input __P((struct mbuf *)); int rip_output __P((struct mbuf *, struct socket *, n_long)); int rip_usrreq __P((struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *)); #endif