diff --git a/Makefile b/Makefile index 9f9982b..85ce99b 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ DESTDIR := /usr/local bin := $(DESTDIR)/bin man8 := $(DESTDIR)/share/man/man8/ -all: nethogs +all: nethogs decpcap_test #CFLAGS=-g -Wall CFLAGS=-O2 @@ -29,6 +29,9 @@ install: nethogs nethogs.8 nethogs: nethogs.cpp $(OBJS) $(CXX) $(CFLAGS) nethogs.cpp $(OBJS) -o nethogs -lpcap -lm -lncurses -DVERSION=\"$(VERSION)\" -DSUBVERSION=\"$(SUBVERSION)\" -DMINORVERSION=\"$(MINORVERSION)\" +decpcap_test: decpcap_test.cpp decpcap.o + $(CXX) $(CFLAGS) decpcap_test.cpp decpcap.o -o decpcap_test -lpcap -lm + #-lefence refresh.o: refresh.cpp refresh.h nethogs.h diff --git a/decpcap.c b/decpcap.c index 3c542a7..8edee55 100644 --- a/decpcap.c +++ b/decpcap.c @@ -9,18 +9,11 @@ /* functions to set up a handle (which is basically just a pcap handle) */ -struct dp_handle * dp_open_live(char * device, int snaplen, int promisc, int to_ms, char * ebuf) +struct dp_handle * dp_fillhandle(pcap_t * phandle) { struct dp_handle * retval = (struct dp_handle *) malloc (sizeof (struct dp_handle)); - pcap_t * temp = pcap_open_live(device, snaplen, promisc, to_ms, ebuf); int i; - retval->pcap_handle = temp; - - if (retval->pcap_handle == NULL) - { - free (retval); - return NULL; - } + retval->pcap_handle = phandle; for (i = 0; i < dp_n_packet_types; i++) { @@ -36,13 +29,40 @@ struct dp_handle * dp_open_live(char * device, int snaplen, int promisc, int to_ case (DLT_PPP): fprintf(stdout, "PPP link detected\n"); break; + case (DLT_LINUX_SLL): + fprintf(stdout, "Linux Cooked Socket link detected\n"); + break; default: fprintf(stdout, "No PPP or Ethernet link: %d\n", retval->linktype); // TODO maybe error? or 'other' callback? break; } - return retval; + return retval; +} + +struct dp_handle * dp_open_offline(char * fname, char * ebuf) +{ + pcap_t * temp = pcap_open_offline(fname, ebuf); + + if (temp == NULL) + { + return NULL; + } + + return dp_fillhandle(temp); +} + +struct dp_handle * dp_open_live(char * device, int snaplen, int promisc, int to_ms, char * ebuf) +{ + pcap_t * temp = pcap_open_live(device, snaplen, promisc, to_ms, ebuf); + + if (temp == NULL) + { + return NULL; + } + + return dp_fillhandle(temp); } /* functions to add callbacks */ @@ -192,6 +212,48 @@ void dp_parse_ppp (struct dp_handle * handle, const dp_header * header, const u_ } } +/* linux cooked header, i hope ;) */ +/* glanced from libpcap/ssl.h */ +#define SLL_ADDRLEN 8 /* length of address field */ +struct sll_header { + u_int16_t sll_pkttype; /* packet type */ + u_int16_t sll_hatype; /* link-layer address type */ + u_int16_t sll_halen; /* link-layer address length */ + u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */ + u_int16_t sll_protocol; /* protocol */ +}; + +void dp_parse_linux_cooked (struct dp_handle * handle, const dp_header * header, const u_char * packet) +{ + const struct sll_header * sll = (struct sll_header *) packet; + u_char * payload = (u_char *) packet + sizeof (struct sll_header); + + /* call handle if it exists */ + if (handle->callback[dp_packet_sll] != NULL) + { + int done = (handle->callback[dp_packet_sll]) + (handle->userdata, header, packet); + + /* return if handle decides we're done */ + if (done) + return; + } + + /* parse payload */ + switch (sll->sll_protocol) + { + case (0x0008): + dp_parse_ip (handle, header, payload); + break; + case (0xDD86): + dp_parse_ip6 (handle, header, payload); + break; + default: + // TODO: support for other than IPv4 / IPv6 + break; + } +} + /* functions to do the monitoring */ void dp_pcap_callback (u_char * u_handle, const struct pcap_pkthdr * header, const u_char * packet) { @@ -209,12 +271,16 @@ void dp_pcap_callback (u_char * u_handle, const struct pcap_pkthdr * header, con case (DLT_PPP): dp_parse_ppp (handle, header, packet); break; + case (DLT_LINUX_SLL): + dp_parse_linux_cooked (handle, header, packet); + break; case (DLT_RAW): case (DLT_NULL): - // just a guess + // hope for the best dp_parse_ip (handle, header, packet); + break; default: - // TODO maybe error? or 'other' callback? + fprintf(stdout, "Unknown linktype %d", handle->linktype); break; } free (userdata_copy); @@ -229,3 +295,8 @@ int dp_dispatch (struct dp_handle * handle, int count, u_char *user, int size) { int dp_setnonblock (struct dp_handle * handle, int i, char * errbuf) { return pcap_setnonblock (handle->pcap_handle, i, errbuf); } + +char * dp_geterr (struct dp_handle * handle) +{ + return pcap_geterr (handle->pcap_handle); +} diff --git a/decpcap.h b/decpcap.h index 545ddee..e67fffc 100644 --- a/decpcap.h +++ b/decpcap.h @@ -2,11 +2,14 @@ #include #include +#define DP_ERRBUFF_SIZE PCAP_ERRBUF_SIZE + /* definitions */ enum dp_packet_type { dp_packet_ethernet, dp_packet_ppp, + dp_packet_sll, dp_packet_ip, dp_packet_ip6, dp_packet_tcp, @@ -37,6 +40,7 @@ struct dp_handle { /* functions to set up a handle (which is basically just a pcap handle) */ struct dp_handle * dp_open_live(char * device, int snaplen, int promisc, int to_ms, char * ebuf); +struct dp_handle * dp_open_offline(char * fname, char * ebuf); /* functions to add callbacks */ @@ -56,4 +60,4 @@ int dp_datalink(struct dp_handle * handle); int dp_setnonblock (struct dp_handle * handle, int i, char * errbuf); - +char * dp_geterr (struct dp_handle * handle);