dnl
dnl $Id: configure.in,v 1.36 2006/11/15 03:43:56 jpr5 Exp $
dnl
dnl Copyright (c) 2001  Jordan Ritter <jpr5@darkridge.com>
dnl
dnl Please refer to the LICENSE file for more information.
dnl
dnl NOTE: configure.in requires autoconf 2.57 or more recent.

AC_INIT(ngrep.c)

echo
echo 'Configuring System ...'
echo

AC_CANONICAL_SYSTEM
AC_PROG_CC
AC_HEADER_STDC

AC_PREFIX_DEFAULT(/usr/local) 
if test -n "`which tcpdump 2> /dev/null`"; then
   AC_PREFIX_PROGRAM(tcpdump)
fi

dnl
dnl The following are globals that we tack on to the associated
dnl variables in the makefile.  They get AC_SUBST'd at the end.
dnl

EXTRA_DEFINES=""
EXTRA_INCLUDES=""
EXTRA_LIBS=""


dnl
dnl Define the arguments that we accept.
dnl

dnl
dnl For libpcap's that don't need the restart function called for 
dnl multiple lexer passes, allow them to turn it off here.  This option
dnl exists solely to address a very rude email from the maintainer 
dnl indicating that it shouldn't be called directly (and of course he
dnl was wrong because this is still needed). 
dnl

AC_ARG_ENABLE(pcap-restart,
[  --disable-pcap-restart  disable libpcap restart in parser],
[ 
  use_pcap_restart="$enableval"
],
[
  use_pcap_restart="yes"
])

if test $use_pcap_restart = yes; then
   USE_PCAP_RESTART="1"
else
   USE_PCAP_RESTART="0"
fi

dnl
dnl Allow user to specify alternate ``nobody'' user.
dnl

AC_ARG_WITH(dropprivs-user,
[  --with-dropprivs-user[=user]  use different user for dropprivs],
[
  DROPPRIVS_USER="$withval"
],
[
  DROPPRIVS_USER="nobody"
])

dnl
dnl Enable or disable the drop privileges logic.
dnl

AC_ARG_ENABLE(dropprivs,
[  --disable-dropprivs     disable privilege dropping logic],
[
  use_dropprivs="$enableval"
],
[
  use_dropprivs="yes"
])

if test $use_dropprivs = yes; then
   USE_DROPPRIVS="1"
else 
   USE_DROPPRIVS="0"
fi

dnl 
dnl IPv6 (and ICMPv6) support
dnl

AC_ARG_ENABLE(ipv6,
[  --enable-ipv6           enable IPv6 (and ICMPv6) support],
[ 
  use_ipv6="$enableval"
],
[ 
  use_ipv6="no"
])

if test $use_ipv6 = yes; then
   USE_IPv6="1"
else
   USE_IPv6="0"
fi


dnl
dnl Configure the regular expression library.
dnl

AC_ARG_ENABLE(pcre,
[  --enable-pcre           use PCRE instead of GNU regex],
[ 
  use_pcre="$enableval"
],
[ 
  use_pcre="no"
])

if test $use_pcre = yes; then
  echo 
  echo 'Configuring Perl-Compatible Regular Expression (PCRE) library ...' 
  echo

  REGEX_DIR='pcre-5.0'
  REGEX_OBJS="$REGEX_DIR/pcre.o $REGEX_DIR/study.o"
  USE_PCRE="1"

else

  echo
  echo 'Configuring GNU Regular Expression library ...'
  echo

  REGEX_DIR='regex-0.12'
  REGEX_OBJS="$REGEX_DIR/regex.o"
  USE_PCRE="0"

fi

( cd $REGEX_DIR && ./configure )

AC_SUBST(REGEX_DIR)
AC_SUBST(REGEX_OBJS)


echo
echo 'Configuring Network Grep (ngrep) ...'
echo 


dnl
dnl OS-specific options
dnl

STRIPFLAG="-s"
HAVE_DUMB_UDPHDR="0"

case "$target_os" in

*linux*)
	AC_SUBST(OS, LINUX)

	AC_MSG_CHECKING(for a broken redhat glibc udphdr declaration)
	AC_TRY_COMPILE([
#ifndef __FAVOR_BSD
#define __FAVOR_BSD
#endif

#ifndef _BSD_SOURCE
#define _BSD_SOURCE 1
#endif

#undef _GNU_SOURCE

#include <netinet/udp.h>
],[
struct udphdr foo;
unsigned short bar = foo.source;
],
	HAVE_DUMB_UDPHDR="1" && echo "yes",
	HAVE_DUMB_UDPHDR="0" && echo "no")

        ;;

