00001
00002
00003
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
00020 #define DEBUGPATH ;
00021
00022
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
00064 if (Globals.NumRoutes == 0)
00065 return TRUE;
00066
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
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
00194 PacketSec++;
00195 if (GetDataByID(PacketSlot, TCPDecoderID, &data)) {
00196 TCPSec++;
00197
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
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
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
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
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
00299 while( (PacketSlot=PopFromPending())!=-1 ){
00300 if (!ProcessPacket(PacketSlot)){
00301 printf("Couldn't process packet\n");
00302 }
00303 }
00304 }else{
00305
00306 IdleFunc();
00307 }
00308
00309 }
00310
00311 return TRUE;
00312 }
00313
00317 int MainLoopThreaded()
00318 {
00319 int i;
00320
00321
00322 DEBUGPATH;
00323
00324 Globals.Done = FALSE;
00325
00326
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
00338
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 }