From 23a56f95a6bd898349ba03c77169f2f8009305fc Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Sat, 11 Sep 2004 15:01:28 +0000 Subject: [PATCH] added decpcap.c and decpcap.h code --- decpcap.c | 206 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ decpcap.h | 51 ++++++++++++++ 2 files changed, 257 insertions(+) create mode 100644 decpcap.c create mode 100644 decpcap.h diff --git a/decpcap.c b/decpcap.c new file mode 100644 index 0000000..5335920 --- /dev/null +++ b/decpcap.c @@ -0,0 +1,206 @@ +#include +#include +#include +#include +#include +#include +#include "decpcap.h" + +/* data container for callback-references */ + +/* functions to set up a handle (which is basically just a pcap handle) */ + +struct dp_handle * dp_open_live(char * device, enum dp_link_type link, int snaplen, int promisc, int to_ms, char * ebuf) +{ + 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; + } + + for (i = 0; i < dp_n_packet_types; i++) + { + retval->callback[i] = NULL; + } + retval->linktype = link; + + return retval; +} + +/* functions to add callbacks */ + +void dp_addcb (struct dp_handle * handle, enum dp_packet_type type, dp_callback callback) +{ + handle->callback[type] = callback; +} + +/* functions for parsing the payloads */ + +void dp_parse_tcp (struct dp_handle * handle, const dp_header * header, const u_char * packet) +{ + const struct tcphdr * tcp = (struct tcphdr *) packet; + u_char * payload = (u_char *) packet + sizeof (struct tcphdr); + + if (handle->callback[dp_packet_tcp] != NULL) + { + int done = (handle->callback[dp_packet_tcp]) + (handle->userdata, header, packet); + if (done) + return; + } + // TODO +} + +void dp_parse_ip (struct dp_handle * handle, const dp_header * header, const u_char * packet) +{ + const struct ip * ip = (struct ip *) packet; + u_char * payload = (u_char *) packet + sizeof (struct ip); + + if (handle->callback[dp_packet_ip] != NULL) + { + int done = (handle->callback[dp_packet_ip]) + (handle->userdata, header, packet); + if (done) + return; + } + switch (ip->ip_p) + { + case (6): + dp_parse_tcp (handle, header, payload); + break; + default: + // TODO + } +} + +void dp_parse_ip6 (struct dp_handle * handle, const dp_header * header, const u_char * packet) +{ + const struct ip6_hdr * ip6 = (struct ip6_hdr *) packet; + u_char * payload = (u_char *) packet + sizeof (struct ip6_hdr); + + if (handle->callback[dp_packet_ip6] != NULL) + { + int done = (handle->callback[dp_packet_ip6]) + (handle->userdata, header, packet); + if (done) + return; + } + switch ((ip6->ip6_ctlun).ip6_un1.ip6_un1_nxt) + { + case (6): + dp_parse_tcp (handle, header, payload); + break; + default: + // TODO + } +} + +void dp_parse_ethernet (struct dp_handle * handle, const dp_header * header, const u_char * packet) +{ + const struct ether_header * ethernet = (struct ether_header *)packet; + u_char * payload = (u_char *) packet + sizeof (struct ether_header); + + /* call handle if it exists */ + if (handle->callback[dp_packet_ethernet] != NULL) + { + int done = (handle->callback[dp_packet_ethernet]) + (handle->userdata, header, packet); + + /* return if handle decides we're done */ + if (done) + return; + } + + /* parse payload */ + switch (ethernet->ether_type) + { + case (0x0008): + dp_parse_ip (handle, header, payload); + break; + case (0xDD86): + dp_parse_ip6 (handle, header, payload); + break; + default: + // TODO + } +} + +/* ppp header, i hope ;) */ +/* glanced from ethereal, it's 16 bytes, and the payload packet type is + * in the last 2 bytes... */ +struct ppp_header { + u_int16_t dummy1; + u_int16_t dummy2; + u_int16_t dummy3; + u_int16_t dummy4; + u_int16_t dummy5; + u_int16_t dummy6; + u_int16_t dummy7; + + u_int16_t packettype; +}; + +void dp_parse_ppp (struct dp_handle * handle, const dp_header * header, const u_char * packet) +{ + const struct ppp_header * ppp = (struct ppp_header *) packet; + u_char * payload = (u_char *) packet + sizeof (struct ppp_header); + + /* call handle if it exists */ + if (handle->callback[dp_packet_ppp] != NULL) + { + int done = (handle->callback[dp_packet_ppp]) + (handle->userdata, header, packet); + + /* return if handle decides we're done */ + if (done) + return; + } + + /* parse payload */ + switch (ppp->packettype) + { + case (0x0008): + dp_parse_ip (handle, header, payload); + break; + case (0xDD86): + dp_parse_ip6 (handle, header, payload); + break; + default: + // TODO + } +} + +/* functions to do the monitoring */ +void dp_pcap_callback (u_char * u_handle, const struct pcap_pkthdr * header, const u_char * packet) +{ + struct dp_handle * handle = (struct dp_handle *) u_handle; + struct dp_header; + + /* make a copy of the userdata for every packet */ + u_char * userdata_copy = (u_char *) malloc (handle->userdata_size); + memcpy (userdata_copy, handle->userdata, handle->userdata_size); + + switch (handle->linktype) { + case (dp_link_ethernet): + dp_parse_ethernet (handle, header, packet); + break; + case (dp_link_ppp): + // TODO + break; + default: + // TODO maybe error? or 'other' callback? + break; + } + free (userdata_copy); +} + +int dp_dispatch (struct dp_handle * handle, int count, u_char *user, int size) { + handle->userdata = user; + handle->userdata_size = size; + return pcap_dispatch (handle->pcap_handle, count, dp_pcap_callback, (u_char *)handle); +} diff --git a/decpcap.h b/decpcap.h new file mode 100644 index 0000000..2b74baf --- /dev/null +++ b/decpcap.h @@ -0,0 +1,51 @@ +#include +#include +#include + +/* definitions */ + +enum dp_packet_type { + dp_packet_ethernet, + dp_packet_ppp, + dp_packet_ip, + dp_packet_ip6, + dp_packet_tcp, + dp_packet_udp, + dp_n_packet_types +}; + +enum dp_link_type { + dp_link_ethernet, + dp_link_ppp, + dp_n_link_types +}; + +/*struct dp_header { +};*/ +typedef struct pcap_pkthdr dp_header; + +typedef int (*dp_callback)(u_char *, const dp_header *, const u_char *); + +struct dp_handle { + pcap_t * pcap_handle; + dp_callback callback [dp_n_packet_types]; + enum dp_link_type linktype; + u_char * userdata; + int userdata_size; +}; + +/* functions to set up a handle (which is basically just a pcap handle) */ + +struct dp_handle * dp_open_live(char * device, enum dp_link_type link, int snaplen, int promisc, int to_ms, char * ebuf); + +/* functions to add callbacks */ + +void dp_addcb (struct dp_handle * handle, enum dp_packet_type type, dp_callback callback); + +/* functions to parse payloads */ + +void dp_parse (enum dp_packet_type type, void * packet); + +/* functions to start monitoring */ + +int dp_dispatch (struct dp_handle * handler, int count, u_char *user, int size);