root/trunk/src/renetcol.c @ 58

Revision 58, 18.0 KB (checked in by andreu, 15 years ago)

new aggregation method, new configuration files, corrections on the php script for graph generation.

  • Property svn:eol-style set to native
Line 
1/*
2 * File: renetcol.c
3 *
4 * Authors: ANDREU Francois-Xavier
5 *
6 * Copyright (C) 2005 2006 2007 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
28struct MyPtrs myPtrs; /* defined in routers_mgmt.h */
29
30struct SHMForAgg *shmForAgg;
31
32unsigned short currentIPOutputFile = 0;    /* index on the current IP file */
33unsigned short currentMPLSOutputFile = 0;  /* index on the current MPLS file */
34char outputName[256];
35char cof_str[20];                          /* current ouput file name */
36FILE *fIP;                                 /* pointer on the IP output file */
37FILE *fMPLS;                              /* pointer on the MPLS output file */
38
39struct sigaction myAction; /* handler for renetcolSender communication */
40sigjmp_buf contextSigalrm; /* '' */
41volatile sig_atomic_t sigusr1Up = 0;
42/* struct sigaction myAction;  for timer not used in this version */
43
44unsigned short currentIntervalle = 0;        /* based on 5 min intervalles */ 
45
46unsigned short offsetV9 = 0;                 /* index in a neflow v9 packet */
47
48unsigned char buffer1;
49unsigned char buffer2[2];
50unsigned char buffer4[4];
51unsigned char buffer6[6];
52
53short currentFlowsetNumber;
54short currentFlowsetId;
55TplFlowSetPtr curTplFlSetPtr; /* current template flowset pointer */
56TplOptionPtr curTplOptionPtr;
57RouterPtr routersListPtr;
58
59unsigned long sortedRouterList[ROUTER_INDEX_MAX];
60unsigned long indexedRouterList[ROUTER_INDEX_MAX];
61int routerNb = 0;                                  /* routers number */
62
63key_t myKey = 0;
64int myQueue = 0;
65
66/* Next structure used as cache in rules reading */
67RuleDefPtr rulesAddress[FIELD_TYPE_NUMBER+1][MAX_RULES_PER_FIELD];
68
69int reInitConf = 0;
70
71static struct tm *tmPtr;
72
73extern int errno;
74static int inputSock;
75static int sockNamelg;
76static int inputSock2;
77static int sockNameFromlg;
78static int rcv;
79static int sockBufSize = SOCKET_BUFFER_SIZE;           
80/* static unsigned short flowNumber; */
81static unsigned short receptPort = RECEPTION_PORT;
82/* static unsigned char *ptr_buffer; */
83static char *receptAddress = RECEPTION_ADDRESS;
84static struct sockaddr_in name;
85static struct sockaddr_in name2;
86static struct sockaddr_in fromName;
87
88/*
89 * Main
90 * ----
91 */
92int 
93main (int argc, char *argv[])
94{
95  RulesPtr tmp = NULL;
96  int shmid;
97  key_t key;
98  int i,j;
99  int k;
100
101#ifdef IPV4AGG
102  fprintf(stderr, "renetcol compilation and execution with IPv4 Aggregation feature enable\n");
103#endif
104 
105  openlog(argv[0], LOG_PID, LOG_USER);
106
107  initCache();
108  /* GET the list of routers who are available to send NDE to the collector */
109  if ( (routerNb = getRegisteredRouters(ROUTERS_LIST,
110                                        &sortedRouterList[0],
111                                        &indexedRouterList[0])) == -1) {
112    fprintf(stderr,
113            "ERROR in getRegisteredRouters from file %s\n",
114            ROUTERS_LIST);
115    exit(-1);
116  }
117  /* Create the list of routers */
118  for (i=0; i<routerNb; i++){
119    fprintf(stderr, "add router : %lu\n", sortedRouterList[i]);
120    routersListPtr = addRouter(routersListPtr, sortedRouterList[i]);
121  }
122 
123  /* Shared memory */
124  key = 8765;
125  if ((shmid = shmget(key, SHMSIZE, IPC_CREAT | 0666)) < 0) {
126    perror("shmget");
127    exit(1);
128  }
129  if ((shmForAgg = (struct SHMForAgg *)shmat(shmid, (void *)0, 0)) == (void *) -1) {
130    perror("shmat");
131    exit(1);
132  }
133
134  if ( (shmForAgg->v4PrefixNb = getPrefixV4(SUBNETS_LIST, &(shmForAgg->prefixV4Tab[0][0]))) < 1){
135    fprintf(stderr, "renetcol: Error \n");
136    exit(1);
137  }
138  if ( (shmForAgg->v4PrefixNb = getPrefixV4(SUBNETS_LIST, &(shmForAgg->prefixV4Tab[1][0]))) < 1){
139    fprintf(stderr, "renetcol:  Error \n");
140    exit(1);
141  }
142
143  shmForAgg->currentTable = 0;
144  shmForAgg->secondTable = 1;
145  shmForAgg->readed = 0;
146
147  /* get the rules */
148  myPtrs.rulesListPtr = NULL;
149  myPtrs.rulesListPtr = getRules(myPtrs.rulesListPtr, RULES_FILE);
150  tmp = myPtrs.rulesListPtr;
151  for ( ; tmp->next; tmp=tmp->next) {
152    if (tmp->type != 2) {
153      myPtrs.rulesListPtr = delRule(tmp, myPtrs.rulesListPtr);
154    }
155  }
156  tmp = NULL;
157#ifdef DEBUG
158  printRule(rulesListPtr);
159#endif
160
161  /* the fork */
162  fprintf(stderr, "renetcol: I become a deamon, next messages via syslogd. By.\n");
163  if (fork () != 0)
164    exit (0);
165  if (setsid() == -1){
166    exit(4);
167  }
168
169  /* handler, SIGUSR1 from renetcolSender */
170  myAction.sa_handler = sigusr1Mgmt;
171  myAction.sa_flags = SA_RESTART;
172  sigemptyset (&(myAction.sa_mask));
173  sigaddset (&(myAction.sa_mask), SIGALRM);
174  sigaction (SIGUSR1, &myAction, NULL);
175
176  /* Cache for fast rules access */
177  setCache(myPtrs.rulesListPtr);
178  myPtrs.rulesAddressPtr = (RuleDefPtr *)rulesAddress;
179
180  /* IPC messages queue init */
181  myKey = createKey(argv[0]);
182  myQueue = createQueue(myKey);
183  sendMyPid(myQueue);
184
185  /* get SNMP index information */
186  k = getSNMPIndexList(INTERFACES_TYPE_LIST, routersListPtr);
187
188  /* INIT THE CURRENTS VARIABLES*/
189  myPtrs.currentRouterPtr = routersListPtr;
190  myPtrs.currentHeaderV9Ptr = (NetFlowV9HeaderPtr)
191    malloc(sizeof(struct NetFlowV9Header));
192  myPtrs.offsetV9Ptr = &offsetV9;
193  myPtrs.currentFlowsetIdPtr = &currentFlowsetId;
194  myPtrs.pcktPtr = (DatagramPtr) malloc(sizeof(struct Datagram));
195  myPtrs.currentFlowsetNumberPtr = &currentFlowsetNumber;
196  myPtrs.routersID = &indexedRouterList;
197  myPtrs.currentV4Tab = shmForAgg->prefixV4Tab[shmForAgg->currentTable];
198  myPtrs.secondV4Tab = shmForAgg->prefixV4Tab[shmForAgg->secondTable];
199  myPtrs.matrixPOP = &(shmForAgg->matrixPOP[shmForAgg->currentTable][0][0]);
200
201  /* INIT MATRIX TABLES */
202  for (i=0; i<ROUTER_INDEX_MAX; i++){
203    for (j=0; j<ROUTER_INDEX_MAX; j++) {
204      shmForAgg->matrixPOP[0][i][j].bytesNb = 0;
205      shmForAgg->matrixPOP[0][i][j].pktsNb = 0;
206      shmForAgg->matrixPOP[0][i][j].flowNb = 0;
207      shmForAgg->matrixPOP[1][i][j].bytesNb = 0;
208      shmForAgg->matrixPOP[1][i][j].pktsNb = 0;
209      shmForAgg->matrixPOP[1][i][j].flowNb = 0;
210    }
211  }
212
213  /* Checkup */
214  if (myPtrs.pcktPtr==NULL) {
215    fprintf(stderr, "ERROR in struct Datagram allocation\n");
216    exit(1);
217  } else {
218    myPtrs.pcktPtr->ipH = (IpHeaderPtr) malloc(sizeof(struct IpHeader));
219    myPtrs.pcktPtr->udp_header = (UdpHeaderPtr) malloc(sizeof(struct UdpHeader));
220  }
221  if (! (myPtrs.ptr_buffer = malloc(sockBufSize))) 
222    {
223      printf("ERROR during socket buffer allocation\n");
224      exit(2);
225    }
226
227  /* INIT INPUT STREAM*/
228  initStream();
229
230  socketLoop(); /* all work on datagram is made here */
231
232  closelog();
233
234  fprintf(stderr, "END\n");
235
236  return (0);
237}
238
239/*
240 * send his PID to another program via IPC message queue
241 *
242 * @param queueID the IPC queue ident
243 *
244 */
245void 
246sendMyPid(int queueID)
247{
248  msgType myMsg;
249  char *msgTextIndex;
250  unsigned short tplMsgType = 12;
251  pid_t myPID;
252 
253  myPID = getpid();
254  msgTextIndex = mempcpy(mempcpy(myMsg.text,
255                                 &tplMsgType,
256                                 sizeof (unsigned short)
257                                 ),
258                         &myPID,
259                         sizeof(pid_t)
260                         );
261  myMsg.type = 1;
262  msgSend(queueID, myMsg);
263}
264
265/*
266 * Send the "read rules list" message to another program
267 *
268 * @param queueID the IPC queue ident
269 *
270 */
271void sendReadRulesSignal(int queueID)
272{
273  msgType myMsg;
274  char *msgTextIndex;
275  unsigned short tplMsgType = 13;
276 
277  msgTextIndex = mempcpy(myMsg.text,
278                         &tplMsgType,
279                         sizeof (unsigned short)
280                         );
281  myMsg.type = 1;
282  msgSend(queueID, myMsg);
283}
284
285/*
286 *
287 */
288void 
289sigusr1Mgmt(int num)
290{
291  sigusr1Up = 1;
292}
293
294/*
295 * init the rule structure
296 */
297void 
298initRule()
299{
300  RulesPtr tmp = NULL;
301  initCache();
302  tmp = myPtrs.rulesListPtr;
303  for ( ; tmp; tmp=tmp->next) {
304    myPtrs.rulesListPtr = delRule(tmp, myPtrs.rulesListPtr);
305  }
306  myPtrs.rulesListPtr = NULL;
307  myPtrs.rulesListPtr = getRules(myPtrs.rulesListPtr, RULES_FILE);
308  tmp = myPtrs.rulesListPtr;
309  for ( ; tmp; tmp=tmp->next) {
310    if (tmp->type != 2) {
311      myPtrs.rulesListPtr = delRule(tmp, myPtrs.rulesListPtr);
312    }
313  }
314  tmp = NULL;
315  initCache();
316  setCache(myPtrs.rulesListPtr);
317  sendReadRulesSignal(myQueue);
318#ifdef DEBUG
319  printRule(myPtrs.rulesListPtr);
320#endif
321}
322
323/*
324 * init cache table
325 */
326void
327initCache()
328{
329  int i,j;
330  for (i=0; i<FIELD_TYPE_NUMBER+1; i++){
331    for (j=0; j<MAX_RULES_PER_FIELD; j++){
332      rulesAddress[i][j] = NULL;
333    }
334  }
335}
336
337/*
338 * setCache()
339 */
340void
341setCache(RulesPtr rPtr)
342{
343  int i=0;
344  RulesPtr tmp = rPtr;
345  RuleDefPtr def = NULL;
346
347#ifdef DEBUG
348  fprintf(stderr,"Cache for Rules\n");
349#endif 
350  while (tmp) {
351    def = tmp->def;
352    while (def) {
353      i = 0;
354      while (rulesAddress[def->fieldType][i] != NULL){
355        i++;
356      }
357      rulesAddress[def->fieldType][i] = def;
358      def = def->next;
359#ifdef DEBUG
360      fprintf(stderr,"%d: %d ", def->fieldType, i);
361#endif     
362    }
363#ifdef DEBUG
364    fprintf(stderr,"\n");
365#endif     
366    tmp = tmp->next;
367  }
368}
369
370/*
371 * initStream()
372 */
373void 
374initStream()
375{
376  static unsigned short n0, n1, n2, n3;
377
378  initSocket();
379  if (sscanf(receptAddress,"%hu.%hu.%hu.%hu",&n0,&n1,&n2,&n3)==0) {
380    perror("sscanf");
381  }             
382  buffer4[0] = (unsigned char)n3;
383  buffer4[1] = (unsigned char)n2;
384  buffer4[2] = (unsigned char)n1;
385  buffer4[3] = (unsigned char)n0;
386}
387
388/*
389 * socketLoop()
390 */
391int 
392socketLoop()
393{
394  short shift;
395  short version = 0;
396  int regRouter = 0;
397  time_t now = time((time_t *)NULL);
398  int loopNb = 0;
399  int gardeFou = 0;
400  time_t lastIPOutput, lastMPLSOutput;
401
402  now = time((time_t *)NULL);
403  tmPtr = localtime(&now);
404  currentIntervalle = tmPtr->tm_min;
405  lastMPLSOutput = now;
406  lastIPOutput = now;
407  do {
408#ifdef DEBUG   
409    fprintf (stderr, "[");
410#endif
411    if ( ((tmPtr->tm_min)%STEP == 0) && (currentIntervalle != tmPtr->tm_min)){
412      currentIntervalle = tmPtr->tm_min;
413      if (shmForAgg->currentTable == 0) {
414        shmForAgg->currentTable = 1;
415        shmForAgg->secondTable = 0;
416      }else{
417        shmForAgg->currentTable = 0;
418        shmForAgg->secondTable = 1;
419      }
420      shmForAgg->readed = 1;
421      myPtrs.matrixPOP = &(shmForAgg->matrixPOP[shmForAgg->currentTable][0][0]);
422    }
423    if (sigusr1Up == 1){
424      sigusr1Up = 0;
425      initRule();
426    }
427    socketReading();
428    getIpHeader(myPtrs.pcktPtr, myPtrs.ptr_buffer);
429    regRouter = checkIpHeader(myPtrs.pcktPtr, &sortedRouterList[0], routerNb);
430    getUdpHeader(myPtrs.pcktPtr, myPtrs.ptr_buffer);
431    if ( checkUdpHeader(myPtrs.pcktPtr, regRouter, receptPort) == 1 ){
432      continue;
433    }
434   
435    switch( version =
436            getNetFlowHeader(myPtrs.pcktPtr, myPtrs.ptr_buffer,
437                             myPtrs.currentHeaderV9Ptr, myPtrs.offsetV9Ptr)){
438    case 9:
439      if ((myPtrs.currentRouterPtr=notExistRouter(routersListPtr,
440                                                  myPtrs.pcktPtr->ipH->srcAdd))==NULL) {
441        myPtrs.currentRouterPtr = routersListPtr;
442      }
443      currentFlowsetNumber = 0;
444      shift = 0;
445      gardeFou=0;
446      while ((currentFlowsetNumber < myPtrs.currentHeaderV9Ptr->count)) {
447        gardeFou++;
448        curTplFlSetPtr = NULL;
449        currentFlowsetId=getFlowsetId(currentFlowsetNumber,
450                                      myPtrs.offsetV9Ptr, myPtrs.ptr_buffer);
451        if ( currentFlowsetId == 0 ) {
452          if ( (shift = checkTemplateFlowSet(myPtrs.currentRouterPtr,
453                                             myPtrs.offsetV9Ptr,
454                                             myPtrs.ptr_buffer,
455                                             myPtrs.currentHeaderV9Ptr,
456                                             curTplFlSetPtr,
457                                             myPtrs.currentFlowsetNumberPtr,
458                                             myQueue)) < 0 ) {
459#ifdef DEBUG
460            fprintf (stderr, "w>\n");
461#endif
462            currentFlowsetNumber = myPtrs.currentHeaderV9Ptr->count + 1;
463          };
464          writeAllTplFlSet();
465        } else if (currentFlowsetId == 1) {
466          if ( (shift = checkTemplateOption(myPtrs.currentRouterPtr,
467                                            myPtrs.offsetV9Ptr,
468                                            myPtrs.ptr_buffer,
469                                            myPtrs.currentHeaderV9Ptr,
470                                            curTplOptionPtr,
471                                            myPtrs.currentFlowsetNumberPtr) ) < 0 ) {
472#ifdef DEBUG
473            fprintf (stderr, "wo>\n");
474#endif 
475            currentFlowsetNumber = myPtrs.currentHeaderV9Ptr->count + 1;
476          }
477        } else if (currentFlowsetId > 255) {
478          if ( (shift = checkDataFlowSet(shift,
479                                         &myPtrs,
480                                         myQueue,
481                                         shmForAgg->prefixV4Tab[shmForAgg->currentTable],
482                                         (size_t) shmForAgg->v4PrefixNb
483                                         ) ) < 0 ) {
484#ifdef DEBUG   
485            fprintf (stderr, "wd>\n");
486#endif
487            currentFlowsetNumber = myPtrs.currentHeaderV9Ptr->count + 1;
488          }
489        } else {
490#ifdef DEBUG   
491          fprintf (stderr, "1<<255\n");
492#endif
493          currentFlowsetNumber = myPtrs.currentHeaderV9Ptr->count + 1;
494        }
495        if ( gardeFou > 200) { exit(-1); }
496      } /* end while flowset exist */
497      break;
498    default:
499      syslog(LOG_INFO,
500             "NetFlow exp. version unknown: %hu, from router: %lu.%lu.%lu.%lu",
501             (unsigned short) version,
502             (myPtrs.pcktPtr->ipH->srcAdd>>24),
503             (myPtrs.pcktPtr->ipH->srcAdd<<8>>24),
504             (myPtrs.pcktPtr->ipH->srcAdd<<16>>24),
505             (myPtrs.pcktPtr->ipH->srcAdd<<24>>24));
506      break;
507    }
508    if (loopNb  > 1000 ){
509      /* FIXME perhaps call this function via the compilation options */
510      writeAllTplFlSet();
511#ifdef DEBUG   
512      fprintf(stderr, "W");
513#endif
514      loopNb = 0;
515    }
516    loopNb++;
517
518    now = time((time_t *)NULL);
519    tmPtr = localtime(&now);
520#ifdef DEBUG   
521    fprintf (stderr, "]\n");
522#endif
523  } while (1);
524}
525
526/*
527 * initSocket()
528 */
529short 
530initSocket()
531{
532  inputSock = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
533  if (inputSock < 0)
534    {
535      syslog(LOG_ERR,"socket : %s", strerror(errno));
536      exit(1);
537    }
538  memset((void*)&name, 0, sizeof(name));
539  name.sin_family = AF_INET;
540  name.sin_addr.s_addr = htonl(INADDR_ANY);
541  if (name.sin_addr.s_addr == INADDR_NONE){
542    syslog(LOG_ERR, " INADDR_NONE ");
543    exit(1);
544  }
545  name.sin_port = htons(receptPort);
546  if (bind(inputSock,(struct sockaddr *)(&name), sizeof(name)) < 0)
547    {
548      syslog(LOG_ERR, "bind : %s", strerror(errno));
549      exit(1);
550    }                                                           
551  sockNamelg = sizeof(name);
552  if (getsockname(inputSock, (struct sockaddr *) (&name),
553                  (socklen_t *)&sockNamelg) < 0)
554    {
555      syslog(LOG_ERR, "getsockname: %s", strerror(errno));
556      exit(1);
557    }
558  /* Here socket DGRAM creation, only to not have a unreachable service */
559  /* message in return */
560  inputSock2 = socket(AF_INET, SOCK_DGRAM, 0);
561  if (inputSock2 < 0)
562    {
563      syslog(LOG_ERR,"socket : %s", strerror(errno));
564      exit(1);
565    }
566  memset((void*)&name, 0, sizeof(name));
567  name2.sin_family = AF_INET;
568  name2.sin_addr.s_addr = htonl(INADDR_ANY);
569  if (name2.sin_addr.s_addr == INADDR_NONE){
570    syslog(LOG_ERR, " INADDR_NONE ");
571    exit(1);
572  }
573  name2.sin_port = htons(receptPort);
574  if (bind(inputSock2,(struct sockaddr *)(&name2), sizeof(name2)) < 0)
575    {
576      syslog(LOG_ERR, "bind : %s", strerror(errno));
577      exit(1);
578    }                                                           
579  sockNamelg = sizeof(name2);
580  if (getsockname(inputSock2, (struct sockaddr *) (&name2),
581                  (socklen_t *)&sockNamelg) < 0)
582    {
583      syslog(LOG_ERR, "getsockname: %s", strerror(errno));
584      exit(1);
585    }
586  return(0);
587}
588
589
590/*
591 * init socket
592 */
593short 
594socketReading()
595{
596  signed short sockLg;
597
598  sockNameFromlg = sizeof(fromName);
599  rcv = recvfrom(inputSock, myPtrs.ptr_buffer, sockBufSize, 0,
600                 (struct sockaddr *)(&fromName),
601                 (socklen_t *)&sockNameFromlg);   
602  sockLg = rcv;
603  if (sockLg < 0) {
604    syslog(LOG_ERR,"recvfrom : %s", strerror(errno));
605    exit(1);
606  }
607  if (sockLg == 0) {
608    syslog(LOG_ERR,"recvfrom : %s", strerror(errno));
609    exit(1);
610  }
611  return(0);
612}
613 
614/*
615 * check up flow datagramme 
616 */
617short 
618checkFlow(short flowNumber)
619{
620  return(0); /* FIXME : why this function ??? */
621}
622
623/*
624 * showAllTplFlSet
625 *
626 * to use only in debug mode
627 */
628void 
629showAllTplFlSet()
630{
631  RouterPtr tmp = routersListPtr;
632  TplFlowSetPtr tmpFS;
633  TplOptionPtr tmpOP;
634  fprintf(stderr,"\n*********************************************\n* All template definitions: (field, size) : *\n*********************************************\n");
635  for (; tmp; tmp=tmp->next) {
636    fprintf(stderr,"----------------------\nrouter %lu.%lu.%lu.%lu : \n----------------------\n",
637            (tmp->IpAddress>>24),
638            (tmp->IpAddress<<8>>24),
639            (tmp->IpAddress<<16>>24),
640            (tmp->IpAddress<<24>>24));
641    tmpFS =  tmp->tplList;
642    for (; tmpFS; tmpFS=tmpFS->next) {
643      fprintf(stderr,"TId %hu (sourceId: %lu):\n",
644              tmpFS->templateFlowSetId,
645              tmpFS->sourceId);
646      printFieldSet(stderr, tmpFS->fieldSet);
647      fprintf(stderr,"\n");
648    }
649    if ((tmpOP = tmp->tplOptList) != NULL){
650      for (; tmpOP; tmpOP=tmpOP->next) {
651        fprintf(stderr,"OpTId %hu (sourceId: %lu) >\n",
652                tmpOP->templateOptionId,
653                tmpOP->sourceId);
654        printFieldSet(stderr, tmpOP->fieldSet);
655        fprintf(stderr,"\n");
656      }
657      fprintf(stderr,"\n");
658    }
659  }
660}
661
662
663/*
664 * writeAllTplFlSet
665 *
666 */
667void 
668writeAllTplFlSet()
669{
670
671  RouterPtr tmp = routersListPtr;
672  TplFlowSetPtr tmpFS;
673  TplOptionPtr tmpOP;
674  FILE *TPLFILE;
675  if (!(TPLFILE = fopen("/tmp/TemplateDef.txt", "w"))) {
676    syslog (LOG_ERR, "error during %s opening", "/tmp/TemplateDef.txt");
677  }
678  fprintf(TPLFILE,"\n*********************************************\n* All template definitions: (field, size) : *\n*********************************************\n");
679  for (; tmp; tmp=tmp->next) {
680    fprintf(TPLFILE,"----------------------\nrouter %lu.%lu.%lu.%lu : \n----------------------\n",
681            (tmp->IpAddress>>24),
682            (tmp->IpAddress<<8>>24),
683            (tmp->IpAddress<<16>>24),
684            (tmp->IpAddress<<24>>24));
685    tmpFS =  tmp->tplList;
686    for (; tmpFS; tmpFS=tmpFS->next) {
687      fprintf(TPLFILE,"TId %hu (sourceId: %lu):\n",
688              tmpFS->templateFlowSetId,
689              tmpFS->sourceId);
690      printFieldSet(TPLFILE, tmpFS->fieldSet);
691      fprintf(TPLFILE,"\n");
692    }
693    if ((tmpOP = tmp->tplOptList) != NULL){
694      for (; tmpOP; tmpOP=tmpOP->next) {
695        fprintf(TPLFILE,"OpTId %hu (sourceId: %lu) last %d brackets are Scope >\n lg: %hu, opScopeLg: %hu, opLg: %hu\n",
696                tmpOP->templateOptionId,
697                tmpOP->sourceId,
698                tmpOP->optionScopeLg/4,
699                tmpOP->length,
700                tmpOP->optionScopeLg,
701                tmpOP->optionLg);
702        printFieldSet(TPLFILE, tmpOP->fieldSet);
703        fprintf(TPLFILE,"\n");
704      }
705      fprintf(TPLFILE,"\n");
706    }
707  }
708  fclose(TPLFILE);
709}
Note: See TracBrowser for help on using the browser.