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