root/trunk/src/renetcol.c @ 6

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

First 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;
31sigjmp_buf contextSigalrm;
32struct sigaction myAction;  /* for timer */ 
33volatile sig_atomic_t isAlarmUp = 0;
34/* V9 */
35unsigned short offsetV9 = 0;
36unsigned short *offsetV9Ptr = &offsetV9;
37unsigned char buffer1;
38unsigned char buffer2[2];
39unsigned char buffer4[4];
40unsigned char buffer6[6];
41short currentFlowsetNumber;
42short *currentFlowsetNumberPtr = &currentFlowsetNumber;
43short currentFlowsetId;
44short *currentFlowsetIdPtr = &currentFlowsetId;
45TplFlowSetPtr curTplFlSetPtr;
46TplOptionPtr curTplOptionPtr;
47RouterPtr routersListPtr;
48RouterPtr currentRouterPtr;
49DatagramPtr pcktPtr;
50unsigned long sortedRouterList[ROUTER_INDEX_MAX];
51unsigned long indexedRouterList[ROUTER_INDEX_MAX];
52int routerNb = 0;
53struct PrefixV4 prefixV4Tab[PREFIX_V4_MAX];
54RulesPtr rulesListPtr;
55NetFlowV9HeaderPtr currentHeaderV9Ptr;
56key_t myKey = 0;
57int myQueue = 0;
58RuleDefPtr rulesAddress[FIELD_TYPE_NUMBER+1][MAX_RULES_PER_FIELD];
59RuleDefPtr *rulesAddressPtr;
60/* ENDV9 */
61static unsigned long datagramNumber;
62static time_t now;
63static unsigned long myHost; /* FIXME to erase */
64static struct tm *tmPtr;
65extern int errno;
66static int inputSock;
67static int sockNamelg;
68static int sockNameFromlg;
69static int rcv;
70static int sockBufSize = SOCKET_BUFFER_SIZE;           
71static unsigned short flowNumber;
72static unsigned short receptPort = RECEPTION_PORT;
73static unsigned char *ptr_buffer;
74static char *receptAddress = RECEPTION_ADDRESS;
75static struct sockaddr_in name;
76static struct sockaddr_in fromName;
77
78/*
79 * Main
80 * ----
81 */
82int 
83main (int argc, char *argv[])
84{
85  RulesPtr tmp = NULL;
86
87  if ( argc != 4) {
88    fprintf (stderr,
89             "%s: Usage: %s <routers file> <prefix IPv4 file> <rules file>\n exp: %s routers.txt IPv4_prefix.txt rules.txt\n",
90             argv[0], argv[0], argv[0]);
91    exit(1);
92  }
93  openlog(argv[0], LOG_PID, LOG_USER);
94
95  configFileName = (char *) malloc((strlen(argv[1])+1) * sizeof(char));
96  strcpy (configFileName, argv[1]);
97  prefixV4FileName = (char *) malloc((strlen(argv[2])+1) * sizeof(char));
98  strcpy (prefixV4FileName, argv[2]);
99  rulesFileName = (char *) malloc((strlen(argv[3])+1) * sizeof(char));
100  strcpy (rulesFileName, argv[3]);
101
102  initCache();
103  routerNb = getRegisteredRouters(configFileName, &sortedRouterList[0],
104                                  &indexedRouterList[0]);
105  if ( getPrefixV4(prefixV4FileName, &prefixV4Tab[0]) < 1){
106    fprintf(stderr, "Error during prefix v4 reading\n");
107    exit(1);
108  }
109  rulesListPtr = NULL;
110  rulesListPtr = getLightRules(rulesListPtr, rulesFileName);
111  tmp = rulesListPtr;
112  for ( ; tmp->next; tmp=tmp->next) {
113    if (tmp->type != 2) {
114      rulesListPtr = delRule(tmp, rulesListPtr);
115    }
116  }
117  setCache(rulesListPtr);
118  rulesAddressPtr = (RuleDefPtr *)rulesAddress;
119
120  /* init IPC messages queue */
121  myKey = createKey(argv[0]);
122  myQueue = createQueue(myKey);
123
124  /* INIT THE CURRENTS VARIABLES*/
125  currentRouterPtr = routersListPtr;
126  currentHeaderV9Ptr = (NetFlowV9HeaderPtr)
127    malloc(sizeof(struct NetFlowV9Header));
128  pcktPtr = (DatagramPtr) malloc(sizeof(struct Datagram));
129  if (pcktPtr==NULL) {
130    fprintf(stderr, "ERROR in struct Datagram allocation\n");
131    exit(1);
132  } else {
133    pcktPtr->ipH = (IpHeaderPtr) malloc(sizeof(struct IpHeader));
134    pcktPtr->udp_header = (UdpHeaderPtr) malloc(sizeof(struct UdpHeader));
135  }
136
137  if (! (ptr_buffer = malloc(sockBufSize))) 
138    {
139      printf("ERROR during socket buffer allocation\n");
140      exit(2);
141    }
142
143  /* INIT INPUT STREAM*/
144  initStream();
145
146  datagramNumber =0;
147
148  /* INIT FROM CONFS FILES*/
149  /*initConf();*/
150
151  /* TIME */
152  now = time((time_t *)NULL);
153  tmPtr = localtime(&now);
154  socketLoop();
155  closelog();
156  fprintf(stderr, "END\n");
157  return (0);
158}
159
160/*
161 *
162 */
163void
164initCache()
165{
166  int i,j;
167  for (i=0; i<FIELD_TYPE_NUMBER+1; i++){
168    for (j=0; j<MAX_RULES_PER_FIELD; j++){
169      rulesAddress[i][j] = NULL;
170    }
171  }
172}
173
174/*
175 *
176 */
177void
178setCache(RulesPtr rPtr)
179{
180  int i=0;
181  RulesPtr tmp = rPtr;
182  RuleDefPtr def = NULL;
183
184  while (tmp) {
185    def = tmp->def;
186    while (def) {
187      i = 0;
188      while (rulesAddress[def->fieldType][i] != NULL){
189        i++;
190      }
191      rulesAddress[def->fieldType][i] = def;
192      def = def->next;
193    }
194    tmp = tmp->next;
195  }
196}
197
198/*
199 * initStream()
200 */
201void 
202initStream()
203{
204  static unsigned short n0, n1, n2, n3;
205 
206  initSocket();
207  if (sscanf(receptAddress,"%hu.%hu.%hu.%hu",&n0,&n1,&n2,&n3)==0) {
208    perror("sscanf");
209  }             
210  buffer4[0] = (unsigned char)n3;
211  buffer4[1] = (unsigned char)n2;
212  buffer4[2] = (unsigned char)n1;
213  buffer4[3] = (unsigned char)n0;
214  myHost = *((unsigned long*)&buffer4[0]);
215}
216
217/*
218 * socketLoop()
219 */
220int 
221socketLoop()
222{
223  unsigned short shift;
224  short version = 0;
225  do {
226    socketReading();
227    getIpHeader(pcktPtr, ptr_buffer);
228    checkIpHeader(pcktPtr, &sortedRouterList[0], routerNb);
229    getUdpHeader(pcktPtr, ptr_buffer);
230    checkUdpHeader(pcktPtr);
231   
232    switch( version =
233            getNetFlowHeader(pcktPtr, ptr_buffer,
234                             currentHeaderV9Ptr, offsetV9Ptr)){
235    case 1:
236      checkNetFlowHeader(pcktPtr);
237      break;
238    case 5:
239      checkNetFlowHeader(pcktPtr);
240      break;
241    case 9:
242      if ((currentRouterPtr=notExistRouter(routersListPtr,
243                                           pcktPtr->ipH->srcAdd))==NULL) {
244        routersListPtr = addRouter(routersListPtr,
245                                   pcktPtr->ipH->srcAdd,
246                                   (unsigned long) 0);
247        currentRouterPtr = routersListPtr;
248      }
249      currentFlowsetNumber = 0;
250      shift = 0;
251      while ((currentFlowsetNumber < currentHeaderV9Ptr->count)) {
252        curTplFlSetPtr = NULL;
253        currentFlowsetId=getFlowsetId(currentFlowsetNumber,
254                                      offsetV9Ptr, ptr_buffer);
255        if ( currentFlowsetId == 0 ) {
256          shift = checkTemplateFlowSet(currentRouterPtr, offsetV9Ptr,
257                                       ptr_buffer, currentHeaderV9Ptr,
258                                       curTplFlSetPtr,
259                                       currentFlowsetNumberPtr,
260                                       myQueue);
261/*        showAllTplFlSet();  */
262        } else if (currentFlowsetId == 1) {
263          shift = checkTemplateOption(currentRouterPtr, offsetV9Ptr,
264                                      ptr_buffer, currentHeaderV9Ptr,
265                                      curTplOptionPtr,
266                                      currentFlowsetNumberPtr);
267        } else {
268          shift = checkDataFlowSet(shift, currentRouterPtr,
269                                   currentHeaderV9Ptr, offsetV9Ptr,
270                                   ptr_buffer, currentFlowsetNumberPtr,
271                                   currentFlowsetIdPtr, pcktPtr,
272                                   rulesAddressPtr, rulesListPtr,
273                                   myQueue);
274        }
275      }
276      break;
277    default:
278      syslog(LOG_INFO,
279             "NetFlow exp. version unknown: %hu, from router: %lu.%lu.%lu.%lu",
280             (unsigned short) version,
281             (pcktPtr->ipH->srcAdd>>24),
282             (pcktPtr->ipH->srcAdd<<8>>24),
283             (pcktPtr->ipH->srcAdd<<16>>24),
284             (pcktPtr->ipH->srcAdd<<24>>24));
285      break;
286    }
287  } while (1);
288}
289
290/*
291 * initSocket()
292 */
293short 
294initSocket()
295{
296  inputSock = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
297  if (inputSock < 0)
298    {
299      syslog(LOG_ERR,"socket : %s", strerror(errno));
300      exit(1);
301    }
302  memset((void*)&name, 0, sizeof(name));
303  name.sin_family = AF_INET;
304  name.sin_addr.s_addr = htonl(INADDR_ANY);
305  if (name.sin_addr.s_addr == INADDR_NONE){
306    syslog(LOG_ERR, " INADDR_NONE ");
307    exit(1);
308  }
309  name.sin_port = htons(receptPort);
310  if (bind(inputSock,(struct sockaddr *)(&name), sizeof(name)) < 0)
311    {
312      syslog(LOG_ERR, "bind : %s", strerror(errno));
313      exit(1);
314    }                                                           
315  sockNamelg = sizeof(name);
316  if (getsockname(inputSock, (struct sockaddr *) (&name),
317                  (socklen_t *)&sockNamelg) < 0)
318    {
319      syslog(LOG_ERR, "getsockname: %s", strerror(errno));
320      exit(1);
321    }
322  return(0);
323}
324
325
326/*
327 * init socket
328 */
329short 
330socketReading()
331{
332  signed short sockLg;
333
334  sockNameFromlg = sizeof(fromName);
335  rcv = recvfrom(inputSock, ptr_buffer, sockBufSize, 0,
336                 (struct sockaddr *)(&fromName),
337                 (socklen_t *)&sockNameFromlg);   
338  sockLg = rcv;
339  if (sockLg < 0) {
340    syslog(LOG_ERR,"recvfrom : %s", strerror(errno));
341    exit(1);
342  }
343  if (sockLg == 0) {
344    syslog(LOG_ERR,"recvfrom : %s", strerror(errno));
345    exit(1);
346  }
347  return(0);
348}
349 
350/*
351 * check up flow datagramme
352 */
353short 
354checkFlow(short flowNumber)
355{
356  return(0);
357}
358
359/*
360 * showAllTplFlSet
361 *
362 */
363void 
364showAllTplFlSet()
365{
366  RouterPtr tmp = routersListPtr;
367  TplFlowSetPtr tmpFS;
368  TplOptionPtr tmpOP;
369  fprintf(stderr,"All template definitions: (field, size) :\n");
370  for (; tmp; tmp=tmp->next) {
371    fprintf(stderr,"router %lu.%lu.%lu.%lu : \n",
372            (tmp->IpAddress>>24),
373            (tmp->IpAddress<<8>>24),
374            (tmp->IpAddress<<16>>24),
375            (tmp->IpAddress<<24>>24));
376    tmpFS =  tmp->tplList;
377    for (; tmpFS; tmpFS=tmpFS->next) {
378      fprintf(stderr,"ID %hu: ", tmpFS->templateFlowSetId);
379      printFieldSet(tmpFS->fieldSet);
380      fprintf(stderr,"\n");
381    }
382    if ((tmpOP = tmp->tplOptList) != NULL){
383      fprintf(stderr,"template option: \n");
384      for (; tmpOP; tmpOP=tmpOP->next) {
385        fprintf(stderr,"ID %hu: ", tmpOP->templateOptionId);
386        printFieldSet(tmpOP->fieldSet);
387        fprintf(stderr,"\n");
388      }
389      fprintf(stderr,"\n");
390    }
391  }
392}
Note: See TracBrowser for help on using the browser.