""
This commit is contained in:
1
CHANGES
1
CHANGES
@@ -6,6 +6,7 @@ $Id$
|
||||
Added support for token ring networks
|
||||
Token ring network direction determination
|
||||
Martin Garton <Martin.Garton@DCSTRANS.COM>
|
||||
Added autoconf/automake build system
|
||||
|
||||
0.10 29/10/02
|
||||
|
||||
|
||||
15
INSTALL
15
INSTALL
@@ -1,13 +1,16 @@
|
||||
Installation instructions for iftop
|
||||
$Id$
|
||||
|
||||
1. Modify any settings at the top of the Makefile. Look in particular at PREFIX
|
||||
and MANDIR.
|
||||
|
||||
2. Compile by typing make.
|
||||
iftop is now autoconf/automake-enabled. You should be able to build it on
|
||||
common platforms by typing `./configure && make'.
|
||||
|
||||
3. Install by typing make install. You will probably want to do this step as
|
||||
root.
|
||||
There is one gotcha, however, which is that some systems, such as FreeBSD,
|
||||
lack a working implementation of the gethostbyaddr_r(3) C library function. On
|
||||
such systems, you may want to use the --with-resolver=ares configure option to
|
||||
build a version of iftop which uses the ARES asynchronous DNS library for name
|
||||
resolution. An alternative is to use --with-resolver=netdb_1thread, which will
|
||||
make iftop run only one name resolution thread. This is not recommended.
|
||||
|
||||
You can also use make uninstall to remove iftop and its manual page.
|
||||
For historical interest, the old iftop makefile is included in Makefile.OLD.
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ VERSION = 0.11pre1
|
||||
#CC = gcc
|
||||
|
||||
# Give the location of pcap.h here:
|
||||
CFLAGS += -I/usr/include/pcap
|
||||
CFLAGS += -I/usr/include/pcap -g
|
||||
# CFLAGS += -I/usr/pkg/include
|
||||
# CFLAGS += -pg -a
|
||||
|
||||
@@ -20,6 +20,11 @@ CFLAGS += -I/usr/include/pcap
|
||||
# LDFLAGS += -L/usr/local/lib
|
||||
# LDFLAGS += -pg -a
|
||||
|
||||
# Do you want to use curses or ncurses? Probably ncurses, unless curses
|
||||
# is ncurses on your machine.
|
||||
CURSES = ncurses
|
||||
#CURSES = curses
|
||||
|
||||
#
|
||||
# Name resolution. Sensible systems have gethostbyaddr_r, which is reentrant
|
||||
# and can be called from several threads of a multithreaded program. Other
|
||||
@@ -39,6 +44,12 @@ CFLAGS += -DUSE_GETHOSTBYADDR_R
|
||||
#CFLAGS += -DUSE_LIBRESOLV
|
||||
#CFLAGS += -DUSE_ARES
|
||||
|
||||
#
|
||||
# On some machines, gethostbyaddr_r returns int; on others, struct hostent*.
|
||||
# Comment out this line if you are using one of the latter.
|
||||
#
|
||||
#CFLAGS += -DGETHOSTBYADD_R_RETURNS_INT
|
||||
|
||||
#
|
||||
# Uncomment if you are using libresolv.
|
||||
#
|
||||
@@ -52,6 +63,11 @@ CFLAGS += -DUSE_GETHOSTBYADDR_R
|
||||
#CFLAGS += -I/software/include
|
||||
#LDFLAGS += -L/software/lib
|
||||
|
||||
#
|
||||
# Solaris needs a library to make sockets go and lacks inet_aton.
|
||||
#
|
||||
LDLIBS += -lsocket -lnsl
|
||||
CFLAGS += -DFAKE_INET_ATON
|
||||
|
||||
# PREFIX specifies the base directory for the installation.
|
||||
PREFIX = /usr/local
|
||||
@@ -66,9 +82,8 @@ MANDIR = man
|
||||
|
||||
# You shouldn't need to change anything below this point.
|
||||
CFLAGS += -g -Wall "-DIFTOP_VERSION=\"$(VERSION)\""
|
||||
LDFLAGS += -g -pthread
|
||||
LDLIBS += -lpcap -lcurses -lm
|
||||
|
||||
LDFLAGS += -g #-pthread
|
||||
LDLIBS += -lpcap -l$(CURSES) -lm -lpthread
|
||||
|
||||
SRCS = iftop.c addr_hash.c hash.c ns_hash.c resolver.c ui.c util.c sorted_list.c\
|
||||
options.c serv_hash.c threadprof.c edline.c screenfilter.c
|
||||
@@ -83,6 +98,9 @@ OBJS = $(SRCS:.c=.o)
|
||||
iftop: $(OBJS) Makefile
|
||||
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS)
|
||||
|
||||
integers.h: integers
|
||||
./integers
|
||||
|
||||
install: iftop
|
||||
install -D iftop $(PREFIX)/$(BINDIR)/iftop
|
||||
install -D iftop.8 $(PREFIX)/$(MANDIR)/man8/iftop.8
|
||||
40
Makefile.am
Normal file
40
Makefile.am
Normal file
@@ -0,0 +1,40 @@
|
||||
#
|
||||
# Makefile.am:
|
||||
# Automake file for iftop.
|
||||
#
|
||||
# I don't understand this stuff, so I just stole it from the tpop3d
|
||||
# distribution. That means that, really, Mark Longair should take credit for
|
||||
# it.
|
||||
# -- Chris Lightfoot
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
|
||||
sbin_PROGRAMS = iftop
|
||||
|
||||
iftop_SOURCES = addr_hash.c edline.c hash.c iftop.c ns_hash.c \
|
||||
options.c resolver.c screenfilter.c serv_hash.c \
|
||||
sorted_list.c threadprof.c ui.c util.c
|
||||
|
||||
noinst_HEADERS = addr_hash.h ether.h ethertype.h extract.h hash.h iftop.h \
|
||||
integers.h ip.h llc.h ns_hash.h options.h resolver.h \
|
||||
screenfilter.h serv_hash.h sll.h sorted_list.h tcp.h \
|
||||
threadprof.h token.h ui.h
|
||||
|
||||
man_MANS = iftop.8
|
||||
|
||||
SUBDIRS = config
|
||||
|
||||
iftop.cat: iftop.8
|
||||
(echo -e ".pl 1100i" ; cat iftop.8 ; echo ".pl \n(nlu+10") | groff -Tascii -man > iftop.cat
|
||||
|
||||
## These need to be distributed along with configure:
|
||||
|
||||
EXTRA_DIST = bootstrap README CHANGES COPYING INSTALL TODO Makefile.OLD \
|
||||
$(man_MANS) iftop.cat
|
||||
|
||||
MAINTERCLEANFILES = Makefile.in aclocal.m4 configure configuration.h.in \
|
||||
stamp-h.in
|
||||
|
||||
ACLOCAL = aclocal -I @ac_aux_dir@
|
||||
|
||||
12
README
12
README
@@ -21,5 +21,13 @@ in order to compile iftop.
|
||||
FreeBSD 4.7:
|
||||
|
||||
This version of FreeBSD lacks a proper gethostbyaddr_r function. You should
|
||||
choose an alternative name resolution technique; see comments in the Makefile.
|
||||
We recommend using ares (-DUSE_ARES).
|
||||
choose an alternative name resolution technique using the --with-resolver=...
|
||||
option to configure.
|
||||
|
||||
Solaris:
|
||||
|
||||
On Solaris, libpcap does not capture outgoing packets unless it is run on an
|
||||
interface in promiscuous mode. Therefore, you will need to use the -p option
|
||||
to iftop to get sensible results. Cf.
|
||||
http://www.tcpdump.org/lists/workers/2002/02/msg00010.html
|
||||
|
||||
|
||||
2
TODO
2
TODO
@@ -7,8 +7,6 @@ $Id$
|
||||
|
||||
* Config file.
|
||||
|
||||
* Find someone gullible to sort out autoconf.
|
||||
|
||||
* Which average to use for the bar graph? Show several and peaks? Colours?
|
||||
|
||||
* Single keypress firewalling of troublesome connections, a la top(1)'s K
|
||||
|
||||
13
bootstrap
Executable file
13
bootstrap
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# bootstrap:
|
||||
# Build the configure script from the .in files.
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
set -x
|
||||
aclocal -I config
|
||||
# libtoolize --force --copy
|
||||
autoheader
|
||||
automake --foreign --add-missing --copy
|
||||
autoconf
|
||||
18
config/Makefile.am
Normal file
18
config/Makefile.am
Normal file
@@ -0,0 +1,18 @@
|
||||
#
|
||||
# config/Makefile.am:
|
||||
# Automake file for the extra config droppings.
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
|
||||
EXTRA_DIST = hostentp_ghba_r.c int_ghba_r.c pthread.c
|
||||
|
||||
AUX_DIST = config.guess \
|
||||
config.sub \
|
||||
install-sh \
|
||||
ltconfig \
|
||||
ltmain.sh \
|
||||
missing \
|
||||
mkinstalldirs
|
||||
|
||||
MAINTERCLEANFILES = $(AUX_DIST)
|
||||
39
config/hostentp_ghba_r.c
Normal file
39
config/hostentp_ghba_r.c
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* hostentp_ghba_r.c:
|
||||
* Test program to see whether gethostbyaddr_r takes 7 arguments and returns
|
||||
* struct hostent*.
|
||||
*/
|
||||
|
||||
static const char rcsid[] = "$Id$";
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
int main(void) {
|
||||
struct in_addr localhost;
|
||||
struct hostent hostbuf, *hp;
|
||||
char *buf;
|
||||
int herr;
|
||||
size_t buflen = 1024;
|
||||
|
||||
localhost.s_addr = htonl(INADDR_LOOPBACK);
|
||||
buf = malloc(buflen);
|
||||
while ((hp = gethostbyaddr_r((char*)&localhost, sizeof(struct in_addr),
|
||||
AF_INET, &hostbuf, buf, buflen, &herr))
|
||||
== NULL
|
||||
&& errno == ERANGE)
|
||||
buf = (char*)realloc(buf, buflen *= 2);
|
||||
|
||||
/* We assume that the loopback address can always be resolved if
|
||||
* gethostbyaddr_r is actually working. */
|
||||
if (hp == NULL) {
|
||||
fprintf(stderr, "errno = %d, herr = %d\n", errno, herr);
|
||||
return -1;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
38
config/int_ghba_r.c
Normal file
38
config/int_ghba_r.c
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* int_ghba_r.c:
|
||||
* Test program to see whether gethostbyaddr_r takes 8 arguments and returns
|
||||
* int.
|
||||
*/
|
||||
|
||||
static const char rcsid[] = "$Id$";
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
int main(void) {
|
||||
struct in_addr localhost;
|
||||
struct hostent hostbuf, *hp;
|
||||
char *buf;
|
||||
int res, herr;
|
||||
size_t buflen = 1024;
|
||||
|
||||
localhost.s_addr = htonl(INADDR_LOOPBACK);
|
||||
buf = malloc(buflen);
|
||||
while ((res = gethostbyaddr_r((char*)&localhost, sizeof localhost, AF_INET,
|
||||
&hostbuf, buf, buflen, &hp, &herr))
|
||||
== ERANGE)
|
||||
buf = (char*)realloc(buf, buflen *= 2);
|
||||
|
||||
/* We assume that the loopback address can always be resolved if
|
||||
* gethostbyaddr_r is actually working. */
|
||||
if (res || hp == NULL) {
|
||||
fprintf(stderr, "errno = %d, herr = %d, res = %d\n", errno, herr, res);
|
||||
return -1;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
62
config/pthread.c
Normal file
62
config/pthread.c
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* pthread.c:
|
||||
* Tiny test program to see whether POSIX threads work.
|
||||
*/
|
||||
|
||||
static const char rcsid[] = "$Id$";
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
|
||||
static int return_value = -1;
|
||||
|
||||
void *worker_thread(void *v) {
|
||||
/* Record successful return and signal parent to wake up. */
|
||||
return_value = 0;
|
||||
pthread_mutex_lock(&mtx);
|
||||
pthread_cond_signal(&cond);
|
||||
pthread_mutex_unlock(&mtx);
|
||||
while (1)
|
||||
pause();
|
||||
}
|
||||
|
||||
/* Start a thread, and have it set a variable to some other value, then signal
|
||||
* a condition variable. If this doesn't happen within some set time, we assume
|
||||
* that something's gone badly wrong and abort (for instance, the thread never
|
||||
* got started). */
|
||||
int main(void) {
|
||||
pthread_t thr;
|
||||
int res;
|
||||
struct timespec deadline = {0};
|
||||
if ((res = pthread_mutex_lock(&mtx)) != 0
|
||||
|| (res = pthread_create(&thr, NULL, worker_thread, NULL)) != 0) {
|
||||
fprintf(stderr, "%s\n", strerror(res));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Thread should now be running; we should wait on the condition
|
||||
* variable. */
|
||||
do
|
||||
deadline.tv_sec = 2 + time(NULL);
|
||||
while ((res = pthread_cond_timedwait(&cond, &mtx, &deadline)) == EINTR);
|
||||
|
||||
if (res != 0) {
|
||||
fprintf(stderr, "%s\n", strerror(res));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((res = pthread_cancel(thr)) != 0
|
||||
|| (res = pthread_join(thr, NULL)) != 0) {
|
||||
fprintf(stderr, "%s\n", strerror(res));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return return_value;
|
||||
}
|
||||
305
configure.in
Normal file
305
configure.in
Normal file
@@ -0,0 +1,305 @@
|
||||
dnl
|
||||
dnl configure.in:
|
||||
dnl Autoconf input for iftop.
|
||||
dnl
|
||||
dnl I hate autoconf with a passion. It's an utter pain to write these bloody
|
||||
dnl things and even once you have you find yourself testing for more and more
|
||||
dnl special cases. But that's OK. Paul is going to maintain it :)
|
||||
dnl -- Chris Lightfoot
|
||||
dnl
|
||||
dnl $Id$
|
||||
dnl
|
||||
|
||||
dnl
|
||||
dnl Boilerplate configuration
|
||||
dnl
|
||||
|
||||
AC_INIT(iftop.c)
|
||||
AC_CONFIG_AUX_DIR(config)
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
AM_INIT_AUTOMAKE(iftop, "0.11pre1")
|
||||
|
||||
AC_DEFINE_UNQUOTED(IFTOP_VERSION, "$VERSION", [The iftop version number])
|
||||
|
||||
dnl Make sure we have a C compiler....
|
||||
AC_PROG_CC
|
||||
AC_HEADER_STDC
|
||||
|
||||
dnl
|
||||
dnl Options to configure.
|
||||
dnl
|
||||
|
||||
AC_ARG_WITH(resolver,
|
||||
[ --with-resolver=TYPE Technique iftop should use for name resolution. Valid
|
||||
options are netdb, netdb_1thread (for systems without
|
||||
working gethostbyaddr_r), ares for the MIT ARES
|
||||
asynchronous resolver library, or none if you don't
|
||||
need any name resolution.
|
||||
[default=netdb]],
|
||||
[resolver=$withval],
|
||||
[resolver=netdb])
|
||||
|
||||
dnl
|
||||
dnl Fairly generic checks.
|
||||
dnl
|
||||
|
||||
dnl Checks for system headers.
|
||||
AC_CHECK_HEADERS(sys/ioctl.h sys/time.h sys/sockio.h unistd.h)
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
AC_TYPE_SIZE_T
|
||||
AC_HEADER_TIME
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_CHECK_FUNCS(regcomp select strdup strerror strspn)
|
||||
|
||||
AC_SEARCH_LIBS(socket, socket)
|
||||
AC_SEARCH_LIBS(log, m)
|
||||
AC_CHECK_FUNC(gethostbyname, ,
|
||||
[AC_CHECK_LIB(nsl, gethostbyname)] )
|
||||
|
||||
AC_SEARCH_LIBS(inet_aton, [-lsocket -lnsl])
|
||||
AC_SEARCH_LIBS(inet_pton, [-lsocket -lnsl])
|
||||
AC_CHECK_FUNCS(inet_aton inet_pton)
|
||||
|
||||
dnl
|
||||
dnl Find integers of known physical size. This is a pain in the arse because
|
||||
dnl we can't use AC_CHECK_SIZEOF to find the original variables, since that
|
||||
dnl function doesn't permit us to include a header file. Sigh.
|
||||
dnl
|
||||
|
||||
for type in u_int8_t u_int16_t u_int32_t ; do
|
||||
AC_MSG_CHECKING([size of $type])
|
||||
defn="SIZEOF_"`echo $type | tr a-z A-Z`
|
||||
AC_TRY_RUN([
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
int main() {
|
||||
$type dummy;
|
||||
FILE *f=fopen("conftestval", "w");
|
||||
if (!f) exit(1);
|
||||
fprintf(f, "%d\n", sizeof($1));
|
||||
exit(0);
|
||||
}
|
||||
], [
|
||||
x=`cat conftestval`
|
||||
eval "size_$type=$x"
|
||||
AC_MSG_RESULT([$x])
|
||||
], [
|
||||
eval "size_$type=0"
|
||||
AC_MSG_RESULT([unknown type])
|
||||
])
|
||||
done
|
||||
|
||||
dnl Groan. Have to do things this way so that autoheader can do its thing....
|
||||
AC_DEFINE_UNQUOTED(SIZEOF_U_INT8_T, [$size_u_int8_t], [size of u_int8_t])
|
||||
AC_DEFINE_UNQUOTED(SIZEOF_U_INT16_T, [$size_u_int16_t], [size of u_int16_t])
|
||||
AC_DEFINE_UNQUOTED(SIZEOF_U_INT32_T, [$size_u_int32_t], [size of u_int32_t])
|
||||
|
||||
dnl If we already have these types, don't piss about any more....
|
||||
if test $size_u_int8_t != 1 -o $size_u_int16_t != 2 -o $size_u_int32_t != 4 ; then
|
||||
do_int_types=1
|
||||
AC_CHECK_HEADERS(
|
||||
[stdint.h dnl C99
|
||||
sys/inttypes.h], dnl Solaris
|
||||
[do_int_types=0; break])
|
||||
|
||||
if test $do_int_types = 1 ; then
|
||||
dnl No C99 int types, so figure them out from basic types.
|
||||
AC_CHECK_SIZEOF(unsigned short int)
|
||||
AC_CHECK_SIZEOF(unsigned int)
|
||||
AC_CHECK_SIZEOF(unsigned long int)
|
||||
else
|
||||
dnl Just use the C99 ones.
|
||||
AC_DEFINE(HAVE_C99_INTS, 1, [C99 fixed-width int types available])
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl
|
||||
dnl Name resolution.
|
||||
dnl
|
||||
dnl This is complicated because we need some sort of reentrant mechanism for
|
||||
dnl name resolution. Naturally, UNIX vendors have come up with a variety of
|
||||
dnl incompatible schemes for this, many of which don't work at all.
|
||||
dnl
|
||||
|
||||
dnl First, the default resolver, which uses getnameinfo or gethostbyaddr_r. If
|
||||
dnl not available, we fall back to gethostbyaddr. We could fall back to ARES,
|
||||
dnl but that's probably not available on typical machines.
|
||||
if test x$resolver = xnetdb ; then
|
||||
dnl Best possibility is getnameinfo.
|
||||
use_getnameinfo=0
|
||||
AC_SEARCH_LIBS(getnameinfo, [-lnsl], [use_getnameinfo=1])
|
||||
|
||||
dnl XXX For the moment, don't use getnameinfo, since it isn't actually
|
||||
dnl thread safe on, e.g., NetBSD.
|
||||
use_getnameinfo=0
|
||||
|
||||
if test $use_getnameinfo = 1 ; then
|
||||
dnl Done.
|
||||
AC_DEFINE(USE_GETNAMEINFO, 1, [use getnameinfo for name resolution])
|
||||
else
|
||||
dnl Now see if we can use gethostbyaddr_r.
|
||||
AC_SEARCH_LIBS(gethostbyaddr_r, [-lnsl], , [resolver=netdb_1thread])
|
||||
|
||||
dnl Still want gethostbyaddr_r....
|
||||
if test x$resolver = xnetdb ; then
|
||||
dnl Figure out whether we have glibc-style or Solaris-style
|
||||
dnl gethostbyaddr_r (or neither...).
|
||||
AC_MSG_CHECKING([how to call gethostbyaddr_r]);
|
||||
|
||||
AC_TRY_RUN([`cat config/int_ghba_r.c`], [
|
||||
dnl 8-arg, int
|
||||
AC_MSG_RESULT([8 args, int return])
|
||||
AC_DEFINE(GETHOSTBYADDR_R_RETURNS_INT, 1,
|
||||
[8-argument gethostbyaddr_r returns int])
|
||||
], [
|
||||
AC_TRY_RUN([`cat config/hostentp_ghba_r.c`], [
|
||||
dnl 7-arg, struct hostent*
|
||||
AC_MSG_RESULT([7 args, struct hostent* return])
|
||||
AC_DEFINE(GETHOSTBYADDR_R_RETURNS_HOSTENT_P, 1,
|
||||
[7-argument gethostbyaddr_r returns struct hostent*])
|
||||
], [
|
||||
dnl neither
|
||||
AC_MSG_RESULT([no idea; dropping back to gethostbyaddr])
|
||||
resolver=netdb_1thread
|
||||
])
|
||||
])
|
||||
|
||||
dnl Found a gethostbyaddr_r we know how to use and which seems to
|
||||
dnl work.
|
||||
if test x$resolver = xnetdb ; then
|
||||
AC_DEFINE(USE_GETHOSTBYADDR_R, 1, [use gethostbyaddr_r for name resolution])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl If we've been told to use ARES, then see if it's available. If it isn't,
|
||||
dnl fall back to gethostbyaddr, since we can probably assume that if the
|
||||
dnl machine had a working gethostbyaddr_r, the user wouldn't be pissing about
|
||||
dnl with ARES.
|
||||
if test x$resolver = xares ; then
|
||||
dnl See if ares is to hand....
|
||||
AC_SEARCH_LIBS(ares_init, [-lares], [
|
||||
AC_DEFINE(USE_ARES, 1, [use ARES for name resolution])
|
||||
], [
|
||||
dnl no ares
|
||||
AC_MSG_RESULT([can't find ARES; dropping back to gethostbyaddr])
|
||||
resolver=netdb_1thread])
|
||||
fi
|
||||
|
||||
|
||||
dnl Ugh. gethostbyaddr.
|
||||
if test x$resolver = xnetdb_1thread ; then
|
||||
AC_SEARCH_LIBS(gethostbyaddr, [-lnsl], , [
|
||||
AC_MSG_ERROR([not even gethostbyaddr is available
|
||||
What sort of UNIX system is this, anyway?])
|
||||
]
|
||||
)
|
||||
|
||||
dnl Oh dear, just use gethostbyaddr; but whine about it
|
||||
AC_MSG_WARN([using single-threaded resolver with gethostbyaddr
|
||||
Consider obtaining ARES or a machine with a working gethostbyaddr_r.])
|
||||
|
||||
AC_DEFINE(USE_GETHOSTBYADDR, 1, [use gethostbyaddr for name resolution])
|
||||
fi
|
||||
|
||||
dnl Otherwise, no resolver at all. Boo hoo.
|
||||
|
||||
|
||||
dnl
|
||||
dnl Ensure that the machine even has libpcap. We do this late, because libpcap
|
||||
dnl calls netdb functions that might need libraries on some systems....
|
||||
dnl
|
||||
|
||||
AC_CHECK_LIB(pcap, pcap_open_live, , [
|
||||
AC_MSG_ERROR([can't find libpcap
|
||||
You're not going to get very far without libpcap.])
|
||||
])
|
||||
|
||||
foundpcap=0
|
||||
AC_CHECK_HEADERS([pcap.h pcap/pcap.h], [
|
||||
foundpcap=1
|
||||
break
|
||||
])
|
||||
|
||||
if test $foundpcap = 0 ; then
|
||||
AC_MSG_ERROR([can't find pcap.h
|
||||
You're not going to get very far without libpcap.])
|
||||
fi
|
||||
|
||||
dnl
|
||||
dnl Curses. Really, we need ncurses or something similarly advanced, since
|
||||
dnl we use the (apparently obscure) mvchgat function. Unfortunately, there's
|
||||
dnl a solid chance that mvchgat is a macro, so we can't just use
|
||||
dnl AC_SEARCH_LIBS....
|
||||
dnl
|
||||
|
||||
AC_MSG_CHECKING([for a curses library containing mvchgat])
|
||||
oldLIBS=$LIBS
|
||||
for curseslib in curses ncurses ; do
|
||||
LIBS="$oldLIBS -l$curseslib"
|
||||
AC_TRY_LINK([
|
||||
#include <curses.h>
|
||||
], [
|
||||
mvchgat(0, 0, 1, A_REVERSE, 0, NULL)
|
||||
], [
|
||||
foundcurseslib=$curseslib
|
||||
break
|
||||
])
|
||||
done
|
||||
|
||||
if test x$foundcurseslib = x ; then
|
||||
AC_MSG_RESULT([none found])
|
||||
AC_MSG_ERROR([Curses! Foiled again!
|
||||
(Can't find a curses library supporting mvchgat.)
|
||||
Consider installing ncurses.])
|
||||
else
|
||||
AC_MSG_RESULT([-l$foundcurseslib])
|
||||
fi
|
||||
|
||||
|
||||
dnl
|
||||
dnl POSIX threads. Different systems like different combinations of flags,
|
||||
dnl libraries, etc. We use a test program to figure this stuff out.
|
||||
dnl
|
||||
|
||||
AC_MSG_CHECKING([how to compile a working program with POSIX threads])
|
||||
thrfail=1
|
||||
oldCFLAGS=$CFLAGS
|
||||
oldLIBS=$LIBS
|
||||
for flag in "" -mt -pthread -thread ; do
|
||||
CFLAGS="$oldCFLAGS $flag"
|
||||
for lib in "" -lpthread "-lpthread -lposix4" ; do
|
||||
LIBS="$oldLIBS $lib"
|
||||
AC_TRY_RUN([`cat config/pthread.c`], [
|
||||
foundthrlib=$lib
|
||||
foundthrflag=$flag
|
||||
thrfail=0
|
||||
break
|
||||
])
|
||||
done
|
||||
if test $thrfail = 0 ; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if test $thrfail = 1 ; then
|
||||
AC_MSG_RESULT([no idea])
|
||||
AC_MSG_ERROR([can't figure out how to compile with POSIX threads
|
||||
If your system actually supports POSIX threads, this means we've messed up.])
|
||||
else
|
||||
AC_MSG_RESULT([$foundthrflag $foundthrlib])
|
||||
fi
|
||||
|
||||
dnl
|
||||
dnl Wahey! This might even work.
|
||||
dnl
|
||||
|
||||
|
||||
AC_SUBST(ac_aux_dir)
|
||||
|
||||
AC_OUTPUT(Makefile config/Makefile)
|
||||
|
||||
4
edline.c
4
edline.c
@@ -88,9 +88,9 @@ char *edline(int linenum, const char *prompt, const char *initial) {
|
||||
|
||||
case 23: /* ^W */
|
||||
for (i = pos; i > 0; --i)
|
||||
if (!isspace(str[i])) break;
|
||||
if (!isspace((int)str[i])) break;
|
||||
for (; i > 0; --i)
|
||||
if (isspace(str[i])) break;
|
||||
if (isspace((int)str[i])) break;
|
||||
if (i != pos) {
|
||||
memmove(str + i, str + pos, strlen(str + pos) + 1);
|
||||
pos = i;
|
||||
|
||||
10
iftop.c
10
iftop.c
@@ -3,7 +3,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "integers.h"
|
||||
|
||||
#if defined(HAVE_PCAP_H)
|
||||
# include <pcap.h>
|
||||
#elif defined(HAVE_PCAP_PCAP_H)
|
||||
# include <pcap/pcap.h>
|
||||
#else
|
||||
# error No pcap.h
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
@@ -464,7 +472,7 @@ void packet_init() {
|
||||
/* packet_loop:
|
||||
* Worker function for packet capture thread. */
|
||||
void packet_loop(void* ptr) {
|
||||
pcap_loop(pd,0,(pcap_handler)packet_handler,NULL);
|
||||
pcap_loop(pd,-1,(pcap_handler)packet_handler,NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
8
iftop.h
8
iftop.h
@@ -6,6 +6,8 @@
|
||||
#ifndef __IFTOP_H_ /* include guard */
|
||||
#define __IFTOP_H_
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/* 60 / 3 */
|
||||
#define HISTORY_LENGTH 20
|
||||
#define RESOLUTION 2
|
||||
@@ -34,11 +36,13 @@ void ui_init(void);
|
||||
void options_read(int argc, char **argv);
|
||||
|
||||
|
||||
/* Make use of SIOCGIFHWADDR work on FreeBSD */
|
||||
/* Make use of SIOCGIFHWADDR work on FreeBSD and Solaris. */
|
||||
#ifndef SIOCGIFHWADDR
|
||||
# ifdef HAVE_SYS_SOCKIO_H
|
||||
# include <sys/sockio.h> /* Solaris and others?? */
|
||||
# endif
|
||||
# define SIOCGIFHWADDR SIOCGIFADDR
|
||||
# define ifr_hwaddr ifr_addr
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __IFTOP_H_ */
|
||||
|
||||
81
integers.h
Normal file
81
integers.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* integers.h:
|
||||
* This header file ensures that we have u_int<n>_t types of the proper width,
|
||||
* using a rather convoluted set of conditionals generated by configure. This
|
||||
* is an almighty pain in the arse, and is completely irrelevant on most
|
||||
* systems which already define this stuff.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __INTEGERS_H_ /* include guard */
|
||||
#define __INTEGERS_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "config.h"
|
||||
|
||||
#if SIZEOF_U_INT8_T != 1 || SIZEOF_U_INT16_T != 2 || SIZEOF_U_INT32_T != 4
|
||||
|
||||
# if defined(HAVE_C99_INTS)
|
||||
|
||||
/*
|
||||
* Use the C99 standard-width integers, defined in some appropriate
|
||||
* header file.
|
||||
*/
|
||||
|
||||
# if defined(HAVE_STDINT_H)
|
||||
# include <stdint.h>
|
||||
# elif defined(HAVE_SYS_INTTYPES_H)
|
||||
# include <sys/inttypes.h>
|
||||
# endif
|
||||
|
||||
/* Don't replace existing u_int<n>_t types. */
|
||||
# if SIZEOF_U_INT8_T != 1
|
||||
typedef uint8_t u_int8_t;
|
||||
# endif
|
||||
|
||||
# if SIZEOF_U_INT16_T != 2
|
||||
typedef uint16_t u_int16_t;
|
||||
# endif
|
||||
|
||||
# if SIZEOF_U_INT32_T != 4
|
||||
typedef uint32_t u_int32_t;
|
||||
# endif
|
||||
|
||||
# elif (SIZEOF_UNSIGNED_SHORT_INT == 2 || SIZEOF_UNSIGNED_INT == 2) \
|
||||
&& (SIZEOF_UNSIGNED_INT == 4 || SIZEOF_UNSIGNED_LONG_INT == 4)
|
||||
|
||||
/*
|
||||
* Use an appropriately-sized basic type.
|
||||
*/
|
||||
|
||||
# if SIZEOF_U_INT8_T != 1
|
||||
typedef unsigned char u_int8_t; /* By definition. */
|
||||
# endif
|
||||
|
||||
# if SIZEOF_U_INT16_T != 2
|
||||
# if SIZEOF_UNSIGNED_SHORT_INT == 2
|
||||
typedef unsigned short int u_int16_t;
|
||||
# elif SIZEOF_UNSIGNED_INT == 2
|
||||
typedef unsigned int u_int16_t; /* Not likely. */
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if SIZEOF_U_INT32_T != 4
|
||||
# if SIZEOF_UNSIGNED_INT == 4
|
||||
typedef unsigned int u_int32_t;
|
||||
# elif SIZEOF_UNSIGNED_LONG_INT == 4
|
||||
typedef unsigned long int u_int32_t;
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* Whew. */
|
||||
|
||||
# else
|
||||
# error "Your C compiler seems to lack 16 and 32 bit unsigned integer types"
|
||||
# endif
|
||||
|
||||
#endif /* No existing u_int<n>_t types. */
|
||||
|
||||
#endif /* __INTEGERS_H_ */
|
||||
@@ -4,6 +4,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@@ -11,11 +13,17 @@
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#include "iftop.h"
|
||||
#include "options.h"
|
||||
|
||||
#if !defined(HAVE_INET_ATON) && defined(HAVE_INET_PTON)
|
||||
# define inet_aton(a, b) inet_pton(AF_INET, (a), (b))
|
||||
#endif
|
||||
|
||||
options_t options;
|
||||
|
||||
char optstr[] = "+i:f:nN:hpbBP";
|
||||
|
||||
47
resolver.c
47
resolver.c
@@ -35,13 +35,37 @@ int tail;
|
||||
|
||||
|
||||
/*
|
||||
* We have a choice of resolver methods. Real computers have gethostbyaddr_r,
|
||||
* which is reentrant and therefore thread safe. Other machines don't, and so
|
||||
* we can use non-reentrant gethostbyaddr and have only one resolver thread.
|
||||
* Alternatively, we can use the MIT ares asynchronous DNS library to do this.
|
||||
* We have a choice of resolver methods. Real computers have getnameinfo or
|
||||
* gethostbyaddr_r, which are reentrant and therefore thread safe. Other
|
||||
* machines don't, and so we can use non-reentrant gethostbyaddr and have only
|
||||
* one resolver thread. Alternatively, we can use the MIT ares asynchronous
|
||||
* DNS library to do this.
|
||||
*/
|
||||
|
||||
#if defined(USE_GETHOSTBYADDR_R)
|
||||
#if defined(USE_GETNAMEINFO)
|
||||
/**
|
||||
* Implementation of do_resolve for platforms with getaddrinfo.
|
||||
*
|
||||
* This is a fairly sane function with a uniform interface which is even --
|
||||
* shock! -- standardised by POSIX and in RFC 2553. Unfortunately systems such
|
||||
* as NetBSD break the RFC and implement it in a non-thread-safe fashion, so
|
||||
* for the moment, the configure script won't try to use it.
|
||||
*/
|
||||
char *do_resolve(struct in_addr *addr) {
|
||||
struct sockaddr_in sin = {0};
|
||||
char buf[NI_MAXHOST]; /* 1025 */
|
||||
int res;
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_addr = *addr;
|
||||
sin.sin_port = 0;
|
||||
|
||||
if (getnameinfo((struct sockaddr*)&sin, sizeof sin, buf, sizeof buf, NULL, 0, NI_NAMEREQD) == 0)
|
||||
return xstrdup(buf);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#elif defined(USE_GETHOSTBYADDR_R)
|
||||
/**
|
||||
* Implementation of do_resolve for platforms with working gethostbyaddr_r
|
||||
*
|
||||
@@ -59,9 +83,20 @@ char* do_resolve(struct in_addr * addr) {
|
||||
/* Allocate buffer, remember to free it to avoid memory leakage. */
|
||||
tmphstbuf = xmalloc (hstbuflen);
|
||||
|
||||
/* Some machines have gethostbyaddr_r returning an integer error code; on
|
||||
* others, it returns a struct hostent*. */
|
||||
#ifdef GETHOSTBYADDR_R_RETURNS_INT
|
||||
while ((res = gethostbyaddr_r((char*)addr, sizeof(struct in_addr), AF_INET,
|
||||
&hostbuf, tmphstbuf, hstbuflen,
|
||||
&hp, &herr)) == ERANGE) {
|
||||
&hp, &herr)) == ERANGE)
|
||||
#else
|
||||
/* ... also assume one fewer argument.... */
|
||||
while ((hp = gethostbyaddr_r((char*)addr, sizeof(struct in_addr), AF_INET,
|
||||
&hostbuf, tmphstbuf, hstbuflen, &herr)) == NULL
|
||||
&& errno == ERANGE)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Enlarge the buffer. */
|
||||
hstbuflen *= 2;
|
||||
tmphstbuf = realloc (tmphstbuf, hstbuflen);
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_REGCOMP
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <regex.h>
|
||||
#include <stdio.h>
|
||||
@@ -54,3 +58,4 @@ int screen_filter_match(char *s) {
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAVE_REGCOMP */
|
||||
|
||||
@@ -10,7 +10,13 @@
|
||||
#ifndef __SCREENFILTER_H_ /* include guard */
|
||||
#define __SCREENFILTER_H_
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_REGCOMP
|
||||
|
||||
int screen_filter_set(char* s);
|
||||
int screen_filter_match(char* s);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __SCREENFILTER_H_ */
|
||||
|
||||
12
ui.c
12
ui.c
@@ -3,6 +3,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <curses.h>
|
||||
#include <errno.h>
|
||||
@@ -591,8 +593,10 @@ void ui_print() {
|
||||
|
||||
|
||||
if(showhelphint) {
|
||||
mvaddstr(0, 0, helpmsg);
|
||||
mvchgat(0, 0, strlen(helpmsg), A_REVERSE, 0, NULL);
|
||||
mvaddstr(0, 0, " ");
|
||||
mvaddstr(0, 1, helpmsg);
|
||||
mvaddstr(0, 1 + strlen(helpmsg), " ");
|
||||
mvchgat(0, 0, strlen(helpmsg) + 2, A_REVERSE, 0, NULL);
|
||||
}
|
||||
move(LINES - 1, COLS - 1);
|
||||
|
||||
@@ -855,6 +859,7 @@ void ui_loop() {
|
||||
break;
|
||||
}
|
||||
case 'l': {
|
||||
#ifdef HAVE_REGCOMP
|
||||
char *s;
|
||||
dontshowdisplay = 1;
|
||||
if ((s = edline(0, "Screen filter", options.screenfilter))) {
|
||||
@@ -864,6 +869,9 @@ void ui_loop() {
|
||||
}
|
||||
dontshowdisplay = 0;
|
||||
ui_print();
|
||||
#else
|
||||
showhelp("Sorry, screen filters not supported on this platform")
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case '!': {
|
||||
|
||||
Reference in New Issue
Block a user