engine/main_loop.c

Go to the documentation of this file.
00001 /*******************************************
00002 * How the main loop works depends on 
00003 * threads and other factors.
00004 *******************************************/
00005 #include "main_loop.h"
00006 #include "hlbrlib.h"
00007 #include <stdio.h>
00008 #include <sys/types.h>
00009 #include <unistd.h>
00010 #include <stdio.h>
00011 #include "../packets/packet.h"
00012 #include "../decoders/decode.h"
00013 #include "../routes/route.h"
00014 #include "../actions/action.h"
00015 #include "bits.h"
00016 #include <stdlib.h>
00017 #include <string.h>
00018 
00019 //#define DEBUG
00020 #define DEBUGPATH ;
00021 //#define DEBUGPACKETS
00022 //#define DEBUG1
00023 
00024 extern GlobalVars       Globals;
00025 extern int                      TCPDecoderID;
00026 extern int                      UDPDecoderID;
00027 
00028 
00032 void IdleFunc()
00033 {
00034         DEBUGPATH;
00035 
00036 #ifdef DEBUGPACKETS
00037         PRINTERROR("There are:\n");
00038         PRINTERROR1("  %i Idle\n",      Globals.IdleCount);
00039         PRINTERROR1("  %i Pending\n",   Globals.PendingCount);
00040         PRINTERROR1("  %i Saved\n",     Globals.SavedCount);
00041         PRINTERROR1("  %i Allocated\n", Globals.AllocatedCount);
00042         PRINTERROR1("  %i Processing\n",Globals.ProcessingCount);
00043 #endif
00044 #ifdef _OBSD_   
00045         usleep(100);
00046 #else
00047         usleep(100);
00048 #endif
00049 }
00050 
00051 
00055 int RouteAndSend(int PacketSlot)
00056 {
00057         PacketRec*      p;
00058         
00059         DEBUGPATH;
00060         
00061         p = &Globals.Packets[PacketSlot];
00062         
00063         /* No routing Protocols */
00064         if (Globals.NumRoutes == 0)
00065                 return TRUE;
00066         /* dropped by rules */
00067         if (!p->PassRawPacket)
00068                 return TRUE;
00069         
00070         p->TargetInterface = -1;
00071         
00072 #ifdef DEBUG1   
00073         if (p->InterfaceNum == 2)
00074         printf("Routing %02X:%02X:%02X:%02X:%02X:%02X->%02X:%02X:%02X:%02X:%02X:%02X\n",
00075                 p->RawPacket[6],
00076                 p->RawPacket[7],
00077                 p->RawPacket[8],
00078                 p->RawPacket[9],
00079                 p->RawPacket[10],
00080                 p->RawPacket[11],
00081                 p->RawPacket[0],
00082                 p->RawPacket[1],
00083                 p->RawPacket[2],
00084                 p->RawPacket[3],
00085                 p->RawPacket[4],
00086                 p->RawPacket[5]);
00087 #endif  
00088         
00089         if (!Route(PacketSlot)) {
00090                 DBG( PRINTERROR("Routing rules dropped the packet\n") );
00091                 return TRUE;
00092         }
00093 
00094         if (p->TargetInterface == -1) {
00095                 DBG( PRINTERROR("No Packet Handler set a route. Dropping.\n") );
00096                 return FALSE;
00097         }
00098 
00099 #ifdef DEBUG1
00100         if (p->InterfaceNum == 2)
00101         printf("- Sending packet out interface %i(%s)\n",p->TargetInterface, Globals.Interfaces[p->TargetInterface].Name);
00102 #endif  
00103 
00104         return WritePacket(PacketSlot); 
00105 }
00106 
00107 /************************************
00108 * Handle any timers that fire
00109 ************************************/
00110 int HandleTimers(int Now){
00111         int                     i;
00112         static int      NextTimer=0;
00113         int                     TimeLeft;
00114         TimerRec*       t;
00115 
00116         DEBUGPATH;
00117 
00118         if ( (NextTimer!=0) && (Now<NextTimer) ) return TRUE;
00119                 
00120         for (i=0;i<MAX_TIMERS;i++){
00121                 t=&Globals.Timers[i];
00122                 if (t->InUse && t->TimerFunc){
00123                         if ((t->Interval+t->LastTime)<=Now){
00124                                 t->InUse=t->TimerFunc(i, Now, t->User);
00125                                 t->LastTime=Now;
00126                         }
00127                 }
00128         }
00129 
00130         NextTimer=-65535;
00131         for (i=0;i<MAX_TIMERS;i++){
00132                 t=&Globals.Timers[i];
00133                 if (t->InUse && t->TimerFunc){
00134                         TimeLeft=t->Interval - (Now - t->LastTime);
00135                         if ( TimeLeft>NextTimer) NextTimer=TimeLeft;
00136                 }
00137         }
00138         
00139         if (NextTimer==-65535) NextTimer=60;
00140         if (NextTimer>60) NextTimer=60;
00141         
00142         NextTimer+=Now;
00143                 
00144         return TRUE;    
00145 }
00146 
00163 int ProcessPacket(int PacketSlot)
00164 {
00165         PacketRec*      p;
00166         static int      PacketSec=0;
00167         static int      TCPSec=0;
00168         static int      UDPSec=0;
00169         static int      LastTime=0;
00170         void*           data;
00171         
00172         DEBUGPATH;
00173 
00174         if (Globals.PacketLimit == 0) {
00175                 PRINTERROR("Packet Limit Reached\n");
00176                 Globals.Done = TRUE;
00177         }
00178         
00179         if (Globals.PacketLimit > 0)
00180                 Globals.PacketLimit--;
00181 
00182         p = &Globals.Packets[PacketSlot];
00183 
00184         DBG( PRINTERROR1("P:%u\n", p->PacketNum) );
00185 
00186         if (p->tv.tv_sec)
00187                 HandleTimers(p->tv.tv_sec);
00188 
00189         if (!Decode(Globals.DecoderRoot,PacketSlot)) {
00190                 PRINTERROR("Error applying decoder to packet\n");
00191         }
00192 
00193         /* update the packet statistics */
00194         PacketSec++;
00195         if (GetDataByID(PacketSlot, TCPDecoderID, &data)) {
00196                 TCPSec++;
00197                 // Unblock first packet from TCP remount buffer
00198                 TCPRemount_unblock(PacketSlot, FALSE);
00199         } else if (GetDataByID(PacketSlot, UDPDecoderID, &data))
00200                 UDPSec++;
00201                 
00202         if (Globals.Packets[PacketSlot].tv.tv_sec != LastTime) {
00203                 Globals.PacketsPerSec = PacketSec;
00204                 Globals.TCPPerSec = TCPSec;
00205                 Globals.UDPPerSec = UDPSec;
00206         
00207                 //printf("%i packet, %i tcp, %i udp %i other\n",PacketSec, TCPSec, UDPSec, PacketSec-(TCPSec+UDPSec));  
00208                 
00209                 PacketSec = 0;
00210                 TCPSec = 0;
00211                 UDPSec = 0;
00212                 LastTime = Globals.Packets[PacketSlot].tv.tv_sec;
00213         }
00214 
00215                 
00216         if (!BitFieldIsEmpty(p->RuleBits,Globals.NumRules)) {
00217                 DBG( PRINTERROR("There are rule matches\n") );
00218                 if (!PerformActions(PacketSlot)) {
00219                         PRINTERROR("Failed to execute the actions\n");
00220                 }
00221         }
00222 
00223         // route the packet only if it isn't blocked by TCP stream remount
00224         if (p->Status != PACKET_STATUS_BLOCKED) {
00225                 RouteAndSend(PacketSlot);
00226                 ReturnEmptyPacket(PacketSlot);
00227         }
00228 
00229         return TRUE;
00230 }
00231 
00232 
00237 void* ProcessPacketThread(void* v)
00238 {
00239         int     PacketSlot;
00240         
00241         DEBUGPATH;
00242 
00243         while (!Globals.Done){
00244                 PacketSlot = PopFromPending();          
00245                 if (PacketSlot != PACKET_NONE) {
00246                         ProcessPacket(PacketSlot);
00247                 } else {
00248                         IdleFunc();
00249                 }       
00250         }
00251 
00252 
00253         return NULL;
00254 }
00255 
00256 /*******************************
00257 * Poll the FD's to get packets
00258 *******************************/
00259 int MainLoopPoll(){
00260         struct timeval  timeout;
00261         int                             result;
00262         fd_set                  set;
00263         int                             i;
00264         int                             highest;
00265         int                             PacketSlot;
00266         
00267         DEBUGPATH;
00268 
00269         Globals.Done=FALSE;
00270         while (!Globals.Done){
00271                 timeout.tv_sec=0;
00272                 timeout.tv_usec=IDLE_TIMEOUT;
00273         
00274                 FD_ZERO(&set);
00275                 highest=-1;
00276                 for (i=0;i<Globals.NumInterfaces;i++){
00277                         FD_SET(Globals.Interfaces[i].FD, &set);
00278                         if (Globals.Interfaces[i].FD>highest)
00279                                 highest=Globals.Interfaces[i].FD;
00280                 }
00281                 highest++;
00282                         
00283                 result = select(highest, &set, NULL, NULL, &timeout);
00284                 if (result){
00285 #ifdef DEBUG
00286                         printf("A packet is waiting\n");
00287 #endif  
00288                         /*pull the packets off*/
00289                         for (i=0;i<Globals.NumInterfaces;i++){
00290                                 if (FD_ISSET(Globals.Interfaces[i].FD, &set)){
00291 #ifdef DEBUG
00292                                         printf("Reading interface %s\n",Globals.Interfaces[i].Name);
00293 #endif                          
00294                                         ReadPacket(i);
00295                                 }       
00296                         }
00297                         
00298                         /*Now Process them*/
00299                         while( (PacketSlot=PopFromPending())!=-1 ){
00300                                 if (!ProcessPacket(PacketSlot)){
00301                                         printf("Couldn't process packet\n");
00302                                 }
00303                         }
00304                 }else{
00305                         //printf("Calling the idle func\n");
00306                         IdleFunc();
00307                 }
00308         
00309         }
00310 
00311         return TRUE;
00312 }
00313 
00317 int MainLoopThreaded()
00318 {
00319         int i;
00320 //      pthread_t       test_thread;
00321         
00322         DEBUGPATH;
00323 
00324         Globals.Done = FALSE;
00325         
00326         /* start up the interface threads */
00327         for (i=0;i<Globals.NumInterfaces;i++)
00328                 if (!StartInterfaceThread(i)){
00329                         printf("Couldn't start thread for interface\n");
00330                         return FALSE;
00331                 }
00332 #ifdef DEBUG
00333                 else
00334                         printf("Starting thread for interface %i\n", i);
00335 #endif
00336         
00337         /*start up the first process packet thread*/
00338         //pthread_create(&test_thread, NULL, ProcessPacketThread, NULL);
00339         ProcessPacketThread(NULL);
00340 
00341         return FALSE;
00342 }
00343 
00350 int MainLoop()
00351 {
00352         int i;
00353         
00354         DEBUGPATH;
00355 
00356         if (!Globals.UseThreads) {
00357                 for (i = 0; i < Globals.NumInterfaces; i++) {
00358                         if (!Globals.Interfaces[i].IsPollable) {
00359                                 PRINTERROR("All interfaces must be able to poll in single thread mode.\n");
00360                                 return FALSE;
00361                         }
00362                 }
00363                 return MainLoopPoll();
00364         } else {
00365                 return MainLoopThreaded();
00366         }
00367         
00368         return FALSE;
00369 }

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