Solaris/autoconf patch from Jonathan Abbey <jonabbey@ganymeta.org>
This commit is contained in:
10
AUTHORS
Normal file
10
AUTHORS
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Another file that automake insists on.
|
||||||
|
|
||||||
|
Written by
|
||||||
|
|
||||||
|
Paul Warren, pdw@ex-parrot.com
|
||||||
|
Chris Lightfoot, chris@ex-parrot.com
|
||||||
|
|
||||||
|
Mangled for Solaris by
|
||||||
|
|
||||||
|
Jonathan Abbey, jonabbey@ganymeta.org
|
||||||
120
CHANGES
120
CHANGES
@@ -1,89 +1,109 @@
|
|||||||
Change log for iftop
|
Change log for iftop
|
||||||
$Id$
|
$Id$
|
||||||
|
|
||||||
|
0.13
|
||||||
|
|
||||||
|
* Fixed configure.in to properly specify libraries without the leading -l
|
||||||
|
* Separated the IP/ethernet identifying routine from iftop.c into addrs_ioctl.c
|
||||||
|
* Added addrs_dlpi.c, dlcommon.c, dlcommon.h to support the STREAMS DataLink
|
||||||
|
Programming Interface on Solaris
|
||||||
|
* Hacked options.h, options.c, iftop.c to enable promiscuous_but_choosy mode
|
||||||
|
which runs the interface in promiscuous mode but filters out non-broadcast
|
||||||
|
packets not addressed to or from the interface
|
||||||
|
* Added NEWS, AUTHORS, ChangeLog
|
||||||
|
* Improved interface auto-detect logic in iftop.c
|
||||||
|
* Fixed configure.in to not overload prefix in the pcap test section
|
||||||
|
Jonathan Abbey <jonabbey@ganymeta.org>
|
||||||
|
|
||||||
0.12 21/05/03
|
0.12 21/05/03
|
||||||
|
|
||||||
Added 1-line display options ("t")
|
* Added 1-line display options ("t")
|
||||||
Added display scrolling ("j", "k")
|
* Added display scrolling ("j", "k")
|
||||||
Fixed code for obtaining hardware address (on Linux at least)
|
* Fixed code for obtaining hardware address (on Linux at least)
|
||||||
Added IP-based direction assignment
|
* Added IP-based direction assignment
|
||||||
|
|
||||||
0.11 08/01/03
|
0.11 08/01/03
|
||||||
|
|
||||||
Added support for token ring networks
|
* Added support for token ring networks
|
||||||
Token ring network direction determination
|
* Token ring network direction determination
|
||||||
Martin Garton <Martin.Garton@DCSTRANS.COM>
|
Martin Garton <Martin.Garton@DCSTRANS.COM>
|
||||||
Added autoconf/automake build system
|
|
||||||
Improved network interface auto selection
|
* Added autoconf/automake build system
|
||||||
|
* Improved network interface auto selection
|
||||||
|
|
||||||
0.10 29/10/02
|
0.10 29/10/02
|
||||||
|
|
||||||
User selectable sort criteria
|
* User selectable sort criteria
|
||||||
On-the-fly filter code changes
|
* On-the-fly filter code changes
|
||||||
Shell escape
|
* Shell escape
|
||||||
Alternative resolver back-ends
|
* Alternative resolver back-ends
|
||||||
Improved totals display
|
* Improved totals display
|
||||||
Added regexp based screen filtering
|
* Added regexp based screen filtering
|
||||||
Fixed pause functionality
|
* Fixed pause functionality
|
||||||
Change option names to be more like tcpdump
|
* Change option names to be more like tcpdump
|
||||||
|
|
||||||
0.9 22/10/02
|
0.9 22/10/02
|
||||||
|
|
||||||
Now works on FreeBSD
|
* Now works on FreeBSD
|
||||||
Added service resolution toggle ("R")
|
* Added service resolution toggle ("R")
|
||||||
Added on-line help ("h")
|
* Added on-line help ("h")
|
||||||
More fixes to rate display
|
* More fixes to rate display
|
||||||
Improved interface selection (excludes lo:* and vmnet*)
|
* Improved interface selection (excludes lo:* and vmnet*)
|
||||||
Added bandwidth-in-bytes option.
|
* Added bandwidth-in-bytes option.
|
||||||
|
|
||||||
0.8 17/10/02
|
0.8 17/10/02
|
||||||
|
|
||||||
Added support for displaying port numbers
|
* Added support for displaying port numbers
|
||||||
Minor fixes to rate display
|
* Minor fixes to rate display
|
||||||
Minor fix to netmask handling (specifying /32 was broken)
|
* Minor fix to netmask handling (specifying /32 was broken)
|
||||||
Updated RPM spec file
|
|
||||||
Iain Lea <iain@bricbrac.de>
|
* Updated RPM spec file
|
||||||
Added pause functionality (P)
|
Iain Lea <iain@bricbrac.de>
|
||||||
Changed behaviour of source/dest traffic aggregation
|
|
||||||
|
* Added pause functionality (P)
|
||||||
|
* Changed behaviour of source/dest traffic aggregation
|
||||||
|
|
||||||
0.7 02/10/02
|
0.7 02/10/02
|
||||||
|
|
||||||
Fixed missing sll.h file.
|
* Fixed missing sll.h file.
|
||||||
|
|
||||||
0.6 28/08/02
|
0.6 28/08/02
|
||||||
|
|
||||||
Fixed segfault bug affecting some systems
|
* Fixed segfault bug affecting some systems
|
||||||
Added support for Linux cooked sockets
|
|
||||||
Michael Bergbauer <michael@noname.franken.de>
|
* Added support for Linux cooked sockets
|
||||||
|
Michael Bergbauer <michael@noname.franken.de>
|
||||||
|
|
||||||
0.5 26/08/02
|
0.5 26/08/02
|
||||||
|
|
||||||
Added support for monitoring PPP interfaces
|
* Added support for monitoring PPP interfaces
|
||||||
Converted longs to double longs in various places to avoid overflow problems
|
* Converted longs to double longs in various places to avoid overflow problems
|
||||||
Minor bug fixes (usage messages, exit on error)
|
* Minor bug fixes (usage messages, exit on error)
|
||||||
Improved selection of default interface when none specified
|
* Improved selection of default interface when none specified
|
||||||
|
|
||||||
0.4 16/04/02
|
0.4 16/04/02
|
||||||
|
|
||||||
No code changes
|
* No code changes
|
||||||
Added RPM spec file
|
|
||||||
Riku Meskanen <mesrik@cc.jyu.fi>
|
* Added RPM spec file
|
||||||
Fixes to "make install"
|
Riku Meskanen <mesrik@cc.jyu.fi>
|
||||||
Steve Baker <sjb@ambrielconsulting.com>
|
|
||||||
|
* Fixes to "make install"
|
||||||
|
Steve Baker <sjb@ambrielconsulting.com>
|
||||||
|
|
||||||
0.3 13/04/02
|
0.3 13/04/02
|
||||||
|
|
||||||
Fixed segfault bug.
|
* Fixed segfault bug.
|
||||||
Added src/dest aggregation.
|
* Added src/dest aggregation.
|
||||||
|
|
||||||
0.2 02/04/02
|
0.2 02/04/02
|
||||||
|
|
||||||
Added -n option to analyse traffic flows across a network boundary.
|
* Added -n option to analyse traffic flows across a network boundary.
|
||||||
Added cumulative traffic totals.
|
* Added cumulative traffic totals.
|
||||||
Graphs now optional.
|
* Graphs now optional.
|
||||||
UI more responsive to key presses.
|
* UI more responsive to key presses.
|
||||||
Auto-sizing bar graph scale.
|
* Auto-sizing bar graph scale.
|
||||||
|
|
||||||
0.1 29/3/02
|
0.1 29/3/02
|
||||||
|
|
||||||
First release.
|
* First release.
|
||||||
|
|||||||
7
COPYING
7
COPYING
@@ -1,9 +1,8 @@
|
|||||||
|
|
||||||
GNU GENERAL PUBLIC LICENSE
|
GNU GENERAL PUBLIC LICENSE
|
||||||
Version 2, June 1991
|
Version 2, June 1991
|
||||||
|
|
||||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
of this license document, but changing it is not allowed.
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
@@ -292,7 +291,7 @@ convey the exclusion of warranty; and each file should have at least
|
|||||||
the "copyright" line and a pointer to where the full notice is found.
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
Copyright (C) 19yy <name of author>
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -314,7 +313,7 @@ Also add information on how to contact you by electronic and paper mail.
|
|||||||
If the program is interactive, make it output a short notice like this
|
If the program is interactive, make it output a short notice like this
|
||||||
when it starts in an interactive mode:
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
This is free software, and you are welcome to redistribute it
|
This is free software, and you are welcome to redistribute it
|
||||||
under certain conditions; type `show c' for details.
|
under certain conditions; type `show c' for details.
|
||||||
|
|||||||
10
ChangeLog
Normal file
10
ChangeLog
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
2003-06-04 Jonathan Abbey <jonabbey@ganymeta.org>
|
||||||
|
* Fixed configure.in to properly specify libraries without the leading -l
|
||||||
|
* Separated the IP/ethernet identifying routine from iftop.c into addrs_ioctl.c
|
||||||
|
* Added addrs_dlpi.c, dlcommon.c, dlcommon.h to support the STREAMS DataLink Programming Interface on Solaris
|
||||||
|
* Hacked options.h, options.c, iftop.c to enable promiscuous_but_choosy mode which runs
|
||||||
|
the interface in promiscuous mode but filters out non-broadcast packets not addressed to or from the interface
|
||||||
|
* Added NEWS, AUTHORS, ChangeLog
|
||||||
|
* Improved interface auto-detect logic in iftop.c
|
||||||
|
* Fixed configure.in to not overload prefix in the pcap test section
|
||||||
|
|
||||||
@@ -14,12 +14,13 @@ sbin_PROGRAMS = iftop
|
|||||||
|
|
||||||
iftop_SOURCES = addr_hash.c edline.c hash.c iftop.c ns_hash.c \
|
iftop_SOURCES = addr_hash.c edline.c hash.c iftop.c ns_hash.c \
|
||||||
options.c resolver.c screenfilter.c serv_hash.c \
|
options.c resolver.c screenfilter.c serv_hash.c \
|
||||||
sorted_list.c threadprof.c ui.c util.c
|
sorted_list.c threadprof.c ui.c util.c \
|
||||||
|
addrs_ioctl.c addrs_dlpi.c dlcommon.c
|
||||||
|
|
||||||
noinst_HEADERS = addr_hash.h ether.h ethertype.h extract.h hash.h iftop.h \
|
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 \
|
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 \
|
screenfilter.h serv_hash.h sll.h sorted_list.h tcp.h \
|
||||||
threadprof.h token.h ui.h
|
threadprof.h token.h ui.h dlcommon.h
|
||||||
|
|
||||||
man_MANS = iftop.8
|
man_MANS = iftop.8
|
||||||
|
|
||||||
@@ -30,8 +31,8 @@ iftop.cat: iftop.8
|
|||||||
|
|
||||||
## These need to be distributed along with configure:
|
## These need to be distributed along with configure:
|
||||||
|
|
||||||
EXTRA_DIST = bootstrap README CHANGES COPYING INSTALL TODO Makefile.OLD \
|
EXTRA_DIST = bootstrap README ChangeLog AUTHORS COPYING INSTALL TODO \
|
||||||
$(man_MANS) iftop.cat
|
Makefile.OLD $(man_MANS) iftop.cat
|
||||||
|
|
||||||
MAINTERCLEANFILES = Makefile.in aclocal.m4 configure configuration.h.in \
|
MAINTERCLEANFILES = Makefile.in aclocal.m4 configure configuration.h.in \
|
||||||
stamp-h.in
|
stamp-h.in
|
||||||
|
|||||||
3
NEWS
Normal file
3
NEWS
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Hm, automake insists on there being a NEWS file in place.
|
||||||
|
|
||||||
|
So, here's one, for the time being.
|
||||||
15
README
15
README
@@ -26,10 +26,17 @@ option to configure.
|
|||||||
|
|
||||||
Solaris:
|
Solaris:
|
||||||
|
|
||||||
On Solaris, libpcap does not capture outgoing packets unless it is run on an
|
On Solaris, iftop has to run in promiscuous mode in order to capture
|
||||||
interface in promiscuous mode. Therefore, you will need to use the -p option
|
outgoing packets. iftop autoconfigures to run in promiscuous mode on
|
||||||
to iftop to get sensible results. Cf.
|
Solaris, but will filter out non-broadcast packets which are not
|
||||||
http://www.tcpdump.org/lists/workers/2002/02/msg00010.html
|
addressed to or from localhost. On Solaris, the -p option merely
|
||||||
|
disables that filter.
|
||||||
|
|
||||||
|
If you have some other sort of system that behaves like Solaris in
|
||||||
|
needing promiscuous mode, you can pass --enable-default-promiscuous to
|
||||||
|
configure to enable this behavior.
|
||||||
|
|
||||||
|
Cf. http://www.tcpdump.org/lists/workers/2002/02/msg00010.html
|
||||||
|
|
||||||
The version of curses distributed with Solaris may not be sufficient for
|
The version of curses distributed with Solaris may not be sufficient for
|
||||||
iftop's needs. You will probably need ncurses or similar.
|
iftop's needs. You will probably need ncurses or similar.
|
||||||
|
|||||||
395
addrs_dlpi.c
Normal file
395
addrs_dlpi.c
Normal file
@@ -0,0 +1,395 @@
|
|||||||
|
/*
|
||||||
|
* addrs_dlpi.c:
|
||||||
|
*
|
||||||
|
* Provides the get_addrs_dlpi() function for use on systems that require
|
||||||
|
* the use of the System V STREAMS DataLink Programming Interface for
|
||||||
|
* acquiring low-level ethernet information about interfaces.
|
||||||
|
*
|
||||||
|
* Like Solaris.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_DLPI
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/sockio.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/dlpi.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
|
||||||
|
#include "dlcommon.h"
|
||||||
|
|
||||||
|
extern char *split_dname(char *device, int *unitp);
|
||||||
|
extern char *strncpy2(char *dest, char *src, int n);
|
||||||
|
extern char *strncat2(char *dest, char *src, int n);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function identifies the IP address and ethernet address for the interface
|
||||||
|
* specified
|
||||||
|
*
|
||||||
|
* This function returns -1 on catastrophic failure, or a bitwise OR of the
|
||||||
|
* following values:
|
||||||
|
*
|
||||||
|
* 1 - Was able to get the ethernet address
|
||||||
|
* 2 - Was able to get the IP address
|
||||||
|
*
|
||||||
|
* This function should return 3 if all information was found
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
get_addrs_dlpi(char *interface, char if_hw_addr[], struct in_addr *if_ip_addr)
|
||||||
|
{
|
||||||
|
int got_hw_addr = 0;
|
||||||
|
int got_ip_addr = 0;
|
||||||
|
|
||||||
|
int fd;
|
||||||
|
long buf[MAXDLBUF]; /* long aligned */
|
||||||
|
union DL_primitives *dlp;
|
||||||
|
|
||||||
|
char *cp;
|
||||||
|
int unit_num = 0;
|
||||||
|
int sap = 0;
|
||||||
|
|
||||||
|
char *devname = NULL;
|
||||||
|
char *devname2 = NULL;
|
||||||
|
char fulldevpath[256];
|
||||||
|
|
||||||
|
struct ifreq ifr = {};
|
||||||
|
|
||||||
|
/* -- */
|
||||||
|
|
||||||
|
memset(if_hw_addr, 0, 6);
|
||||||
|
|
||||||
|
// we want to be able to process either a fully qualified /dev/ge0
|
||||||
|
// type interface definition, or just ge0.
|
||||||
|
|
||||||
|
if (strncmp(interface, "/dev/", strlen("/dev/")) == 0) {
|
||||||
|
devname = interface + strlen("/dev/");
|
||||||
|
} else {
|
||||||
|
devname = interface;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy2(fulldevpath, "/dev/", sizeof(fulldevpath)-1);
|
||||||
|
cp = strncat2(fulldevpath, interface, sizeof(fulldevpath));
|
||||||
|
|
||||||
|
if (strlen(cp) != 0) {
|
||||||
|
fprintf(stderr, "device name buffer overflow %s\n", fulldevpath);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr,"if: %s\n", devname);
|
||||||
|
|
||||||
|
// on Solaris, even though we are wanting to talk to ethernet device
|
||||||
|
// ge0, we have to open /dev/ge, then bind to unit 0. Dupe our
|
||||||
|
// full path, then identify and cut off the unit number
|
||||||
|
|
||||||
|
devname2 = strdup(fulldevpath);
|
||||||
|
|
||||||
|
cp = split_dname(devname2, &unit_num);
|
||||||
|
|
||||||
|
if (cp == NULL) {
|
||||||
|
free(devname2);
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
*cp = '\0'; /* null terminate devname2 right before numeric extension */
|
||||||
|
}
|
||||||
|
|
||||||
|
// devname2 should now be something akin to /dev/ge. Try to open
|
||||||
|
// it, and if it fails, fall back to the full /dev/ge0.
|
||||||
|
|
||||||
|
if ((fd = open(devname2, O_RDWR)) < 0) {
|
||||||
|
if (errno != ENOENT) {
|
||||||
|
fprintf(stderr, "Couldn't open %s\n", devname2);
|
||||||
|
free(devname2);
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
if ((fd = open(fulldevpath, O_RDWR)) < 0) {
|
||||||
|
fprintf(stderr, "Couldn't open %s\n", fulldevpath);
|
||||||
|
free(devname2);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(devname2);
|
||||||
|
devname2 = NULL;
|
||||||
|
|
||||||
|
/* Use the dlcommon functions to get access to the DLPI information for this
|
||||||
|
* interface. All of these functions exit() out on failure
|
||||||
|
*/
|
||||||
|
|
||||||
|
dlp = (union DL_primitives*) buf;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DLPI attach to our low-level device
|
||||||
|
*/
|
||||||
|
|
||||||
|
dlattachreq(fd, unit_num);
|
||||||
|
dlokack(fd, buf);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DLPI bind
|
||||||
|
*/
|
||||||
|
|
||||||
|
dlbindreq(fd, sap, 0, DL_CLDLS, 0, 0);
|
||||||
|
dlbindack(fd, buf);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DLPI DL_INFO_REQ
|
||||||
|
*/
|
||||||
|
|
||||||
|
dlinforeq(fd);
|
||||||
|
dlinfoack(fd, buf);
|
||||||
|
|
||||||
|
/*
|
||||||
|
printdlprim(dlp); // uncomment this to dump out info from DLPI
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (dlp->info_ack.dl_addr_length + dlp->info_ack.dl_sap_length == 6) {
|
||||||
|
memcpy(if_hw_addr,
|
||||||
|
OFFADDR(dlp, dlp->info_ack.dl_addr_offset),
|
||||||
|
dlp->info_ack.dl_addr_length);
|
||||||
|
got_hw_addr = 1;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Error, bad length for hardware interface %s -- %d\n",
|
||||||
|
interface,
|
||||||
|
dlp->info_ack.dl_addr_length);
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
/* Get the IP address of the interface */
|
||||||
|
|
||||||
|
#ifdef SIOCGIFADDR
|
||||||
|
|
||||||
|
fd = socket(PF_INET, SOCK_DGRAM, 0); /* any sort of IP socket will do */
|
||||||
|
|
||||||
|
strncpy(ifr.ifr_name, interface, IFNAMSIZ);
|
||||||
|
|
||||||
|
(*(struct sockaddr_in *) &ifr.ifr_addr).sin_family = AF_INET;
|
||||||
|
|
||||||
|
if (ioctl(fd, SIOCGIFADDR, &ifr) < 0) {
|
||||||
|
fprintf(stderr, "Error getting IP address for interface: %s\n", "ge0");
|
||||||
|
perror("ioctl(SIOCGIFADDR)");
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memcpy(if_ip_addr, &((*(struct sockaddr_in *) &ifr.ifr_addr).sin_addr), sizeof(struct in_addr));
|
||||||
|
got_ip_addr = 2;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
fprintf(stderr, "Cannot obtain IP address on this platform\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
return got_hw_addr + got_ip_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Split a device name into a device type name and a unit number;
|
||||||
|
* return the a pointer to the beginning of the unit number, which
|
||||||
|
* is the end of the device type name, and set "*unitp" to the unit
|
||||||
|
* number.
|
||||||
|
*
|
||||||
|
* Returns NULL on error, and fills "ebuf" with an error message.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
split_dname(char *device, int *unitp)
|
||||||
|
{
|
||||||
|
char *cp;
|
||||||
|
char *eos;
|
||||||
|
int unit;
|
||||||
|
|
||||||
|
/* -- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Look for a number at the end of the device name string.
|
||||||
|
*/
|
||||||
|
|
||||||
|
cp = device + strlen(device) - 1;
|
||||||
|
if (*cp < '0' || *cp > '9') {
|
||||||
|
fprintf(stderr, "%s missing unit number", device);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Digits at end of string are unit number */
|
||||||
|
while (cp-1 >= device && *(cp-1) >= '0' && *(cp-1) <= '9')
|
||||||
|
cp--;
|
||||||
|
|
||||||
|
unit = (int) strtol(cp, &eos, 10);
|
||||||
|
if (*eos != '\0') {
|
||||||
|
fprintf(stderr, "%s bad unit number", device);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
*unitp = unit;
|
||||||
|
return (cp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
strncpy2()
|
||||||
|
|
||||||
|
strncpy2() is like strncpy(), except that strncpy2() will always
|
||||||
|
insure that the <dest> buffer is null terminated. strncpy() will not
|
||||||
|
NULL terminate the destination buffer if the <src> string is <n>
|
||||||
|
characters long or longer, not counting the terminating NULL character.
|
||||||
|
|
||||||
|
STRNCPY2() IS NOT A COMPATIBLE REPLACEMENT FOR STRNCPY()!!
|
||||||
|
|
||||||
|
There are two reasons to use strncpy2().
|
||||||
|
|
||||||
|
The first reason is to guarantee that <dest> buffer's bounds are not
|
||||||
|
violated. In this case, <n> should be the size of the <dest> buffer
|
||||||
|
minus one.
|
||||||
|
|
||||||
|
i.e.,
|
||||||
|
|
||||||
|
char tempstring[MAXLINE];
|
||||||
|
|
||||||
|
strncpy2(tempstring, my_own_string, MAXLINE - 1);
|
||||||
|
|
||||||
|
The second reason is to copy a specific number of characters from
|
||||||
|
<src> to <dest>. In this case, <n> should be the number of characters
|
||||||
|
you want to transfer, not including the terminating NULL character.
|
||||||
|
|
||||||
|
The following example copies "abc" into tempstring, and NULL
|
||||||
|
terminates it.
|
||||||
|
|
||||||
|
char tempstring[MAXLINE];
|
||||||
|
|
||||||
|
strncpy2(tempstring, "abcdef123", 3);
|
||||||
|
|
||||||
|
strncpy2() returns a pointer to the first character in <src> that was
|
||||||
|
not copied to <dest>. If all of <src> was copied to <dest>,
|
||||||
|
strncpy2() will return a pointer to the NULL character terminating the
|
||||||
|
<src> string.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------*/
|
||||||
|
char *
|
||||||
|
strncpy2(char *dest, char *src, int n)
|
||||||
|
{
|
||||||
|
int
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
char
|
||||||
|
*char_ptr;
|
||||||
|
|
||||||
|
/* -- */
|
||||||
|
|
||||||
|
if ((!dest) || (!src))
|
||||||
|
return(src);
|
||||||
|
|
||||||
|
char_ptr = dest;
|
||||||
|
|
||||||
|
while ((i++ < n) && *src)
|
||||||
|
*char_ptr++ = *src++;
|
||||||
|
|
||||||
|
*char_ptr = '\0';
|
||||||
|
|
||||||
|
return(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
strncat2()
|
||||||
|
|
||||||
|
Similar to strncat except that <n> is the size of the <dest> buffer
|
||||||
|
(INCLUDING SPACE FOR THE TRAILING NULL CHAR), NOT the number of
|
||||||
|
characters to add to the buffer.
|
||||||
|
|
||||||
|
STRNCAT2() IS NOT A COMPATIBLE REPLACEMENT FOR STRNCAT()!
|
||||||
|
|
||||||
|
strncat2() always guarantees that the <dest> will be null terminated, and that
|
||||||
|
the buffer limits will be honored. strncat2() will not write even one
|
||||||
|
byte beyond the end of the <dest> buffer.
|
||||||
|
|
||||||
|
strncat2() concatenates up to <n-1> - strlen(<dest>) characters from
|
||||||
|
<src> to <dest>.
|
||||||
|
|
||||||
|
So if the <dest> buffer has a size of 20 bytes (including trailing NULL),
|
||||||
|
and <dest> contains a 19 character string, nothing will be done to
|
||||||
|
<dest>.
|
||||||
|
|
||||||
|
If the string in <dest> is longer than <n-1> characters upon entry to
|
||||||
|
strncat2(), <dest> will be truncated after the <n-1>th character.
|
||||||
|
|
||||||
|
strncat2() returns a pointer to the first character in the src buffer that
|
||||||
|
was not copied into dest.. so if strncat2() returns a non-zero character,
|
||||||
|
string truncation occurred in the concat operation.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------*/
|
||||||
|
char *
|
||||||
|
strncat2(char *dest, char *src, int n)
|
||||||
|
{
|
||||||
|
int
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
char
|
||||||
|
*dest_ptr,
|
||||||
|
*src_ptr;
|
||||||
|
|
||||||
|
/* -- */
|
||||||
|
|
||||||
|
if (!dest || !src)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
dest_ptr = dest;
|
||||||
|
src_ptr = src;
|
||||||
|
|
||||||
|
/* i = 0 */
|
||||||
|
|
||||||
|
while ((i < (n-1)) && *dest_ptr)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
dest_ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* i is the number of characters in dest before the concatenation
|
||||||
|
operation.. a number between 0 and n-1 */
|
||||||
|
|
||||||
|
while ((i++ < (n-1)) && *src_ptr)
|
||||||
|
*dest_ptr++ = *src_ptr++;
|
||||||
|
|
||||||
|
/* i is the number of characters in dest after the concatenation
|
||||||
|
operation, or n if the concat operation got truncated.. a number
|
||||||
|
between 0 and n
|
||||||
|
|
||||||
|
We need to check src_ptr here because i will be equal to n if
|
||||||
|
<dest> was full before the concatenation operation started (which
|
||||||
|
effectively causes instant truncation even if the <src> string is
|
||||||
|
empty..
|
||||||
|
|
||||||
|
We could just test src_ptr here, but that would report
|
||||||
|
a string truncation if <src> was empty, which we don't
|
||||||
|
necessarily want. */
|
||||||
|
|
||||||
|
if ((i == n) && *src_ptr)
|
||||||
|
{
|
||||||
|
// we could log truncation here
|
||||||
|
}
|
||||||
|
|
||||||
|
*dest_ptr = '\0';
|
||||||
|
|
||||||
|
/* should point to a non-empty substring only if the concatenation
|
||||||
|
operation got truncated.
|
||||||
|
|
||||||
|
If src_ptr points to an empty string, the operation always
|
||||||
|
succeeded, either due to an empty <src> or because of
|
||||||
|
sufficient room in <dest>. */
|
||||||
|
|
||||||
|
return(src_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_DLPI */
|
||||||
93
addrs_ioctl.c
Normal file
93
addrs_ioctl.c
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* addrs_ioctl.c:
|
||||||
|
*
|
||||||
|
* Provides the get_addrs_ioctl() function for use on systems that
|
||||||
|
* support a simple socket ioctl for acquiring low-level ethernet
|
||||||
|
* information about interfaces.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#include "iftop.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function identifies the IP address and ethernet address for the requested
|
||||||
|
* interface
|
||||||
|
*
|
||||||
|
* This function returns -1 on catastrophic failure, or a bitwise OR of the
|
||||||
|
* following values:
|
||||||
|
*
|
||||||
|
* 1 - Was able to get the ethernet address
|
||||||
|
* 2 - Was able to get the IP address
|
||||||
|
*
|
||||||
|
* This function should return 3 if all information was found
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
get_addrs_ioctl(char *interface, char if_hw_addr[], struct in_addr *if_ip_addr)
|
||||||
|
{
|
||||||
|
int s;
|
||||||
|
struct ifreq ifr = {};
|
||||||
|
int got_hw_addr = 0;
|
||||||
|
int got_ip_addr = 0;
|
||||||
|
|
||||||
|
/* -- */
|
||||||
|
|
||||||
|
s = socket(PF_INET, SOCK_DGRAM, 0); /* any sort of IP socket will do */
|
||||||
|
|
||||||
|
if (s == -1) {
|
||||||
|
perror("socket");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr,"if: %s\n", interface);
|
||||||
|
|
||||||
|
memset(if_hw_addr, 0, 6);
|
||||||
|
strncpy(ifr.ifr_name, interface, IFNAMSIZ);
|
||||||
|
|
||||||
|
#ifdef SIOCGIFHWADDR
|
||||||
|
if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
|
||||||
|
fprintf(stderr, "Error getting hardware address for interface: %s\n", interface);
|
||||||
|
perror("ioctl(SIOCGIFHWADDR)");
|
||||||
|
close(s);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memcpy(if_hw_addr, ifr.ifr_hwaddr.sa_data, 6);
|
||||||
|
got_hw_addr = 1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
fprintf(stderr, "Cannot obtain hardware address on this platform\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Get the IP address of the interface */
|
||||||
|
#ifdef SIOCGIFADDR
|
||||||
|
(*(struct sockaddr_in *) &ifr.ifr_addr).sin_family = AF_INET;
|
||||||
|
if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
|
||||||
|
fprintf(stderr, "Error getting IP address for interface: %s\n", interface);
|
||||||
|
perror("ioctl(SIOCGIFADDR)");
|
||||||
|
close(s);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memcpy(if_ip_addr, &((*(struct sockaddr_in *) &ifr.ifr_addr).sin_addr), sizeof(struct in_addr));
|
||||||
|
got_ip_addr = 2;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
fprintf(stderr, "Cannot obtain IP address on this platform\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
close(s);
|
||||||
|
|
||||||
|
return got_hw_addr + got_ip_addr;
|
||||||
|
}
|
||||||
61
configure.in
61
configure.in
@@ -15,9 +15,13 @@ dnl Boilerplate configuration
|
|||||||
dnl
|
dnl
|
||||||
|
|
||||||
AC_INIT(iftop.c)
|
AC_INIT(iftop.c)
|
||||||
|
|
||||||
AC_CONFIG_AUX_DIR(config)
|
AC_CONFIG_AUX_DIR(config)
|
||||||
|
|
||||||
|
AC_CANONICAL_SYSTEM
|
||||||
|
|
||||||
AM_CONFIG_HEADER(config.h)
|
AM_CONFIG_HEADER(config.h)
|
||||||
AM_INIT_AUTOMAKE(iftop, "0.12")
|
AM_INIT_AUTOMAKE(iftop, "0.13pre1")
|
||||||
|
|
||||||
AC_DEFINE_UNQUOTED(IFTOP_VERSION, "$VERSION", [The iftop version number])
|
AC_DEFINE_UNQUOTED(IFTOP_VERSION, "$VERSION", [The iftop version number])
|
||||||
|
|
||||||
@@ -60,6 +64,12 @@ AC_C_CONST
|
|||||||
AC_TYPE_SIZE_T
|
AC_TYPE_SIZE_T
|
||||||
AC_HEADER_TIME
|
AC_HEADER_TIME
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl Are we on a system that uses the STREAMS low-level DLPI interface?
|
||||||
|
dnl
|
||||||
|
|
||||||
|
AC_CHECK_HEADER([sys/dlpi.h],[AC_DEFINE([HAVE_DLPI],1,[Are we running on a STREAMS system with DLPI?])])
|
||||||
|
|
||||||
dnl Checks for library functions.
|
dnl Checks for library functions.
|
||||||
AC_CHECK_FUNCS(regcomp select strdup strerror strspn)
|
AC_CHECK_FUNCS(regcomp select strdup strerror strspn)
|
||||||
|
|
||||||
@@ -68,8 +78,8 @@ AC_SEARCH_LIBS(log, m)
|
|||||||
AC_CHECK_FUNC(gethostbyname, ,
|
AC_CHECK_FUNC(gethostbyname, ,
|
||||||
[AC_CHECK_LIB(nsl, gethostbyname)] )
|
[AC_CHECK_LIB(nsl, gethostbyname)] )
|
||||||
|
|
||||||
AC_SEARCH_LIBS(inet_aton, [-lsocket -lnsl])
|
AC_SEARCH_LIBS(inet_aton, [socket nsl])
|
||||||
AC_SEARCH_LIBS(inet_pton, [-lsocket -lnsl])
|
AC_SEARCH_LIBS(inet_pton, [socket nsl])
|
||||||
AC_CHECK_FUNCS(inet_aton inet_pton)
|
AC_CHECK_FUNCS(inet_aton inet_pton)
|
||||||
|
|
||||||
dnl
|
dnl
|
||||||
@@ -143,7 +153,7 @@ dnl but that's probably not available on typical machines.
|
|||||||
if test x$resolver = xnetdb ; then
|
if test x$resolver = xnetdb ; then
|
||||||
dnl Best possibility is getnameinfo.
|
dnl Best possibility is getnameinfo.
|
||||||
use_getnameinfo=0
|
use_getnameinfo=0
|
||||||
AC_SEARCH_LIBS(getnameinfo, [-lnsl], [use_getnameinfo=1])
|
AC_SEARCH_LIBS(getnameinfo, [nsl], [use_getnameinfo=1])
|
||||||
|
|
||||||
dnl XXX For the moment, don't use getnameinfo, since it isn't actually
|
dnl XXX For the moment, don't use getnameinfo, since it isn't actually
|
||||||
dnl thread safe on, e.g., NetBSD.
|
dnl thread safe on, e.g., NetBSD.
|
||||||
@@ -154,7 +164,7 @@ if test x$resolver = xnetdb ; then
|
|||||||
AC_DEFINE(USE_GETNAMEINFO, 1, [use getnameinfo for name resolution])
|
AC_DEFINE(USE_GETNAMEINFO, 1, [use getnameinfo for name resolution])
|
||||||
else
|
else
|
||||||
dnl Now see if we can use gethostbyaddr_r.
|
dnl Now see if we can use gethostbyaddr_r.
|
||||||
AC_SEARCH_LIBS(gethostbyaddr_r, [-lnsl], , [resolver=netdb_1thread])
|
AC_SEARCH_LIBS(gethostbyaddr_r, [nsl], , [resolver=netdb_1thread])
|
||||||
|
|
||||||
dnl Still want gethostbyaddr_r....
|
dnl Still want gethostbyaddr_r....
|
||||||
if test x$resolver = xnetdb ; then
|
if test x$resolver = xnetdb ; then
|
||||||
@@ -195,7 +205,7 @@ dnl machine had a working gethostbyaddr_r, the user wouldn't be pissing about
|
|||||||
dnl with ARES.
|
dnl with ARES.
|
||||||
if test x$resolver = xares ; then
|
if test x$resolver = xares ; then
|
||||||
dnl See if ares is to hand....
|
dnl See if ares is to hand....
|
||||||
AC_SEARCH_LIBS(ares_init, [-lares], [
|
AC_SEARCH_LIBS(ares_init, [ares], [
|
||||||
AC_DEFINE(USE_ARES, 1, [use ARES for name resolution])
|
AC_DEFINE(USE_ARES, 1, [use ARES for name resolution])
|
||||||
], [
|
], [
|
||||||
dnl no ares
|
dnl no ares
|
||||||
@@ -206,7 +216,7 @@ fi
|
|||||||
|
|
||||||
dnl Ugh. gethostbyaddr.
|
dnl Ugh. gethostbyaddr.
|
||||||
if test x$resolver = xnetdb_1thread ; then
|
if test x$resolver = xnetdb_1thread ; then
|
||||||
AC_SEARCH_LIBS(gethostbyaddr, [-lnsl], , [
|
AC_SEARCH_LIBS(gethostbyaddr, [nsl], , [
|
||||||
AC_MSG_ERROR([not even gethostbyaddr is available
|
AC_MSG_ERROR([not even gethostbyaddr is available
|
||||||
What sort of UNIX system is this, anyway?])
|
What sort of UNIX system is this, anyway?])
|
||||||
]
|
]
|
||||||
@@ -232,15 +242,15 @@ fi
|
|||||||
AC_MSG_CHECKING([where to find pcap.h])
|
AC_MSG_CHECKING([where to find pcap.h])
|
||||||
foundpcaph=0
|
foundpcaph=0
|
||||||
oldCPPFLAGS=$CPPFLAGS
|
oldCPPFLAGS=$CPPFLAGS
|
||||||
for prefix in "" $libpcap_prefix ; do
|
for test_prefix in "" $libpcap_prefix ; do
|
||||||
for x in "" /pcap ; do
|
for x in "" /pcap ; do
|
||||||
if test x$prefix != x ; then
|
if test x$test_prefix != x ; then
|
||||||
CPPFLAGS="$oldCPPFLAGS -I$prefix/include$x"
|
CPPFLAGS="$oldCPPFLAGS -I$test_prefix/include$x"
|
||||||
fi
|
fi
|
||||||
AC_TRY_CPP([
|
AC_TRY_CPP([
|
||||||
#include <pcap.h>
|
#include <pcap.h>
|
||||||
], [
|
], [
|
||||||
AC_MSG_RESULT([$prefix/include$x])
|
AC_MSG_RESULT([$test_prefix/include$x])
|
||||||
foundpcaph=1
|
foundpcaph=1
|
||||||
break
|
break
|
||||||
])
|
])
|
||||||
@@ -255,9 +265,9 @@ if test $foundpcaph = 0 ; then
|
|||||||
AC_MSG_ERROR([can't find pcap.h
|
AC_MSG_ERROR([can't find pcap.h
|
||||||
You're not going to get very far without libpcap.])
|
You're not going to get very far without libpcap.])
|
||||||
else
|
else
|
||||||
dnl assume that -lpcap is under $prefix/lib
|
dnl assume that -lpcap is under $test_prefix/lib
|
||||||
if test x$prefix != x ; then
|
if test x$test_prefix != x ; then
|
||||||
LDFLAGS="$LDFLAGS -L$prefix"
|
LDFLAGS="$LDFLAGS -L$test_prefix"
|
||||||
fi
|
fi
|
||||||
AC_CHECK_LIB(pcap, pcap_open_live, , [
|
AC_CHECK_LIB(pcap, pcap_open_live, , [
|
||||||
AC_MSG_ERROR([can't find libpcap
|
AC_MSG_ERROR([can't find libpcap
|
||||||
@@ -341,9 +351,30 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
dnl
|
dnl
|
||||||
dnl Wahey! This might even work.
|
dnl Are we on a system (like Solaris) that requires promiscuous mode in order to
|
||||||
|
dnl see any outgoing packets?
|
||||||
dnl
|
dnl
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([if we need to enable promiscuous mode by default])
|
||||||
|
|
||||||
|
enable_default_promiscuous="no"
|
||||||
|
|
||||||
|
case "$host_os" in
|
||||||
|
solaris*) enable_default_promiscuous="yes" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(default-promiscuous,
|
||||||
|
[--enable-default-promiscuous If enabled, iftop will operate in promiscuous mode to capture outgoing packets])
|
||||||
|
|
||||||
|
AC_MSG_RESULT([$enable_default_promiscuous])
|
||||||
|
|
||||||
|
if test x"$enable_default_promiscuous" = x"yes"; then
|
||||||
|
AC_DEFINE([NEED_PROMISCUOUS_FOR_OUTGOING],1,[Enable default promiscuous mode to capture outgoing packets])
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl Wahey! This might even work.
|
||||||
|
dnl
|
||||||
|
|
||||||
AC_SUBST(ac_aux_dir)
|
AC_SUBST(ac_aux_dir)
|
||||||
|
|
||||||
|
|||||||
1365
dlcommon.c
Normal file
1365
dlcommon.c
Normal file
File diff suppressed because it is too large
Load Diff
37
dlcommon.h
Normal file
37
dlcommon.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#ifndef DLCOMMON_H
|
||||||
|
#define DLCOMMON_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Common DLPI Test Suite header file
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Maximum control/data buffer size (in long's !!) for getmsg().
|
||||||
|
*/
|
||||||
|
#define MAXDLBUF 8192
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Maximum number of seconds we'll wait for any
|
||||||
|
* particular DLPI acknowledgment from the provider
|
||||||
|
* after issuing a request.
|
||||||
|
*/
|
||||||
|
#define MAXWAIT 15
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Maximum address buffer length.
|
||||||
|
*/
|
||||||
|
#define MAXDLADDR 1024
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handy macro.
|
||||||
|
*/
|
||||||
|
#define OFFADDR(s, n) (u_char*)((char*)(s) + (int)(n))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* externs go here
|
||||||
|
*/
|
||||||
|
extern void sigalrm();
|
||||||
|
|
||||||
|
#endif /* !DLCOMMON_H */
|
||||||
79
iftop.c
79
iftop.c
@@ -222,6 +222,9 @@ static void handle_ip_packet(struct ip* iptr, int hw_dir)
|
|||||||
* source and dest arbitrarily (by numerical value) and account as
|
* source and dest arbitrarily (by numerical value) and account as
|
||||||
* incoming.
|
* incoming.
|
||||||
*/
|
*/
|
||||||
|
else if (options.promiscuous_but_choosy) {
|
||||||
|
return; /* junk it */
|
||||||
|
}
|
||||||
else if(iptr->ip_src.s_addr < iptr->ip_dst.s_addr) {
|
else if(iptr->ip_src.s_addr < iptr->ip_dst.s_addr) {
|
||||||
assign_addr_pair(&ap, iptr, 1);
|
assign_addr_pair(&ap, iptr, 1);
|
||||||
direction = 0;
|
direction = 0;
|
||||||
@@ -384,10 +387,13 @@ static void handle_eth_packet(unsigned char* args, const struct pcap_pkthdr* pkt
|
|||||||
if(have_hw_addr && memcmp(eptr->ether_shost, if_hw_addr, 6) == 0 ) {
|
if(have_hw_addr && memcmp(eptr->ether_shost, if_hw_addr, 6) == 0 ) {
|
||||||
/* packet leaving this i/f */
|
/* packet leaving this i/f */
|
||||||
dir = 1;
|
dir = 1;
|
||||||
}
|
}
|
||||||
else if((have_hw_addr && memcmp(eptr->ether_dhost, if_hw_addr, 6) == 0)
|
else if(have_hw_addr && memcmp(eptr->ether_dhost, if_hw_addr, 6) == 0 ) {
|
||||||
|| memcmp("\xFF\xFF\xFF\xFF\xFF\xFF", eptr->ether_dhost, 6) == 0) {
|
/* packet entering this i/f */
|
||||||
/* packet entering this i/f (include broadcast packets here */
|
dir = 0;
|
||||||
|
}
|
||||||
|
else if (memcmp("\xFF\xFF\xFF\xFF\xFF\xFF", eptr->ether_dhost, 6) == 0) {
|
||||||
|
/* broadcast packet, count as incoming */
|
||||||
dir = 0;
|
dir = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -430,59 +436,34 @@ void packet_init() {
|
|||||||
char *m;
|
char *m;
|
||||||
int s;
|
int s;
|
||||||
int i;
|
int i;
|
||||||
struct ifreq ifr = {};
|
|
||||||
int dlt;
|
int dlt;
|
||||||
|
int result;
|
||||||
|
|
||||||
/* First, get the address of the interface. If it isn't an ethernet
|
#ifdef HAVE_DLPI
|
||||||
* interface whose address we can obtain, there's not a lot we can do. */
|
result = get_addrs_dlpi(options.interface, if_hw_addr, &if_ip_addr);
|
||||||
s = socket(PF_INET, SOCK_DGRAM, 0); /* any sort of IP socket will do */
|
|
||||||
if (s == -1) {
|
|
||||||
perror("socket");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
fprintf(stderr,"if: %s\n", options.interface);
|
|
||||||
memset(if_hw_addr, 0, 6);
|
|
||||||
strncpy(ifr.ifr_name, options.interface, IFNAMSIZ);
|
|
||||||
#ifdef SIOCGIFHWADDR
|
|
||||||
if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
|
|
||||||
fprintf(stderr, "Error getting hardware address for interface: %s\n", options.interface);
|
|
||||||
perror("ioctl(SIOCGIFHWADDR)");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
memcpy(if_hw_addr, ifr.ifr_hwaddr.sa_data, 6);
|
|
||||||
have_hw_addr = 1;
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
fprintf(stderr, "Cannot obtain hardware address on this platform\n");
|
result = get_addrs_ioctl(options.interface, if_hw_addr, &if_ip_addr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (result < 0) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
have_hw_addr = result & 1;
|
||||||
|
have_ip_addr = result & 2;
|
||||||
|
|
||||||
|
if(have_ip_addr) {
|
||||||
|
fprintf(stderr, "IP address is: %s\n", inet_ntoa(if_ip_addr));
|
||||||
|
}
|
||||||
|
|
||||||
if(have_hw_addr) {
|
if(have_hw_addr) {
|
||||||
fprintf(stderr, "MAC address is:");
|
fprintf(stderr, "MAC address is:");
|
||||||
for (i = 0; i < 6; ++i)
|
for (i = 0; i < 6; ++i)
|
||||||
fprintf(stderr, "%c%02x", i ? ':' : ' ', (unsigned int)if_hw_addr[i]);
|
fprintf(stderr, "%c%02x", i ? ':' : ' ', (unsigned int)if_hw_addr[i]);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the IP address of the interface */
|
|
||||||
#ifdef SIOCGIFADDR
|
|
||||||
(*(struct sockaddr_in *) &ifr.ifr_addr).sin_family = AF_INET;
|
|
||||||
if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
|
|
||||||
fprintf(stderr, "Error getting IP address for interface: %s\n", options.interface);
|
|
||||||
perror("ioctl(SIOCGIFADDR)");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
have_ip_addr = 1;
|
|
||||||
memcpy(&if_ip_addr, &((*(struct sockaddr_in *) &ifr.ifr_addr).sin_addr), sizeof(struct sockaddr_in));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
fprintf(stderr, "Cannot obtain IP address on this platform\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
close(s);
|
|
||||||
|
|
||||||
if(have_ip_addr)
|
|
||||||
fprintf(stderr, "IP address is: %s\n", inet_ntoa(((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr));
|
|
||||||
|
|
||||||
|
// exit(0);
|
||||||
resolver_initialise();
|
resolver_initialise();
|
||||||
|
|
||||||
pd = pcap_open_live(options.interface, CAPTURE_LENGTH, options.promiscuous, 1000, errbuf);
|
pd = pcap_open_live(options.interface, CAPTURE_LENGTH, options.promiscuous, 1000, errbuf);
|
||||||
|
|||||||
10
options.c
10
options.c
@@ -4,6 +4,8 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -37,6 +39,7 @@ char optstr[] = "+i:f:nN:hpbBP";
|
|||||||
* likely to want to listen. We also compare candidate interfaces to lo. */
|
* likely to want to listen. We also compare candidate interfaces to lo. */
|
||||||
static char *bad_interface_names[] = {
|
static char *bad_interface_names[] = {
|
||||||
"lo:",
|
"lo:",
|
||||||
|
"lo",
|
||||||
"dummy",
|
"dummy",
|
||||||
"vmnet",
|
"vmnet",
|
||||||
NULL /* last entry must be NULL */
|
NULL /* last entry must be NULL */
|
||||||
@@ -87,7 +90,13 @@ static void set_defaults() {
|
|||||||
inet_aton("255.255.255.0", &options.netfiltermask);
|
inet_aton("255.255.255.0", &options.netfiltermask);
|
||||||
options.dnsresolution = 1;
|
options.dnsresolution = 1;
|
||||||
options.portresolution = 1;
|
options.portresolution = 1;
|
||||||
|
#ifdef NEED_PROMISCUOUS_FOR_OUTGOING
|
||||||
|
options.promiscuous = 1;
|
||||||
|
options.promiscuous_but_choosy = 1;
|
||||||
|
#else
|
||||||
options.promiscuous = 0;
|
options.promiscuous = 0;
|
||||||
|
options.promiscuous_but_choosy = 0;
|
||||||
|
#endif
|
||||||
options.showbars = 1;
|
options.showbars = 1;
|
||||||
options.showports = OPTION_PORTS_OFF;
|
options.showports = OPTION_PORTS_OFF;
|
||||||
options.aggregate_src = 0;
|
options.aggregate_src = 0;
|
||||||
@@ -200,6 +209,7 @@ void options_read(int argc, char **argv) {
|
|||||||
|
|
||||||
case 'p':
|
case 'p':
|
||||||
options.promiscuous = 1;
|
options.promiscuous = 1;
|
||||||
|
options.promiscuous_but_choosy = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'P':
|
case 'P':
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ typedef struct {
|
|||||||
int dnsresolution;
|
int dnsresolution;
|
||||||
int portresolution;
|
int portresolution;
|
||||||
int promiscuous;
|
int promiscuous;
|
||||||
|
int promiscuous_but_choosy;
|
||||||
int showbars;
|
int showbars;
|
||||||
option_port_t showports;
|
option_port_t showports;
|
||||||
int aggregate_src;
|
int aggregate_src;
|
||||||
|
|||||||
Reference in New Issue
Block a user