Implement --hexdump
authorEmil Mikulic <emikulic@gmail.com>
Sat, 25 Apr 2009 11:20:55 +0000 (21:20 +1000)
committerEmil Mikulic <emikulic@gmail.com>
Sat, 25 Apr 2009 11:20:55 +0000 (21:20 +1000)
cap.c
darkstat.8
darkstat.c
decode.c
decode.h

diff --git a/cap.c b/cap.c
index 986bed5..4c53e59 100644 (file)
--- a/cap.c
+++ b/cap.c
@@ -1,5 +1,5 @@
 /* darkstat 3
- * copyright (c) 2001-2008 Emil Mikulic.
+ * copyright (c) 2001-2009 Emil Mikulic.
  *
  * cap.c: interface to libpcap.
  *
@@ -28,7 +28,7 @@
 #include <string.h>
 #include <unistd.h>
 
-extern int want_pppoe, want_macs;
+extern int want_pppoe, want_macs, want_hexdump;
 
 /* The cap process life-cycle:
  *
@@ -92,7 +92,7 @@ cap_init(const char *device, const char *filter, int promisc)
    errbuf[0] = '\0'; /* zero length string */
    pcap = pcap_open_live(
       tmp_device,
-      caplen,      /* snaplen */
+      caplen,
       promisc,
       CAP_TIMEOUT,
       errbuf);
@@ -210,6 +210,44 @@ cap_stats_update(void)
    pkts_drop = ps.ps_drop;
 }
 
+/*
+ * Print hexdump of received packet.
+ */
+static void
+hexdump(const u_char *buf, const uint32_t len)
+{
+   uint32_t i, col;
+
+   printf("packet of %u bytes:\n", len);
+   col = 0;
+   for (i=0, col=0; i<len; i++) {
+      if (col == 0) printf(" ");
+      printf("%02x", buf[i]);
+      if (i+1 == linkhdr->hdrlen)
+         printf("[");
+      else if (i+1 == linkhdr->hdrlen + IP_HDR_LEN)
+         printf("]");
+      else printf(" ");
+      col += 3;
+      if (col >= 72) {
+         printf("\n");
+         col = 0;
+      }
+   }
+   if (col != 0) printf("\n");
+   printf("\n");
+}
+
+/*
+ * Callback function for pcap_dispatch() which chains to the decoder specified
+ * in linkhdr struct.
+ */
+static void
+callback(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
+{
+   if (want_hexdump) hexdump(bytes, h->caplen);
+   linkhdr->handler(user, h, bytes);
+}
 
 /*
  * Process any packets currently in the capture buffer.
@@ -241,7 +279,7 @@ cap_poll(fd_set *read_set
       ret = pcap_dispatch(
             pcap,
             -1,               /* count, -1 = entire buffer */
-            linkhdr->handler, /* callback func from decode.c */
+            callback,
             NULL);            /* user */
 
       if (ret < 0) {
@@ -322,7 +360,7 @@ cap_from_file(const char *capfile, const char *filter)
    ret = pcap_dispatch(
          pcap,
          -1,               /* count, -1 = entire buffer */
-         linkhdr->handler, /* callback func from decode.c */
+         callback,
          NULL);            /* user */
 
    if (ret < 0)
index b095653..65071c2 100644 (file)
@@ -1,6 +1,6 @@
 .\"
 .\" darkstat 3
-.\" Copyright 2001-2008, Emil Mikulic.
+.\" Copyright 2001-2009, Emil Mikulic.
 .\"
 .\" You may use, modify and redistribute this file under the terms of the
 .\" GNU General Public License version 2. (see COPYING.GPL)
@@ -57,6 +57,8 @@ darkstat \- network statistics gatherer
 .BI \-\-ports\-keep " count"
 ] [
 .BI \-\-highest\-port " port"
+] [
+.BI \-\-hexdump
 ]
 .\"
 .SH DESCRIPTION
@@ -290,6 +292,11 @@ for.
 This can be used to hide ephemeral ports.
 By default, all ports are tracked.
 .\"
+.TP
+.BI \-\-hexdump
+Show hex dumps of received traffic.
+This is only for debugging, and implies \-\-verbose and \-\-no\-daemon.
+.\"
 .\" --------------------------------------------------------------------
 .SH USAGE EXAMPLES
 To gather statistics on the
index 736e28f..e974d52 100644 (file)
@@ -168,6 +168,9 @@ unsigned int highest_port = 65535;
 static void cb_highest_port(const char *arg)
 { highest_port = parsenum(arg, 65535); }
 
+int want_hexdump = 0;
+static void cb_hexdump(const char *arg _unused_) { want_hexdump = 1; }
+
 /* --- */
 
 struct cmdline_arg {
@@ -200,6 +203,7 @@ static struct cmdline_arg cmdline_args[] = {
    {"--ports-max",    "count",           cb_ports_max,    0},
    {"--ports-keep",   "count",           cb_ports_keep,   0},
    {"--highest-port", "port",            cb_highest_port, 0},
+   {"--hexdump",      NULL,              cb_hexdump,      0},
    {NULL,             NULL,              NULL,            0}
 };
 
@@ -310,6 +314,16 @@ parse_cmdline(const int argc, char * const *argv)
    }
    verbosef("max %u ports per host, cutting down to %u when exceeded",
       ports_max, ports_keep);
+
+   if (want_hexdump && !want_verbose) {
+      want_verbose = 1;
+      verbosef("--hexdump implies --verbose");
+   }
+
+   if (want_hexdump && want_daemonize) {
+      want_daemonize = 0;
+      verbosef("--hexdump implies --no-daemon");
+   }
 }
 
 static void
index 1abbf1a..57e62c6 100644 (file)
--- a/decode.c
+++ b/decode.c
@@ -1,5 +1,5 @@
 /* darkstat 3
- * copyright (c) 2001-2007 Emil Mikulic.
+ * copyright (c) 2001-2009 Emil Mikulic.
  *
  * decode.c: packet decoding.
  *
index 5128ec9..31a9fa1 100644 (file)
--- a/decode.h
+++ b/decode.h
@@ -1,5 +1,5 @@
 /* darkstat 3
- * copyright (c) 2001-2007 Emil Mikulic.
+ * copyright (c) 2001-2009 Emil Mikulic.
  *
  * decode.h: packet decoding.
  *
@@ -26,7 +26,7 @@
 
 typedef struct {
    int linktype;
-   int hdrlen;
+   unsigned int hdrlen;
    pcap_handler handler;
 } linkhdr_t;