root/trunk/src/renetcol.c @ 20

Revision 20, 16.1 KB (checked in by andreu, 16 years ago)

new release 0.0.6, with CRIHAN compilation feature

  • 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
28#ifdef CRIHAN
29struct IPFLowCache tabIP[MAX_IP_FLOW], *tabIPPtr = tabIP;
30struct MPLSFlowCache tabMPLS[MAX_MPLS_FLOW], *tabMPLSPtr = tabMPLS;
31unsigned long ipNb = 0;
32unsigned long mplsNb = 0;
33unsigned long *ipNbPtr = &ipNb;
34unsigned long *mplsNbPtr = &mplsNb;
35unsigned short currentIPOutputFile = 0;
36unsigned short currentMPLSOutputFile = 0;
37char outputName[256];
38char cof_str[20];
39FILE *fIP;
40FILE *fMPLS;
41#endif /* CRIHAN */
42
43char *rulesFileName;
44char *configFileName;
45char *prefixV4FileName;
46struct sigaction myAction;
47sigjmp_buf contextSigalrm;
48/* struct sigaction myAction;  for timer */ 
49volatile sig_atomic_t sigusr1Up = 0;
50/* V9 */
51unsigned short offsetV9 = 0;
52unsigned short *offsetV9Ptr = &offsetV9;
53unsigned char buffer1;
54unsigned char buffer2[2];
55unsigned char buffer4[4];
56unsigned char buffer6[6];
57short currentFlowsetNumber;
58short *currentFlowsetNumberPtr = &currentFlowsetNumber;
59short currentFlowsetId;
60short *currentFlowsetIdPtr = &currentFlowsetId;
61TplFlowSetPtr curTplFlSetPtr;
62TplOptionPtr curTplOptionPtr;
63RouterPtr routersListPtr;
64RouterPtr currentRouterPtr;
65DatagramPtr pcktPtr;
66unsigned long sortedRouterList[ROUTER_INDEX_MAX];
67unsigned long indexedRouterList[ROUTER_INDEX_MAX];
68int routerNb = 0;
69unsigned short v4PrefixNb = 0;
70struct PrefixV4 prefixV4Tab[PREFIX_V4_MAX];
71RulesPtr rulesListPtr;
72NetFlowV9HeaderPtr currentHeaderV9Ptr;
73key_t myKey = 0;
74int myQueue = 0;
75RuleDefPtr rulesAddress[FIELD_TYPE_NUMBER+1][MAX_RULES_PER_FIELD];
76RuleDefPtr *rulesAddressPtr;
77int reInitConf = 0;
78/* ENDV9 */
79static unsigned long datagramNumber;
80static time_t now;
81static unsigned long myHost; /* FIXME to erase */
82static struct tm *tmPtr;
83extern int errno;
84static int inputSock;
85static int sockNamelg;
86static int inputSock2;
87static int sockNameFromlg;
88static int rcv;
89static int sockBufSize = SOCKET_BUFFER_SIZE;           
90/* static unsigned short flowNumber; */
91static unsigned short receptPort = RECEPTION_PORT;
92static unsigned char *ptr_buffer;
93static char *receptAddress = RECEPTION_ADDRESS;
94static struct sockaddr_in name;
95static struct sockaddr_in name2;
96static struct sockaddr_in fromName;
97
98/*
99 * Main
100 * ----
101 */
102int 
103main (int argc, char *argv[])
104{
105  RulesPtr tmp = NULL;
106
107  if ( argc != 4) {
108    fprintf (stderr,
109             "%s: Usage: %s <routers file> <prefix IPv4 file> <rules file>\n exp: %s routers.txt IPv4_prefix.txt rules.txt\n",
110             argv[0], argv[0], argv[0]);
111    exit(1);
112  }
113
114  openlog(argv[0], LOG_PID, LOG_USER);
115
116  configFileName = (char *) malloc((strlen(argv[1])+1) * sizeof(char));
117  strcpy (configFileName, argv[1]);
118  prefixV4FileName = (char *) malloc((strlen(argv[2])+1) * sizeof(char));
119  strcpy (prefixV4FileName, argv[2]);
120  rulesFileName = (char *) malloc((strlen(argv[3])+1) * sizeof(char));
121  strcpy (rulesFileName, argv[3]);
122
123  initCache();
124  fprintf(stderr, "reading the routers list\n");
125  routerNb = getRegisteredRouters(configFileName, &sortedRouterList[0],
126                                  &indexedRouterList[0]);
127  fprintf(stderr, "reading the IPv4 prefix\n");
128  if ( (v4PrefixNb = getPrefixV4(prefixV4FileName, &prefixV4Tab[0])) < 1){
129    fprintf(stderr, "Error during prefix v4 reading\n");
130    exit(1);
131  }
132  rulesListPtr = NULL;
133  fprintf(stderr, "reading the rules\n");
134  rulesListPtr = getLightRules(rulesListPtr, rulesFileName);
135  tmp = rulesListPtr;
136  for ( ; tmp->next; tmp=tmp->next) {
137    if (tmp->type != 2) {
138      rulesListPtr = delRule(tmp, rulesListPtr);
139    }
140  }
141/*   printRule(rulesListPtr); */
142/*   exit(1); */
143
144  fprintf(stderr, "I become a deamon, next messages via syslogd.\n");
145  if (fork () != 0)
146    exit (0);
147  if (setsid() == -1){
148    exit(4);
149  }
150
151  /* handler, SIGUSR1 from renetcolSender */
152  myAction.sa_handler = sigusr1Mgmt;
153  myAction.sa_flags = SA_RESTART;
154  sigemptyset (&(myAction.sa_mask));
155  sigaddset (&(myAction.sa_mask), SIGALRM);
156  sigaction (SIGUSR1, &myAction, NULL);
157
158  setCache(rulesListPtr);
159  rulesAddressPtr = (RuleDefPtr *)rulesAddress;
160
161  /* init IPC messages queue */
162  myKey = createKey(argv[0]);
163  myQueue = createQueue(myKey);
164  sendMyPid(myQueue);
165
166  /* INIT THE CURRENTS VARIABLES*/
167  currentRouterPtr = routersListPtr;
168  currentHeaderV9Ptr = (NetFlowV9HeaderPtr)
169    malloc(sizeof(struct NetFlowV9Header));
170  pcktPtr = (DatagramPtr) malloc(sizeof(struct Datagram));
171  if (pcktPtr==NULL) {
172    fprintf(stderr, "ERROR in struct Datagram allocation\n");
173    exit(1);
174  } else {
175    pcktPtr->ipH = (IpHeaderPtr) malloc(sizeof(struct IpHeader));
176    pcktPtr->udp_header = (UdpHeaderPtr) malloc(sizeof(struct UdpHeader));
177  }
178
179  if (! (ptr_buffer = malloc(sockBufSize))) 
180    {
181      printf("ERROR during socket buffer allocation\n");
182      exit(2);
183    }
184
185  /* INIT INPUT STREAM*/
186  initStream();
187
188  datagramNumber =0; /* FIXME : ???? */
189
190  now = time((time_t *)NULL);
191  tmPtr = localtime(&now);
192  socketLoop(); /* all work on datagram is made here */
193  closelog();
194  fprintf(stderr, "END\n");
195  return (0);
196}
197
198/*
199 *
200 */
201void sendMyPid(int queueID)
202{
203  msgType myMsg;
204  char *msgTextIndex;
205  unsigned short tplMsgType = 12;
206  pid_t myPID;
207 
208  myPID = getpid();
209  msgTextIndex = mempcpy(mempcpy(myMsg.text,
210                                 &tplMsgType,
211                                 sizeof (unsigned short)
212                                 ),
213                         &myPID,
214                         sizeof(pid_t)
215                         );
216  myMsg.type = 1;
217  msgSend(queueID, myMsg);
218}
219
220/*
221 *
222 */
223void sendReadRulesSignal(int queueID)
224{
225  msgType myMsg;
226  char *msgTextIndex;
227  unsigned short tplMsgType = 13;
228 
229  msgTextIndex = mempcpy(myMsg.text,
230                         &tplMsgType,
231                         sizeof (unsigned short)
232                         );
233  myMsg.type = 1;
234  msgSend(queueID, myMsg);
235}
236
237/*
238 *
239 */
240void sigusr1Mgmt(int num)
241{
242  sigusr1Up = 1;
243}
244
245/*
246 *
247 */
248void 
249initRule()
250{
251  RulesPtr tmp = NULL;
252  initCache();
253  tmp = rulesListPtr;
254  for ( ; tmp; tmp=tmp->next) {
255    rulesListPtr = delRule(tmp, rulesListPtr);
256  }
257  rulesListPtr = NULL;
258  rulesListPtr = getLightRules(rulesListPtr, rulesFileName);
259  tmp = rulesListPtr;
260  for ( ; tmp; tmp=tmp->next) {
261    if (tmp->type != 2) {
262      rulesListPtr = delRule(tmp, rulesListPtr);
263    }
264  }
265  tmp = NULL;
266  initCache();
267  setCache(rulesListPtr);
268  sendReadRulesSignal(myQueue);
269}
270
271/*
272 *
273 */
274void
275initCache()
276{
277  int i,j;
278  for (i=0; i<FIELD_TYPE_NUMBER+1; i++){
279    for (j=0; j<MAX_RULES_PER_FIELD; j++){
280      rulesAddress[i][j] = NULL;
281    }
282  }
283}
284
285/*
286 * setCache()
287 */
288void
289setCache(RulesPtr rPtr)
290{
291  int i=0;
292  RulesPtr tmp = rPtr;
293  RuleDefPtr def = NULL;
294
295  while (tmp) {
296    def = tmp->def;
297    while (def) {
298      i = 0;
299      while (rulesAddress[def->fieldType][i] != NULL){
300        i++;
301      }
302      rulesAddress[def->fieldType][i] = def;
303      def = def->next;
304    }
305    tmp = tmp->next;
306  }
307}
308
309/*
310 * initStream()
311 */
312void 
313initStream()
314{
315  static unsigned short n0, n1, n2, n3;
316 
317  initSocket();
318  if (sscanf(receptAddress,"%hu.%hu.%hu.%hu",&n0,&n1,&n2,&n3)==0) {
319    perror("sscanf");
320  }             
321  buffer4[0] = (unsigned char)n3;
322  buffer4[1] = (unsigned char)n2;
323  buffer4[2] = (unsigned char)n1;
324  buffer4[3] = (unsigned char)n0;
325  myHost = *((unsigned long*)&buffer4[0]);
326}
327
328/*
329 * socketLoop()
330 */
331int 
332socketLoop()
333{
334  unsigned short shift;
335  short version = 0;
336  int regRouter = 0;
337  /* CRI */
338  time_t now = time((time_t *)NULL);
339  int iIP, iMPLS;
340  time_t lastIPOutput, lastMPLSOutput;
341  time_t receptionTime;
342  /* end */
343
344  now = time((time_t *)NULL);
345  lastMPLSOutput = now;
346  lastIPOutput = now;
347  do {
348    if (sigusr1Up == 1){
349      sigusr1Up = 0;
350      initRule();
351    }
352    socketReading();
353    getIpHeader(pcktPtr, ptr_buffer);
354    regRouter = checkIpHeader(pcktPtr, &sortedRouterList[0], routerNb);
355    getUdpHeader(pcktPtr, ptr_buffer);
356    checkUdpHeader(pcktPtr, regRouter, receptPort);
357   
358    switch( version =
359            getNetFlowHeader(pcktPtr, ptr_buffer,
360                             currentHeaderV9Ptr, offsetV9Ptr)){
361    case 9:
362      if ((currentRouterPtr=notExistRouter(routersListPtr,
363                                           pcktPtr->ipH->srcAdd))==NULL) {
364        routersListPtr = addRouter(routersListPtr,
365                                   pcktPtr->ipH->srcAdd,
366                                   (unsigned long) 0);
367        currentRouterPtr = routersListPtr;
368      }
369      currentFlowsetNumber = 0;
370      shift = 0;
371      while ((currentFlowsetNumber < currentHeaderV9Ptr->count)) {
372        curTplFlSetPtr = NULL;
373        currentFlowsetId=getFlowsetId(currentFlowsetNumber,
374                                      offsetV9Ptr, ptr_buffer);
375        if ( currentFlowsetId == 0 ) {
376          shift = checkTemplateFlowSet(currentRouterPtr, offsetV9Ptr,
377                                       ptr_buffer, currentHeaderV9Ptr,
378                                       curTplFlSetPtr,
379                                       currentFlowsetNumberPtr,
380                                       myQueue);
381/*        showAllTplFlSet();  */
382        } else if (currentFlowsetId == 1) {
383          shift = checkTemplateOption(currentRouterPtr, offsetV9Ptr,
384                                      ptr_buffer, currentHeaderV9Ptr,
385                                      curTplOptionPtr,
386                                      currentFlowsetNumberPtr);
387        } else {
388          shift = checkDataFlowSet(shift, currentRouterPtr,
389                                   currentHeaderV9Ptr, offsetV9Ptr,
390                                   ptr_buffer, currentFlowsetNumberPtr,
391                                   currentFlowsetIdPtr, pcktPtr,
392                                   rulesAddressPtr, rulesListPtr,
393                                   myQueue, prefixV4Tab,
394                                   (size_t) v4PrefixNb,
395                                   tabIPPtr,
396                                   tabMPLSPtr,
397                                   ipNbPtr, mplsNbPtr);
398        }
399      }
400      break;
401    default:
402/*        syslog(LOG_INFO,  */
403/*           "NetFlow exp. version unknown: %hu, from router: %lu.%lu.%lu.%lu", */
404/*           (unsigned short) version, */
405/*           (pcktPtr->ipH->srcAdd>>24), */
406/*           (pcktPtr->ipH->srcAdd<<8>>24), */
407/*           (pcktPtr->ipH->srcAdd<<16>>24), */
408/*           (pcktPtr->ipH->srcAdd<<24>>24));  */
409      break;
410    }
411
412#ifdef CRIHAN
413    now = time((time_t *)NULL);
414    receptionTime = now;
415    if ( (ipNb > (MAX_IP_FLOW - 50)) ||
416         ( (now-lastIPOutput) > IP_TIME_THRESHOLD) ) {
417      outputName[0] = '\0';
418      sprintf(cof_str, "%d", currentIPOutputFile);
419      strcat(outputName, OUTPUT_IP);
420      strcat(outputName, cof_str);
421      strcat(outputName, EXTENSION);
422      if (fopen(outputName, "x") == NULL) {
423        currentIPOutputFile = (currentIPOutputFile + 1)%MAX_IP_OUTPUT_FILES;
424        outputName[0] = '\0';
425        sprintf(cof_str, "%d", currentIPOutputFile);
426        strcat(outputName, OUTPUT_IP);
427        strcat(outputName, cof_str);
428        strcat(outputName, EXTENSION);
429      }
430      if ((fIP = fopen(outputName, "w")) == NULL) {
431        syslog(LOG_ERR,"Error in OUTPUT_IP opening : %s", strerror(errno));
432      } else {
433        for ( iIP = 0; iIP < ipNb; iIP++){
434          if ( tabIP[iIP].ipProt == 0 ) {
435            fprintf(fIP, "%lu;%lu;%hu;%hu;%lu.%lu.%lu.%lu;%lu.%lu.%lu.%lu;%d;%hu;%hu;%d;%d;%lu.%lu.%lu.%lu;%lu;%d\n",
436                    tabIP[iIP].bytes, tabIP[iIP].pkts,
437                    tabIP[iIP].inSnmp,  tabIP[iIP].outSnmp,
438                    tabIP[iIP].v4AdS>>24, tabIP[iIP].v4AdS<<8>>24,
439                    tabIP[iIP].v4AdS<<16>>24, tabIP[iIP].v4AdS<<24>>24,
440                    tabIP[iIP].v4AdD>>24, tabIP[iIP].v4AdD<<8>>24,
441                    tabIP[iIP].v4AdD<<16>>24, tabIP[iIP].v4AdD<<24>>24,
442                    tabIP[iIP].tProt, tabIP[iIP].sPort,
443                    tabIP[iIP].dPort, tabIP[iIP].maskD,
444                    tabIP[iIP].maskS, tabIP[iIP].routerAd>>24,
445                    tabIP[iIP].routerAd<<8>>24, tabIP[iIP].routerAd<<16>>24,
446                    tabIP[iIP].routerAd<<24>>24, tabIP[iIP].liveTime,
447                    receptionTime
448                    );
449          }
450        }
451        fclose(fIP);
452      }
453      ipNb = 0;
454      lastIPOutput = now;
455    }
456    now = time((time_t *)NULL);
457    if ( mplsNb > (MAX_MPLS_FLOW - 50) ||
458         ( (now-lastMPLSOutput) > MPLS_TIME_THRESHOLD) ) {
459      outputName[0] = '\0';
460      sprintf(cof_str, "%d", currentMPLSOutputFile);
461      strcat(outputName, OUTPUT_MPLS);
462      strcat(outputName, cof_str);
463      strcat(outputName, EXTENSION);
464      if (fopen(outputName, "x") == NULL) {
465        currentMPLSOutputFile = (currentMPLSOutputFile + 1)%MAX_MPLS_OUTPUT_FILES;
466        outputName[0] = '\0';
467        sprintf(cof_str, "%d", currentMPLSOutputFile);
468        strcat(outputName, OUTPUT_MPLS);
469        strcat(outputName, cof_str);
470        strcat(outputName, EXTENSION);
471      }
472      if ((fMPLS = fopen(outputName, "w")) == NULL) {
473        syslog(LOG_ERR,"Error in OUTPUT_MPLS opening : %s", strerror(errno));
474      } else {
475        for ( iMPLS = 0; iMPLS < mplsNb; iMPLS++){
476          if ( tabMPLS[iMPLS].ipProt == 0 ) {
477            fprintf(fMPLS, "%lu.%lu.%lu.%lu;%hu;%lu.%lu.%lu.%lu;%lu.%lu.%lu.%lu\n",
478                    tabMPLS[iMPLS].routerAd>>24,tabMPLS[iMPLS].routerAd<<8>>24,
479                    tabMPLS[iMPLS].routerAd<<16>>24,
480                    tabMPLS[iMPLS].routerAd<<24>>24,
481                    tabMPLS[iMPLS].mplsLabel1,tabMPLS[iMPLS].v4AdS>>24,
482                    tabMPLS[iMPLS].v4AdS<<8>>24,tabMPLS[iMPLS].v4AdS<<16>>24,
483                    tabMPLS[iMPLS].v4AdS<<24>>24,tabMPLS[iMPLS].v4AdD>>24,
484                    tabMPLS[iMPLS].v4AdD<<8>>24,tabMPLS[iMPLS].v4AdD<<16>>24,
485                    tabMPLS[iMPLS].v4AdD<<24>>24
486                    );
487          }
488        }
489        fclose(fMPLS);
490      }
491      mplsNb = 0;
492      lastMPLSOutput = now;
493    }
494#endif /* CRIHAN */
495  } while (1);
496}
497
498/*
499 * initSocket()
500 */
501short 
502initSocket()
503{
504  inputSock = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
505  if (inputSock < 0)
506    {
507      syslog(LOG_ERR,"socket : %s", strerror(errno));
508      exit(1);
509    }
510  memset((void*)&name, 0, sizeof(name));
511  name.sin_family = AF_INET;
512  name.sin_addr.s_addr = htonl(INADDR_ANY);
513  if (name.sin_addr.s_addr == INADDR_NONE){
514    syslog(LOG_ERR, " INADDR_NONE ");
515    exit(1);
516  }
517  name.sin_port = htons(receptPort);
518  if (bind(inputSock,(struct sockaddr *)(&name), sizeof(name)) < 0)
519    {
520      syslog(LOG_ERR, "bind : %s", strerror(errno));
521      exit(1);
522    }                                                           
523  sockNamelg = sizeof(name);
524  if (getsockname(inputSock, (struct sockaddr *) (&name),
525                  (socklen_t *)&sockNamelg) < 0)
526    {
527      syslog(LOG_ERR, "getsockname: %s", strerror(errno));
528      exit(1);
529    }
530  /* Here socket DGRAM creation, only to not have a unreachable service */
531  inputSock2 = socket(AF_INET, SOCK_DGRAM, 0);
532  if (inputSock2 < 0)
533    {
534      syslog(LOG_ERR,"socket : %s", strerror(errno));
535      exit(1);
536    }
537  memset((void*)&name, 0, sizeof(name));
538  name2.sin_family = AF_INET;
539  name2.sin_addr.s_addr = htonl(INADDR_ANY);
540  if (name2.sin_addr.s_addr == INADDR_NONE){
541    syslog(LOG_ERR, " INADDR_NONE ");
542    exit(1);
543  }
544  name2.sin_port = htons(receptPort);
545  if (bind(inputSock2,(struct sockaddr *)(&name2), sizeof(name2)) < 0)
546    {
547      syslog(LOG_ERR, "bind : %s", strerror(errno));
548      exit(1);
549    }                                                           
550  sockNamelg = sizeof(name2);
551  if (getsockname(inputSock2, (struct sockaddr *) (&name2),
552                  (socklen_t *)&sockNamelg) < 0)
553    {
554      syslog(LOG_ERR, "getsockname: %s", strerror(errno));
555      exit(1);
556    }
557  return(0);
558}
559
560
561/*
562 * init socket
563 */
564short 
565socketReading()
566{
567  signed short sockLg;
568
569  sockNameFromlg = sizeof(fromName);
570  rcv = recvfrom(inputSock, ptr_buffer, sockBufSize, 0,
571                 (struct sockaddr *)(&fromName),
572                 (socklen_t *)&sockNameFromlg);   
573  sockLg = rcv;
574  if (sockLg < 0) {
575    syslog(LOG_ERR,"recvfrom : %s", strerror(errno));
576    exit(1);
577  }
578  if (sockLg == 0) {
579    syslog(LOG_ERR,"recvfrom : %s", strerror(errno));
580    exit(1);
581  }
582  return(0);
583}
584 
585/*
586 * check up flow datagramme
587 */
588short 
589checkFlow(short flowNumber)
590{
591  return(0);
592}
593
594/*
595 * showAllTplFlSet
596 *
597 */
598void 
599showAllTplFlSet()
600{
601  RouterPtr tmp = routersListPtr;
602  TplFlowSetPtr tmpFS;
603  TplOptionPtr tmpOP;
604  fprintf(stderr,"All template definitions: (field, size) :\n");
605  for (; tmp; tmp=tmp->next) {
606    fprintf(stderr,"router %lu.%lu.%lu.%lu : \n",
607            (tmp->IpAddress>>24),
608            (tmp->IpAddress<<8>>24),
609            (tmp->IpAddress<<16>>24),
610            (tmp->IpAddress<<24>>24));
611    tmpFS =  tmp->tplList;
612    for (; tmpFS; tmpFS=tmpFS->next) {
613      fprintf(stderr,"ID %hu: ", tmpFS->templateFlowSetId);
614      printFieldSet(tmpFS->fieldSet);
615      fprintf(stderr,"\n");
616    }
617    if ((tmpOP = tmp->tplOptList) != NULL){
618      fprintf(stderr,"template option: \n");
619      for (; tmpOP; tmpOP=tmpOP->next) {
620        fprintf(stderr,"ID %hu: ", tmpOP->templateOptionId);
621        printFieldSet(tmpOP->fieldSet);
622        fprintf(stderr,"\n");
623      }
624      fprintf(stderr,"\n");
625    }
626  }
627}
Note: See TracBrowser for help on using the browser.