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 * rarpwatch.c - IPv4 and IPv6 arpwatch, driven by argus flow data.
24 *
25 * written by Carter Bullard
26 * QoSient, LLC
27 *
28 */
29
30 /*
31 * $Id: //depot/argus/clients/examples/rarpwatch/rarpwatch.c#11 $
32 * $DateTime: 2016/06/01 15:17:28 $
33 * $Change: 3148 $
34 */
35
36 #ifdef HAVE_CONFIG_H
37 #include "argus_config.h"
38 #endif
39
40 #if defined(CYGWIN)
41 #define USE_IPV6
42 #endif
43
44 #include <unistd.h>
45 #include <stdlib.h>
46 #include <signal.h>
47 #include <ctype.h>
48
49 #include <argus_compat.h>
50
51 #include <rabins.h>
52 #include <argus_util.h>
53 #include <argus_client.h>
54 #include <argus_main.h>
55 #include <argus_sort.h>
56
57 #include <argus_filter.h>
58 #include <argus_cluster.h>
59 #include <netinet/ip_icmp.h>
60
61
62 void
ArgusClientInit(struct ArgusParserStruct * parser)63 ArgusClientInit (struct ArgusParserStruct *parser)
64 {
65 struct ArgusModeStruct *mode = NULL;
66 int correct = 1;
67 parser->RaWriteOut = 0;
68
69 if (!(parser->RaInitialized)) {
70 (void) signal (SIGHUP, (void (*)(int)) RaParseComplete);
71 (void) signal (SIGTERM, (void (*)(int)) RaParseComplete);
72 (void) signal (SIGQUIT, (void (*)(int)) RaParseComplete);
73 (void) signal (SIGINT, (void (*)(int)) RaParseComplete);
74
75 if ((mode = parser->ArgusModeList) != NULL) {
76 while (mode) {
77 if (!(strncasecmp (mode->mode, "correct", 7)))
78 correct = 1;
79 if (!(strncasecmp (mode->mode, "nocorrect", 9)))
80 correct = 0;
81 if (!(strncasecmp (mode->mode, "rmon", 4)))
82 parser->RaMonMode++;
83 if (!(strncasecmp (mode->mode, "norep", 5)))
84 parser->RaAgMode++;
85 if (!(strncasecmp (mode->mode, "ind", 3)))
86 ArgusProcessFileIndependantly = 1;
87 if (!(strncasecmp (mode->mode, "replace", 7))) {
88 ArgusProcessFileIndependantly = 1;
89 parser->ArgusReplaceMode++;
90 if ((parser->ArgusWfileList != NULL) && (!(ArgusListEmpty(parser->ArgusWfileList)))) {
91 ArgusLog (LOG_ERR, "replace mode and -w option are incompatible\n");
92 }
93 }
94 mode = mode->nxt;
95 }
96 }
97
98 if ((parser->ArgusMaskList) == NULL)
99 parser->ArgusReverse = 1;
100 else
101 parser->ArgusReverse = 0;
102
103 if (parser->ArgusFlowModelFile) {
104 if ((parser->ArgusAggregator = ArgusParseAggregator(parser, parser->ArgusFlowModelFile, NULL)) == NULL)
105 ArgusLog (LOG_ERR, "ArgusClientInit: ArgusParseAggregator error");
106
107 } else
108 if ((parser->ArgusAggregator = ArgusNewAggregator(parser, NULL, ARGUS_RECORD_AGGREGATOR)) == NULL)
109 ArgusLog (LOG_ERR, "ArgusClientInit: ArgusNewAggregator error");
110
111 if (correct == 0) {
112 if (parser->ArgusAggregator->correct != NULL)
113 free(parser->ArgusAggregator->correct);
114 parser->ArgusAggregator->correct = NULL;
115 } else {
116 if (parser->ArgusAggregator->correct != NULL)
117 free(parser->ArgusAggregator->correct);
118 parser->ArgusAggregator->correct = strdup("yes");
119 }
120
121 if (parser->Hstr)
122 if (!(ArgusHistoMetricParse (parser, parser->ArgusAggregator)))
123 usage ();
124
125 if (parser->vflag)
126 ArgusReverseSortDir++;
127
128 if ((parser->ArgusWfileList != NULL) && (!(ArgusListEmpty(parser->ArgusWfileList))))
129 parser->nflag = 2;
130
131 parser->RaInitialized++;
132 parser->RaParseCompleting = 0;
133 parser->ArgusLastRecordTime = 0;
134 parser->RaSortedInput = 1;
135 }
136 }
137
138 void
RaArgusInputComplete(struct ArgusInput * input)139 RaArgusInputComplete (struct ArgusInput *input)
140 {
141 if (ArgusProcessFileIndependantly) {
142 ArgusParser->ArgusCurrentInput = input;
143 RaParseComplete (0);
144
145 ArgusParser->RaInitialized = 0;
146 ArgusParser->ArgusCurrentInput = NULL;
147 ArgusClientInit(ArgusParser);
148 }
149
150 #ifdef ARGUSDEBUG
151 ArgusDebug (7, "RaArgusInputComplete(0x%x) done", input);
152 #endif
153 }
154
155 void
RaParseComplete(int sig)156 RaParseComplete (int sig)
157 {
158 struct ArgusModeStruct *mode = NULL;
159 int i = 0, x = 0, nflag = ArgusParser->eNflag;
160 struct ArgusInput *file = ArgusParser->ArgusCurrentInput;
161 char buf[MAXSTRLEN];
162 int label;
163
164 if (sig >= 0) {
165 if (!(ArgusParser->RaParseCompleting++)) {
166 struct ArgusAggregatorStruct *agg = ArgusParser->ArgusAggregator;
167
168 ArgusParser->RaParseCompleting += sig;
169
170 if (ArgusParser->ArgusReplaceMode && file) {
171
172 if (!(ArgusParser->ArgusRandomSeed))
173 srandom(ArgusParser->ArgusRandomSeed);
174
175 srandom (ArgusParser->ArgusRealTime.tv_usec);
176 label = random() % 100000;
177
178 bzero(buf, sizeof(buf));
179 snprintf (buf, MAXSTRLEN, "%s.tmp%d", file->filename, label);
180
181 setArgusWfile(ArgusParser, buf, NULL);
182 }
183
184 while (agg != NULL) {
185 if (agg->queue->count) {
186 struct ArgusRecordStruct *argus;
187
188 if (!(ArgusSorter))
189 if ((ArgusSorter = ArgusNewSorter(ArgusParser)) == NULL)
190 ArgusLog (LOG_ERR, "RaParseComplete: ArgusNewSorter error %s", strerror(errno));
191
192 if ((mode = ArgusParser->ArgusMaskList) != NULL) {
193 while (mode) {
194 for (x = 0; x < MAX_SORT_ALG_TYPES; x++) {
195 if (!strncmp (ArgusSortKeyWords[x], mode->mode, strlen(ArgusSortKeyWords[x]))) {
196 ArgusSorter->ArgusSortAlgorithms[i++] = ArgusSortAlgorithmTable[x];
197 break;
198 }
199 }
200
201 mode = mode->nxt;
202 }
203 }
204
205 ArgusSortQueue (ArgusSorter, agg->queue);
206
207 argus = ArgusCopyRecordStruct((struct ArgusRecordStruct *) agg->queue->array[0]);
208
209 if (nflag == 0)
210 ArgusParser->eNflag = agg->queue->count;
211 else
212 ArgusParser->eNflag = nflag > agg->queue->count ? agg->queue->count : nflag;
213
214 for (i = 1; i < ArgusParser->eNflag; i++)
215 ArgusMergeRecords (agg, argus, (struct ArgusRecordStruct *)agg->queue->array[i]);
216
217 ArgusParser->ns = argus;
218
219 for (i = 0; i < ArgusParser->eNflag; i++) {
220 RaSendArgusRecord ((struct ArgusRecordStruct *) agg->queue->array[i]);
221 ArgusDeleteRecordStruct(ArgusParser, (struct ArgusRecordStruct *) agg->queue->array[i]);
222 }
223
224 ArgusDeleteRecordStruct(ArgusParser, ArgusParser->ns);
225 }
226
227 agg = agg->nxt;
228 }
229
230 if (ArgusParser->ArgusAggregator != NULL)
231 ArgusDeleteAggregator(ArgusParser, ArgusParser->ArgusAggregator);
232
233 if (ArgusParser->ArgusReplaceMode && file) {
234 if (ArgusParser->ArgusWfileList != NULL) {
235 struct ArgusWfileStruct *wfile = NULL;
236
237 if ((wfile = (void *)ArgusParser->ArgusWfileList->start) != NULL) {
238 fflush (wfile->fd);
239 rename (wfile->filename, file->filename);
240 fclose (wfile->fd);
241 wfile->fd = NULL;
242 }
243
244 ArgusDeleteList(ArgusParser->ArgusWfileList, ARGUS_WFILE_LIST);
245 ArgusParser->ArgusWfileList = NULL;
246
247 if (ArgusParser->Vflag)
248 ArgusLog(LOG_INFO, "file %s aggregated", file->filename);
249 }
250 }
251
252 #ifdef ARGUSDEBUG
253 ArgusDebug (2, "RaParseComplete(caught signal %d)\n", sig);
254 #endif
255 switch (sig) {
256 case SIGHUP:
257 case SIGINT:
258 case SIGTERM:
259 case SIGQUIT: {
260 struct ArgusWfileStruct *wfile = NULL;
261
262 ArgusShutDown(sig);
263
264 if (ArgusParser->ArgusWfileList != NULL) {
265 struct ArgusListObjectStruct *lobj = NULL;
266 int i, count = ArgusParser->ArgusWfileList->count;
267
268 if ((lobj = ArgusParser->ArgusWfileList->start) != NULL) {
269 for (i = 0; i < count; i++) {
270 if ((wfile = (struct ArgusWfileStruct *) lobj) != NULL) {
271 if (wfile->fd != NULL) {
272 #ifdef ARGUSDEBUG
273 ArgusDebug (2, "RaParseComplete: closing %s\n", wfile->filename);
274 #endif
275 fflush (wfile->fd);
276 fclose (wfile->fd);
277 wfile->fd = NULL;
278 }
279 }
280 lobj = lobj->nxt;
281 }
282 }
283 }
284 exit(0);
285 break;
286 }
287 }
288 }
289 }
290
291 ArgusParser->eNflag = nflag;
292
293 #ifdef ARGUSDEBUG
294 ArgusDebug (6, "RaParseComplete(%d) done", sig);
295 #endif
296 }
297
298
299 void
ArgusClientTimeout()300 ArgusClientTimeout ()
301 {
302 struct ArgusAggregatorStruct *agg = ArgusParser->ArgusAggregator;
303
304 while (agg) {
305 int i, count;
306
307 if (agg->statusint > 0) {
308 if ((count = agg->queue->count) > 0) {
309 for (i = 0; i < count; i++) {
310 struct ArgusRecordStruct *ns = (void *) ArgusPopQueue(agg->queue, ARGUS_LOCK);
311 double nsst = ArgusFetchStartTime(ns);
312 double nslt = ArgusFetchLastTime(ns);
313 double glt = (double)(ArgusParser->ArgusGlobalTime.tv_sec * 1.0) + (double)(ArgusParser->ArgusGlobalTime.tv_usec/1000000.0);
314
315 if (agg->statusint && ((glt - nsst) >= agg->statusint)) {
316 RaSendArgusRecord(ns);
317
318 } else {
319 if (agg->idleint && ((glt - nslt) >= agg->idleint)) {
320 ArgusRemoveHashEntry(&ns->htblhdr);
321 RaSendArgusRecord(ns);
322 ArgusDeleteRecordStruct (ArgusParser, ns);
323 ns = NULL;
324 }
325 }
326
327 if (ns != NULL)
328 ArgusAddToQueue(agg->queue, &ns->qhdr, ARGUS_LOCK);
329 }
330 }
331 } else {
332 if (agg->idleint) {
333 int done = 0;
334 while ((!done) && (agg->queue->count > 0)) {
335 struct ArgusRecordStruct *ns = (void *) agg->queue->start;
336 double nslt = ArgusFetchLastTime(ns);
337 double glt = (double)(ArgusParser->ArgusGlobalTime.tv_sec * 1.0) + (double)(ArgusParser->ArgusGlobalTime.tv_usec/1000000.0);
338
339 if ((glt - nslt) >= agg->idleint) {
340 ArgusRemoveHashEntry(&ns->htblhdr);
341 RaSendArgusRecord(ns);
342 ArgusDeleteRecordStruct (ArgusParser, ns);
343 } else
344 done = 1;
345 }
346 }
347 }
348
349 agg = agg->nxt;
350 }
351
352 #ifdef ARGUSDEBUG
353 ArgusDebug (6, "ArgusClientTimeout()\n");
354 #endif
355 }
356
357 void
parse_arg(int argc,char ** argv)358 parse_arg (int argc, char**argv)
359 {}
360
361 void
usage()362 usage ()
363 {
364 extern char version[];
365
366 fprintf (stdout, "Rarpwatch Version %s\n", version);
367 fprintf (stdout, "usage: %s [-f rarpwatch.conf]\n", ArgusParser->ArgusProgramName);
368 fprintf (stdout, "usage: %s [-f rarpwatch.conf] [ra-options] [- filter-expression]\n\n", ArgusParser->ArgusProgramName);
369 fprintf (stdout, "options: -f <rarpwatch.conf> read aggregation rules from <rarpwatch.conf>.\n");
370 fprintf (stdout, " -m flow key fields specify fields to be used as flow keys.\n");
371 fprintf (stdout, " -M modes modify mode of operation.\n");
372 fprintf (stdout, " Available modes: \n");
373 fprintf (stdout, " correct turn on direction correction (default)\n");
374 fprintf (stdout, " nocorrect turn off direction correction\n");
375 fprintf (stdout, " ind aggregate multiple files independently\n");
376 fprintf (stdout, " norep do not report aggregation statistics\n");
377 fprintf (stdout, " rmon convert bi-directional data into rmon in/out data\n");
378 fprintf (stdout, " replace replace input files with aggregation output\n");
379 fprintf (stdout, " -V verbose mode.\n");
380 fflush (stdout);
381
382 exit(1);
383 }
384
385
386 void RaProcessThisRecord (struct ArgusParserStruct *, struct ArgusRecordStruct *);
387 int RaValidateArpFlowRecord (struct ArgusParserStruct *, struct ArgusRecordStruct *);
388
389
390 int
RaValidateArpFlowRecord(struct ArgusParserStruct * parser,struct ArgusRecordStruct * ns)391 RaValidateArpFlowRecord (struct ArgusParserStruct *parser, struct ArgusRecordStruct *ns)
392 {
393 int retn = 1;
394
395 // check various conditions that arpwatch would normally generate syslog messages for.
396 // if generate syslog, then return 0, if not then return 1.
397
398 return retn;
399 }
400
401 void
RaProcessRecord(struct ArgusParserStruct * parser,struct ArgusRecordStruct * ns)402 RaProcessRecord (struct ArgusParserStruct *parser, struct ArgusRecordStruct *ns)
403 {
404 {
405 double nowTime = ArgusFetchStartTime(ns);
406 if (parser->ArgusLastRecordTime == 0) {
407 parser->ArgusLastRecordTime = nowTime;
408 } else {
409 if (parser->ArgusLastRecordTime > nowTime)
410 parser->RaSortedInput = 0;
411 parser->ArgusLastRecordTime = nowTime;
412 }
413 }
414
415 ArgusClientTimeout();
416
417 switch (ns->hdr.type & 0xF0) {
418 case ARGUS_MAR:
419 case ARGUS_EVENT:
420 case ARGUS_NETFLOW:
421 break;
422
423 case ARGUS_FAR: {
424 struct ArgusFlow *flow = (struct ArgusFlow *) ns->dsrs[ARGUS_FLOW_INDEX];
425
426 if (flow != NULL) {
427 switch(flow->hdr.subtype & 0x3F) {
428 case ARGUS_FLOW_LAYER_3_MATRIX:
429 case ARGUS_FLOW_CLASSIC5TUPLE: {
430 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
431 case ARGUS_FLOW_ARP: {
432 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
433 case ARGUS_TYPE_ARP:
434 case ARGUS_TYPE_RARP: {
435 ArgusProcessServiceAvailability(parser, ns);
436 if (ns->status & RA_SVCPASSED) {
437 #ifdef ARGUSDEBUG
438 ArgusDebug (3, "RaProcessRecord (%p, %p) service test failed", parser, ns);
439 #endif
440 RaProcessThisRecord(parser, ns);
441 }
442 break;
443 }
444 }
445 break;
446 }
447 }
448 break;
449 }
450
451 case ARGUS_FLOW_ARP: {
452 if (RaValidateArpFlowRecord(parser, ns)) {
453 ArgusProcessServiceAvailability(parser, ns);
454
455 if (ns->status & RA_SVCPASSED)
456 RaProcessThisRecord(parser, ns);
457 }
458 break;
459 }
460
461 }
462 }
463 break;
464 }
465 }
466 }
467
468
469 void
RaProcessThisRecord(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus)470 RaProcessThisRecord (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus)
471 {
472
473 struct ArgusAggregatorStruct *agg = parser->ArgusAggregator;
474 struct ArgusHashStruct *hstruct = NULL;
475 int found = 0;
476
477 while (agg && !found) {
478 int retn = 0, fretn = -1, lretn = -1;
479 if (agg->filterstr) {
480 struct nff_insn *fcode = agg->filter.bf_insns;
481 fretn = ArgusFilterRecord (fcode, argus);
482 }
483
484 if (agg->grepstr) {
485 struct ArgusLabelStruct *label;
486 if (((label = (void *)argus->dsrs[ARGUS_LABEL_INDEX]) != NULL)) {
487 if (regexec(&agg->lpreg, label->l_un.label, 0, NULL, 0))
488 lretn = 0;
489 else
490 lretn = 1;
491 } else
492 lretn = 0;
493 }
494
495 retn = (lretn < 0) ? ((fretn < 0) ? 1 : fretn) : ((fretn < 0) ? lretn : (lretn && fretn));
496
497 if (retn != 0) {
498 struct ArgusRecordStruct *tns, *ns = ArgusCopyRecordStruct(argus);
499
500 if ((agg->rap = RaFlowModelOverRides(agg, ns)) == NULL)
501 agg->rap = agg->drap;
502
503 ArgusGenerateNewFlow(agg, ns);
504
505 if ((hstruct = ArgusGenerateHashStruct(agg, ns, (struct ArgusFlow *)&agg->fstruct)) == NULL)
506 ArgusLog (LOG_ERR, "RaProcessThisRecord: ArgusGenerateHashStruct error %s", strerror(errno));
507
508 if ((tns = ArgusFindRecord(agg->htable, hstruct)) == NULL) {
509 struct ArgusFlow *flow = (struct ArgusFlow *) ns->dsrs[ARGUS_FLOW_INDEX];
510 if (!parser->RaMonMode && parser->ArgusReverse) {
511 int tryreverse = 0;
512
513 if (flow != NULL) {
514 if (agg->correct != NULL)
515 tryreverse = 1;
516
517 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
518 case ARGUS_TYPE_IPV4: {
519 switch (flow->ip_flow.ip_p) {
520 case IPPROTO_ESP:
521 tryreverse = 0;
522 break;
523 }
524 break;
525 }
526 case ARGUS_TYPE_IPV6: {
527 switch (flow->ipv6_flow.ip_p) {
528 case IPPROTO_ESP:
529 tryreverse = 0;
530 break;
531 }
532 break;
533 }
534 }
535 } else
536 tryreverse = 0;
537
538 if (tryreverse) {
539 if ((hstruct = ArgusGenerateReverseHashStruct(agg, ns, (struct ArgusFlow *)&agg->fstruct)) == NULL)
540 ArgusLog (LOG_ERR, "RaProcessThisRecord: ArgusGenerateHashStruct error %s", strerror(errno));
541
542 if ((tns = ArgusFindRecord(agg->htable, hstruct)) == NULL) {
543 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
544 case ARGUS_TYPE_IPV4: {
545 switch (flow->ip_flow.ip_p) {
546 case IPPROTO_ICMP: {
547 struct ArgusICMPFlow *icmpFlow = &flow->flow_un.icmp;
548
549 if (ICMP_INFOTYPE(icmpFlow->type)) {
550 switch (icmpFlow->type) {
551 case ICMP_ECHO:
552 case ICMP_ECHOREPLY:
553 icmpFlow->type = (icmpFlow->type == ICMP_ECHO) ? ICMP_ECHOREPLY : ICMP_ECHO;
554 if ((hstruct = ArgusGenerateReverseHashStruct(agg, ns, (struct ArgusFlow *)&agg->fstruct)) != NULL)
555 tns = ArgusFindRecord(agg->htable, hstruct);
556 icmpFlow->type = (icmpFlow->type == ICMP_ECHO) ? ICMP_ECHOREPLY : ICMP_ECHO;
557 if (tns)
558 ArgusReverseRecord (ns);
559 break;
560
561 case ICMP_ROUTERADVERT:
562 case ICMP_ROUTERSOLICIT:
563 icmpFlow->type = (icmpFlow->type == ICMP_ROUTERADVERT) ? ICMP_ROUTERSOLICIT : ICMP_ROUTERADVERT;
564 if ((hstruct = ArgusGenerateReverseHashStruct(agg, ns, (struct ArgusFlow *)&agg->fstruct)) != NULL)
565 tns = ArgusFindRecord(agg->htable, hstruct);
566 icmpFlow->type = (icmpFlow->type == ICMP_ROUTERADVERT) ? ICMP_ROUTERSOLICIT : ICMP_ROUTERADVERT;
567 if (tns)
568 ArgusReverseRecord (ns);
569 break;
570
571 case ICMP_TSTAMP:
572 case ICMP_TSTAMPREPLY:
573 icmpFlow->type = (icmpFlow->type == ICMP_TSTAMP) ? ICMP_TSTAMPREPLY : ICMP_TSTAMP;
574 if ((hstruct = ArgusGenerateReverseHashStruct(agg, ns, (struct ArgusFlow *)&agg->fstruct)) != NULL)
575 tns = ArgusFindRecord(agg->htable, hstruct);
576 icmpFlow->type = (icmpFlow->type == ICMP_TSTAMP) ? ICMP_TSTAMPREPLY : ICMP_TSTAMP;
577 if (tns)
578 ArgusReverseRecord (ns);
579 break;
580
581 case ICMP_IREQ:
582 case ICMP_IREQREPLY:
583 icmpFlow->type = (icmpFlow->type == ICMP_IREQ) ? ICMP_IREQREPLY : ICMP_IREQ;
584 if ((hstruct = ArgusGenerateReverseHashStruct(agg, ns, (struct ArgusFlow *)&agg->fstruct)) != NULL)
585 tns = ArgusFindRecord(agg->htable, hstruct);
586 icmpFlow->type = (icmpFlow->type == ICMP_IREQ) ? ICMP_IREQREPLY : ICMP_IREQ;
587 if (tns)
588 ArgusReverseRecord (ns);
589 break;
590
591 case ICMP_MASKREQ:
592 case ICMP_MASKREPLY:
593 icmpFlow->type = (icmpFlow->type == ICMP_MASKREQ) ? ICMP_MASKREPLY : ICMP_MASKREQ;
594 if ((hstruct = ArgusGenerateReverseHashStruct(agg, ns, (struct ArgusFlow *)&agg->fstruct)) != NULL)
595 tns = ArgusFindRecord(agg->htable, hstruct);
596 icmpFlow->type = (icmpFlow->type == ICMP_MASKREQ) ? ICMP_MASKREPLY : ICMP_MASKREQ;
597 if (tns)
598 ArgusReverseRecord (ns);
599 break;
600 }
601 }
602 break;
603 }
604 }
605 }
606 }
607 if ((hstruct = ArgusGenerateHashStruct(agg, ns, (struct ArgusFlow *)&agg->fstruct)) == NULL)
608 ArgusLog (LOG_ERR, "RaProcessThisRecord: ArgusGenerateHashStruct error %s", strerror(errno));
609
610 } else {
611 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
612 case ARGUS_TYPE_IPV4: {
613 switch (flow->ip_flow.ip_p) {
614 case IPPROTO_TCP: {
615 struct ArgusTCPObject *tcp = (struct ArgusTCPObject *)ns->dsrs[ARGUS_NETWORK_INDEX];
616 if (tcp != NULL) {
617 struct ArgusTCPObject *ttcp = (struct ArgusTCPObject *)tns->dsrs[ARGUS_NETWORK_INDEX];
618 if (ttcp != NULL) {
619 if ((tcp->status & ARGUS_SAW_SYN) && !(ttcp->status & ARGUS_SAW_SYN)) {
620 ArgusReverseRecord (tns);
621 } else
622 ArgusReverseRecord (ns);
623 } else
624 ArgusReverseRecord (ns);
625 } else
626 ArgusReverseRecord (ns);
627 break;
628 }
629
630 default:
631 ArgusReverseRecord (ns);
632 break;
633 }
634 }
635 break;
636
637 case ARGUS_TYPE_IPV6: {
638 switch (flow->ipv6_flow.ip_p) {
639 case IPPROTO_TCP: {
640 struct ArgusTCPObject *tcp = (struct ArgusTCPObject *)ns->dsrs[ARGUS_NETWORK_INDEX];
641 if (tcp != NULL) {
642 struct ArgusTCPObject *ttcp = (struct ArgusTCPObject *)tns->dsrs[ARGUS_NETWORK_INDEX];
643 if (ttcp != NULL) {
644 if ((tcp->status & ARGUS_SAW_SYN) && !(ttcp->status & ARGUS_SAW_SYN)) {
645 ArgusReverseRecord (tns);
646 } else
647 ArgusReverseRecord (ns);
648 } else
649 ArgusReverseRecord (ns);
650 } else
651 ArgusReverseRecord (ns);
652 break;
653 }
654
655 default:
656 ArgusReverseRecord (ns);
657 break;
658 }
659 }
660 break;
661
662 default:
663 ArgusReverseRecord (ns);
664 }
665 }
666 }
667 }
668 }
669
670 if (tns != NULL) {
671 if (parser->Aflag) {
672 if ((tns->status & RA_SVCTEST) != (ns->status & RA_SVCTEST)) {
673 RaSendArgusRecord(tns);
674 tns->status &= ~(RA_SVCTEST);
675 tns->status |= (ns->status & RA_SVCTEST);
676 }
677 }
678
679 if (tns->status & ARGUS_RECORD_WRITTEN) {
680 ArgusZeroRecord (tns);
681
682 } else {
683 if (agg->statusint || agg->idleint) {
684 double dur, nsst, tnsst, nslt, tnslt;
685
686 nsst = ArgusFetchStartTime(ns);
687 tnsst = ArgusFetchStartTime(tns);
688 nslt = ArgusFetchLastTime(ns);
689 tnslt = ArgusFetchLastTime(tns);
690
691 dur = ((tnslt > nslt) ? tnslt : nslt) - ((nsst < tnsst) ? nsst : tnsst);
692
693 if (agg->statusint && (dur >= agg->statusint)) {
694 RaSendArgusRecord(tns);
695 ArgusZeroRecord(tns);
696 } else {
697 dur = ((nslt < tnsst) ? (tnsst - nslt) : ((tnslt < nsst) ? (nsst - tnslt) : 0.0));
698 if (agg->idleint && (dur >= agg->idleint)) {
699 RaSendArgusRecord(tns);
700 ArgusZeroRecord(tns);
701 }
702 }
703 }
704 }
705
706 ArgusMergeRecords (agg, tns, ns);
707 ArgusRemoveFromQueue (agg->queue, &tns->qhdr, ARGUS_NOLOCK);
708 ArgusAddToQueue (agg->queue, &tns->qhdr, ARGUS_NOLOCK);
709 ArgusDeleteRecordStruct(parser, ns);
710 agg->status |= ARGUS_AGGREGATOR_DIRTY;
711
712 } else {
713 tns = ns;
714 tns->htblhdr = ArgusAddHashEntry (agg->htable, tns, hstruct);
715 ArgusAddToQueue (agg->queue, &tns->qhdr, ARGUS_NOLOCK);
716 agg->status |= ARGUS_AGGREGATOR_DIRTY;
717 }
718
719 if (agg->cont)
720 agg = agg->nxt;
721 else
722 found++;
723
724 } else
725 agg = agg->nxt;
726 }
727 }
728
729
730 int
RaSendArgusRecord(struct ArgusRecordStruct * argus)731 RaSendArgusRecord(struct ArgusRecordStruct *argus)
732 {
733 struct ArgusRecord *argusrec = NULL;
734 char buf[0x10000], argusbuf[0x10000];
735 int retn = 1;
736
737 if (ArgusParser->RaAgMode)
738 argus->dsrs[ARGUS_AGR_INDEX] = NULL;
739
740 if (argus->status & ARGUS_RECORD_WRITTEN)
741 return (retn);
742
743 if ((argusrec = ArgusGenerateRecord (argus, 0L, argusbuf)) != NULL) {
744 #ifdef _LITTLE_ENDIAN
745 ArgusHtoN(argusrec);
746 #endif
747 if (ArgusParser->ArgusWfileList != NULL) {
748 struct ArgusWfileStruct *wfile = NULL;
749 struct ArgusListObjectStruct *lobj = NULL;
750 int i, count = ArgusParser->ArgusWfileList->count;
751
752 if ((lobj = ArgusParser->ArgusWfileList->start) != NULL) {
753 for (i = 0; i < count; i++) {
754 if ((wfile = (struct ArgusWfileStruct *) lobj) != NULL) {
755 int pass = 1;
756 if (wfile->filterstr) {
757 struct nff_insn *wfcode = wfile->filter.bf_insns;
758 pass = ArgusFilterRecord (wfcode, argus);
759 }
760
761 if (pass != 0) {
762 if ((ArgusParser->exceptfile == NULL) || strcmp(wfile->filename, ArgusParser->exceptfile)) {
763 ArgusWriteNewLogfile (ArgusParser, argus->input, wfile, argusrec);
764 }
765 }
766
767 lobj = lobj->nxt;
768 }
769 }
770 }
771
772 } else {
773 if (!ArgusParser->qflag) {
774 if (ArgusParser->Lflag) {
775 if (ArgusParser->RaLabel == NULL)
776 ArgusParser->RaLabel = ArgusGenerateLabel(ArgusParser, argus);
777
778 if (!(ArgusParser->RaLabelCounter++ % ArgusParser->Lflag))
779 printf ("%s\n", ArgusParser->RaLabel);
780
781 if (ArgusParser->Lflag < 0)
782 ArgusParser->Lflag = 0;
783 }
784
785 *(int *)&buf = 0;
786 ArgusPrintRecord(ArgusParser, buf, argus, MAXSTRLEN);
787 if (fprintf (stdout, "%s\n", buf) < 0)
788 RaParseComplete(SIGQUIT);
789 fflush(stdout);
790 }
791 }
792 }
793
794 argus->status |= ARGUS_RECORD_WRITTEN;
795 return (retn);
796 }
797
798 void ArgusWindowClose(void);
799
ArgusWindowClose(void)800 void ArgusWindowClose(void) {
801 #ifdef ARGUSDEBUG
802 ArgusDebug (6, "ArgusWindowClose () returning\n");
803 #endif
804 }
805