root/trunk/src/renetcol.c @ 15

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

?

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