softflowd-0.9.9004075500017500001750000000000001171606503400116365ustar00djmdjmsoftflowd-0.9.9/softflowctl.8010064400017500001750000000057121171606473600143660ustar00djmdjm.\" Copyright (c) 2002 Damien Miller. 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. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. .\" .Dd October 18, 2002 .Dt SOFTFLOWCTL 8 .Os .Sh NAME .Nm softflowctl .Nd Remote control program for softflowd .Sh SYNOPSIS .Nm softflowctl .Op Fl h .Op Fl c Ar ctl_sock .Ar command .Sh DESCRIPTION .Nm is a remote control program used to control a running .Xr softflowd 8 daemon. .Pp The command line options are as follows: .Bl -tag -width Ds .It Fl c Ar ctlsock Specify an alternate location for the remote control socket. Default is .Pa /var/run/softflowd.ctl .It Fl h Display command line usage information. .El .Pp .Sh COMMANDS .Bl -tag -width Ds .It Pa shutdown Ask .Xr softflowd 8 to gracefully exit. This is equivalent to sending it a .Dv SIGTERM or .Dv SIGINT . .It Pa exit Ask .Xr softflowd 8 to immediately exit. No flow expiry processing or data export is performed. .It Pa expire-all Immediately expire all tracked flows. .It Pa delete-all Immediately delete all tracked flows. No flow expiry processing or data export is performed. .It Pa statistics Return statistics collected by .Xr softflowd 8 on expired flows. .It Pa debug+ Increase the debugging level of .Xr softflowd 8 .It Pa debug- Decrease the debugging level. .It Pa stop-gather Stops network data collection by .Xr softflowd 8 . .It Pa start-gather Resumes network data collection. .It Pa dump-flows Return information on all tracked flows. .It Pa timeouts Print information on flow timeout parameters. .It Pa send-template Resend a NetFlow v.9 template record before the next flow export. Has no effect for other flow export versions. .El .Sh BUGS All times are unconditionally displayed in UTC, regardless of the system timezone. .Sh AUTHORS .An Damien Miller Aq djm@mindrot.org .Sh SEE ALSO .Xr softflowd 8 softflowd-0.9.9/.hg_archival.txt010064400017500001750000000002031171606473600150030ustar00djmdjmrepo: a471267f42340e3926cc0d68c98ec64789cffcca node: c496d4d4934828f6b62ff38e1702891f75710b0a branch: default tag: softflowd-0.9.9 softflowd-0.9.9/.cvsignore010064400017500001750000000000261171606473600137200ustar00djmdjmsoftflowd softflowctl softflowd-0.9.9/.hgtags010064400017500001750000000020441171606473600132000ustar00djmdjm0e7b1c83c22d691f0c2dc6a964d1334250f9be95 PRE_EXPIRY_RB_CONVERT 0f4d543cfadd3f34162eb5e2785c057c548cfd22 SOFTFLOWD_0_3 4680effcb255c612bc63f0ddedbea72f92151b59 SOFTFLOWD_0_9 51c8e6737def4f6dd6de2692c98a8fda0d646a54 SOFTFLOWD_0_6 7e447d5b8c8a7430bfaa234b45a06045b4ec04ba SOFTFLOWD_0_1 7eaa764bbb3dbf71d5b329e61aed810bf7107f4a SOFTFLOWD_0_9_2 8779cbdad42aaf29f981e2f9a7b617df8d2ac090 START 9a9e2cd7e3b5dd05b63927acad9d0ca9bf39ce26 SOFTFLOWD_0_9_7 9dae7a93ec5a71f921ea9ab8a46ad43942d28fc3 SOFTFLOWD_0_8 b0c4bca0d46803f21e656a8c486e8a6ccb4fa676 SOFTFLOWD_0_2 b7c24dd071091cbc74391e02799205c081edf8f1 SOFTFLOWD_0_8_1 bcbc1910e8a68a3351d3bad37ca55558ff66d17c BEFORE_TREE_CHANGES bf9ccfda73346e315d37415d32a7c69653d4a245 SOFTFLOWD_0_5 c025775ad959e68161ce6cf18a9ce9ffe35a92aa SOFTFLOWD_0_9_1 ca5de0007bccbf42748d02630db01bb8a8961a92 SOFTFLOWD_0_7 de48250d22aa20026d89fc715fff3bd27dcb0db1 PRE_BIDI eb6dc8d8b9c3166594cfa4bf5fd2c73c4a131820 SOFTFLOWD_0_7_1 f81d538391377dc23346ddda4bd2fb0520daf6ea SOFTFLOWD_0_9_6 ffda749c4623fcc78ea4a7ead6da6eeca64188aa SOFTFLOWD_0_9_8 softflowd-0.9.9/LICENSE010064400017500001750000000162371171606473600127400ustar00djmdjmOriginal code is licensed under the following BSD-style license: /* * Copyright 2002-2006 Damien Miller 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. */ closefrom.c: /* * Copyright (c) 2004 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ convtime.c: /* * Copyright (c) 2001 Kevin Steves. 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. */ daemon.c: /*- * Copyright (c) 1990, 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. 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. */ strlcat.c, strlcpy.c: /* * Copyright (c) 1998 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ sys-tree.h: /* * Copyright 2002 Niels Provos * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. */ softflowd-0.9.9/Makefile.in010064400017500001750000000031061171606473600137670ustar00djmdjmprefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ sbindir=@sbindir@ libexecdir=@libexecdir@ datadir=@datadir@ mandir=@mandir@ sysconfdir=@sysconfdir@ srcdir=@srcdir@ top_srcdir=@top_srcdir@ VPATH=@srcdir@ CC=@CC@ LDFLAGS=@LDFLAGS@ CFLAGS=@CFLAGS@ CPPFLAGS=-I$(srcdir) @CPPFLAGS@ LIBS=@LIBS@ EXEEXT=@EXEEXT@ INSTALL=@INSTALL@ #CFLAGS+=-DFLOW_RB # Use red-black tree for flows CFLAGS+=-DFLOW_SPLAY # Use splay tree for flows CFLAGS+=-DEXPIRY_RB # Use red-black tree for expiry events #CFLAGS+=-DEXPIRY_SPLAY # Use splay tree for expiry events TARGETS=softflowd${EXEEXT} softflowctl${EXEEXT} COMMON=convtime.o strlcpy.o strlcat.o closefrom.o daemon.o SOFTFLOWD=softflowd.o log.o netflow1.o netflow5.o netflow9.o freelist.o all: $(TARGETS) softflowd${EXEEXT}: ${SOFTFLOWD} $(COMMON) $(CC) $(LDFLAGS) -o $@ ${SOFTFLOWD} $(COMMON) $(LIBS) softflowctl${EXEEXT}: softflowctl.o $(COMMON) $(CC) $(LDFLAGS) -o $@ softflowctl.o $(COMMON) $(LIBS) clean: rm -f $(TARGETS) *.o core *.core realclean: clean rm -rf autom4te.cache Makefile config.log config.status distclean: realclean rm -f config.h* configure strip: strip $(TARGETS) install: [ -d $(DESTDIR)$(sbindir) ] || \ $(srcdir)/mkinstalldirs $(DESTDIR)$(sbindir) [ -d $(DESTDIR)$(mandir)/man8 ] || \ $(srcdir)/mkinstalldirs $(DESTDIR)$(mandir)/man8 $(INSTALL) -m 0755 -s softflowd $(DESTDIR)$(sbindir)/softflowd $(INSTALL) -m 0755 -s softflowctl $(DESTDIR)$(sbindir)/softflowctl $(INSTALL) -m 0644 softflowd.8 $(DESTDIR)$(mandir)/man8/softflowd.8 $(INSTALL) -m 0644 softflowctl.8 $(DESTDIR)$(mandir)/man8/softflowctl.8 softflowd-0.9.9/README010064400017500001750000000047541171606473600126140ustar00djmdjmWelcome to softflowd, a flow-based network monitor. Introduction ------------ softflowd listens promiscuously on a network interface and semi-statefully tracks network flows. These flows can be reported using NetFlow version 1, 5 or 9 datagrams. softflowd is fully IPv6 capable: it can track IPv6 flows and export to IPv6 hosts. More details about softflowd's function and usage may be found in the supplied manpages, which you can view prior to installation using /usr/bin/nroff -c -mandoc softflowd.8 | less /usr/bin/nroff -c -mandoc softflowctl.8 | less If you are in need of a NetFlow collector, you may be interested in softflowd's companion project "flowd" (http://www.mindrot.org/flowd.html). flowd is a NetFlow collector that is maintained in parallel with softflowd and includes a few handy features, such as the ability to filter flows it receives as well as Perl and Python APIs to its storage format. NB. You don't have to use flowd: any NetFlow compatible collector should work with softflowd. An example Perl collector is included for testing purposes as collector.pl, but it doesn't yet support NetFlow v.9 Installing ---------- Building softflowd should be as simple as typing: ./configure make make install Unfortunately some systems like to make life complicated. Things work fine on the systems that I develop and test on (OpenBSD and Linux). There is peliminary support for Solaris 9 (i.e. it compiled), but no testing on this platform has been performed. Licensing --------- Softflowd is licensed under a two-term BSD license (see the source files for details). The code in sys-tree.h is Copyright Niels Provos and comes straight from OpenBSD CVS, convtime.c comes is Copyright Kevin Steves and comes from OpenSSH (misc.c). Both of these files are licensed under two-term BSD licenses too. strlcpy.c, strlcat.c and closefrom.c also come from OpenBSD CVS and are Copyright Todd C. Miller. Please refer to the LICENSE file for full details. Reporting Bugs -------------- Please report bugs in softflowd to http://bugzilla.mindrot.org/ If you find a security bug, please report it directly by email. If you have any feedback or questions, please email me: Contributing ------------ Softflowd has an extensive TODO list of interesting features, large and small, that are waiting to be implemented. If you are interested in helping, please contact me. The latest source code may be obtained from Google Code: http://code.google.com/p/softflowd/ Damien Miller softflowd-0.9.9/TODO010064400017500001750000000104241171606473600124130ustar00djmdjmThings yet to do: softflowd --------- - Use strtonum() Flow tracking engine - Calculate hash over flow and use it as a key to avoid lots of cache-trashing comparisons - Verify checksums (maybe. perhaps bad for accounting, good for flow tracking) - Fragment processing - We don't handle fragments right - This shouldn't be too hard or too memory intensive. We just need to keep a tree of fragment entries. Each entry would need to contain enough information to reconstruct the flow (source/dest addr, etc), but also fragment related info: IP id, list of fragment offsets. etc. - When we receive a new fragment, we add an entry to this tree (keyed by source IP, protocol, IP id) - Each new fragment matched in the tree gets its offset added to the list, until all fragments have been seen - Must be careful, as later fragments may arrive before inital one - When does accounting occur? - Upon receipt of inital fragment? (and thus for ever frag thereafter) - When we have seen all fragments? (what if we don't?) - Must limit size of tree - Must have fragment timeout (what happens then, apart from removal?) - Timeouts - Timeout for unanswered TCP connection - Ditto orphaned connections (one packet in one direction only) - Track ICMP generated by TCP/UDP session (painful, probably unecessary) - More datalink types - Improve fast-expiry of TCP session by tracking FIN sequence numbers - Multiple interface support - Requires some way to avoid duplicate recording of flows (IP ID) - Track IPsec SPIs - Track ToS / DSCP - Make counters 64 bits - We can report these directly for NetFlow v.9 - For older NetFlow, report by sending multiple flows until counter < 2^32 Misc features - Ability to open more than one interface (maybe) - Ability to read more than one pcap file (maybe) - Fork for ctlsock actions? (don't block mainloop) - Remote control over network (requires SSL) Performance - Profile and see where the hot spots are - Fast "new flow" test using a bloom filter - See if we can reduce per-packet overhead more - Cost of expiry remove and re-add per packet - Stop run-time malloc (maybe) - Preallocate a pool of expiry events and flow entries - keep a queue, pick/push first from head Exporter features - sflow support (www.sflow.org) - Needs XDR encoding - Ability to export to multiple hosts - Partly done, just need to keep a list of targets instead of a single one - Ability to directly write to file (maybe. If so, reuse flowd store code) - NetFlow v.9 field selection - Get AS numbers from bgpd and fill in to Netflow packets Statistics code - Collect more statistics (maybe) - Advanced packet analysis: store hash of packet payload, keep statistics on traffic similarity - Bloom filter? - Option to record histograms of - Flow lifetime and size, packet size - Flow bandwidth - Per well-known-port - How to do this quicky? Memory efficiently? - Per IP address/range - How to do this quicky? Memory efficiently? - Moving averages - Track traffic over lifetime of flow - Maintain linked list traffic counts, keyed by time interval - E.g. key by (now / 300) - Or (now - start_time) / 300 (better) - When new packet comes in: - If timestamp of HEAD of list == (now / xxx), then counter += octets - Otherwise create new traffic counter at HEAD and update it - Then trim tail if the list length is too big - Maybe store "hunks" of data, rather than individual counts in the list, as storing a single int is a huge waste of space - Maybe a rrdtool-like heirarchy of timespans - 300 seconds (5 minutes) (2400 bytes) - 360 1-minute blocks (6 hours) (2880 bytes) - 288 10-minute blocks (2 days) (2304 bytes) - 336 1-hour blocks (2 weeks) (2688 bytes) - Total 10kb worst-case per-flow (scary, probably overkill) softflowctl ----------- - Extend interface - Query for specific flows (e.g. by address) - Do this in softflowd or softflowctl? - Expire/delete specific flows (maybe) - Runtime respecify timeouts - Real-time binary dump of flowtable (shm/mmap fd pass?) - ntop like view - Spiffy GUI (separate tool) softflowd-0.9.9/aclocal.m4010064400017500001750000000000211171606473600135530ustar00djmdjmdnl Nothing here softflowd-0.9.9/closefrom.c010064400017500001750000000051621171606473600140630ustar00djmdjm/* * Copyright (c) 2004 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "common.h" #ifndef HAVE_CLOSEFROM #include #include #include #include #include #include #include #ifdef HAVE_DIRENT_H # include # define NAMLEN(dirent) strlen((dirent)->d_name) #else # define dirent direct # define NAMLEN(dirent) (dirent)->d_namlen # ifdef HAVE_SYS_NDIR_H # include # endif # ifdef HAVE_SYS_DIR_H # include # endif # ifdef HAVE_NDIR_H # include # endif #endif #ifndef OPEN_MAX # define OPEN_MAX 256 #endif #ifndef lint static const char rcsid[] = "$Sudo: closefrom.c,v 1.6 2004/06/01 20:51:56 millert Exp $"; #endif /* lint */ /* * Close all file descriptors greater than or equal to lowfd. */ void closefrom(int lowfd) { long fd, maxfd; #if defined(HAVE_DIRFD) && defined(HAVE_PROC_PID) char fdpath[PATH_MAX], *endp; struct dirent *dent; DIR *dirp; int len; /* Check for a /proc/$$/fd directory. */ len = snprintf(fdpath, sizeof(fdpath), "/proc/%ld/fd", (long)getpid()); if (len != -1 && len <= sizeof(fdpath) && (dirp = opendir(fdpath))) { while ((dent = readdir(dirp)) != NULL) { fd = strtol(dent->d_name, &endp, 10); if (dent->d_name != endp && *endp == '\0' && fd >= 0 && fd < INT_MAX && fd >= lowfd && fd != dirfd(dirp)) (void) close((int) fd); } (void) closedir(dirp); } else #endif { /* * Fall back on sysconf() or getdtablesize(). We avoid checking * resource limits since it is possible to open a file descriptor * and then drop the rlimit such that it is below the open fd. */ #ifdef HAVE_SYSCONF maxfd = sysconf(_SC_OPEN_MAX); #else maxfd = getdtablesize(); #endif /* HAVE_SYSCONF */ if (maxfd < 0) maxfd = OPEN_MAX; for (fd = lowfd; fd < maxfd; fd++) (void) close((int) fd); } } #endif /* HAVE_CLOSEFROM */ softflowd-0.9.9/collector.pl010075500017500001750000000151411171606473600142520ustar00djmdjm#!/usr/bin/perl -w # This is a Cisco NetFlow datagram collector # Netflow protocol reference: # http://www.cisco.com/en/US/products/sw/netmgtsw/ps1964/products_implementation_design_guide09186a00800d6a11.html # XXX Doesn't support NetFlow 9 my $af; BEGIN { use strict; use warnings; use IO qw(Socket); use Socket; use Carp; use POSIX qw(strftime); use Getopt::Long; eval "use IO::Socket::INET6;"; eval "use Socket6;"; } ############################################################################ sub timestamp() { return strftime "%Y-%m-%dT%H:%M:%S", localtime; } sub fuptime($) { my $t = shift; my $r = ""; my $tmp; # Milliseconds $tmp = $t % 1000; $r = sprintf ".%03u%s", $tmp, $r; # Seconds $t = int($t / 1000); $tmp = $t % 60; $r = "${tmp}s${r}"; # Minutes $t = int($t / 60); $tmp = $t % 60; $r = "${tmp}m${r}" if $tmp; # Hours $t = int($t / 60); $tmp = $t % 24; $r = "${tmp}h${r}" if $tmp; # Days $t = int($t / 24); $tmp = $t % 7; $r = "${tmp}d${r}" if $tmp; # Weeks $t = int($t / 7); $tmp = $t % 52; $r = "${tmp}w${r}" if $tmp; # Years $t = int($t / 52); $r = "${tmp}y${r}" if $tmp; return $r; } sub do_listen($$) { my $port = shift or confess "No UDP port specified"; my $socket; if ($af == 4) { $socket = IO::Socket::INET->new(Proto=>'udp', LocalPort=>$port) or croak "Couldn't open UDP socket: $!"; } elsif ($af == 6) { $socket = IO::Socket::INET6->new(Proto=>'udp', LocalPort=>$port) or croak "Couldn't open UDP socket: $!"; } else { croak "Unsupported AF"; } return $socket; } sub process_nf_v1($$) { my $sender = shift; my $pkt = shift; my %header; my %flow; my $sender_s; %header = qw(); $sender_s = inet_ntoa($sender) if $af == 4; $sender_s = inet_ntop(AF_INET6, $sender) if $af == 6; ($header{ver}, $header{flows}, $header{uptime}, $header{secs}, $header{nsecs}) = unpack("nnNNN", $pkt); if (length($pkt) < (16 + (48 * $header{flows}))) { printf STDERR timestamp()." Short Netflow v.1 packet: %d < %d\n", length($pkt), 16 + (48 * $header{flows}); return; } printf timestamp() . " HEADER v.%u (%u flow%s)\n", $header{ver}, $header{flows}, $header{flows} == 1 ? "" : "s"; for(my $i = 0; $i < $header{flows}; $i++) { my $off = 16 + (48 * $i); my $ptr = substr($pkt, $off, 52); %flow = qw(); (my $src1, my $src2, my $src3, my $src4, my $dst1, my $dst2, my $dst3, my $dst4, my $nxt1, my $nxt2, my $nxt3, my $nxt4, $flow{in_ndx}, $flow{out_ndx}, $flow{pkts}, $flow{bytes}, $flow{start}, $flow{finish}, $flow{src_port}, $flow{dst_port}, my $pad1, $flow{protocol}, $flow{tos}, $flow{tcp_flags}) = unpack("CCCCCCCCCCCCnnNNNNnnnCCC", $ptr); $flow{src} = sprintf "%u.%u.%u.%u", $src1, $src2, $src3, $src4; $flow{dst} = sprintf "%u.%u.%u.%u", $dst1, $dst2, $dst3, $dst4; $flow{nxt} = sprintf "%u.%u.%u.%u", $nxt1, $nxt2, $nxt3, $nxt4; printf timestamp() . " " . "from %s started %s finish %s proto %u %s:%u > %s:%u %u " . "packets %u octets\n", $sender_s, fuptime($flow{start}), fuptime($flow{finish}), $flow{protocol}, $flow{src}, $flow{src_port}, $flow{dst}, $flow{dst_port}, $flow{pkts}, $flow{bytes}; } } sub process_nf_v5($$) { my $sender = shift; my $pkt = shift; my %header; my %flow; my $sender_s; %header = qw(); $sender_s = inet_ntoa($sender) if $af == 4; $sender_s = inet_ntop(AF_INET6, $sender) if $af == 6; ($header{ver}, $header{flows}, $header{uptime}, $header{secs}, $header{nsecs}, $header{flow_seq}, ) = unpack("nnNNNN", $pkt); if (length($pkt) < (24 + (48 * $header{flows}))) { printf STDERR timestamp()." Short Netflow v.1 packet: %d < %d\n", length($pkt), 24 + (48 * $header{flows}); return; } printf timestamp() . " HEADER v.%u (%u flow%s) seq %u\n", $header{ver}, $header{flows}, $header{flows} == 1 ? "" : "s", $header{flow_seq}; for(my $i = 0; $i < $header{flows}; $i++) { my $off = 24 + (48 * $i); my $ptr = substr($pkt, $off, 52); %flow = qw(); (my $src1, my $src2, my $src3, my $src4, my $dst1, my $dst2, my $dst3, my $dst4, my $nxt1, my $nxt2, my $nxt3, my $nxt4, $flow{in_ndx}, $flow{out_ndx}, $flow{pkts}, $flow{bytes}, $flow{start}, $flow{finish}, $flow{src_port}, $flow{dst_port}, my $pad1, $flow{tcp_flags}, $flow{protocol}, $flow{tos}, $flow{src_as}, $flow{dst_as}, $flow{src_mask}, $flow{dst_mask}) = unpack("CCCCCCCCCCCCnnNNNNnnCCCCnnCC", $ptr); $flow{src} = sprintf "%u.%u.%u.%u", $src1, $src2, $src3, $src4; $flow{dst} = sprintf "%u.%u.%u.%u", $dst1, $dst2, $dst3, $dst4; $flow{nxt} = sprintf "%u.%u.%u.%u", $nxt1, $nxt2, $nxt3, $nxt4; printf timestamp() . " " . "from %s started %s finish %s proto %u %s:%u > %s:%u %u " . "packets %u octets\n", $sender_s, fuptime($flow{start}), fuptime($flow{finish}), $flow{protocol}, $flow{src}, $flow{src_port}, $flow{dst}, $flow{dst_port}, $flow{pkts}, $flow{bytes}; } } ############################################################################ # Commandline options my $debug = 0; my $af4 = 0; my $af6 = 0; my $port; # Long option Short option GetOptions( 'debug+' => \$debug, 'd+' => \$debug, '4+' => \$af4, '6+' => \$af6, 'port=i' => \$port, 'p=i' => \$port); # Unbuffer output $| = 1; die "The -4 and -6 are mutually exclusive\n" if $af4 && $af6; die "You must specify a port (collector.pl -p XXX).\n" unless $port; $af4 = $af = 4 if $af4 || (!$af4 && !$af6); $af6 = $af = 6 if $af6; # These modules aren't standard everywhere, so load them only if necessary # Main loop - receive and process a packet for (;;) { my $socket; my $from; my $payload; my $ver; my $failcount = 0; my $netflow; my $junk; my $sender; # Open the listening port if we haven't already $socket = do_listen($port, $af) unless defined $socket; # Fetch a packet $from = $socket->recv($payload, 8192, 0); ($junk, $sender) = unpack_sockaddr_in($from) if $af4; ($junk, $sender) = unpack_sockaddr_in6($from) if $af6; # Reopen listening socket on error if (!defined $from) { $socket->close; undef $socket; $failcount++; die "Couldn't recv: $!\n" if ($failcount > 5); next; # Socket will be reopened at start of loop } if (length($payload) < 16) { printf STDERR timestamp()." Short packet recevied: %d < 16\n", length($payload); next; } # The version is always the first 16 bits of the packet ($ver) = unpack("n", $payload); if ($ver == 1) { process_nf_v1($sender, $payload); } elsif ($ver == 5) { process_nf_v5($sender, $payload); } else { printf STDERR timestamp()." Unsupported netflow version %d\n", $ver; next; } undef $payload; next; } exit 0; softflowd-0.9.9/common.h010064400017500001750000000110121171606473600133560ustar00djmdjm/* * Copyright (c) 2002 Damien Miller. 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 _SFD_COMMON_H #define _SFD_COMMON_H #include "config.h" #define _BSD_SOURCE /* Needed for BSD-style struct ip,tcp,udp on Linux */ #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 #include #include #include #if defined(HAVE_NET_BPF_H) #include #elif defined(HAVE_PCAP_BPF_H) #include #endif #if defined(HAVE_INTTYPES_H) #include #endif /* The name of the program */ #define PROGNAME "softflowd" /* The name of the program */ #define PROGVER "0.9.9" /* Default pidfile */ #define DEFAULT_PIDFILE "/var/run/" PROGNAME ".pid" /* Default control socket */ #define DEFAULT_CTLSOCK "/var/run/" PROGNAME ".ctl" #define RCSID(msg) \ static /**/const char *const flowd_rcsid[] = \ { (const char *)flowd_rcsid, "\100(#)" msg } \ #ifndef IP_OFFMASK # define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ #endif #ifndef IPV6_VERSION #define IPV6_VERSION 0x60 #endif #ifndef IPV6_VERSION_MASK #define IPV6_VERSION_MASK 0xf0 #endif #ifndef IPV6_FLOWINFO_MASK #define IPV6_FLOWINFO_MASK ntohl(0x0fffffff) #endif #ifndef IPV6_FLOWLABEL_MASK #define IPV6_FLOWLABEL_MASK ntohl(0x000fffff) #endif #ifndef _PATH_DEVNULL # define _PATH_DEVNULL "/dev/null" #endif #ifndef MIN # define MIN(a,b) (((a)<(b))?(a):(b)) #endif #ifndef MAX # define MAX(a,b) (((a)>(b))?(a):(b)) #endif #ifndef offsetof # define offsetof(type, member) ((size_t) &((type *)0)->member) #endif #if defined(__GNUC__) # ifndef __dead # define __dead __attribute__((__noreturn__)) # endif # ifndef __packed # define __packed __attribute__((__packed__)) # endif #endif #if !defined(HAVE_INT8_T) && defined(OUR_CFG_INT8_T) typedef OUR_CFG_INT8_T int8_t; #endif #if !defined(HAVE_INT16_T) && defined(OUR_CFG_INT16_T) typedef OUR_CFG_INT16_T int16_t; #endif #if !defined(HAVE_INT32_T) && defined(OUR_CFG_INT32_T) typedef OUR_CFG_INT32_T int32_t; #endif #if !defined(HAVE_INT64_T) && defined(OUR_CFG_INT64_T) typedef OUR_CFG_INT64_T int64_t; #endif #if !defined(HAVE_U_INT8_T) && defined(OUR_CFG_U_INT8_T) typedef OUR_CFG_U_INT8_T u_int8_t; #endif #if !defined(HAVE_U_INT16_T) && defined(OUR_CFG_U_INT16_T) typedef OUR_CFG_U_INT16_T u_int16_t; #endif #if !defined(HAVE_U_INT32_T) && defined(OUR_CFG_U_INT32_T) typedef OUR_CFG_U_INT32_T u_int32_t; #endif #if !defined(HAVE_U_INT64_T) && defined(OUR_CFG_U_INT64_T) typedef OUR_CFG_U_INT64_T u_int64_t; #endif #ifndef HAVE_STRLCPY size_t strlcpy(char *dst, const char *src, size_t siz); #endif #ifndef HAVE_STRLCAT size_t strlcat(char *dst, const char *src, size_t siz); #endif #ifndef HAVE_CLOSEFROM void closefrom(int lowfd); #endif #ifndef HAVE_STRUCT_IP6_EXT struct ip6_ext { u_int8_t ip6e_nxt; u_int8_t ip6e_len; } __packed; #endif #endif /* _SFD_COMMON_H */ softflowd-0.9.9/configure.ac010064400017500001750000000137261171606473600142210ustar00djmdjm# Copyright (c) 2004 Damien Miller # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT AC_CONFIG_SRCDIR([softflowd.c]) AC_CONFIG_HEADER(config.h) AC_PROG_CC AC_PROG_INSTALL # Optional verbose warnings for gcc, see below WFLAGS="-Wall -Waggregate-return -Wcast-align -Wcast-qual" WFLAGS="$WFLAGS -Wmissing-declarations -Wmissing-prototypes" WFLAGS="$WFLAGS -Wno-conversion -Wpointer-arith -Wshadow" WFLAGS="$WFLAGS -Wuninitialized -Wcast-align -Wcast-qual" WFLAGS="$WFLAGS -Wformat=2 -Wformat-nonliteral -Wwrite-strings" # Process flag arguments early, so they are available for tests later AC_ARG_ENABLE(gcc-warnings, [ --enable-gcc-warnings Enable verbose warnings (only for gcc)], [ if test "x$enableval" = "xyes" ; then CFLAGS="$CFLAGS $WFLAGS"; fi ] ) AC_ARG_WITH(cflags, [ --with-cflags Specify additional compiler flags], [ if test "x$withval" != "xno" ; then CFLAGS="$CFLAGS $withval"; fi ] ) AC_ARG_WITH(cppflags, [ --with-cppflags Specify additional preprocessor flags] , [ if test "x$withval" != "xno"; then CPPFLAGS="$CPPFLAGS $withval"; fi ] ) AC_ARG_WITH(ldflags, [ --with-ldflags Specify additional linker flags], [ if test "x$withval" != "xno" ; then LDFLAGS="$LDFLAGS $withval"; fi ] ) AC_ARG_WITH(libs, [ --with-libs Specify additional libraries to link with], [ if test "x$withval" != "xno" ; then LIBS="$LIBS $withval"; fi ] ) AC_ARG_WITH(chrootdir, [ --with-chrootdir Specify chroot directory], [ AC_DEFINE_UNQUOTED([PRIVDROP_CHROOT_DIR], ["${withval}"], [privdrop chroot directory]) ] ) AC_CHECK_HEADERS(net/bpf.h pcap.h pcap-bpf.h) dnl AC_CHECK_HEADERS(netinet/in_systm.h netinet/tcp.h netinet/udp.h) dnl dnl # This ugliness is because of autoconf's stupid default include list dnl AC_CHECK_HEADERS([netinet/ip.h], dnl [AC_DEFINE([HAVE_HAVE_NETINET_IP_H], 1, [has netinet/ip.h])], [], dnl [ dnl #include dnl #include dnl #if HAVE_NETINET_IN_SYSTM_H dnl #include dnl #endif dnl ]) AC_CHECK_MEMBER([struct sockaddr.sa_len], [AC_DEFINE([SOCK_HAS_LEN], 1, [struct sockaddr contains length])], , [#include #include ]) AC_CHECK_MEMBER(struct ip6_ext.ip6e_nxt, [AC_DEFINE([HAVE_STRUCT_IP6_EXT], 1, [struct ip6_ext.ip6e_nxt exists])], [], [ #include #include #include #include ]) AC_SEARCH_LIBS(daemon, bsd) AC_SEARCH_LIBS(gethostbyname, nsl) AC_SEARCH_LIBS(socket, socket) AC_CHECK_LIB(pcap, pcap_open_live) AC_CHECK_FUNCS(closefrom daemon setresuid setreuid setresgid setgid strlcpy strlcat) AC_CHECK_TYPES([u_int64_t, int64_t, uint64_t, u_int32_t, int32_t, uint32_t]) AC_CHECK_TYPES([u_int16_t, int16_t, uint16_t, u_int8_t, int8_t, uint8_t]) AC_CHECK_SIZEOF(char, 1) AC_CHECK_SIZEOF(short int, 2) AC_CHECK_SIZEOF(int, 4) AC_CHECK_SIZEOF(long int, 4) AC_CHECK_SIZEOF(long long int, 8) if test "x$ac_cv_type_uint8_t" = "xyes" ; then AC_DEFINE([OUR_CFG_U_INT8_T], [uint8_t], [8-bit unsigned int]) elif test "x$ac_cv_sizeof_char" = "x1" ; then AC_DEFINE([OUR_CFG_U_INT8_T], [unsigned char], [8-bit unsigned int]) else AC_MSG_ERROR([No 8-bit unsigned int type found]) fi if test "x$ac_cv_sizeof_char" = "x1" ; then AC_DEFINE([OUR_CFG_INT8_T], [signed char], [8-bit signed int]) else AC_MSG_ERROR([No 8-bit signed int type found]) fi if test "x$ac_cv_type_uint16_t" = "xyes" ; then AC_DEFINE([OUR_CFG_U_INT16_T], [uint16_t], [16-bit unsigned int]) elif test "x$ac_cv_sizeof_short_int" = "x2" ; then AC_DEFINE([OUR_CFG_U_INT16_T], [unsigned short int], [16-bit unsigned int]) else AC_MSG_ERROR([No 16-bit unsigned int type found]) fi if test "x$ac_cv_sizeof_short_int" = "x2" ; then AC_DEFINE([OUR_CFG_INT16_T], [short int], [16-bit signed int]) else AC_MSG_ERROR([No 16-bit signed int type found]) fi if test "x$ac_cv_type_uint32_t" = "xyes" ; then AC_DEFINE([OUR_CFG_U_INT32_T], [uint32_t], [32-bit unsigned int]) elif test "x$ac_cv_sizeof_int" = "x4" ; then AC_DEFINE([OUR_CFG_U_INT32_T], [unsigned int], [32-bit unsigned int]) else AC_MSG_ERROR([No 32-bit unsigned int type found]) fi if test "x$ac_cv_sizeof_int" = "x4" ; then AC_DEFINE([OUR_CFG_INT32_T], [int], [32-bit signed int]) else AC_MSG_ERROR([No 32-bit signed int type found]) fi if test "x$ac_cv_type_uint64_t" = "xyes" ; then AC_DEFINE([OUR_CFG_U_INT64_T], [uint64_t], [64-bit unsigned int]) elif test "x$ac_cv_sizeof_long_int" = "x8" ; then AC_DEFINE([OUR_CFG_U_INT64_T], [unsigned long int], [64-bit unsigned int]) elif test "x$ac_cv_sizeof_long_long_int" = "x8" ; then AC_DEFINE([OUR_CFG_U_INT64_T], [unsigned long long int], [64-bit unsigned int]) else AC_MSG_ERROR([No 64-bit unsigned int type found]) fi if test "x$ac_cv_sizeof_long_int" = "x8" ; then AC_DEFINE([OUR_CFG_INT64_T], [long int], [64-bit signed int]) elif test "x$ac_cv_sizeof_long_long_int" = "x8" ; then AC_DEFINE([OUR_CFG_INT64_T], [long long int], [64-bit signed int]) else AC_MSG_ERROR([No 64-bit signed int type found]) fi if test "x$ac_cv_header_pcap_bpf_h" != "xyes" && \ test "x$ac_cv_header_net_bpf_h" != "xyes" ; then AC_MSG_ERROR([No BPF header found]) fi if test "x$ac_cv_header_pcap_h" != "xyes" ; then AC_MSG_ERROR([No pcap.h header found]) fi if test "x$ac_cv_lib_pcap_pcap_open_live" != "xyes" ; then AC_MSG_ERROR([libpcap not found]) fi AC_EXEEXT AC_CONFIG_FILES([Makefile]) AC_OUTPUT softflowd-0.9.9/convtime.c010064400017500001750000000042511171606473600137140ustar00djmdjm/* * Copyright (c) 2001 Kevin Steves. 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. */ #include "common.h" #include "convtime.h" #define SECONDS 1 #define MINUTES (SECONDS * 60) #define HOURS (MINUTES * 60) #define DAYS (HOURS * 24) #define WEEKS (DAYS * 7) long int convtime(const char *s) { long total, secs; const char *p; char *endp; errno = 0; total = 0; p = s; if (p == NULL || *p == '\0') return -1; while (*p) { secs = strtol(p, &endp, 10); if (p == endp || (errno == ERANGE && (secs == LONG_MIN || secs == LONG_MAX)) || secs < 0) return -1; switch (*endp++) { case '\0': endp--; case 's': case 'S': break; case 'm': case 'M': secs *= MINUTES; break; case 'h': case 'H': secs *= HOURS; break; case 'd': case 'D': secs *= DAYS; break; case 'w': case 'W': secs *= WEEKS; break; default: return -1; } total += secs; if (total < 0) return -1; p = endp; } return total; } softflowd-0.9.9/convtime.h010064400017500001750000000034501171606473600137210ustar00djmdjm/* * Copyright (c) 2001 Kevin Steves. 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 _SFD_CONVTIME_H /* * Convert a time string into seconds; format is * a sequence of: * time[qualifier] * * Valid time qualifiers are: * seconds * s|S seconds * m|M minutes * h|H hours * d|D days * w|W weeks * * Examples: * 90m 90 minutes * 1h30m 90 minutes * 2d 2 days * 1w 1 week * * Return -1 if time string is invalid. */ long int convtime(const char *s); #endif /* _SFD_CONVTIME_H */ softflowd-0.9.9/daemon.c010064400017500001750000000047251171606473600133410ustar00djmdjm/* OPENBSD ORIGINAL: lib/libc/gen/daemon.c */ /*- * Copyright (c) 1990, 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. 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. */ #include "common.h" #ifndef HAVE_DAEMON #if defined(LIBC_SCCS) && !defined(lint) static char rcsid[] = "$OpenBSD: daemon.c,v 1.5 2003/07/15 17:32:41 deraadt Exp $"; #endif /* LIBC_SCCS and not lint */ int daemon(int nochdir, int noclose) { int fd; switch (fork()) { case -1: return (-1); case 0: #ifdef HAVE_CYGWIN register_9x_service(); #endif break; default: #ifdef HAVE_CYGWIN /* * This sleep avoids a race condition which kills the * child process if parent is started by a NT/W2K service. */ sleep(1); #endif _exit(0); } if (setsid() == -1) return (-1); if (!nochdir) (void)chdir("/"); if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { (void)dup2(fd, STDIN_FILENO); (void)dup2(fd, STDOUT_FILENO); (void)dup2(fd, STDERR_FILENO); if (fd > 2) (void)close (fd); } return (0); } #endif /* !HAVE_DAEMON */ softflowd-0.9.9/freelist.c010064400017500001750000000114731171606473600137110ustar00djmdjm/* * Copyright (c) 2007 Damien Miller. 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. */ #include "common.h" #include "freelist.h" #include "log.h" #define FREELIST_MAX_ALLOC 0x1000000 #define FREELIST_ALLOC_ALIGN 16 #define FREELIST_INITIAL_ALLOC 16 #ifndef roundup #define roundup(x, y) ((((x) + (y) - 1)/(y))*(y)) #endif /* roundup */ #undef FREELIST_DEBUG #ifdef FREELIST_DEBUG # define FLOGIT(a) logit a #else # define FLOGIT(a) #endif void freelist_init(struct freelist *fl, size_t allocsz) { FLOGIT((LOG_DEBUG, "%s: %s(%p, %zu)", __func__, __func__, fl, allocsz)); bzero(fl, sizeof(fl)); fl->allocsz = roundup(allocsz, FREELIST_ALLOC_ALIGN); fl->free_entries = NULL; } static int freelist_grow(struct freelist *fl) { size_t i, oldnalloc, need; void *p; FLOGIT((LOG_DEBUG, "%s: %s(%p)", __func__, __func__, fl)); FLOGIT((LOG_DEBUG, "%s: nalloc = %zu", __func__, fl->nalloc)); /* Sanity check */ if (fl->nalloc > FREELIST_MAX_ALLOC) return -1; oldnalloc = fl->nalloc; if (fl->nalloc == 0) fl->nalloc = FREELIST_INITIAL_ALLOC; else fl->nalloc <<= 1; if (fl->nalloc > FREELIST_MAX_ALLOC) fl->nalloc = FREELIST_MAX_ALLOC; FLOGIT((LOG_DEBUG, "%s: nalloc now %zu", __func__, fl->nalloc)); /* Check for integer overflow */ if (SIZE_MAX / fl->nalloc < fl->allocsz || SIZE_MAX / fl->nalloc < sizeof(*fl->free_entries)) { FLOGIT((LOG_DEBUG, "%s: integer overflow", __func__)); resize_fail: fl->nalloc = oldnalloc; return -1; } /* Allocate freelist - max size of nalloc */ need = fl->nalloc * sizeof(*fl->free_entries); if ((p = realloc(fl->free_entries, need)) == NULL) { FLOGIT((LOG_DEBUG, "%s: realloc(%zu) failed", __func__, need)); goto resize_fail; } /* Allocate the entries */ fl->free_entries = p; need = (fl->nalloc - oldnalloc) * fl->allocsz; if ((p = malloc(need)) == NULL) { FLOGIT((LOG_DEBUG, "%s: malloc(%zu) failed", __func__, need)); goto resize_fail; } /* * XXX store these malloc ranges in a tree or list, so we can * validate them in _get/_put. Check that r_low <= addr < r_high, and * (addr - r_low) % fl->allocsz == 0 */ fl->navail = fl->nalloc - oldnalloc; for (i = 0; i < fl->navail; i++) fl->free_entries[i] = (u_char *)p + (i * fl->allocsz); for (i = fl->navail; i < fl->nalloc; i++) fl->free_entries[i] = NULL; FLOGIT((LOG_DEBUG, "%s: done, navail = %zu", __func__, fl->navail)); return 0; } void * freelist_get(struct freelist *fl) { void *r; FLOGIT((LOG_DEBUG, "%s: %s(%p)", __func__, __func__, fl)); FLOGIT((LOG_DEBUG, "%s: navail = %zu", __func__, fl->navail)); if (fl->navail == 0) { if (freelist_grow(fl) == -1) return NULL; } /* Sanity check */ if (fl->navail == 0 || fl->navail > FREELIST_MAX_ALLOC || fl->free_entries[fl->navail - 1] == NULL) { logit(LOG_ERR, "%s: invalid navail", __func__); raise(SIGSEGV); } fl->navail--; r = fl->free_entries[fl->navail]; fl->free_entries[fl->navail] = NULL; FLOGIT((LOG_DEBUG, "%s: done, navail = %zu", __func__, fl->navail)); return r; } void freelist_put(struct freelist *fl, void *p) { FLOGIT((LOG_DEBUG, "%s: %s(%p, %zu)", __func__, __func__, fl, p)); FLOGIT((LOG_DEBUG, "%s: navail = %zu", __func__, fl->navail)); FLOGIT((LOG_DEBUG, "%s: nalloc = %zu", __func__, fl->navail)); /* Sanity check */ if (fl->navail >= fl->nalloc) { logit(LOG_ERR, "%s: freelist navail >= nalloc", __func__); raise(SIGSEGV); } if (fl->free_entries[fl->navail] != NULL) { logit(LOG_ERR, "%s: free_entries[%lu] != NULL", __func__, (unsigned long)fl->navail); raise(SIGSEGV); } fl->free_entries[fl->navail] = p; fl->navail++; FLOGIT((LOG_DEBUG, "%s: done, navail = %zu", __func__, fl->navail)); } softflowd-0.9.9/freelist.h010064400017500001750000000037741171606473600137230ustar00djmdjm/* * Copyright (c) 2007 Damien Miller. 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 _FREELIST_H #define _FREELIST_H #include "common.h" /* Simple freelist of fixed-sized allocations */ struct freelist { size_t allocsz; size_t nalloc; size_t navail; void **free_entries; }; /* * Initialise a freelist. * allocsz is the size of the individual allocations */ void freelist_init(struct freelist *freelist, size_t allocsz); /* * Get an entry from a freelist. * Will allocate new entries if necessary * Returns pointer to allocated memory or NULL on failure. */ void *freelist_get(struct freelist *freelist); /* * Returns an entry to the freelist. * p must be a pointer to an allocation from the freelist. */ void freelist_put(struct freelist *freelist, void *p); #endif /* FREELIST_H */ softflowd-0.9.9/install-sh010075500017500001750000000127221171606473600137320ustar00djmdjm#!/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=: chmodcmd="" 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 softflowd-0.9.9/log.c010064400017500001750000000033521171606473600126520ustar00djmdjm/* * Copyright 2004 Damien Miller 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. */ #include "common.h" #include "log.h" #include static int logstderr = 0; void loginit(const char *ident, int to_stderr) { if (to_stderr) logstderr = 1; else openlog(PROGNAME, LOG_PID|LOG_NDELAY, LOG_DAEMON); } void logit(int level, const char *fmt,...) { va_list args; va_start(args, fmt); if (logstderr) { vfprintf(stderr, fmt, args); fputs("\n", stderr); } else vsyslog(level, fmt, args); va_end(args); } softflowd-0.9.9/log.h010064400017500001750000000027011171606473600126540ustar00djmdjm/* * Copyright 2004 Damien Miller 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 _LOG_H #define _LOG_H void loginit(const char *ident, int to_stderr); void logit(int level, const char *fmt,...); #endif /* _LOG_H */ softflowd-0.9.9/mkinstalldirs010075500017500001750000000011711171606473600145300ustar00djmdjm#! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain errstatus=0 for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr fi fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here softflowd-0.9.9/netflow1.c010064400017500001750000000130111171606473600136210ustar00djmdjm/* * Copyright 2002 Damien Miller 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. */ #include "common.h" #include "log.h" #include "treetype.h" #include "softflowd.h" /* * This is the Cisco Netflow(tm) version 1 packet format * Based on: * http://www.cisco.com/en/US/products/sw/netmgtsw/ps1964/products_implementation_design_guide09186a00800d6a11.html */ struct NF1_HEADER { u_int16_t version, flows; u_int32_t uptime_ms, time_sec, time_nanosec; }; struct NF1_FLOW { u_int32_t src_ip, dest_ip, nexthop_ip; u_int16_t if_index_in, if_index_out; u_int32_t flow_packets, flow_octets; u_int32_t flow_start, flow_finish; u_int16_t src_port, dest_port; u_int16_t pad1; u_int8_t protocol, tos, tcp_flags; u_int8_t pad2, pad3, pad4; u_int32_t reserved1; #if 0 u_int8_t reserved2; /* XXX: no longer used */ #endif }; /* Maximum of 24 flows per packet */ #define NF1_MAXFLOWS 24 #define NF1_MAXPACKET_SIZE (sizeof(struct NF1_HEADER) + \ (NF1_MAXFLOWS * sizeof(struct NF1_FLOW))) /* * Given an array of expired flows, send netflow v1 report packets * Returns number of packets sent or -1 on error */ int send_netflow_v1(struct FLOW **flows, int num_flows, int nfsock, u_int16_t ifidx, u_int64_t *flows_exported, struct timeval *system_boot_time, int verbose_flag, struct OPTION *option) { struct timeval now; u_int32_t uptime_ms; u_int8_t packet[NF1_MAXPACKET_SIZE]; /* Maximum allowed packet size (24 flows) */ struct NF1_HEADER *hdr = NULL; struct NF1_FLOW *flw = NULL; int i, j, offset, num_packets, err; socklen_t errsz; gettimeofday(&now, NULL); uptime_ms = timeval_sub_ms(&now, system_boot_time); hdr = (struct NF1_HEADER *)packet; for(num_packets = offset = j = i = 0; i < num_flows; i++) { if (j >= NF1_MAXFLOWS - 1) { if (verbose_flag) logit(LOG_DEBUG, "Sending flow packet len = %d", offset); hdr->flows = htons(hdr->flows); errsz = sizeof(err); getsockopt(nfsock, SOL_SOCKET, SO_ERROR, &err, &errsz); /* Clear ICMP errors */ if (send(nfsock, packet, (size_t)offset, 0) == -1) return (-1); *flows_exported += j; j = 0; num_packets++; } if (j == 0) { memset(&packet, '\0', sizeof(packet)); hdr->version = htons(1); hdr->flows = 0; /* Filled in as we go */ hdr->uptime_ms = htonl(uptime_ms); hdr->time_sec = htonl(now.tv_sec); hdr->time_nanosec = htonl(now.tv_usec * 1000); offset = sizeof(*hdr); } flw = (struct NF1_FLOW *)(packet + offset); flw->if_index_in = flw->if_index_out = htons(ifidx); /* NetFlow v.1 doesn't do IPv6 */ if (flows[i]->af != AF_INET) continue; if (flows[i]->octets[0] > 0) { flw->src_ip = flows[i]->addr[0].v4.s_addr; flw->dest_ip = flows[i]->addr[1].v4.s_addr; flw->src_port = flows[i]->port[0]; flw->dest_port = flows[i]->port[1]; flw->flow_packets = htonl(flows[i]->packets[0]); flw->flow_octets = htonl(flows[i]->octets[0]); flw->flow_start = htonl(timeval_sub_ms(&flows[i]->flow_start, system_boot_time)); flw->flow_finish = htonl(timeval_sub_ms(&flows[i]->flow_last, system_boot_time)); flw->protocol = flows[i]->protocol; flw->tcp_flags = flows[i]->tcp_flags[0]; offset += sizeof(*flw); j++; hdr->flows++; } flw = (struct NF1_FLOW *)(packet + offset); flw->if_index_in = flw->if_index_out = htons(ifidx); if (flows[i]->octets[1] > 0) { flw->src_ip = flows[i]->addr[1].v4.s_addr; flw->dest_ip = flows[i]->addr[0].v4.s_addr; flw->src_port = flows[i]->port[1]; flw->dest_port = flows[i]->port[0]; flw->flow_packets = htonl(flows[i]->packets[1]); flw->flow_octets = htonl(flows[i]->octets[1]); flw->flow_start = htonl(timeval_sub_ms(&flows[i]->flow_start, system_boot_time)); flw->flow_finish = htonl(timeval_sub_ms(&flows[i]->flow_last, system_boot_time)); flw->protocol = flows[i]->protocol; flw->tcp_flags = flows[i]->tcp_flags[1]; offset += sizeof(*flw); j++; hdr->flows++; } } /* Send any leftovers */ if (j != 0) { if (verbose_flag) logit(LOG_DEBUG, "Sending flow packet len = %d", offset); hdr->flows = htons(hdr->flows); errsz = sizeof(err); getsockopt(nfsock, SOL_SOCKET, SO_ERROR, &err, &errsz); /* Clear ICMP errors */ if (send(nfsock, packet, (size_t)offset, 0) == -1) return (-1); num_packets++; } *flows_exported += j; return (num_packets); } softflowd-0.9.9/netflow5.c010064400017500001750000000133351171606473600136360ustar00djmdjm/* * Copyright 2002 Damien Miller 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. */ #include "common.h" #include "log.h" #include "treetype.h" #include "softflowd.h" /* * This is the Cisco Netflow(tm) version 5 packet format * Based on: * http://www.cisco.com/en/US/products/sw/netmgtsw/ps1964/products_implementation_design_guide09186a00800d6a11.html */ struct NF5_HEADER { u_int16_t version, flows; u_int32_t uptime_ms, time_sec, time_nanosec, flow_sequence; u_int8_t engine_type, engine_id; u_int16_t sampling_interval; }; struct NF5_FLOW { u_int32_t src_ip, dest_ip, nexthop_ip; u_int16_t if_index_in, if_index_out; u_int32_t flow_packets, flow_octets; u_int32_t flow_start, flow_finish; u_int16_t src_port, dest_port; u_int8_t pad1; u_int8_t tcp_flags, protocol, tos; u_int16_t src_as, dest_as; u_int8_t src_mask, dst_mask; u_int16_t pad2; }; #define NF5_MAXFLOWS 30 #define NF5_MAXPACKET_SIZE (sizeof(struct NF5_HEADER) + \ (NF5_MAXFLOWS * sizeof(struct NF5_FLOW))) /* * Given an array of expired flows, send netflow v5 report packets * Returns number of packets sent or -1 on error */ int send_netflow_v5(struct FLOW **flows, int num_flows, int nfsock, u_int16_t ifidx, u_int64_t *flows_exported, struct timeval *system_boot_time, int verbose_flag, struct OPTION *option) { struct timeval now; u_int32_t uptime_ms; u_int8_t packet[NF5_MAXPACKET_SIZE]; /* Maximum allowed packet size (24 flows) */ struct NF5_HEADER *hdr = NULL; struct NF5_FLOW *flw = NULL; int i, j, offset, num_packets, err; socklen_t errsz; gettimeofday(&now, NULL); uptime_ms = timeval_sub_ms(&now, system_boot_time); hdr = (struct NF5_HEADER *)packet; for (num_packets = offset = j = i = 0; i < num_flows; i++) { if (j >= NF5_MAXFLOWS - 1) { if (verbose_flag) logit(LOG_DEBUG, "Sending flow packet len = %d", offset); hdr->flows = htons(hdr->flows); errsz = sizeof(err); getsockopt(nfsock, SOL_SOCKET, SO_ERROR, &err, &errsz); /* Clear ICMP errors */ if (send(nfsock, packet, (size_t)offset, 0) == -1) return (-1); *flows_exported += j; j = 0; num_packets++; } if (j == 0) { memset(&packet, '\0', sizeof(packet)); hdr->version = htons(5); hdr->flows = 0; /* Filled in as we go */ hdr->uptime_ms = htonl(uptime_ms); hdr->time_sec = htonl(now.tv_sec); hdr->time_nanosec = htonl(now.tv_usec * 1000); hdr->flow_sequence = htonl(*flows_exported); if (option->sample > 0) { hdr->sampling_interval = htons(0x01 << 14 | option->sample & 0x3FFF); } /* Other fields are left zero */ offset = sizeof(*hdr); } flw = (struct NF5_FLOW *)(packet + offset); flw->if_index_in = flw->if_index_out = htons(ifidx); /* NetFlow v.5 doesn't do IPv6 */ if (flows[i]->af != AF_INET) continue; if (flows[i]->octets[0] > 0) { flw->src_ip = flows[i]->addr[0].v4.s_addr; flw->dest_ip = flows[i]->addr[1].v4.s_addr; flw->src_port = flows[i]->port[0]; flw->dest_port = flows[i]->port[1]; flw->flow_packets = htonl(flows[i]->packets[0]); flw->flow_octets = htonl(flows[i]->octets[0]); flw->flow_start = htonl(timeval_sub_ms(&flows[i]->flow_start, system_boot_time)); flw->flow_finish = htonl(timeval_sub_ms(&flows[i]->flow_last, system_boot_time)); flw->tcp_flags = flows[i]->tcp_flags[0]; flw->protocol = flows[i]->protocol; offset += sizeof(*flw); j++; hdr->flows++; } flw = (struct NF5_FLOW *)(packet + offset); flw->if_index_in = flw->if_index_out = htons(ifidx); if (flows[i]->octets[1] > 0) { flw->src_ip = flows[i]->addr[1].v4.s_addr; flw->dest_ip = flows[i]->addr[0].v4.s_addr; flw->src_port = flows[i]->port[1]; flw->dest_port = flows[i]->port[0]; flw->flow_packets = htonl(flows[i]->packets[1]); flw->flow_octets = htonl(flows[i]->octets[1]); flw->flow_start = htonl(timeval_sub_ms(&flows[i]->flow_start, system_boot_time)); flw->flow_finish = htonl(timeval_sub_ms(&flows[i]->flow_last, system_boot_time)); flw->tcp_flags = flows[i]->tcp_flags[1]; flw->protocol = flows[i]->protocol; offset += sizeof(*flw); j++; hdr->flows++; } } /* Send any leftovers */ if (j != 0) { if (verbose_flag) logit(LOG_DEBUG, "Sending v5 flow packet len = %d", offset); hdr->flows = htons(hdr->flows); errsz = sizeof(err); getsockopt(nfsock, SOL_SOCKET, SO_ERROR, &err, &errsz); /* Clear ICMP errors */ if (send(nfsock, packet, (size_t)offset, 0) == -1) return (-1); num_packets++; } *flows_exported += j; return (num_packets); } softflowd-0.9.9/netflow9.c010064400017500001750000000357531171606473600136520ustar00djmdjm/* * Copyright 2002 Damien Miller 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. */ #include "common.h" #include "log.h" #include "treetype.h" #include "softflowd.h" /* Netflow v.9 */ struct NF9_HEADER { u_int16_t version, flows; u_int32_t uptime_ms, time_sec; u_int32_t package_sequence, source_id; } __packed; struct NF9_FLOWSET_HEADER_COMMON { u_int16_t flowset_id, length; } __packed; struct NF9_TEMPLATE_FLOWSET_HEADER { struct NF9_FLOWSET_HEADER_COMMON c; u_int16_t template_id, count; } __packed; struct NF9_OPTION_TEMPLATE_FLOWSET_HEADER { struct NF9_FLOWSET_HEADER_COMMON c; u_int16_t template_id, scope_length, option_length; } __packed; struct NF9_TEMPLATE_FLOWSET_RECORD { u_int16_t type, length; } __packed; struct NF9_DATA_FLOWSET_HEADER { struct NF9_FLOWSET_HEADER_COMMON c; } __packed; #define NF9_TEMPLATE_FLOWSET_ID 0 #define NF9_OPTIONS_FLOWSET_ID 1 #define NF9_MIN_RECORD_FLOWSET_ID 256 /* Flowset record types the we care about */ #define NF9_IN_BYTES 1 #define NF9_IN_PACKETS 2 /* ... */ #define NF9_IN_PROTOCOL 4 /* ... */ #define NF9_TCP_FLAGS 6 #define NF9_L4_SRC_PORT 7 #define NF9_IPV4_SRC_ADDR 8 /* ... */ #define NF9_IF_INDEX_IN 10 #define NF9_L4_DST_PORT 11 #define NF9_IPV4_DST_ADDR 12 /* ... */ #define NF9_IF_INDEX_OUT 14 /* ... */ #define NF9_LAST_SWITCHED 21 #define NF9_FIRST_SWITCHED 22 /* ... */ #define NF9_IPV6_SRC_ADDR 27 #define NF9_IPV6_DST_ADDR 28 /* ... */ #define NF9_SAMPLING_INTERVAL 34 #define NF9_SAMPLING_ALGORITHM 35 /* ... */ #define NF9_IP_PROTOCOL_VERSION 60 /* Stuff pertaining to the templates that softflowd uses */ #define NF9_SOFTFLOWD_TEMPLATE_NRECORDS 13 struct NF9_SOFTFLOWD_TEMPLATE { struct NF9_TEMPLATE_FLOWSET_HEADER h; struct NF9_TEMPLATE_FLOWSET_RECORD r[NF9_SOFTFLOWD_TEMPLATE_NRECORDS]; } __packed; #define NF9_SOFTFLOWD_OPTION_TEMPLATE_SCOPE_RECORDS 1 #define NF9_SOFTFLOWD_OPTION_TEMPLATE_NRECORDS 2 struct NF9_SOFTFLOWD_OPTION_TEMPLATE { struct NF9_OPTION_TEMPLATE_FLOWSET_HEADER h; struct NF9_TEMPLATE_FLOWSET_RECORD s[NF9_SOFTFLOWD_OPTION_TEMPLATE_SCOPE_RECORDS]; struct NF9_TEMPLATE_FLOWSET_RECORD r[NF9_SOFTFLOWD_OPTION_TEMPLATE_NRECORDS]; } __packed; /* softflowd data flowset types */ struct NF9_SOFTFLOWD_DATA_COMMON { u_int32_t last_switched, first_switched; u_int32_t bytes, packets; u_int32_t if_index_in, if_index_out; u_int16_t src_port, dst_port; u_int8_t protocol, tcp_flags, ipproto; } __packed; struct NF9_SOFTFLOWD_DATA_V4 { u_int32_t src_addr, dst_addr; struct NF9_SOFTFLOWD_DATA_COMMON c; } __packed; struct NF9_SOFTFLOWD_DATA_V6 { u_int8_t src_addr[16], dst_addr[16]; struct NF9_SOFTFLOWD_DATA_COMMON c; } __packed; struct NF9_SOFTFLOWD_OPTION_DATA { struct NF9_FLOWSET_HEADER_COMMON c; u_int32_t scope_ifidx; u_int32_t sampling_interval; u_int8_t sampling_algorithm; u_int8_t padding[3]; } __packed; /* Local data: templates and counters */ #define NF9_SOFTFLOWD_MAX_PACKET_SIZE 512 #define NF9_SOFTFLOWD_V4_TEMPLATE_ID 1024 #define NF9_SOFTFLOWD_V6_TEMPLATE_ID 2048 #define NF9_SOFTFLOWD_OPTION_TEMPLATE_ID 256 #define NF9_DEFAULT_TEMPLATE_INTERVAL 16 /* ... */ #define NF9_OPTION_SCOPE_SYSTEM 1 #define NF9_OPTION_SCOPE_INTERFACE 2 #define NF9_OPTION_SCOPE_LINECARD 3 #define NF9_OPTION_SCOPE_CACHE 4 #define NF9_OPTION_SCOPE_TEMPLATE 5 /* ... */ #define NF9_SAMPLING_ALGORITHM_DETERMINISTIC 1 #define NF9_SAMPLING_ALGORITHM_RANDOM 2 /* ... */ static struct NF9_SOFTFLOWD_TEMPLATE v4_template; static struct NF9_SOFTFLOWD_TEMPLATE v6_template; static struct NF9_SOFTFLOWD_OPTION_TEMPLATE option_template; static struct NF9_SOFTFLOWD_OPTION_DATA option_data; static int nf9_pkts_until_template = -1; static void nf9_init_template(void) { bzero(&v4_template, sizeof(v4_template)); v4_template.h.c.flowset_id = htons(NF9_TEMPLATE_FLOWSET_ID); v4_template.h.c.length = htons(sizeof(v4_template)); v4_template.h.template_id = htons(NF9_SOFTFLOWD_V4_TEMPLATE_ID); v4_template.h.count = htons(NF9_SOFTFLOWD_TEMPLATE_NRECORDS); v4_template.r[0].type = htons(NF9_IPV4_SRC_ADDR); v4_template.r[0].length = htons(4); v4_template.r[1].type = htons(NF9_IPV4_DST_ADDR); v4_template.r[1].length = htons(4); v4_template.r[2].type = htons(NF9_LAST_SWITCHED); v4_template.r[2].length = htons(4); v4_template.r[3].type = htons(NF9_FIRST_SWITCHED); v4_template.r[3].length = htons(4); v4_template.r[4].type = htons(NF9_IN_BYTES); v4_template.r[4].length = htons(4); v4_template.r[5].type = htons(NF9_IN_PACKETS); v4_template.r[5].length = htons(4); v4_template.r[6].type = htons(NF9_IF_INDEX_IN); v4_template.r[6].length = htons(4); v4_template.r[7].type = htons(NF9_IF_INDEX_OUT); v4_template.r[7].length = htons(4); v4_template.r[8].type = htons(NF9_L4_SRC_PORT); v4_template.r[8].length = htons(2); v4_template.r[9].type = htons(NF9_L4_DST_PORT); v4_template.r[9].length = htons(2); v4_template.r[10].type = htons(NF9_IN_PROTOCOL); v4_template.r[10].length = htons(1); v4_template.r[11].type = htons(NF9_TCP_FLAGS); v4_template.r[11].length = htons(1); v4_template.r[12].type = htons(NF9_IP_PROTOCOL_VERSION); v4_template.r[12].length = htons(1); bzero(&v6_template, sizeof(v6_template)); v6_template.h.c.flowset_id = htons(NF9_TEMPLATE_FLOWSET_ID); v6_template.h.c.length = htons(sizeof(v6_template)); v6_template.h.template_id = htons(NF9_SOFTFLOWD_V6_TEMPLATE_ID); v6_template.h.count = htons(NF9_SOFTFLOWD_TEMPLATE_NRECORDS); v6_template.r[0].type = htons(NF9_IPV6_SRC_ADDR); v6_template.r[0].length = htons(16); v6_template.r[1].type = htons(NF9_IPV6_DST_ADDR); v6_template.r[1].length = htons(16); v6_template.r[2].type = htons(NF9_LAST_SWITCHED); v6_template.r[2].length = htons(4); v6_template.r[3].type = htons(NF9_FIRST_SWITCHED); v6_template.r[3].length = htons(4); v6_template.r[4].type = htons(NF9_IN_BYTES); v6_template.r[4].length = htons(4); v6_template.r[5].type = htons(NF9_IN_PACKETS); v6_template.r[5].length = htons(4); v6_template.r[6].type = htons(NF9_IF_INDEX_IN); v6_template.r[6].length = htons(4); v6_template.r[7].type = htons(NF9_IF_INDEX_OUT); v6_template.r[7].length = htons(4); v6_template.r[8].type = htons(NF9_L4_SRC_PORT); v6_template.r[8].length = htons(2); v6_template.r[9].type = htons(NF9_L4_DST_PORT); v6_template.r[9].length = htons(2); v6_template.r[10].type = htons(NF9_IN_PROTOCOL); v6_template.r[10].length = htons(1); v6_template.r[11].type = htons(NF9_TCP_FLAGS); v6_template.r[11].length = htons(1); v6_template.r[12].type = htons(NF9_IP_PROTOCOL_VERSION); v6_template.r[12].length = htons(1); } static void nf9_init_option(u_int16_t ifidx, struct OPTION *option) { bzero(&option_template, sizeof(option_template)); option_template.h.c.flowset_id = htons(NF9_OPTIONS_FLOWSET_ID); option_template.h.c.length = htons(sizeof(option_template)); option_template.h.template_id = htons(NF9_SOFTFLOWD_OPTION_TEMPLATE_ID); option_template.h.scope_length = htons(sizeof(option_template.s)); option_template.h.option_length = htons(sizeof(option_template.r)); option_template.s[0].type = htons(NF9_OPTION_SCOPE_INTERFACE); option_template.s[0].length = htons(sizeof(option_data.scope_ifidx)); option_template.r[0].type = htons(NF9_SAMPLING_INTERVAL); option_template.r[0].length = htons(sizeof(option_data.sampling_interval)); option_template.r[1].type = htons(NF9_SAMPLING_ALGORITHM); option_template.r[1].length = htons(sizeof(option_data.sampling_algorithm)); bzero(&option_data, sizeof(option_data)); option_data.c.flowset_id = htons(NF9_SOFTFLOWD_OPTION_TEMPLATE_ID); option_data.c.length = htons(sizeof(option_data)); option_data.scope_ifidx = htonl(ifidx); option_data.sampling_interval = htonl(option->sample); option_data.sampling_algorithm = NF9_SAMPLING_ALGORITHM_DETERMINISTIC; } static int nf_flow_to_flowset(const struct FLOW *flow, u_char *packet, u_int len, u_int16_t ifidx, const struct timeval *system_boot_time, u_int *len_used) { union { struct NF9_SOFTFLOWD_DATA_V4 d4; struct NF9_SOFTFLOWD_DATA_V6 d6; } d[2]; struct NF9_SOFTFLOWD_DATA_COMMON *dc[2]; u_int freclen, ret_len, nflows; bzero(d, sizeof(d)); *len_used = nflows = ret_len = 0; switch (flow->af) { case AF_INET: freclen = sizeof(struct NF9_SOFTFLOWD_DATA_V4); memcpy(&d[0].d4.src_addr, &flow->addr[0].v4, 4); memcpy(&d[0].d4.dst_addr, &flow->addr[1].v4, 4); memcpy(&d[1].d4.src_addr, &flow->addr[1].v4, 4); memcpy(&d[1].d4.dst_addr, &flow->addr[0].v4, 4); dc[0] = &d[0].d4.c; dc[1] = &d[1].d4.c; dc[0]->ipproto = dc[1]->ipproto = 4; break; case AF_INET6: freclen = sizeof(struct NF9_SOFTFLOWD_DATA_V6); memcpy(&d[0].d6.src_addr, &flow->addr[0].v6, 16); memcpy(&d[0].d6.dst_addr, &flow->addr[1].v6, 16); memcpy(&d[1].d6.src_addr, &flow->addr[1].v6, 16); memcpy(&d[1].d6.dst_addr, &flow->addr[0].v6, 16); dc[0] = &d[0].d6.c; dc[1] = &d[1].d6.c; dc[0]->ipproto = dc[1]->ipproto = 6; break; default: return (-1); } dc[0]->first_switched = dc[1]->first_switched = htonl(timeval_sub_ms(&flow->flow_start, system_boot_time)); dc[0]->last_switched = dc[1]->last_switched = htonl(timeval_sub_ms(&flow->flow_last, system_boot_time)); dc[0]->bytes = htonl(flow->octets[0]); dc[1]->bytes = htonl(flow->octets[1]); dc[0]->packets = htonl(flow->packets[0]); dc[1]->packets = htonl(flow->packets[1]); dc[0]->if_index_in = dc[0]->if_index_out = htonl(ifidx); dc[1]->if_index_in = dc[1]->if_index_out = htonl(ifidx); dc[0]->src_port = dc[1]->dst_port = flow->port[0]; dc[1]->src_port = dc[0]->dst_port = flow->port[1]; dc[0]->protocol = dc[1]->protocol = flow->protocol; dc[0]->tcp_flags = flow->tcp_flags[0]; dc[1]->tcp_flags = flow->tcp_flags[1]; if (flow->octets[0] > 0) { if (ret_len + freclen > len) return (-1); memcpy(packet + ret_len, &d[0], freclen); ret_len += freclen; nflows++; } if (flow->octets[1] > 0) { if (ret_len + freclen > len) return (-1); memcpy(packet + ret_len, &d[1], freclen); ret_len += freclen; nflows++; } *len_used = ret_len; return (nflows); } /* * Given an array of expired flows, send netflow v9 report packets * Returns number of packets sent or -1 on error */ int send_netflow_v9(struct FLOW **flows, int num_flows, int nfsock, u_int16_t ifidx, u_int64_t *flows_exported, struct timeval *system_boot_time, int verbose_flag, struct OPTION *option) { struct NF9_HEADER *nf9; struct NF9_DATA_FLOWSET_HEADER *dh; struct timeval now; u_int offset, last_af, i, j, num_packets, inc, last_valid; socklen_t errsz; int err, r; u_char packet[NF9_SOFTFLOWD_MAX_PACKET_SIZE]; gettimeofday(&now, NULL); if (nf9_pkts_until_template == -1) { nf9_init_template(); nf9_pkts_until_template = 0; if (option != NULL && option->sample > 1){ nf9_init_option(ifidx, option); } } last_valid = num_packets = 0; for (j = 0; j < num_flows;) { bzero(packet, sizeof(packet)); nf9 = (struct NF9_HEADER *)packet; nf9->version = htons(9); nf9->flows = 0; /* Filled as we go, htons at end */ nf9->uptime_ms = htonl(timeval_sub_ms(&now, system_boot_time)); nf9->time_sec = htonl(time(NULL)); nf9->package_sequence = htonl(*flows_exported + j); nf9->source_id = 0; offset = sizeof(*nf9); /* Refresh template headers if we need to */ if (nf9_pkts_until_template <= 0) { memcpy(packet + offset, &v4_template, sizeof(v4_template)); offset += sizeof(v4_template); memcpy(packet + offset, &v6_template, sizeof(v6_template)); offset += sizeof(v6_template); if (option != NULL && option->sample > 1){ memcpy(packet + offset, &option_template, sizeof(option_template)); offset += sizeof(option_template); memcpy(packet + offset, &option_data, sizeof(option_data)); offset += sizeof(option_data); } nf9_pkts_until_template = NF9_DEFAULT_TEMPLATE_INTERVAL; } dh = NULL; last_af = 0; for (i = 0; i + j < num_flows; i++) { if (dh == NULL || flows[i + j]->af != last_af) { if (dh != NULL) { if (offset % 4 != 0) { /* Pad to multiple of 4 */ dh->c.length += 4 - (offset % 4); offset += 4 - (offset % 4); } /* Finalise last header */ dh->c.length = htons(dh->c.length); } if (offset + sizeof(*dh) > sizeof(packet)) { /* Mark header is finished */ dh = NULL; break; } dh = (struct NF9_DATA_FLOWSET_HEADER *) (packet + offset); dh->c.flowset_id = (flows[i + j]->af == AF_INET) ? v4_template.h.template_id : v6_template.h.template_id; last_af = flows[i + j]->af; last_valid = offset; dh->c.length = sizeof(*dh); /* Filled as we go */ offset += sizeof(*dh); } r = nf_flow_to_flowset(flows[i + j], packet + offset, sizeof(packet) - offset, ifidx, system_boot_time, &inc); if (r <= 0) { /* yank off data header, if we had to go back */ if (last_valid) offset = last_valid; break; } offset += inc; dh->c.length += inc; nf9->flows += r; last_valid = 0; /* Don't clobber this header now */ if (verbose_flag) { logit(LOG_DEBUG, "Flow %d/%d: " "r %d offset %d type %04x len %d(0x%04x) " "flows %d", r, i, j, offset, dh->c.flowset_id, dh->c.length, dh->c.length, nf9->flows); } } /* Don't finish header if it has already been done */ if (dh != NULL) { if (offset % 4 != 0) { /* Pad to multiple of 4 */ dh->c.length += 4 - (offset % 4); offset += 4 - (offset % 4); } /* Finalise last header */ dh->c.length = htons(dh->c.length); } nf9->flows = htons(nf9->flows); if (verbose_flag) logit(LOG_DEBUG, "Sending flow packet len = %d", offset); errsz = sizeof(err); /* Clear ICMP errors */ getsockopt(nfsock, SOL_SOCKET, SO_ERROR, &err, &errsz); if (send(nfsock, packet, (size_t)offset, 0) == -1) return (-1); num_packets++; nf9_pkts_until_template--; j += i; } *flows_exported += j; return (num_packets); } void netflow9_resend_template(void) { if (nf9_pkts_until_template > 0) nf9_pkts_until_template = 0; } softflowd-0.9.9/softflowd.sysconfig010064400017500001750000000004471171606473600156640ustar00djmdjm# Config file for softflowd startup # Location of softflowd binary #SOFTFLOW_PROG=/usr/sbin/softflowd # Options passed to the softflowd program # Default - not very useful #SOFTFLOW_OPTS="-i eth0" # Example NetFlow v5 export from traffic on eth1 #SOFTFLOW_OPTS="-v 5 -i eth1 -n hostname:2055" softflowd-0.9.9/softflowctl.c010064400017500001750000000061461171606473600144430ustar00djmdjm/* * Copyright 2002 Damien Miller 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. */ #include "common.h" static void usage(void) { fprintf(stderr, "Usage: [-c ctlsock] softflowctl [command]\n"); } int main(int argc, char **argv) { const char *ctlsock_path; char buf[8192], *command; struct sockaddr_un ctl; socklen_t ctllen; int ctlsock, ch; FILE *ctlf; extern char *optarg; extern int optind; ctlsock_path = DEFAULT_CTLSOCK; while ((ch = getopt(argc, argv, "hc:")) != -1) { switch (ch) { case 'h': usage(); return (0); case 'c': ctlsock_path = optarg; break; default: fprintf(stderr, "Invalid commandline option.\n"); usage(); exit(1); } } /* Accept only one argument */ if (optind != argc - 1) { usage(); exit(1); } command = argv[optind]; memset(&ctl, '\0', sizeof(ctl)); if (strlcpy(ctl.sun_path, ctlsock_path, sizeof(ctl.sun_path)) >= sizeof(ctl.sun_path)) { fprintf(stderr, "Control socket path too long.\n"); exit(1); } ctl.sun_path[sizeof(ctl.sun_path) - 1] = '\0'; ctl.sun_family = AF_UNIX; ctllen = offsetof(struct sockaddr_un, sun_path) + strlen(ctlsock_path) + 1; #ifdef SOCK_HAS_LEN ctl.sun_len = ctllen; #endif if ((ctlsock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { fprintf(stderr, "ctl socket() error: %s\n", strerror(errno)); exit(1); } if (connect(ctlsock, (struct sockaddr*)&ctl, sizeof(ctl)) == -1) { fprintf(stderr, "ctl connect(\"%s\") error: %s\n", ctl.sun_path, strerror(errno)); exit(1); } if ((ctlf = fdopen(ctlsock, "r+")) == NULL) { fprintf(stderr, "fdopen: %s\n", strerror(errno)); exit(1); } setlinebuf(ctlf); /* Send command */ if (fprintf(ctlf, "%s\n", command) < 0) { fprintf(stderr, "write: %s\n", strerror(errno)); exit(1); } /* Write out reply */ while((fgets(buf, sizeof(buf), ctlf)) != NULL) fputs(buf, stdout); fclose(ctlf); close(ctlsock); exit(0); } softflowd-0.9.9/softflowd.8010064400017500001750000000274321171606473600140320ustar00djmdjm.\" Copyright (c) 2002 Damien Miller. All rights reserved. .\" Portions Copyright (c) 2001 Kevin Steves. 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. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. .\" .Dd October 14, 2002 .Dt SOFTFLOWD 8 .Os .Sh NAME .Nm softflowd .Nd Traffic flow monitoring .Sh SYNOPSIS .Nm softflowd .Op Fl 6dDh .Op Fl L Ar hoplimit .Op Fl T Ar track_level .Op Fl c Ar ctl_sock .Bk -words .Oo Fl i\ \& .Sm off .Oo Ar if_ndx : Oc .Ar interface .Sm on .Oc .Ek .Op Fl m Ar max_flows .Op Fl n Ar host:port .Op Fl p Ar pidfile .Op Fl r Ar pcap_file .Op Fl t Ar timeout_name=seconds .Op Fl v Ar netflow_version .Op Fl s Ar sampling_rate .Op bpf_expression .Sh DESCRIPTION .Nm is a software implementation of a flow-based network traffic monitor. .Nm reads network traffic and gathers information about active traffic flows. A "traffic flow" is communication between two IP addresses or (if the overlying protocol is TCP or UDP) address/port tuples. .Pp The intended use of .Nm is as a software implementation of Cisco's NetFlow(tm) traffic account system. .Nm supports data export using versions 1, 5 or 9 of the NetFlow protocol. .Nm can also run in statistics-only mode, where it just collects summary information. However, too few statistics are collected to make this mode really useful for anything other than debugging. .Pp Network traffic may be obtained by listening on a promiscuous network interface or by reading stored .Xr pcap 3 files, such as those written by .Xr tcpdump 8 . Traffic may be filtered with an optional .Xr bpf 4 program, specified on the command-line as .Ar bpf_expression . .Nm is IPv6 capable and will track IPv6 flows if the NetFlow export protocol supports it (currently only NetFlow v.9 possesses an IPv6 export capability). .Pp .Nm tries to track only active traffic flows. When the flow has been quiescent for a period of time it is expired automatically. Flows may also be expired early if they approach their traffic counts exceed 2 Gib or if the number of flows being tracked exceeds .Ar max_flows (default: 8192). In this last case, flows are expired oldest-first. .Pp Upon expiry, the flow information is accumulated into statistics which may be viewed using .Xr softflowctl 8 . If the .Fl n option has been specified the flow information is formatted in a UDP datagram which is compatible with versions 1, 5 or 9 of Cisco's NetFlow(tm) accounting export format. These records are sent to the specified .Ar host and .Ar port . The host may represent a unicast host or a multicast group. .Pp The command-line options are as follows: .Bl -tag -width Ds .It Fl n Ar host:port Specify the .Ar host and .Ar port that the accounting datagrams are to be sent to. The host may be specified using a hostname or using a numeric IPv4 or IPv6 address. Numeric IPv6 addresses should be encosed in square brackets to avoid ambiguity between the address and the port. The destination port may be a portname listed in .Xr services 5 or a numeric port. .It Fl i Xo .Sm off .Oo Ar if_ndx : Oc .Ar interface .Sm on .Xc Specify a network interface on which to listen for traffic. Either the .Fl i or the .Fl r options must be specified. .It Fl r Ar pcap_file Specify that .Nm should read from a .Xr pcap 3 packet capture file (such as one created with the .Fl w option of .Xr tcpdump 8 ) file rather than a network interface. .Nm processes the whole capture file and only expires flows when .Ar max_flows is exceeded. In this mode, .Nm will not fork and will automatically print summary statistics before exiting. .It Fl p Ar pidfile Specify an alternate location to store the process ID when in daemon mode. Default is .Pa /var/run/softflowd.pid .It Fl c Ar ctlsock Specify an alternate location for the remote control socket in daemon mode. Default is .Pa /var/run/softflowd.ctl .It Fl m Ar max_flows Specify the maximum number of flows to concurrently track. If this limit is exceeded, the flows which have least recently seen traffic are forcibly expired. In practice, the actual maximum may briefly exceed this limit by a small amount as expiry processing happens less frequently than traffic collection. The default is 8192 flows, which corresponds to slightly less than 800k of working data. .It Fl t Ar timeout_name=time Set the timeout names .Ar timeout_name to .Ar time . Refer to the .Sx Timeouts section for the valid timeout names and their meanings. The .Ar time parameter may be specified using one of the formats explained in the .Sx Time Formats section below. .It Fl d Specify that .Nm should not fork and daemonise itself. .It Fl 6 Force .Nm to track IPv6 flows even if the NetFlow export protocol does not support reporting them. This is useful for debugging and statistics gathering only. .It Fl D Places .Nm in a debugging mode. This implies the .Fl d and .Fl 6 flags and turns on additional debugging output. .It Fl h Display command-line usage information. .It Fl L Ar hoplimit Set the IPv4 TTL or the IPv6 hop limit to .Ar hoplimit . .Nm will use the default system TTL when exporting flows to a unicast host. When exporting to a multicast group, the default TTL will be 1 (i.e. link-local). .It Fl T Ar track_level Specify which flow elements .Nm should be used to define a flow. .Ar track_level may be one of: .Dq full (track everything in the flow, the default), .Dq proto (track source and destination addresses and protocol), or .Dq ip (only track source and destination addresses). Selecting either of the latter options will produce flows with less information in them (e.g. TCP/UDP ports will not be recorded). This will cause flows to be consolidated, reducing the quantity of output and CPU load that .Nm will place on the system at the cost of some detail being lost. .It Fl v Ar netflow_version Specify which version of the NetFlow(tm) protocol .Nm should use for export of the flow data. Supported versions are 1, 5 and 9. Default is version 5. .It Fl s Ar sampling_rate Specify periodical sampling rate (denominator). .El .Pp Any further command-line arguments will be concatenated together and applied as a .Xr bpf 4 packet filter. This filter will cause .Nm to ignore the specified traffic. .Ss Timeouts .Pp .Nm will expire quiescent flows after user-configurable periods. The exact timeout used depends on the nature of the flow. The various timeouts that may be set from the command-line (using the .Fl t option) and their meanings are: .Bl -tag -width Ds .It Ar general This is the general timeout applied to all traffic unless overridden by one of the other timeouts. .It Ar tcp This is the general TCP timeout, applied to open TCP connections. .It Ar tcp.rst This timeout is applied to a TCP connection when a RST packet has been sent by one or both endpoints. .It Ar tcp.fin This timeout is applied to a TCP connection when a FIN packet has been sent by both endpoints. .It Ar udp This is the general UDP timeout, applied to all UDP connections. .It Ar maxlife This is the maximum lifetime that a flow may exist for. All flows are forcibly expired when they pass .Ar maxlife seconds. To disable this feature, specify a .Ar maxlife of 0. .It Ar expint Specify the interval between expiry checks. Increase this to group more flows into a NetFlow packet. To disable this feature, specify a .Ar expint of 0. .El .Pp Flows may also be expired if there are not enough flow entries to hold them or if their traffic exceeds 2 Gib in either direction. .Xr softflowctl 8 may be used to print information on the average lifetimes of flows and the reasons for their expiry. .Ss Time Formats .Pp .Nm command-line arguments that specify time may be expressed using a sequence of the form: .Sm off .Ar time Op Ar qualifier , .Sm on where .Ar time is a positive integer value and .Ar qualifier is one of the following: .Pp .Bl -tag -width Ds -compact -offset indent .It Cm seconds .It Cm s | Cm S seconds .It Cm m | Cm M minutes .It Cm h | Cm H hours .It Cm d | Cm D days .It Cm w | Cm W weeks .El .Pp Each member of the sequence is added together to calculate the total time value. .Pp Time format examples: .Pp .Bl -tag -width Ds -compact -offset indent .It 600 600 seconds (10 minutes) .It 10m 10 minutes .It 1h30m 1 hour 30 minutes (90 minutes) .El .Ss Run-time Control .Pp A daemonised .Nm instance may be controlled using the .Xr softflowctl 8 command. This interface allows one to shut down the daemon, force expiry of all tracked flows and extract debugging and summary data. Also, receipt of a .Dv SIGTERM or .Dv SIGINT will cause .Nm to exit, after expiring all flows (and thus sending flow export packets if .Fl n was specified on the command-line). If you do not want to export flows upon shutdown, clear them first with .Xr softflowctl 8 or use .Xr softflowctl 8 's .Dq exit command. .Sh EXAMPLES .Bl -tag -width Ds .It softflowd -i fxp0 This command-line will cause .Nm to listen on interface fxp0 and to run in statistics gathering mode only (i.e. no NetFlow data export). .It softflowd -i fxp0 -n 10.1.0.2:4432 This command-line will cause .Nm to listen on interface fxp0 and to export NetFlow v.5 datagrams on flow expiry to a flow collector running on 10.1.0.2 port 4432. .It softflowd -v 5 -i fxp0 -n 10.1.0.2:4432 -m 65536 -t udp=1m30s This command-line increases the number of concurrent flows that .Nm will track to 65536 and increases the timeout for UDP flows to 90 seconds. .It softflowd -v 9 -i fxp0 -n 224.0.1.20:4432 -L 64 This command-line will export NetFlow v.9 flows to the multicast group 224.0.1.20. The export datagrams will have their TTL set to 64, so multicast receivers can be many hops away. .It softflowd -i fxp0 -p /var/run/sfd.pid.fxp0 -c /var/run/sfd.ctl.fxp0 This command-line specifies alternate locations for the control socket and pid file. Similar command-lines are useful when running multiple instances of .Nm on a single machine. .El .Sh FILES .Bl -tag -width Ds .It Pa /var/run/softflowd.pid This file stores the process ID when .Nm is in daemon mode. This location may be overridden using the .Fl p command-line option. .It Pa /var/run/softflowd.ctl This is the remote control socket. .Nm listens on this socket for commands from .Xr softflowctl 8 . This location may be overridden using the .Fl c command-line option. .El .Sh BUGS Currently .Nm does not handle maliciously fragmented packets properly, i.e. packets fragemented such that the UDP or TCP header does not fit into the first fragment. It will product correct traffic counts when presented with maliciously fragmented packets, but will not record TCP or UDP port information. .Sh AUTHORS .An Damien Miller Aq djm@mindrot.org .Sh SEE ALSO .Xr softflowctl 8 , .Xr tcpdump 8 , .Xr pcap 3 , .Xr bpf 4 .Bd -literal http://www.ietf.org/rfc/rfc3954.txt .br http://www.cisco.com/en/US/products/sw/netmgtsw/ps1964/products_implementation_design_guide09186a00800d6a11.html .Ed softflowd-0.9.9/softflowd.c010064400017500001750000001533161171606473600141060ustar00djmdjm/* * Copyright 2002 Damien Miller 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. */ /* * This is software implementation of Cisco's NetFlow(tm) traffic * reporting system. It operates by listening (via libpcap) on a * promiscuous interface and tracking traffic flows. * * Traffic flows are recorded by source/destination/protocol * IP address or, in the case of TCP and UDP, by * src_addr:src_port/dest_addr:dest_port/protocol * * Flows expire automatically after a period of inactivity (default: 1 * hour) They may also be evicted (in order of age) in situations where * there are more flows than slots available. * * Netflow compatible packets are sent to a specified target host upon * flow expiry. * * As this implementation watches traffic promiscuously, it is likely to * place significant load on hosts or gateways on which it is installed. */ #include "common.h" #include "sys-tree.h" #include "convtime.h" #include "softflowd.h" #include "treetype.h" #include "freelist.h" #include "log.h" #include /* Global variables */ static int verbose_flag = 0; /* Debugging flag */ static u_int16_t if_index = 0; /* "manual" interface index */ /* Signal handler flags */ static volatile sig_atomic_t graceful_shutdown_request = 0; /* Context for libpcap callback functions */ struct CB_CTXT { struct FLOWTRACK *ft; int linktype; int fatal; int want_v6; }; /* Describes a datalink header and how to extract v4/v6 frames from it */ struct DATALINK { int dlt; /* BPF datalink type */ int skiplen; /* Number of bytes to skip datalink header */ int ft_off; /* Datalink frametype offset */ int ft_len; /* Datalink frametype length */ int ft_is_be; /* Set if frametype is big-endian */ u_int32_t ft_mask; /* Mask applied to frametype */ u_int32_t ft_v4; /* IPv4 frametype */ u_int32_t ft_v6; /* IPv6 frametype */ }; /* Datalink types that we know about */ static const struct DATALINK lt[] = { { DLT_EN10MB, 14, 12, 2, 1, 0xffffffff, 0x0800, 0x86dd }, { DLT_PPP, 5, 3, 2, 1, 0xffffffff, 0x0021, 0x0057 }, #ifdef DLT_LINUX_SLL { DLT_LINUX_SLL,16, 14, 2, 1, 0xffffffff, 0x0800, 0x86dd }, #endif { DLT_RAW, 0, 0, 1, 1, 0x000000f0, 0x0040, 0x0060 }, { DLT_NULL, 4, 0, 4, 0, 0xffffffff, AF_INET, AF_INET6 }, #ifdef DLT_LOOP { DLT_LOOP, 4, 0, 4, 1, 0xffffffff, AF_INET, AF_INET6 }, #endif { -1, -1, -1, -1, -1, 0x00000000, 0xffff, 0xffff }, }; /* Netflow send functions */ typedef int (netflow_send_func_t)(struct FLOW **, int, int, u_int16_t, u_int64_t *, struct timeval *, int, struct OPTION *); struct NETFLOW_SENDER { int version; netflow_send_func_t *func; int v6_capable; }; /* Array of NetFlow export function that we know of. NB. nf[0] is default */ static const struct NETFLOW_SENDER nf[] = { { 5, send_netflow_v5, 0 }, { 1, send_netflow_v1, 0 }, { 9, send_netflow_v9, 1 }, { -1, NULL, 0 }, }; /* Describes a location where we send NetFlow packets to */ struct NETFLOW_TARGET { int fd; const struct NETFLOW_SENDER *dialect; }; /* Signal handlers */ static void sighand_graceful_shutdown(int signum) { graceful_shutdown_request = signum; } static void sighand_other(int signum) { /* XXX: this may not be completely safe */ logit(LOG_WARNING, "Exiting immediately on unexpected signal %d", signum); _exit(0); } /* * This is the flow comparison function. */ static int flow_compare(struct FLOW *a, struct FLOW *b) { /* Be careful to avoid signed vs unsigned issues here */ int r; if (a->af != b->af) return (a->af > b->af ? 1 : -1); if ((r = memcmp(&a->addr[0], &b->addr[0], sizeof(a->addr[0]))) != 0) return (r > 0 ? 1 : -1); if ((r = memcmp(&a->addr[1], &b->addr[1], sizeof(a->addr[1]))) != 0) return (r > 0 ? 1 : -1); #ifdef notyet if (a->ip6_flowlabel[0] != 0 && b->ip6_flowlabel[0] != 0 && a->ip6_flowlabel[0] != b->ip6_flowlabel[0]) return (a->ip6_flowlabel[0] > b->ip6_flowlabel[0] ? 1 : -1); if (a->ip6_flowlabel[1] != 0 && b->ip6_flowlabel[1] != 0 && a->ip6_flowlabel[1] != b->ip6_flowlabel[1]) return (a->ip6_flowlabel[1] > b->ip6_flowlabel[1] ? 1 : -1); #endif if (a->protocol != b->protocol) return (a->protocol > b->protocol ? 1 : -1); if (a->port[0] != b->port[0]) return (ntohs(a->port[0]) > ntohs(b->port[0]) ? 1 : -1); if (a->port[1] != b->port[1]) return (ntohs(a->port[1]) > ntohs(b->port[1]) ? 1 : -1); return (0); } /* Generate functions for flow tree */ FLOW_PROTOTYPE(FLOWS, FLOW, trp, flow_compare); FLOW_GENERATE(FLOWS, FLOW, trp, flow_compare); /* * This is the expiry comparison function. */ static int expiry_compare(struct EXPIRY *a, struct EXPIRY *b) { if (a->expires_at != b->expires_at) return (a->expires_at > b->expires_at ? 1 : -1); /* Make expiry entries unique by comparing flow sequence */ if (a->flow->flow_seq != b->flow->flow_seq) return (a->flow->flow_seq > b->flow->flow_seq ? 1 : -1); return (0); } /* Generate functions for flow tree */ EXPIRY_PROTOTYPE(EXPIRIES, EXPIRY, trp, expiry_compare); EXPIRY_GENERATE(EXPIRIES, EXPIRY, trp, expiry_compare); static struct FLOW * flow_get(struct FLOWTRACK *ft) { return freelist_get(&ft->flow_freelist); } static void flow_put(struct FLOWTRACK *ft, struct FLOW *flow) { return freelist_put(&ft->flow_freelist, flow); } static struct EXPIRY * expiry_get(struct FLOWTRACK *ft) { return freelist_get(&ft->expiry_freelist); } static void expiry_put(struct FLOWTRACK *ft, struct EXPIRY *expiry) { return freelist_put(&ft->expiry_freelist, expiry); } #if 0 /* Dump a packet */ static void dump_packet(const u_int8_t *p, int len) { char buf[1024], tmp[3]; int i; for (*buf = '\0', i = 0; i < len; i++) { snprintf(tmp, sizeof(tmp), "%02x%s", p[i], i % 2 ? " " : ""); if (strlcat(buf, tmp, sizeof(buf) - 4) >= sizeof(buf) - 4) { strlcat(buf, "...", sizeof(buf)); break; } } logit(LOG_INFO, "packet len %d: %s", len, buf); } #endif /* Format a time in an ISOish format */ static const char * format_time(time_t t) { struct tm *tm; static char buf[32]; tm = gmtime(&t); strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S", tm); return (buf); } /* Format a flow in a verbose and ugly way */ static const char * format_flow(struct FLOW *flow) { char addr1[64], addr2[64], stime[32], ftime[32]; static char buf[1024]; inet_ntop(flow->af, &flow->addr[0], addr1, sizeof(addr1)); inet_ntop(flow->af, &flow->addr[1], addr2, sizeof(addr2)); snprintf(stime, sizeof(ftime), "%s", format_time(flow->flow_start.tv_sec)); snprintf(ftime, sizeof(ftime), "%s", format_time(flow->flow_last.tv_sec)); snprintf(buf, sizeof(buf), "seq:%"PRIu64" [%s]:%hu <> [%s]:%hu proto:%u " "octets>:%u packets>:%u octets<:%u packets<:%u " "start:%s.%03ld finish:%s.%03ld tcp>:%02x tcp<:%02x " "flowlabel>:%08x flowlabel<:%08x ", flow->flow_seq, addr1, ntohs(flow->port[0]), addr2, ntohs(flow->port[1]), (int)flow->protocol, flow->octets[0], flow->packets[0], flow->octets[1], flow->packets[1], stime, (flow->flow_start.tv_usec + 500) / 1000, ftime, (flow->flow_last.tv_usec + 500) / 1000, flow->tcp_flags[0], flow->tcp_flags[1], flow->ip6_flowlabel[0], flow->ip6_flowlabel[1]); return (buf); } /* Format a flow in a brief way */ static const char * format_flow_brief(struct FLOW *flow) { char addr1[64], addr2[64]; static char buf[1024]; inet_ntop(flow->af, &flow->addr[0], addr1, sizeof(addr1)); inet_ntop(flow->af, &flow->addr[1], addr2, sizeof(addr2)); snprintf(buf, sizeof(buf), "seq:%"PRIu64" [%s]:%hu <> [%s]:%hu proto:%u", flow->flow_seq, addr1, ntohs(flow->port[0]), addr2, ntohs(flow->port[1]), (int)flow->protocol); return (buf); } /* Fill in transport-layer (tcp/udp) portions of flow record */ static int transport_to_flowrec(struct FLOW *flow, const u_int8_t *pkt, const size_t caplen, int isfrag, int protocol, int ndx) { const struct tcphdr *tcp = (const struct tcphdr *)pkt; const struct udphdr *udp = (const struct udphdr *)pkt; const struct icmp *icmp = (const struct icmp *)pkt; /* * XXX to keep flow in proper canonical format, it may be necessary to * swap the array slots based on the order of the port numbers does * this matter in practice??? I don't think so - return flows will * always match, because of their symmetrical addr/ports */ switch (protocol) { case IPPROTO_TCP: /* Check for runt packet, but don't error out on short frags */ if (caplen < sizeof(*tcp)) return (isfrag ? 0 : 1); flow->port[ndx] = tcp->th_sport; flow->port[ndx ^ 1] = tcp->th_dport; flow->tcp_flags[ndx] |= tcp->th_flags; break; case IPPROTO_UDP: /* Check for runt packet, but don't error out on short frags */ if (caplen < sizeof(*udp)) return (isfrag ? 0 : 1); flow->port[ndx] = udp->uh_sport; flow->port[ndx ^ 1] = udp->uh_dport; break; case IPPROTO_ICMP: /* * Encode ICMP type * 256 + code into dest port like * Cisco routers */ flow->port[ndx] = 0; flow->port[ndx ^ 1] = htons(icmp->icmp_type * 256 + icmp->icmp_code); break; } return (0); } /* Convert a IPv4 packet to a partial flow record (used for comparison) */ static int ipv4_to_flowrec(struct FLOW *flow, const u_int8_t *pkt, size_t caplen, size_t len, int *isfrag, int af) { const struct ip *ip = (const struct ip *)pkt; int ndx; if (caplen < 20 || caplen < ip->ip_hl * 4) return (-1); /* Runt packet */ if (ip->ip_v != 4) return (-1); /* Unsupported IP version */ /* Prepare to store flow in canonical format */ ndx = memcmp(&ip->ip_src, &ip->ip_dst, sizeof(ip->ip_src)) > 0 ? 1 : 0; flow->af = af; flow->addr[ndx].v4 = ip->ip_src; flow->addr[ndx ^ 1].v4 = ip->ip_dst; flow->protocol = ip->ip_p; flow->octets[ndx] = len; flow->packets[ndx] = 1; *isfrag = (ntohs(ip->ip_off) & (IP_OFFMASK|IP_MF)) ? 1 : 0; /* Don't try to examine higher level headers if not first fragment */ if (*isfrag && (ntohs(ip->ip_off) & IP_OFFMASK) != 0) return (0); return (transport_to_flowrec(flow, pkt + (ip->ip_hl * 4), caplen - (ip->ip_hl * 4), *isfrag, ip->ip_p, ndx)); } /* Convert a IPv6 packet to a partial flow record (used for comparison) */ static int ipv6_to_flowrec(struct FLOW *flow, const u_int8_t *pkt, size_t caplen, size_t len, int *isfrag, int af) { const struct ip6_hdr *ip6 = (const struct ip6_hdr *)pkt; const struct ip6_ext *eh6; const struct ip6_frag *fh6; int ndx, nxt; if (caplen < sizeof(*ip6)) return (-1); /* Runt packet */ if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) return (-1); /* Unsupported IPv6 version */ /* Prepare to store flow in canonical format */ ndx = memcmp(&ip6->ip6_src, &ip6->ip6_dst, sizeof(ip6->ip6_src)) > 0 ? 1 : 0; flow->af = af; flow->ip6_flowlabel[ndx] = ip6->ip6_flow & IPV6_FLOWLABEL_MASK; flow->addr[ndx].v6 = ip6->ip6_src; flow->addr[ndx ^ 1].v6 = ip6->ip6_dst; flow->octets[ndx] = len; flow->packets[ndx] = 1; *isfrag = 0; nxt = ip6->ip6_nxt; pkt += sizeof(*ip6); caplen -= sizeof(*ip6); /* Now loop through headers, looking for transport header */ for (;;) { eh6 = (const struct ip6_ext *)pkt; if (nxt == IPPROTO_HOPOPTS || nxt == IPPROTO_ROUTING || nxt == IPPROTO_DSTOPTS) { if (caplen < sizeof(*eh6) || caplen < (eh6->ip6e_len + 1) << 3) return (1); /* Runt */ nxt = eh6->ip6e_nxt; pkt += (eh6->ip6e_len + 1) << 3; caplen -= (eh6->ip6e_len + 1) << 3; } else if (nxt == IPPROTO_FRAGMENT) { *isfrag = 1; fh6 = (const struct ip6_frag *)eh6; if (caplen < sizeof(*fh6)) return (1); /* Runt */ /* * Don't try to examine higher level headers if * not first fragment */ if ((fh6->ip6f_offlg & IP6F_OFF_MASK) != 0) return (0); nxt = fh6->ip6f_nxt; pkt += sizeof(*fh6); caplen -= sizeof(*fh6); } else break; } flow->protocol = nxt; return (transport_to_flowrec(flow, pkt, caplen, *isfrag, nxt, ndx)); } static void flow_update_expiry(struct FLOWTRACK *ft, struct FLOW *flow) { EXPIRY_REMOVE(EXPIRIES, &ft->expiries, flow->expiry); /* Flows over 2 GiB traffic */ if (flow->octets[0] > (1U << 31) || flow->octets[1] > (1U << 31)) { flow->expiry->expires_at = 0; flow->expiry->reason = R_OVERBYTES; goto out; } /* Flows over maximum life seconds */ if (ft->maximum_lifetime != 0 && flow->flow_last.tv_sec - flow->flow_start.tv_sec > ft->maximum_lifetime) { flow->expiry->expires_at = 0; flow->expiry->reason = R_MAXLIFE; goto out; } if (flow->protocol == IPPROTO_TCP) { /* Reset TCP flows */ if (ft->tcp_rst_timeout != 0 && ((flow->tcp_flags[0] & TH_RST) || (flow->tcp_flags[1] & TH_RST))) { flow->expiry->expires_at = flow->flow_last.tv_sec + ft->tcp_rst_timeout; flow->expiry->reason = R_TCP_RST; goto out; } /* Finished TCP flows */ if (ft->tcp_fin_timeout != 0 && ((flow->tcp_flags[0] & TH_FIN) && (flow->tcp_flags[1] & TH_FIN))) { flow->expiry->expires_at = flow->flow_last.tv_sec + ft->tcp_fin_timeout; flow->expiry->reason = R_TCP_FIN; goto out; } /* TCP flows */ if (ft->tcp_timeout != 0) { flow->expiry->expires_at = flow->flow_last.tv_sec + ft->tcp_timeout; flow->expiry->reason = R_TCP; goto out; } } if (ft->udp_timeout != 0 && flow->protocol == IPPROTO_UDP) { /* UDP flows */ flow->expiry->expires_at = flow->flow_last.tv_sec + ft->udp_timeout; flow->expiry->reason = R_UDP; goto out; } if (ft->icmp_timeout != 0 && ((flow->af == AF_INET && flow->protocol == IPPROTO_ICMP) || ((flow->af == AF_INET6 && flow->protocol == IPPROTO_ICMPV6)))) { /* ICMP flows */ flow->expiry->expires_at = flow->flow_last.tv_sec + ft->icmp_timeout; flow->expiry->reason = R_ICMP; goto out; } /* Everything else */ flow->expiry->expires_at = flow->flow_last.tv_sec + ft->general_timeout; flow->expiry->reason = R_GENERAL; out: if (ft->maximum_lifetime != 0 && flow->expiry->expires_at != 0) { flow->expiry->expires_at = MIN(flow->expiry->expires_at, flow->flow_start.tv_sec + ft->maximum_lifetime); } EXPIRY_INSERT(EXPIRIES, &ft->expiries, flow->expiry); } /* Return values from process_packet */ #define PP_OK 0 #define PP_BAD_PACKET -2 #define PP_MALLOC_FAIL -3 /* * Main per-packet processing function. Take a packet (provided by * libpcap) and attempt to find a matching flow. If no such flow exists, * then create one. * * Also marks flows for fast expiry, based on flow or packet attributes * (the actual expiry is performed elsewhere) */ static int process_packet(struct FLOWTRACK *ft, const u_int8_t *pkt, int af, const u_int32_t caplen, const u_int32_t len, const struct timeval *received_time) { struct FLOW tmp, *flow; int frag; ft->total_packets++; /* Convert the IP packet to a flow identity */ memset(&tmp, 0, sizeof(tmp)); switch (af) { case AF_INET: if (ipv4_to_flowrec(&tmp, pkt, caplen, len, &frag, af) == -1) goto bad; break; case AF_INET6: if (ipv6_to_flowrec(&tmp, pkt, caplen, len, &frag, af) == -1) goto bad; break; default: bad: ft->bad_packets++; return (PP_BAD_PACKET); } if (frag) ft->frag_packets++; /* Zero out bits of the flow that aren't relevant to tracking level */ switch (ft->track_level) { case TRACK_IP_ONLY: tmp.protocol = 0; /* FALLTHROUGH */ case TRACK_IP_PROTO: tmp.port[0] = tmp.port[1] = 0; tmp.tcp_flags[0] = tmp.tcp_flags[1] = 0; /* FALLTHROUGH */ case TRACK_FULL: break; } /* If a matching flow does not exist, create and insert one */ if ((flow = FLOW_FIND(FLOWS, &ft->flows, &tmp)) == NULL) { /* Allocate and fill in the flow */ if ((flow = flow_get(ft)) == NULL) { logit(LOG_ERR, "process_packet: flow_get failed", sizeof(*flow)); return (PP_MALLOC_FAIL); } memcpy(flow, &tmp, sizeof(*flow)); memcpy(&flow->flow_start, received_time, sizeof(flow->flow_start)); flow->flow_seq = ft->next_flow_seq++; FLOW_INSERT(FLOWS, &ft->flows, flow); /* Allocate and fill in the associated expiry event */ if ((flow->expiry = expiry_get(ft)) == NULL) { logit(LOG_ERR, "process_packet: expiry_get failed", sizeof(*flow->expiry)); return (PP_MALLOC_FAIL); } flow->expiry->flow = flow; /* Must be non-zero (0 means expire immediately) */ flow->expiry->expires_at = 1; flow->expiry->reason = R_GENERAL; EXPIRY_INSERT(EXPIRIES, &ft->expiries, flow->expiry); ft->num_flows++; if (verbose_flag) logit(LOG_DEBUG, "ADD FLOW %s", format_flow_brief(flow)); } else { /* Update flow statistics */ flow->packets[0] += tmp.packets[0]; flow->octets[0] += tmp.octets[0]; flow->tcp_flags[0] |= tmp.tcp_flags[0]; flow->packets[1] += tmp.packets[1]; flow->octets[1] += tmp.octets[1]; flow->tcp_flags[1] |= tmp.tcp_flags[1]; } memcpy(&flow->flow_last, received_time, sizeof(flow->flow_last)); if (flow->expiry->expires_at != 0) flow_update_expiry(ft, flow); return (PP_OK); } /* * Subtract two timevals. Returns (t1 - t2) in milliseconds. */ u_int32_t timeval_sub_ms(const struct timeval *t1, const struct timeval *t2) { struct timeval res; res.tv_sec = t1->tv_sec - t2->tv_sec; res.tv_usec = t1->tv_usec - t2->tv_usec; if (res.tv_usec < 0) { res.tv_usec += 1000000L; res.tv_sec--; } return ((u_int32_t)res.tv_sec * 1000 + (u_int32_t)res.tv_usec / 1000); } static void update_statistic(struct STATISTIC *s, double new, double n) { if (n == 1.0) { s->min = s->mean = s->max = new; return; } s->min = MIN(s->min, new); s->max = MAX(s->max, new); s->mean = s->mean + ((new - s->mean) / n); } /* Update global statistics */ static void update_statistics(struct FLOWTRACK *ft, struct FLOW *flow) { double tmp; static double n = 1.0; ft->flows_expired++; ft->flows_pp[flow->protocol % 256]++; tmp = (double)flow->flow_last.tv_sec + ((double)flow->flow_last.tv_usec / 1000000.0); tmp -= (double)flow->flow_start.tv_sec + ((double)flow->flow_start.tv_usec / 1000000.0); if (tmp < 0.0) tmp = 0.0; update_statistic(&ft->duration, tmp, n); update_statistic(&ft->duration_pp[flow->protocol], tmp, (double)ft->flows_pp[flow->protocol % 256]); tmp = flow->octets[0] + flow->octets[1]; update_statistic(&ft->octets, tmp, n); ft->octets_pp[flow->protocol % 256] += tmp; tmp = flow->packets[0] + flow->packets[1]; update_statistic(&ft->packets, tmp, n); ft->packets_pp[flow->protocol % 256] += tmp; n++; } static void update_expiry_stats(struct FLOWTRACK *ft, struct EXPIRY *e) { switch (e->reason) { case R_GENERAL: ft->expired_general++; break; case R_TCP: ft->expired_tcp++; break; case R_TCP_RST: ft->expired_tcp_rst++; break; case R_TCP_FIN: ft->expired_tcp_fin++; break; case R_UDP: ft->expired_udp++; break; case R_ICMP: ft->expired_icmp++; break; case R_MAXLIFE: ft->expired_maxlife++; break; case R_OVERBYTES: ft->expired_overbytes++; break; case R_OVERFLOWS: ft->expired_maxflows++; break; case R_FLUSH: ft->expired_flush++; break; } } /* How long before the next expiry event in millisecond */ static int next_expire(struct FLOWTRACK *ft) { struct EXPIRY *expiry; struct timeval now; u_int32_t expires_at, ret, fudge; gettimeofday(&now, NULL); if ((expiry = EXPIRY_MIN(EXPIRIES, &ft->expiries)) == NULL) return (-1); /* indefinite */ expires_at = expiry->expires_at; /* Don't cluster urgent expiries */ if (expires_at == 0 && (expiry->reason == R_OVERBYTES || expiry->reason == R_OVERFLOWS || expiry->reason == R_FLUSH)) return (0); /* Now */ /* Cluster expiries by expiry_interval */ if (ft->expiry_interval > 1) { if ((fudge = expires_at % ft->expiry_interval) > 0) expires_at += ft->expiry_interval - fudge; } if (expires_at < now.tv_sec) return (0); /* Now */ ret = 999 + (expires_at - now.tv_sec) * 1000; return (ret); } /* * Scan the tree of expiry events and process expired flows. If zap_all * is set, then forcibly expire all flows. */ #define CE_EXPIRE_NORMAL 0 /* Normal expiry processing */ #define CE_EXPIRE_ALL -1 /* Expire all flows immediately */ #define CE_EXPIRE_FORCED 1 /* Only expire force-expired flows */ static int check_expired(struct FLOWTRACK *ft, struct NETFLOW_TARGET *target, int ex) { struct FLOW **expired_flows, **oldexp; int num_expired, i, r; struct timeval now; struct EXPIRY *expiry, *nexpiry; gettimeofday(&now, NULL); r = 0; num_expired = 0; expired_flows = NULL; if (verbose_flag) logit(LOG_DEBUG, "Starting expiry scan: mode %d", ex); for(expiry = EXPIRY_MIN(EXPIRIES, &ft->expiries); expiry != NULL; expiry = nexpiry) { nexpiry = EXPIRY_NEXT(EXPIRIES, &ft->expiries, expiry); if ((expiry->expires_at == 0) || (ex == CE_EXPIRE_ALL) || (ex != CE_EXPIRE_FORCED && (expiry->expires_at < now.tv_sec))) { /* Flow has expired */ if (ft->maximum_lifetime != 0 && expiry->flow->flow_last.tv_sec - expiry->flow->flow_start.tv_sec >= ft->maximum_lifetime) expiry->reason = R_MAXLIFE; if (verbose_flag) logit(LOG_DEBUG, "Queuing flow seq:%"PRIu64" (%p) for expiry " "reason %d", expiry->flow->flow_seq, expiry->flow, expiry->reason); /* Add to array of expired flows */ oldexp = expired_flows; expired_flows = realloc(expired_flows, sizeof(*expired_flows) * (num_expired + 1)); /* Don't fatal on realloc failures */ if (expired_flows == NULL) expired_flows = oldexp; else { expired_flows[num_expired] = expiry->flow; num_expired++; } if (ex == CE_EXPIRE_ALL) expiry->reason = R_FLUSH; update_expiry_stats(ft, expiry); /* Remove from flow tree, destroy expiry event */ FLOW_REMOVE(FLOWS, &ft->flows, expiry->flow); EXPIRY_REMOVE(EXPIRIES, &ft->expiries, expiry); expiry->flow->expiry = NULL; expiry_put(ft, expiry); ft->num_flows--; } } if (verbose_flag) logit(LOG_DEBUG, "Finished scan %d flow(s) to be evicted", num_expired); /* Processing for expired flows */ if (num_expired > 0) { if (target != NULL && target->fd != -1) { r = target->dialect->func(expired_flows, num_expired, target->fd, if_index, &ft->flows_exported, &ft->system_boot_time, verbose_flag, &ft->option); if (verbose_flag) logit(LOG_DEBUG, "sent %d netflow packets", r); if (r > 0) { ft->packets_sent += r; /* XXX what if r < num_expired * 2 ? */ } else { ft->flows_dropped += num_expired * 2; } } for (i = 0; i < num_expired; i++) { if (verbose_flag) { logit(LOG_DEBUG, "EXPIRED: %s (%p)", format_flow(expired_flows[i]), expired_flows[i]); } update_statistics(ft, expired_flows[i]); flow_put(ft, expired_flows[i]); } free(expired_flows); } return (r == -1 ? -1 : num_expired); } /* * Force expiry of num_to_expire flows (e.g. when flow table overfull) */ static void force_expire(struct FLOWTRACK *ft, u_int32_t num_to_expire) { struct EXPIRY *expiry, **expiryv; int i; /* XXX move all overflow processing here (maybe) */ if (verbose_flag) logit(LOG_INFO, "Forcing expiry of %d flows", num_to_expire); /* * Do this in two steps, as it is dangerous to change a key on * a tree entry without first removing it and then re-adding it. * It is even worse when this has to be done during a FOREACH :) * To get around this, we make a list of expired flows and _then_ * alter them */ if ((expiryv = calloc(num_to_expire, sizeof(*expiryv))) == NULL) { /* * On malloc failure, expire ALL flows. I assume that * setting all the keys in a tree to the same value is * safe. */ logit(LOG_ERR, "Out of memory while expiring flows - " "all flows expired"); EXPIRY_FOREACH(expiry, EXPIRIES, &ft->expiries) { expiry->expires_at = 0; expiry->reason = R_OVERFLOWS; ft->flows_force_expired++; } return; } /* Make the list of flows to expire */ i = 0; EXPIRY_FOREACH(expiry, EXPIRIES, &ft->expiries) { if (i >= num_to_expire) break; expiryv[i++] = expiry; } if (i < num_to_expire) { logit(LOG_ERR, "Needed to expire %d flows, " "but only %d active", num_to_expire, i); num_to_expire = i; } for(i = 0; i < num_to_expire; i++) { EXPIRY_REMOVE(EXPIRIES, &ft->expiries, expiryv[i]); expiryv[i]->expires_at = 0; expiryv[i]->reason = R_OVERFLOWS; EXPIRY_INSERT(EXPIRIES, &ft->expiries, expiryv[i]); } ft->flows_force_expired += num_to_expire; free(expiryv); /* XXX - this is overcomplicated, perhaps use a separate queue */ } /* Delete all flows that we know about without processing */ static int delete_all_flows(struct FLOWTRACK *ft) { struct FLOW *flow, *nflow; int i; i = 0; for(flow = FLOW_MIN(FLOWS, &ft->flows); flow != NULL; flow = nflow) { nflow = FLOW_NEXT(FLOWS, &ft->flows, flow); FLOW_REMOVE(FLOWS, &ft->flows, flow); EXPIRY_REMOVE(EXPIRIES, &ft->expiries, flow->expiry); expiry_put(ft, flow->expiry); ft->num_flows--; flow_put(ft, flow); i++; } return (i); } /* * Log our current status. * Includes summary counters and (in verbose mode) the list of current flows * and the tree of expiry events. */ static int statistics(struct FLOWTRACK *ft, FILE *out, pcap_t *pcap) { int i; struct protoent *pe; char proto[32]; struct pcap_stat ps; fprintf(out, "Number of active flows: %d\n", ft->num_flows); fprintf(out, "Packets processed: %"PRIu64"\n", ft->total_packets); if (ft->non_sampled_packets) fprintf(out, "Packets non-sampled: %"PRIu64"\n", ft->non_sampled_packets); fprintf(out, "Fragments: %"PRIu64"\n", ft->frag_packets); fprintf(out, "Ignored packets: %"PRIu64" (%"PRIu64" non-IP, %"PRIu64" too short)\n", ft->non_ip_packets + ft->bad_packets, ft->non_ip_packets, ft->bad_packets); fprintf(out, "Flows expired: %"PRIu64" (%"PRIu64" forced)\n", ft->flows_expired, ft->flows_force_expired); fprintf(out, "Flows exported: %"PRIu64" in %"PRIu64" packets (%"PRIu64" failures)\n", ft->flows_exported, ft->packets_sent, ft->flows_dropped); if (pcap_stats(pcap, &ps) == 0) { fprintf(out, "Packets received by libpcap: %lu\n", (unsigned long)ps.ps_recv); fprintf(out, "Packets dropped by libpcap: %lu\n", (unsigned long)ps.ps_drop); fprintf(out, "Packets dropped by interface: %lu\n", (unsigned long)ps.ps_ifdrop); } fprintf(out, "\n"); if (ft->flows_expired != 0) { fprintf(out, "Expired flow statistics: minimum average maximum\n"); fprintf(out, " Flow bytes: %12.0f %12.0f %12.0f\n", ft->octets.min, ft->octets.mean, ft->octets.max); fprintf(out, " Flow packets: %12.0f %12.0f %12.0f\n", ft->packets.min, ft->packets.mean, ft->packets.max); fprintf(out, " Duration: %12.2fs %12.2fs %12.2fs\n", ft->duration.min, ft->duration.mean, ft->duration.max); fprintf(out, "\n"); fprintf(out, "Expired flow reasons:\n"); fprintf(out, " tcp = %9"PRIu64" tcp.rst = %9"PRIu64" " "tcp.fin = %9"PRIu64"\n", ft->expired_tcp, ft->expired_tcp_rst, ft->expired_tcp_fin); fprintf(out, " udp = %9"PRIu64" icmp = %9"PRIu64" " "general = %9"PRIu64"\n", ft->expired_udp, ft->expired_icmp, ft->expired_general); fprintf(out, " maxlife = %9"PRIu64"\n", ft->expired_maxlife); fprintf(out, "over 2 GiB = %9"PRIu64"\n", ft->expired_overbytes); fprintf(out, " maxflows = %9"PRIu64"\n", ft->expired_maxflows); fprintf(out, " flushed = %9"PRIu64"\n", ft->expired_flush); fprintf(out, "\n"); fprintf(out, "Per-protocol statistics: Octets " "Packets Avg Life Max Life\n"); for(i = 0; i < 256; i++) { if (ft->packets_pp[i]) { pe = getprotobynumber(i); snprintf(proto, sizeof(proto), "%s (%d)", pe != NULL ? pe->p_name : "Unknown", i); fprintf(out, " %17s: %14"PRIu64" %12"PRIu64" %8.2fs " "%10.2fs\n", proto, ft->octets_pp[i], ft->packets_pp[i], ft->duration_pp[i].mean, ft->duration_pp[i].max); } } } return (0); } static void dump_flows(struct FLOWTRACK *ft, FILE *out) { struct EXPIRY *expiry; time_t now; now = time(NULL); EXPIRY_FOREACH(expiry, EXPIRIES, &ft->expiries) { fprintf(out, "ACTIVE %s\n", format_flow(expiry->flow)); if ((long int) expiry->expires_at - now < 0) { fprintf(out, "EXPIRY EVENT for flow %"PRIu64" now%s\n", expiry->flow->flow_seq, expiry->expires_at == 0 ? " (FORCED)": ""); } else { fprintf(out, "EXPIRY EVENT for flow %"PRIu64" in %ld seconds\n", expiry->flow->flow_seq, (long int) expiry->expires_at - now); } fprintf(out, "\n"); } } /* * Figure out how many bytes to skip from front of packet to get past * datalink headers. If pkt is specified, also check whether determine * whether or not it is one that we are interested in (IPv4 or IPv6 for now) * * Returns number of bytes to skip or -1 to indicate that entire * packet should be skipped */ static int datalink_check(int linktype, const u_int8_t *pkt, u_int32_t caplen, int *af) { int i, j; u_int32_t frametype; static const struct DATALINK *dl = NULL; /* Try to cache last used linktype */ if (dl == NULL || dl->dlt != linktype) { for (i = 0; lt[i].dlt != linktype && lt[i].dlt != -1; i++) ; dl = <[i]; } if (dl->dlt == -1 || pkt == NULL) return (dl->dlt); if (caplen <= dl->skiplen) return (-1); /* Suck out the frametype */ frametype = 0; if (dl->ft_is_be) { for (j = 0; j < dl->ft_len; j++) { frametype <<= 8; frametype |= pkt[j + dl->ft_off]; } } else { for (j = dl->ft_len - 1; j >= 0 ; j--) { frametype <<= 8; frametype |= pkt[j + dl->ft_off]; } } frametype &= dl->ft_mask; if (frametype == dl->ft_v4) *af = AF_INET; else if (frametype == dl->ft_v6) *af = AF_INET6; else return (-1); return (dl->skiplen); } /* * Per-packet callback function from libpcap. Pass the packet (if it is IP) * sans datalink headers to process_packet. */ static void flow_cb(u_char *user_data, const struct pcap_pkthdr* phdr, const u_char *pkt) { int s, af; struct CB_CTXT *cb_ctxt = (struct CB_CTXT *)user_data; struct timeval tv; if (cb_ctxt->ft->option.sample && (cb_ctxt->ft->total_packets + cb_ctxt->ft->non_sampled_packets) % cb_ctxt->ft->option.sample > 0) { cb_ctxt->ft->non_sampled_packets++; return; } s = datalink_check(cb_ctxt->linktype, pkt, phdr->caplen, &af); if (s < 0 || (!cb_ctxt->want_v6 && af == AF_INET6)) { cb_ctxt->ft->non_ip_packets++; } else { tv.tv_sec = phdr->ts.tv_sec; tv.tv_usec = phdr->ts.tv_usec; if (process_packet(cb_ctxt->ft, pkt + s, af, phdr->caplen - s, phdr->len - s, &tv) == PP_MALLOC_FAIL) cb_ctxt->fatal = 1; } } static void print_timeouts(struct FLOWTRACK *ft, FILE *out) { fprintf(out, " TCP timeout: %ds\n", ft->tcp_timeout); fprintf(out, " TCP post-RST timeout: %ds\n", ft->tcp_rst_timeout); fprintf(out, " TCP post-FIN timeout: %ds\n", ft->tcp_fin_timeout); fprintf(out, " UDP timeout: %ds\n", ft->udp_timeout); fprintf(out, " ICMP timeout: %ds\n", ft->icmp_timeout); fprintf(out, " General timeout: %ds\n", ft->general_timeout); fprintf(out, " Maximum lifetime: %ds\n", ft->maximum_lifetime); fprintf(out, " Expiry interval: %ds\n", ft->expiry_interval); } static int accept_control(int lsock, struct NETFLOW_TARGET *target, struct FLOWTRACK *ft, pcap_t *pcap, int *exit_request, int *stop_collection_flag) { unsigned char buf[64], *p; FILE *ctlf; int fd, ret; if ((fd = accept(lsock, NULL, NULL)) == -1) { logit(LOG_ERR, "ctl accept: %s - exiting", strerror(errno)); return(-1); } if ((ctlf = fdopen(fd, "r+")) == NULL) { logit(LOG_ERR, "fdopen: %s - exiting\n", strerror(errno)); close(fd); return (-1); } setlinebuf(ctlf); if (fgets(buf, sizeof(buf), ctlf) == NULL) { logit(LOG_ERR, "Control socket yielded no data"); return (0); } if ((p = strchr(buf, '\n')) != NULL) *p = '\0'; if (verbose_flag) logit(LOG_DEBUG, "Control socket \"%s\"", buf); /* XXX - use dispatch table */ ret = -1; if (strcmp(buf, "help") == 0) { fprintf(ctlf, "Valid control words are:\n"); fprintf(ctlf, "\tdebug+ debug- delete-all dump-flows exit " "expire-all\n"); fprintf(ctlf, "\tshutdown start-gather statistics stop-gather " "timeouts\n"); fprintf(ctlf, "\tsend-template\n"); ret = 0; } else if (strcmp(buf, "shutdown") == 0) { fprintf(ctlf, "softflowd[%u]: Shutting down gracefully...\n", getpid()); graceful_shutdown_request = 1; ret = 1; } else if (strcmp(buf, "exit") == 0) { fprintf(ctlf, "softflowd[%u]: Exiting now...\n", getpid()); *exit_request = 1; ret = 1; } else if (strcmp(buf, "expire-all") == 0) { netflow9_resend_template(); fprintf(ctlf, "softflowd[%u]: Expired %d flows.\n", getpid(), check_expired(ft, target, CE_EXPIRE_ALL)); ret = 0; } else if (strcmp(buf, "send-template") == 0) { netflow9_resend_template(); fprintf(ctlf, "softflowd[%u]: Template will be sent at " "next flow export\n", getpid()); ret = 0; } else if (strcmp(buf, "delete-all") == 0) { fprintf(ctlf, "softflowd[%u]: Deleted %d flows.\n", getpid(), delete_all_flows(ft)); ret = 0; } else if (strcmp(buf, "statistics") == 0) { fprintf(ctlf, "softflowd[%u]: Accumulated statistics " "since %s UTC:\n", getpid(), format_time(ft->system_boot_time.tv_sec)); statistics(ft, ctlf, pcap); ret = 0; } else if (strcmp(buf, "debug+") == 0) { fprintf(ctlf, "softflowd[%u]: Debug level increased.\n", getpid()); verbose_flag = 1; ret = 0; } else if (strcmp(buf, "debug-") == 0) { fprintf(ctlf, "softflowd[%u]: Debug level decreased.\n", getpid()); verbose_flag = 0; ret = 0; } else if (strcmp(buf, "stop-gather") == 0) { fprintf(ctlf, "softflowd[%u]: Data collection stopped.\n", getpid()); *stop_collection_flag = 1; ret = 0; } else if (strcmp(buf, "start-gather") == 0) { fprintf(ctlf, "softflowd[%u]: Data collection resumed.\n", getpid()); *stop_collection_flag = 0; ret = 0; } else if (strcmp(buf, "dump-flows") == 0) { fprintf(ctlf, "softflowd[%u]: Dumping flow data:\n", getpid()); dump_flows(ft, ctlf); ret = 0; } else if (strcmp(buf, "timeouts") == 0) { fprintf(ctlf, "softflowd[%u]: Printing timeouts:\n", getpid()); print_timeouts(ft, ctlf); ret = 0; } else { fprintf(ctlf, "Unknown control commmand \"%s\"\n", buf); ret = 0; } fclose(ctlf); close(fd); return (ret); } static int connsock(struct sockaddr_storage *addr, socklen_t len, int hoplimit) { int s; unsigned int h6; unsigned char h4; struct sockaddr_in *in4 = (struct sockaddr_in *)addr; struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)addr; if ((s = socket(addr->ss_family, SOCK_DGRAM, 0)) == -1) { fprintf(stderr, "socket() error: %s\n", strerror(errno)); exit(1); } if (connect(s, (struct sockaddr*)addr, len) == -1) { fprintf(stderr, "connect() error: %s\n", strerror(errno)); exit(1); } switch (addr->ss_family) { case AF_INET: /* Default to link-local TTL for multicast addresses */ if (hoplimit == -1 && IN_MULTICAST(in4->sin_addr.s_addr)) hoplimit = 1; if (hoplimit == -1) break; h4 = hoplimit; if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, &h4, sizeof(h4)) == -1) { fprintf(stderr, "setsockopt(IP_MULTICAST_TTL, " "%u): %s\n", h4, strerror(errno)); exit(1); } break; case AF_INET6: /* Default to link-local hoplimit for multicast addresses */ if (hoplimit == -1 && IN6_IS_ADDR_MULTICAST(&in6->sin6_addr)) hoplimit = 1; if (hoplimit == -1) break; h6 = hoplimit; if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &h6, sizeof(h6)) == -1) { fprintf(stderr, "setsockopt(IPV6_MULTICAST_HOPS, %u): " "%s\n", h6, strerror(errno)); exit(1); } } return(s); } static int unix_listener(const char *path) { struct sockaddr_un addr; socklen_t addrlen; int s; memset(&addr, '\0', sizeof(addr)); addr.sun_family = AF_UNIX; if (strlcpy(addr.sun_path, path, sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) { fprintf(stderr, "control socket path too long\n"); exit(1); } addr.sun_path[sizeof(addr.sun_path) - 1] = '\0'; addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(path) + 1; #ifdef SOCK_HAS_LEN addr.sun_len = addrlen; #endif if ((s = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { fprintf(stderr, "unix domain socket() error: %s\n", strerror(errno)); exit(1); } unlink(path); if (bind(s, (struct sockaddr*)&addr, addrlen) == -1) { fprintf(stderr, "unix domain bind(\"%s\") error: %s\n", addr.sun_path, strerror(errno)); exit(1); } if (listen(s, 64) == -1) { fprintf(stderr, "unix domain listen() error: %s\n", strerror(errno)); exit(1); } return (s); } static void setup_packet_capture(struct pcap **pcap, int *linktype, char *dev, char *capfile, char *bpf_prog, int need_v6) { char ebuf[PCAP_ERRBUF_SIZE]; struct bpf_program prog_c; u_int32_t bpf_mask, bpf_net; /* Open pcap */ if (dev != NULL) { if ((*pcap = pcap_open_live(dev, need_v6 ? LIBPCAP_SNAPLEN_V6 : LIBPCAP_SNAPLEN_V4, 1, 0, ebuf)) == NULL) { fprintf(stderr, "pcap_open_live: %s\n", ebuf); exit(1); } if (pcap_lookupnet(dev, &bpf_net, &bpf_mask, ebuf) == -1) bpf_net = bpf_mask = 0; } else { if ((*pcap = pcap_open_offline(capfile, ebuf)) == NULL) { fprintf(stderr, "pcap_open_offline(%s): %s\n", capfile, ebuf); exit(1); } bpf_net = bpf_mask = 0; } *linktype = pcap_datalink(*pcap); if (datalink_check(*linktype, NULL, 0, NULL) == -1) { fprintf(stderr, "Unsupported datalink type %d\n", *linktype); exit(1); } /* Attach BPF filter, if specified */ if (bpf_prog != NULL) { if (pcap_compile(*pcap, &prog_c, bpf_prog, 1, bpf_mask) == -1) { fprintf(stderr, "pcap_compile(\"%s\"): %s\n", bpf_prog, pcap_geterr(*pcap)); exit(1); } if (pcap_setfilter(*pcap, &prog_c) == -1) { fprintf(stderr, "pcap_setfilter: %s\n", pcap_geterr(*pcap)); exit(1); } } #ifdef BIOCLOCK /* * If we are reading from an device (not a file), then * lock the underlying BPF device to prevent changes in the * unprivileged child */ if (dev != NULL && ioctl(pcap_fileno(*pcap), BIOCLOCK) < 0) { fprintf(stderr, "ioctl(BIOCLOCK) failed: %s\n", strerror(errno)); exit(1); } #endif } static void init_flowtrack(struct FLOWTRACK *ft) { /* Set up flow-tracking structure */ memset(ft, '\0', sizeof(*ft)); ft->next_flow_seq = 1; FLOW_INIT(&ft->flows); EXPIRY_INIT(&ft->expiries); freelist_init(&ft->flow_freelist, sizeof(struct FLOW)); freelist_init(&ft->expiry_freelist, sizeof(struct EXPIRY)); ft->max_flows = DEFAULT_MAX_FLOWS; ft->track_level = TRACK_FULL; ft->tcp_timeout = DEFAULT_TCP_TIMEOUT; ft->tcp_rst_timeout = DEFAULT_TCP_RST_TIMEOUT; ft->tcp_fin_timeout = DEFAULT_TCP_FIN_TIMEOUT; ft->udp_timeout = DEFAULT_UDP_TIMEOUT; ft->icmp_timeout = DEFAULT_ICMP_TIMEOUT; ft->general_timeout = DEFAULT_GENERAL_TIMEOUT; ft->maximum_lifetime = DEFAULT_MAXIMUM_LIFETIME; ft->expiry_interval = DEFAULT_EXPIRY_INTERVAL; } static char * argv_join(int argc, char **argv) { int i; size_t ret_len; char *ret; ret_len = 0; ret = NULL; for (i = 0; i < argc; i++) { ret_len += strlen(argv[i]); if ((ret = realloc(ret, ret_len + 2)) == NULL) { fprintf(stderr, "Memory allocation failed.\n"); exit(1); } if (i == 0) ret[0] = '\0'; else { ret_len++; /* Make room for ' ' */ strlcat(ret, " ", ret_len + 1); } strlcat(ret, argv[i], ret_len + 1); } return (ret); } /* Display commandline usage information */ static void usage(void) { fprintf(stderr, "Usage: %s [options] [bpf_program]\n" "This is %s version %s. Valid commandline options:\n" " -i [idx:]interface Specify interface to listen on\n" " -r pcap_file Specify packet capture file to read\n" " -t timeout=time Specify named timeout\n" " -m max_flows Specify maximum number of flows to track (default %d)\n" " -n host:port Send Cisco NetFlow(tm)-compatible packets to host:port\n" " -p pidfile Record pid in specified file\n" " (default: %s)\n" " -c pidfile Location of control socket\n" " (default: %s)\n" " -v 1|5|9 NetFlow export packet version\n" " -L hoplimit Set TTL/hoplimit for export datagrams\n" " -T full|proto|ip Set flow tracking level (default: full)\n" " -6 Track IPv6 flows, regardless of whether selected \n" " NetFlow export protocol supports it\n" " -d Don't daemonise (run in foreground)\n" " -D Debug mode: foreground + verbosity + track v6 flows\n" " -s sampling_rate Specify periodical sampling rate (denominator)\n" " -h Display this help\n" "\n" "Valid timeout names and default values:\n" " tcp (default %6d)" " tcp.rst (default %6d)" " tcp.fin (default %6d)\n" " udp (default %6d)" " icmp (default %6d)" " general (default %6d)\n" " maxlife (default %6d)" " expint (default %6d)\n" "\n" , PROGNAME, PROGNAME, PROGVER, DEFAULT_MAX_FLOWS, DEFAULT_PIDFILE, DEFAULT_CTLSOCK, DEFAULT_TCP_TIMEOUT, DEFAULT_TCP_RST_TIMEOUT, DEFAULT_TCP_FIN_TIMEOUT, DEFAULT_UDP_TIMEOUT, DEFAULT_ICMP_TIMEOUT, DEFAULT_GENERAL_TIMEOUT, DEFAULT_MAXIMUM_LIFETIME, DEFAULT_EXPIRY_INTERVAL); } static void set_timeout(struct FLOWTRACK *ft, const char *to_spec) { char *name, *value; int timeout; if ((name = strdup(to_spec)) == NULL) { fprintf(stderr, "Out of memory\n"); exit(1); } if ((value = strchr(name, '=')) == NULL || *(++value) == '\0') { fprintf(stderr, "Invalid -t option \"%s\".\n", name); usage(); exit(1); } *(value - 1) = '\0'; timeout = convtime(value); if (timeout < 0) { fprintf(stderr, "Invalid -t timeout.\n"); usage(); exit(1); } if (strcmp(name, "tcp") == 0) ft->tcp_timeout = timeout; else if (strcmp(name, "tcp.rst") == 0) ft->tcp_rst_timeout = timeout; else if (strcmp(name, "tcp.fin") == 0) ft->tcp_fin_timeout = timeout; else if (strcmp(name, "udp") == 0) ft->udp_timeout = timeout; else if (strcmp(name, "icmp") == 0) ft->icmp_timeout = timeout; else if (strcmp(name, "general") == 0) ft->general_timeout = timeout; else if (strcmp(name, "maxlife") == 0) ft->maximum_lifetime = timeout; else if (strcmp(name, "expint") == 0) ft->expiry_interval = timeout; else { fprintf(stderr, "Invalid -t name.\n"); usage(); exit(1); } if (ft->general_timeout == 0) { fprintf(stderr, "\"general\" flow timeout must be " "greater than zero\n"); exit(1); } free(name); } static void parse_hostport(const char *s, struct sockaddr *addr, socklen_t *len) { char *orig, *host, *port; struct addrinfo hints, *res; int herr; if ((host = orig = strdup(s)) == NULL) { fprintf(stderr, "Out of memory\n"); exit(1); } if ((port = strrchr(host, ':')) == NULL || *(++port) == '\0' || *host == '\0') { fprintf(stderr, "Invalid -n argument.\n"); usage(); exit(1); } *(port - 1) = '\0'; /* Accept [host]:port for numeric IPv6 addresses */ if (*host == '[' && *(port - 2) == ']') { host++; *(port - 2) = '\0'; } memset(&hints, '\0', sizeof(hints)); hints.ai_socktype = SOCK_DGRAM; if ((herr = getaddrinfo(host, port, &hints, &res)) == -1) { fprintf(stderr, "Address lookup failed: %s\n", gai_strerror(herr)); exit(1); } if (res == NULL || res->ai_addr == NULL) { fprintf(stderr, "No addresses found for [%s]:%s\n", host, port); exit(1); } if (res->ai_addrlen > *len) { fprintf(stderr, "Address too long\n"); exit(1); } memcpy(addr, res->ai_addr, res->ai_addrlen); free(orig); *len = res->ai_addrlen; } /* * Drop privileges and chroot, will exit on failure */ static void drop_privs(void) { struct passwd *pw; if ((pw = getpwnam(PRIVDROP_USER)) == NULL) { logit(LOG_ERR, "Unable to find unprivileged user \"%s\"", PRIVDROP_USER); exit(1); } if (chdir(PRIVDROP_CHROOT_DIR) != 0) { logit(LOG_ERR, "Unable to chdir to chroot directory \"%s\": %s", PRIVDROP_CHROOT_DIR, strerror(errno)); exit(1); } if (chroot(PRIVDROP_CHROOT_DIR) != 0) { logit(LOG_ERR, "Unable to chroot to directory \"%s\": %s", PRIVDROP_CHROOT_DIR, strerror(errno)); exit(1); } if (chdir("/") != 0) { logit(LOG_ERR, "Unable to chdir to chroot root: %s", strerror(errno)); exit(1); } if (setgroups(1, &pw->pw_gid) != 0) { logit(LOG_ERR, "Couldn't setgroups (%u): %s", (unsigned int)pw->pw_gid, strerror(errno)); exit(1); } #if defined(HAVE_SETRESGID) if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1) { #elif defined(HAVE_SETREGID) if (setregid(pw->pw_gid, pw->pw_gid) == -1) { #else if (setegid(pw->pw_gid) == -1 || setgid(pw->pw_gid) == -1) { #endif logit(LOG_ERR, "Couldn't set gid (%u): %s", (unsigned int)pw->pw_gid, strerror(errno)); exit(1); } #if defined(HAVE_SETRESUID) if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1) { #elif defined(HAVE_SETREUID) if (setreuid(pw->pw_uid, pw->pw_uid) == -1) { #else if (seteuid(pw->pw_uid) == -1 || setuid(pw->pw_uid) == -1) { #endif logit(LOG_ERR, "Couldn't set uid (%u): %s", (unsigned int)pw->pw_uid, strerror(errno)); exit(1); } } int main(int argc, char **argv) { char *dev, *capfile, *bpf_prog, dest_addr[256], dest_serv[256]; const char *pidfile_path, *ctlsock_path; extern char *optarg; extern int optind; int ch, dontfork_flag, linktype, ctlsock, i, err, always_v6, r; int stop_collection_flag, exit_request, hoplimit; pcap_t *pcap = NULL; struct sockaddr_storage dest; struct FLOWTRACK flowtrack; socklen_t dest_len; struct NETFLOW_TARGET target; struct CB_CTXT cb_ctxt; struct pollfd pl[2]; closefrom(STDERR_FILENO + 1); init_flowtrack(&flowtrack); memset(&dest, '\0', sizeof(dest)); dest_len = 0; memset(&target, '\0', sizeof(target)); target.fd = -1; target.dialect = &nf[0]; hoplimit = -1; bpf_prog = NULL; ctlsock = -1; dev = capfile = NULL; pidfile_path = DEFAULT_PIDFILE; ctlsock_path = DEFAULT_CTLSOCK; dontfork_flag = 0; always_v6 = 0; while ((ch = getopt(argc, argv, "6hdDL:T:i:r:f:t:n:m:p:c:v:s:")) != -1) { switch (ch) { case '6': always_v6 = 1; break; case 'h': usage(); return (0); case 'D': verbose_flag = 1; always_v6 = 1; /* FALLTHROUGH */ case 'd': dontfork_flag = 1; break; case 'i': if (capfile != NULL || dev != NULL) { fprintf(stderr, "Packet source already " "specified.\n\n"); usage(); exit(1); } dev = strsep(&optarg, ":"); if (optarg != NULL) { if_index = (u_int16_t) atoi(dev); dev = optarg; } if (verbose_flag) fprintf(stderr, "Using %s (idx: %d)\n", dev, if_index); break; case 'r': if (capfile != NULL || dev != NULL) { fprintf(stderr, "Packet source already " "specified.\n\n"); usage(); exit(1); } capfile = optarg; dontfork_flag = 1; ctlsock_path = NULL; break; case 't': /* Will exit on failure */ set_timeout(&flowtrack, optarg); break; case 'T': if (strcasecmp(optarg, "full") == 0) flowtrack.track_level = TRACK_FULL; else if (strcasecmp(optarg, "proto") == 0) flowtrack.track_level = TRACK_IP_PROTO; else if (strcasecmp(optarg, "ip") == 0) flowtrack.track_level = TRACK_IP_ONLY; else { fprintf(stderr, "Unknown flow tracking " "level\n"); usage(); exit(1); } break; case 'L': hoplimit = atoi(optarg); if (hoplimit < 0 || hoplimit > 255) { fprintf(stderr, "Invalid hop limit\n\n"); usage(); exit(1); } break; case 'm': if ((flowtrack.max_flows = atoi(optarg)) < 0) { fprintf(stderr, "Invalid maximum flows\n\n"); usage(); exit(1); } break; case 'n': /* Will exit on failure */ dest_len = sizeof(dest); parse_hostport(optarg, (struct sockaddr *)&dest, &dest_len); break; case 'p': pidfile_path = optarg; break; case 'c': if (strcmp(optarg, "none") == 0) ctlsock_path = NULL; else ctlsock_path = optarg; break; case 'v': for(i = 0, r = atoi(optarg); nf[i].version != -1; i++) { if (nf[i].version == r) break; } if (nf[i].version == -1) { fprintf(stderr, "Invalid NetFlow version\n"); exit(1); } target.dialect = &nf[i]; break; case 's': flowtrack.option.sample = atoi(optarg); if (flowtrack.option.sample < 2) { flowtrack.option.sample = 0; } break; default: fprintf(stderr, "Invalid commandline option.\n"); usage(); exit(1); } } if (capfile == NULL && dev == NULL) { fprintf(stderr, "-i or -r option not specified.\n"); usage(); exit(1); } /* join remaining arguments (if any) into bpf program */ bpf_prog = argv_join(argc - optind, argv + optind); /* Will exit on failure */ setup_packet_capture(&pcap, &linktype, dev, capfile, bpf_prog, target.dialect->v6_capable || always_v6); /* Netflow send socket */ if (dest.ss_family != 0) { if ((err = getnameinfo((struct sockaddr *)&dest, dest_len, dest_addr, sizeof(dest_addr), dest_serv, sizeof(dest_serv), NI_NUMERICHOST)) == -1) { fprintf(stderr, "getnameinfo: %d\n", err); exit(1); } target.fd = connsock(&dest, dest_len, hoplimit); } /* Control socket */ if (ctlsock_path != NULL) ctlsock = unix_listener(ctlsock_path); /* Will exit on fail */ if (dontfork_flag) { loginit(PROGNAME, 1); } else { FILE *pidfile; r = daemon(0, 0); loginit(PROGNAME, 0); if ((pidfile = fopen(pidfile_path, "w")) == NULL) { fprintf(stderr, "Couldn't open pidfile %s: %s\n", pidfile_path, strerror(errno)); exit(1); } fprintf(pidfile, "%u\n", getpid()); fclose(pidfile); signal(SIGINT, sighand_graceful_shutdown); signal(SIGTERM, sighand_graceful_shutdown); signal(SIGSEGV, sighand_other); setprotoent(1); drop_privs(); } logit(LOG_NOTICE, "%s v%s starting data collection", PROGNAME, PROGVER); if (dest.ss_family != 0) { logit(LOG_NOTICE, "Exporting flows to [%s]:%s", dest_addr, dest_serv); } /* Main processing loop */ gettimeofday(&flowtrack.system_boot_time, NULL); stop_collection_flag = 0; memset(&cb_ctxt, '\0', sizeof(cb_ctxt)); cb_ctxt.ft = &flowtrack; cb_ctxt.linktype = linktype; cb_ctxt.want_v6 = target.dialect->v6_capable || always_v6; for (r = 0; graceful_shutdown_request == 0; r = 0) { /* * Silly libpcap's timeout function doesn't work, so we * do it here (only if we are reading live) */ if (capfile == NULL) { memset(pl, '\0', sizeof(pl)); /* This can only be set via the control socket */ if (!stop_collection_flag) { pl[0].events = POLLIN|POLLERR|POLLHUP; pl[0].fd = pcap_fileno(pcap); } if (ctlsock != -1) { pl[1].fd = ctlsock; pl[1].events = POLLIN|POLLERR|POLLHUP; } r = poll(pl, (ctlsock == -1) ? 1 : 2, next_expire(&flowtrack)); if (r == -1 && errno != EINTR) { logit(LOG_ERR, "Exiting on poll: %s", strerror(errno)); break; } } /* Accept connection on control socket if present */ if (ctlsock != -1 && pl[1].revents != 0) { if (accept_control(ctlsock, &target, &flowtrack, pcap, &exit_request, &stop_collection_flag) != 0) break; } /* If we have data, run it through libpcap */ if (!stop_collection_flag && (capfile != NULL || pl[0].revents != 0)) { r = pcap_dispatch(pcap, flowtrack.max_flows, flow_cb, (void*)&cb_ctxt); if (r == -1) { logit(LOG_ERR, "Exiting on pcap_dispatch: %s", pcap_geterr(pcap)); break; } else if (r == 0 && capfile != NULL) { logit(LOG_NOTICE, "Shutting down after " "pcap EOF"); graceful_shutdown_request = 1; break; } } r = 0; /* Fatal error from per-packet functions */ if (cb_ctxt.fatal) { logit(LOG_WARNING, "Fatal error - exiting immediately"); break; } /* * Expiry processing happens every recheck_rate seconds * or whenever we have exceeded the maximum number of active * flows */ if (flowtrack.num_flows > flowtrack.max_flows || next_expire(&flowtrack) == 0) { expiry_check: /* * If we are reading from a capture file, we never * expire flows based on time - instead we only * expire flows when the flow table is full. */ if (check_expired(&flowtrack, &target, capfile == NULL ? CE_EXPIRE_NORMAL : CE_EXPIRE_FORCED) < 0) logit(LOG_WARNING, "Unable to export flows"); /* * If we are over max_flows, force-expire the oldest * out first and immediately reprocess to evict them */ if (flowtrack.num_flows > flowtrack.max_flows) { force_expire(&flowtrack, flowtrack.num_flows - flowtrack.max_flows); goto expiry_check; } } } /* Flags set by signal handlers or control socket */ if (graceful_shutdown_request) { logit(LOG_WARNING, "Shutting down on user request"); check_expired(&flowtrack, &target, CE_EXPIRE_ALL); } else if (exit_request) logit(LOG_WARNING, "Exiting immediately on user request"); else logit(LOG_ERR, "Exiting immediately on internal error"); if (capfile != NULL && dontfork_flag) statistics(&flowtrack, stdout, pcap); pcap_close(pcap); if (target.fd != -1) close(target.fd); unlink(pidfile_path); if (ctlsock_path != NULL) unlink(ctlsock_path); return(r == 0 ? 0 : 1); } softflowd-0.9.9/softflowd.h010064400017500001750000000176301171606473600141110ustar00djmdjm/* * Copyright (c) 2002 Damien Miller. 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 _SOFTFLOWD_H #define _SOFTFLOWD_H #include "common.h" #include "sys-tree.h" #include "freelist.h" #include "treetype.h" /* User to setuid to and directory to chroot to when we drop privs */ #ifndef PRIVDROP_USER # define PRIVDROP_USER "nobody" #endif #ifndef PRIVDROP_CHROOT_DIR # define PRIVDROP_CHROOT_DIR "/var/empty" #endif /* * Capture length for libpcap: Must fit the link layer header, plus * a maximally sized ip/ipv6 header and most of a TCP header */ #define LIBPCAP_SNAPLEN_V4 96 #define LIBPCAP_SNAPLEN_V6 160 /* * Timeouts */ #define DEFAULT_TCP_TIMEOUT 3600 #define DEFAULT_TCP_RST_TIMEOUT 120 #define DEFAULT_TCP_FIN_TIMEOUT 300 #define DEFAULT_UDP_TIMEOUT 300 #define DEFAULT_ICMP_TIMEOUT 300 #define DEFAULT_GENERAL_TIMEOUT 3600 #define DEFAULT_MAXIMUM_LIFETIME (3600*24*7) #define DEFAULT_EXPIRY_INTERVAL 60 /* * Default maximum number of flow to track simultaneously * 8192 corresponds to just under 1Mb of flow data */ #define DEFAULT_MAX_FLOWS 8192 /* Store a couple of statistics, maybe more in the future */ struct STATISTIC { double min, mean, max; }; /* Flow tracking levels */ #define TRACK_FULL 1 /* src/dst/addr/port/proto 5-tuple */ #define TRACK_IP_PROTO 2 /* src/dst/proto 3-tuple */ #define TRACK_IP_ONLY 3 /* src/dst tuple */ /* * This structure contains optional information carried by Option Data * Record. */ struct OPTION { uint32_t sample; }; /* * This structure is the root of the flow tracking system. * It holds the root of the tree of active flows and the head of the * tree of expiry events. It also collects miscellaneous statistics */ struct FLOWTRACK { /* The flows and their expiry events */ FLOW_HEAD(FLOWS, FLOW) flows; /* Top of flow tree */ EXPIRY_HEAD(EXPIRIES, EXPIRY) expiries; /* Top of expiries tree */ struct freelist flow_freelist; /* Freelist for flows */ struct freelist expiry_freelist; /* Freelist for expiry events */ unsigned int num_flows; /* # of active flows */ unsigned int max_flows; /* Max # of active flows */ u_int64_t next_flow_seq; /* Next flow ID */ /* Stuff related to flow export */ struct timeval system_boot_time; /* SysUptime */ int track_level; /* See TRACK_* above */ /* Flow timeouts */ int tcp_timeout; /* Open TCP connections */ int tcp_rst_timeout; /* TCP flows after RST */ int tcp_fin_timeout; /* TCP flows after bidi FIN */ int udp_timeout; /* UDP flows */ int icmp_timeout; /* ICMP flows */ int general_timeout; /* Everything else */ int maximum_lifetime; /* Maximum life for flows */ int expiry_interval; /* Interval between expiries */ /* Statistics */ u_int64_t total_packets; /* # of good packets */ u_int64_t non_sampled_packets; /* # of not sampled packets */ u_int64_t frag_packets; /* # of fragmented packets */ u_int64_t non_ip_packets; /* # of not-IP packets */ u_int64_t bad_packets; /* # of bad packets */ u_int64_t flows_expired; /* # expired */ u_int64_t flows_exported; /* # of flows sent */ u_int64_t flows_dropped; /* # of flows dropped */ u_int64_t flows_force_expired; /* # of flows forced out */ u_int64_t packets_sent; /* # netflow packets sent */ struct STATISTIC duration; /* Flow duration */ struct STATISTIC octets; /* Bytes (bidir) */ struct STATISTIC packets; /* Packets (bidir) */ /* Per protocol statistics */ u_int64_t flows_pp[256]; u_int64_t octets_pp[256]; u_int64_t packets_pp[256]; struct STATISTIC duration_pp[256]; /* Timeout statistics */ u_int64_t expired_general; u_int64_t expired_tcp; u_int64_t expired_tcp_rst; u_int64_t expired_tcp_fin; u_int64_t expired_udp; u_int64_t expired_icmp; u_int64_t expired_maxlife; u_int64_t expired_overbytes; u_int64_t expired_maxflows; u_int64_t expired_flush; /* Optional information */ struct OPTION option; }; /* * This structure is an entry in the tree of flows that we are * currently tracking. * * Because flows are matched _bi-directionally_, they must be stored in * a canonical format: the numerically lowest address and port number must * be stored in the first address and port array slot respectively. */ struct FLOW { /* Housekeeping */ struct EXPIRY *expiry; /* Pointer to expiry record */ FLOW_ENTRY(FLOW) trp; /* Tree pointer */ /* Flow identity (all are in network byte order) */ int af; /* Address family of flow */ u_int32_t ip6_flowlabel[2]; /* IPv6 Flowlabel */ union { struct in_addr v4; struct in6_addr v6; } addr[2]; /* Endpoint addresses */ u_int16_t port[2]; /* Endpoint ports */ u_int8_t tcp_flags[2]; /* Cumulative OR of flags */ u_int8_t protocol; /* Protocol */ /* Per-flow statistics (all in _host_ byte order) */ u_int64_t flow_seq; /* Flow ID */ struct timeval flow_start; /* Time of creation */ struct timeval flow_last; /* Time of last traffic */ /* Per-endpoint statistics (all in _host_ byte order) */ u_int32_t octets[2]; /* Octets so far */ u_int32_t packets[2]; /* Packets so far */ }; /* * This is an entry in the tree of expiry events. The tree is used to * avoid traversion the whole tree of active flows looking for ones to * expire. "expires_at" is the time at which the flow should be discarded, * or zero if it is scheduled for immediate disposal. * * When a flow which hasn't been scheduled for immediate expiry registers * traffic, it is deleted from its current position in the tree and * re-inserted (subject to its updated timeout). * * Expiry scans operate by starting at the head of the tree and expiring * each entry with expires_at < now * */ struct EXPIRY { EXPIRY_ENTRY(EXPIRY) trp; /* Tree pointer */ struct FLOW *flow; /* pointer to flow */ u_int32_t expires_at; /* time_t */ enum { R_GENERAL, R_TCP, R_TCP_RST, R_TCP_FIN, R_UDP, R_ICMP, R_MAXLIFE, R_OVERBYTES, R_OVERFLOWS, R_FLUSH } reason; }; /* Prototype for functions shared from softflowd.c */ u_int32_t timeval_sub_ms(const struct timeval *t1, const struct timeval *t2); /* Prototypes for functions to send NetFlow packets, from netflow*.c */ int send_netflow_v1(struct FLOW **flows, int num_flows, int nfsock, u_int16_t ifidx, u_int64_t *flows_exported, struct timeval *system_boot_time, int verbose_flag, struct OPTION *option); int send_netflow_v5(struct FLOW **flows, int num_flows, int nfsock, u_int16_t ifidx, u_int64_t *flows_exported, struct timeval *system_boot_time, int verbose_flag, struct OPTION *option); int send_netflow_v9(struct FLOW **flows, int num_flows, int nfsock, u_int16_t ifidx, u_int64_t *flows_exported, struct timeval *system_boot_time, int verbose_flag, struct OPTION *option); /* Force a resend of the flow template */ void netflow9_resend_template(void); #endif /* _SOFTFLOWD_H */ softflowd-0.9.9/softflowd.init010064400017500001750000000021201171606473600146110ustar00djmdjm#!/bin/bash # # softflowd Starts softflowd NetFlow probe # # chkconfig: 2345 95 02 # description: Starts and stops the softflowd Netflow probe # Source function library. . /etc/init.d/functions SOFTFLOW_CONF=/etc/sysconfig/softflowd SOFTFLOW_LOCK=/var/lock/subsys/softflowd SOFTFLOW_PROG=/usr/sbin/softflowd SOFTFLOW_OPTS="-i eth0" # Source config if [ -f $SOFTFLOW_CONF ]; then . $SOFTFLOW_CONF fi [ -x $SOFTFLOW_PROG ] || exit 0 RETVAL=0 start() { echo -n $"Starting softflowd: " daemon $SOFTFLOW_PROG $SOFTFLOW_OPTS RETVAL=$? echo [ $RETVAL -eq 0 ] && touch $SOFTFLOW_LOCK return $RETVAL } stop() { echo -n $"Shutting down softflowd: " killproc $SOFTFLOW_PROG RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f $SOFTFLOW_LOCK return $RETVAL } restart() { stop start } case "$1" in start) start ;; stop) stop ;; status) status $SOFTFLOW_PROG ;; restart|reload) restart ;; condrestart) [ -f $SOFTFLOW_LOCK ] && restart || : ;; *) echo $"Usage: $0 {start|stop|status|restart|condrestart}" exit 1 esac exit $? softflowd-0.9.9/softflowd.spec010064400017500001750000000030011171606473600145770ustar00djmdjm# Figure out release tag (e.g. rhel3, fc1) based on redhat-release file %global _RHTAG %(sed 's/(.*)//;s/ [A-Z]* //;s/[a-z ]*//g' /etc/redhat-release | tr '[:upper:]' '[:lower:]') Name: softflowd Summary: Network traffic analyser capable of Cisco NetFlow data export Version: 0.9.9 Release: 1.%{_RHTAG} Source: softflowd-%{version}.tar.gz Group: System/Utilities License: BSD BuildRoot: %{_tmppath}/%{name}-root URL: http://www.mindrot.org/softflowd.html Vendor: mindrot.org %description softflowd is a software implementation of a flow-based network traffic monitor. softflowd reads network traffic and gathers information about active traffic flows. A "traffic flow" is communication between two IP addresses or (if the overlying protocol is TCP or UDP) address/port tuples. The intended use of softflowd is as a software implementation of Cisco’s NetFlow traffic account system. softflowd supports data export using versions 1, 5 or 9 of the NetFlow protocol. %prep %setup %build %configure make %install rm -rf $RPM_BUILD_ROOT make install DESTDIR=$RPM_BUILD_ROOT mkdir -p $RPM_BUILD_ROOT/etc/rc.d/init.d mkdir -p $RPM_BUILD_ROOT/etc/sysconfig cp %_sourcedir/softflowd.init $RPM_BUILD_ROOT/etc/rc.d/init.d/softflowd cp %_sourcedir/softflowd.sysconfig $RPM_BUILD_ROOT/etc/sysconfig/softflowd %files %defattr(-,root,root) /usr/sbin/* /usr/share/man/* %attr(0755,root,root) /etc/rc.d/init.d/softflowd %config(noreplace) %attr(0644,root,root) /etc/sysconfig/softflowd %doc ChangeLog README TODO %clean rm -rf $RPM_BUILD_ROOT softflowd-0.9.9/strlcat.c010064400017500001750000000037141171606473600135470ustar00djmdjm/* OPENBSD ORIGINAL: lib/libc/string/strlcat.c */ /* $OpenBSD: strlcat.c,v 1.11 2003/06/17 21:56:24 millert Exp $ */ /* * Copyright (c) 1998 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "common.h" #ifndef HAVE_STRLCAT #if defined(LIBC_SCCS) && !defined(lint) static char *rcsid = "$OpenBSD: strlcat.c,v 1.11 2003/06/17 21:56:24 millert Exp $"; #endif /* LIBC_SCCS and not lint */ #include #include /* * Appends src to string dst of size siz (unlike strncat, siz is the * full size of dst, not space left). At most siz-1 characters * will be copied. Always NUL terminates (unless siz <= strlen(dst)). * Returns strlen(src) + MIN(siz, strlen(initial dst)). * If retval >= siz, truncation occurred. */ size_t strlcat(char *dst, const char *src, size_t siz) { register char *d = dst; register const char *s = src; register size_t n = siz; size_t dlen; /* Find the end of dst and adjust bytes left but don't go past end */ while (n-- != 0 && *d != '\0') d++; dlen = d - dst; n = siz - dlen; if (n == 0) return(dlen + strlen(s)); while (*s != '\0') { if (n != 1) { *d++ = *s; n--; } s++; } *d = '\0'; return(dlen + (s - src)); /* count does not include NUL */ } #endif /* !HAVE_STRLCAT */ softflowd-0.9.9/strlcpy.c010064400017500001750000000035341171606473600135730ustar00djmdjm/* OPENBSD ORIGINAL: lib/libc/string/strlcpy.c */ /* $OpenBSD: strlcpy.c,v 1.8 2003/06/17 21:56:24 millert Exp $ */ /* * Copyright (c) 1998 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "common.h" #ifndef HAVE_STRLCPY #if defined(LIBC_SCCS) && !defined(lint) static char *rcsid = "$OpenBSD: strlcpy.c,v 1.8 2003/06/17 21:56:24 millert Exp $"; #endif /* LIBC_SCCS and not lint */ #include #include /* * Copy src to string dst of size siz. At most siz-1 characters * will be copied. Always NUL terminates (unless siz == 0). * Returns strlen(src); if retval >= siz, truncation occurred. */ size_t strlcpy(char *dst, const char *src, size_t siz) { register char *d = dst; register const char *s = src; register size_t n = siz; /* Copy as many bytes as will fit */ if (n != 0 && --n != 0) { do { if ((*d++ = *s++) == 0) break; } while (--n != 0); } /* Not enough room in dst, add NUL and traverse rest of src */ if (n == 0) { if (siz != 0) *d = '\0'; /* NUL-terminate dst */ while (*s++) ; } return(s - src - 1); /* count does not include NUL */ } #endif /* !HAVE_STRLCPY */ softflowd-0.9.9/sys-tree.h010064400017500001750000000542021171606473600136510ustar00djmdjm/* $OpenBSD: tree.h,v 1.9 2004/11/24 18:10:42 tdeval Exp $ */ /* * Copyright 2002 Niels Provos * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 _SYS_TREE_H_ #define _SYS_TREE_H_ /* * This file defines data structures for different types of trees: * splay trees and red-black trees. * * A splay tree is a self-organizing data structure. Every operation * on the tree causes a splay to happen. The splay moves the requested * node to the root of the tree and partly rebalances it. * * This has the benefit that request locality causes faster lookups as * the requested nodes move to the top of the tree. On the other hand, * every lookup causes memory writes. * * The Balance Theorem bounds the total access time for m operations * and n inserts on an initially empty tree as O((m + n)lg n). The * amortized cost for a sequence of m accesses to a splay tree is O(lg n); * * A red-black tree is a binary search tree with the node color as an * extra attribute. It fulfills a set of conditions: * - every search path from the root to a leaf consists of the * same number of black nodes, * - each red node (except for the root) has a black parent, * - each leaf node is black. * * Every operation on a red-black tree is bounded as O(lg n). * The maximum height of a red-black tree is 2lg (n+1). */ #define SPLAY_HEAD(name, type) \ struct name { \ struct type *sph_root; /* root of the tree */ \ } #define SPLAY_INITIALIZER(root) \ { NULL } #define SPLAY_INIT(root) do { \ (root)->sph_root = NULL; \ } while (0) #define SPLAY_ENTRY(type) \ struct { \ struct type *spe_left; /* left element */ \ struct type *spe_right; /* right element */ \ } #define SPLAY_LEFT(elm, field) (elm)->field.spe_left #define SPLAY_RIGHT(elm, field) (elm)->field.spe_right #define SPLAY_ROOT(head) (head)->sph_root #define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL) /* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */ #define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \ SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \ SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ (head)->sph_root = tmp; \ } while (0) #define SPLAY_ROTATE_LEFT(head, tmp, field) do { \ SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \ SPLAY_LEFT(tmp, field) = (head)->sph_root; \ (head)->sph_root = tmp; \ } while (0) #define SPLAY_LINKLEFT(head, tmp, field) do { \ SPLAY_LEFT(tmp, field) = (head)->sph_root; \ tmp = (head)->sph_root; \ (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \ } while (0) #define SPLAY_LINKRIGHT(head, tmp, field) do { \ SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ tmp = (head)->sph_root; \ (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \ } while (0) #define SPLAY_ASSEMBLE(head, node, left, right, field) do { \ SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \ SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\ SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \ SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \ } while (0) /* Generates prototypes and inline functions */ #define SPLAY_PROTOTYPE(name, type, field, cmp) \ void name##_SPLAY(struct name *, struct type *); \ void name##_SPLAY_MINMAX(struct name *, int); \ struct type *name##_SPLAY_INSERT(struct name *, struct type *); \ struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \ \ /* Finds the node with the same key as elm */ \ static __inline struct type * \ name##_SPLAY_FIND(struct name *head, struct type *elm) \ { \ if (SPLAY_EMPTY(head)) \ return(NULL); \ name##_SPLAY(head, elm); \ if ((cmp)(elm, (head)->sph_root) == 0) \ return (head->sph_root); \ return (NULL); \ } \ \ static __inline struct type * \ name##_SPLAY_NEXT(struct name *head, struct type *elm) \ { \ name##_SPLAY(head, elm); \ if (SPLAY_RIGHT(elm, field) != NULL) { \ elm = SPLAY_RIGHT(elm, field); \ while (SPLAY_LEFT(elm, field) != NULL) { \ elm = SPLAY_LEFT(elm, field); \ } \ } else \ elm = NULL; \ return (elm); \ } \ \ static __inline struct type * \ name##_SPLAY_MIN_MAX(struct name *head, int val) \ { \ name##_SPLAY_MINMAX(head, val); \ return (SPLAY_ROOT(head)); \ } /* Main splay operation. * Moves node close to the key of elm to top */ #define SPLAY_GENERATE(name, type, field, cmp) \ struct type * \ name##_SPLAY_INSERT(struct name *head, struct type *elm) \ { \ if (SPLAY_EMPTY(head)) { \ SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \ } else { \ int __comp; \ name##_SPLAY(head, elm); \ __comp = (cmp)(elm, (head)->sph_root); \ if(__comp < 0) { \ SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\ SPLAY_RIGHT(elm, field) = (head)->sph_root; \ SPLAY_LEFT((head)->sph_root, field) = NULL; \ } else if (__comp > 0) { \ SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\ SPLAY_LEFT(elm, field) = (head)->sph_root; \ SPLAY_RIGHT((head)->sph_root, field) = NULL; \ } else \ return ((head)->sph_root); \ } \ (head)->sph_root = (elm); \ return (NULL); \ } \ \ struct type * \ name##_SPLAY_REMOVE(struct name *head, struct type *elm) \ { \ struct type *__tmp; \ if (SPLAY_EMPTY(head)) \ return (NULL); \ name##_SPLAY(head, elm); \ if ((cmp)(elm, (head)->sph_root) == 0) { \ if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \ (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\ } else { \ __tmp = SPLAY_RIGHT((head)->sph_root, field); \ (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\ name##_SPLAY(head, elm); \ SPLAY_RIGHT((head)->sph_root, field) = __tmp; \ } \ return (elm); \ } \ return (NULL); \ } \ \ void \ name##_SPLAY(struct name *head, struct type *elm) \ { \ struct type __node, *__left, *__right, *__tmp; \ int __comp; \ \ SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ __left = __right = &__node; \ \ while ((__comp = (cmp)(elm, (head)->sph_root))) { \ if (__comp < 0) { \ __tmp = SPLAY_LEFT((head)->sph_root, field); \ if (__tmp == NULL) \ break; \ if ((cmp)(elm, __tmp) < 0){ \ SPLAY_ROTATE_RIGHT(head, __tmp, field); \ if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ break; \ } \ SPLAY_LINKLEFT(head, __right, field); \ } else if (__comp > 0) { \ __tmp = SPLAY_RIGHT((head)->sph_root, field); \ if (__tmp == NULL) \ break; \ if ((cmp)(elm, __tmp) > 0){ \ SPLAY_ROTATE_LEFT(head, __tmp, field); \ if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ break; \ } \ SPLAY_LINKRIGHT(head, __left, field); \ } \ } \ SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ } \ \ /* Splay with either the minimum or the maximum element \ * Used to find minimum or maximum element in tree. \ */ \ void name##_SPLAY_MINMAX(struct name *head, int __comp) \ { \ struct type __node, *__left, *__right, *__tmp; \ \ SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ __left = __right = &__node; \ \ while (1) { \ if (__comp < 0) { \ __tmp = SPLAY_LEFT((head)->sph_root, field); \ if (__tmp == NULL) \ break; \ if (__comp < 0){ \ SPLAY_ROTATE_RIGHT(head, __tmp, field); \ if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ break; \ } \ SPLAY_LINKLEFT(head, __right, field); \ } else if (__comp > 0) { \ __tmp = SPLAY_RIGHT((head)->sph_root, field); \ if (__tmp == NULL) \ break; \ if (__comp > 0) { \ SPLAY_ROTATE_LEFT(head, __tmp, field); \ if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ break; \ } \ SPLAY_LINKRIGHT(head, __left, field); \ } \ } \ SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ } #define SPLAY_NEGINF -1 #define SPLAY_INF 1 #define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y) #define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y) #define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y) #define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y) #define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \ : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF)) #define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \ : name##_SPLAY_MIN_MAX(x, SPLAY_INF)) #define SPLAY_FOREACH(x, name, head) \ for ((x) = SPLAY_MIN(name, head); \ (x) != NULL; \ (x) = SPLAY_NEXT(name, head, x)) /* Macros that define a red-black tree */ #define RB_HEAD(name, type) \ struct name { \ struct type *rbh_root; /* root of the tree */ \ } #define RB_INITIALIZER(root) \ { NULL } #define RB_INIT(root) do { \ (root)->rbh_root = NULL; \ } while (0) #define RB_BLACK 0 #define RB_RED 1 #define RB_ENTRY(type) \ struct { \ struct type *rbe_left; /* left element */ \ struct type *rbe_right; /* right element */ \ struct type *rbe_parent; /* parent element */ \ int rbe_color; /* node color */ \ } #define RB_LEFT(elm, field) (elm)->field.rbe_left #define RB_RIGHT(elm, field) (elm)->field.rbe_right #define RB_PARENT(elm, field) (elm)->field.rbe_parent #define RB_COLOR(elm, field) (elm)->field.rbe_color #define RB_ROOT(head) (head)->rbh_root #define RB_EMPTY(head) (RB_ROOT(head) == NULL) #define RB_SET(elm, parent, field) do { \ RB_PARENT(elm, field) = parent; \ RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \ RB_COLOR(elm, field) = RB_RED; \ } while (0) #define RB_SET_BLACKRED(black, red, field) do { \ RB_COLOR(black, field) = RB_BLACK; \ RB_COLOR(red, field) = RB_RED; \ } while (0) #ifndef RB_AUGMENT #define RB_AUGMENT(x) #endif #define RB_ROTATE_LEFT(head, elm, tmp, field) do { \ (tmp) = RB_RIGHT(elm, field); \ if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) { \ RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \ } \ RB_AUGMENT(elm); \ if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \ if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ else \ RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ } else \ (head)->rbh_root = (tmp); \ RB_LEFT(tmp, field) = (elm); \ RB_PARENT(elm, field) = (tmp); \ RB_AUGMENT(tmp); \ if ((RB_PARENT(tmp, field))) \ RB_AUGMENT(RB_PARENT(tmp, field)); \ } while (0) #define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \ (tmp) = RB_LEFT(elm, field); \ if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) { \ RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \ } \ RB_AUGMENT(elm); \ if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \ if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ else \ RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ } else \ (head)->rbh_root = (tmp); \ RB_RIGHT(tmp, field) = (elm); \ RB_PARENT(elm, field) = (tmp); \ RB_AUGMENT(tmp); \ if ((RB_PARENT(tmp, field))) \ RB_AUGMENT(RB_PARENT(tmp, field)); \ } while (0) /* Generates prototypes and inline functions */ #define RB_PROTOTYPE(name, type, field, cmp) \ void name##_RB_INSERT_COLOR(struct name *, struct type *); \ void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\ struct type *name##_RB_REMOVE(struct name *, struct type *); \ struct type *name##_RB_INSERT(struct name *, struct type *); \ struct type *name##_RB_FIND(struct name *, struct type *); \ struct type *name##_RB_NEXT(struct type *); \ struct type *name##_RB_MINMAX(struct name *, int); \ \ /* Main rb operation. * Moves node close to the key of elm to top */ #define RB_GENERATE(name, type, field, cmp) \ void \ name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \ { \ struct type *parent, *gparent, *tmp; \ while ((parent = RB_PARENT(elm, field)) && \ RB_COLOR(parent, field) == RB_RED) { \ gparent = RB_PARENT(parent, field); \ if (parent == RB_LEFT(gparent, field)) { \ tmp = RB_RIGHT(gparent, field); \ if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ RB_COLOR(tmp, field) = RB_BLACK; \ RB_SET_BLACKRED(parent, gparent, field);\ elm = gparent; \ continue; \ } \ if (RB_RIGHT(parent, field) == elm) { \ RB_ROTATE_LEFT(head, parent, tmp, field);\ tmp = parent; \ parent = elm; \ elm = tmp; \ } \ RB_SET_BLACKRED(parent, gparent, field); \ RB_ROTATE_RIGHT(head, gparent, tmp, field); \ } else { \ tmp = RB_LEFT(gparent, field); \ if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ RB_COLOR(tmp, field) = RB_BLACK; \ RB_SET_BLACKRED(parent, gparent, field);\ elm = gparent; \ continue; \ } \ if (RB_LEFT(parent, field) == elm) { \ RB_ROTATE_RIGHT(head, parent, tmp, field);\ tmp = parent; \ parent = elm; \ elm = tmp; \ } \ RB_SET_BLACKRED(parent, gparent, field); \ RB_ROTATE_LEFT(head, gparent, tmp, field); \ } \ } \ RB_COLOR(head->rbh_root, field) = RB_BLACK; \ } \ \ void \ name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \ { \ struct type *tmp; \ while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \ elm != RB_ROOT(head)) { \ if (RB_LEFT(parent, field) == elm) { \ tmp = RB_RIGHT(parent, field); \ if (RB_COLOR(tmp, field) == RB_RED) { \ RB_SET_BLACKRED(tmp, parent, field); \ RB_ROTATE_LEFT(head, parent, tmp, field);\ tmp = RB_RIGHT(parent, field); \ } \ if ((RB_LEFT(tmp, field) == NULL || \ RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ (RB_RIGHT(tmp, field) == NULL || \ RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ RB_COLOR(tmp, field) = RB_RED; \ elm = parent; \ parent = RB_PARENT(elm, field); \ } else { \ if (RB_RIGHT(tmp, field) == NULL || \ RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\ struct type *oleft; \ if ((oleft = RB_LEFT(tmp, field)))\ RB_COLOR(oleft, field) = RB_BLACK;\ RB_COLOR(tmp, field) = RB_RED; \ RB_ROTATE_RIGHT(head, tmp, oleft, field);\ tmp = RB_RIGHT(parent, field); \ } \ RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ RB_COLOR(parent, field) = RB_BLACK; \ if (RB_RIGHT(tmp, field)) \ RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\ RB_ROTATE_LEFT(head, parent, tmp, field);\ elm = RB_ROOT(head); \ break; \ } \ } else { \ tmp = RB_LEFT(parent, field); \ if (RB_COLOR(tmp, field) == RB_RED) { \ RB_SET_BLACKRED(tmp, parent, field); \ RB_ROTATE_RIGHT(head, parent, tmp, field);\ tmp = RB_LEFT(parent, field); \ } \ if ((RB_LEFT(tmp, field) == NULL || \ RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ (RB_RIGHT(tmp, field) == NULL || \ RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ RB_COLOR(tmp, field) = RB_RED; \ elm = parent; \ parent = RB_PARENT(elm, field); \ } else { \ if (RB_LEFT(tmp, field) == NULL || \ RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\ struct type *oright; \ if ((oright = RB_RIGHT(tmp, field)))\ RB_COLOR(oright, field) = RB_BLACK;\ RB_COLOR(tmp, field) = RB_RED; \ RB_ROTATE_LEFT(head, tmp, oright, field);\ tmp = RB_LEFT(parent, field); \ } \ RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ RB_COLOR(parent, field) = RB_BLACK; \ if (RB_LEFT(tmp, field)) \ RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\ RB_ROTATE_RIGHT(head, parent, tmp, field);\ elm = RB_ROOT(head); \ break; \ } \ } \ } \ if (elm) \ RB_COLOR(elm, field) = RB_BLACK; \ } \ \ struct type * \ name##_RB_REMOVE(struct name *head, struct type *elm) \ { \ struct type *child, *parent, *old = elm; \ int color; \ if (RB_LEFT(elm, field) == NULL) \ child = RB_RIGHT(elm, field); \ else if (RB_RIGHT(elm, field) == NULL) \ child = RB_LEFT(elm, field); \ else { \ struct type *left; \ elm = RB_RIGHT(elm, field); \ while ((left = RB_LEFT(elm, field))) \ elm = left; \ child = RB_RIGHT(elm, field); \ parent = RB_PARENT(elm, field); \ color = RB_COLOR(elm, field); \ if (child) \ RB_PARENT(child, field) = parent; \ if (parent) { \ if (RB_LEFT(parent, field) == elm) \ RB_LEFT(parent, field) = child; \ else \ RB_RIGHT(parent, field) = child; \ RB_AUGMENT(parent); \ } else \ RB_ROOT(head) = child; \ if (RB_PARENT(elm, field) == old) \ parent = elm; \ (elm)->field = (old)->field; \ if (RB_PARENT(old, field)) { \ if (RB_LEFT(RB_PARENT(old, field), field) == old)\ RB_LEFT(RB_PARENT(old, field), field) = elm;\ else \ RB_RIGHT(RB_PARENT(old, field), field) = elm;\ RB_AUGMENT(RB_PARENT(old, field)); \ } else \ RB_ROOT(head) = elm; \ RB_PARENT(RB_LEFT(old, field), field) = elm; \ if (RB_RIGHT(old, field)) \ RB_PARENT(RB_RIGHT(old, field), field) = elm; \ if (parent) { \ left = parent; \ do { \ RB_AUGMENT(left); \ } while ((left = RB_PARENT(left, field))); \ } \ goto color; \ } \ parent = RB_PARENT(elm, field); \ color = RB_COLOR(elm, field); \ if (child) \ RB_PARENT(child, field) = parent; \ if (parent) { \ if (RB_LEFT(parent, field) == elm) \ RB_LEFT(parent, field) = child; \ else \ RB_RIGHT(parent, field) = child; \ RB_AUGMENT(parent); \ } else \ RB_ROOT(head) = child; \ color: \ if (color == RB_BLACK) \ name##_RB_REMOVE_COLOR(head, parent, child); \ return (old); \ } \ \ /* Inserts a node into the RB tree */ \ struct type * \ name##_RB_INSERT(struct name *head, struct type *elm) \ { \ struct type *tmp; \ struct type *parent = NULL; \ int comp = 0; \ tmp = RB_ROOT(head); \ while (tmp) { \ parent = tmp; \ comp = (cmp)(elm, parent); \ if (comp < 0) \ tmp = RB_LEFT(tmp, field); \ else if (comp > 0) \ tmp = RB_RIGHT(tmp, field); \ else \ return (tmp); \ } \ RB_SET(elm, parent, field); \ if (parent != NULL) { \ if (comp < 0) \ RB_LEFT(parent, field) = elm; \ else \ RB_RIGHT(parent, field) = elm; \ RB_AUGMENT(parent); \ } else \ RB_ROOT(head) = elm; \ name##_RB_INSERT_COLOR(head, elm); \ return (NULL); \ } \ \ /* Finds the node with the same key as elm */ \ struct type * \ name##_RB_FIND(struct name *head, struct type *elm) \ { \ struct type *tmp = RB_ROOT(head); \ int comp; \ while (tmp) { \ comp = cmp(elm, tmp); \ if (comp < 0) \ tmp = RB_LEFT(tmp, field); \ else if (comp > 0) \ tmp = RB_RIGHT(tmp, field); \ else \ return (tmp); \ } \ return (NULL); \ } \ \ struct type * \ name##_RB_NEXT(struct type *elm) \ { \ if (RB_RIGHT(elm, field)) { \ elm = RB_RIGHT(elm, field); \ while (RB_LEFT(elm, field)) \ elm = RB_LEFT(elm, field); \ } else { \ if (RB_PARENT(elm, field) && \ (elm == RB_LEFT(RB_PARENT(elm, field), field))) \ elm = RB_PARENT(elm, field); \ else { \ while (RB_PARENT(elm, field) && \ (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\ elm = RB_PARENT(elm, field); \ elm = RB_PARENT(elm, field); \ } \ } \ return (elm); \ } \ \ struct type * \ name##_RB_MINMAX(struct name *head, int val) \ { \ struct type *tmp = RB_ROOT(head); \ struct type *parent = NULL; \ while (tmp) { \ parent = tmp; \ if (val < 0) \ tmp = RB_LEFT(tmp, field); \ else \ tmp = RB_RIGHT(tmp, field); \ } \ return (parent); \ } #define RB_NEGINF -1 #define RB_INF 1 #define RB_INSERT(name, x, y) name##_RB_INSERT(x, y) #define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) #define RB_FIND(name, x, y) name##_RB_FIND(x, y) #define RB_NEXT(name, x, y) name##_RB_NEXT(y) #define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) #define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) #define RB_FOREACH(x, name, head) \ for ((x) = RB_MIN(name, head); \ (x) != NULL; \ (x) = name##_RB_NEXT(x)) #endif /* _SYS_TREE_H_ */ softflowd-0.9.9/treetype.h010064400017500001750000000056251171606473600137440ustar00djmdjm/* * Copyright 2002 Damien Miller 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. */ /* Select our tree types for various data structures */ #if defined(FLOW_RB) #define FLOW_HEAD RB_HEAD #define FLOW_ENTRY RB_ENTRY #define FLOW_PROTOTYPE RB_PROTOTYPE #define FLOW_GENERATE RB_GENERATE #define FLOW_INSERT RB_INSERT #define FLOW_FIND RB_FIND #define FLOW_REMOVE RB_REMOVE #define FLOW_FOREACH RB_FOREACH #define FLOW_MIN RB_MIN #define FLOW_NEXT RB_NEXT #define FLOW_INIT RB_INIT #elif defined(FLOW_SPLAY) #define FLOW_HEAD SPLAY_HEAD #define FLOW_ENTRY SPLAY_ENTRY #define FLOW_PROTOTYPE SPLAY_PROTOTYPE #define FLOW_GENERATE SPLAY_GENERATE #define FLOW_INSERT SPLAY_INSERT #define FLOW_FIND SPLAY_FIND #define FLOW_REMOVE SPLAY_REMOVE #define FLOW_FOREACH SPLAY_FOREACH #define FLOW_MIN SPLAY_MIN #define FLOW_NEXT SPLAY_NEXT #define FLOW_INIT SPLAY_INIT #else #error No flow tree type defined #endif #if defined(EXPIRY_RB) #define EXPIRY_HEAD RB_HEAD #define EXPIRY_ENTRY RB_ENTRY #define EXPIRY_PROTOTYPE RB_PROTOTYPE #define EXPIRY_GENERATE RB_GENERATE #define EXPIRY_INSERT RB_INSERT #define EXPIRY_FIND RB_FIND #define EXPIRY_REMOVE RB_REMOVE #define EXPIRY_FOREACH RB_FOREACH #define EXPIRY_MIN RB_MIN #define EXPIRY_NEXT RB_NEXT #define EXPIRY_INIT RB_INIT #elif defined(EXPIRY_SPLAY) #define EXPIRY_HEAD SPLAY_HEAD #define EXPIRY_ENTRY SPLAY_ENTRY #define EXPIRY_PROTOTYPE SPLAY_PROTOTYPE #define EXPIRY_GENERATE SPLAY_GENERATE #define EXPIRY_INSERT SPLAY_INSERT #define EXPIRY_FIND SPLAY_FIND #define EXPIRY_REMOVE SPLAY_REMOVE #define EXPIRY_FOREACH SPLAY_FOREACH #define EXPIRY_MIN SPLAY_MIN #define EXPIRY_NEXT SPLAY_NEXT #define EXPIRY_INIT SPLAY_INIT #else #error No expiry tree type defined #endif softflowd-0.9.9/configure010075500017500001750000004757111171606502600136410ustar00djmdjm#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.68. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software # Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= PACKAGE_URL= ac_unique_file="softflowd.c" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='LTLIBOBJS LIBOBJS EGREP GREP CPP INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_gcc_warnings with_cflags with_cppflags with_ldflags with_libs with_chrootdir ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= 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=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -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_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$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 ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$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 | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$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 ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) 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 | -n) 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 ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$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_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=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 ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # 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 the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` 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 test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # 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 <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-gcc-warnings Enable verbose warnings (only for gcc) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-cflags Specify additional compiler flags --with-cppflags Specify additional preprocessor flags --with-ldflags Specify additional linker flags --with-libs Specify additional libraries to link with --with-chrootdir Specify chroot directory Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES # ---------------------------------------------------- # Tries to find if the field MEMBER exists in type AGGR, after including # INCLUDES, setting cache variable VAR accordingly. ac_fn_c_check_member () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 $as_echo_n "checking for $2.$3... " >&6; } if eval \${$4+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$4=yes" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (sizeof ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$4=yes" else eval "$4=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$4 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_member # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* 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_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES # -------------------------------------------- # Tries to find the compile-time value of EXPR in a program that includes # INCLUDES, setting VAR accordingly. Returns whether the value could be # computed ac_fn_c_compute_int () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= 0)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=0 ac_mid=0 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid; break else as_fn_arith $ac_mid + 1 && ac_lo=$as_val if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) < 0)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=-1 ac_mid=-1 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=$ac_mid; break else as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid else as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in #(( ?*) eval "$3=\$ac_lo"; ac_retval=0 ;; '') ac_retval=1 ;; esac else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 static long int longval () { return $2; } static unsigned long int ulongval () { return $2; } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (($2) < 0) { long int i = longval (); if (i != ($2)) return 1; fprintf (f, "%ld", i); } else { unsigned long int i = ulongval (); if (i != ($2)) return 1; fprintf (f, "%lu", i); } /* Do not output a trailing newline, as this causes \r\n confusion on some platforms. */ return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : echo >>conftest.val; read $3 config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_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 $# != 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 ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu 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 elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # 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 # AmigaOS /C/install, which installs bootblocks on floppy discs # 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" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /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 for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir 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. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&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}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' # Optional verbose warnings for gcc, see below WFLAGS="-Wall -Waggregate-return -Wcast-align -Wcast-qual" WFLAGS="$WFLAGS -Wmissing-declarations -Wmissing-prototypes" WFLAGS="$WFLAGS -Wno-conversion -Wpointer-arith -Wshadow" WFLAGS="$WFLAGS -Wuninitialized -Wcast-align -Wcast-qual" WFLAGS="$WFLAGS -Wformat=2 -Wformat-nonliteral -Wwrite-strings" # Process flag arguments early, so they are available for tests later # Check whether --enable-gcc-warnings was given. if test "${enable_gcc_warnings+set}" = set; then : enableval=$enable_gcc_warnings; if test "x$enableval" = "xyes" ; then CFLAGS="$CFLAGS $WFLAGS"; fi fi # Check whether --with-cflags was given. if test "${with_cflags+set}" = set; then : withval=$with_cflags; if test "x$withval" != "xno" ; then CFLAGS="$CFLAGS $withval"; fi fi # Check whether --with-cppflags was given. if test "${with_cppflags+set}" = set; then : withval=$with_cppflags; if test "x$withval" != "xno"; then CPPFLAGS="$CPPFLAGS $withval"; fi fi # Check whether --with-ldflags was given. if test "${with_ldflags+set}" = set; then : withval=$with_ldflags; if test "x$withval" != "xno" ; then LDFLAGS="$LDFLAGS $withval"; fi fi # Check whether --with-libs was given. if test "${with_libs+set}" = set; then : withval=$with_libs; if test "x$withval" != "xno" ; then LIBS="$LIBS $withval"; fi fi # Check whether --with-chrootdir was given. if test "${with_chrootdir+set}" = set; then : withval=$with_chrootdir; cat >>confdefs.h <<_ACEOF #define PRIVDROP_CHROOT_DIR "${withval}" _ACEOF fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in net/bpf.h pcap.h pcap-bpf.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_member "$LINENO" "struct sockaddr" "sa_len" "ac_cv_member_struct_sockaddr_sa_len" "#include #include " if test "x$ac_cv_member_struct_sockaddr_sa_len" = xyes; then : $as_echo "#define SOCK_HAS_LEN 1" >>confdefs.h fi ac_fn_c_check_member "$LINENO" "struct ip6_ext" "ip6e_nxt" "ac_cv_member_struct_ip6_ext_ip6e_nxt" " #include #include #include #include " if test "x$ac_cv_member_struct_ip6_ext_ip6e_nxt" = xyes; then : $as_echo "#define HAVE_STRUCT_IP6_EXT 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing daemon" >&5 $as_echo_n "checking for library containing daemon... " >&6; } if ${ac_cv_search_daemon+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char daemon (); int main () { return daemon (); ; return 0; } _ACEOF for ac_lib in '' bsd; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_daemon=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_daemon+:} false; then : break fi done if ${ac_cv_search_daemon+:} false; then : else ac_cv_search_daemon=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_daemon" >&5 $as_echo "$ac_cv_search_daemon" >&6; } ac_res=$ac_cv_search_daemon if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethostbyname" >&5 $as_echo_n "checking for library containing gethostbyname... " >&6; } if ${ac_cv_search_gethostbyname+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostbyname (); int main () { return gethostbyname (); ; return 0; } _ACEOF for ac_lib in '' nsl; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_gethostbyname=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_gethostbyname+:} false; then : break fi done if ${ac_cv_search_gethostbyname+:} false; then : else ac_cv_search_gethostbyname=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_gethostbyname" >&5 $as_echo "$ac_cv_search_gethostbyname" >&6; } ac_res=$ac_cv_search_gethostbyname if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing socket" >&5 $as_echo_n "checking for library containing socket... " >&6; } if ${ac_cv_search_socket+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char socket (); int main () { return socket (); ; return 0; } _ACEOF for ac_lib in '' socket; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_socket=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_socket+:} false; then : break fi done if ${ac_cv_search_socket+:} false; then : else ac_cv_search_socket=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_socket" >&5 $as_echo "$ac_cv_search_socket" >&6; } ac_res=$ac_cv_search_socket if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pcap_open_live in -lpcap" >&5 $as_echo_n "checking for pcap_open_live in -lpcap... " >&6; } if ${ac_cv_lib_pcap_pcap_open_live+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpcap $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pcap_open_live (); int main () { return pcap_open_live (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pcap_pcap_open_live=yes else ac_cv_lib_pcap_pcap_open_live=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pcap_pcap_open_live" >&5 $as_echo "$ac_cv_lib_pcap_pcap_open_live" >&6; } if test "x$ac_cv_lib_pcap_pcap_open_live" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPCAP 1 _ACEOF LIBS="-lpcap $LIBS" fi for ac_func in closefrom daemon setresuid setreuid setresgid setgid strlcpy strlcat do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_type "$LINENO" "u_int64_t" "ac_cv_type_u_int64_t" "$ac_includes_default" if test "x$ac_cv_type_u_int64_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_U_INT64_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "int64_t" "ac_cv_type_int64_t" "$ac_includes_default" if test "x$ac_cv_type_int64_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_INT64_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "uint64_t" "ac_cv_type_uint64_t" "$ac_includes_default" if test "x$ac_cv_type_uint64_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UINT64_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "u_int32_t" "ac_cv_type_u_int32_t" "$ac_includes_default" if test "x$ac_cv_type_u_int32_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_U_INT32_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "int32_t" "ac_cv_type_int32_t" "$ac_includes_default" if test "x$ac_cv_type_int32_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_INT32_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "uint32_t" "ac_cv_type_uint32_t" "$ac_includes_default" if test "x$ac_cv_type_uint32_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UINT32_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "u_int16_t" "ac_cv_type_u_int16_t" "$ac_includes_default" if test "x$ac_cv_type_u_int16_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_U_INT16_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "int16_t" "ac_cv_type_int16_t" "$ac_includes_default" if test "x$ac_cv_type_int16_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_INT16_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "uint16_t" "ac_cv_type_uint16_t" "$ac_includes_default" if test "x$ac_cv_type_uint16_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UINT16_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "u_int8_t" "ac_cv_type_u_int8_t" "$ac_includes_default" if test "x$ac_cv_type_u_int8_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_U_INT8_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "int8_t" "ac_cv_type_int8_t" "$ac_includes_default" if test "x$ac_cv_type_int8_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_INT8_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "uint8_t" "ac_cv_type_uint8_t" "$ac_includes_default" if test "x$ac_cv_type_uint8_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UINT8_T 1 _ACEOF fi # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char" >&5 $as_echo_n "checking size of char... " >&6; } if ${ac_cv_sizeof_char+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char))" "ac_cv_sizeof_char" "$ac_includes_default"; then : else if test "$ac_cv_type_char" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (char) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_char=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_char" >&5 $as_echo "$ac_cv_sizeof_char" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_CHAR $ac_cv_sizeof_char _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short int" >&5 $as_echo_n "checking size of short int... " >&6; } if ${ac_cv_sizeof_short_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short int))" "ac_cv_sizeof_short_int" "$ac_includes_default"; then : else if test "$ac_cv_type_short_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (short int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_short_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short_int" >&5 $as_echo "$ac_cv_sizeof_short_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_SHORT_INT $ac_cv_sizeof_short_int _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 $as_echo_n "checking size of int... " >&6; } if ${ac_cv_sizeof_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then : else if test "$ac_cv_type_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 $as_echo "$ac_cv_sizeof_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_INT $ac_cv_sizeof_int _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long int" >&5 $as_echo_n "checking size of long int... " >&6; } if ${ac_cv_sizeof_long_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long int))" "ac_cv_sizeof_long_int" "$ac_includes_default"; then : else if test "$ac_cv_type_long_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_long_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_int" >&5 $as_echo "$ac_cv_sizeof_long_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG_INT $ac_cv_sizeof_long_int _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long int" >&5 $as_echo_n "checking size of long long int... " >&6; } if ${ac_cv_sizeof_long_long_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long int))" "ac_cv_sizeof_long_long_int" "$ac_includes_default"; then : else if test "$ac_cv_type_long_long_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long long int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_long_long_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long_int" >&5 $as_echo "$ac_cv_sizeof_long_long_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG_LONG_INT $ac_cv_sizeof_long_long_int _ACEOF if test "x$ac_cv_type_uint8_t" = "xyes" ; then $as_echo "#define OUR_CFG_U_INT8_T uint8_t" >>confdefs.h elif test "x$ac_cv_sizeof_char" = "x1" ; then $as_echo "#define OUR_CFG_U_INT8_T unsigned char" >>confdefs.h else as_fn_error $? "No 8-bit unsigned int type found" "$LINENO" 5 fi if test "x$ac_cv_sizeof_char" = "x1" ; then $as_echo "#define OUR_CFG_INT8_T signed char" >>confdefs.h else as_fn_error $? "No 8-bit signed int type found" "$LINENO" 5 fi if test "x$ac_cv_type_uint16_t" = "xyes" ; then $as_echo "#define OUR_CFG_U_INT16_T uint16_t" >>confdefs.h elif test "x$ac_cv_sizeof_short_int" = "x2" ; then $as_echo "#define OUR_CFG_U_INT16_T unsigned short int" >>confdefs.h else as_fn_error $? "No 16-bit unsigned int type found" "$LINENO" 5 fi if test "x$ac_cv_sizeof_short_int" = "x2" ; then $as_echo "#define OUR_CFG_INT16_T short int" >>confdefs.h else as_fn_error $? "No 16-bit signed int type found" "$LINENO" 5 fi if test "x$ac_cv_type_uint32_t" = "xyes" ; then $as_echo "#define OUR_CFG_U_INT32_T uint32_t" >>confdefs.h elif test "x$ac_cv_sizeof_int" = "x4" ; then $as_echo "#define OUR_CFG_U_INT32_T unsigned int" >>confdefs.h else as_fn_error $? "No 32-bit unsigned int type found" "$LINENO" 5 fi if test "x$ac_cv_sizeof_int" = "x4" ; then $as_echo "#define OUR_CFG_INT32_T int" >>confdefs.h else as_fn_error $? "No 32-bit signed int type found" "$LINENO" 5 fi if test "x$ac_cv_type_uint64_t" = "xyes" ; then $as_echo "#define OUR_CFG_U_INT64_T uint64_t" >>confdefs.h elif test "x$ac_cv_sizeof_long_int" = "x8" ; then $as_echo "#define OUR_CFG_U_INT64_T unsigned long int" >>confdefs.h elif test "x$ac_cv_sizeof_long_long_int" = "x8" ; then $as_echo "#define OUR_CFG_U_INT64_T unsigned long long int" >>confdefs.h else as_fn_error $? "No 64-bit unsigned int type found" "$LINENO" 5 fi if test "x$ac_cv_sizeof_long_int" = "x8" ; then $as_echo "#define OUR_CFG_INT64_T long int" >>confdefs.h elif test "x$ac_cv_sizeof_long_long_int" = "x8" ; then $as_echo "#define OUR_CFG_INT64_T long long int" >>confdefs.h else as_fn_error $? "No 64-bit signed int type found" "$LINENO" 5 fi if test "x$ac_cv_header_pcap_bpf_h" != "xyes" && \ test "x$ac_cv_header_net_bpf_h" != "xyes" ; then as_fn_error $? "No BPF header found" "$LINENO" 5 fi if test "x$ac_cv_header_pcap_h" != "xyes" ; then as_fn_error $? "No pcap.h header found" "$LINENO" 5 fi if test "x$ac_cv_lib_pcap_pcap_open_live" != "xyes" ; then as_fn_error $? "libpcap not found" "$LINENO" 5 fi ac_config_files="$ac_config_files Makefile" cat >confcache <<\_ACEOF # 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, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # 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. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by $as_me, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" Copyright (C) 2010 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi softflowd-0.9.9/config.h.in010064400017500001750000000101301171606502700137320ustar00djmdjm/* config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have the `closefrom' function. */ #undef HAVE_CLOSEFROM /* Define to 1 if you have the `daemon' function. */ #undef HAVE_DAEMON /* Define to 1 if the system has the type `int16_t'. */ #undef HAVE_INT16_T /* Define to 1 if the system has the type `int32_t'. */ #undef HAVE_INT32_T /* Define to 1 if the system has the type `int64_t'. */ #undef HAVE_INT64_T /* Define to 1 if the system has the type `int8_t'. */ #undef HAVE_INT8_T /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `pcap' library (-lpcap). */ #undef HAVE_LIBPCAP /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the header file. */ #undef HAVE_NET_BPF_H /* Define to 1 if you have the header file. */ #undef HAVE_PCAP_BPF_H /* Define to 1 if you have the header file. */ #undef HAVE_PCAP_H /* Define to 1 if you have the `setgid' function. */ #undef HAVE_SETGID /* Define to 1 if you have the `setresgid' function. */ #undef HAVE_SETRESGID /* Define to 1 if you have the `setresuid' function. */ #undef HAVE_SETRESUID /* Define to 1 if you have the `setreuid' function. */ #undef HAVE_SETREUID /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strlcat' function. */ #undef HAVE_STRLCAT /* Define to 1 if you have the `strlcpy' function. */ #undef HAVE_STRLCPY /* struct ip6_ext.ip6e_nxt exists */ #undef HAVE_STRUCT_IP6_EXT /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if the system has the type `uint16_t'. */ #undef HAVE_UINT16_T /* Define to 1 if the system has the type `uint32_t'. */ #undef HAVE_UINT32_T /* Define to 1 if the system has the type `uint64_t'. */ #undef HAVE_UINT64_T /* Define to 1 if the system has the type `uint8_t'. */ #undef HAVE_UINT8_T /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if the system has the type `u_int16_t'. */ #undef HAVE_U_INT16_T /* Define to 1 if the system has the type `u_int32_t'. */ #undef HAVE_U_INT32_T /* Define to 1 if the system has the type `u_int64_t'. */ #undef HAVE_U_INT64_T /* Define to 1 if the system has the type `u_int8_t'. */ #undef HAVE_U_INT8_T /* 16-bit signed int */ #undef OUR_CFG_INT16_T /* 32-bit signed int */ #undef OUR_CFG_INT32_T /* 64-bit signed int */ #undef OUR_CFG_INT64_T /* 8-bit signed int */ #undef OUR_CFG_INT8_T /* 16-bit unsigned int */ #undef OUR_CFG_U_INT16_T /* 32-bit unsigned int */ #undef OUR_CFG_U_INT32_T /* 64-bit unsigned int */ #undef OUR_CFG_U_INT64_T /* 8-bit unsigned int */ #undef OUR_CFG_U_INT8_T /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* privdrop chroot directory */ #undef PRIVDROP_CHROOT_DIR /* The size of `char', as computed by sizeof. */ #undef SIZEOF_CHAR /* The size of `int', as computed by sizeof. */ #undef SIZEOF_INT /* The size of `long int', as computed by sizeof. */ #undef SIZEOF_LONG_INT /* The size of `long long int', as computed by sizeof. */ #undef SIZEOF_LONG_LONG_INT /* The size of `short int', as computed by sizeof. */ #undef SIZEOF_SHORT_INT /* struct sockaddr contains length */ #undef SOCK_HAS_LEN /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS