Commit 83c17335 by chris

""

1 parent 09e55647
......@@ -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
......
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
......@@ -40,6 +45,12 @@ CFLAGS += -DUSE_GETHOSTBYADDR_R
#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.
#
#LDLIBS += -lresolv # or /usr/lib/libresolv.a on Linux?
......@@ -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
......
#
# 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@
......@@ -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
......@@ -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
......
#!/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
#
# 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)
/*
* 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;
}
/*
* 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;
}
/*
* 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;
}
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)
......@@ -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;
......
......@@ -3,7 +3,15 @@
*
*/
#include <pcap.h>
#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>
......@@ -340,9 +348,9 @@ static void handle_eth_packet(unsigned char* args, const struct pcap_pkthdr* pkt
{
struct ether_header *eptr;
eptr = (struct ether_header*)packet;
tick(0);
if(ntohs(eptr->ether_type) == ETHERTYPE_IP) {
struct ip* iptr;
int dir = -1;
......@@ -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);
}
......
......@@ -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
#define SIOCGIFHWADDR SIOCGIFADDR
#define ifr_hwaddr ifr_addr
# 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_ */
/*
* 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";
......
......@@ -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);
while ((res = gethostbyaddr_r ((char*)addr, sizeof(struct in_addr), AF_INET,
&hostbuf, tmphstbuf, hstbuflen,
&hp, &herr)) == ERANGE) {
/* 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)
#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_ */
......@@ -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 '!': {
......