summaryrefslogtreecommitdiff
path: root/usr.sbin/ipmon/ipmon.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/ipmon/ipmon.c')
-rw-r--r--usr.sbin/ipmon/ipmon.c361
1 files changed, 295 insertions, 66 deletions
diff --git a/usr.sbin/ipmon/ipmon.c b/usr.sbin/ipmon/ipmon.c
index ba827cec129..e7a488b4bf9 100644
--- a/usr.sbin/ipmon/ipmon.c
+++ b/usr.sbin/ipmon/ipmon.c
@@ -11,7 +11,8 @@
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
-#include <sys/syslog.h>
+#include <stdlib.h>
+#include <syslog.h>
#include <sys/errno.h>
#include <sys/file.h>
#include <sys/ioctl.h>
@@ -37,15 +38,16 @@
#include <netinet/ip_icmp.h>
#include <netdb.h>
#include <arpa/inet.h>
+#include <ctype.h>
-#ifndef lint
-static char sccsid[] = "@(#)ipmon.c 1.21 6/5/96 (C)1993-1996 Darren Reed";
-static char rcsid[] = "$Id: ipmon.c,v 1.6 1996/10/08 07:33:38 niklas Exp $";
+#if !defined(lint) && defined(LIBC_SCCS)
+static char rcsid[] = "$Id: ipmon.c,v 1.7 1997/02/11 22:24:10 kstailey Exp $";
#endif
#include "ip_fil_compat.h"
#include "ip_fil.h"
+
struct flags {
int value;
char flag;
@@ -61,8 +63,162 @@ struct flags tcpfl[] = {
{ 0, '\0' }
};
+
static char line[2048];
-static void printpacket();
+static void printpacket(), dumphex();
+static int opts = 0;
+
+#define OPT_SYSLOG 0x01
+#define OPT_RESOLVE 0x02
+#define OPT_HEXBODY 0x04
+#define OPT_VERBOSE 0x08
+#define OPT_HEXHDR 0x10
+
+#ifndef LOGFAC
+#define LOGFAC LOG_LOCAL0
+#endif
+
+void printiplci(icp)
+struct ipl_ci *icp;
+{
+ printf("sec %ld usec %ld hlen %d plen %d\n", icp->sec, icp->usec,
+ icp->hlen, icp->plen);
+}
+
+
+void resynclog(fd, iplcp, log)
+int fd;
+struct ipl_ci *iplcp;
+FILE *log;
+{
+ time_t now;
+ char *s = NULL;
+ int len, nr = 0;
+
+ do {
+ if (s) {
+ s = (char *)&iplcp->sec;
+ if (opts & OPT_SYSLOG) {
+ syslog(LOG_INFO, "Sync bytes:");
+ syslog(LOG_INFO, " %02x %02x %02x %02x",
+ *s, *(s+1), *(s+2), *(s+3));
+ syslog(LOG_INFO, " %02x %02x %02x %02x\n",
+ *(s+4), *(s+5), *(s+6), *(s+7));
+ } else {
+ fprintf(log, "Sync bytes:");
+ fprintf(log, " %02x %02x %02x %02x",
+ *s, *(s+1), *(s+2), *(s+3));
+ fprintf(log, " %02x %02x %02x %02x\n",
+ *(s+4), *(s+5), *(s+6), *(s+7));
+ }
+ }
+ do {
+ s = (char *)&iplcp->sec;
+ len = sizeof(iplcp->sec);
+ while (len) {
+ switch ((nr = read(fd, s, len)))
+ {
+ case -1:
+ case 0:
+ return;
+ default :
+ s += nr;
+ len -= nr;
+ now = time(NULL);
+ break;
+ }
+ }
+ } while ((now < iplcp->sec) ||
+ ((iplcp->sec - now) > (86400*5)));
+
+ len = sizeof(iplcp->usec);
+ while (len) {
+ switch ((nr = read(fd, s, len)))
+ {
+ case -1:
+ case 0:
+ return;
+ default :
+ s += nr;
+ len -= nr;
+ break;
+ }
+ }
+ } while (iplcp->usec > 1000000);
+
+ len = sizeof(*iplcp) - sizeof(iplcp->sec) - sizeof(iplcp->usec);
+ while (len) {
+ switch ((nr = read(fd, s, len)))
+ {
+ case -1:
+ case 0:
+ return;
+ default :
+ s += nr;
+ len -= nr;
+ break;
+ }
+ }
+}
+
+
+int readlogentry(fd, lenp, buf, bufsize, log)
+int fd, bufsize, *lenp;
+char *buf;
+FILE *log;
+{
+ struct ipl_ci *icp = (struct ipl_ci *)buf;
+ time_t now;
+ char *s;
+ int len, n = bufsize, tr = sizeof(struct ipl_ci), nr;
+
+ if (bufsize < tr)
+ return 1;
+ for (s = buf; (n > 0) && (tr > 0); s += nr, n -= nr) {
+ nr = read(fd, s, tr);
+ if (nr > 0)
+ tr -= nr;
+ else
+ return -1;
+ }
+
+ now = time(NULL);
+ if ((icp->hlen > 92) || (now < icp->sec) ||
+ ((now - icp->sec) > (86400*5))) {
+ if (opts & OPT_SYSLOG)
+ syslog(LOG_INFO, "Out of sync! (1,%x)\n", now);
+ else
+ fprintf(log, "Out of sync! (1,%x)\n", now);
+ dumphex(log, buf, sizeof(struct ipl_ci));
+ resynclog(fd, icp, log);
+ }
+
+
+ len = (int)((u_int)icp->plen);
+ if (len > 128 || len < 0) {
+ if (opts & OPT_SYSLOG)
+ syslog(LOG_INFO, "Out of sync! (2,%d)\n", len);
+ else
+ fprintf(log, "Out of sync! (2,%d)\n", len);
+ dumphex(log, buf, sizeof(struct ipl_ci));
+ resynclog(fd, icp, log);
+ }
+
+
+ tr = icp->hlen + icp->plen;
+ if (n < tr)
+ return 1;
+
+ for (; (n > 0) && (tr > 0); s += nr, n-= nr) {
+ nr = read(fd, s, tr);
+ if (nr > 0)
+ tr -= nr;
+ else
+ return -1;
+ }
+ *lenp = s - buf;
+ return 0;
+}
char *hostname(res, ip)
@@ -98,39 +254,61 @@ u_short port;
}
-static void dumphex(log, ip, lp)
+static void dumphex(log, buf, len)
FILE *log;
-struct ip *ip;
-struct ipl_ci *lp;
+u_char *buf;
+int len;
{
+ char line[80];
int i, j, k;
- u_char *s = (u_char *)ip;
+ u_char *s = buf, *t = (u_char *)line;
- for (i = lp->plen + lp->hlen, j = 0; i; i--, j++, s++) {
- if (j && !(j & 0xf))
- putchar('\n');
- printf("%02x", *s);
+ for (i = len, j = 0; i; i--, j++, s++) {
+ if (j && !(j & 0xf)) {
+ *t++ = '\n';
+ *t = '\0';
+ fputs(line, stdout);
+ t = (u_char *)line;
+ *t = '\0';
+ }
+ sprintf(t, "%02x", *s & 0xff);
+ t += 2;
if (!((j + 1) & 0xf)) {
- s -= 16;
- printf(" ");
+ s -= 15;
+ sprintf(t, " ");
+ t += 8;
for (k = 16; k; k--, s++)
- putchar(isprint(*s) ? *s : '.');
+ *t++ = (isprint(*s) ? *s : '.');
+ s--;
}
if ((j + 1) & 0xf)
- putchar(' ');
+ *t++ = ' ';;
}
- if ((j - 1) & 0xf)
- putchar('\n');
+ if (j & 0xf) {
+ for (k = 16 - (j & 0xf); k; k--) {
+ *t++ = ' ';
+ *t++ = ' ';
+ *t++ = ' ';
+ }
+ sprintf(t, " ");
+ t += 7;
+ s -= j & 0xf;
+ for (k = j & 0xf; k; k--, s++)
+ *t++ = (isprint(*s) ? *s : '.');
+ *t++ = '\n';
+ *t = '\0';
+ }
+ fputs(line, stdout);
+ fflush(stdout);
}
-static void printpacket(log, ip, lp, opts)
+static void printpacket(log, buf, blen)
FILE *log;
-struct ip *ip;
-struct ipl_ci *lp;
-int opts;
+char *buf;
+int blen;
{
struct protoent *pr;
struct tcphdr *tp;
@@ -139,24 +317,32 @@ int opts;
struct tm *tm;
char c[3], pname[8], *t, *proto;
u_short hl, p;
- int i, lvl, res, len;
+ int i, lvl, res;
+#if !SOLARIS && !(defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603))\
+ && !(defined(OpenBSD) && (OpenBSD <= 1991011) && (OpenBSD >= 199603))
+ int len;
+#endif
+ struct ip *ip;
+ struct ipl_ci *lp;
- res = (opts & 2) ? 1 : 0;
+ lp = (struct ipl_ci *)buf;
+ ip = (struct ip *)(buf + sizeof(*lp));
+ res = (opts & OPT_RESOLVE) ? 1 : 0;
t = line;
*t = '\0';
hl = (ip->ip_hl << 2);
p = (u_short)ip->ip_p;
tm = localtime((time_t *)&lp->sec);
- if (!(opts & 1)) {
+ if (!(opts & OPT_SYSLOG)) {
(void) sprintf(t, "%2d/%02d/%4d ",
tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900);
t += strlen(t);
}
-#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
- (defined(OpenBSD) && (OpenBSD >= 199606))
- (void) sprintf(t, "%02d:%02d:%02d.%-.6ld %s @%hd ",
+#if SOLARIS || (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) \
+ || (defined(OpenBSD) && (OpenBSD <= 1991011) && (OpenBSD >= 199603))
+ (void) sprintf(t, "%02d:%02d:%02d.%-.6ld %.*s @%hd ",
tm->tm_hour, tm->tm_min, tm->tm_sec, lp->usec,
- lp->ifname, lp->rule);
+ (int)sizeof(lp->ifname), lp->ifname, lp->rule);
#else
for (len = 0; len < 3; len++)
if (!lp->ifname[len])
@@ -220,6 +406,12 @@ int opts;
if (tp->th_flags & tcpfl[i].value)
*t++ = tcpfl[i].flag;
}
+ if (opts & OPT_VERBOSE) {
+ (void) sprintf(t, " %lu %lu %hu",
+ (u_long)tp->th_seq,
+ (u_long)tp->th_ack, tp->th_win);
+ t += strlen(t);
+ }
*t = '\0';
} else {
(void) sprintf(t, "%s -> ", hostname(res, ip->ip_src));
@@ -287,70 +479,107 @@ int opts;
*t++ = '\n';
*t++ = '\0';
- if (opts & 1)
+ if (opts & OPT_SYSLOG)
syslog(lvl, "%s", line);
else
(void) fprintf(log, "%s", line);
+ if (opts & OPT_HEXHDR)
+ dumphex(log, buf, sizeof(struct ipl_ci));
+ if (opts & OPT_HEXBODY)
+ dumphex(log, ip, lp->plen + lp->hlen);
fflush(log);
- if (opts & 4)
- dumphex(log, ip, lp);
}
int main(argc, argv)
int argc;
char *argv[];
{
- FILE *log;
- int fd, flushed = 0, opts = 0;
- u_int len;
- char buf[512], c;
- struct ipl_ci iplci;
+ FILE *log = NULL;
+ int fd = -1, flushed = 0, doread, n;
+ char buf[512], c, *iplfile = IPL_NAME;
extern int optind;
+ extern char *optarg;
- if ((fd = open(IPL_NAME, O_RDONLY)) == -1) {
- (void) fprintf(stderr, "%s: ", IPL_NAME);
- perror("open");
- exit(-1);
- }
-
- while ((c = getopt(argc, argv, "Nfsx")) != -1)
+ while ((c = getopt(argc, argv, "Nf:FsvxX")) != -1)
switch (c)
{
case 'f' :
+ iplfile = optarg;
+ break;
+ case 'F' :
+ if ((fd == -1) &&
+ (fd = open(iplfile, O_RDWR)) == -1) {
+ (void) fprintf(stderr, "%s: ", IPL_NAME);
+ perror("open");
+ exit(-1);
+ }
if (ioctl(fd, SIOCIPFFB, &flushed) == 0) {
printf("%d bytes flushed from log buffer\n",
flushed);
fflush(stdout);
- }
+ } else
+ perror("SIOCIPFFB");
break;
case 'N' :
- opts |= 2;
- break;
- case 'x' :
- opts |= 4;
+ opts |= OPT_RESOLVE;
break;
case 's' :
openlog(argv[0], LOG_NDELAY|LOG_PID, LOGFAC);
- opts |= 1;
+ opts |= OPT_SYSLOG;
+ break;
+ case 'v' :
+ opts |= OPT_VERBOSE;
+ break;
+ case 'x' :
+ opts |= OPT_HEXBODY;
+ break;
+ case 'X' :
+ opts |= OPT_HEXHDR;
break;
}
- log = argv[optind] ? fopen(argv[1], "a") : stdout;
- setvbuf(log, NULL, _IONBF, 0);
- if (flushed)
- fprintf(log, "%d bytes flushed from log\n", flushed);
-
- while (1) {
- assert(read(fd, &iplci, sizeof(struct ipl_ci)) ==
- sizeof(struct ipl_ci));
- assert(iplci.hlen > 0 && iplci.hlen <= 92);
- len = (u_int)iplci.plen;
- assert(len <= 128);
- assert(read(fd, buf, iplci.hlen + iplci.plen) ==
- (iplci.hlen + iplci.plen));
- printpacket(log, buf, &iplci, opts);
+ if ((fd == -1) && (fd = open(iplfile, O_RDONLY)) == -1) {
+ (void) fprintf(stderr, "%s: ", IPL_NAME);
+ perror("open");
+ exit(-1);
+ }
+
+ if (!(opts & OPT_SYSLOG)) {
+ log = argv[optind] ? fopen(argv[optind], "a") : stdout;
+ setvbuf(log, NULL, _IONBF, 0);
}
- /* NOTREACHED */
+
+ if (flushed) {
+ if (opts & OPT_SYSLOG)
+ syslog(LOG_INFO, "%d bytes flushed from log\n",
+ flushed);
+ else
+ fprintf(log, "%d bytes flushed from log\n", flushed);
+ }
+
+ for (doread = 1; doread; )
+ switch (readlogentry(fd, &n, buf, sizeof(buf), log))
+ {
+ case -1 :
+ if (opts & OPT_SYSLOG)
+ syslog(LOG_ERR, "read: %m\n");
+ else
+ perror("read");
+ doread = 0;
+ break;
+ case 1 :
+ if (opts & OPT_SYSLOG)
+ syslog(LOG_ERR, "aborting logging\n");
+ else
+ fprintf(log, "aborting logging\n");
+ doread = 0;
+ break;
+ case 2 :
+ break;
+ case 0 :
+ printpacket(log, buf, n, opts);
+ break;
+ }
exit(0);
/* NOTREACHED */
}