PERFORCE change 145272 for review

Rui Paulo rpaulo at FreeBSD.org
Tue Jul 15 09:33:52 UTC 2008


http://perforce.freebsd.org/chv.cgi?CH=145272

Change 145272 by rpaulo at 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 <assert.h>
+#include <err.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
+#include <stdarg.h>
 #include <unistd.h>
+#include <arpa/inet.h>
 #include <sys/queue.h>
 #include <pcap.h>
 
+#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 <sys/types.h>
@@ -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 <err.h>
@@ -33,18 +33,19 @@
 #include <pcap.h>
 #include <sys/queue.h>
 
+#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 <sys/socketvar.h>
 #include <netinet/in.h>
 #include <netinet/tcp.h>
 #include <netinet/tcp_seq.h>
+#include <netinet/tcp_var.h>
 
 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 <stdio.h>
@@ -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;
 }


More information about the p4-projects mailing list