/*-
* Copyright (c) 2001 Hellmuth Michaelis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*---------------------------------------------------------------------------
*
* nifmon - main
* -------------
*
* last edit-date: [Wed May 2 16:32:52 2001]
*
*---------------------------------------------------------------------------*/
#define MAIN
#include "nifmon.h"
#undef MAIN
static pid_t pid;
/*---------------------------------------------------------------------------
* Display usage and exit
*---------------------------------------------------------------------------*/
static void
usage()
{
fprintf(stderr, "\n");
fprintf(stderr, "nifmon -b -e <expr> -i <if> -r <tty> -t <termtype> (V%d.%d)\n", VERSION, RELEASE);
fprintf(stderr, " -b run in background [needs -r and -t]\n");
fprintf(stderr, " -e <expr> tcpdump expression\n");
fprintf(stderr, " -i <if> monitor interface <if>, default lo0\n");
fprintf(stderr, " -r <tty> redirect output to device <tty>\n");
fprintf(stderr, " -t <term> terminal type for device <tty>\n");
exit(1);
}
/*---------------------------------------------------------------------------
* Parse command line, startup monitor client
*---------------------------------------------------------------------------*/
int
main(int argc, char **argv)
{
int i;
char *netif = "lo0";
char *expression = "";
while ((i = getopt(argc, argv, "be:i:r:t:")) != -1)
{
switch (i)
{
case 'b':
background = 1;
break;
case 'e':
expression = optarg;
break;
case 'i':
netif = optarg;
break;
case 'r':
rdev = optarg;
has_rdev = 1;
break;
case 't':
term = optarg;
has_term = 1;
break;
default:
usage();
break;
}
}
if (background)
{
if (has_rdev == 0 || has_term == 0)
{
fprintf(stderr, "-b option needs both -t and -r!\n");
exit(1);
}
}
/* only root is able to open /dev/bpfN */
if (getuid() != 0)
{
fprintf(stderr,
"You must be superuser (root) to run this program\n");
exit(1);
}
sprintf(pidfile, "%s-%s%s", PIDFIL, netif, PIDPID);
if (background)
{
check_pid(pidfile);
daemonize();
write_pid(pidfile);
}
signal(SIGHUP, do_exit);
signal(SIGINT, do_exit);
signal(SIGQUIT, do_exit);
signal(SIGTERM, do_exit);
signal(SIGUSR1, do_exit);
signal(SIGUSR2, do_exit);
init_interface(netif);
init_screen(netif);
pfp = mpopen(netif, expression);
if (pfp == NULL)
{
perror("mpopen");
do_exit(1);
}
for (;;)
{
fd_set set;
struct timeval timeout;
int ret;
int high_selfd;
FD_ZERO(&set);
FD_SET(fileno(stdin), &set);
high_selfd = fileno(stdin);
FD_SET(fileno(pfp), &set);
high_selfd = fileno(pfp);
timeout.tv_sec = 1;
timeout.tv_usec = 0;
ret = select(high_selfd + 1, &set, NULL, NULL, &timeout);
if (ret > 0)
{
if (FD_ISSET(fileno(stdin), &set))
kbdrdhdl();
if (FD_ISSET(fileno(pfp), &set))
loghdl(pfp);
}
update_interface(netif);
}
}
/*---------------------------------------------------------------------------*
* program exit
*---------------------------------------------------------------------------*/
void
do_exit(int exitval)
{
mpclose(pfp);
if (curses_ready)
endwin();
unlink(pidfile);
exit(exitval);
}
/*---------------------------------------------------------------------------*
* open pipe to tcpdump
*---------------------------------------------------------------------------*/
FILE *
mpopen(char *interface, char *expression)
{
FILE *fp;
int pdes[2];
char *argv[5];
if (pipe(pdes) < 0)
return (NULL);
argv[0] = TCPDUMP;
argv[1] = TCPDUMPFLAGS;
argv[2] = interface;
argv[3] = expression;
argv[4] = NULL;
switch (pid = vfork())
{
case -1: /* Error. */
(void) close(pdes[0]);
(void) close(pdes[1]);
return (NULL);
case 0: /* Child. */
(void) close(pdes[0]);
if (pdes[1] != STDOUT_FILENO)
{
(void) dup2(pdes[1], STDOUT_FILENO);
(void) close(pdes[1]);
}
/*XXX*/ close(STDERR_FILENO);
execv(TCPDUMPPATH, argv);
_exit(127);
}
/* Parent */
fp = fdopen(pdes[0], "r");
(void) close(pdes[1]);
return (fp);
}
/*---------------------------------------------------------------------------*
* close pipe and terminate tcpdump
*---------------------------------------------------------------------------*/
int
mpclose(FILE * fp)
{
int pstat;
pid_t mpid;
(void) fclose(fp);
kill(pid, SIGTERM);
do
{
mpid = wait4(pid, &pstat, 0, (struct rusage *) 0);
}
while (mpid == -1 && errno == EINTR);
return (mpid == -1 ? -1 : pstat);
}
syntax highlighted by Code2HTML, v. 0.9.1