[Snort-devel] divert packet acquisition engine

Matthew George mgeorge at ...120...
Tue Feb 6 06:33:33 EST 2001


attached is a FreeBSD implementation (using divert sockets) of the packet
acquisition engine submitted by Todd Lewis yesterday.

-- 
Matthew George
Security Analyst
SecureWorks
404.327.6339x131
-------------- next part --------------
/********************************************************************
 * paengine_divert.c: divert-based packet acquisition engine        *
 * (c) 2000, Matthew George, SecureWorks, <mgeorge at secureworks.net> *
 * released under the GNU GPL, v2                                   *
 ********************************************************************/

#include "paengine.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <stdlib.h> /* malloc */

#define PAENGINE_NAME divert
#define PADIVERT_PORT 4020

static int my_configure(char *);
static int my_init(void);
static pa_packet * my_get_packet(void);
static int my_dispose_packet(pa_packet *);
static int my_close(void);
static int my_get_devtype(void);
static int my_get_capabilities(void);

static int s; // divert socket fd

#ifdef ENABLE_DYN_MODULES
paengine_s paengine = {
#else /* ENABLE_DYN_MODULES */
paengine_s paengine_divert= {
#endif /* ENABLE_DYN_MODULES */
   "divert",
   my_configure,
   my_init,
   my_get_packet,
   my_dispose_packet,
   my_close,
   my_get_devtype,
   my_get_capabilities
};

typedef struct _pa_packet_divert {
	pa_packet 				packet;
	unsigned char 			buf[IP_MAXPACKET];
	struct sockaddr 		addr;
	socklen_t				addrlen;
} pa_packet_divert;


/* this could be used to set the divert port ... */
static int
my_configure(char *config)
{
   return (0);
}


static int
my_init(void)
{
	struct sockaddr_in	addr;

#ifdef DEBUG
	printf("*** init ***\n");
#endif

	if ((s = socket(PF_INET, SOCK_RAW, IPPROTO_DIVERT)) == -1)
	{
		perror("Could not create divert socket");
		exit(-1);
	}

	addr.sin_family 		= AF_INET;
	addr.sin_port			= PADIVERT_PORT;
	addr.sin_addr.s_addr	= INADDR_ANY;

	if (bind(s, (struct sockaddr *) &addr, sizeof(struct sockaddr)) == -1)
	{
		perror("Could not bind to divert socket");
		exit(-1);
	}

   return (0);
}


static pa_packet *
my_get_packet(void)
{
   pa_packet_divert	*packet;
	int					rcvd;

#ifdef DEBUG
	printf("*** get_packet ***\n");
#endif

	packet = (pa_packet_divert *) malloc(sizeof(pa_packet_divert));

	if ((rcvd = recvfrom(s, packet->buf, sizeof(packet->buf), 0, &(packet->addr), &(packet->addrlen))) == -1)
	{
		perror("Read from divert socket failed");
		exit(-1);
	}

#ifdef DEBUG
	printf("%i bytes read from divert socket\n", rcvd);
#endif

/* see netinet/ip.h ip_timestamp struct . . .
 *	    packet->packet.pkthdr.ts.tv_sec = packet->nhdr->timestamp_sec;
 *	    packet->packet.pkthdr.ts.tv_usec = packet->nhdr->timestamp_usec;
 */

	packet->packet.pkthdr.caplen = rcvd;
	packet->packet.pkthdr.len = rcvd;
	packet->packet.code = PA_PACKET_CODE_OK;
	packet->packet.buf = packet->buf;


	return(&(packet->packet));
}


static int
my_dispose_packet(pa_packet *in_packet)
{
   pa_packet_divert	*packet = (pa_packet_divert *)in_packet;
	int					sent = 0;

#ifdef DEBUG
	printf("*** dispose_packet ***\n");
#endif

   switch(packet->packet.code){
	   case PA_PACKET_VERDICT_ACCEPT:
			if ((sent = sendto(s, packet->buf, packet->packet.pkthdr.len, 0, &(packet->addr), packet->addrlen)) == -1)
			{
				perror("Write to divert socket failed");
				exit(-1);
			}

#ifdef DEBUG
	printf("%i bytes written to divert socket\n", sent);
#endif

		break;

   	case PA_PACKET_VERDICT_DROP:
#ifdef DEBUG
	printf("packet dropped\n");
#endif
		break;

   	case PA_PACKET_VERDICT_REJECT:
			/* FIXME: Call raw socket ICMP reject routine */
#ifdef DEBUG
	printf("packet dropped\n");
#endif
		break;

   	default:
			fprintf(stderr, "ERROR: unrecognized verdict (%i)\n", packet->packet.code);
			exit(-1);
		break;
   }

   free(packet);
   return (0);
}


static int
my_close(void)
{
   return (0);
}

static int
my_get_devtype(void)
{
   return (PA_DEVTYPE_RAW);
}

static int
my_get_capabilities(void)
{
   return (PA_CAP_DUMP | PA_CAP_DISCARD);
}



More information about the Snort-devel mailing list