1$Id$ 2 3It is possible to send alert messages and some packet relevant data 4from snort through a unix socket, to perform additional separate 5processing of alert data. 6Snort has to be built with spo_unsock.c/h output plugin is built in and 7-A unsock (or its equivalent through the config file) is 8used. The unix socket file should be created in /dev/snort_alert. Your 9'client' code should act as 'server' listening to this unix socket. 10Snort will be sending you Alertpkt structures which contain alert 11message, event id. Original datagram, libpcap pkthdr, and offsets to 12datalink, netlayer, and transport layer headers. 13 14Below is an example how unix sockets could be used. If you have any 15comments bug reports, and feature requests, please contact 16snort-devel@lists.snort.org or drop me an email to fygrave at 17tigerteam dot net. 18 19-Fyodor 20 21[for copyright notice, see snort distribution code] 22 23#include <stdio.h> 24#include <stdlib.h> 25#include <sys/types.h> 26#include <sys/socket.h> 27#include <sys/un.h> 28#include <signal.h> 29#include "snort.h" 30 31int sockfd; 32 33void 34sig_term (int sig) 35{ 36 printf ("Exiting!\n"); 37 close (sockfd); 38 unlink (UNSOCK_FILE); 39 exit (1); 40} 41 42int 43main (void) 44{ 45 struct sockaddr_un snortaddr; 46 struct sockaddr_un bogus; 47 Alertpkt alert; 48 Packet *p; 49 int recv; 50 socklen_t len = sizeof (struct sockaddr_un); 51 52 if ((sockfd = socket (AF_UNIX, SOCK_DGRAM, 0)) < 0) 53 { 54 perror ("socket"); 55 exit (1); 56 } 57 58 bzero (&snortaddr, sizeof (snortaddr)); 59 snortaddr.sun_family = AF_UNIX; 60 strcpy (snortaddr.sun_path, UNSOCK_FILE); 61 62 63 if (bind (sockfd, (struct sockaddr *) &snortaddr, sizeof (snortaddr)) < 0) 64 { 65 perror ("bind"); 66 exit (1); 67 } 68 69 signal(SIGINT, sig_term); 70 71 while ((recv = recvfrom (sockfd, (void *) &alert, sizeof (alert), 72 0, (struct sockaddr *) &bogus, &len)) > 0) 73 { 74 75 /* do validation of recv if you care */ 76 77 if (!(alert.val & NOPACKET_STRUCT)) 78 { 79 if ((p = calloc (1, sizeof (Packet))) == NULL) 80 { 81 perror ("calloc"); 82 exit (1); 83 } 84 85 p->pkt = alert.pkt; 86 p->pkth = &alert.pkth; 87 if (alert.dlthdr) 88 p->eh = (EtherHdr *) (alert.pkt + alert.dlthdr); 89 if (alert.nethdr) 90 { 91 p->iph = (IPHdr *) (alert.pkt + alert.nethdr); 92 if (alert.transhdr) 93 { 94 switch (p->iph->ip_proto) 95 { 96 case IPPROTO_TCP: 97 p->tcph = (TCPHdr *) (alert.pkt + alert.transhdr); 98 break; 99 case IPPROTO_UDP: 100 p->udph = (UDPHdr *) (alert.pkt + alert.transhdr); 101 break; 102 case IPPROTO_ICMP: 103 p->icmph = (ICMPHdr *) (alert.pkt + alert.transhdr); 104 break; 105 default: 106 printf ("My, that's interesting.\n"); 107 } /* case */ 108 } /* thanshdr */ 109 } /* nethdr */ 110 if (alert.data) 111 p->data = alert.pkt + alert.data; 112 113 /* now do whatever you want with these packet structures */ 114 } /* if (!NOPACKET_STRUCT) */ 115 116 printf ("%s [%d]\n", alert.alertmsg, alert.event.event_id); 117 if (!(alert.val & NOPACKET_STRUCT)) 118 if (p->iph && (p->tcph || p->udph || p->icmph)) 119 { 120 switch (p->iph->ip_proto) 121 { 122 case IPPROTO_TCP: 123 printf ("TCP from: %s:%d ", 124 inet_ntoa (p->iph->ip_src), 125 ntohs (p->tcph->th_sport)); 126 printf ("to: %s:%d\n", inet_ntoa (p->iph->ip_dst), 127 ntohs (p->tcph->th_dport)); 128 break; 129 case IPPROTO_UDP: 130 printf ("UDP from: %s:%d ", 131 inet_ntoa (p->iph->ip_src), 132 ntohs (p->udph->uh_sport)); 133 printf ("to: %s:%d\n", inet_ntoa (p->iph->ip_dst), 134 ntohs (p->udph->uh_dport)); 135 break; 136 case IPPROTO_ICMP: 137 printf ("ICMP type: %d code: %d from: %s ", 138 p->icmph->type, 139 p->icmph->code, inet_ntoa (p->iph->ip_src)); 140 printf ("to: %s\n", inet_ntoa (p->iph->ip_dst)); 141 break; 142 } 143 } 144 145 } 146 147 perror ("recvfrom"); 148 close (sockfd); 149 unlink (UNSOCK_FILE); 150 151 return 0; 152} 153