1 /*
2 * Argus Software
3 * Copyright (c) 2000-2016 QoSient, LLC
4 * All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22 /*
23 * rapath - print derivable path information from argus data.
24 *
25 * The strategy is to take in 'icmpmap' data, and to formulate path information
26 * for the collection of records received. By classifying all the flow data by
27 * the tuple {src, dst}, we can track any number of simulataneous traceroutes
28 * and report on the results in a manner that preserves the granularity of the
29 * data seen, but provide means to modify that granularity to get interesting
30 * results.
31 *
32 * The intermediate nodes
33 *
34 * written by Carter Bullard
35 * QoSient, LLC
36 *
37 * $Id: //depot/argus/clients/examples/rapath/rapath.c#15 $
38 * $DateTime: 2016/06/01 15:17:28 $
39 * $Change: 3148 $
40 */
41
42 #ifdef HAVE_CONFIG_H
43 #include "argus_config.h"
44 #endif
45
46 #if defined(CYGWIN)
47 #define USE_IPV6
48 #endif
49
50 #include <unistd.h>
51 #include <stdlib.h>
52 #include <signal.h>
53 #include <ctype.h>
54
55 #include <argus_compat.h>
56
57 #include <rabins.h>
58 #include <argus_util.h>
59 #include <argus_client.h>
60 #include <argus_main.h>
61 #include <argus_sort.h>
62
63 #include <argus_filter.h>
64 #include <argus_cluster.h>
65
66 #include <math.h>
67
68 int RaInitialized = 0;
69 int RaPrintThinkMapOutput = 0;
70 int RaPrintSVGOutput = 0;
71 int RaPrintASNum = 0;
72 int RaPrintNode = 0;
73 int RaPrintAddr = 0;
74 int RaPrintTreeNode = 0;
75 int RaPrintDistance = 0;
76
77 extern int RaHistoStart;
78 extern int RaHistoEnd;
79
80 struct ArgusQueueStruct *ArgusModelerQueue;
81
82 int RaCompareArgusStore (const void *, const void *);
83 void RaPackQueue (struct ArgusQueueStruct *);
84 void RaSortQueue (struct ArgusQueueStruct *);
85 void RaProcessQueue(struct ArgusQueueStruct *, unsigned char);
86
87 #define RAMAP_ETHER_MAC_ADDR 0x1
88 #define RAMAP_IP_ADDR 0x10
89
90 #define MAX_OBJ_SIZE 1024
91 unsigned int RaMapHash = 0;
92 unsigned int RaHashSize = 0;
93
94 struct RaMapHashTableStruct {
95 int size;
96 struct RaMapHashTableHeader **array;
97 };
98
99 struct RaMapHashTableHeader {
100 struct ArgusQueueHeader qhdr;
101 struct RaMapHashTableHeader *nxt, *prv;
102 unsigned int hash;
103 int type, len, value, mask, visited;
104 void *obj, *sub;
105 };
106
107 struct ArgusHashTable *ArgusHashTable;
108 struct RaMapHashTableStruct RaMapAddrTable;
109 struct RaMapHashTableHeader *RaMapFindHashObject (struct RaMapHashTableStruct *, void *, int, int);
110 struct RaMapHashTableHeader *RaMapAddHashEntry (struct RaMapHashTableStruct *, void *, int, int);
111 void RaMapRemoveHashEntry (struct RaMapHashTableStruct *, struct RaMapHashTableHeader *);
112
113
114 unsigned int RaMapCalcHash (void *, int, int);
115
116 struct ArgusAggregatorStruct *ArgusMatrixAggregator = NULL;
117 struct ArgusAggregatorStruct *ArgusFlowAggregator = NULL;
118
119
120 char *RaMatrixAggregationConfig[] = {
121 "RACLUSTER_PRESERVE_FIELDS=yes",
122 " model=\"srcid saddr daddr\" status=0 idle=3600\n",
123 NULL,
124 };
125
126 char *RaPathAggregationConfig[] = {
127 "RACLUSTER_PRESERVE_FIELDS=yes",
128 "filter=\"icmpmap\" model=\"srcid saddr daddr proto sttl inode\" status=120 idle=3600\n",
129 " model=\"srcid saddr daddr proto sttl\" status=0 idle=3600\n",
130 NULL,
131 };
132
133 #define ARGUS_RCITEMS 4
134
135 #define ARGUS_RC_FILTER 0
136 #define ARGUS_RC_MODEL 1
137 #define ARGUS_RC_STATUS 2
138 #define ARGUS_RC_IDLE 3
139
140 extern char *ArgusAggregatorFields[];
141
142 void
ArgusClientInit(struct ArgusParserStruct * parser)143 ArgusClientInit (struct ArgusParserStruct *parser)
144 {
145 struct ArgusModeStruct *mode = NULL;
146
147 parser->RaWriteOut = 0;
148
149 if (!(parser->RaInitialized)) {
150 if ((mode = parser->ArgusModeList) != NULL) {
151 while (mode) {
152 if (!(strcasecmp (mode->mode, "think")))
153 RaPrintThinkMapOutput++;
154 if (!(strcasecmp (mode->mode, "svg")))
155 RaPrintSVGOutput++;
156 if (!(strcasecmp (mode->mode, "addr"))) {
157 RaPrintAddr = 1;
158 RaPrintNode = 0;
159 }
160 if (!(strcasecmp (mode->mode, "tree")))
161 RaPrintTreeNode = 1;
162
163 if (!(strcasecmp (mode->mode, "node"))) {
164 RaPrintAddr = 0;
165 RaPrintNode = 1;
166 }
167 if (!(strcasecmp (mode->mode, "aspath"))) {
168 RaPrintASNum++;
169 }
170 if (!(strcasecmp (mode->mode, "asnode"))) {
171 RaPrintASNum++;
172 RaPrintNode++;
173 }
174 if (!(strcasecmp (mode->mode, "dist")))
175 RaPrintDistance = 1;
176 mode = mode->nxt;
177 }
178 }
179
180 if (!(RaPrintAddr) && !(RaPrintNode) && !(RaPrintASNum))
181 RaPrintNode = 1;
182
183 if (ArgusParser->RaPrintOptionStrings[0] == NULL) {
184 parser->RaPrintOptionIndex = 0;
185 parser->RaPrintOptionStrings[parser->RaPrintOptionIndex++] = strdup("srcid");
186 parser->RaPrintOptionStrings[parser->RaPrintOptionIndex++] = strdup("saddr");
187 parser->RaPrintOptionStrings[parser->RaPrintOptionIndex++] = strdup("dir");
188 parser->RaPrintOptionStrings[parser->RaPrintOptionIndex++] = strdup("daddr");
189 parser->RaPrintOptionStrings[parser->RaPrintOptionIndex++] = strdup("inode");
190
191 if (RaPrintASNum)
192 parser->RaPrintOptionStrings[parser->RaPrintOptionIndex++] = strdup("ias:8");
193
194 parser->RaPrintOptionStrings[parser->RaPrintOptionIndex++] = strdup("sttl");
195 parser->RaPrintOptionStrings[parser->RaPrintOptionIndex++] = strdup("mean");
196 parser->RaPrintOptionStrings[parser->RaPrintOptionIndex++] = strdup("stddev");
197 parser->RaPrintOptionStrings[parser->RaPrintOptionIndex++] = strdup("max");
198 parser->RaPrintOptionStrings[parser->RaPrintOptionIndex++] = strdup("min");
199 parser->RaPrintOptionStrings[parser->RaPrintOptionIndex++] = strdup("trans");
200 ArgusProcessSOptions(parser);
201 }
202
203 if (parser->ArgusFlowModelFile) {
204 if ((parser->ArgusLabeler = ArgusNewLabeler(parser, 0L)) == NULL)
205 ArgusLog (LOG_ERR, "ArgusClientInit: ArgusNewLabeler error");
206
207 RaLabelParseResourceFile (parser, parser->ArgusLabeler, parser->ArgusFlowModelFile);
208 free(parser->ArgusFlowModelFile);
209 parser->ArgusFlowModelFile = NULL;
210 }
211
212 if ((ArgusFlowAggregator = ArgusParseAggregator(parser, NULL, RaPathAggregationConfig)) == NULL)
213 ArgusLog (LOG_ERR, "ArgusClientInit: ArgusParseAggregator error");
214
215 if (parser->ArgusMaskList != NULL) {
216 if ((parser->ArgusAggregator = ArgusNewAggregator(parser, NULL, ARGUS_RECORD_AGGREGATOR)) == NULL)
217 ArgusLog (LOG_ERR, "ArgusClientInit: ArgusNewAggregator error");
218
219 // have to see if we need to modify the model definition in our RaPathAggregation Config
220
221 if (ArgusFlowAggregator->saddrlen != parser->ArgusAggregator->saddrlen) {
222 ArgusFlowAggregator->saddrlen = parser->ArgusAggregator->saddrlen;
223 bcopy(&parser->ArgusAggregator->smask, &ArgusFlowAggregator->smask, sizeof(parser->ArgusAggregator->smask));
224 }
225
226 if (ArgusFlowAggregator->daddrlen != parser->ArgusAggregator->daddrlen) {
227 ArgusFlowAggregator->daddrlen = parser->ArgusAggregator->daddrlen;
228 bcopy(&parser->ArgusAggregator->dmask, &ArgusFlowAggregator->dmask, sizeof(parser->ArgusAggregator->dmask));
229 }
230
231 } else {
232 if ((parser->ArgusAggregator = ArgusParseAggregator(parser, NULL, RaMatrixAggregationConfig)) == NULL)
233 ArgusLog (LOG_ERR, "ArgusClientInit: ArgusParseAggregator error");
234 }
235
236 if ((ArgusSorter = ArgusNewSorter(parser)) == NULL)
237 ArgusLog (LOG_ERR, "ArgusClientInit: ArgusNewSorter error %s", strerror(errno));
238
239 if (parser->vflag)
240 ArgusReverseSortDir++;
241
242 bzero ((char *) ArgusSorter->ArgusSortAlgorithms, sizeof(ArgusSorter->ArgusSortAlgorithms));
243 ArgusSorter->ArgusSortAlgorithms[0] = ArgusSortAlgorithmTable[ARGUSSORTSRCADDR];
244 ArgusSorter->ArgusSortAlgorithms[1] = ArgusSortAlgorithmTable[ARGUSSORTDSTADDR];
245 ArgusSorter->ArgusSortAlgorithms[2] = ArgusSortAlgorithmTable[ARGUSSORTPROTOCOL];
246 ArgusSorter->ArgusSortAlgorithms[3] = ArgusSortAlgorithmTable[ARGUSSORTSRCTTL];
247 ArgusSorter->ArgusSortAlgorithms[4] = ArgusSortAlgorithmTable[ARGUSSORTTRANSACTIONS];
248 ArgusSorter->ArgusSortAlgorithms[4] = ArgusSortAlgorithmTable[ARGUSSORTMINDURATION];
249
250 if ((ArgusModelerQueue = ArgusNewQueue()) == NULL)
251 exit(0);
252
253 if ((ArgusHashTable = ArgusNewHashTable(RABINS_HASHTABLESIZE)) == NULL)
254 ArgusLog (LOG_ERR, "ArgusClientInit: ArgusCalloc error %s\n", strerror(errno));
255
256 if ((RaMapAddrTable.array = (struct RaMapHashTableHeader **) ArgusCalloc (RA_HASHTABLESIZE,
257 sizeof (struct RaMapHashTableHeader *))) != NULL) {
258 RaMapAddrTable.size = RA_HASHTABLESIZE;
259 }
260
261 parser->RaCumulativeMerge = 1;
262
263 if (parser->Hflag) {
264 if (!(ArgusHistoMetricParse (parser, parser->ArgusAggregator)))
265 usage();
266 }
267
268 parser->RaInitialized++;
269 }
270 }
271
272
273 void
ArgusClientTimeout()274 ArgusClientTimeout ()
275 {
276 /*
277 RaProcessQueue (ArgusModelerQueue, ARGUS_STATUS);
278 */
279 #ifdef ARGUSDEBUG
280 ArgusDebug (9, "ArgusClientTimeout() done\n");
281 #endif
282 }
283
284
285 struct RaPathNode {
286 struct RaPathNode *nxt;
287 struct ArgusQueueStruct *nodes;
288 int as, ttl;
289 };
290
291 struct RaPathTree {
292 };
293
294
295 struct RaPathNode *RaPathBuildPath (struct ArgusQueueStruct *);
296 void RaPathDeletePath (struct RaPathNode *);
297 void RaPrintPath (struct RaPathNode *, char *, int);
298
299 /*
300 The idea is to build the path tree for a given queue. The queue
301 should have ArgusRecordStruct's that have unique icmp->osrcaddr
302 elements, sorted by sttl. These queue elements represent the
303 unique elements to deal with in this path and a path is constructed.
304
305 Nodes in the path can be single elements,
306
307 */
308
309
310 void RaPathInsertTree (struct RaPathTree *, struct RaPathNode *);
311 void RaPrintPathNodes (struct RaPathNode *, int, char *buf, int);
312
313 struct RaPathNode *
RaPathBuildPath(struct ArgusQueueStruct * queue)314 RaPathBuildPath (struct ArgusQueueStruct *queue)
315 {
316 struct RaPathNode *path = NULL, *node = NULL;
317 struct ArgusRecordStruct *argus;
318 unsigned int pttl, tttl, as;
319
320 if (queue->count > 0) {
321 while ((argus = (struct ArgusRecordStruct *) ArgusPopQueue(queue, ARGUS_NOLOCK)) != NULL) {
322 struct ArgusIPAttrStruct *attr = (void *)argus->dsrs[ARGUS_IPATTR_INDEX];
323 struct ArgusAsnStruct *asn = (void *)argus->dsrs[ARGUS_ASN_INDEX];
324
325 tttl = attr->src.ttl;
326
327 if (path == NULL) {
328 if ((path = (struct RaPathNode *) ArgusCalloc (1, sizeof (*node))) == NULL)
329 ArgusLog (LOG_ERR, "ArgusCalloc error %s", strerror(errno));
330
331 node = path;
332 node->ttl = tttl;
333
334 if ((asn != NULL) && (asn->hdr.argus_dsrvl8.len > 2))
335 if ((as = asn->inode_as) != 0) {
336 node->as = as;
337 }
338
339 if ((node->nodes = ArgusNewQueue()) == NULL)
340 ArgusLog (LOG_ERR, "ArgusNewQueue error %s", strerror(errno));
341
342 ArgusAddToQueue (node->nodes, &argus->qhdr, ARGUS_NOLOCK);
343
344 } else {
345 struct ArgusIPAttrStruct *pattr = (void *)((struct ArgusRecordStruct *)node->nodes->start)->dsrs[ARGUS_IPATTR_INDEX];
346
347 if ((pattr != NULL) && (attr != NULL)) {
348 pttl = pattr->src.ttl;
349
350 if (pttl == tttl) {
351 ArgusAddToQueue (node->nodes, &argus->qhdr, ARGUS_NOLOCK);
352
353 if ((asn != NULL) && (asn->hdr.argus_dsrvl8.len > 2))
354 if (node->as != asn->inode_as)
355 node->as = -1;
356 } else {
357 struct RaPathNode *prv = node;
358
359 if ((node = (struct RaPathNode *) ArgusCalloc (1, sizeof (*node))) == NULL)
360 ArgusLog (LOG_ERR, "ArgusCalloc error %s", strerror(errno));
361
362 node->ttl = tttl;
363
364 if ((asn != NULL) && (asn->hdr.argus_dsrvl8.len > 2))
365 if ((as = asn->inode_as) != 0)
366 node->as = as;
367
368 prv->nxt = node;
369
370 if ((node->nodes = ArgusNewQueue()) == NULL)
371 ArgusLog (LOG_ERR, "ArgusNewQueue error %s", strerror(errno));
372
373 ArgusAddToQueue (node->nodes, &argus->qhdr, ARGUS_NOLOCK);
374 }
375 }
376 }
377 }
378 }
379
380 return (path);
381 }
382
383 void
RaPathDeletePath(struct RaPathNode * path)384 RaPathDeletePath (struct RaPathNode *path)
385 {
386 if (path->nxt != NULL)
387 RaPathDeletePath(path->nxt);
388
389 if (path->nodes != NULL) {
390 ArgusDeleteQueue(path->nodes);
391 }
392 ArgusFree(path);
393
394 return;
395 }
396
397
398 void
RaPathInsertTree(struct RaPathTree * tree,struct RaPathNode * path)399 RaPathInsertTree (struct RaPathTree *tree, struct RaPathNode *path)
400 {
401 }
402
403 // "as" AS1 -> AS2 -> AS3
404 // "node" A -> B -> {C, D} -> F
405 // "node" [A -> B] -> [{C, D} -> F] -> [G -> H]
406 // "asnode" AS30496:[A -> B] -> AS6079:[C -> {D,E}] -> AS1257:[F] -> AS11164:[G -> H] -> AS5050:[I] -> AS9:[J -> {K,L}]
407
408 void
RaPrintPathNodes(struct RaPathNode * tree,int level,char * buf,int len)409 RaPrintPathNodes (struct RaPathNode *tree, int level, char *buf, int len)
410 {
411 struct RaPathNode *path = tree;
412 unsigned short as = 0;
413 int status = 0, shop = 0;
414
415 while (path != NULL) {
416 struct ArgusQueueStruct *queue = path->nodes;
417 struct ArgusRecordStruct *argus = NULL;
418 int hopcount, multias = 0;
419
420 if (status == 0) {
421 if (path->as != 0) {
422 if (path->as == -1) {
423 multias = 1;
424 } else {
425 as = path->as;
426
427 if (RaPrintASNum) {
428 sprintf (&buf[strlen(buf)], "AS%d", as);
429
430 if (RaPrintNode || RaPrintAddr)
431 sprintf (&buf[strlen(buf)], ":[");
432
433 } else
434 sprintf (&buf[strlen(buf)], "[");
435
436 status++;
437 }
438 }
439 shop = path->ttl;
440 hopcount = 0;
441 }
442
443 if (queue->count > 1) {
444 if (RaPrintNode || RaPrintAddr) {
445 sprintf (&buf[strlen(buf)], "{");
446 while ((argus = (struct ArgusRecordStruct *) ArgusPopQueue(queue, ARGUS_NOLOCK)) != NULL) {
447 if (multias) {
448 struct ArgusAsnStruct *asn = (void *)argus->dsrs[ARGUS_ASN_INDEX];
449 if ((asn != NULL) && (asn->hdr.argus_dsrvl8.len > 2)) {
450 if (RaPrintASNum) {
451 if (asn->inode_as > 0) {
452 sprintf (&buf[strlen(buf)], "AS%d", asn->inode_as);
453 } else {
454 sprintf (&buf[strlen(buf)], "%c", argus->autoid);
455 }
456 } else
457 sprintf (&buf[strlen(buf)], ":[");
458 }
459 }
460
461 if (RaPrintAddr) {
462 char inodeStr[256], *inodePtr = inodeStr;
463 ArgusPrintInode (ArgusParser, inodeStr, argus, 256);
464 while (*inodePtr == ' ') inodePtr++;
465 while (inodePtr[strlen(inodePtr) - 1] == ' ') inodePtr[strlen(inodePtr) - 1] = '\0';
466 sprintf (&buf[strlen(buf)], "%s", inodePtr);
467 } else
468 sprintf (&buf[strlen(buf)], "%c", argus->autoid);
469
470 if (multias) {
471 sprintf (&buf[strlen(buf)], "]");
472 }
473
474 if (queue->count > 0)
475 sprintf (&buf[strlen(buf)], ", ");
476
477 ArgusAddToQueue(ArgusModelerQueue, &argus->qhdr, ARGUS_LOCK);
478 }
479
480 sprintf (&buf[strlen(buf)], "}");
481 if (RaPrintDistance) {
482 sprintf (&buf[strlen(buf)], ":%d", path->ttl);
483 shop = path->ttl;
484 }
485
486 while ((argus = (struct ArgusRecordStruct *) ArgusPopQueue(ArgusModelerQueue, ARGUS_LOCK)) != NULL)
487 ArgusAddToQueue(queue, &argus->qhdr, ARGUS_NOLOCK);
488 }
489
490 } else {
491 argus = (struct ArgusRecordStruct *) queue->start;
492
493 if (RaPrintAddr) {
494 char inodeStr[256], *inodePtr = inodeStr;
495 ArgusPrintInode (ArgusParser, inodeStr, argus, 256);
496 while (*inodePtr == ' ') inodePtr++;
497 while (inodePtr[strlen(inodePtr) - 1] == ' ') inodePtr[strlen(inodePtr) - 1] = '\0';
498 sprintf (&buf[strlen(buf)], "%s", inodePtr);
499
500 } else
501 if (RaPrintNode) {
502 sprintf (&buf[strlen(buf)], "%c", argus->autoid);
503 }
504
505 if (RaPrintDistance) {
506 sprintf (&buf[strlen(buf)], ":%d", path->ttl);
507 shop = path->ttl;
508 }
509 }
510
511 if ((path = path->nxt) != NULL) {
512 if (status) {
513 if (path->as != as) {
514 if (RaPrintNode || RaPrintAddr)
515 sprintf (&buf[strlen(buf)], "]");
516
517 if (RaPrintDistance) {
518 if ((hopcount - shop) > 0) {
519 sprintf (&buf[strlen(buf)], ":%d-%d", shop, hopcount);
520 hopcount = 0;
521 }
522 }
523
524 sprintf (&buf[strlen(buf)], " -> ");
525 status--;
526 as = 0;
527
528 } else {
529 if (RaPrintNode || RaPrintAddr)
530 sprintf (&buf[strlen(buf)], " -> ");
531 hopcount = path->ttl;
532 }
533
534 } else
535 if (RaPrintNode || RaPrintAddr)
536 sprintf (&buf[strlen(buf)], " -> ");
537
538 } else {
539 if (status) {
540 if (RaPrintDistance) {
541 if ((hopcount - shop) > 0)
542 sprintf (&buf[strlen(buf)], ":%d-%d", shop, hopcount);
543 }
544
545 if (RaPrintNode || RaPrintAddr)
546 sprintf (&buf[strlen(buf)], "]");
547 }
548 }
549 }
550 }
551
552
553 void
RaPrintPath(struct RaPathNode * tree,char * buf,int len)554 RaPrintPath (struct RaPathNode *tree, char *buf, int len)
555 {
556 bzero (buf, len);
557 RaPrintPathNodes(tree, 0, buf, len);
558 }
559
560
RaArgusInputComplete(struct ArgusInput * input)561 void RaArgusInputComplete (struct ArgusInput *input) { return; }
562
563
564 int RaParseCompleting = 0;
565 struct RaPathTree *RaTreeNode = NULL;
566
567 void
RaParseComplete(int sig)568 RaParseComplete (int sig)
569 {
570 struct ArgusModeStruct *mode = NULL;
571 int i = 0, x = 0, nflag = ArgusParser->eNflag;
572
573 if (sig >= 0) {
574 if (!(ArgusParser->RaParseCompleting++)) {
575 struct ArgusAggregatorStruct *agg = ArgusParser->ArgusAggregator;
576
577 ArgusParser->RaParseCompleting += sig;
578
579 if (agg != NULL) {
580 if (agg->queue->count) {
581 struct ArgusRecordStruct *tns = NULL, *cns = NULL;
582
583 if (!(ArgusSorter)) {
584 if ((ArgusSorter = ArgusNewSorter(ArgusParser)) == NULL)
585 ArgusLog (LOG_ERR, "RaParseComplete: ArgusNewSorter error %s", strerror(errno));
586
587 if ((mode = ArgusParser->ArgusMaskList) != NULL) {
588 while (mode) {
589 for (x = 0; x < MAX_SORT_ALG_TYPES; x++) {
590 if (!strncmp (ArgusSortKeyWords[x], mode->mode, strlen(ArgusSortKeyWords[x]))) {
591 ArgusSorter->ArgusSortAlgorithms[i++] = ArgusSortAlgorithmTable[x];
592 break;
593 }
594 }
595
596 mode = mode->nxt;
597 }
598 }
599 }
600
601 ArgusSortQueue (ArgusSorter, agg->queue);
602 if (nflag == 0)
603 ArgusParser->eNflag = agg->queue->count;
604 else
605 ArgusParser->eNflag = nflag > agg->queue->count ? agg->queue->count : nflag;
606
607 for (i = 0; i < ArgusParser->eNflag; i++) {
608 tns = (struct ArgusRecordStruct *) agg->queue->array[i];
609
610 if (tns->agg != NULL) {
611 int count = tns->agg->queue->count;
612 char nodeChar = 'A';
613
614 ArgusSortQueue (ArgusSorter, tns->agg->queue);
615
616 for (x = 0; x < count; x++) {
617 cns = (struct ArgusRecordStruct *) tns->agg->queue->array[x];
618 cns->autoid = nodeChar;
619 nodeChar = ((nodeChar == 'Z') ? 'a' : nodeChar + 1);
620 }
621
622 if (ArgusParser->Aflag) {
623 struct RaPathNode *path = RaPathBuildPath (tns->agg->queue);
624 char RaTreeBuffer[MAXSTRLEN];
625
626 if (path) {
627 char srcId[32], srcAddr[32], dstAddr[32];
628
629 if (RaPrintTreeNode)
630 RaPathInsertTree(RaTreeNode, path);
631
632 cns = (struct ArgusRecordStruct *) tns->agg->queue->array[0];
633
634 bzero(srcId, sizeof(srcId));
635 bzero(srcAddr, sizeof(srcAddr));
636 bzero(dstAddr, sizeof(dstAddr));
637
638 ArgusPrintSourceID (ArgusParser, srcId, cns, 0);
639 ArgusPrintSrcAddr (ArgusParser, srcAddr, cns, 0);
640 ArgusPrintDstAddr (ArgusParser, dstAddr, cns, 0);
641
642 RaPrintPath (path, RaTreeBuffer, sizeof(RaTreeBuffer));
643
644 srcId[strlen(srcId) - 1] = '\0';
645 srcAddr[strlen(srcAddr) - 1] = '\0';
646 dstAddr[strlen(dstAddr) - 1] = '\0';
647
648 printf("%s(%s::%s) %s\n", srcId, srcAddr, dstAddr, RaTreeBuffer);
649 RaPathDeletePath(path);
650 }
651 }
652
653 for (x = 0; x < count; x++) {
654 cns = (struct ArgusRecordStruct *) tns->agg->queue->array[x];
655 RaSendArgusRecord (cns);
656 }
657 if (!(ArgusParser->qflag))
658 printf ("\n");
659 }
660 }
661 ArgusFree(ArgusParser->ns);
662 }
663 }
664
665 ArgusDeleteAggregator(ArgusParser, ArgusFlowAggregator);
666 ArgusDeleteHashTable(ArgusHashTable);
667 ArgusDeleteSorter(ArgusSorter);
668 ArgusDeleteQueue(ArgusModelerQueue);
669
670 if (RaMapAddrTable.array != NULL) {
671 ArgusFree (RaMapAddrTable.array);
672 RaMapAddrTable.array = NULL;
673 }
674
675 #ifdef ARGUSDEBUG
676 ArgusDebug (2, "RaParseComplete(caught signal %d)\n", sig);
677 #endif
678 switch (sig) {
679 case SIGHUP:
680 case SIGINT:
681 case SIGTERM:
682 case SIGQUIT: {
683 struct ArgusWfileStruct *wfile = NULL;
684
685 ArgusShutDown(sig);
686
687 if (ArgusParser->ArgusWfileList != NULL) {
688 struct ArgusListObjectStruct *lobj = NULL;
689 int i, count = ArgusParser->ArgusWfileList->count;
690
691 if ((lobj = ArgusParser->ArgusWfileList->start) != NULL) {
692 for (i = 0; i < count; i++) {
693 if ((wfile = (struct ArgusWfileStruct *) lobj) != NULL) {
694 if (wfile->fd != NULL) {
695 #ifdef ARGUSDEBUG
696 ArgusDebug (2, "RaParseComplete: closing %s\n", wfile->filename);
697 #endif
698 fflush (wfile->fd);
699 fclose (wfile->fd);
700 wfile->fd = NULL;
701 }
702 }
703 lobj = lobj->nxt;
704 }
705 }
706 }
707 exit(0);
708 break;
709 }
710 }
711 }
712 }
713
714 ArgusParser->eNflag = nflag;
715
716 #ifdef ARGUSDEBUG
717 ArgusDebug (6, "RaParseComplete(%d) done", sig);
718 #endif
719 }
720
721 void
usage()722 usage ()
723 {
724 extern char version[];
725
726 fprintf (stdout, "Rapath Version %s\n", version);
727 fprintf (stdout, "usage: %s \n", ArgusParser->ArgusProgramName);
728 fprintf (stdout, "usage: %s [-f ralabel.conf] [ra-options] [- filter-expression]\n\n", ArgusParser->ArgusProgramName);
729
730
731 fprintf (stdout, "options: -f <racluster.conf> read label rules from <ralabel.conf>.\n");
732 fprintf (stdout, " -A print path graph\n");
733 #ifdef ARGUSDEBUG
734 fprintf (stdout, " -D <level> specify debug level\n");
735 #endif
736 fprintf (stdout, " -q quiet mode. Supress printing records.\n");
737 fprintf (stdout, " -m flow key fields modify the flow model for path data.\n");
738 fprintf (stdout, " -M <option> specify a Mode of operation.\n");
739 fprintf (stdout, " Available modes: \n");
740 fprintf (stdout, " as print path with AS information\n");
741 fprintf (stdout, " addr print path as list of addresses\n");
742 fprintf (stdout, " node print path as list of nodes\n");
743 fprintf (stdout, " dist print path with hop counts\n");
744 fprintf (stdout, " tree print path tree\n");
745
746 fflush (stdout);
747
748 exit(1);
749 }
750
751 void RaProcessThisRecord (struct ArgusParserStruct *, struct ArgusRecordStruct *);
752 void RaPrintArgusPath (struct ArgusRecordStruct *);
753
754 void
RaProcessRecord(struct ArgusParserStruct * parser,struct ArgusRecordStruct * ns)755 RaProcessRecord (struct ArgusParserStruct *parser, struct ArgusRecordStruct *ns)
756 {
757 struct ArgusFlow *flow = (struct ArgusFlow *) ns->dsrs[ARGUS_FLOW_INDEX];
758 struct ArgusIcmpStruct *icmp = NULL;
759
760 switch (ns->hdr.type & 0xF0) {
761 case ARGUS_MAR:
762 case ARGUS_EVENT: {
763 break;
764 }
765
766 case ARGUS_NETFLOW:
767 case ARGUS_FAR: {
768 if (flow != NULL) {
769 switch (flow->hdr.subtype & 0x3F) {
770 case ARGUS_FLOW_LAYER_3_MATRIX:
771 case ARGUS_FLOW_CLASSIC5TUPLE: {
772 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
773 case ARGUS_TYPE_IPV4: {
774 if (flow->ip_flow.ip_src > flow->ip_flow.ip_dst) {
775 }
776 break;
777 }
778
779 case ARGUS_TYPE_IPV6: {
780 int i;
781 for (i = 0; i < 4; i++) {
782 if (flow->ipv6_flow.ip_src[i] < flow->ipv6_flow.ip_dst[i])
783 break;
784
785 if (flow->ipv6_flow.ip_src[i] > flow->ipv6_flow.ip_dst[i]) {
786 break;
787 }
788 }
789 break;
790 }
791 }
792 break;
793 }
794 default:
795 return;
796 break;
797 }
798
799 if ((icmp = (struct ArgusIcmpStruct *) ns->dsrs[ARGUS_ICMP_INDEX]) != NULL) {
800 if ((icmp->hdr.argus_dsrvl8.qual & ARGUS_ICMPUNREACH_MAPPED) ||
801 (icmp->hdr.argus_dsrvl8.qual & ARGUS_ICMPTIMXCED_MAPPED)) {
802
803 unsigned int srchost, dsthost, intnode;
804
805 srchost = flow->ip_flow.ip_src;
806 dsthost = flow->ip_flow.ip_dst;
807
808 intnode = icmp->osrcaddr;
809
810 if ((intnode == srchost) || (intnode == dsthost))
811 return;
812 }
813
814 switch (flow->ip_flow.ip_p) {
815 case IPPROTO_UDP:
816 case IPPROTO_TCP:
817 break;
818
819 case IPPROTO_ICMP:
820 break;
821
822 default:
823 break;
824 }
825
826 RaProcessThisRecord (parser, ns);
827 }
828 }
829 break;
830 }
831 }
832 }
833
834
835 void RaUpdateArgusStorePath(struct ArgusRecord *, struct ArgusRecordStruct *);
836 struct ArgusRecordStruct *RaProcessAggregation(struct ArgusParserStruct *, struct ArgusAggregatorStruct *, struct ArgusRecordStruct *);
837
838 struct ArgusRecordStruct *
RaProcessAggregation(struct ArgusParserStruct * parser,struct ArgusAggregatorStruct * agg,struct ArgusRecordStruct * ns)839 RaProcessAggregation(struct ArgusParserStruct *parser, struct ArgusAggregatorStruct *agg, struct ArgusRecordStruct *ns)
840 {
841 struct ArgusHashStruct *hstruct = NULL;
842 struct ArgusRecordStruct *retn = NULL;
843
844 if ((agg->rap = RaFlowModelOverRides(agg, ns)) == NULL)
845 agg->rap = agg->drap;
846
847 ArgusGenerateNewFlow(agg, ns);
848
849 if ((hstruct = ArgusGenerateHashStruct(agg, ns, (struct ArgusFlow *)&agg->fstruct)) == NULL)
850 ArgusLog (LOG_ERR, "RaProcessThisRecord: ArgusGenerateHashStruct error %s", strerror(errno));
851
852 if ((retn = ArgusFindRecord(agg->htable, hstruct)) != NULL) {
853 if (parser->Aflag) {
854 if ((retn->status & RA_SVCTEST) != (ns->status & RA_SVCTEST)) {
855 RaSendArgusRecord(retn);
856 ArgusZeroRecord(retn);
857 retn->status &= ~(RA_SVCTEST);
858 retn->status |= (ns->status & RA_SVCTEST);
859 }
860 }
861 ArgusMergeRecords (agg, retn, ns);
862
863 } else {
864 if (!parser->RaMonMode) {
865 struct ArgusFlow *flow = (struct ArgusFlow *) ns->dsrs[ARGUS_FLOW_INDEX];
866 int tryreverse = 1;
867
868 if (flow != NULL) {
869 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
870 case ARGUS_TYPE_IPV4: {
871 switch (flow->ip_flow.ip_p) {
872 case IPPROTO_ESP:
873 tryreverse = 0;
874 break;
875 }
876 }
877 }
878 }
879
880 if (tryreverse) {
881 if ((hstruct = ArgusGenerateReverseHashStruct(agg, ns, (struct ArgusFlow *)&agg->fstruct)) == NULL)
882 ArgusLog (LOG_ERR, "RaProcessThisRecord: ArgusGenerateHashStruct error %s", strerror(errno));
883
884 if ((retn = ArgusFindRecord(agg->htable, hstruct)) == NULL) {
885 if ((hstruct = ArgusGenerateHashStruct(agg, ns, (struct ArgusFlow *)&agg->fstruct)) == NULL)
886 ArgusLog (LOG_ERR, "RaProcessThisRecord: ArgusGenerateHashStruct error %s", strerror(errno));
887
888 } else {
889 ArgusReverseRecord (ns);
890 }
891 }
892 }
893
894 if (retn != NULL) {
895 if (parser->Aflag) {
896 if ((retn->status & RA_SVCTEST) != (ns->status & RA_SVCTEST)) {
897 RaSendArgusRecord(retn);
898 ArgusZeroRecord(retn);
899 }
900 retn->status &= ~(RA_SVCTEST);
901 retn->status |= (ns->status & RA_SVCTEST);
902 } else
903 ArgusMergeRecords (agg, retn, ns);
904
905 } else {
906 retn = ArgusCopyRecordStruct(ns);
907 ArgusAddHashEntry (agg->htable, retn, hstruct);
908 ArgusAddToQueue (agg->queue, &retn->qhdr, ARGUS_NOLOCK);
909 }
910 }
911
912 return retn;
913 }
914
915 void
RaProcessThisRecord(struct ArgusParserStruct * parser,struct ArgusRecordStruct * ns)916 RaProcessThisRecord (struct ArgusParserStruct *parser, struct ArgusRecordStruct *ns)
917 {
918 struct ArgusAggregatorStruct *agg = parser->ArgusAggregator;
919 struct ArgusRecordStruct *tns, *cns;
920 int retn = 0;
921
922 struct nff_insn *fcode = agg->filter.bf_insns;
923
924 if ((retn = ArgusFilterRecord (fcode, ns)) != 0) {
925 if ((cns = ArgusCopyRecordStruct(ns)) == NULL)
926 ArgusLog (LOG_ERR, "RaProcessThisRecord: ArgusCopyRecordStruct error %s", strerror(errno));
927
928 ArgusLabelRecord(parser, cns);
929
930 if ((tns = RaProcessAggregation(parser, agg, cns)) != NULL) {
931 if (tns->agg == NULL)
932 if ((tns->agg = ArgusCopyAggregator(ArgusFlowAggregator)) == NULL)
933 ArgusLog (LOG_ERR, "RaProcessThisRecod: ArgusCopyAggregator error");
934
935 if (tns != NULL)
936 RaProcessAggregation(parser, tns->agg, cns);
937 }
938
939 ArgusDeleteRecordStruct(parser, cns);
940 }
941 }
942
943
944 int
RaSendArgusRecord(struct ArgusRecordStruct * argus)945 RaSendArgusRecord(struct ArgusRecordStruct *argus)
946 {
947 struct ArgusRecord *argusrec = NULL;
948 char buf[0x10000], argusbuf[0x10000];
949 int retn = 1;
950
951 if (argus->status & ARGUS_RECORD_WRITTEN)
952 return (retn);
953
954 if (ArgusParser->RaAgMode)
955 argus->dsrs[ARGUS_AGR_INDEX] = NULL;
956
957 if ((argusrec = ArgusGenerateRecord (argus, 0L, argusbuf)) != NULL) {
958 #ifdef _LITTLE_ENDIAN
959 ArgusHtoN(argusrec);
960 #endif
961 if (ArgusParser->ArgusWfileList != NULL) {
962 struct ArgusWfileStruct *wfile = NULL;
963 struct ArgusListObjectStruct *lobj = NULL;
964 int i, count = ArgusParser->ArgusWfileList->count;
965
966 if ((lobj = ArgusParser->ArgusWfileList->start) != NULL) {
967 for (i = 0; i < count; i++) {
968 if ((wfile = (struct ArgusWfileStruct *) lobj) != NULL) {
969 int pass = 1;
970 if (wfile->filterstr) {
971 struct nff_insn *wfcode = wfile->filter.bf_insns;
972 pass = ArgusFilterRecord (wfcode, argus);
973 }
974
975 if (pass != 0) {
976 if ((ArgusParser->exceptfile == NULL) || strcmp(wfile->filename, ArgusParser->exceptfile)) {
977 ArgusWriteNewLogfile (ArgusParser, argus->input, wfile, argusrec);
978 }
979 }
980 }
981 lobj = lobj->nxt;
982 }
983 }
984
985 } else {
986 if (!ArgusParser->qflag) {
987 if (ArgusParser->Lflag) {
988 if (ArgusParser->RaLabel == NULL)
989 ArgusParser->RaLabel = ArgusGenerateLabel(ArgusParser, argus);
990
991 if (!(ArgusParser->RaLabelCounter++ % ArgusParser->Lflag)) {
992 if (ArgusParser->Aflag && (!(RaPrintAddr)))
993 printf (" Node %s\n", ArgusParser->RaLabel);
994 else
995 printf ("%s\n", ArgusParser->RaLabel);
996 }
997
998 if (ArgusParser->Lflag < 0)
999 ArgusParser->Lflag = 0;
1000 }
1001
1002 *(int *)&buf = 0;
1003 ArgusPrintRecord(ArgusParser, buf, argus, MAXSTRLEN);
1004
1005 if (ArgusParser->Aflag && (!(RaPrintAddr))) {
1006 int ret = fprintf (stdout, " %c %s\n", argus->autoid, buf);
1007 if (ret < 0)
1008 RaParseComplete(SIGQUIT);
1009 } else
1010 if (fprintf (stdout, "%s\n", buf) < 0)
1011 RaParseComplete(SIGQUIT);
1012 fflush(stdout);
1013 }
1014 }
1015 }
1016
1017 argus->status |= ARGUS_RECORD_WRITTEN;
1018 return (retn);
1019 }
1020
ArgusWindowClose(void)1021 void ArgusWindowClose(void) { }
1022