*bsd*)
	AC_SUBST(OS, BSD)

	if test "$USE_PCAP_RESTART" = "0"; then 

        AC_MSG_WARN(
Your OS ($target_os) may have an old libpcap installation.
If the resulting ngrep binary segfaults when a BPF filter is specified 
without an ngrep match string then you should reconfigure ngrep with 
the option ``--disable-pcap-restart''.
)
	sleep 3

	fi

        ;;

*solaris*)
	AC_SUBST(OS, SOLARIS)

        AC_CHECK_LIB(socket, socket,,
                     echo no socket in -lsocket\?; exit)
        AC_CHECK_LIB(nsl, gethostbyname,,
                     echo no gethostbyname in -lnsl\?; exit)

	EXTRA_LIBS="$EXTRA_LIBS -lnsl -lsocket"

	;;

*osf*)
	AC_SUBST(OS, OSF1)

	EXTRA_DEFINES="$EXTRA_DEFINES -D__STDC__=2"

	;;

*hpux11*) 
        AC_SUBST(OS, BSD)
	
	;;

*aix*)
	AC_SUBST(OS, AIX)
	
	;;

*darwin*)
	AC_SUBST(OS, MACOSX)

	STRIPFLAG=""

	;;

*)
	AC_SUBST(OS, UNKNOWN_OS)
        AC_MSG_WARN(
Your OS ($target_os) is not supported yet.  
Try playing with the build host and target options.
)
	sleep 3

        ;;

esac

AC_SUBST(STRIPFLAG)

EXTRA_DEFINES="$EXTRA_DEFINES -D_BSD_SOURCE=1 -D__FAVOR_BSD=1"


dnl
dnl First find some usable PCAP headers.
dnl

AC_MSG_CHECKING(for a complete set of pcap headers)

possible_dirs="`eval echo -n ${includedir}` \
	       /usr/include /usr/include/pcap \
               /usr/local/include /usr/local/include/pcap \
               /usr/share/include /usr/share/include/pcap"

AC_ARG_WITH(pcap-includes,
[  --with-pcap-includes        specify the pcap include directory],
[PCAP_DIR=$withval],
[PCAP_DIR=$possible_dirs])

pcap_dir=""
for dir in $PCAP_DIR ; do 
    if test -d $dir -a -r "$dir/pcap.h" ; then 
       if test -n "$pcap_dir" -a "$pcap_dir" != "$dir"; then
          echo 
          echo; echo more than one set found in:
          echo  $pcap_dir 
          echo  $dir
          echo; echo please wipe out all unused pcap installations
          exit
       else 
          pcap_dir="$dir"
       fi
    fi
done

if test -z "$pcap_dir" ; then
   echo no; echo !!! couldn\'t find a complete set of pcap headers
   exit
else
   echo found $pcap_dir

   PCAP_INCLUDE="-I$pcap_dir"
   PCAP_LINK="-L`dirname $pcap_dir`/lib"

   AC_SUBST(PCAP_INCLUDE)
   AC_SUBST(PCAP_LINK)
  
fi


dnl 
dnl Next figure out which bpf header file to look at.
dnl

AC_MSG_CHECKING(for BPF include path)
BPF=`/usr/bin/perl -ne '/include\s+<(.*bpf\.h)>/ && print "$1\n"' $pcap_dir/pcap.h`
echo $BPF

dnl
dnl Check for DLT_* types that might not have existed in older
dnl libpcap's
dnl

present=""
AC_MSG_CHECKING(for DLT_LINUX_SLL in bpf.h)
AC_EGREP_CPP(yes,
[
#include <$BPF>
#ifdef DLT_LINUX_SLL
yes
#endif
],
[HAVE_DLT_LINUX_SLL="1" && echo yes], [HAVE_DLT_LINUX_SLL="0" && echo no])


present=""
AC_MSG_CHECKING(for DLT_LOOP in bpf.h)
AC_EGREP_CPP(yes,
[
#include <$BPF>
#ifdef DLT_LOOP
yes
#endif
],
[HAVE_DLT_LOOP="1" && echo yes], [HAVE_DLT_LOOP="0" && echo no])


present=""
AC_MSG_CHECKING(for DLT_IEEE802_11 in bpf.h)
AC_EGREP_CPP(yes,
[
#include <$BPF>
#ifdef DLT_IEEE802_11
yes
#endif
],
[HAVE_DLT_IEEE802_11="1" && echo yes], [HAVE_DLT_IEEE802_11="0" && echo no])


present=""
AC_MSG_CHECKING(for DLT_IEEE802_11_RADIO in bpf.h)
AC_EGREP_CPP(yes,
[
#include <$BPF>
#ifdef DLT_IEEE802_11_RADIO
yes
#endif
],
[HAVE_DLT_IEEE802_11_RADIO="1" && echo yes], [HAVE_DLT_IEEE802_11_RADIO="0" && echo no])


