added decpcap.c and decpcap.h code
This commit is contained in:
206
decpcap.c
Normal file
206
decpcap.c
Normal file
@@ -0,0 +1,206 @@
|
||||
#include <net/ethernet.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip6.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <pcap.h>
|
||||
#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);
|
||||
}
|
||||
51
decpcap.h
Normal file
51
decpcap.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <pcap.h>
|
||||
|
||||
/* 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);
|
||||
Reference in New Issue
Block a user