root/trunk/src/dataFlowSet.c @ 17

Revision 17, 15.7 KB (checked in by andreu, 17 years ago)

*** empty log message ***

  • Property svn:eol-style set to native
Line 
1/*
2 * File: dataFlowSet.c
3 *
4 * Authors: ANDREU Francois-Xavier
5 *
6 * Copyright (C) 2005 GIP RENATER
7 */
8
9/*  This file is part of renetcol.
10 *
11 *  renetcol is free software; you can redistribute it and/or modify
12 *  it under the terms of the GNU General Public License as published by
13 *  the Free Software Foundation; either version 2 of the License, or
14 *  (at your option) any later version.
15 *
16 *  renetcol is distributed in the hope that it will be useful,
17 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 *  GNU General Public License for more details.
20 *
21 *  You should have received a copy of the GNU General Public License
22 *  along with renetcol; if not, write to the Free Software
23 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
24 */
25
26#include "dataFlowSet.h"
27
28/*
29 * checkDataFlowSet
30 *
31 */
32unsigned short 
33checkDataFlowSet(unsigned short shift, RouterPtr cr, NetFlowV9HeaderPtr v9Ptr,
34                 unsigned short *offV9, unsigned char *buf, short *cFNPtr,
35                 short *cFId, DatagramPtr pcktPtr, RuleDefPtr *rulesCache,
36                 RulesPtr rlPtr, int myQueue, struct PrefixV4 *V4PTab,
37                 size_t nbPV4)
38{
39  TplFlowSetPtr tmp;
40  FieldPtr pftmp;
41  FieldPtr secondPftmp;
42  unsigned short data_length = 0;
43  unsigned short flow_size = 0;
44  unsigned short oldOffset = *offV9;
45  unsigned short secondOffset = 0;
46  unsigned short secondOldOffset = 0;
47  int moreIsNecessary = 1;
48  int field_size = 0;
49  int cpt = 0;
50  int secondCpt = 0;
51  int overflow = 0;
52  int noEnd = 1;
53  int i = 0;
54  int j = 0;
55  int pos = 0;
56  unsigned char buffer1; 
57  unsigned char buffer2[2];
58  unsigned char buffer4[4];
59  RulesPtr tmpRuleList = rlPtr;
60  msgType myMsg;
61  char *msgTextIndex;
62  unsigned short tplMsgType = 11;
63  struct PrefixV4 prefixKey, *res; /* for bsearch */
64  struct AggCache agCache;
65  int bool = 0;
66
67  buffer2[1] = *(buf+(*offV9));(*offV9)++;
68  buffer2[0] = *(buf+(*offV9));(*offV9)++;
69  (*cFId) = *((unsigned short*)&buffer2);
70  buffer2[1] = *(buf+(*offV9));(*offV9)++;
71  buffer2[0] = *(buf+(*offV9));(*offV9)++;
72  data_length = *((unsigned short*)&buffer2);
73  if ((tmp=existTplId(cr, v9Ptr->sourceId,
74                      (*cFId)))!=NULL) {
75    pftmp = tmp->lastField;
76    for (; pftmp; pftmp = pftmp->prev) {
77      flow_size += pftmp->fieldLength;
78    }
79    if ( data_length%flow_size >= 9 ) {
80      (*cFNPtr) = v9Ptr->count;
81      syslog(LOG_INFO, "data flowset length not match with length from template definition, wrong template definition suspected; all next informations of this data flowset are not considered! flowset ID: %hu, from router: %lu.%lu.%lu.%lu",
82             (*cFId),
83             (pcktPtr->ipH->srcAdd>>24),
84             (pcktPtr->ipH->srcAdd<<8>>24),
85             (pcktPtr->ipH->srcAdd<<16>>24),
86             (pcktPtr->ipH->srcAdd<<24>>24));
87      return (data_length+shift);
88    }
89    /* aggreg */
90    agCache.routerAd = pcktPtr->ipH->srcAdd;
91    /* end aggreg */
92    pftmp = tmp->lastField;
93    secondPftmp = tmp->lastField;   
94    secondOffset = *offV9;
95    secondOldOffset = secondOffset;
96    while ( (((*offV9)-48-shift) <= data_length) && (overflow!=1) ) {
97      /*
98       * progression in a flow Set
99       * notes:
100       *   48=header ip + header netf
101       *   shift = shift if there is a template declaration
102       */
103      cpt++;
104      j=0;
105      pos = (pftmp->fieldType)*10+j;
106      field_size = (int) pftmp->fieldLength;
107      /*
108       * Comparaison between the field value and the rules
109       * ... if one rule exist
110       */
111      if (((RuleDefPtr)(*(rulesCache+pos))) != NULL) {
112        oldOffset = *offV9;
113        while (((RuleDefPtr)(*(rulesCache+pos))) != NULL){
114          /*
115           * while on one cache table line
116           */
117          *offV9 = oldOffset;
118          switch ((int)
119                  (((RuleDefPtr)(*(rulesCache+pos)))->operator)){
120          case 2:
121            switch (field_size) {
122            case 1:
123              buffer1 = *(buf+(*offV9)); (*offV9)++;
124              /* rule check */
125              if (((RuleDefPtr)(*(rulesCache+pos)))->value->stor.cvalue
126                  == *((unsigned char*)&buffer1)) {
127                ((RuleDefPtr)(*(rulesCache+pos)))->check = 1;
128              }
129              /* end rule check */
130              /* aggregation */
131              if ((pftmp->fieldType==9)||(pftmp->fieldType==29)){
132                agCache.maskS = *((unsigned char*)&buffer1);
133              }
134              if ((pftmp->fieldType==13)||(pftmp->fieldType==30)){
135                agCache.maskD = *((unsigned char*)&buffer1);
136              }
137              if (pftmp->fieldType==60){
138                agCache.ipProt = *((unsigned char*)&buffer1);
139              }
140              if (pftmp->fieldType==4){
141                agCache.tProt = *((unsigned char*)&buffer1);
142              }
143              if (pftmp->fieldType==61){
144                agCache.sens = *((unsigned char*)&buffer1);
145              }
146              if (pftmp->fieldType==5){
147                agCache.dscp = *((unsigned char*)&buffer1);
148              }
149              /* end aggregation */
150              break;
151            case 2:
152              buffer2[1]= *(buf+(*offV9)); (*offV9)++;
153              buffer2[0]= *(buf+(*offV9)); (*offV9)++;
154              if (((RuleDefPtr)(*(rulesCache+pos)))->value->stor.svalue
155                  == *((unsigned short*)&buffer2))
156                ((RuleDefPtr)(*(rulesCache+pos)))->check = 1;
157              /* aggregation */
158              if (pftmp->fieldType==10){
159                agCache.idSnmp = *((unsigned short*)&buffer2);
160              }
161              /* end aggregation */
162              break;
163            case 3:
164              buffer4[3]= 0;
165              buffer4[2]= *(buf+(*offV9)); (*offV9)++;
166              buffer4[1]= *(buf+(*offV9)); (*offV9)++;
167              buffer4[0]= *(buf+(*offV9)); (*offV9)++;
168              if (((RuleDefPtr)(*(rulesCache+pos)))->value->stor.lvalue
169                  == *((unsigned long*)&buffer4))
170                ((RuleDefPtr)(*(rulesCache+pos)))->check = 1;
171              /* aggregation */
172              /* end aggregation */
173              break;
174            case 4:
175              buffer4[3]= *(buf+(*offV9)); (*offV9)++;
176              buffer4[2]= *(buf+(*offV9)); (*offV9)++;
177              buffer4[1]= *(buf+(*offV9)); (*offV9)++;
178              buffer4[0]= *(buf+(*offV9)); (*offV9)++;
179              /* FIXME : here , add a check on the field type */
180              if ((pftmp->fieldType==8)||(pftmp->fieldType==12)){
181                if ((((RuleDefPtr)(*(rulesCache+pos)))->value->stor.lvalue)
182                    == (*((unsigned long*)&buffer4))>>(32-((RuleDefPtr)(*(rulesCache+pos)))->value->mask)<<(32-((RuleDefPtr)(*(rulesCache+pos)))->value->mask) )
183                  {
184                    ((RuleDefPtr)(*(rulesCache+pos)))->check = 1;
185                  }
186              }       
187              /* aggregation */
188              if ((pftmp->fieldType==8)){
189                agCache.v4AdS = *((unsigned long*)&buffer4);
190              }
191              if ((pftmp->fieldType==12)){
192                agCache.v4AdD = *((unsigned long*)&buffer4);
193              }
194              if (pftmp->fieldType==1){
195                agCache.bytes = *((unsigned long*)&buffer4);
196              }
197              if (pftmp->fieldType==2){
198                agCache.pkts = *((unsigned long*)&buffer4);
199              }
200              /* end aggregation */
201              break;
202            case 16:
203              for (i=0; i<4; i++) {
204                buffer4[3]= *(buf+(*offV9)); (*offV9)++;
205                buffer4[2]= *(buf+(*offV9)); (*offV9)++;
206                buffer4[1]= *(buf+(*offV9)); (*offV9)++;
207                buffer4[0]= *(buf+(*offV9)); (*offV9)++;
208                if (1==moreIsNecessary){
209                  switch(i){
210                  case 0:
211                    if (((RuleDefPtr)(*(rulesCache+pos)))->value->mask <= 32){
212                      if (ntohl(((RuleDefPtr)(*(rulesCache+pos)))->value->stor.tabAdd6[i])
213                          ==
214                          (*((unsigned long*)&buffer4))>>(32-((RuleDefPtr)(*(rulesCache+pos)))->value->mask)<<(32-((RuleDefPtr)(*(rulesCache+pos)))->value->mask)
215                          )
216                        {
217                          ((RuleDefPtr)(*(rulesCache+pos)))->check = 1;
218                          moreIsNecessary = 0;
219                        } else {
220                          ((RuleDefPtr)(*(rulesCache+pos)))->check = 0;
221                          moreIsNecessary = 0;
222                        }
223                    } else {
224                      if (ntohl(((RuleDefPtr)(*(rulesCache+pos)))->value->stor.tabAdd6[i])
225                          ==
226                          (*((unsigned long*)&buffer4))
227                          )
228                        {
229                          ((RuleDefPtr)(*(rulesCache+pos)))->check = 1;
230                        } else {
231                          ((RuleDefPtr)(*(rulesCache+pos)))->check = 0;
232                          moreIsNecessary = 0;
233                        }
234                    }
235                    break;
236                  case 1:
237                    if (((RuleDefPtr)(*(rulesCache+pos)))->value->mask <= 64){
238                      if (ntohl(((RuleDefPtr)(*(rulesCache+pos)))->value->stor.tabAdd6[i])
239                          ==
240                          (*((unsigned long*)&buffer4))>>(64-((RuleDefPtr)(*(rulesCache+pos)))->value->mask)<<(64-((RuleDefPtr)(*(rulesCache+pos)))->value->mask)
241                          )
242                        {
243                          ((RuleDefPtr)(*(rulesCache+pos)))->check =
244                            ((RuleDefPtr)(*(rulesCache+pos)))->check && 1;
245                          moreIsNecessary = 0;
246                        } else {
247                          ((RuleDefPtr)(*(rulesCache+pos)))->check = 0;
248                          moreIsNecessary = 0;
249                        }
250                    } else {
251                      if (ntohl(((RuleDefPtr)(*(rulesCache+pos)))->value->stor.tabAdd6[i])
252                          ==
253                          (*((unsigned long*)&buffer4))
254                          )
255                        {
256                          ((RuleDefPtr)(*(rulesCache+pos)))->check =
257                            ((RuleDefPtr)(*(rulesCache+pos)))->check && 1;
258                        } else {
259                          ((RuleDefPtr)(*(rulesCache+pos)))->check = 0;
260                          moreIsNecessary = 0;
261                        }
262                    }
263                    break;
264                  case 2:
265                    if (((RuleDefPtr)(*(rulesCache+pos)))->value->mask <= 96){
266                      if (ntohl(((RuleDefPtr)(*(rulesCache+pos)))->value->stor.tabAdd6[i])
267                          ==
268                          (*((unsigned long*)&buffer4))>>(96-((RuleDefPtr)(*(rulesCache+pos)))->value->mask)<<(96-((RuleDefPtr)(*(rulesCache+pos)))->value->mask)
269                          )
270                        {
271                          ((RuleDefPtr)(*(rulesCache+pos)))->check =
272                            ((RuleDefPtr)(*(rulesCache+pos)))->check && 1;
273                          moreIsNecessary = 0;
274                        } else {
275                          ((RuleDefPtr)(*(rulesCache+pos)))->check = 0;
276                          moreIsNecessary = 0;
277                        }
278                    } else {
279                      if (ntohl(((RuleDefPtr)(*(rulesCache+pos)))->value->stor.tabAdd6[i])
280                          ==
281                          (*((unsigned long*)&buffer4))
282                          )
283                        {
284                          ((RuleDefPtr)(*(rulesCache+pos)))->check =
285                            ((RuleDefPtr)(*(rulesCache+pos)))->check && 1;
286                        } else {
287                          ((RuleDefPtr)(*(rulesCache+pos)))->check = 0;
288                          moreIsNecessary = 0;
289                        }
290                    }
291                    break;
292                  case 3:
293                    if (((RuleDefPtr)(*(rulesCache+pos)))->value->mask <= 128){
294                      if (ntohl(((RuleDefPtr)(*(rulesCache+pos)))->value->stor.tabAdd6[i])
295                          ==
296                          (*((unsigned long*)&buffer4))>>(128-((RuleDefPtr)(*(rulesCache+pos)))->value->mask)<<(128-((RuleDefPtr)(*(rulesCache+pos)))->value->mask)
297                          )
298                        {
299                          ((RuleDefPtr)(*(rulesCache+pos)))->check =
300                            ((RuleDefPtr)(*(rulesCache+pos)))->check && 1;
301                        } else {
302                          ((RuleDefPtr)(*(rulesCache+pos)))->check = 0;
303                          moreIsNecessary = 0;
304                        }
305                    } else {
306                      if (ntohl(((RuleDefPtr)(*(rulesCache+pos)))->value->stor.tabAdd6[i])
307                          ==
308                          (*((unsigned long*)&buffer4))
309                          )
310                        {
311                          ((RuleDefPtr)(*(rulesCache+pos)))->check =
312                            ((RuleDefPtr)(*(rulesCache+pos)))->check && 1;
313                        } else {
314                          ((RuleDefPtr)(*(rulesCache+pos)))->check = 0;
315                          moreIsNecessary = 0;
316                        }
317                    }
318                    break;
319                  default:
320                    break;
321                  } /* end of switch(i) */
322                } /* end of if moreIsNecessary */
323              }
324              moreIsNecessary = 1;
325              /* aggregation */
326             
327              /* end aggregation */
328              break;
329            default:
330              syslog(LOG_INFO, "Field size not known: %d\n", field_size);
331              for (i=0; i<field_size; i++){
332                (*offV9)++;
333              }
334              break;
335            }
336            break;
337          default:
338            syslog(LOG_INFO, "Operator not known: %d\n",
339                   (int)(((RuleDefPtr)(*(rulesCache+pos)))->operator));
340            break;
341          }
342          j++;
343          pos = (pftmp->fieldType)*10+j;
344        } /* end while rulesCache */
345      } else {
346        /*
347         * no rule within this field type, but we must reading the value
348         */
349        switch (field_size) {
350        case 1:
351          buffer1 = *(buf+(*offV9)); (*offV9)++;
352          /* aggregation */
353          if ((pftmp->fieldType==9)||(pftmp->fieldType==29)){
354            agCache.maskS = *((unsigned char*)&buffer1);
355          }
356          if ((pftmp->fieldType==13)||(pftmp->fieldType==30)){
357            agCache.maskD = *((unsigned char*)&buffer1);
358          }
359          if (pftmp->fieldType==60){
360            agCache.ipProt = *((unsigned char*)&buffer1);
361          }
362          if (pftmp->fieldType==4){
363            agCache.tProt = *((unsigned char*)&buffer1);
364          }
365          if (pftmp->fieldType==61){
366            agCache.sens = *((unsigned char*)&buffer1);
367          }
368          if (pftmp->fieldType==5){
369            agCache.dscp = *((unsigned char*)&buffer1);
370          }       
371          /* end aggregation */
372          break;
373        case 2:
374          buffer2[1]= *(buf+(*offV9)); (*offV9)++;
375          buffer2[0]= *(buf+(*offV9)); (*offV9)++;
376          /* aggregation */
377          if (pftmp->fieldType==10){
378            agCache.idSnmp = *((unsigned short*)&buffer2);
379          }       
380          /* end aggregation */
381          break;
382        case 3:
383          buffer4[3]= 0;
384          buffer4[2]= *(buf+(*offV9)); (*offV9)++;
385          buffer4[1]= *(buf+(*offV9)); (*offV9)++;
386          buffer4[0]= *(buf+(*offV9)); (*offV9)++;
387/*        fprintf(stderr,"L: %lu\n",(*((unsigned long*)&buffer4))); */
388/*        fprintf(stderr,"L>>4: %lu\n",(*((unsigned long*)&buffer4))>>4); */
389/*        fprintf(stderr,"L>>1<<29>>29: %lu\n",(*((unsigned long*)&buffer4))>>1<<29>>29); */
390/*        fprintf(stderr,"L<<31>>31: %lu\n",(*((unsigned long*)&buffer4))<<31>>31); */
391          /* aggregation */
392          /* end aggregation */
393          break;
394        case 4:
395          buffer4[3]= *(buf+(*offV9)); (*offV9)++;
396          buffer4[2]= *(buf+(*offV9)); (*offV9)++;
397          buffer4[1]= *(buf+(*offV9)); (*offV9)++;
398          buffer4[0]= *(buf+(*offV9)); (*offV9)++;
399          /* aggregation */
400          if ((pftmp->fieldType==8)){
401            bool = 1;
402            agCache.v4AdS = *((unsigned long*)&buffer4);
403          } else if ((pftmp->fieldType==12)){
404            agCache.v4AdD = *((unsigned long*)&buffer4);
405          } else if (pftmp->fieldType==1){
406            agCache.bytes = *((unsigned long*)&buffer4);
407          } else if (pftmp->fieldType==2){
408            agCache.pkts = *((unsigned long*)&buffer4);
409          }
410          /* end aggregation */
411          break;
412        case 16:
413          for (i=0; i<4; i++) {
414            buffer2[1]= *(buf+(*offV9)); (*offV9)++;
415            buffer2[0]= *(buf+(*offV9)); (*offV9)++;
416            buffer2[1]= *(buf+(*offV9)); (*offV9)++;
417            buffer2[0]= *(buf+(*offV9)); (*offV9)++;
418          }
419          /* aggregation */
420         
421          /* end aggregation */
422          break;
423        default:
424          syslog(LOG_INFO,"UNKNOWN FIELDS LENGTH: %d ", field_size);
425          for (i=0; i<field_size; i++){
426            (*offV9)++;
427          }
428        }
429      } /* end if one cache table line existence */
430      if (cpt==tmp->fieldCount) {
431        /*
432         * end of one flow (not the flowset)
433         */
434        /* put aggregation cache information to tables */
435        if (bool == 1){
436          prefixKey.beginning = agCache.v4AdS>>(32-agCache.maskS)<<(32-agCache.maskS);
437          res = bsearch(&prefixKey, V4PTab, nbPV4,
438                        sizeof(struct PrefixV4), prefCmp);
439        }
440        bool = 0;   
441        /* end put */
442        /*
443         * Redirection if needed
444         * switch the rules definition (check & fieldToRecord),
445         * we send the flow or a part of the flow to the msg queue
446         */
447        tmpRuleList = rlPtr;
448        while (tmpRuleList){
449          unsigned short check = 1;
450          RuleDefPtr tmpRuleDefList = tmpRuleList->def;
451          secondOffset = secondOldOffset;
452          while (tmpRuleDefList){
453            check = check && tmpRuleDefList->check;
454            tmpRuleDefList->check = 0;
455            tmpRuleDefList = tmpRuleDefList->next;
456          }
457          if ( (tmpRuleList->def != NULL) && (check == 1)) {
458            /* msg building */
459            secondPftmp = tmp->lastField;
460/*          memcpy(myMsg.text, (char*)(buf+secondOffset),flow_size); */
461            msgTextIndex = mempcpy(mempcpy(mempcpy(myMsg.text,
462                                                   &tplMsgType,
463                                                   sizeof(unsigned short)
464                                                   ),
465                                           &tmpRuleList->id,
466                                           sizeof(tmpRuleList->id)
467                                           ),
468                                   &cr->IpAddress,
469                                   sizeof(unsigned long)
470                                   );
471            msgTextIndex = mempcpy(mempcpy(mempcpy(msgTextIndex,
472                                                   &tmp->sourceId,
473                                                   sizeof(unsigned long)
474                                                   ),
475                                           &tmp->templateFlowSetId,
476                                           sizeof(tmp->templateFlowSetId)
477                                           ),
478                                   buf+secondOffset,
479                                   flow_size
480                                   );
481            myMsg.type = 1;
482            msgSend( myQueue, myMsg);
483            noEnd = 1;
484            secondCpt=0;
485          } /* end if check */
486          tmpRuleList = tmpRuleList->next;
487          secondPftmp = tmp->lastField;
488        } /* end while tmpRuleList */
489        /*
490         * end redirection
491         */
492        secondOffset = *offV9;
493        secondOldOffset = secondOffset;
494        pftmp = tmp->lastField;
495        cpt=0;
496        (*cFNPtr)++; /* pointer on the flows number */
497        if (((*offV9)-48-shift+flow_size) > data_length){
498          overflow = 1; /* buffer index not correct */
499        }
500      } else {
501        /* not the flow end, progress in field list */
502        pftmp = pftmp->prev;
503      }
504    } /* end of the while on one flow record */   
505  }else{
506    /*
507     * template unknown, we skip this all the data
508     */
509    (*offV9)+=(data_length-4);
510    (*cFNPtr) = v9Ptr->count;
511  }
512  while ( ((*offV9)-48-shift) < data_length ) {
513    (*offV9)++; /* if padding */
514  }
515  while ( (*offV9)-48-shift > data_length ) {
516    (*offV9)--; /* crazy loop (when bug appears in template def) */
517  }
518  return (data_length+shift);
519}
Note: See TracBrowser for help on using the browser.