Main Page | Modules | Class List | Directories | File List | Class Members | File Members | Related Pages

spo_alert_unixsock.c

Go to the documentation of this file.
00001 /* $Id$ */
00002 /*
00003 ** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
00004 ** Copyright (C) 2000,2001 Andrew R. Baker <andrewb@uab.edu>
00005 **
00006 ** This program is free software; you can redistribute it and/or modify
00007 ** it under the terms of the GNU General Public License as published by
00008 ** the Free Software Foundation; either version 2 of the License, or
00009 ** (at your option) any later version.
00010 **
00011 ** This program is distributed in the hope that it will be useful,
00012 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 ** GNU General Public License for more details.
00015 **
00016 ** You should have received a copy of the GNU General Public License
00017 ** along with this program; if not, write to the Free Software
00018 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00019 */
00020 
00021 /* spo_alert_unixsock
00022  * 
00023  * Purpose:  output plugin for Unix Socket alerting
00024  *
00025  * Arguments:  none (yet)
00026  *   
00027  * Effect:      ???
00028  *
00029  */
00030 
00031 #ifdef HAVE_CONFIG_H
00032 #include "config.h"
00033 #endif
00034 
00035 #include <sys/types.h>
00036 #include <string.h>
00037 #ifdef HAVE_STRINGS_H
00038 #include <strings.h>
00039 #endif
00040 #ifndef WIN32
00041 #include <sys/un.h>
00042 #endif /* !WIN32 */
00043 #include <unistd.h>
00044 #include <errno.h>
00045 
00046 #include "event.h"
00047 #include "decode.h"
00048 #include "plugbase.h"
00049 #include "spo_plugbase.h"
00050 #include "parser.h"
00051 #include "debug.h"
00052 #include "util.h"
00053 
00054 #include "snort.h"
00055 #include "spo_alert_unixsock.h"
00056 
00057 #define UNSOCK_FILE "snort_alert"
00058 
00059 
00060 
00061 /*
00062  * Win32 does not support Unix sockets (sockaddr_un).  This file
00063  * will not be compiled on Win32 until a proper patch is supported.
00064  */
00065 #ifndef WIN32
00066 
00067 
00068 
00069 
00070 /* not used yet */
00071 typedef struct _SpoAlertUnixSockData
00072 {
00073     char *filename;
00074 
00075 } SpoAlertUnixSockData;
00076 
00077 
00078 static int alertsd;
00079 #ifndef WIN32
00080 struct sockaddr_un alertaddr;
00081 #else
00082 struct sockaddr_in alertaddr;
00083 #endif
00084 
00085 void AlertUnixSockInit(u_char *);
00086 void AlertUnixSock(Packet *, char *, void *, Event *);
00087 void ParseAlertUnixSockArgs(char *);
00088 void AlertUnixSockCleanExit(int, void *);
00089 void AlertUnixSockRestart(int, void *);
00090 void OpenAlertSock(void);
00091 void CloseAlertSock(void);
00092 
00093 /*
00094  * Function: SetupAlertUnixSock()
00095  *
00096  * Purpose: Registers the output plugin keyword and initialization 
00097  *          function into the output plugin list.  This is the function that
00098  *          gets called from InitOutputPlugins() in plugbase.c.
00099  *
00100  * Arguments: None.
00101  *
00102  * Returns: void function
00103  *
00104  */
00105 void AlertUnixSockSetup(void)
00106 {
00107     /* link the preprocessor keyword to the init function in 
00108        the preproc list */
00109     RegisterOutputPlugin("alert_unixsock", NT_OUTPUT_ALERT, AlertUnixSockInit);
00110     DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Output plugin: AlertUnixSock is setup...\n"););
00111 }
00112 
00113 
00114 /*
00115  * Function: AlertUnixSockInit(u_char *)
00116  *
00117  * Purpose: Calls the argument parsing function, performs final setup on data
00118  *          structs, links the preproc function into the function list.
00119  *
00120  * Arguments: args => ptr to argument string
00121  *
00122  * Returns: void function
00123  *
00124  */
00125 void AlertUnixSockInit(u_char *args)
00126 {
00127     DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Output: AlertUnixSock Initialized\n"););
00128 
00129     pv.alert_plugin_active = 1;
00130 
00131     /* parse the argument list from the rules file */
00132     ParseAlertUnixSockArgs(args);
00133 
00134     DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Linking UnixSockAlert functions to call lists...\n"););
00135 
00136     /* Set the preprocessor function into the function list */
00137     AddFuncToOutputList(AlertUnixSock, NT_OUTPUT_ALERT, NULL);
00138 
00139     AddFuncToCleanExitList(AlertUnixSockCleanExit, NULL);
00140     AddFuncToRestartList(AlertUnixSockRestart, NULL);
00141 }
00142 
00143 
00144 /*
00145  * Function: ParseAlertUnixSockArgs(char *)
00146  *
00147  * Purpose: Process the preprocessor arguements from the rules file and 
00148  *          initialize the preprocessor's data struct.  This function doesn't
00149  *          have to exist if it makes sense to parse the args in the init 
00150  *          function.
00151  *
00152  * Arguments: args => argument list
00153  *
00154  * Returns: void function
00155  */
00156 void ParseAlertUnixSockArgs(char *args)
00157 {
00158     DEBUG_WRAP(DebugMessage(DEBUG_LOG,"ParseAlertUnixSockArgs: %s\n", args););
00159     /* eventually we may support more than one socket */
00160     OpenAlertSock();
00161 }
00162 
00163 /****************************************************************************
00164  *
00165  * Function: SpoUnixSockAlert(Packet *, char *)
00166  *
00167  * Arguments: p => pointer to the packet data struct
00168  *            msg => the message to print in the alert
00169  *
00170  * Returns: void function
00171  *
00172  ***************************************************************************/
00173 void AlertUnixSock(Packet *p, char *msg, void *arg, Event *event)
00174 {
00175     static Alertpkt alertpkt;
00176 
00177     DEBUG_WRAP(DebugMessage(DEBUG_LOG, "Logging Alert data!\n"););
00178 
00179     bzero((char *)&alertpkt,sizeof(alertpkt));
00180     if (event)
00181     {
00182         bcopy((const void *)event,(void *)&alertpkt.event,sizeof(Event));
00183     }
00184 
00185     if(p && p->pkt)
00186     {
00187         bcopy((const void *)p->pkth,(void *)&alertpkt.pkth,sizeof(struct pcap_pkthdr));
00188         bcopy((const void *)p->pkt,alertpkt.pkt,
00189               alertpkt.pkth.caplen > SNAPLEN? SNAPLEN : alertpkt.pkth.caplen);
00190     }
00191     else
00192         alertpkt.val|=NOPACKET_STRUCT;
00193 
00194     if (msg)
00195     {
00196         bcopy((const void *)msg,(void *)alertpkt.alertmsg,
00197                strlen(msg)>ALERTMSG_LENGTH-1 ? ALERTMSG_LENGTH - 1 : strlen(msg));
00198     }
00199 
00200     /* some data which will help monitoring utility to dissect packet */
00201     if(!(alertpkt.val & NOPACKET_STRUCT))
00202     {
00203         if(p)
00204         {
00205             if (p->eh) 
00206             {
00207                 alertpkt.dlthdr=(char *)p->eh-(char *)p->pkt;
00208             }
00209     
00210             /* we don't log any headers besides eth yet */
00211             if (p->iph && p->pkt) 
00212             {
00213                 alertpkt.nethdr=(char *)p->iph-(char *)p->pkt;
00214         
00215                 switch(p->iph->ip_proto)
00216                 {
00217                     case IPPROTO_TCP:
00218                        if (p->tcph) 
00219                        {
00220                            alertpkt.transhdr=(char *)p->tcph-(char *)p->pkt;
00221                        }
00222                        break;
00223                     
00224                     case IPPROTO_UDP:
00225                         if (p->udph) 
00226                         {
00227                             alertpkt.transhdr=(char *)p->udph-(char *)p->pkt;
00228                         }
00229                         break;
00230                     
00231                     case IPPROTO_ICMP:
00232                        if (p->icmph) 
00233                        {
00234                            alertpkt.transhdr=(char *)p->icmph-(char *)p->pkt;
00235                        }
00236                        break;
00237                     
00238                     default:
00239                         /* alertpkt.transhdr is null due to initial bzero */
00240                         alertpkt.val|=NO_TRANSHDR;
00241                         break;
00242                 }
00243             }
00244 
00245             if (p->data && p->pkt) alertpkt.data=p->data - p->pkt;
00246         }
00247     }
00248 
00249 
00250     if(sendto(alertsd,(const void *)&alertpkt,sizeof(Alertpkt),
00251               0,(struct sockaddr *)&alertaddr,sizeof(alertaddr))==-1)
00252     {
00253         /* whatever we do to sign that some alerts could be missed */
00254     }
00255 
00256 
00257 }
00258 
00259 
00260 
00261 /*
00262  * Function: OpenAlertSock
00263  *
00264  * Purpose:  Connect to UNIX socket for alert logging..
00265  *
00266  * Arguments: none..
00267  *
00268  * Returns: void function
00269  */
00270 void OpenAlertSock(void)
00271 {
00272     char srv[STD_BUF];
00273 
00274     /* srv is our filename workspace. Set it to file UNSOCK_FILE inside the log directory. */
00275     snprintf(srv, STD_BUF - 1, "%s%s/%s", pv.chroot_dir == NULL ? "" : pv.chroot_dir, pv.log_dir, UNSOCK_FILE);
00276 
00277     if(access(srv, W_OK))
00278     {
00279        ErrorMessage("%s file doesn't exist or isn't writable!\n",
00280             srv);
00281     }
00282 
00283     bzero((char *) &alertaddr, sizeof(alertaddr));
00284     
00285     /* 108 is the size of sun_path */
00286     strncpy(alertaddr.sun_path, srv, 108);
00287 
00288     alertaddr.sun_family = AF_UNIX;
00289 
00290     if((alertsd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
00291     {
00292         FatalError("socket() call failed: %s", strerror(errno));
00293     }
00294 }
00295 
00296 void AlertUnixSockCleanExit(int signal, void *arg) 
00297 {
00298     DEBUG_WRAP(DebugMessage(DEBUG_LOG,"AlertUnixSockCleanExitFunc\n"););
00299     CloseAlertSock();
00300 }
00301 
00302 void AlertUnixSockRestart(int signal, void *arg) 
00303 {
00304     DEBUG_WRAP(DebugMessage(DEBUG_LOG,"AlertUnixSockRestartFunc\n"););
00305     CloseAlertSock();
00306 }
00307 
00308 void CloseAlertSock()
00309 {
00310     if(alertsd >= 0) {
00311         close(alertsd);
00312     }
00313 }
00314 
00315 
00316 
00317 
00318 #endif /* !WIN32 */
00319 

Generated on Sun May 14 14:51:14 2006 by  doxygen 1.4.2