root/trunk/src/renetcol.c @ 12

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

second RENETCOL CVS Integration

  • Property svn:eol-style set to native
Line 
1/*
2 * File: renetcol.c
3 *
4 * Authors: ANDREU François-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 "renetcol.h"
27
28char *rulesFileName;
29char *configFileName;
30char *prefixV4FileName;
31struct sigaction myAction;
32sigjmp_buf contextSigalrm;
33/* struct sigaction myAction;  for timer */ 
34volatile sig_atomic_t sigusr1Up = 0;
35/* V9 */
36unsigned short offsetV9 = 0;
37unsigned short *offsetV9Ptr = &offsetV9;
38unsigned char buffer1;
39unsigned char buffer2[2];
40unsigned char buffer4[4];
41unsigned char buffer6[6];
42short currentFlowsetNumber;
43short *currentFlowsetNumberPtr = &currentFlowsetNumber;
44short currentFlowsetId;
45short *currentFlowsetIdPtr = &currentFlowsetId;
46TplFlowSetPtr curTplFlSetPtr;
47TplOptionPtr curTplOptionPtr;
48RouterPtr routersListPtr;
49RouterPtr currentRouterPtr;
50DatagramPtr pcktPtr;
51unsigned long sortedRouterList[ROUTER_INDEX_MAX];
52unsigned long indexedRouterList[ROUTER_INDEX_MAX];
53int routerNb = 0;
54struct PrefixV4 prefixV4Tab[PREFIX_V4_MAX];
55RulesPtr rulesListPtr;
56NetFlowV9HeaderPtr currentHeaderV9Ptr;
57key_t myKey = 0;
58int myQueue = 0;
59RuleDefPtr rulesAddress[FIELD_TYPE_NUMBER+1][MAX_RULES_PER_FIELD];
60RuleDefPtr *rulesAddressPtr;
61int reInitConf = 0;
62/* ENDV9 */
63static unsigned long datagramNumber;
64static time_t now;
65static unsigned long myHost; /* FIXME to erase */
66static struct tm *tmPtr;
67extern int errno;
68static int inputSock;
69static int sockNamelg;
70static int sockNameFromlg;
71static int rcv;
72static int sockBufSize = SOCKET_BUFFER_SIZE;           
73/* static unsigned short flowNumber; */
74static unsigned short receptPort = RECEPTION_PORT;
75static unsigned char *ptr_buffer;
76static char *receptAddress = RECEPTION_ADDRESS;
77static struct sockaddr_in name;
78static struct sockaddr_in fromName;
79
80/*
81 * Main
82 * ----
83 */
84int 
85main (int argc, char *argv[])
86{
87  RulesPtr tmp = NULL;
88
89  if ( argc != 4) {
90    fprintf (stderr,
91             "%s: Usage: %s <routers file> <prefix IPv4 file> <rules file>\n exp: %s routers.txt IPv4_prefix.txt rules.txt\n",
92             argv[0], argv[0], argv[0]);
93    exit(1);
94  }
95
96  openlog(argv[0], LOG_PID, LOG_USER);
97
98  configFileName = (char *) malloc((strlen(argv[1])+1) * sizeof(char));
99  strcpy (configFileName, argv[1]);
100  prefixV4FileName = (char *) malloc((strlen(argv[2])+1) * sizeof(char));
101  strcpy (prefixV4FileName, argv[2]);
102  rulesFileName = (char *) malloc((strlen(argv[3])+1) * sizeof(char));
103  strcpy (rulesFileName, argv[3]);
104
105  initCache();
106  fprintf(stderr, "reading the routers list\n");
107  routerNb = getRegisteredRouters(configFileName, &sortedRouterList[0],
108                                  &indexedRouterList[0]);
109  fprintf(stderr, "reading the IPv4 prefix\n");
110  if ( getPrefixV4(prefixV4FileName, &prefixV4Tab[0]) < 1){
111    fprintf(stderr, "Error during prefix v4 reading\n");
112    exit(1);
113  }
114  rulesListPtr = NULL;
115  fprintf(stderr, "reading the rules\n");
116  rulesListPtr = getLightRules(rulesListPtr, rulesFileName);
117  tmp = rulesListPtr;
118  for ( ; tmp->next; tmp=tmp->next) {
119    if (tmp->type != 2) {
120      rulesListPtr = delRule(tmp, rulesListPtr);
121    }
122  }
123
124  fprintf(stderr, "I become a deamon, next messages via syslogd.\n");
125  if (fork () != 0)
126    exit (0);
127  if (setsid() == -1){
128    exit(4);
129  }
130
131  myAction.sa_handler = sigusr1Mgmt;
132  myAction.sa_flags = SA_RESTART;
133  sigemptyset (&(myAction.sa_mask));
134  sigaddset (&(myAction.sa_mask), SIGALRM);
135  sigaction (SIGUSR1, &myAction, NULL);
136
137  setCache(rulesListPtr);
138  rulesAddressPtr = (RuleDefPtr *)rulesAddress;
139
140  /* init IPC messages queue */
141  myKey = createKey(argv[0]);
142  myQueue = createQueue(myKey);
143  sendMyPid(myQueue);
144
145  /* INIT THE CURRENTS VARIABLES*/
146  currentRouterPtr = routersListPtr;
147  currentHeaderV9Ptr = (NetFlowV9HeaderPtr)
148    malloc(sizeof(struct NetFlowV9Header));
149  pcktPtr = (DatagramPtr) malloc(sizeof(struct Datagram));
150  if (pcktPtr==NULL) {
151    fprintf(stderr, "ERROR in struct Datagram allocation\n");
152    exit(1);
153  } else {
154    pcktPtr->ipH = (IpHeaderPtr) malloc(sizeof(struct IpHeader));
155    pcktPtr->udp_header = (UdpHeaderPtr) malloc(sizeof(struct UdpHeader));
156  }
157
158  if (! (ptr_buffer = malloc(sockBufSize))) 
159    {
160      printf("ERROR during socket buffer allocation\n");
161      exit(2);
162    }
163
164  /* INIT INPUT STREAM*/
165  initStream();
166
167  datagramNumber =0;
168
169  /* TIME */
170  now = time((time_t *)NULL);
171  tmPtr = localtime(&now);
172  socketLoop();
173  closelog();
174  fprintf(stderr, "END\n");
175  return (0);
176}
177
178/*
179 *
180 */
181void sendMyPid(int queueID)
182{
183  msgType myMsg;
184  char *msgTextIndex;
185  unsigned short tplMsgType = 12;
186  pid_t myPID;
187 
188  myPID = getpid();
189  msgTextIndex = mempcpy(mempcpy(myMsg.text,
190                                 &tplMsgType,
191                                 sizeof (unsigned short)
192                                 ),
193                         &myPID,
194                         sizeof(pid_t)
195                         );
196  myMsg.type = 1;
197  msgSend(queueID, myMsg);
198}
199
200/*
201 *
202 */
203void sendReadRulesSignal(int queueID)
204{
205  msgType myMsg;
206  char *msgTextIndex;
207  unsigned short tplMsgType = 13;
208 
209  msgTextIndex = mempcpy(myMsg.text,
210                         &tplMsgType,
211                         sizeof (unsigned short)
212                         );
213  myMsg.type = 1;
214  msgSend(queueID, myMsg);
215}
216
217/*
218 *
219 */
220void sigusr1Mgmt(int num)
221{
222  sigusr1Up = 1;
223}
224
225/*
226 *
227 */
228void 
229initRule()
230{
231  RulesPtr tmp = NULL;
232  initCache();
233  tmp = rulesListPtr;
234  for ( ; tmp; tmp=tmp->next) {
235    rulesListPtr = delRule(tmp, rulesListPtr);
236  }
237  rulesListPtr = NULL;
238  rulesListPtr = getLightRules(rulesListPtr, rulesFileName);
239  tmp = rulesListPtr;
240  for ( ; tmp; tmp=tmp->next) {
241    if (tmp->type != 2) {
242      rulesListPtr = delRule(tmp, rulesListPtr);
243    }
244  }
245  tmp = NULL;
246  initCache();
247  setCache(rulesListPtr);
248  sendReadRulesSignal(myQueue);
249}
250
251/*
252 *
253 */
254void
255initCache()
256{
257  int i,j;
258  for (i=0; i<FIELD_TYPE_NUMBER+1; i++){
259    for (j=0; j<MAX_RULES_PER_FIELD; j++){
260      rulesAddress[i][j] = NULL;
261    }
262  }
263}
264
265/*
266 *
267 */
268void
269setCache(RulesPtr rPtr)
270{
271  int i=0;
272  RulesPtr tmp = rPtr;
273  RuleDefPtr def = NULL;
274
275  while (tmp) {
276    def = tmp->def;
277    while (def) {
278      i = 0;
279      while (rulesAddress[def->fieldType][i] != NULL){
280        i++;
281      }
282      rulesAddress[def->fieldType][i] = def;
283      def = def->next;
284    }
285    tmp = tmp->next;
286  }
287}
288
289/*
290 * initStream()
291 */
292void 
293initStream()
294{
295  static unsigned short n0, n1, n2, n3;
296 
297  initSocket();
298  if (sscanf(receptAddress,"%hu.%hu.%hu.%hu",&n0,&n1,&n2,&n3)==0) {
299    perror("sscanf");
300  }             
301  buffer4[0] = (unsigned char)n3;
302  buffer4[1] = (unsigned char)n2;
303  buffer4[2] = (unsigned char)n1;
304  buffer4[3] = (unsigned char)n0;
305  myHost = *((unsigned long*)&buffer4[0]);
306}
307
308/*
309 * socketLoop()
310 */
311int 
312socketLoop()
313{
314  unsigned short shift;
315  short version = 0;
316  int regRouter = 0;
317 
318  do {
319    if (sigusr1Up == 1){
320      sigusr1Up = 0;
321      initRule();
322    }
323    socketReading();
324    getIpHeader(pcktPtr, ptr_buffer);
325    regRouter = checkIpHeader(pcktPtr, &sortedRouterList[0], routerNb);
326    getUdpHeader(pcktPtr, ptr_buffer);
327    checkUdpHeader(pcktPtr, regRouter, receptPort);
328   
329    switch( version =
330            getNetFlowHeader(pcktPtr, ptr_buffer,
331                             currentHeaderV9Ptr, offsetV9Ptr)){
332    case 1:
333      checkNetFlowHeader(pcktPtr);
334      break;
335    case 5:
336/*       if ((currentRouterPtr=notExistRouter(routersListPtr,  */
337/*                                         pcktPtr->ipH->srcAdd))==NULL) { */
338/*      routersListPtr = addRouter(routersListPtr,  */
339/*                                 pcktPtr->ipH->srcAdd,  */
340/*                                 (unsigned long) 0); */
341/*      currentRouterPtr = routersListPtr; */
342/*       } */
343/*       currentFlowsetNumber = 0; */
344/*       shift = 0; */
345/*       while ((currentFlowsetNumber < currentHeaderV9Ptr->count)) { */
346/*      curTplFlSetPtr = NULL; */
347/*      currentFlowsetId=getFlowsetId(currentFlowsetNumber,  */
348/*                                    offsetV9Ptr, ptr_buffer); */
349        /* remplacer par creation du template v5 si pas deja fait */
350/*      shift = checkTemplateFlowSet(currentRouterPtr, offsetV9Ptr,  */
351/*                                   ptr_buffer, currentHeaderV9Ptr, */
352/*                                   curTplFlSetPtr, */
353/*                                   currentFlowsetNumberPtr, */
354/*                                   myQueue); */
355        /*        showAllTplFlSet();  */
356/*      shift = checkDataFlowSet(shift, currentRouterPtr, */
357/*                               currentHeaderV9Ptr, offsetV9Ptr, */
358/*                               ptr_buffer, currentFlowsetNumberPtr, */
359/*                               currentFlowsetIdPtr, pcktPtr, */
360/*                               rulesAddressPtr, rulesListPtr, */
361/*                               myQueue); */
362/*       } */
363      break;
364    case 9:
365      if ((currentRouterPtr=notExistRouter(routersListPtr,
366                                           pcktPtr->ipH->srcAdd))==NULL) {
367        routersListPtr = addRouter(routersListPtr,
368                                   pcktPtr->ipH->srcAdd,
369                                   (unsigned long) 0);
370        currentRouterPtr = routersListPtr;
371      }
372      currentFlowsetNumber = 0;
373      shift = 0;
374      while ((currentFlowsetNumber < currentHeaderV9Ptr->count)) {
375        curTplFlSetPtr = NULL;
376        currentFlowsetId=getFlowsetId(currentFlowsetNumber,
377                                      offsetV9Ptr, ptr_buffer);
378        if ( currentFlowsetId == 0 ) {
379          shift = checkTemplateFlowSet(currentRouterPtr, offsetV9Ptr,
380                                       ptr_buffer, currentHeaderV9Ptr,
381                                       curTplFlSetPtr,
382                                       currentFlowsetNumberPtr,
383                                       myQueue);
384/*        showAllTplFlSet();  */
385        } else if (currentFlowsetId == 1) {
386          shift = checkTemplateOption(currentRouterPtr, offsetV9Ptr,
387                                      ptr_buffer, currentHeaderV9Ptr,
388                                      curTplOptionPtr,
389                                      currentFlowsetNumberPtr);
390        } else {
391          shift = checkDataFlowSet(shift, currentRouterPtr,
392                                   currentHeaderV9Ptr, offsetV9Ptr,
393                                   ptr_buffer, currentFlowsetNumberPtr,
394                                   currentFlowsetIdPtr, pcktPtr,
395                                   rulesAddressPtr, rulesListPtr,
396                                   myQueue);
397        }
398      }
399      break;
400    default:
401      syslog(LOG_INFO,
402             "NetFlow exp. version unknown: %hu, from router: %lu.%lu.%lu.%lu",
403             (unsigned short) version,
404             (pcktPtr->ipH->srcAdd>>24),
405             (pcktPtr->ipH->srcAdd<<8>>24),
406             (pcktPtr->ipH->srcAdd<<16>>24),
407             (pcktPtr->ipH->srcAdd<<24>>24));
408      break;
409    }
410  } while (1);
411}
412
413/*
414 * initSocket()
415 */
416short 
417initSocket()
418{
419  inputSock = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
420  if (inputSock < 0)
421    {
422      syslog(LOG_ERR,"socket : %s", strerror(errno));
423      exit(1);
424    }
425  memset((void*)&name, 0, sizeof(name));
426  name.sin_family = AF_INET;
427  name.sin_addr.s_addr = htonl(INADDR_ANY);
428  if (name.sin_addr.s_addr == INADDR_NONE){
429    syslog(LOG_ERR, " INADDR_NONE ");
430    exit(1);
431  }
432  name.sin_port = htons(receptPort);
433  if (bind(inputSock,(struct sockaddr *)(&name), sizeof(name)) < 0)
434    {
435      syslog(LOG_ERR, "bind : %s", strerror(errno));
436      exit(1);
437    }                                                           
438  sockNamelg = sizeof(name);
439  if (getsockname(inputSock, (struct sockaddr *) (&name),
440                  (socklen_t *)&sockNamelg) < 0)
441    {
442      syslog(LOG_ERR, "getsockname: %s", strerror(errno));
443      exit(1);
444    }
445  return(0);
446}
447
448
449/*
450 * init socket
451 */
452short 
453socketReading()
454{
455  signed short sockLg;
456
457  sockNameFromlg = sizeof(fromName);
458  rcv = recvfrom(inputSock, ptr_buffer, sockBufSize, 0,
459                 (struct sockaddr *)(&fromName),
460                 (socklen_t *)&sockNameFromlg);   
461  sockLg = rcv;
462  if (sockLg < 0) {
463    syslog(LOG_ERR,"recvfrom : %s", strerror(errno));
464    exit(1);
465  }
466  if (sockLg == 0) {
467    syslog(LOG_ERR,"recvfrom : %s", strerror(errno));
468    exit(1);
469  }
470  return(0);
471}
472 
473/*
474 * check up flow datagramme
475 */
476short 
477checkFlow(short flowNumber)
478{
479  return(0);
480}
481
482/*
483 * showAllTplFlSet
484 *
485 */
486void 
487showAllTplFlSet()
488{
489  RouterPtr tmp = routersListPtr;
490  TplFlowSetPtr tmpFS;
491  TplOptionPtr tmpOP;
492  fprintf(stderr,"All template definitions: (field, size) :\n");
493  for (; tmp; tmp=tmp->next) {
494    fprintf(stderr,"router %lu.%lu.%lu.%lu : \n",
495            (tmp->IpAddress>>24),
496            (tmp->IpAddress<<8>>24),
497            (tmp->IpAddress<<16>>24),
498            (tmp->IpAddress<<24>>24));
499    tmpFS =  tmp->tplList;
500    for (; tmpFS; tmpFS=tmpFS->next) {
501      fprintf(stderr,"ID %hu: ", tmpFS->templateFlowSetId);
502      printFieldSet(tmpFS->fieldSet);
503      fprintf(stderr,"\n");
504    }
505    if ((tmpOP = tmp->tplOptList) != NULL){
506      fprintf(stderr,"template option: \n");
507      for (; tmpOP; tmpOP=tmpOP->next) {
508        fprintf(stderr,"ID %hu: ", tmpOP->templateOptionId);
509        printFieldSet(tmpOP->fieldSet);
510        fprintf(stderr,"\n");
511      }
512      fprintf(stderr,"\n");
513    }
514  }
515}
Note: See TracBrowser for help on using the browser.