actions/action_alert_listensocket.c

Go to the documentation of this file.
00001 #include "action_alert_listensocket.h"
00002 #include <stdio.h>
00003 #include "../engine/message.h"
00004 #include <stdlib.h>
00005 #include <string.h>
00006 #include <netdb.h>
00007 #include <sys/socket.h>
00008 #include <netinet/in.h>
00009 #include <unistd.h>
00010 
00011 //#define DEBUG
00012 
00013 #define MAX_SOCKET_RETRIES      10
00014 
00015 typedef struct action_listensocket_rec{
00016         unsigned short  Port;
00017         int                     SockFD;
00018         int                     ListenSocketFD[2];
00019 } ActionLSocketRec;
00020 
00021 #define MAX_REMOTES     10
00022 
00023 typedef struct remote_connection{
00024         int             InUse;
00025         int             FD;
00026 } RemoteConn;
00027 
00028 extern GlobalVars       Globals;
00029 RemoteConn                      RCons[MAX_REMOTES];
00030 
00031 
00032 /*****************************************
00033 * push out the stats at regular intervals
00034 *****************************************/
00035 int ListenSocketTimerFunc(int TimerID, int Time, void* User){
00036         int                                     newfd;
00037         ActionLSocketRec*       data;
00038         DRecStat                        s;
00039 
00040         //printf("Listen Socket timer called\n");
00041 
00042         data=(ActionLSocketRec*)User;
00043         newfd=data->ListenSocketFD[0];
00044 
00045         s.PreMagic=htonl(PREMAGIC);
00046         s.Type=LDATA_TYPE_STATISTICS;
00047         s.Len=sizeof(DRecStat);
00048         s.Len=htons(s.Len);
00049         s.Time=htonl(Time);
00050         s.PacketCount=htons(Globals.PacketsPerSec);
00051         s.TCPCount=htons(Globals.TCPPerSec);
00052         s.UDPCount=htons(Globals.UDPPerSec);
00053 
00054         write(newfd, &s, sizeof(s));
00055 
00056         return TRUE;    
00057 }
00058 
00059 /*********************************************/
00060 /* Handle all the connections                */
00061 /*********************************************/
00062 void HandleClients(int sockfd, int readfd){
00063         fd_set                          rfds;
00064         struct timeval          tv;     
00065         int                                     retval;
00066         int                                     max;
00067         int                                     i;
00068         
00069         struct sockaddr_in      remote_addr;
00070         int                                     sin_size;
00071         
00072         char                            buff[1024];
00073 
00074         bzero(RCons, sizeof(RemoteConn) * MAX_REMOTES);
00075 
00076         if (listen(sockfd, 10)==-1){
00077                 printf("Can't listen\n");
00078                 return;
00079         }
00080 
00081         /*main loop to handle stuff*/
00082         while (1){
00083                 max=0;
00084                 FD_ZERO(&rfds);
00085                 FD_SET(sockfd, &rfds);
00086                 if (sockfd>max) max=sockfd;
00087                 FD_SET(readfd, &rfds);
00088                 if (readfd>max) max=readfd;
00089                 for (i=0;i<MAX_REMOTES;i++)
00090                         if (RCons[i].InUse){
00091                                 FD_SET(RCons[i].FD, &rfds);
00092                                 if (RCons[i].FD>max) max=RCons[i].FD;
00093                         }
00094                 
00095                 tv.tv_sec=10;
00096                 tv.tv_usec=0;
00097                 
00098                 retval=select(max+1, &rfds, NULL, NULL, &tv);
00099                 
00100                 if (retval){
00101                         for (i=0;i<MAX_REMOTES;i++){
00102                                 if (RCons[i].InUse)
00103                                 if (FD_ISSET(RCons[i].FD, &rfds)){
00104                                         close(RCons[i].FD);
00105                                         RCons[i].InUse=FALSE;
00106                                 }
00107                         }
00108                         if (FD_ISSET(readfd, &rfds)){
00109                                 sin_size=read(readfd, buff, 1024);
00110                                 for (i=0;i<MAX_REMOTES;i++){
00111                                         if (RCons[i].InUse)
00112                                         if (write(RCons[i].FD, buff, sin_size)<0){      
00113                                                 printf("Failed to write to newfd\n");
00114                                         }
00115                                 }
00116                         }               
00117                         if (FD_ISSET(sockfd, &rfds)){
00118                                 sin_size=sizeof(struct sockaddr_in);
00119                                 for (i=0;i<MAX_REMOTES;i++){
00120                                         if (RCons[i].InUse==FALSE){
00121                                                 RCons[i].FD=accept(sockfd, (struct sockaddr*)&remote_addr, &sin_size);
00122                                                 if (RCons[i].FD==-1){
00123                                                         printf("Failed to get new connection\n");
00124                                                 }
00125                                                 RCons[i].InUse=TRUE;
00126                                         
00127                                                 write(RCons[i].FD, "200 HLBR data server ready\n", strlen("200 HLBR data server ready\n"));
00128                                                 break;
00129                                         }                                               
00130                                 }
00131                         }
00132                 }
00133         }
00134 }
00135 
00136 /******************************************
00137 * Parse the args for this action
00138 ******************************************/
00139 void* AlertListenSocketParseArgs(char* Args){
00140         ActionLSocketRec*       data;
00141         unsigned short          Port;
00142         struct sockaddr_in      listen_addr;
00143         
00144 #ifdef DEBUGPATH
00145         printf("In AlertListenSocketParseArgs\n");
00146 #endif
00147 
00148 #ifdef DEBUG
00149         printf("Parsing args for action_alert_listensocket\n");
00150 #endif  
00151 
00152         while (*Args==' ') Args++;
00153         
00154         Port=atoi(Args);
00155         if (Port==0xFFFF){
00156                 printf("Invalid port number %s\n",Args);
00157                 return NULL;
00158         }
00159 
00160         data=(ActionLSocketRec*)calloc(sizeof(ActionLSocketRec),1);
00161         data->Port=Port;
00162         
00163         data->SockFD=socket(AF_INET, SOCK_STREAM, 0);
00164         if (data->SockFD==-1){
00165                 printf("Unable to create socket\n");
00166                 return NULL;
00167         }
00168         
00169         bzero(&listen_addr, sizeof(struct sockaddr_in));
00170         listen_addr.sin_family=AF_INET;
00171         listen_addr.sin_port=htons(data->Port);
00172         listen_addr.sin_addr.s_addr=INADDR_ANY;
00173         
00174         if (bind(data->SockFD, (struct sockaddr*)&listen_addr, sizeof(struct sockaddr))==-1){
00175                 printf("Failed to bind to port %u\n",data->Port);
00176                 return NULL;
00177         }
00178         
00179         /*create a socket pair for inter process comm*/
00180         if (socketpair(AF_UNIX, SOCK_STREAM, 0, data->ListenSocketFD)==-1){
00181                 printf("Couldn't set up a socketpair\n");
00182                 return NULL;
00183         }
00184 
00185         /*fork off for the handler*/
00186         if (fork()){
00187                 HandleClients(data->SockFD, data->ListenSocketFD[1]);
00188                 exit(0);
00189         }
00190 
00191         CreateTimer("AlertListenSocket Stats", 1, ListenSocketTimerFunc, (void*)data);
00192         
00193         return data;
00194 }
00195 
00196 
00197 /******************************************
00198 * handle informational messages
00199 ******************************************/
00200 int AlertListenSocketMessage(char* Message, void* Data){
00201         ActionLSocketRec*       data;
00202         
00203 #ifdef DEBUGPATH
00204         printf("In AlertListenSocketMessage\n");
00205 #endif
00206 
00207 #ifdef DEBUG
00208         printf("Writing to the Alert Socket\n");
00209 #endif
00210 
00211         if (!Data){
00212 #ifdef DEBUG
00213                 printf("I must have a socket to write to\n");
00214 #endif  
00215                 return FALSE;
00216         }
00217         
00218         data=(ActionLSocketRec*)Data;
00219 
00220         if (write(data->SockFD, Message, strlen(Message))==-1)
00221                 return FALSE;
00222                 
00223         return TRUE;
00224 }
00225 
00226 /******************************************
00227 * write the alert message to the alert socket
00228 ******************************************/
00229 int AlertListenSocketAction(int RuleNum, int PacketSlot, void* Data){
00230         char                            Buff[1024];
00231         char                            Buff2[1024];
00232         ActionLSocketRec*       data;
00233         PacketRec*                      p;
00234         DRecAlert                       alert;
00235         
00236 #ifdef DEBUGPATH
00237         printf("In AlertListenSocketAction\n");
00238 #endif
00239 
00240 #ifdef DEBUG
00241         printf("Writing to the Alert Socket\n");
00242 #endif
00243 
00244         if (!Data){
00245 #ifdef DEBUG
00246                 printf("I must have a socket to write to\n");
00247 #endif  
00248                 return FALSE;
00249         }
00250         
00251         p=&Globals.Packets[PacketSlot];
00252         data=(ActionLSocketRec*)Data;
00253 
00254 
00255         bzero(&alert, sizeof(DRecAlert));
00256         if (!ApplyMessage(Globals.AlertHeader, PacketSlot, Buff, 1024)){
00257                 printf("Couldn't alert header to packet\n");
00258                 return FALSE;
00259         }
00260         
00261         if (!ApplyMessage(Globals.Rules[RuleNum].MessageFormat, PacketSlot, Buff2, 1024)){
00262                 printf("Couldn't apply message to packet\n");
00263                 return FALSE;
00264         }
00265 
00266         snprintf(alert.Message, 1024, "%s %s\n",Buff, Buff2);
00267         
00268         alert.PreMagic=htonl(PREMAGIC);
00269         alert.Type=LDATA_TYPE_ALERT;
00270         alert.Len=sizeof(DRecAlert);
00271         alert.Len=htons(alert.Len);
00272         
00273         write(data->ListenSocketFD[0], &alert, sizeof(DRecAlert));
00274         
00275         return TRUE;
00276 }
00277 
00278 /********************************
00279 * Set up the alert socket stuff
00280 ********************************/
00281 int InitActionAlertListenSocket(){
00282         int ActionID;
00283 
00284 #ifdef DEBUGPATH
00285         printf("In InitActionAlertListenSocket\n");
00286 #endif
00287 
00288         ActionID=CreateAction("alert lsocket");
00289         if (ActionID==ACTION_NONE){
00290 #ifdef DEBUG
00291                 printf("Couldn't allocation action alert lsocket\n");
00292 #endif  
00293                 return FALSE;
00294         }
00295         
00296         Globals.ActionItems[ActionID].ActionFunc=AlertListenSocketAction;
00297         Globals.ActionItems[ActionID].MessageFunc=AlertListenSocketMessage;
00298         Globals.ActionItems[ActionID].ParseArgs=AlertListenSocketParseArgs;
00299 
00300         return TRUE;
00301 }

Generated on Sat Jul 7 23:33:09 2007 for HLBR by  doxygen 1.5.2