1dnl
2dnl configure.ac:
3dnl Autoconf input for iftop.
4dnl
5dnl I hate autoconf with a passion. It's an utter pain to write these bloody
6dnl things and even once you have you find yourself testing for more and more
7dnl special cases. But that's OK. Paul is going to maintain it :)
8dnl     -- Chris Lightfoot
9dnl
10dnl $Id: configure.ac,v 1.2 2014/01/19 20:28:31 pdw Exp $
11dnl
12dnl To regenerate everything from source, do:
13dnl    autoheader
14dnl    aclocal
15dnl    automake
16dnl    autoconf
17dnl Now you should have good sources to make into a tarball and distribute.
18dnl    ./configure     (perhaps with some arguments)
19dnl    make
20dnl Tested with automake 1.9.6-1.14 and autoconf 2.59-2.69.
21dnl
22dnl Boilerplate configuration
23dnl
24
25AC_INIT([iftop], [1.0pre4], [pdw@ex-parrot.com], [iftop], [http://www.ex-parrot.com/pdw/iftop/])
26
27AC_CONFIG_AUX_DIR(config)
28
29AC_CANONICAL_SYSTEM
30
31AC_CONFIG_HEADERS([config.h])
32AM_INIT_AUTOMAKE
33
34dnl Make sure we have a C compiler....
35AC_PROG_CC
36AC_HEADER_STDC
37
38dnl
39dnl Options to configure.
40dnl
41
42AC_ARG_WITH(resolver,
43    [  --with-resolver=TYPE    Technique iftop should use for name resolution.
44                          Valid options are:
45			  netdb          use gethostbyaddr_r in multiple
46			                 threads.
47			  netdb_1thread  use gethostbyaddr_r and
48					 assume it is not reentrant.
49			  ares           use the MIT ARES asynchronous
50					 resolver library.
51			  forking        use the REALLY SUCKY forking resolver.
52			  guess          run experiments to guess a
53					 reasonable value.  Only works if you
54					 aren't cross-compiling.  This
55					 is the default.  guess will
56					 either select netdb or netdb_1thread.
57			  none           don't do name resolution.],
58    [resolver=$withval],
59    [resolver=guess])
60
61AC_ARG_WITH(libpcap,
62    [  --with-libpcap=WHERE    Where the libpcap packet-capture library is found.
63                          The pcap library should be installed  in WHERE/lib,
64                          and the header file in either WHERE/include or
65                          WHERE/include/pcap.
66                          [default=look in standard locations]],
67    [libpcap_prefix=$withval],
68    [libpcap_prefix=""])
69
70dnl
71dnl Fairly generic checks.
72dnl
73
74dnl Checks for system headers.
75AC_CHECK_HEADERS([sgtty.h sys/ioctl.h sys/time.h sys/sockio.h termio.h termios.h unistd.h])
76
77dnl Checks for typedefs, structures, and compiler characteristics.
78AC_C_CONST
79AC_TYPE_SIZE_T
80AC_HEADER_TIME
81
82dnl
83dnl Are we on a system that uses the STREAMS low-level DLPI interface?
84dnl
85
86AC_CHECK_HEADER([sys/dlpi.h],[AC_DEFINE([HAVE_DLPI],1,[Are we running on a STREAMS system with DLPI?])])
87
88dnl Checks for library functions.
89AC_CHECK_FUNCS(regcomp select strdup strerror strspn)
90
91AC_SEARCH_LIBS(socket, socket)
92AC_SEARCH_LIBS(log, m)
93AC_CHECK_FUNC(gethostbyname, ,
94	[AC_CHECK_LIB(nsl, gethostbyname)] )
95
96AC_SEARCH_LIBS(inet_aton, [socket nsl])
97AC_SEARCH_LIBS(inet_pton, [socket nsl])
98AC_CHECK_FUNCS(inet_aton inet_pton)
99
100dnl
101dnl Find integers of known physical size. This is a pain in the arse because
102dnl we can't use AC_CHECK_SIZEOF to find the original variables, since that
103dnl function doesn't permit us to include a header file. Sigh.
104dnl
105
106for type in u_int8_t u_int16_t u_int32_t ; do
107    AC_MSG_CHECKING([size of $type])
108    AC_RUN_IFELSE([AC_LANG_SOURCE([
109#include <sys/types.h>
110#include <stdio.h>
111int main() {
112    $type dummy;
113    FILE *f=fopen("conftestval", "w");
114    if (!f) exit(1);
115    fprintf(f, "%d\n", sizeof($1));
116    exit(0);
117}
118    ])], [
119        x=`cat conftestval`
120        eval "size_$type=$x"
121        AC_MSG_RESULT([$x])
122    ], [
123        eval "size_$type=0"
124        AC_MSG_RESULT([unknown type])
125    ], [
126        eval "size_$type=0"
127        AC_MSG_RESULT([can't determine when cross-compiling])
128    ])
129done
130
131dnl Groan. Have to do things this way so that autoheader can do its thing....
132AC_DEFINE_UNQUOTED(SIZEOF_U_INT8_T,  [$size_u_int8_t],  [size of u_int8_t])
133AC_DEFINE_UNQUOTED(SIZEOF_U_INT16_T, [$size_u_int16_t], [size of u_int16_t])
134AC_DEFINE_UNQUOTED(SIZEOF_U_INT32_T, [$size_u_int32_t], [size of u_int32_t])
135
136dnl If we already have these types, don't piss about any more....
137
138if test $size_u_int8_t != 1 || test $size_u_int16_t != 2 || test $size_u_int32_t != 4 ; then
139dnl XXXif test $size_u_int8_t != 1 -o $size_u_int16_t != 2 -o $size_u_int32_t != 4 ; then
140    do_int_types=1
141    AC_CHECK_HEADERS(
142        stdint.h             dnl C99
143        sys/inttypes.h,      dnl Solaris
144        [do_int_types=0; break])
145
146    if test $do_int_types = 1 ; then
147        dnl No C99 int types, so figure them out from basic types.
148        AC_CHECK_SIZEOF(unsigned short int)
149        AC_CHECK_SIZEOF(unsigned int)
150        AC_CHECK_SIZEOF(unsigned long int)
151    else
152        dnl Just use the C99 ones.
153        AC_DEFINE(HAVE_C99_INTS, 1, [C99 fixed-width int types available])
154    fi
155fi
156
157dnl
158dnl Name resolution.
159dnl
160dnl This is complicated because we need some sort of reentrant mechanism for
161dnl name resolution. Naturally, UNIX vendors have come up with a variety of
162dnl incompatible schemes for this, many of which don't work at all.
163dnl
164
165dnl First, the default resolver, which uses getnameinfo or gethostbyaddr_r. If
166dnl not available, we fall back to gethostbyaddr. We could fall back to ARES,
167dnl but that's probably not available on typical machines.
168
169dnl If we've been asked to guess, remember that fact in specified_resolver.
170dnl From this point on, resolver is our preferred resolver given the
171dnl experiments we've done so far, or "guess" if we have no idea.
172specified_resolver=$resolver
173if test x$specified_resolver = xguess ; then
174    dnl Best possibility is getnameinfo.
175    use_getnameinfo=0
176    AC_SEARCH_LIBS(getnameinfo, [nsl], [use_getnameinfo=1])
177
178    dnl XXX For the moment, don't use getnameinfo, since it isn't actually
179    dnl thread safe on, e.g., NetBSD.
180    use_getnameinfo=0
181
182    if test $use_getnameinfo = 1 ; then
183        dnl Done.
184        AC_DEFINE(USE_GETNAMEINFO, 1, [use getnameinfo for name resolution])
185    else
186	dnl Best hope is netdb, which presently means gethostbyaddr_r.
187	resolver=netdb
188    fi
189fi
190
191if test x$resolver = xnetdb ; then
192    dnl Can use gethostbyaddr_r?
193    AC_SEARCH_LIBS(gethostbyaddr_r, [nsl], , [resolver=guess])
194    if test x$resolver = xguess && test x$specified_resolver != xguess ; then
195       dnl They wanted gethostbyaddr_r, but they can't have it, so stop.
196       AC_MSG_ERROR([no library defines gethostbyaddr_r])
197    fi
198fi
199
200dnl We still might do gethostbyaddr_r.  Figure out whether we have
201dnl glibc-style or Solaris-style gethostbyaddr_r (or neither...).
202dnl Separate determining how to call gethostbyaddr_r from testing
203dnl whether it works so we can support cross-compilation.
204if test x$resolver = xnetdb ; then
205    AC_MSG_CHECKING([how to call gethostbyaddr_r])
206    dnl Try 7 arguments returning a struct hostent*.
207    AC_LINK_IFELSE([AC_LANG_SOURCE([`cat config/hostentp_ghba_r.c`])],
208                   [AC_MSG_RESULT([7 args])
209		    ghba_args=8
210	            AC_DEFINE(GETHOSTBYADDR_R_RETURNS_HOSTENT_P, 1,
211                    [7-argument gethostbyaddr_r returns struct hostent*])], [
212    dnl Try 8 arguments returning an int.
213    AC_LINK_IFELSE([AC_LANG_SOURCE([`cat config/int_ghba_r.c`])],
214                   [AC_MSG_RESULT([8 args, int return])
215		    ghba_args=8
216	            AC_DEFINE(GETHOSTBYADDR_R_RETURNS_INT, 1,
217                    [8-argument gethostbyaddr_r returns int])], [
218    dnl Neither.
219    AC_MSG_RESULT([don't know how])
220    resolver=guess])])
221    if test x$resolver = xguess && test x$specified_resolver != xguess ; then
222       dnl They wanted gethostbyaddr_r, but they can't have it, so stop.
223       AC_MSG_ERROR([gethostbyaddr_r has no known calling convention])
224    fi
225fi
226
227dnl If we still want to do gethostbyaddr_r, and we aren't
228dnl cross-compiling, test it.
229if test x$resolver = xnetdb ; then
230    if test x$ghba_args = x8 ; then
231       testfile=int_ghba_r
232    else
233       testfile=hostentp_ghba_r
234    fi
235    AC_MSG_CHECKING(gethostbyaddr_r usability)
236    AC_RUN_IFELSE([AC_LANG_SOURCE([`cat config/$testfile.c`])],
237                  [AC_MSG_RESULT([yes])],
238		  [AC_MSG_RESULT([no])
239		   resolver=guess],
240		  [AC_MSG_RESULT([can't test because we are cross-compiling])])
241    if test x$resolver = xguess ; then
242        if test x$specified_resolver = xguess ; then
243           AC_MSG_RESULT([gethostbyaddr_r doesn't work, so we'll try something else])
244        else
245           dnl They wanted gethostbyaddr_r, but it doesn't work, so stop.
246           AC_MSG_ERROR([gethostbyaddr_r doesn't work])
247        fi
248    fi
249fi
250
251dnl We found a gethostbyaddr_r we know how to use and which seems to
252dnl work.
253if test x$resolver = xnetdb ; then
254    AC_DEFINE(USE_GETHOSTBYADDR_R, 1, [use gethostbyaddr_r for name resolution])
255fi
256
257dnl They may have asked for ares.
258if test x$resolver = xares ; then
259    dnl See if ares is to hand....
260    AC_SEARCH_LIBS(ares_init, [ares], [
261        AC_DEFINE(USE_ARES, 1, [use ARES for name resolution])
262        ], [
263        dnl They asked for ares, but we can't give it to them, so stop.
264        AC_MSG_ERROR([can't find ARES.  Re-run configure and ask for a different resolver.])])
265fi
266
267dnl Last thing to try if we haven't decided yet is netdb_1thread.
268if test x$resolver = xguess ; then
269   resolver=netdb_1thread
270fi
271
272dnl Ugh. Both the single-threaded and the forking resolvers use gethostbyaddr.
273if test x$resolver = xnetdb_1thread || test x$resolver = xforking ; then
274    AC_SEARCH_LIBS(gethostbyaddr, [nsl], , [
275        AC_MSG_ERROR([gethostbyaddr is not available.  You will have to
276  recompile with no name resolution at all.])])
277
278    if test x$resolver = xnetdb_1thread ; then
279        AC_MSG_WARN([using single-threaded resolver with gethostbyaddr
280  Consider obtaining ARES or a machine with a working gethostbyaddr_r.])
281        AC_DEFINE(USE_GETHOSTBYADDR, 1, [use gethostbyaddr for name resolution])
282    else
283        AC_DEFINE(USE_FORKING_RESOLVER, 1, [use a REALLY SUCKY forking resolver for name resolution])
284    fi
285fi
286
287dnl Otherwise, no resolver at all. Boo hoo.
288
289dnl
290dnl Find libpcap.
291dnl
292
293if test x$libpcap_prefix = x ; then
294    libpcap_prefix="/usr /usr/local /opt /software"
295fi
296
297AC_MSG_CHECKING([where to find pcap.h])
298foundpcaph=0
299oldCPPFLAGS=$CPPFLAGS
300for test_prefix in "" $libpcap_prefix ; do
301    for x in "" /pcap ; do
302        if test x$test_prefix != x ; then
303            CPPFLAGS="$oldCPPFLAGS -I$test_prefix/include$x"
304        fi
305        AC_TRY_CPP([
306#include <pcap.h>
307        ], [
308        AC_MSG_RESULT([$test_prefix/include$x])
309        foundpcaph=1
310        break
311        ])
312    done
313    if test $foundpcaph = 1 ; then
314        break
315    fi
316done
317
318if test $foundpcaph = 0 ; then
319    AC_MSG_RESULT([no idea])
320    AC_MSG_ERROR([can't find pcap.h
321  You're not going to get very far without libpcap.])
322else
323    dnl assume that -lpcap is under $test_prefix/lib
324    if test x$test_prefix != x ; then
325        LDFLAGS="$LDFLAGS -L$test_prefix/lib"
326    fi
327    AC_CHECK_LIB(pcap, pcap_open_live, , [
328            AC_MSG_ERROR([can't find libpcap
329  You're not going to get very far without libpcap.])
330        ])
331fi
332
333foundpcap=0
334AC_CHECK_HEADERS([pcap.h pcap/pcap.h], [
335    foundpcap=1
336    break
337    ])
338
339if test $foundpcap = 0 ; then
340    AC_MSG_ERROR([can't find pcap.h
341  You're not going to get very far without libpcap.])
342fi
343
344dnl
345dnl Curses. Really, we need ncurses or something similarly advanced, since
346dnl we use the (apparently obscure) mvchgat function. Unfortunately, there's
347dnl a solid chance that mvchgat is a macro, so we can't just use
348dnl AC_SEARCH_LIBS....
349dnl
350
351AC_MSG_CHECKING([for a curses library containing mvchgat])
352oldLIBS=$LIBS
353for curseslib in ncursesw curses ncurses ; do
354    LIBS="$oldLIBS -l$curseslib"
355    AC_TRY_LINK([
356#include <$curseslib.h>
357        ], [
358        mvchgat(0, 0, 1, A_REVERSE, 0, NULL)
359        ], [
360        foundcurseslib=$curseslib
361        break
362        ])
363done
364
365if test x$foundcurseslib = x ; then
366    AC_MSG_RESULT([none found])
367    AC_MSG_ERROR([Curses! Foiled again!
368  (Can't find a curses library supporting mvchgat.)
369  Consider installing ncurses.])
370else
371    AC_MSG_RESULT([-l$foundcurseslib])
372fi
373
374
375dnl
376dnl POSIX threads. Different systems like different combinations of flags,
377dnl libraries, etc. We use a test program to figure this stuff out.
378dnl
379
380AC_MSG_CHECKING([POSIX threads compilation])
381thrfail=1
382oldCFLAGS=$CFLAGS
383oldLIBS=$LIBS
384for flag in "" -mt -pthread -thread ; do
385    CFLAGS="$oldCFLAGS $flag"
386    for lib in "" -lpthread "-lpthread -lposix4" ; do
387        LIBS="$oldLIBS $lib"
388        AC_LINK_IFELSE([AC_LANG_SOURCE([`cat config/pthread.c`])], [
389            foundthrlib=$lib
390            foundthrflag=$flag
391            thrfail=0
392            break
393            ])
394    done
395    if test $thrfail = 0 ; then
396        break
397    fi
398done
399
400if test $thrfail = 1 ; then
401    AC_MSG_RESULT([no idea])
402    AC_MSG_ERROR([can't figure out how to compile with POSIX threads
403  If your system actually supports POSIX threads, this means we've messed up.])
404fi
405
406AC_MSG_RESULT([CFLAGS=$foundthrflag and LIBS=$foundthrlib])
407AC_MSG_CHECKING([POSIX threads usability])
408AC_RUN_IFELSE([AC_LANG_SOURCE([`cat config/pthread.c`])],
409	      [AC_MSG_RESULT([yes])],
410              [AC_MSG_ERROR(
411	       [it fails.  We probably guessed the wrong CFLAGS.])],
412	      [AC_MSG_RESULT([can't test because we are cross-compiling])])
413
414dnl
415dnl Are we on a system (like Solaris) that requires promiscuous mode in order to
416dnl see any outgoing packets?
417dnl
418
419AC_MSG_CHECKING([if we need to enable promiscuous mode by default])
420
421enable_default_promiscuous="no"
422
423case "$host_os" in
424solaris*) enable_default_promiscuous="yes" ;;
425esac
426
427AC_ARG_ENABLE(default-promiscuous,
428	[  --enable-default-promiscuous If enabled, iftop will operate in promiscuous mode
429                          to capture outgoing packets])
430
431AC_MSG_RESULT([$enable_default_promiscuous])
432
433if test x"$enable_default_promiscuous" = x"yes"; then
434	AC_DEFINE([NEED_PROMISCUOUS_FOR_OUTGOING],1,[Enable default promiscuous mode to capture outgoing packets])
435fi
436
437dnl
438dnl Wahey! This might even work.
439dnl
440
441AC_SUBST(ac_aux_dir)
442
443AC_OUTPUT(Makefile config/Makefile)
444
445if echo $PACKAGE_VERSION | grep 'pre' > /dev/null ; then
446	AC_MSG_WARN([
447******************************************************************************
448
449This is a pre-release version.  Pre-releases are subject to limited
450announcements, and therefore limited circulation, as a means of testing
451the more widely circulated final releases.
452
453Please do not be surprised if this release is broken, and if it is broken, do
454not assume that someone else has spotted it.  Instead, please drop a note on
455the mailing list, or a brief email to me on pdw@ex-parrot.com
456
457Thank you for taking the time to be the testing phase of this development
458process.
459
460Paul Warren
461
462******************************************************************************
463])
464fi
465