present=""
AC_MSG_CHECKING(for DLT_RAW in bpf.h)
AC_EGREP_CPP(yes,
[
#include <$BPF>
#ifdef DLT_RAW
yes
#endif
],
[HAVE_DLT_RAW="1" && echo yes], [HAVE_DLT_RAW="0" && echo no])


dnl
dnl Now that we're past the OS-specific stuff, which could have
dnl modified our USE_* and other defines, define them all now.
dnl 

AC_DEFINE_UNQUOTED(USE_PCAP_RESTART,          $USE_PCAP_RESTART,          [whether to call pcap_restart() before subsequent invocations of pcap_compile() (default yes)])

AC_DEFINE_UNQUOTED(USE_PCRE,                  $USE_PCRE,                  [whether to use PCRE (default GNU Regex)])
AC_DEFINE_UNQUOTED(USE_IPv6,                  $USE_IPv6,                  [whether to use IPv6 (default off)])

AC_DEFINE_UNQUOTED(USE_DROPPRIVS,             $USE_DROPPRIVS,             [whether to use privileges dropping (default yes)])
AC_DEFINE_UNQUOTED(DROPPRIVS_USER,           "$DROPPRIVS_USER",           [pseudo-user for running ngrep (default "nobody")])

AC_DEFINE_UNQUOTED(HAVE_DUMB_UDPHDR,          $HAVE_DUMB_UDPHDR,          [whether to accommodate broken redhat-glibc udphdr declaration (default no)])

AC_DEFINE_UNQUOTED(HAVE_DLT_RAW,              $HAVE_DLT_RAW,              [presence of DLT_RAW in bpf.h]) 
AC_DEFINE_UNQUOTED(HAVE_DLT_IEEE802_11,       $HAVE_DLT_IEEE802_11,       [presence of DLT_IEEE802_11 in bpf.h]) 
AC_DEFINE_UNQUOTED(HAVE_DLT_IEEE802_11_RADIO, $HAVE_DLT_IEEE802_11_RADIO, [presence of DLT_IEEE802_11_RADIO in bpf.h]) 
AC_DEFINE_UNQUOTED(HAVE_DLT_LOOP,             $HAVE_DLT_LOOP,             [presence of DLT_LOOP in bpf.h]) 
AC_DEFINE_UNQUOTED(HAVE_DLT_LINUX_SLL,        $HAVE_DLT_LINUX_SLL,        [presence of DLT_LINUX_SLL in bpf.h]) 


dnl
dnl And the PCAP library..
dnl

AC_CHECK_LIB(pcap, pcap_open_live,,echo need pcap lib; exit)

dnl
dnl And the PCAP restart function..
dnl

pcap_restart_func=""
if test "$use_pcap_restart" = "yes" ; then 
   AC_CHECK_LIB(pcap, pcap_restart, pcap_restart_func="pcap_restart",
     AC_CHECK_LIB(pcap, pcap_yyrestart, pcap_restart_func="pcap_yyrestart",
       AC_CHECK_LIB(pcap, yyrestart, pcap_restart_func="yyrestart",
         echo no yacc restart func found
         echo perhaps libpcap wasn\'t compiled with bison/flex\?
         exit)))
fi

if test -z "$pcap_restart_func"; then
   pcap_restart_func="unused"
fi

AC_DEFINE_UNQUOTED(PCAP_RESTART_FUNC, $pcap_restart_func, [routine used for restarting the PCAP lexer])

dnl
dnl AC_SUBST in the tack-on globals..
dnl

AC_SUBST(EXTRA_DEFINES)
AC_SUBST(EXTRA_INCLUDES)
AC_SUBST(EXTRA_LIBS)


dnl
dnl Emit configuration messages about any flags specified.
dnl

echo 

if test "$HAVE_DUMB_UDPHDR" = "1"; then
    echo "CONFIG: support for broken redhat glibc udphdr enabled"
fi

if test "$USE_PCAP_RESTART" = "0"; then 
    echo "CONFIG: pcap restart logic disabled"
fi

if test "$USE_IPv6" = "1"; then
    echo "CONFIG: ipv6 support enabled"
else
    echo "CONFIG: ipv6 support disabled"
fi

if test "$USE_DROPPRIVS" = "1"; then
    echo "CONFIG: privilege dropping enabled, using \"$DROPPRIVS_USER\""
else
    echo "CONFIG: privilege dropping disabled"
fi

if test "$USE_PCRE" = "1"; then
    echo "CONFIG: using PCRE regex library"
else
    echo "CONFIG: using GNU regex library"
fi


dnl
dnl And we're done.
dnl

echo

AC_CONFIG_HEADERS(config.h)
AC_CONFIG_FILES(Makefile)
AC_OUTPUT
