root/trunk/src/renetcol.c @ 18

Revision 18, 14.6 KB (checked in by andreu, 16 years ago)

ajout pour CRIHAN

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