From owner-p4-projects@FreeBSD.ORG Tue Jul 15 09:33:52 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 296A4106566C; Tue, 15 Jul 2008 09:33:52 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E137F1065670 for ; Tue, 15 Jul 2008 09:33:51 +0000 (UTC) (envelope-from rpaulo@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id C710F8FC31 for ; Tue, 15 Jul 2008 09:33:51 +0000 (UTC) (envelope-from rpaulo@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m6F9Xpqf012141 for ; Tue, 15 Jul 2008 09:33:51 GMT (envelope-from rpaulo@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.2/8.14.1/Submit) id m6F9XpoU012139 for perforce@freebsd.org; Tue, 15 Jul 2008 09:33:51 GMT (envelope-from rpaulo@FreeBSD.org) Date: Tue, 15 Jul 2008 09:33:51 GMT Message-Id: <200807150933.m6F9XpoU012139@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to rpaulo@FreeBSD.org using -f From: Rui Paulo To: Perforce Change Reviews Cc: Subject: PERFORCE change 145272 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 Jul 2008 09:33:52 -0000 http://perforce.freebsd.org/chv.cgi?CH=145272 Change 145272 by rpaulo@rpaulo_epsilon on 2008/07/15 09:33:33 Improve the debugging framework. Use struct tcpcb available from the OS. When dumping a pcap file, also create a textfile explaining the error and the current tcpcb values. Affected files ... .. //depot/projects/soc2008/rpaulo-tcpad/Makefile#10 edit .. //depot/projects/soc2008/rpaulo-tcpad/debug.h#4 edit .. //depot/projects/soc2008/rpaulo-tcpad/dumper.c#8 edit .. //depot/projects/soc2008/rpaulo-tcpad/dumper.h#6 edit .. //depot/projects/soc2008/rpaulo-tcpad/linkhdr.c#8 edit .. //depot/projects/soc2008/rpaulo-tcpad/main.c#8 edit .. //depot/projects/soc2008/rpaulo-tcpad/tcpad.h#11 edit .. //depot/projects/soc2008/rpaulo-tcpad/timer.c#4 edit Differences ... ==== //depot/projects/soc2008/rpaulo-tcpad/Makefile#10 (text+ko) ==== @@ -1,9 +1,9 @@ -# $P4: //depot/projects/soc2008/rpaulo-tcpad/Makefile#9 $ +# $P4: //depot/projects/soc2008/rpaulo-tcpad/Makefile#10 $ PROG=tcpad SRCS=main.c device.c linkhdr.c handler.c helper.c dumper.c timer.c CFLAGS+=-DDEBUG -ggdb -CFLAGS+=-DDUMPER_PATH=\"dumpfiles/\" +CFLAGS+=-DDUMPER_PATH=\"dumpfiles\" WARNS=5 LDADD=-lpcap ==== //depot/projects/soc2008/rpaulo-tcpad/debug.h#4 (text+ko) ==== @@ -23,19 +23,30 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $P4: //depot/projects/soc2008/rpaulo-tcpad/debug.h#3 $ + * $P4: //depot/projects/soc2008/rpaulo-tcpad/debug.h#4 $ */ #ifndef _DEBUG_H_ #define _DEBUG_H_ #ifdef DEBUG -#define DPRINTF(...) do { \ - fprintf(stderr, "%s: ", __func__); \ - fprintf(stderr, __VA_ARGS__); \ + +unsigned int debug_level; +#define DEBUG_TIMER 0x001 +#define DEBUG_FSM 0x002 +#define DEBUG_DUMP 0x004 +#define DEBUG_LINK 0x008 +#define DEBUG_SEQ 0x010 +#define DEBUG_ALL 0xfff + +#define DPRINTF(level, ...) do { \ + if (debug_level & level) { \ + fprintf(stderr, "%s: ", __func__); \ + fprintf(stderr, __VA_ARGS__); \ + } \ } while (0) #else -#define DPRINTF +#define DPRINTF /* */ #endif #endif /* _DEBUG_H_ */ ==== //depot/projects/soc2008/rpaulo-tcpad/dumper.c#8 (text+ko) ==== @@ -23,17 +23,21 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $P4: //depot/projects/soc2008/rpaulo-tcpad/dumper.c#7 $ + * $P4: //depot/projects/soc2008/rpaulo-tcpad/dumper.c#8 $ */ #include +#include #include #include #include +#include #include +#include #include #include +#include "tcpad.h" #include "debug.h" #include "dumper.h" @@ -58,36 +62,87 @@ } /** - * An error occured. Dump the packet list to a file. + * An error occured. Dump the packet list to a file and create a meaningful + * descriptive text file. */ void -dumper_error(pcap_t *p, struct dumppkth *head) +dumper_error(struct tcpc *cp, const char *fmt, ...) { int i; pcap_dumper_t *pd; struct dumppkt *dp; - char path[128]; + char cappath[128], path[128]; + FILE *fp; + va_list ap; for (i = 0; i < 3000; i++) { - - snprintf(path, sizeof(path), "%s/dump%d.cap", DUMPER_PATH, - i); - if (access(path, W_OK) != 0) + snprintf(path, sizeof(path), "%s/dump%d.txt", DUMPER_PATH, i); + if (access(path, F_OK) != 0) break; } if (i == 3000) { - fprintf(stderr, "%s, %s is full!\n", __func__, DUMPER_PATH); + fprintf(stderr, "%s: %s is full!\n", __func__, DUMPER_PATH); + return; + } + + fp = fopen(path, "w"); + if (fp == NULL) { + warn("failure to open dump file: %s", path); return; } - pd = pcap_dump_open(p, path); + snprintf(cappath, sizeof(cappath), "%s/dump%d.cap", DUMPER_PATH, i); + pd = pcap_dump_open(p, cappath); if (pd == NULL) { fprintf(stderr, "%s: %s\n", __func__, pcap_geterr(p)); + fclose(fp); + unlink(path); return; } - TAILQ_FOREACH(dp, head, entries) + TAILQ_FOREACH(dp, cp->pktshead, entries) pcap_dump((u_char *)pd, &dp->pheader, dp->headers); pcap_dump_close(pd); + + fprintf(fp, "tcpad (TCP Anomaly Detector) version xx.xx\n\n"); + fprintf(fp, "Related pcap file:\t%s\n", cappath); + fprintf(fp, "Error message:\t\t"); + va_start(ap, fmt); + vfprintf(fp, fmt, ap); + va_end(ap); + fprintf(fp, "\n\n"); + fprintf(fp, "\t\t| Local endpoint | Remote endpoint |\n"); + fprintf(fp, "IP: \t\t| %18s | ", inet_ntoa(cp->sv4addr)); + fprintf(fp, "%18s |\n", inet_ntoa(cp->dv4addr)); + fprintf(fp, "TCP Port:\t| %18d | %18d |\n", cp->sport, cp->dport); + fprintf(fp, "\n"); +#define DUMPER_TPFIELD(cp, field, name) do { \ + fprintf(fp, "%s:\t", name); \ + if (strlen(name) < 7) \ + fprintf(fp, "\t"); \ + if (cp) \ + fprintf(fp, "| %18u | ", cp->tp.field); \ + else \ + fprintf(fp, "| | "); \ + if (cp->rcp) \ + fprintf(fp, "%18u |", cp->rcp->tp.field); \ + \ + fprintf(fp, "\n"); \ +} while (0) + DUMPER_TPFIELD(cp, t_state, "FSM state"); + DUMPER_TPFIELD(cp, iss, "ISS"); + DUMPER_TPFIELD(cp, snd_una, "SND.UNA"); + DUMPER_TPFIELD(cp, snd_max, "SND.MAX"); + DUMPER_TPFIELD(cp, snd_nxt, "SND.NXT"); + DUMPER_TPFIELD(cp, snd_up, "SND.UP"); + DUMPER_TPFIELD(cp, snd_wl1, "SND.WL1"); + DUMPER_TPFIELD(cp, snd_wl2, "SND.WL2"); + DUMPER_TPFIELD(cp, snd_wnd, "SND.WND"); + DUMPER_TPFIELD(cp, irs, "IRS"); + DUMPER_TPFIELD(cp, rcv_nxt, "RCV.NXT"); + DUMPER_TPFIELD(cp, rcv_wnd, "RCV.WND"); + DUMPER_TPFIELD(cp, rcv_up, "RCV.UP"); +#undef DUMPER_TPFIELD + fclose(fp); } /** @@ -100,7 +155,7 @@ assert(head != NULL); - DPRINTF("freeing dumppkth struct @ %p\n", head); + DPRINTF(DEBUG_DUMP, "freeing dumppkth struct @ %p\n", head); p1 = TAILQ_FIRST(head); while (p1 != NULL) { p2 = TAILQ_NEXT(p1, entries); ==== //depot/projects/soc2008/rpaulo-tcpad/dumper.h#6 (text+ko) ==== @@ -23,7 +23,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $P4: //depot/projects/soc2008/rpaulo-tcpad/dumper.h#5 $ + * $P4: //depot/projects/soc2008/rpaulo-tcpad/dumper.h#6 $ */ #ifndef _DUMPER_H_ @@ -41,8 +41,7 @@ void dumper_addpkt(struct dumppkth *head, const struct pcap_pkthdr *ph, const unsigned char *headers); -void dumper_error(pcap_t *, struct dumppkth *head); +void dumper_error(struct tcpc *cp, const char *msg, ...); void dumper_free(struct dumppkth *head); - #endif /* _DUMPER_H_ */ ==== //depot/projects/soc2008/rpaulo-tcpad/linkhdr.c#8 (text+ko) ==== @@ -23,7 +23,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $P4: //depot/projects/soc2008/rpaulo-tcpad/linkhdr.c#7 $ + * $P4: //depot/projects/soc2008/rpaulo-tcpad/linkhdr.c#8 $ */ #include @@ -62,16 +62,16 @@ { int i; - DPRINTF("dlt = %d\n", dlt); + DPRINTF(DEBUG_LINK, "dlt = %d\n", dlt); for (i = 0; linktypes[i].type != -1; i++) { if (linktypes[i].type == dlt) { - DPRINTF("hlen = %d\n", linktypes[i].skip); + DPRINTF(DEBUG_LINK, "hlen = %d\n", linktypes[i].skip); return (linktypes[i].skip); } } - DPRINTF("dlt not found\n"); + DPRINTF(DEBUG_LINK, "dlt not found\n"); return (-1); } ==== //depot/projects/soc2008/rpaulo-tcpad/main.c#8 (text+ko) ==== @@ -23,7 +23,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $P4: //depot/projects/soc2008/rpaulo-tcpad/main.c#7 $ + * $P4: //depot/projects/soc2008/rpaulo-tcpad/main.c#8 $ */ #include @@ -33,18 +33,19 @@ #include #include +#include "tcpad.h" #include "dumper.h" -#include "tcpad.h" #include "device.h" #include "linkhdr.h" #include "handler.h" #include "timer.h" +#include "debug.h" static void usage(void) { fprintf(stderr, "%s\n", pcap_lib_version()); - fprintf(stderr, "%s: [-r file] [-pD] [-i interface] [-s snaplen]\n", + fprintf(stderr, "%s: [-r file] [-p] [-i interface] [-s snaplen]\n", getprogname()); exit(1); } @@ -61,12 +62,17 @@ struct bpf_program fp; char filter[] = "ip proto \\tcp"; int linkhlen; + const char options[] = "r:pi:s:l" +#ifdef DEBUG + "d:" +#endif + ; promisc = 1; - snaplen = 100; + snaplen = 78; interface = NULL; readfile = NULL; - while ((ch = getopt(argc, argv, "r:pDi:s:l")) != -1) { + while ((ch = getopt(argc, argv, options)) != -1) { switch (ch) { case 'r': readfile = optarg; @@ -83,6 +89,11 @@ device_listall(); exit(0); break; +#ifdef DEBUG + case 'd': + debug_level = atoi(optarg); + break; +#endif case '?': default: usage(); @@ -92,6 +103,8 @@ argc -= optind; argv += optind; + debug_level = DEBUG_ALL; + if (readfile) p = pcap_open_offline(readfile, errbuf); else { ==== //depot/projects/soc2008/rpaulo-tcpad/tcpad.h#11 (text+ko) ==== @@ -23,15 +23,17 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $P4: //depot/projects/soc2008/rpaulo-tcpad/tcpad.h#10 $ + * $P4: //depot/projects/soc2008/rpaulo-tcpad/tcpad.h#11 $ */ #ifndef _TCPAD_H_ #define _TCPAD_H_ +#include #include #include #include +#include pcap_t *p; @@ -41,26 +43,10 @@ struct in_addr dv4addr; unsigned short dport; unsigned short sport; - - /* TCP internal variables, from tcpcb */ - int t_state; /* TCP FSM state */ - tcp_seq snd_una; - tcp_seq snd_nxt; - tcp_seq snd_wnd; - tcp_seq snd_up; - tcp_seq snd_wl1; - tcp_seq snd_wl2; - tcp_seq iss; - - tcp_seq rcv_nxt; - tcp_seq rcv_wnd; - tcp_seq rcv_up; - tcp_seq irs; - int isv6; struct dumppkth *pktshead; + struct tcpcb tp; struct tcpc *rcp; - }; LIST_HEAD(tcpchead, tcpc) tcpchead; ==== //depot/projects/soc2008/rpaulo-tcpad/timer.c#4 (text+ko) ==== @@ -23,7 +23,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $P4: //depot/projects/soc2008/rpaulo-tcpad/timer.c#3 $ + * $P4: //depot/projects/soc2008/rpaulo-tcpad/timer.c#4 $ */ #include @@ -54,7 +54,7 @@ struct itimerval itp; if (firstime) { - DPRINTF("setting up signal function\n"); + DPRINTF(DEBUG_TIMER, "setting up signal function\n"); signal(SIGALRM, timer_sigalrm); firstime = 0; } @@ -75,17 +75,25 @@ timer_sigalrm(int __unused sig) { struct tcpc *cp, *cp_t; + int nc; + static int prevnc; + nc = 0; LIST_FOREACH_SAFE(cp, &tcpchead, entries, cp_t) { - if (cp->t_state == TCPS_TIME_WAIT) { - DPRINTF("freeing tcp connection @ %p\n", cp); + nc++; + if (cp->tp.t_state == TCPS_TIME_WAIT) { + DPRINTF(DEBUG_TIMER, "freeing tcp connection @ %p\n", + cp); LIST_REMOVE(cp, entries); if (cp->pktshead) dumper_free(cp->pktshead); cp->pktshead = NULL; cp->rcp->pktshead = NULL; free(cp); + nc--; } } - + if (nc != prevnc) + DPRINTF(DEBUG_TIMER, "connections being tracked: %d\n", nc); + prevnc = nc; }