root/trunk/src/renetcol.c @ 17

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

*** empty log message ***

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