root/trunk/src/dataFlowSet.c @ 15

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

?

  • 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)
37{
38  TplFlowSetPtr tmp;
39  FieldPtr pftmp;
40  FieldPtr secondPftmp;
41  unsigned short data_length = 0;
42  unsigned short flow_size = 0;
43  unsigned short oldOffset = *offV9;
44  unsigned short secondOffset = 0;
45  unsigned short secondOldOffset = 0;
46  int moreIsNecessary = 1;
47  int field_size = 0;
48  int cpt = 0;
49  int secondCpt = 0;
50  int overflow = 0;
51  int noEnd = 1;
52  int i=0;
53  int j=0;
54  int pos = 0;
55  unsigned char buffer1; 
56  unsigned char buffer2[2];
57  unsigned char buffer4[4];
58  RulesPtr tmpRuleList = rlPtr;
59  msgType myMsg;
60  char *msgTextIndex;
61  unsigned short tplMsgType = 11;
62
63  buffer2[1] = *(buf+(*offV9));(*offV9)++;
64  buffer2[0] = *(buf+(*offV9));(*offV9)++;
65  (*cFId) = *((unsigned short*)&buffer2);
66  buffer2[1] = *(buf+(*offV9));(*offV9)++;
67  buffer2[0] = *(buf+(*offV9));(*offV9)++;
68  data_length = *((unsigned short*)&buffer2);
69  if ((tmp=existTplId(cr, v9Ptr->sourceId,
70                      (*cFId)))!=NULL) {
71    pftmp = tmp->lastField;
72    for (; pftmp; pftmp = pftmp->prev) {
73      flow_size += pftmp->fieldLength;
74    }
75    if ( data_length%flow_size >= 9 ) {
76      (*cFNPtr) = v9Ptr->count;
77      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",
78             (*cFId),
79             (pcktPtr->ipH->srcAdd>>24),
80             (pcktPtr->ipH->srcAdd<<8>>24),
81             (pcktPtr->ipH->srcAdd<<16>>24),
82             (pcktPtr->ipH->srcAdd<<24>>24));
83      return (data_length+shift);
84    }
85    pftmp = tmp->lastField;
86    secondPftmp = tmp->lastField;   
87    secondOffset = *offV9;
88    secondOldOffset = secondOffset;
89    while ( (((*offV9)-48-shift) <= data_length) && (overflow!=1) ) {
90      /*
91       * progression in a flow Set
92       * notes:
93       *   48=header ip + header netf
94       *   shift = shift if there is a template declaration
95       */
96      cpt++;
97      j=0;
98      pos = (pftmp->fieldType)*10+j;
99      field_size = (int) pftmp->fieldLength;
100      /*
101       * Comparaison between the field value and the rules
102       * ... if one rule exist
103       */
104      if (((RuleDefPtr)(*(rulesCache+pos))) != NULL) {
105        oldOffset = *offV9;
106        while (((RuleDefPtr)(*(rulesCache+pos))) != NULL){
107          /*
108           * while on one cache table line
109           */
110          *offV9 = oldOffset;
111          switch ((int)
112                  (((RuleDefPtr)(*(rulesCache+pos)))->operator)){
113          case 2:
114            switch (field_size) {
115            case 1:
116              buffer1 = *(buf+(*offV9)); (*offV9)++;
117              if (((RuleDefPtr)(*(rulesCache+pos)))->value->stor.cvalue
118                  == *((unsigned char*)&buffer1)) {
119                ((RuleDefPtr)(*(rulesCache+pos)))->check = 1;
120              }
121              break;
122            case 2:
123              buffer2[1]= *(buf+(*offV9)); (*offV9)++;
124              buffer2[0]= *(buf+(*offV9)); (*offV9)++;
125              if (((RuleDefPtr)(*(rulesCache+pos)))->value->stor.svalue
126                  == *((unsigned short*)&buffer2))
127                ((RuleDefPtr)(*(rulesCache+pos)))->check = 1;
128              break;
129            case 4:
130              buffer4[3]= *(buf+(*offV9)); (*offV9)++;
131              buffer4[2]= *(buf+(*offV9)); (*offV9)++;
132              buffer4[1]= *(buf+(*offV9)); (*offV9)++;
133              buffer4[0]= *(buf+(*offV9)); (*offV9)++;
134              /* FIXME : here , add a check on the field type */
135              if ((((RuleDefPtr)(*(rulesCache+pos)))->value->stor.lvalue)
136                  == (*((unsigned long*)&buffer4))>>(32-((RuleDefPtr)(*(rulesCache+pos)))->value->mask)<<(32-((RuleDefPtr)(*(rulesCache+pos)))->value->mask) )
137                {
138                  ((RuleDefPtr)(*(rulesCache+pos)))->check = 1;
139                }
140              break;
141            case 16:
142              for (i=0; i<4; i++) {
143                buffer4[3]= *(buf+(*offV9)); (*offV9)++;
144                buffer4[2]= *(buf+(*offV9)); (*offV9)++;
145                buffer4[1]= *(buf+(*offV9)); (*offV9)++;
146                buffer4[0]= *(buf+(*offV9)); (*offV9)++;
147                if (1==moreIsNecessary){
148                  switch(i){
149                  case 0:
150                    if (((RuleDefPtr)(*(rulesCache+pos)))->value->mask <= 32){
151                      if (ntohl(((RuleDefPtr)(*(rulesCache+pos)))->value->stor.tabAdd6[i])
152                          ==
153                          (*((unsigned long*)&buffer4))>>(32-((RuleDefPtr)(*(rulesCache+pos)))->value->mask)<<(32-((RuleDefPtr)(*(rulesCache+pos)))->value->mask)
154                          )
155                        {
156                          ((RuleDefPtr)(*(rulesCache+pos)))->check = 1;
157                          moreIsNecessary = 0;
158                        } else {
159                          ((RuleDefPtr)(*(rulesCache+pos)))->check = 0;
160                          moreIsNecessary = 0;
161                        }
162                    } else {
163                      if (ntohl(((RuleDefPtr)(*(rulesCache+pos)))->value->stor.tabAdd6[i])
164                          ==
165                          (*((unsigned long*)&buffer4))
166                          )
167                        {
168                          ((RuleDefPtr)(*(rulesCache+pos)))->check = 1;
169                        } else {
170                          ((RuleDefPtr)(*(rulesCache+pos)))->check = 0;
171                          moreIsNecessary = 0;
172                        }
173                    }
174                    break;
175                  case 1:
176                    if (((RuleDefPtr)(*(rulesCache+pos)))->value->mask <= 64){
177                      if (ntohl(((RuleDefPtr)(*(rulesCache+pos)))->value->stor.tabAdd6[i])
178                          ==
179                          (*((unsigned long*)&buffer4))>>(64-((RuleDefPtr)(*(rulesCache+pos)))->value->mask)<<(64-((RuleDefPtr)(*(rulesCache+pos)))->value->mask)
180                          )
181                        {
182                          ((RuleDefPtr)(*(rulesCache+pos)))->check =
183                            ((RuleDefPtr)(*(rulesCache+pos)))->check && 1;
184                          moreIsNecessary = 0;
185                        } else {
186                          ((RuleDefPtr)(*(rulesCache+pos)))->check = 0;
187                          moreIsNecessary = 0;
188                        }
189                    } else {
190                      if (ntohl(((RuleDefPtr)(*(rulesCache+pos)))->value->stor.tabAdd6[i])
191                          ==
192                          (*((unsigned long*)&buffer4))
193                          )
194                        {
195                          ((RuleDefPtr)(*(rulesCache+pos)))->check =
196                            ((RuleDefPtr)(*(rulesCache+pos)))->check && 1;
197                        } else {
198                          ((RuleDefPtr)(*(rulesCache+pos)))->check = 0;
199                          moreIsNecessary = 0;
200                        }
201                    }
202                    break;
203                  case 2:
204                    if (((RuleDefPtr)(*(rulesCache+pos)))->value->mask <= 96){
205                      if (ntohl(((RuleDefPtr)(*(rulesCache+pos)))->value->stor.tabAdd6[i])
206                          ==
207                          (*((unsigned long*)&buffer4))>>(96-((RuleDefPtr)(*(rulesCache+pos)))->value->mask)<<(96-((RuleDefPtr)(*(rulesCache+pos)))->value->mask)
208                          )
209                        {
210                          ((RuleDefPtr)(*(rulesCache+pos)))->check =
211                            ((RuleDefPtr)(*(rulesCache+pos)))->check && 1;
212                          moreIsNecessary = 0;
213                        } else {
214                          ((RuleDefPtr)(*(rulesCache+pos)))->check = 0;
215                          moreIsNecessary = 0;
216                        }
217                    } else {
218                      if (ntohl(((RuleDefPtr)(*(rulesCache+pos)))->value->stor.tabAdd6[i])
219                          ==
220                          (*((unsigned long*)&buffer4))
221                          )
222                        {
223                          ((RuleDefPtr)(*(rulesCache+pos)))->check =
224                            ((RuleDefPtr)(*(rulesCache+pos)))->check && 1;
225                        } else {
226                          ((RuleDefPtr)(*(rulesCache+pos)))->check = 0;
227                          moreIsNecessary = 0;
228                        }
229                    }
230                    break;
231                  case 3:
232                    if (((RuleDefPtr)(*(rulesCache+pos)))->value->mask <= 128){
233                      if (ntohl(((RuleDefPtr)(*(rulesCache+pos)))->value->stor.tabAdd6[i])
234                          ==
235                          (*((unsigned long*)&buffer4))>>(128-((RuleDefPtr)(*(rulesCache+pos)))->value->mask)<<(128-((RuleDefPtr)(*(rulesCache+pos)))->value->mask)
236                          )
237                        {
238                          ((RuleDefPtr)(*(rulesCache+pos)))->check =
239                            ((RuleDefPtr)(*(rulesCache+pos)))->check && 1;
240                        } else {
241                          ((RuleDefPtr)(*(rulesCache+pos)))->check = 0;
242                          moreIsNecessary = 0;
243                        }
244                    } else {
245                      if (ntohl(((RuleDefPtr)(*(rulesCache+pos)))->value->stor.tabAdd6[i])
246                          ==
247                          (*((unsigned long*)&buffer4))
248                          )
249                        {
250                          ((RuleDefPtr)(*(rulesCache+pos)))->check =
251                            ((RuleDefPtr)(*(rulesCache+pos)))->check && 1;
252                        } else {
253                          ((RuleDefPtr)(*(rulesCache+pos)))->check = 0;
254                          moreIsNecessary = 0;
255                        }
256                    }
257                    break;
258                  default:
259                    break;
260                  } /* end of switch(i) */
261                } /* end of if moreIsNecessary */
262              }
263              moreIsNecessary = 1;
264              break;
265            default:
266              syslog(LOG_INFO, "Field size not known: %d\n", field_size);
267              for (i=0; i<field_size; i++){
268                (*offV9)++;
269              }
270              break;
271            }
272            break;
273          default:
274            syslog(LOG_INFO, "Operator not known: %d\n",
275                   (int)(((RuleDefPtr)(*(rulesCache+pos)))->operator));
276            break;
277          }
278          j++;
279          pos = (pftmp->fieldType)*10+j;
280        } /* end while rulesCache */
281      } else {
282        /*
283         * no rule within this field type, but we must reading the value
284         */
285        switch (field_size) {
286        case 1:
287          buffer1 = *(buf+(*offV9)); (*offV9)++;
288          break;
289        case 2:
290          buffer2[1]= *(buf+(*offV9)); (*offV9)++;
291          buffer2[0]= *(buf+(*offV9)); (*offV9)++;
292          break;
293        case 4:
294          buffer4[3]= *(buf+(*offV9)); (*offV9)++;
295          buffer4[2]= *(buf+(*offV9)); (*offV9)++;
296          buffer4[1]= *(buf+(*offV9)); (*offV9)++;
297          buffer4[0]= *(buf+(*offV9)); (*offV9)++;
298          break;
299        case 16:
300          for (i=0; i<4; i++) {
301            buffer2[1]= *(buf+(*offV9)); (*offV9)++;
302            buffer2[0]= *(buf+(*offV9)); (*offV9)++;
303            buffer2[1]= *(buf+(*offV9)); (*offV9)++;
304            buffer2[0]= *(buf+(*offV9)); (*offV9)++;
305          }
306          break;
307        default:
308          syslog(LOG_INFO,"UNKNOWN FIELDS LENGTH: %d ", field_size);
309          for (i=0; i<field_size; i++){
310            (*offV9)++;
311          }
312        }
313      } /* end if one cache table line existence */
314      if (cpt==tmp->fieldCount) {
315        /*
316         * end of one flow (not the flowset)
317         */
318        /*
319         * Redirection if needed
320         * switch the rules definition (check & fieldToRecord),
321         * we send the flow or a part of the flow to the msg queue
322         */
323        tmpRuleList = rlPtr;
324        while (tmpRuleList){
325          unsigned short check = 1;
326          RuleDefPtr tmpRuleDefList = tmpRuleList->def;
327          secondOffset = secondOldOffset;
328          while (tmpRuleDefList){
329            check = check && tmpRuleDefList->check;
330            tmpRuleDefList->check = 0;
331            tmpRuleDefList = tmpRuleDefList->next;
332          }
333          if ( (tmpRuleList->def != NULL) && (check == 1)) {
334            /* msg building */
335            secondPftmp = tmp->lastField;
336/*          memcpy(myMsg.text, (char*)(buf+secondOffset),flow_size); */
337            msgTextIndex = mempcpy(mempcpy(mempcpy(myMsg.text,
338                                                   &tplMsgType,
339                                                   sizeof(unsigned short)
340                                                   ),
341                                           &tmpRuleList->id,
342                                           sizeof(tmpRuleList->id)
343                                           ),
344                                   &cr->IpAddress,
345                                   sizeof(unsigned long)
346                                   );
347            msgTextIndex = mempcpy(mempcpy(mempcpy(msgTextIndex,
348                                                   &tmp->sourceId,
349                                                   sizeof(unsigned long)
350                                                   ),
351                                           &tmp->templateFlowSetId,
352                                           sizeof(tmp->templateFlowSetId)
353                                           ),
354                                   buf+secondOffset,
355                                   flow_size
356                                   );
357            myMsg.type = 1;
358            msgSend( myQueue, myMsg);
359            noEnd = 1;
360            secondCpt=0;
361          } /* end if check */
362          tmpRuleList = tmpRuleList->next;
363          secondPftmp = tmp->lastField;
364        } /* end while tmpRuleList */
365        /*
366         * end redirection
367         */
368        secondOffset = *offV9;
369        secondOldOffset = secondOffset;
370        pftmp = tmp->lastField;
371        cpt=0;
372        (*cFNPtr)++; /* pointer on the flows number */
373        if (((*offV9)-48-shift+flow_size) > data_length){
374          overflow = 1; /* buffer index not correct */
375        }
376      } else {
377        /* not the flow end, progress in field list */
378        pftmp = pftmp->prev;
379      }
380    } /* end of the while on one flow record */   
381  }else{
382    /*
383     * template unknown, we skip this all the data
384     */
385    (*offV9)+=(data_length-4);
386    (*cFNPtr) = v9Ptr->count;
387  }
388  while ( ((*offV9)-48-shift) < data_length ) {
389    (*offV9)++; /* if padding */
390  }
391  while ( (*offV9)-48-shift > data_length ) {
392    (*offV9)--; /* crazy loop (when bug appears in template def) */
393  }
394  return (data_length+shift);
395}
Note: See TracBrowser for help on using the browser.