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

tag.c

Go to the documentation of this file.
00001 /*
00002 ** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
00003 ** Copyright (C) 2003 Sourcefire, Inc.
00004 **               Chris Green <cmg@sourcefire.com>
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 /* $Id$ */
00022 
00023 /*  I N C L U D E S  ************************************************/
00024 #ifdef HAVE_CONFIG_H
00025 #include "config.h"
00026 #endif
00027 
00028 #include <sys/types.h>
00029 #include <stdlib.h>
00030 #include <rpc/types.h>
00031 #include <string.h>
00032 #include <ctype.h>
00033 
00034 #include "decode.h"
00035 #include "rules.h"
00036 #include "debug.h"
00037 #include "util.h"
00038 #include "generators.h"
00039 #include "log.h"
00040 
00041 #include "ubi_SplayTree.h"
00042 
00043 /* @todo Move all inlines to one central place */
00044 #ifndef DEBUG
00045     #ifndef INLINE
00046         #define INLINE inline
00047     #endif
00048 #else
00049     #ifdef INLINE
00050         #undef INLINE
00051     #endif
00052     #define INLINE   
00053 #endif /* DEBUG */
00054 
00055 /*  D E F I N E S  **************************************************/
00056 #define TAG_SESSION   1
00057 #define TAG_HOST      2
00058 #define TAG_HOST_SRC  3
00059 #define TAG_HOST_DST  4
00060 
00061 #define TAG_METRIC_SECONDS  1
00062 #define TAG_METRIC_PACKETS  2
00063 #define TAG_METRIC_BYTES    4
00064 
00065 #define MAX_TAG_NODES   256
00066 
00067 /* by default we'll set a 10 minute timeout if we see no activity 
00068  * on a tag with a 'count' metric so that we prune dead sessions 
00069  * periodically since we're not doing TCP state tracking
00070  */
00071 #define TAG_PRUNE_QUANTUM   300
00072 #define TAG_MEMCAP          4194304  /* 4MB */
00073 
00074 
00075 /*  D A T A   S T R U C T U R E S  **********************************/
00076 typedef struct _PruneData
00077 {
00078     u_int32_t pruned;
00079     u_int32_t time;
00080     ubi_trRootPtr tree;
00081 } PruneData;
00082 
00083 typedef struct _TagNode
00084 {
00085     ubi_trNode Node;
00086     
00087     /* ip addrs */
00088     u_int32_t sip;
00089     u_int32_t dip;
00090 
00091     /* ports */
00092     u_int16_t sp;
00093     u_int16_t dp;
00094 
00095     /* transport proto */
00096     u_int8_t proto;
00097 
00098     /* number of packets/seconds/bytes to tag for */
00099     int seconds;
00100     int packets;
00101     int bytes;
00102 
00103     /* packets/seconds selector */
00104     int metric;
00105 
00106     /* session or host mode */
00107     int mode;
00108 
00109     /* last UNIX second that this node had a successful match */
00110     u_int32_t last_access;
00111 
00112     /* event id number for correlation with trigger events */
00113     u_int16_t event_id;
00114     struct timeval event_time;
00115 
00116     /* for later expansion... */
00117     OptTreeNode *otn;
00118 
00119 } TagNode;
00120 
00121 /*  G L O B A L S  **************************************************/
00122 static ubi_trRoot host_tag_cache;
00123 static ubi_trRootPtr host_tag_cache_ptr = &host_tag_cache;
00124 
00125 static ubi_trRoot ssn_tag_cache;
00126 static ubi_trRootPtr ssn_tag_cache_ptr = &ssn_tag_cache;
00127 
00128 static u_int32_t last_prune_time;
00129 static u_int32_t tag_alloc_faults;
00130 static u_int32_t tag_memory_usage;
00131 
00132 extern char check_tags_flag;
00133 extern char *file_name;
00134 extern int file_line;
00135 
00136 /*  P R O T O T Y P E S  ********************************************/
00137 static void *TagAlloc(unsigned long);
00138 static int PruneTagCache(u_int32_t, int);
00139 static int PruneTime(ubi_trRootPtr, u_int32_t);
00140 static void TagSession(Packet *, TagData *, u_int32_t, u_int16_t);
00141 static void TagHost(Packet *, TagData *, u_int32_t, u_int16_t);
00142 static void AddTagNode(Packet *, TagData *, int, u_int32_t, u_int16_t);
00143 static INLINE void SwapTag(TagNode *);
00144 
00145 
00146 /* I should really make a generic function to do this... */
00147 static void *TagAlloc(unsigned long size)
00148 {
00149     void *tmp;
00150 
00151     tag_memory_usage += size;
00152 
00153     if(tag_memory_usage > TAG_MEMCAP)
00154     {
00155         /* aggressively prune */
00156         struct timeval tv;
00157         struct timezone tz;
00158 
00159         tag_alloc_faults++;
00160 
00161         gettimeofday(&tv, &tz);
00162 
00163         if(!PruneTagCache((u_int32_t)tv.tv_sec, 0))
00164         {
00165             /* if we can't prune due to time, just nuke 5 random sessions */
00166             PruneTagCache(0, 5);
00167         }
00168     }
00169 
00170     tmp = (void *) calloc(size, sizeof(char));
00171 
00172     if(tmp == NULL)
00173     {
00174         FatalError("TagAlloc(): Unable to allocate memory! (%d bytes in use)\n",
00175                     tag_memory_usage);
00176     }
00177 
00178     return tmp;
00179 }
00180 
00181 #ifdef DEBUG
00182 
00183 /** 
00184  * Print out a tag node IFF we are current in debug_flow
00185  * 
00186  * @param np tagnode pointer to print
00187  */
00188 static void PrintTagNode(TagNode *np)
00189 {
00190     if(!DebugThis(DEBUG_FLOW))
00191     {
00192         return;
00193     }
00194     
00195     printf("+--------------------------------------------------------------\n");
00196     printf("| Ssn Counts: %u, Host Counts: %u\n",
00197            ssn_tag_cache.count,
00198            host_tag_cache.count);
00199     
00200     printf("| (%u) %x:%d -> %x:%d Metric: %u "
00201            "LastAccess: %u, event_id: %u mode: %u event_time.tv_sec: %u\n"
00202            "| Packets: %d, Bytes: %d, Seconds: %d\n",
00203            np->proto,
00204            np->sip, np->sp,
00205            np->dip, np->dp,
00206            np->metric,
00207            np->last_access,
00208            np->event_id,
00209            np->mode,
00210            np->event_time.tv_sec,
00211            np->packets,
00212            np->bytes,
00213            np->seconds);
00214     printf("+--------------------------------------------------------------\n");
00215 }
00216 
00217 #endif /* DEBUG */
00218 
00219 /** 
00220  * swap the sips and dips, dp's and sp's
00221  * 
00222  * @param np TagNode ptr
00223  */
00224 static INLINE void SwapTag(TagNode *np)
00225 {
00226     u_int32_t tip;
00227     u_int16_t tport;
00228 
00229     tip = np->sip;
00230     np->sip = np->dip;
00231     np->dip = tip;
00232 
00233     tport = np->sp;
00234     np->sp = np->dp;
00235     np->dp = tport;
00236 }
00237 
00238 
00239 static int TagCompareSession(ubi_trItemPtr ItemPtr, ubi_trNodePtr NodePtr)
00240 {
00241     TagNode *nTag;
00242     TagNode *iTag; 
00243 
00244     nTag = ((TagNode *)NodePtr);
00245     iTag = ((TagNode *)ItemPtr);
00246 
00247     if(nTag->sip < iTag->sip)
00248     {
00249         return 1;
00250     }
00251     else if(nTag->sip > iTag->sip)
00252     {
00253         return -1;
00254     }
00255         
00256     if(nTag->dip < iTag->dip)
00257     {
00258         return 1;
00259     }
00260     else if(nTag->dip > iTag->dip)
00261     {
00262         return -1;
00263     }
00264 
00265     if(nTag->sp < iTag->sp)
00266     {
00267         return 1;
00268     }
00269     else if(nTag->sp > iTag->sp)
00270     {
00271         return -1;
00272     }
00273 
00274     if(nTag->dp < iTag->dp)
00275     {
00276         return 1;
00277     }
00278     else if(nTag->dp > iTag->dp)
00279     {
00280         return -1;
00281     }
00282 
00283     return 0;
00284 }
00285 
00286 
00287 static int TagCompareHost(ubi_trItemPtr ItemPtr, ubi_trNodePtr NodePtr)
00288 {
00289     TagNode *nTag;
00290     TagNode *iTag; 
00291 
00292     nTag = ((TagNode *)NodePtr);
00293     iTag = ((TagNode *)ItemPtr);
00294 
00295     if(nTag->sip < iTag->sip)
00296     {
00297         return 1;
00298     }
00299     else if(nTag->sip > iTag->sip)
00300     {
00301         return -1;
00302     }
00303 
00304     return 0;
00305 }
00306 
00307 void InitTag()
00308 {
00309     (void)ubi_trInitTree(ssn_tag_cache_ptr,  /* ptr to the tree head */
00310                          TagCompareSession,  /* comparison function */
00311                          0);            /* don't allow overwrites/duplicates */
00312 
00313     (void)ubi_trInitTree(host_tag_cache_ptr, /* ptr to the tree head */
00314                          TagCompareHost,     /* comparison function */
00315                          0);            /* don't allow overwrites/duplicates */
00316 }
00317 
00318 
00319 static void TagSession(Packet *p, TagData *tag, u_int32_t time, u_int16_t event_id)
00320 {
00321     DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "TAGGING SESSION\n"););
00322 
00323     AddTagNode(p, tag, TAG_SESSION, time, event_id);
00324 }
00325 
00326 
00327 static void TagHost(Packet *p, TagData *tag, u_int32_t time, u_int16_t event_id)
00328 {
00329     int mode; 
00330 
00331     DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "TAGGING HOST\n"););
00332 
00333     switch(tag->tag_direction)
00334     {
00335         case TAG_HOST_DST:
00336             mode = TAG_HOST_DST;
00337             break;
00338         case TAG_HOST_SRC:
00339             mode = TAG_HOST_SRC;
00340             break;
00341         default:
00342             mode = TAG_HOST_SRC;
00343             break;
00344     }
00345 
00346     AddTagNode(p, tag, mode, time, event_id);
00347 }
00348 
00349 static void AddTagNode(Packet *p, TagData *tag, int mode, u_int32_t now, 
00350                 u_int16_t event_id)
00351 {
00352     TagNode *idx;  /* index pointer */
00353     TagNode *returned;
00354     ubi_trRootPtr tag_cache_ptr = NULL;
00355 
00356     DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "Adding new Tag Head\n"););
00357 
00358     idx = (TagNode *) TagAlloc(sizeof(TagNode));
00359 
00360     idx->sip = p->iph->ip_src.s_addr;
00361     idx->dip = p->iph->ip_dst.s_addr;
00362     idx->sp = p->sp;
00363     idx->dp = p->dp;
00364     idx->proto = p->iph->ip_proto;
00365     idx->metric = tag->tag_metric;
00366     idx->last_access = now;
00367     idx->event_id = event_id;
00368     idx->event_time.tv_sec = p->pkth->ts.tv_sec;
00369     idx->event_time.tv_usec = p->pkth->ts.tv_usec;
00370     idx->mode = mode;
00371     
00372     if(idx->metric & TAG_METRIC_SECONDS)
00373     {
00374         /* set the expiration time for this tag */
00375         idx->seconds = now + tag->tag_seconds;
00376     }
00377 
00378     if(idx->metric & TAG_METRIC_BYTES)
00379     {
00380         /* set the expiration time for this tag */
00381         idx->bytes = tag->tag_bytes;
00382     }
00383 
00384     if(idx->metric & TAG_METRIC_PACKETS)
00385     {
00386         /* set the expiration time for this tag */
00387         idx->packets = tag->tag_packets;
00388     }
00389 
00390     DEBUG_WRAP(PrintTagNode(idx););
00391     
00392     if(mode == TAG_SESSION)
00393     {
00394         DEBUG_WRAP(DebugMessage(DEBUG_FLOW,"Session Tag!\n"););
00395         tag_cache_ptr = ssn_tag_cache_ptr;
00396     }
00397     else
00398     {
00399         DEBUG_WRAP(DebugMessage(DEBUG_FLOW,"Host Tag!\n"););
00400         tag_cache_ptr = host_tag_cache_ptr;
00401     }
00402     
00403     /* check for duplicates */
00404     returned = (TagNode *) ubi_sptFind(tag_cache_ptr, 
00405                                        (ubi_btItemPtr)idx);
00406         
00407     if(returned == NULL)
00408     {
00409         DEBUG_WRAP(DebugMessage(DEBUG_FLOW,"Looking the other way!!\n"););
00410         SwapTag(idx);            
00411         returned = (TagNode *) ubi_sptFind(tag_cache_ptr, 
00412                                            (ubi_btItemPtr)idx);
00413         SwapTag(idx);
00414     }
00415 
00416     if(returned == NULL)
00417     {
00418         DEBUG_WRAP(DebugMessage(DEBUG_FLOW,"Inserting a New Tag!\n"););
00419 
00420         /* if we're supposed to be tagging the other side, swap it
00421            around -- Lawrence Reed */
00422         if(mode == TAG_HOST_DST)
00423         {
00424             SwapTag(idx);
00425         }
00426 
00427         if(ubi_sptInsert(tag_cache_ptr,
00428                          (ubi_btNodePtr)idx, (ubi_btNodePtr)idx, NULL) == FALSE)
00429         {
00430             DEBUG_WRAP(DebugMessage(DEBUG_FLOW,
00431                                     "sptInsert failed, that's going to "
00432                                     "make life difficult\n"););
00433             return;
00434         }
00435     }
00436     else
00437     {
00438         DEBUG_WRAP(DebugMessage(DEBUG_FLOW,"Existing Tag found!\n"););
00439 
00440         if(idx->metric & TAG_METRIC_SECONDS)
00441             returned->seconds = idx->seconds;
00442         else
00443             returned->seconds += idx->seconds;
00444 
00445         /* get rid of the new tag since we are using an existing one */
00446         free(idx); 
00447         tag_memory_usage -= sizeof(TagNode);
00448     }
00449 
00450     DEBUG_WRAP(PrintTagNode(idx););
00451     
00452     return;
00453 }
00454 
00455 
00456 int CheckTagList(Packet *p, Event *event)
00457 {
00458     TagNode idx;
00459     TagNode *returned = NULL;
00460     ubi_trRootPtr taglist = NULL;
00461 
00462     /* check for active tags */
00463     if(!ubi_trCount(host_tag_cache_ptr) && !ubi_trCount(ssn_tag_cache_ptr))
00464     {
00465         return 0;
00466     }
00467 
00468     if(p == NULL || p->iph == NULL)
00469     {
00470         DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "bailing from CheckTagList, p->iph == NULL\n"););
00471         return 0;
00472     }
00473 
00474     DEBUG_WRAP(DebugMessage(DEBUG_FLOW,"Host Tags Active: %d   Session Tags Active: %d\n", 
00475                             ubi_trCount(host_tag_cache_ptr), ubi_trCount(ssn_tag_cache_ptr)););
00476 
00477     DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "[*] Checking session tag list (forward)...\n"););
00478 
00479     idx.sip = p->iph->ip_src.s_addr;
00480     idx.dip = p->iph->ip_dst.s_addr;
00481     idx.sp = p->sp;
00482     idx.dp = p->dp;
00483 
00484     /* check for session tags... */
00485     returned = (TagNode *) ubi_sptFind(ssn_tag_cache_ptr, (ubi_btItemPtr)&idx);
00486 
00487     if(returned == NULL)
00488     {
00489         idx.dip = p->iph->ip_src.s_addr;
00490         idx.sip = p->iph->ip_dst.s_addr;
00491         idx.dp = p->sp;
00492         idx.sp = p->dp;
00493 
00494         DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "   Checking session tag list (reverse)...\n"););
00495         returned = (TagNode *) ubi_sptFind(ssn_tag_cache_ptr, 
00496                 (ubi_btItemPtr)&idx);
00497 
00498         if(returned == NULL)
00499         {
00500             DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "   Checking host tag list "
00501                                     "(forward)...\n"););
00502 
00503             returned = (TagNode *) ubi_sptFind(host_tag_cache_ptr, 
00504                     (ubi_btItemPtr)&idx);
00505 
00506             if(returned == NULL)
00507             {
00508                 /*
00509                 **  Only switch sip, because that's all we check for
00510                 **  the host tags.
00511                 */
00512                 idx.sip = p->iph->ip_src.s_addr;
00513 
00514                 returned = (TagNode *) ubi_sptFind(host_tag_cache_ptr, 
00515                         (ubi_btItemPtr)&idx);
00516             }
00517 
00518             if(returned != NULL)
00519             {
00520                 DEBUG_WRAP(DebugMessage(DEBUG_FLOW,"   [*!*] Found host node\n"););
00521                 taglist = host_tag_cache_ptr;
00522             }
00523         }
00524         else
00525         {
00526             DEBUG_WRAP(DebugMessage(DEBUG_FLOW,"   [*!*] Found session node\n"););
00527             taglist = ssn_tag_cache_ptr;
00528         }
00529     }
00530     else
00531     {
00532         DEBUG_WRAP(DebugMessage(DEBUG_FLOW,"   [*!*] Found session node\n"););
00533         taglist = ssn_tag_cache_ptr;
00534     }
00535 
00536     if(returned != NULL)
00537     {
00538         DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "    ! Found tag node !\n"););
00539 
00540         returned->last_access = p->pkth->ts.tv_sec;
00541 
00542         if(returned->metric & TAG_METRIC_SECONDS)
00543         {
00544             if(p->pkth->ts.tv_sec > returned->seconds)
00545             {
00546                 returned->seconds = 0;
00547             }
00548         }
00549 
00550         if(returned->metric & TAG_METRIC_PACKETS)
00551         {
00552             /* decrement the packet count */
00553             returned->packets--;
00554         }
00555 
00556         if(returned->metric & TAG_METRIC_BYTES)
00557         {
00558             returned->bytes -= (int) ntohs(p->iph->ip_len);
00559 
00560             if(returned->bytes < 0)
00561             {
00562                 returned->bytes = 0;
00563             }
00564         }
00565 
00566         /* set the event info */
00567         SetEvent(event, GENERATOR_TAG, TAG_LOG_PKT, 1, 1, 1, 
00568                 returned->event_id);
00569         /* set event reference details */
00570         event->ref_time.tv_sec = returned->event_time.tv_sec;
00571         event->ref_time.tv_usec = returned->event_time.tv_usec;
00572         
00573         if(returned->bytes == 0 && returned->packets == 0 && 
00574                 returned->seconds == 0)
00575         {
00576             DEBUG_WRAP(DebugMessage(DEBUG_FLOW,"    Prune condition met for tag, removing"
00577                                     " from list\n"););
00578             returned = (TagNode *) ubi_sptRemove(taglist, 
00579                     (ubi_btNodePtr)returned);
00580 
00581             free(returned);
00582             tag_memory_usage -= sizeof(TagNode);
00583         }
00584     }
00585 
00586     if( (u_int)(p->pkth->ts.tv_sec) > last_prune_time + TAG_PRUNE_QUANTUM)
00587     {
00588         DEBUG_WRAP(DebugMessage(DEBUG_FLOW,
00589                                 "Exceeded Prune Quantum, pruning tag trees\n"););
00590         PruneTagCache(p->pkth->ts.tv_sec, 0);
00591         last_prune_time = p->pkth->ts.tv_sec;
00592     }
00593 
00594     if(returned != NULL)
00595     {
00596         return 1;
00597     }
00598 
00599     return 0;
00600 }
00601 
00602 
00603 static int PruneTagCache(u_int32_t thetime, int mustdie)
00604 {
00605     TagNode *idx;
00606     int pruned = 0;
00607 
00608     if(!mustdie)
00609     {
00610         if(ubi_trCount(ssn_tag_cache_ptr))
00611         {
00612             pruned = PruneTime(ssn_tag_cache_ptr, thetime);
00613         }
00614 
00615         if(ubi_trCount(host_tag_cache_ptr))
00616         {
00617             pruned += PruneTime(host_tag_cache_ptr, thetime);
00618         }
00619 
00620         return pruned;
00621     }
00622     else
00623     {
00624         while(mustdie > 0)
00625         {
00626             if(ubi_trCount(ssn_tag_cache_ptr))
00627             {
00628                 idx = (TagNode *) 
00629                     ubi_btLeafNode((ubi_btNodePtr)ssn_tag_cache_ptr);
00630                 mustdie--;
00631                 free(idx);
00632                 tag_memory_usage -= sizeof(TagNode);
00633             }
00634 
00635             if(ubi_trCount(host_tag_cache_ptr))
00636             {
00637                 idx = (TagNode *) 
00638                     ubi_btLeafNode((ubi_btNodePtr)host_tag_cache_ptr);
00639                 mustdie--;
00640                 free(idx);
00641                 tag_memory_usage -= sizeof(TagNode);
00642             }
00643         }
00644 
00645         return 0;
00646 
00647     }
00648 }
00649 
00650 
00651 static int PruneTime(ubi_trRootPtr tree, u_int32_t thetime)
00652 {
00653     int pruned = 0;
00654     TagNode *idx;
00655     TagNode *savidx;
00656     TagNode *killme;
00657 
00658     idx = (TagNode *) ubi_btFirst((ubi_btNodePtr)tree);
00659 
00660     if(idx == NULL)
00661     {
00662         return 0;
00663     }
00664 
00665     do
00666     {
00667         if((idx->last_access+TAG_PRUNE_QUANTUM) < thetime)
00668         {
00669             savidx = idx;
00670             idx = (TagNode *) ubi_btNext((ubi_btNodePtr)idx);
00671 
00672             killme = (TagNode *) ubi_sptRemove(tree, (ubi_btNodePtr) savidx);
00673 
00674             free(killme);
00675             tag_memory_usage -= sizeof(TagNode);
00676             pruned++;
00677         }
00678         else
00679         {
00680             if(idx != NULL && ubi_trCount(tree))
00681             {
00682                 idx = (TagNode *) ubi_btNext((ubi_btNodePtr)idx);
00683             }
00684             else
00685             {
00686                 return pruned;
00687             }
00688         }
00689     } while(idx != NULL);
00690 
00691     return pruned;
00692 }
00693 
00694 void SetTags(Packet *p, OptTreeNode *otn, u_int16_t event_id)
00695 {
00696    DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "Setting tags\n"););
00697 
00698     if(otn != NULL && otn->tag != NULL)
00699     {
00700         if (otn->tag->tag_type != 0)
00701         {
00702             switch(otn->tag->tag_type)
00703             {
00704                 case TAG_SESSION: 
00705                     DEBUG_WRAP(DebugMessage(DEBUG_FLOW,"Setting session tag:\n");
00706                                DebugMessage(DEBUG_FLOW,"SIP: 0x%X  SP: %d   DIP: 0x%X  "
00707                                             "DP: %d\n", p->iph->ip_src.s_addr,p->sp,
00708                                             p->iph->ip_dst.s_addr,p->dp););
00709                     
00710                     TagSession(p, otn->tag, p->pkth->ts.tv_sec, event_id);
00711                     break;
00712 
00713                 case TAG_HOST:
00714                     DEBUG_WRAP(DebugMessage(DEBUG_FLOW,"Setting host tag:\n");
00715                                DebugMessage(DEBUG_FLOW,"SIP: 0x%X  SP: %d   DIP: 0x%X  "
00716                                             "DP: %d\n", p->iph->ip_src.s_addr,p->sp,
00717                                             p->iph->ip_dst.s_addr,p->dp););
00718                     TagHost(p, otn->tag, p->pkth->ts.tv_sec, event_id);
00719                     break;    
00720     
00721                 default:
00722                     LogMessage("WARNING: Trying to tag with unknown "
00723                             "tag type!\n");
00724                     break;    
00725             }
00726 
00727             check_tags_flag = 0;
00728         }
00729     }
00730 
00731     return;
00732 }
00733 
00734 
00735 
00736 void ParseTag(char *args, OptTreeNode *otn)
00737 {
00738     char *arg = args;
00739     int type = 0;
00740     int count = 0;
00741     int metric = 0;
00742     int packets = 0;
00743     int seconds = 0;
00744     int bytes = 0;
00745     int direction = 0;
00746     int i = 0;
00747 
00748     DEBUG_WRAP(DebugMessage(DEBUG_RULES, "Parsing tag args: %s\n", args););
00749 
00750     while ((arg = strtok( arg, " ,"))) 
00751     {
00752         DEBUG_WRAP(DebugMessage(DEBUG_RULES, "parsing tag tok: \"%s\"\n", arg););
00753 
00754         while(isspace((int)*arg))
00755         {
00756             arg++;
00757         }
00758 
00759         if(!strncasecmp(arg, "session", 7))
00760         {
00761             DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "Setting type to SESSION\n"););
00762             type = TAG_SESSION;
00763         }
00764         else if(!strncasecmp(arg, "host", 4))
00765         {
00766             type = TAG_HOST;
00767         }
00768         else if(!strncasecmp(arg, "src", 3))
00769         {
00770             direction = TAG_HOST_SRC;
00771         }
00772         else if(!strncasecmp(arg, "dst", 3))
00773         {
00774             direction = TAG_HOST_DST;
00775         }
00776         else if(!strncasecmp(arg, "seconds", 7))
00777         {
00778             metric |= TAG_METRIC_SECONDS;
00779             seconds = count;
00780         }
00781         else if (!strncasecmp(arg, "packets", 7))
00782         {
00783             metric |= TAG_METRIC_PACKETS;
00784             packets = count;
00785         }
00786         else if(!strncasecmp(arg, "bytes", 5))
00787         {
00788             metric |= TAG_METRIC_BYTES;
00789             bytes = count;
00790         }
00791         else if(isdigit((int) *arg))
00792         {
00793             count = atoi(arg);
00794         }
00795         else
00796         {
00797             FatalError("%s(%d) Unable to Parse Tag option: %s\n", file_name, file_line, arg);
00798         }
00799 
00800         arg = NULL;
00801         i++;
00802     }
00803 
00804     DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Set type: %d  metric: %x count: %d\n", type, 
00805                 metric, count););
00806 
00807     /* check that we've got enough to set a tag with */
00808     if(type && metric && count)
00809     {
00810         otn->tag = (TagData *)calloc(sizeof(TagData), sizeof(char));
00811 
00812         otn->tag->tag_type = type;
00813         otn->tag->tag_metric = metric;
00814         otn->tag->tag_seconds = seconds;
00815         otn->tag->tag_bytes = bytes;
00816         otn->tag->tag_packets = packets;
00817         otn->tag->tag_direction = direction;
00818     }
00819 
00820     return;
00821 }

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