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 * argus client library
24 *
25 * written by Carter Bullard
26 * QoSient, LLC
27 *
28 */
29
30 /*
31 * $Id: //depot/argus/clients/common/argus_client.c#341 $
32 * $DateTime: 2016/08/22 00:42:29 $
33 * $Change: 3177 $
34 */
35
36 #ifdef HAVE_CONFIG_H
37 #include "argus_config.h"
38 #endif
39
40 #ifndef ArgusClient
41 #define ArgusClient
42 #endif
43
44 #ifndef ArgusSort
45 #define ArgusSort
46 #endif
47
48 #ifndef ArgusMetric
49 #define ArgusMetric
50 #endif
51
52 #ifndef _REENTRANT
53 #define _REENTRANT
54 #endif
55
56 #include <stdlib.h>
57 #include <syslog.h>
58 #include <errno.h>
59
60 #include <math.h>
61 #include <ctype.h>
62
63 #include <sys/types.h>
64 #include <argus_compat.h>
65
66 #define ARGUS_MAIN
67
68 #include <argus_def.h>
69 #include <argus_out.h>
70 #include <argus_util.h>
71 #include <argus_client.h>
72 #include <argus_sort.h>
73 #include <argus_metric.h>
74 #include <argus_histo.h>
75 #include <argus_label.h>
76
77 #include <rasplit.h>
78
79 #if defined(__OpenBSD__)
80 #include <netinet/in_systm.h>
81 #include <netinet/ip.h>
82 #endif
83
84 #include <netinet/ip_icmp.h>
85 #include <netinet/igmp.h>
86 #include <netinet/tcp.h>
87
88 #include <argus_main.h>
89
90 #define RA_HASHSIZE 256
91
92 #include <rpc/types.h>
93
94 #if defined(HAVE_XDR)
95 #include <rpc/xdr.h>
96 #endif
97
98 #include <sys/socket.h>
99 #include <netinet/in.h>
100 #include <arpa/inet.h>
101
102 #ifndef ETH_ALEN
103 #define ETH_ALEN 6
104 #endif
105
106 #ifndef AF_INET6
107 #define AF_INET6 23
108 #endif
109
110
111 #ifndef ArgusOutputC
112 #define ArgusOutputC
113 #endif
114
115 #include <unistd.h>
116 #include <stdlib.h>
117 #include <stdio.h>
118
119
120 #if defined(ARGUS_THREADS)
121 #include <pthread.h>
122 #endif
123
124 #include <argus_output.h>
125
126 int ArgusConnect(int, const struct sockaddr *, socklen_t, int);
127
128 struct ArgusRecord *ArgusGenerateRecord (struct ArgusRecordStruct *, unsigned char, char *);
129 struct ArgusRecordStruct *ArgusCopyRecordStruct (struct ArgusRecordStruct *);
130 void ArgusDeleteRecordStruct (struct ArgusParserStruct *, struct ArgusRecordStruct *);
131 int ArgusSortSrvSignatures (struct ArgusRecordStruct *, struct ArgusRecordStruct *);
132
133
134 #ifdef ARGUS_SASL
135 #include <argus/saslint.h>
136
137
138 // ArgusReadSaslStreamSocket() - this routine needs to keep reading data from the
139 // socket, decrypt it and then copy it into the
140 // standard ArgusReadBuffer, and then use the standard
141 // processing logic to read records.
142
143
144 int ArgusReadSaslStreamSocket (struct ArgusParserStruct *parser, struct ArgusInput *);
145
146 int
ArgusReadSaslStreamSocket(struct ArgusParserStruct * parser,struct ArgusInput * input)147 ArgusReadSaslStreamSocket (struct ArgusParserStruct *parser, struct ArgusInput *input)
148 {
149 int retn = 0, fd = input->fd, cnt = 0;
150 u_int val = 0, *pval = &val;
151 char *output = NULL, *ptr = NULL;
152 u_int outputlen = 0;
153 const int *ssfp;
154 int result;
155
156 if ((retn = sasl_getprop(input->sasl_conn, SASL_MAXOUTBUF, (const void **) &pval)) != SASL_OK)
157 ArgusLog (LOG_ERR, "ArgusReadSaslStreamSocket: sasl_getprop %s", strerror(errno));
158
159 if (val == 0)
160 val = ARGUS_MAX_BUFFER_READ;
161
162 cnt = (input->ArgusBufferLen - input->ArgusSaslBufCnt);
163 val = (cnt > val) ? val : cnt;
164
165 if ((cnt = read (fd, input->ArgusSaslBuffer + input->ArgusSaslBufCnt, val)) > 0) {
166 ptr = (char *) input->ArgusSaslBuffer;
167 input->ArgusSaslBufCnt += cnt;
168
169 #ifdef ARGUSDEBUG
170 ArgusDebug (5, "ArgusReadSaslStreamSocket (%p) read returned %d bytes\n", input, cnt);
171 #endif
172
173 if ((result = sasl_getprop(input->sasl_conn, SASL_SSF, (const void **) &ssfp)) != SASL_OK)
174 ArgusLog (LOG_ERR, "sasl_getprop: error %s\n", sasl_errdetail(input->sasl_conn));
175
176 if (ssfp && (*ssfp > 0)) {
177 if ((retn = sasl_decode (input->sasl_conn, ptr, input->ArgusSaslBufCnt, (const char **) &output, &outputlen)) == SASL_OK) {
178 #ifdef ARGUSDEBUG
179 ArgusDebug (5, "ArgusReadSaslStreamSocket (%p) sasl_decoded %d bytes\n", input, outputlen);
180 #endif
181
182 } else
183 ArgusLog (LOG_ERR, "ArgusReadSaslStreamSocket: sasl_decode (%p, %p, %d, %p, %p) failed %d",
184 input->sasl_conn, ptr, cnt, &output, &outputlen, retn);
185 } else {
186 output = ptr;
187 outputlen = input->ArgusSaslBufCnt;
188 }
189
190 if (outputlen) {
191 while (input->ArgusSaslBufCnt) {
192 int bytes, done = 0;
193 bytes = (input->ArgusBufferLen - input->ArgusReadSocketCnt);
194 bytes = (bytes > outputlen) ? outputlen : bytes;
195
196 bcopy (output, input->ArgusReadPtr + input->ArgusReadSocketCnt, bytes);
197
198 cnt = (input->ArgusBufferLen - input->ArgusSaslBufCnt);
199
200 if (bytes > 0) {
201 struct ArgusRecord *rec = NULL;
202 input->ArgusReadSocketCnt += bytes;
203 retn = 0;
204
205 while (!retn && !done && !parser->RaParseDone) {
206 unsigned short length = 0;
207
208 switch (input->type) {
209 case ARGUS_V2_DATA_SOURCE: {
210 struct ArgusV2Record *recv2 = (struct ArgusV2Record *)input->ArgusReadPtr;
211 if (input->ArgusReadSocketCnt >= sizeof(recv2->ahdr)) {
212 if ((length = ntohs(recv2->ahdr.length)) > 0) {
213 if (input->ArgusReadSocketCnt >= length)
214 rec = (struct ArgusRecord *) ArgusConvertRecord (input, (char *)input->ArgusReadPtr);
215 } else {
216 ArgusLog (LOG_ALERT, "ArgusReadSaslStreamSocket (%p) record length is zero");
217 retn = 1;
218 }
219 }
220 break;
221 }
222 case ARGUS_DATA_SOURCE: {
223 struct ArgusRecordHeader *recv3 = (struct ArgusRecordHeader *) input->ArgusReadPtr;
224 if (input->ArgusReadSocketCnt >= sizeof(*recv3)) {
225 if ((length = ntohs(recv3->len) * 4) > 0) {
226 if (input->ArgusReadSocketCnt >= length) {
227 rec = (struct ArgusRecord *) input->ArgusReadPtr;
228 }
229
230 } else {
231 ArgusLog (LOG_ALERT, "ArgusReadSaslStreamSocket (%p) record length is zero");
232 retn = 1;
233 }
234 }
235 break;
236 }
237 }
238
239 if (rec) {
240 int len;
241 if ((len = ArgusHandleRecord (ArgusParser, input, rec, &ArgusParser->ArgusFilterCode)) == -1) {
242 retn = 1;
243 } else {
244 input->offset += len;
245 input->ArgusReadPtr += len;
246 input->ArgusReadSocketCnt -= len;
247
248 if (input->ostop != -1)
249 if (input->offset > input->ostop)
250 retn = 1;
251 }
252
253 rec = NULL;
254
255 } else
256 done = 1;
257 }
258
259 if (input->ArgusReadPtr != input->ArgusReadBuffer) {
260 if (input->ArgusReadSocketCnt > 0)
261 memmove(input->ArgusReadBuffer, input->ArgusReadPtr, input->ArgusReadSocketCnt);
262 input->ArgusReadPtr = input->ArgusReadBuffer;
263 }
264 }
265 input->ArgusSaslBufCnt = 0;
266 }
267 }
268
269 } else {
270 retn = 1;
271
272 if ((cnt < 0) && ((errno == EAGAIN) || (errno == EINTR))) {
273 retn = 0;
274 } else
275 ArgusLog (LOG_ERR, "ArgusReadSaslStreamSocket: read (%d, %p, %d) failed '%s'",
276 fd, input->ArgusSaslBuffer, val, strerror(errno));
277 }
278
279 #ifdef ARGUSDEBUG
280 ArgusDebug (5, "ArgusReadSaslStreamSocket (%p) returning %d\n", input, retn);
281 #endif
282
283 return (retn);
284 }
285
286 #endif // ARGUS_SASL
287
288
289 int
ArgusReadStreamSocket(struct ArgusParserStruct * parser,struct ArgusInput * input)290 ArgusReadStreamSocket (struct ArgusParserStruct *parser, struct ArgusInput *input)
291 {
292 int retn = 0, cnt = 0, done = 0;
293 int bytes = 0, rbytes = 0;
294
295 if (!(input))
296 return (retn);
297
298 bytes = (input->ArgusBufferLen - input->ArgusReadSocketCnt);
299 bytes = (bytes > ARGUS_MAX_BUFFER_READ) ? ARGUS_MAX_BUFFER_READ : bytes;
300 if (input->ostop != -1) {
301 if ((rbytes = (input->ostop - input->ostart)) > 0) {
302 bytes = (bytes > rbytes) ? rbytes : bytes;
303 }
304 }
305
306 if (input->file != NULL) {
307 clearerr(input->file);
308
309 if (input->file == stdin) {
310 int sretn;
311 fd_set readmask;
312 struct timeval wait;
313
314 FD_ZERO (&readmask);
315 FD_SET (fileno(stdin), &readmask);
316 wait.tv_sec = 0;
317 wait.tv_usec = 250000;
318
319 if (!((sretn = select (fileno(stdin)+1, &readmask, NULL, NULL, &wait)) > 0)) {
320 #ifdef ARGUSDEBUG
321 ArgusDebug (4, "ArgusReadStreamSocket (%p) select returned %d\n", input, sretn);
322 #endif
323 return (sretn);
324 } else {
325 if ((cnt = fread (input->ArgusReadPtr + input->ArgusReadSocketCnt, 1, bytes, input->file)) == 0) {
326 if ((retn = ferror(input->file))) {
327 if ((retn == EAGAIN) || (retn == EINTR))
328 retn = 0;
329 else
330 retn = 1;
331 } else {
332 if ((retn = feof(input->file))) {
333 done++;
334 retn = 1;
335 }
336 }
337 }
338 }
339 } else {
340 if ((cnt = fread (input->ArgusReadPtr + input->ArgusReadSocketCnt, 1, bytes, input->file)) == 0) {
341 if ((retn = ferror(input->file))) {
342 if ((retn == EAGAIN) || (retn == EINTR))
343 retn = 0;
344 else
345 retn = 1;
346 } else {
347 if ((retn = feof(input->file))) {
348 done++;
349 retn = 1;
350 }
351 }
352 }
353 }
354
355 } else {
356 switch (input->type) {
357 default:
358 if ((cnt = read (input->fd, input->ArgusReadPtr + input->ArgusReadSocketCnt, bytes)) < 0) {
359 switch (errno) {
360 case EINTR:
361 case EAGAIN:
362 retn = 0;
363
364 default:
365 ArgusLog (LOG_WARNING, "ArgusReadStreamSocket (%p) read error %s\n", input, strerror(errno));
366 retn = 1;
367 }
368 } else {
369 if (cnt == 0) {
370 retn = 1;
371 }
372 }
373 }
374 }
375
376 #ifdef ARGUSDEBUG
377 ArgusDebug (4, "ArgusReadStreamSocket (%p) read %d bytes\n", input, cnt);
378 #endif
379
380 if (cnt > 0) {
381 struct ArgusRecord *rec = NULL;
382 input->ArgusReadSocketCnt += cnt;
383
384 while (!done) {
385 int length = 0;
386
387 rec = NULL;
388
389 switch (input->type) {
390 case ARGUS_V2_DATA_SOURCE: {
391 if (input->ArgusReadSocketCnt >= sizeof(void *)) {
392 struct ArgusV2Record *recv2 = (struct ArgusV2Record *)input->ArgusReadPtr;
393 length = ntohs(recv2->ahdr.length);
394
395 if ((length < 1) || (length > 4098)) {
396 unsigned int pattern = 0xa4000801;
397 do {
398 if (input->ArgusReadSocketCnt >= sizeof(recv2->ahdr)) {
399 input->ArgusReadPtr += 4;
400 input->ArgusReadSocketCnt -= 4;
401 recv2 = (struct ArgusV2Record *)input->ArgusReadPtr;
402 } else
403 break;
404 } while (bcmp(&recv2->ahdr, &pattern, 4));
405 length = ntohs(recv2->ahdr.length);
406 }
407
408 if (input->ArgusReadSocketCnt >= length)
409 if ((rec = (struct ArgusRecord *) ArgusConvertRecord (input, (char *)input->ArgusReadPtr)) != NULL)
410 break;
411 }
412 break;
413 }
414
415 case ARGUS_DATA_SOURCE: {
416 struct ArgusRecordHeader *recv3 = (struct ArgusRecordHeader *) input->ArgusReadPtr;
417
418 while ((ntohs(recv3->len) == 0) && (input->ArgusReadSocketCnt >= sizeof(*recv3))) {
419 recv3++;
420 input->ArgusReadSocketCnt -= sizeof(*recv3);
421 input->ArgusReadPtr += sizeof(*recv3);
422 }
423
424 if (input->ArgusReadSocketCnt >= sizeof(*recv3)) {
425 if ((length = ntohs(recv3->len) * 4) > 0) {
426 if (input->ArgusReadSocketCnt >= length) {
427 rec = (struct ArgusRecord *) input->ArgusReadPtr;
428 }
429 } else {
430 ArgusLog (LOG_ALERT, "ArgusReadStreamSocket (%p) record length is zero");
431 retn = 1;
432 }
433 }
434 break;
435 }
436 }
437
438 if (rec && !done && !parser->RaParseDone) {
439 int len = 0;
440 if ((len = ArgusHandleRecord (ArgusParser, input, rec, &ArgusParser->ArgusFilterCode)) < 0) {
441 input->offset += length;
442 input->ArgusReadPtr += length;
443 input->ArgusReadSocketCnt -= length;
444
445 if (input->ArgusReadSocketCnt < 128) {
446 retn = 1;
447 done = 1;
448 }
449 } else {
450
451 if (input->type == ARGUS_V2_DATA_SOURCE)
452 len = length;
453
454 input->offset += len;
455 input->ArgusReadPtr += len;
456 input->ArgusReadSocketCnt -= len;
457
458 if (input->ostop != -1) {
459 if (input->offset >= input->ostop) {
460 retn = 1;
461 done++;
462 }
463 }
464 }
465
466 } else
467 done = 1;
468 }
469
470 if (input->ArgusReadPtr != input->ArgusReadBuffer) {
471 if (input->ArgusReadSocketCnt > 0)
472 memmove(input->ArgusReadBuffer, input->ArgusReadPtr, input->ArgusReadSocketCnt);
473 input->ArgusReadPtr = input->ArgusReadBuffer;
474 }
475 }
476
477 #ifdef ARGUSDEBUG
478 ArgusDebug (7, "ArgusReadStreamSocket (%p) returning %d\n", input, retn);
479 #endif
480
481 return (retn);
482 }
483
484
485 void
ArgusReadFileStream(struct ArgusParserStruct * parser,struct ArgusInput * input)486 ArgusReadFileStream (struct ArgusParserStruct *parser, struct ArgusInput *input)
487 {
488 int retn = 0, done = 0;
489 struct timeval timeoutValue;
490
491 #ifdef ARGUSDEBUG
492 ArgusDebug (6, "ArgusReadFileStream() starting\n");
493 #endif
494
495 timeoutValue.tv_sec = 0;
496
497 while (input && !done) {
498
499 switch (input->type) {
500 case ARGUS_DATA_SOURCE:
501 case ARGUS_V2_DATA_SOURCE:
502 if ((retn = ArgusReadStreamSocket (parser, input)) > 0) {
503 ArgusCloseInput(parser, input);
504 done++;
505 }
506 break;
507
508 case ARGUS_CISCO_DATA_SOURCE:
509 if ((retn = ArgusReadCiscoStreamSocket (parser, input)) > 0) {
510 ArgusCloseInput(parser, input);
511 done++;
512 }
513 break;
514
515 }
516
517 if (timeoutValue.tv_sec == 0) {
518 timeoutValue = ArgusParser->ArgusRealTime;
519
520 timeoutValue.tv_sec += ArgusParser->RaClientTimeout.tv_sec;
521 timeoutValue.tv_usec += ArgusParser->RaClientTimeout.tv_usec;
522
523 while (timeoutValue.tv_usec >= 1000000) {
524 timeoutValue.tv_sec += 1;
525 timeoutValue.tv_usec -= 1000000;
526 }
527 }
528
529 if ((ArgusParser->ArgusRealTime.tv_sec > timeoutValue.tv_sec) ||
530 ((ArgusParser->ArgusRealTime.tv_sec == timeoutValue.tv_sec) &&
531 (ArgusParser->ArgusRealTime.tv_usec > timeoutValue.tv_usec))) {
532
533 ArgusClientTimeout ();
534
535 if (ArgusParser->Tflag) {
536 if ((ArgusParser->Tflag - 1) == 0) {
537 ArgusShutDown(0);
538 }
539 ArgusParser->Tflag--;
540 }
541
542 timeoutValue = ArgusParser->ArgusRealTime;
543 timeoutValue.tv_sec += ArgusParser->RaClientTimeout.tv_sec;
544 timeoutValue.tv_usec += ArgusParser->RaClientTimeout.tv_usec;
545
546 while (timeoutValue.tv_usec >= 1000000) {
547 timeoutValue.tv_sec += 1;
548 timeoutValue.tv_usec -= 1000000;
549 }
550 }
551 }
552
553 #ifdef ARGUSDEBUG
554 ArgusDebug (5, "ArgusReadFileStream() returning\n");
555 #endif
556 }
557
558
559 void *
ArgusConnectRemotes(void * arg)560 ArgusConnectRemotes (void *arg)
561 {
562 #if defined(ARGUS_THREADS)
563 struct ArgusQueueStruct *queue = arg;
564 struct ArgusInput *addr = NULL;
565 int status, retn, done = 0;
566 pthread_attr_t attr;
567
568 if ((status = pthread_attr_init(&attr)) != 0)
569 ArgusLog (LOG_ERR, "pthreads init error");
570
571 while (!done && !ArgusParser->RaParseDone) {
572 if ((addr = (struct ArgusInput *) ArgusPopQueue(queue, ARGUS_LOCK)) != NULL) {
573 if ((retn = pthread_create(&addr->tid, &attr, ArgusConnectRemote, addr)) != 0) {
574 switch (retn) {
575 case EAGAIN:
576 ArgusLog (LOG_ERR, "main: pthread_create ArgusConnectRemotes: EAGAIN \n");
577 break;
578 case EINVAL:
579 ArgusLog (LOG_ERR, "main: pthread_create ArgusConnectRemotes, EINVAL\n");
580 break;
581 }
582 }
583 }
584
585 sleep(1);
586 }
587 #endif
588
589 #ifdef ARGUSDEBUG
590 ArgusDebug (2, "ArgusConnectRemotes() done!");
591 #endif
592
593 #if defined(ARGUS_THREADS)
594 pthread_exit (NULL);
595 #else
596 return (NULL);
597 #endif
598 }
599
600
601 // This routine basically runs until it connects to the remote
602 // site and then it exists. If it is run in a threaded environment,
603 // it will run forever until it connects, then it will exit.
604
605
606 void *
ArgusConnectRemote(void * arg)607 ArgusConnectRemote (void *arg)
608 {
609 struct ArgusInput *addr = (struct ArgusInput *)arg;
610 struct timespec tsbuf = {5, 0};
611 struct timespec *ts = &tsbuf;
612 int done = 0;
613
614 #if defined(ARGUS_THREADS)
615 sigset_t blocked_signals;
616 sigfillset(&blocked_signals);
617 pthread_sigmask(SIG_BLOCK, &blocked_signals, NULL);
618 #endif
619
620 if (ArgusParser->ArgusConnectTime == 0)
621 ArgusParser->ArgusConnectTime = 10;
622
623 #ifdef ARGUSDEBUG
624 ArgusDebug (2, "ArgusConnectRemote(%p) starting", arg);
625 #endif
626
627 while (!done && !ArgusParser->RaParseDone) {
628 #if defined(ARGUS_THREADS)
629 pthread_mutex_lock(&addr->lock);
630 #endif
631
632 addr->status &= ~ARGUS_CLOSED;
633
634 if (addr->fd < 0) {
635 if ((addr->fd = ArgusGetServerSocket (addr, ArgusParser->ArgusConnectTime)) >= 0) {
636 if ((ArgusReadConnection (ArgusParser, addr, ARGUS_SOCKET)) >= 0) {
637 int flags;
638 if ((flags = fcntl(addr->fd, F_GETFL, 0L)) < 0)
639 ArgusLog (LOG_ERR, "ArgusConnectRemote: fcntl error %s", strerror(errno));
640
641 if (fcntl (addr->fd, F_SETFL, flags | O_NONBLOCK) < 0)
642 ArgusLog (LOG_ERR, "ArgusConnectRemote: fcntl error %s", strerror(errno));
643
644 #ifdef ARGUSDEBUG
645 if (addr->hostname != NULL)
646 ArgusDebug (2, "ArgusConnectRemote(%p) connected to %s", arg, addr->hostname);
647 else
648 ArgusDebug (2, "ArgusConnectRemote(%p) connected to %p", arg, addr);
649 #endif
650 if (addr->qhdr.queue != NULL) {
651 if (addr->qhdr.queue != ArgusParser->ArgusActiveHosts) {
652 ArgusRemoveFromQueue(addr->qhdr.queue, &addr->qhdr, ARGUS_LOCK);
653 ArgusAddToQueue(ArgusParser->ArgusActiveHosts, &addr->qhdr, ARGUS_LOCK);
654 }
655 } else
656 ArgusAddToQueue(ArgusParser->ArgusActiveHosts, &addr->qhdr, ARGUS_LOCK);
657
658 ArgusParser->ArgusTotalMarRecords++;
659 ArgusParser->ArgusTotalRecords++;
660 done++;
661 } else {
662 #ifdef ARGUSDEBUG
663 ArgusDebug (2, "ArgusConnectRemote() ArgusReadConnection(%s) failed", addr->hostname);
664 #endif
665 }
666
667 } else {
668 #ifdef ARGUSDEBUG
669 ArgusDebug (2, "ArgusConnectRemote() ArgusGetServerSocket failed errno %d: %s", errno, strerror(errno));
670 #endif
671 switch (errno) {
672 case EHOSTDOWN:
673 case EHOSTUNREACH:
674 case ENETUNREACH: {
675 break;
676 }
677 }
678 }
679 }
680 #if defined(ARGUS_THREADS)
681 pthread_mutex_unlock(&addr->lock);
682 #endif
683
684 if (!done && ArgusParser->ArgusReliableConnection)
685 nanosleep(ts, NULL);
686 }
687
688 #ifdef ARGUSDEBUG
689 ArgusDebug (2, "ArgusConnectRemote() done!");
690 #endif
691
692 #if defined(ARGUS_THREADS)
693 pthread_exit (NULL);
694 #else
695 return (NULL);
696 #endif
697 }
698
699
700 void
ArgusReadStream(struct ArgusParserStruct * parser,struct ArgusQueueStruct * queue)701 ArgusReadStream (struct ArgusParserStruct *parser, struct ArgusQueueStruct *queue)
702 {
703 struct ArgusInput *input = NULL;
704 struct timeval wait, timeoutValue;
705 int retn = 0, started = 0;
706
707 #if defined(ARGUS_THREADS)
708 struct timespec tsbuf = {0, 50000000};
709 struct timespec *ts = &tsbuf;
710 #endif
711
712 #ifdef ARGUSDEBUG
713 ArgusDebug (3, "ArgusReadStream(%p) starting", parser);
714 #endif
715
716 timeoutValue.tv_sec = 0;
717
718 while (!(parser->RaParseDone)) {
719 int width = -1, i;
720 fd_set readmask;
721
722 FD_ZERO (&readmask);
723
724 if ((input = (struct ArgusInput *) queue->start) != NULL) {
725 for (i = 0; i < queue->count; i++) {
726 if (input->fd >= 0) {
727 FD_SET (input->fd, &readmask);
728 width = (width < input->fd) ? input->fd : width;
729 }
730 input = (void *)input->qhdr.nxt;
731 }
732 }
733
734 if (width >= 0) {
735 width++;
736 wait.tv_sec = 0;
737 wait.tv_usec = 250000;
738
739 started = 1;
740
741 if (input->ArgusStartTime.tv_sec == 0)
742 gettimeofday (&input->ArgusStartTime, 0L);
743
744 if ((retn = select (width, &readmask, NULL, NULL, &wait)) >= 0) {
745 gettimeofday (&parser->ArgusRealTime, NULL);
746 ArgusAdjustGlobalTime(ArgusParser, &ArgusParser->ArgusRealTime);
747
748 for (input = (struct ArgusInput *) queue->start, i = 0; i < queue->count; i++) {
749 if ((input->fd >= 0) && FD_ISSET (input->fd, &readmask)) {
750 input->ArgusLastTime = parser->ArgusRealTime;
751
752 switch (input->type) {
753 case ARGUS_DATA_SOURCE:
754 case ARGUS_V2_DATA_SOURCE:
755 #ifdef ARGUS_SASL
756 if (input->sasl_conn) {
757 if (ArgusReadSaslStreamSocket (parser, input))
758 ArgusCloseInput(parser, input);
759 } else
760 #endif // ARGUS_SASL
761 if (ArgusReadStreamSocket (parser, input))
762 ArgusCloseInput(parser, input);
763 break;
764
765 case ARGUS_JFLOW_DATA_SOURCE:
766 case ARGUS_CISCO_DATA_SOURCE:
767 if (parser->Sflag) {
768 if (ArgusReadCiscoDatagramSocket (parser, input))
769 ArgusCloseInput(parser, input);
770 } else {
771 if (ArgusReadCiscoStreamSocket (parser, input))
772 ArgusCloseInput(parser, input);
773 }
774 break;
775
776 case ARGUS_SFLOW_DATA_SOURCE:
777 if (parser->Sflag) {
778 if (ArgusReadSflowDatagramSocket (parser, input))
779 ArgusCloseInput(parser, input);
780 } else {
781 if (ArgusReadSflowStreamSocket (parser, input))
782 ArgusCloseInput(parser, input);
783 }
784 break;
785 }
786
787 } else {
788 if (input->fd >= 0) {
789 if (input->hostname && input->ArgusMarInterval) {
790 if (input->ArgusLastTime.tv_sec) {
791 if ((parser->ArgusRealTime.tv_sec - input->ArgusLastTime.tv_sec) > (input->ArgusMarInterval * 2)) {
792 ArgusLog (LOG_WARNING, "ArgusReadStream %s: idle stream: closing", input->hostname);
793 ArgusCloseInput(parser, input);
794 }
795 }
796 }
797 }
798 }
799 input = (void *)input->qhdr.nxt;
800 }
801 } else {
802 gettimeofday (&parser->ArgusRealTime, NULL);
803 ArgusAdjustGlobalTime(ArgusParser, &ArgusParser->ArgusRealTime);
804 }
805
806 } else {
807 if (started) {
808 if (!(parser->ArgusReliableConnection)) {
809 parser->RaParseDone++;
810 }
811 }
812
813 #if defined(ARGUS_THREADS)
814 if ((!parser->RaParseDone && !retn) || (width < 0))
815 if (parser->ArgusReliableConnection)
816 nanosleep(ts, NULL);
817 #endif
818 gettimeofday (&parser->ArgusRealTime, NULL);
819 ArgusAdjustGlobalTime(ArgusParser, &ArgusParser->ArgusRealTime);
820 }
821
822 if (timeoutValue.tv_sec == 0) {
823 gettimeofday (&ArgusParser->ArgusRealTime, NULL);
824 timeoutValue = parser->ArgusRealTime;
825 timeoutValue.tv_sec += parser->RaClientTimeout.tv_sec;
826 timeoutValue.tv_usec += parser->RaClientTimeout.tv_usec;
827 while (timeoutValue.tv_usec >= 1000000) {
828 timeoutValue.tv_sec += 1;
829 timeoutValue.tv_usec -= 1000000;
830 }
831 }
832
833 if ((parser->ArgusRealTime.tv_sec > timeoutValue.tv_sec) ||
834 ((parser->ArgusRealTime.tv_sec == timeoutValue.tv_sec) &&
835 (parser->ArgusRealTime.tv_usec > timeoutValue.tv_usec))) {
836
837 ArgusClientTimeout ();
838
839 if (parser->Tflag) {
840 struct timeval diff;
841 RaDiffTime (&parser->ArgusRealTime, &input->ArgusStartTime, &diff);
842 if (diff.tv_sec >= parser->Tflag)
843 ArgusShutDown(0);
844 }
845
846 #if !defined(ARGUS_THREADS)
847 if (parser->ArgusReliableConnection) {
848 struct ArgusInput *addr;
849 int flags;
850
851 if ((addr = (void *)ArgusPopQueue(ArgusParser->ArgusRemoteHosts, ARGUS_LOCK)) != NULL) {
852 if ((addr->fd = ArgusGetServerSocket (addr, 5)) >= 0) {
853 if ((ArgusReadConnection (ArgusParser, addr, ARGUS_SOCKET)) >= 0) {
854 ArgusParser->ArgusTotalMarRecords++;
855 ArgusParser->ArgusTotalRecords++;
856
857 if ((flags = fcntl(addr->fd, F_GETFL, 0L)) < 0)
858 ArgusLog (LOG_ERR, "ArgusConnectRemote: fcntl error %s", strerror(errno));
859
860 if (fcntl(addr->fd, F_SETFL, flags | O_NONBLOCK) < 0)
861 ArgusLog (LOG_ERR, "ArgusConnectRemote: fcntl error %s", strerror(errno));
862
863 if (ArgusParser->RaPollMode)
864 ArgusHandleRecord (ArgusParser, addr, &addr->ArgusInitCon, &ArgusParser->ArgusFilterCode);
865
866 ArgusAddToQueue(ArgusParser->ArgusActiveHosts, &addr->qhdr, ARGUS_LOCK);
867 ArgusParser->ArgusHostsActive++;
868
869 } else
870 ArgusAddToQueue(ArgusParser->ArgusRemoteHosts, &addr->qhdr, ARGUS_LOCK);
871 } else
872 ArgusAddToQueue(ArgusParser->ArgusRemoteHosts, &addr->qhdr, ARGUS_LOCK);
873 }
874 }
875 #endif
876
877 timeoutValue = parser->ArgusRealTime;
878 timeoutValue.tv_sec += parser->RaClientTimeout.tv_sec;
879 timeoutValue.tv_usec += parser->RaClientTimeout.tv_usec;
880
881 if (timeoutValue.tv_usec >= 1000000) {
882 timeoutValue.tv_sec += 1;
883 timeoutValue.tv_usec -= 1000000;
884 }
885 if (timeoutValue.tv_usec < 0) {
886 timeoutValue.tv_usec = 0;
887 }
888 }
889
890 }
891
892 #ifdef ARGUSDEBUG
893 ArgusDebug (3, "ArgusReadStream(%p, %p) returning", parser, queue);
894 #endif
895 }
896
897 int ArgusTotalRecords = 0;
898
899
900 #include <netdb.h>
901
902 extern void ArgusLog (int, char *, ...);
903
904 #define ARGUS_DEFAULTCISCOPORT 9995
905
906 char *ArgusRecordType = NULL;
907
908 extern int ArgusInitializeAuthentication(void);
909
910 #include <netinet/in.h>
911 #include <arpa/inet.h>
912
913
914
915 int
ArgusGetServerSocket(struct ArgusInput * input,int timeout)916 ArgusGetServerSocket (struct ArgusInput *input, int timeout)
917 {
918 #if HAVE_GETADDRINFO
919 struct addrinfo *hp = input->host;
920 #else
921 struct hostent *hp = input->host;
922 int type = SOCK_DGRAM;
923 #endif
924 struct servent *sp;
925 int s, retn = -1;
926 u_short portnum = 0;
927
928 #if HAVE_GETADDRINFO
929 char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
930 int optval = 1;
931 #endif
932
933 switch (input->type) {
934 case ARGUS_DATA_SOURCE:
935 case ARGUS_V2_DATA_SOURCE: {
936 char *protoStr;
937 ArgusRecordType = "Argus";
938 if (input->mode == IPPROTO_UDP) {
939 input->mode = ARGUS_DATAGRAM_SOURCE;
940 protoStr = "udp";
941 } else {
942 protoStr = "tcp";
943 #if !HAVE_GETADDRINFO
944 type = SOCK_STREAM;
945 #endif
946 }
947 if (!input->portnum) {
948 if (!ArgusParser->ArgusPortNum) {
949 if ((sp = getservbyname ("monitor", protoStr)) != NULL)
950 portnum = sp->s_port;
951 else
952 portnum = htons(ARGUS_DEFAULTPORT);
953 } else
954 portnum = htons(ArgusParser->ArgusPortNum);
955
956 input->portnum = ntohs(portnum);
957
958 } else
959 portnum = htons(input->portnum);
960
961 break;
962 }
963
964 case ARGUS_JFLOW_DATA_SOURCE: {
965 ArgusRecordType = "Jflow";
966 input->mode = ARGUS_DATAGRAM_SOURCE;
967 break;
968 }
969
970 case ARGUS_SFLOW_DATA_SOURCE: {
971 ArgusRecordType = "Sflow";
972 input->mode = ARGUS_DATAGRAM_SOURCE;
973 break;
974 }
975
976 case ARGUS_CISCO_DATA_SOURCE: {
977 struct ArgusRecord argus;
978
979 ArgusRecordType = "Netflow";
980 if (!input->portnum) {
981 if (!ArgusParser->ArgusPortNum) {
982 if ((sp = getservbyname ("monitor", "udp")) != NULL)
983 portnum = sp->s_port;
984 else
985 portnum = htons(ARGUS_DEFAULTCISCOPORT);
986 } else
987 portnum = htons(ArgusParser->ArgusPortNum);
988 } else
989 portnum = htons(input->portnum);
990
991 bzero ((char *)&argus, sizeof(argus));
992 argus.hdr.type = ARGUS_MAR | ARGUS_NETFLOW | ARGUS_VERSION;
993 argus.hdr.cause = ARGUS_START;
994 argus.hdr.len = sizeof (argus) / 4;
995 argus.argus_mar.argusid = ARGUS_COOKIE;
996
997 if (input->addr.s_addr != 0)
998 argus.argus_mar.thisid = input->addr.s_addr;
999
1000 argus.argus_mar.startime.tv_sec = ArgusParser->ArgusGlobalTime.tv_sec;
1001 argus.argus_mar.now.tv_sec = ArgusParser->ArgusGlobalTime.tv_sec;
1002 argus.argus_mar.major_version = VERSION_MAJOR;
1003 argus.argus_mar.minor_version = VERSION_MINOR;
1004 argus.argus_mar.record_len = -1;
1005
1006 input->major_version = argus.argus_mar.major_version;
1007 input->minor_version = argus.argus_mar.minor_version;
1008
1009 #if defined(_LITTLE_ENDIAN)
1010 ArgusHtoN(&argus);
1011 #endif
1012 bcopy ((char *) &argus, (char *)&input->ArgusInitCon, sizeof (argus));
1013 break;
1014 }
1015
1016 case ARGUS_IPFIX_DATA_SOURCE: {
1017 ArgusRecordType = "Ipfix";
1018 break;
1019 }
1020
1021 default:
1022 ArgusLog (LOG_ERR, "ArgusGetServerSocket(%p) unknown type", input);
1023 }
1024
1025 switch (input->type) {
1026 case ARGUS_DATA_SOURCE:
1027 case ARGUS_V2_DATA_SOURCE: {
1028
1029 if (hp == NULL) {
1030 char *hptr = input->hostname;
1031 #if HAVE_GETADDRINFO
1032 struct addrinfo hints;
1033 #endif
1034 if ((hptr != NULL) && (strlen(hptr) > 0)) {
1035 char msgbuf[1024];
1036 int rval;
1037 #if HAVE_GETADDRINFO
1038 memset(&hints, 0, sizeof(hints));
1039 // hints.ai_family = AF_INET;
1040 if ((input->type == ARGUS_CISCO_DATA_SOURCE) || (input->mode == ARGUS_DATAGRAM_SOURCE)) {
1041 hints.ai_socktype = SOCK_DGRAM;
1042 hints.ai_protocol = IPPROTO_UDP;
1043 hints.ai_family = AF_INET;
1044 } else
1045 hints.ai_socktype = SOCK_STREAM;
1046
1047 if (!(strncasecmp("any", hptr, 3))) {
1048 hptr = NULL;
1049 hints.ai_flags = AI_PASSIVE;
1050 }
1051
1052 if ((rval = getaddrinfo(hptr, input->servname, &hints, &hp)) != 0) {
1053 switch (rval) {
1054 case EAI_AGAIN:
1055 sprintf (msgbuf, "dns server not available");
1056 break;
1057 case EAI_NONAME:
1058 sprintf (msgbuf, "host %s unknown", hptr);
1059 break;
1060 #if defined(EAI_ADDRFAMILY)
1061 case EAI_ADDRFAMILY:
1062 sprintf (msgbuf, "host %s has no IP address", hptr);
1063 break;
1064 #endif
1065 case EAI_SYSTEM:
1066 default:
1067 sprintf (msgbuf, "host '%s' %s", hptr, gai_strerror(rval));
1068 break;
1069 }
1070 }
1071 #else
1072 if ((hp = gethostbyname(hptr)) != NULL) {
1073 u_int **p;
1074 for (p = (u_int **)hp->h_addr_list; *p; ++p)
1075 **p = ntohl(**p);
1076 } else {
1077 switch (h_errno) {
1078 case TRY_AGAIN:
1079 sprintf (msgbuf, "dns server not available");
1080 break;
1081 case HOST_NOT_FOUND:
1082 sprintf (msgbuf, "host %s unknown", hptr);
1083 break;
1084 case NO_ADDRESS:
1085 sprintf (msgbuf, "host %s has no IP address", hptr);
1086 break;
1087 case NO_RECOVERY:
1088 sprintf (msgbuf, "host %s name server error", hptr);
1089 break;
1090 }
1091 }
1092 #endif
1093 }
1094 }
1095
1096 if (hp != NULL) {
1097 #if HAVE_GETADDRINFO
1098 do {
1099 if (getnameinfo(hp->ai_addr, hp->ai_addrlen, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV))
1100 ArgusLog(LOG_ERR, "could not get numeric hostname");
1101
1102 if (hp->ai_canonname) {
1103 if (input->hostname)
1104 free(input->hostname);
1105 input->hostname = strdup(hp->ai_canonname);
1106 } else {
1107 if (input->hostname)
1108 free(input->hostname);
1109 input->hostname = strdup(hbuf);
1110 }
1111
1112 if ((s = socket (hp->ai_family, hp->ai_socktype, hp->ai_protocol)) >= 0) {
1113 if (hp->ai_socktype == SOCK_DGRAM) {
1114 if (hp->ai_addr->sa_family == PF_INET) {
1115 struct sockaddr_in *sinaddr = (struct sockaddr_in *)hp->ai_addr;
1116 struct in_addr ia;
1117 // int reuse = 1;
1118
1119 bcopy(&sinaddr->sin_addr, &ia, sizeof(ia));
1120
1121 if (IN_MULTICAST(ntohl(ia.s_addr))) {
1122 struct ip_mreq mreq;
1123 bcopy(&ia, &mreq.imr_multiaddr.s_addr, sizeof(struct in_addr));
1124 // set interface
1125 mreq.imr_interface.s_addr = htonl(INADDR_ANY);
1126
1127 // do membership call
1128 if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(struct ip_mreq)) == -1)
1129 ArgusLog (LOG_ERR, "ArgusGetServerSocket: setsockopt() join multicast failed. %s", strerror(errno));
1130
1131 // if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &reuse, sizeof(reuse)) == -1)
1132 // ArgusLog (LOG_ERR, "ArgusGetServerSocket: setsockopt() reuse port failed. %s", strerror(errno));
1133 }
1134
1135 } else if (hp->ai_addr->sa_family == PF_INET6) {
1136 // if (IN6_IS_ADDR_MULTICAST(hp->ai_addr->sa_data)) {
1137 // }
1138 }
1139
1140 #ifdef ARGUSDEBUG
1141 ArgusDebug (1, "Binding %s:%s Expecting %s records", input->hostname, sbuf, ArgusRecordType);
1142 #endif
1143 if ((retn = bind (s, hp->ai_addr, hp->ai_addrlen)) < 0) {
1144 ArgusLog(LOG_WARNING, "connect to %s:%s failed '%s'", input->hostname, sbuf, strerror(errno));
1145 hp = hp->ai_next;
1146 } else {
1147 retn = s;
1148 input->fd = s;
1149 }
1150
1151 } else {
1152 if (ArgusParser->ArgusSourcePort) {
1153 struct sockaddr_in server;
1154 bzero(&server, sizeof(server));
1155 server.sin_family = AF_INET;
1156 server.sin_addr.s_addr = INADDR_ANY;
1157 server.sin_port = htons(ArgusParser->ArgusSourcePort);
1158 #ifdef ARGUSDEBUG
1159 ArgusDebug (1, "Binding TCP to source INADDR_ANY:%d Expecting %s records", ArgusParser->ArgusSourcePort, ArgusRecordType);
1160 #endif
1161 if ((bind (s, (struct sockaddr *)&server, sizeof(server))) < 0)
1162 ArgusLog (LOG_ERR, "bind (%d, %s:%hu, %d) failed '%s'", s, "INADDR_ANY",
1163 ntohs(server.sin_port), sizeof(server), strerror(errno));
1164
1165 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&optval, sizeof(int)) < 0) {
1166 #ifdef ARGUSDEBUG
1167 ArgusDebug (1, "setsockopt(%d, SOL_SOCKET, SO_REUSEADDR, x%x, %d) failed:", s, optval, sizeof(int));
1168 #endif
1169 }
1170 }
1171
1172 if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char *)&optval, sizeof(int)) < 0) {
1173 #ifdef ARGUSDEBUG
1174 ArgusDebug (1, "setsockopt(%d, SOL_SOCKET, SO_KEEPALIVE, 0x%x, %d) failed:", s, optval, sizeof(int));
1175 #endif
1176 }
1177 #ifdef ARGUSDEBUG
1178 ArgusDebug (1, "Trying %s port %s Expecting %s records\n", input->hostname, sbuf, ArgusRecordType);
1179 #endif
1180 if ((retn = ArgusConnect (s, hp->ai_addr, hp->ai_addrlen, timeout)) < 0) {
1181 ArgusLog(LOG_WARNING, "connect to %s:%s failed '%s'", input->hostname, sbuf, strerror(errno));
1182 hp = hp->ai_next;
1183 } else {
1184 retn = s;
1185 input->fd = s;
1186 }
1187 }
1188
1189 if (retn < 0)
1190 close(s);
1191 #ifdef ARGUSDEBUG
1192 else {
1193 if (hp->ai_socktype == SOCK_DGRAM)
1194 ArgusDebug (1, "receiving\n");
1195 else
1196 ArgusDebug (1, "connected\n");
1197
1198 input->status &= ~ARGUS_CLOSED;
1199 }
1200 #endif
1201 } else
1202 ArgusLog (LOG_ERR, "ArgusGetServerSocket: socket() failed. errno %d: %s", errno, strerror(errno));
1203
1204 } while (hp && (retn < 0));
1205 #endif
1206 } else {
1207 #if !HAVE_GETADDRINFO
1208 struct sockaddr_in server;
1209
1210 bzero ((char *) &server, sizeof (server));
1211
1212 if ((s = socket (PF_INET, type, 0)) >= 0) {
1213 if (type == SOCK_DGRAM) {
1214 if (input->addr.s_addr != 0)
1215 server.sin_addr.s_addr = htonl(input->addr.s_addr);
1216 else
1217 server.sin_addr.s_addr = INADDR_ANY;
1218
1219 server.sin_family = AF_INET;
1220 server.sin_port = portnum;
1221
1222 #ifdef ARGUSDEBUG
1223 ArgusLog (1, "Binding %s:%d Expecting %s records",
1224 ArgusGetName(ArgusParser, (unsigned char *)&input->addr.s_addr), ntohs(portnum), ArgusRecordType);
1225 #endif
1226 if ((bind (s, (struct sockaddr *)&server, sizeof(server))) < 0)
1227 ArgusLog (LOG_ERR, "bind (%d, %s:%hu, %d) failed '%s'", s, inet_ntoa(server.sin_addr),
1228 server.sin_port, sizeof(server), strerror(errno));
1229 retn = s;
1230 input->fd = s;
1231
1232 } else {
1233 in_addr_t saddr;
1234 int optval = 1;
1235
1236 if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char *)&optval, sizeof(int)) < 0) {
1237 #ifdef ARGUSDEBUG
1238 ArgusDebug (1, "setsockopt(%d, SOL_SOCKET, SO_KEEPALIVE, 0x%x, %d) failed:", s, optval, sizeof(int));
1239 #endif
1240 }
1241
1242 if (ArgusParser->ArgusSourcePort) {
1243 server.sin_family = AF_INET;
1244 server.sin_addr.s_addr = INADDR_ANY;
1245 server.sin_port = htons(ArgusParser->ArgusSourcePort);
1246
1247 #ifdef ARGUSDEBUG
1248 ArgusDebug (1, "Binding TCP to source INADDR_ANY:%d Expecting %s records",
1249 ArgusGetName(ArgusParser, ArgusParser->ArgusSourcePort, ArgusRecordType));
1250 #endif
1251 if ((bind (s, (struct sockaddr *)&server, sizeof(server))) < 0)
1252 ArgusLog (LOG_ERR, "bind (%d, %s:%hu, %d) failed '%s'", s, "INADDR_ANY",
1253 ntohs(server.sin_port), sizeof(server), strerror(errno));
1254 }
1255
1256 saddr = htonl(input->addr.s_addr);
1257 if ((hp = gethostbyaddr ((char *)&saddr, sizeof (saddr), AF_INET)) != NULL) {
1258 input->hostname = strdup(hp->h_name);
1259 bcopy ((char *) hp->h_addr, (char *)&server.sin_addr, hp->h_length);
1260 server.sin_family = hp->h_addrtype;
1261 server.sin_port = portnum;
1262 #ifdef ARGUSDEBUG
1263 ArgusDebug (1, "Trying %s port %d Expecting %s records\n", (hp->h_name) ?
1264 (hp->h_name) : intoa (saddr), ntohs(portnum), ArgusRecordType);
1265 #endif
1266 } else {
1267 server.sin_addr.s_addr = saddr;
1268 server.sin_family = AF_INET;
1269 server.sin_port = portnum;
1270 #ifdef ARGUSDEBUG
1271 ArgusDebug (1, "Trying %s port %d Expecting %s records\n",
1272 intoa (saddr), ntohs(portnum), ArgusRecordType);
1273 #endif
1274 }
1275
1276 if ((retn = ArgusConnect (s, (struct sockaddr *)&server, sizeof(server), timeout)) < 0) {
1277 ArgusLog(LOG_WARNING, "connect to %s:%hu failed '%s'", inet_ntoa(server.sin_addr),
1278 ntohs(server.sin_port), strerror(errno));
1279 close(s);
1280
1281 } else {
1282 retn = s;
1283 input->fd = s;
1284
1285 #ifdef ARGUSDEBUG
1286 if (type == SOCK_DGRAM)
1287 ArgusDebug (1, "receiving\n");
1288 else
1289 ArgusDebug (1, "connected\n");
1290 #endif
1291 }
1292 }
1293
1294 } else {
1295 ArgusLog (LOG_ERR, "ArgusGetServerSocket: socket() failed. errno %d: %s", errno, strerror(errno));
1296 }
1297 #endif
1298 }
1299 break;
1300 }
1301
1302 case ARGUS_SFLOW_DATA_SOURCE:
1303 case ARGUS_JFLOW_DATA_SOURCE:
1304 case ARGUS_CISCO_DATA_SOURCE: {
1305 #if HAVE_GETADDRINFO
1306 if (hp != NULL)
1307 s = socket (hp->ai_family, hp->ai_socktype, hp->ai_protocol);
1308 else
1309 #endif
1310 s = socket (AF_INET, SOCK_DGRAM, 0);
1311
1312 if (s >= 0) {
1313 if (hp != NULL) {
1314 #if HAVE_GETADDRINFO
1315 if (getnameinfo(hp->ai_addr, hp->ai_addrlen, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV))
1316 ArgusLog(LOG_ERR, "could not get numeric hostname");
1317
1318 if (hp->ai_canonname) {
1319 if (input->hostname)
1320 free(input->hostname);
1321 input->hostname = strdup(hp->ai_canonname);
1322 } else {
1323 if (input->hostname)
1324 free(input->hostname);
1325 input->hostname = strdup(hbuf);
1326 }
1327
1328 if (hp->ai_socktype == SOCK_DGRAM) {
1329 #ifdef ARGUSDEBUG
1330 char *name = input->hostname;
1331 if (!(strncmp(name, "0.0.0.0", 7))) name = "AF_ANY";
1332 ArgusLog (1, "Binding %s:%s Expecting %s records", name, sbuf, ArgusRecordType);
1333 #endif
1334 if ((retn = bind (s, hp->ai_addr, hp->ai_addrlen)) < 0) {
1335 ArgusLog(LOG_WARNING, "connect to %s:%s failed '%s'", input->hostname, sbuf, strerror(errno));
1336 hp = hp->ai_next;
1337 } else {
1338 retn = s;
1339 input->fd = s;
1340 }
1341
1342 } else {
1343 if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char *)&optval, sizeof(int)) < 0) {
1344 #ifdef ARGUSDEBUG
1345 ArgusDebug (1, "setsockopt(%d, SOL_SOCKET, SO_KEEPALIVE, 0x%x, %d) failed:", s, optval, sizeof(int));
1346 #endif
1347 }
1348 #ifdef ARGUSDEBUG
1349 ArgusDebug (1, "Trying %s port %s Expecting %s records\n", input->hostname, sbuf, ArgusRecordType);
1350 #endif
1351 if ((retn = ArgusConnect (s, hp->ai_addr, hp->ai_addrlen, timeout)) < 0) {
1352 ArgusLog(LOG_WARNING, "connect to %s:%s failed '%s'", input->hostname, sbuf, strerror(errno));
1353 hp = hp->ai_next;
1354 } else {
1355 retn = s;
1356 input->fd = s;
1357 }
1358 }
1359
1360 if (retn < 0)
1361 close(s);
1362 #ifdef ARGUSDEBUG
1363 else {
1364 if (hp->ai_socktype == SOCK_DGRAM)
1365 ArgusDebug (1, "receiving\n");
1366 else
1367 ArgusDebug (1, "connected\n");
1368 }
1369 #endif
1370 #endif
1371 } else {
1372 struct sockaddr_in server;
1373 bzero(&server, sizeof(server));
1374
1375 if (input->addr.s_addr != 0)
1376 server.sin_addr.s_addr = htonl(input->addr.s_addr);
1377 else
1378 server.sin_addr.s_addr = INADDR_ANY;
1379
1380 server.sin_family = AF_INET;
1381 server.sin_port = htons(input->portnum);
1382 #ifdef ARGUSDEBUG
1383 if ((server.sin_addr.s_addr == INADDR_ANY) || (!(strncmp((char *)&input->addr.s_addr, "0.0.0.0", 7))))
1384 ArgusLog (1, "Binding %s:%d Expecting %s records", "AF_ANY", input->portnum, ArgusRecordType);
1385 else {
1386 ArgusLog (1, "Binding %s:%d Expecting %s records", (unsigned char *)&input->addr.s_addr, input->portnum, ArgusRecordType);
1387 }
1388 #endif
1389 if ((retn = bind (s, (struct sockaddr *)&server, sizeof(server))) < 0) {
1390 ArgusLog(LOG_WARNING, "connect to %s:%d failed '%s'", inet_ntoa(server.sin_addr),
1391 ntohs(server.sin_port), strerror(errno));
1392 close(s);
1393
1394 } else {
1395 retn = s;
1396 input->fd = s;
1397 }
1398 }
1399 } else
1400 ArgusLog (LOG_ERR, "ArgusGetServerSocket: socket() failed. errno %d: %s", errno, strerror(errno));
1401 break;
1402 }
1403 }
1404
1405 #ifdef ARGUSDEBUG
1406 ArgusDebug (1, "ArgusGetServerSocket (%p) returning %d", input, retn);
1407 #endif
1408
1409 return (retn);
1410 }
1411
1412
1413 int
ArgusConnect(int s,const struct sockaddr * name,socklen_t namelen,int timeout)1414 ArgusConnect(int s, const struct sockaddr *name, socklen_t namelen, int timeout)
1415 {
1416 int retn = 0, flags, width = (s + 1);
1417 struct timeval tbuf;
1418 fd_set rset, wset;
1419
1420 if ((flags = fcntl(s, F_GETFL, 0)) < 0)
1421 ArgusLog (LOG_ERR, "ArgusConnect: fcntl error %s", strerror(errno));
1422
1423 if ((fcntl(s, F_SETFL, flags | O_NONBLOCK)) < 0)
1424 ArgusLog (LOG_ERR, "ArgusConnect: fcntl error %s", strerror(errno));
1425
1426 if ((retn = connect(s, name, namelen)) < 0)
1427 if (errno != EINPROGRESS)
1428 return(retn);
1429
1430 if (retn) {
1431 FD_ZERO(&rset); FD_SET(s, &rset);
1432 FD_ZERO(&wset); FD_SET(s, &wset);
1433 tbuf.tv_sec = timeout;
1434 tbuf.tv_usec = 0;
1435
1436 if ((retn = select (width, &rset, &wset, NULL, &tbuf)) == 0) {
1437 errno = ETIMEDOUT;
1438 return(-1);
1439
1440 } else {
1441 if (FD_ISSET(s, &rset) || FD_ISSET(s, &wset)) {
1442 int error;
1443 socklen_t len = sizeof(error);
1444 if (getsockopt(s, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
1445 return(-1);
1446 }
1447 if (error) {
1448 errno = error;
1449 return(-1);
1450 }
1451 }
1452 }
1453 }
1454
1455 if ((fcntl(s, F_SETFL, flags)) < 0)
1456 ArgusLog (LOG_ERR, "ArgusConnect: fcntl error %s", strerror(errno));
1457
1458 return(0);
1459 }
1460
1461 struct ArgusRecordStruct ArgusGenerateRecordBuffer;
1462 struct ArgusCanonRecord ArgusGenerateCanonBuffer;
1463 char ArgusCanonLabelBuffer[MAXBUFFERLEN];
1464
1465 struct ArgusRecordStruct *
ArgusGenerateRecordStruct(struct ArgusParserStruct * parser,struct ArgusInput * input,struct ArgusRecord * argus)1466 ArgusGenerateRecordStruct (struct ArgusParserStruct *parser, struct ArgusInput *input, struct ArgusRecord *argus)
1467 {
1468 unsigned int ArgusReverse = 0, status = 0;
1469 struct ArgusRecordStruct *retn = NULL;
1470 struct ArgusCanonRecord *canon = NULL;
1471 char *label = NULL;
1472
1473 if (input != NULL) {
1474 retn = &input->ArgusGenerateRecordStructBuf;
1475 canon = &input->ArgusGenerateRecordCanonBuf;
1476 label = input->ArgusGenerateRecordLabelBuf;
1477 } else {
1478 retn = &ArgusGenerateRecordBuffer;
1479 canon = &ArgusGenerateCanonBuffer;
1480 label = ArgusCanonLabelBuffer;
1481 }
1482
1483 if (argus == NULL) {
1484 bzero ((char *)retn, sizeof(*retn));
1485 bzero ((char *)canon, sizeof(*canon));
1486
1487 retn->input = input;
1488 retn->hdr.type = ARGUS_FAR | ARGUS_VERSION;
1489 retn->hdr.cause = ARGUS_STATUS;
1490 retn->hdr.len = 8;
1491 retn->dsrs[ARGUS_TRANSPORT_INDEX] = &canon->trans.hdr;
1492
1493 retn->dsrs[ARGUS_TIME_INDEX] = &canon->time.hdr;
1494 canon->time.hdr.type = ARGUS_TIME_DSR;
1495 canon->time.hdr.subtype = ARGUS_TIME_ABSOLUTE_RANGE;
1496 canon->time.hdr.argus_dsrvl8.qual = ARGUS_TYPE_UTC_MICROSECONDS;
1497 canon->time.hdr.argus_dsrvl8.len = (sizeof(canon->time) + 3)/4;
1498 retn->dsrindex |= (0x01 << ARGUS_TIME_INDEX);
1499
1500 retn->sload = 0.0;
1501 retn->dload = 0.0;
1502 retn->srate = 0.0;
1503 retn->drate = 0.0;
1504 retn->pcr = 0.0;
1505 retn->dur = 0.0;
1506
1507 } else {
1508 struct ArgusRecordHeader *hdr = &argus->hdr;
1509
1510 bzero ((char *)retn->dsrs, sizeof(retn->dsrs));
1511 bzero ((char *)&retn->qhdr, sizeof(retn->qhdr));
1512
1513 retn->status = 0;
1514 retn->dsrindex = 0;
1515 retn->input = input;
1516
1517 retn->sload = 0.0;
1518 retn->dload = 0.0;
1519 retn->srate = 0.0;
1520 retn->drate = 0.0;
1521 retn->pcr = 0.0;
1522 retn->dur = 0.0;
1523
1524 retn->bins = NULL;
1525 retn->htblhdr = NULL;
1526 retn->nsq = NULL;
1527
1528 switch (hdr->type & 0xF0) {
1529 case ARGUS_MAR: {
1530 if (argus->hdr.len > 1) {
1531 retn->dsrs[0] = (void *) canon;
1532 bcopy ((char *)argus, (char *)retn->dsrs[0], (argus->hdr.len * 4));
1533 retn->dsrindex |= (0x01 << ARGUS_MAR_INDEX);
1534 }
1535 bcopy((char *)hdr, (char *)&retn->hdr, sizeof(*hdr));
1536
1537 if (argus == &input->ArgusInitCon) {
1538 retn->status |= ARGUS_INIT_MAR;
1539 }
1540 break;
1541 }
1542
1543 case ARGUS_EVENT:
1544 case ARGUS_NETFLOW:
1545 case ARGUS_FAR: {
1546 struct ArgusDSRHeader *dsr = (struct ArgusDSRHeader *) (hdr + 1);
1547 int dsrlen = hdr->len * 4;
1548 char *argusend = (char *)argus + dsrlen;
1549 double seconds = 0.0;
1550
1551 bcopy((char *)hdr, (char *)&retn->hdr, sizeof(*hdr));
1552
1553 while (retn && ((char *) dsr < argusend)) {
1554 unsigned char type = dsr->type, subtype = dsr->subtype;
1555 int cnt;
1556
1557 if ((cnt = (((type & ARGUS_IMMEDIATE_DATA) ? 1 :
1558 ((subtype & ARGUS_LEN_16BITS) ? dsr->argus_dsrvl16.len :
1559 dsr->argus_dsrvl8.len))) * 4) > 0) {
1560
1561 if (argusend < ((char *)dsr + cnt))
1562 break;
1563
1564 switch (type & 0x7F) {
1565 case ARGUS_FLOW_DSR: {
1566 struct ArgusFlow *flow = (struct ArgusFlow *) dsr;
1567
1568 bzero ((char *)&canon->flow, sizeof(canon->flow));
1569 switch (subtype & 0x3F) {
1570 case ARGUS_FLOW_LAYER_3_MATRIX:
1571 case ARGUS_FLOW_CLASSIC5TUPLE: {
1572 status = flow->hdr.argus_dsrvl8.qual & ARGUS_DIRECTION;
1573
1574 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
1575 case ARGUS_TYPE_IPV4: {
1576 if (flow->hdr.argus_dsrvl8.qual & ARGUS_FRAGMENT) {
1577
1578 if ((flow->hdr.subtype & 0x3F) == ARGUS_FLOW_CLASSIC5TUPLE) { // lets modify the flow direction
1579 // if needs reversing, to get things right.
1580 if (!(flow->hdr.subtype & ARGUS_REVERSE)) {
1581 canon->flow.frag_flow.ip_src = flow->frag_flow.ip_src;
1582 canon->flow.frag_flow.ip_dst = flow->frag_flow.ip_dst;
1583 } else {
1584 canon->flow.frag_flow.ip_src = flow->frag_flow.ip_dst;
1585 canon->flow.frag_flow.ip_dst = flow->frag_flow.ip_src;
1586 }
1587 canon->flow.frag_flow.ip_p = flow->frag_flow.ip_p;
1588 canon->flow.frag_flow.pad[0] = 0;
1589 canon->flow.frag_flow.pad[1] = 0;
1590 }
1591 } else {
1592 if (!(flow->hdr.subtype & ARGUS_REVERSE)) {
1593 canon->flow.ip_flow.ip_src = flow->ip_flow.ip_src;
1594 canon->flow.ip_flow.ip_dst = flow->ip_flow.ip_dst;
1595 } else {
1596 canon->flow.ip_flow.ip_src = flow->ip_flow.ip_dst;
1597 canon->flow.ip_flow.ip_dst = flow->ip_flow.ip_src;
1598 }
1599 if ((flow->hdr.subtype & 0x3F) == ARGUS_FLOW_CLASSIC5TUPLE) {
1600 canon->flow.ip_flow.ip_p = flow->ip_flow.ip_p;
1601 switch (flow->ip_flow.ip_p) {
1602 case IPPROTO_UDP:
1603 if (flow->ip_flow.tp_p == ARGUS_V2_RTCP_FLOWTAG) {
1604 retn->dsrs[ARGUS_NETWORK_INDEX] = &canon->net.hdr;
1605 canon->net.hdr.type = ARGUS_NETWORK_DSR;
1606 canon->net.hdr.subtype = ARGUS_RTCP_FLOW;
1607 canon->net.hdr.argus_dsrvl8.qual = 0;
1608 canon->net.hdr.argus_dsrvl8.len = ((sizeof(struct ArgusRTCPObject)+3/4) + 1);
1609 retn->dsrindex |= (0x01 << ARGUS_NETWORK_INDEX);
1610 }
1611
1612 case IPPROTO_TCP:
1613 if (!(flow->hdr.subtype & ARGUS_REVERSE)) {
1614 canon->flow.ip_flow.sport = flow->ip_flow.sport;
1615 canon->flow.ip_flow.dport = flow->ip_flow.dport;
1616 } else {
1617 canon->flow.ip_flow.sport = flow->ip_flow.dport;
1618 canon->flow.ip_flow.dport = flow->ip_flow.sport;
1619 }
1620 break;
1621
1622 case IPPROTO_ICMP:
1623 canon->flow.icmp_flow.type = flow->icmp_flow.type;
1624 canon->flow.icmp_flow.code = flow->icmp_flow.code;
1625 canon->flow.icmp_flow.id = flow->icmp_flow.id;
1626 canon->flow.icmp_flow.ip_id = flow->icmp_flow.ip_id;
1627 break;
1628
1629 case IPPROTO_ESP:
1630 canon->flow.esp_flow.spi = flow->esp_flow.spi;
1631 break;
1632 }
1633 }
1634 if (flow->hdr.argus_dsrvl8.qual & ARGUS_MASKLEN) {
1635 if (!(flow->hdr.subtype & ARGUS_REVERSE)) {
1636 canon->flow.ip_flow.smask = flow->ip_flow.smask;
1637 canon->flow.ip_flow.dmask = flow->ip_flow.dmask;
1638 } else {
1639 canon->flow.ip_flow.smask = flow->ip_flow.dmask;
1640 canon->flow.ip_flow.dmask = flow->ip_flow.smask;
1641 }
1642 if (canon->flow.ip_flow.smask == 0)
1643 canon->flow.ip_flow.smask = 32;
1644
1645 if (canon->flow.ip_flow.dmask == 0)
1646 canon->flow.ip_flow.dmask = 32;
1647 } else {
1648 flow->hdr.argus_dsrvl8.qual |= ARGUS_MASKLEN;
1649 canon->flow.ip_flow.smask = 32;
1650 canon->flow.ip_flow.dmask = 32;
1651 }
1652 }
1653 break;
1654 }
1655
1656 case ARGUS_TYPE_IPV6: {
1657 int i;
1658
1659 for (i = 0; i < 4; i++) {
1660 if (!(flow->hdr.subtype & ARGUS_REVERSE)) {
1661 canon->flow.ipv6_flow.ip_src[i] = flow->ipv6_flow.ip_src[i];
1662 canon->flow.ipv6_flow.ip_dst[i] = flow->ipv6_flow.ip_dst[i];
1663 } else {
1664 canon->flow.ipv6_flow.ip_dst[i] = flow->ipv6_flow.ip_src[i];
1665 canon->flow.ipv6_flow.ip_src[i] = flow->ipv6_flow.ip_dst[i];
1666 }
1667 }
1668
1669 if ((flow->hdr.subtype & 0x3F) == ARGUS_FLOW_CLASSIC5TUPLE) {
1670 canon->flow.ipv6_flow.flow = flow->ipv6_flow.flow;
1671 switch (canon->flow.ipv6_flow.ip_p = flow->ipv6_flow.ip_p) {
1672 case IPPROTO_TCP:
1673 case IPPROTO_UDP:
1674 if (!(flow->hdr.subtype & ARGUS_REVERSE)) {
1675 canon->flow.ipv6_flow.sport = flow->ipv6_flow.sport;
1676 canon->flow.ipv6_flow.dport = flow->ipv6_flow.dport;
1677 } else {
1678 canon->flow.ipv6_flow.sport = flow->ipv6_flow.dport;
1679 canon->flow.ipv6_flow.dport = flow->ipv6_flow.sport;
1680 }
1681 break;
1682
1683 case IPPROTO_ICMPV6:
1684 canon->flow.icmpv6_flow.type = flow->icmpv6_flow.type;
1685 canon->flow.icmpv6_flow.code = flow->icmpv6_flow.code;
1686 canon->flow.icmpv6_flow.id = ntohs(flow->icmpv6_flow.id);
1687 break;
1688
1689 case IPPROTO_ESP:
1690 canon->flow.esp_flow.spi = flow->esp_flow.spi;
1691 break;
1692 }
1693 }
1694
1695 if (flow->hdr.argus_dsrvl8.qual & ARGUS_MASKLEN) {
1696 if (!(flow->hdr.subtype & ARGUS_REVERSE)) {
1697 canon->flow.ipv6_flow.smask = flow->ipv6_flow.smask;
1698 canon->flow.ipv6_flow.dmask = flow->ipv6_flow.dmask;
1699 } else {
1700 canon->flow.ipv6_flow.smask = flow->ipv6_flow.dmask;
1701 canon->flow.ipv6_flow.dmask = flow->ipv6_flow.smask;
1702 }
1703 if (canon->flow.ipv6_flow.smask > 128)
1704 canon->flow.ipv6_flow.smask = 128;
1705
1706 if (canon->flow.ipv6_flow.dmask > 128)
1707 canon->flow.ipv6_flow.dmask = 128;
1708
1709 if (canon->flow.ipv6_flow.smask == 0)
1710 canon->flow.ipv6_flow.smask = 128;
1711
1712 if (canon->flow.ipv6_flow.dmask == 0)
1713 canon->flow.ipv6_flow.dmask = 128;
1714
1715 } else {
1716 flow->hdr.argus_dsrvl8.qual |= ARGUS_MASKLEN;
1717 flow->hdr.argus_dsrvl8.len++;
1718 canon->flow.ipv6_flow.smask = 128;
1719 canon->flow.ipv6_flow.dmask = 128;
1720 }
1721 break;
1722 }
1723
1724 case ARGUS_TYPE_RARP: {
1725 struct ArgusLegacyRarpFlow *trarp = &flow->lrarp_flow;
1726 struct ArgusRarpFlow *rarp = &canon->flow.rarp_flow;
1727
1728 flow->hdr.subtype = ARGUS_FLOW_ARP;
1729 flow->hdr.argus_dsrvl8.qual = ARGUS_TYPE_RARP;
1730 flow->hdr.argus_dsrvl8.len = 1 + sizeof(*rarp)/4;
1731 rarp->hrd = 1;
1732 rarp->pro = 2048;
1733 rarp->hln = 6;
1734 rarp->pln = 4;
1735 rarp->op = 3;
1736
1737 rarp->arp_tpa = trarp->arp_tpa;
1738 bcopy((char *)&trarp->srceaddr, (char *)&rarp->shaddr, 6);
1739 bcopy((char *)&trarp->tareaddr, (char *)&rarp->dhaddr, 6);
1740 break;
1741 }
1742
1743 case ARGUS_TYPE_ARP: {
1744 struct ArgusLegacyArpFlow *tarp = &flow->larp_flow;
1745 struct ArgusArpFlow *arp = &canon->flow.arp_flow;
1746
1747 flow->hdr.subtype = ARGUS_FLOW_ARP;
1748 flow->hdr.argus_dsrvl8.qual = ARGUS_TYPE_ARP;
1749 flow->hdr.argus_dsrvl8.len = 1 + sizeof(*arp)/4;
1750 arp->hrd = 1;
1751 arp->pro = 2048;
1752 arp->hln = 6;
1753 arp->pln = 4;
1754 arp->op = 1;
1755
1756 arp->arp_spa = (tarp->arp_spa);
1757 arp->arp_tpa = (tarp->arp_tpa);
1758 bcopy((char *)&tarp->etheraddr, (char *)&arp->haddr, 6);
1759 break;
1760 }
1761 case ARGUS_TYPE_ETHER:
1762 bcopy (&flow->mac_flow, &canon->flow.mac_flow, sizeof(canon->flow.mac_flow));
1763 break;
1764
1765 case ARGUS_TYPE_WLAN:
1766 bcopy (&flow->wlan_flow, &canon->flow.wlan_flow, sizeof(canon->flow.wlan_flow));
1767 break;
1768
1769 case ARGUS_TYPE_MPLS:
1770 case ARGUS_TYPE_VLAN:
1771 bcopy ((char *)flow, &canon->flow, cnt);
1772 break;
1773
1774 case ARGUS_TYPE_ISIS:
1775 bcopy (&flow->isis_flow, &canon->flow.isis_flow, sizeof(canon->flow.isis_flow));
1776 break;
1777 }
1778 break;
1779 }
1780
1781 case ARGUS_FLOW_ARP: {
1782 canon->flow.hdr = flow->hdr;
1783
1784 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
1785 case ARGUS_TYPE_RARP: {
1786 struct ArgusRarpFlow *trarp = &flow->flow_un.rarp;
1787 struct ArgusRarpFlow *rarp = &canon->flow.flow_un.rarp;
1788
1789 canon->flow.hdr = flow->hdr;
1790 rarp->hrd = trarp->hrd;
1791 rarp->pro = trarp->pro;
1792 rarp->hln = trarp->hln;
1793 rarp->pln = trarp->pln;
1794 rarp->op = trarp->op;
1795 rarp->arp_tpa = trarp->arp_tpa;
1796 bcopy (&((char *)&trarp->shaddr)[0], &rarp->shaddr, rarp->hln);
1797 bcopy (&((char *)&trarp->shaddr)[rarp->hln], &rarp->dhaddr, rarp->hln);
1798 break;
1799 }
1800
1801 case ARGUS_TYPE_ARP: {
1802 struct ArgusArpFlow *tarp = &flow->flow_un.arp;
1803 struct ArgusArpFlow *arp = &canon->flow.flow_un.arp;
1804
1805 flow->hdr.argus_dsrvl8.len = sizeof(*arp)/4 + 1;
1806 canon->flow.hdr = flow->hdr;
1807
1808 if ((arp->hrd = tarp->hrd) == 0)
1809 arp->hrd = 1;
1810 if ((arp->pro = tarp->pro) == 0)
1811 arp->pro = 2048;
1812 if ((arp->hln = tarp->hln) == 0)
1813 arp->hln = 6;
1814 if ((arp->pln = tarp->pln) == 0)
1815 arp->pln = 4;
1816
1817 arp->op = tarp->op;
1818 arp->arp_spa = tarp->arp_spa;
1819 arp->arp_tpa = tarp->arp_tpa;
1820 bcopy ((char *)&arp->haddr, &arp->haddr, arp->hln);
1821 break;
1822 }
1823
1824 default: {
1825 struct ArgusInterimArpFlow *tarp = &flow->flow_un.iarp;
1826 struct ArgusArpFlow *arp = &canon->flow.flow_un.arp;
1827
1828 flow->hdr.subtype = ARGUS_FLOW_ARP;
1829 flow->hdr.argus_dsrvl8.qual = ARGUS_TYPE_ARP;
1830 flow->hdr.argus_dsrvl8.len = sizeof(*arp)/4 + 1;
1831 arp->hrd = 1;
1832 arp->pro = tarp->pro;
1833 arp->hln = tarp->hln;
1834 arp->pln = tarp->pln;
1835 arp->op = 0;
1836 arp->arp_spa = tarp->arp_spa;
1837 arp->arp_tpa = tarp->arp_tpa;
1838 bcopy ((char *)&arp->haddr, &arp->haddr, arp->hln);
1839 }
1840 }
1841 break;
1842 }
1843
1844 default:
1845 break;
1846 }
1847
1848 bcopy((char *)&flow->hdr, (char *)&canon->flow.hdr, sizeof(flow->hdr));
1849
1850 retn->dsrs[ARGUS_FLOW_INDEX] = (struct ArgusDSRHeader*) &canon->flow;
1851 retn->dsrindex |= (0x01 << ARGUS_FLOW_INDEX);
1852 break;
1853 }
1854
1855 case ARGUS_TRANSPORT_DSR: {
1856 struct ArgusTransportStruct *trans = (struct ArgusTransportStruct *) dsr;
1857
1858 if (cnt >= 12)
1859 trans->hdr.subtype |= (ARGUS_SRCID | ARGUS_SEQ);
1860
1861 // bzero ((char *)&canon->trans, sizeof(struct ArgusTransportStruct));
1862 bcopy((char *)&trans->hdr, (char *)&canon->trans.hdr, 4);
1863
1864 if (trans->hdr.subtype & ARGUS_SRCID) {
1865 switch (trans->hdr.argus_dsrvl8.qual) {
1866 case ARGUS_TYPE_INT: {
1867 canon->trans.srcid.a_un.value = trans->srcid.a_un.value;
1868 break;
1869 }
1870
1871 default:
1872 case ARGUS_TYPE_IPV4: {
1873 canon->trans.srcid.a_un.ipv4 = trans->srcid.a_un.ipv4;
1874 break;
1875 }
1876 case ARGUS_TYPE_IPV6: {
1877 break;
1878 }
1879 case ARGUS_TYPE_ETHER: {
1880 break;
1881 }
1882 case ARGUS_TYPE_STRING: {
1883 bcopy(trans->srcid.a_un.str, canon->trans.srcid.a_un.str, 4);
1884 break;
1885 }
1886 }
1887 }
1888
1889 if (trans->hdr.subtype & ARGUS_SEQ)
1890 canon->trans.seqnum = trans->seqnum;
1891
1892 retn->dsrs[ARGUS_TRANSPORT_INDEX] = (struct ArgusDSRHeader*) &canon->trans;
1893 retn->dsrindex |= (0x01 << ARGUS_TRANSPORT_INDEX);
1894 break;
1895 }
1896
1897 case ARGUS_ENCAPS_DSR: {
1898 struct ArgusEncapsStruct *encaps = (struct ArgusEncapsStruct *) dsr;
1899 struct ArgusEncapsStruct *cncaps = &canon->encaps;
1900
1901 bcopy((char *) encaps, (char *) cncaps, sizeof(*encaps));
1902
1903 retn->dsrs[ARGUS_ENCAPS_INDEX] = &cncaps->hdr;
1904 retn->dsrindex |= (0x01 << ARGUS_ENCAPS_INDEX);
1905 break;
1906 }
1907
1908 case ARGUS_TIME_DSR: {
1909 struct ArgusTimeObject *time = (struct ArgusTimeObject *) dsr;
1910 struct ArgusTimeObject *ctime = (struct ArgusTimeObject *) &canon->time;
1911 int i, num = (time->hdr.argus_dsrvl8.len - 1)/2;
1912
1913 if (subtype & (ARGUS_TIME_SRC_START | ARGUS_TIME_DST_START)) { // 3.0 time bi-directional dsr subtype
1914 unsigned int *tptr = (unsigned int *) (dsr + 1);
1915 int tlen = 2, sindex = -1, tind = 0, cnt = 0;
1916 struct ArgusTime *tstart = NULL;
1917 unsigned int *tval = NULL;
1918
1919 bzero ((char *)ctime, sizeof(*ctime));
1920 ctime->hdr = time->hdr;
1921
1922 for (i = 0; i < 4; i++) {
1923 int stype = (ARGUS_TIME_SRC_START << i);
1924 if (subtype & stype) {
1925 tind |= (ARGUS_TIME_SRC_START << i);
1926 cnt++;
1927 switch(stype) {
1928 case ARGUS_TIME_SRC_START: {
1929 if (tstart == NULL) tstart = &ctime->src.start;
1930 break;
1931 }
1932 case ARGUS_TIME_DST_START: {
1933 if (tstart == NULL) tstart = &ctime->dst.start;
1934 break;
1935 }
1936 }
1937 }
1938 }
1939
1940 if (!(tind & ARGUS_TIME_SRC_START) && (tind & ARGUS_TIME_SRC_END)) {
1941 tind &= ~ARGUS_TIME_SRC_END;
1942 cnt--;
1943 }
1944 if (!(tind & ARGUS_TIME_DST_START) && (tind & ARGUS_TIME_DST_END)) {
1945 tind &= ~ARGUS_TIME_DST_END;
1946 cnt--;
1947 }
1948
1949 // test length against number of objects in the dsr, and correct
1950 // subtype so that it refects use of absolute vs relative.
1951 subtype &= ~(0x07);
1952
1953 if (cnt == num) { // this is an absolute timestamp. each timestamp uses 2 ints.
1954 if (cnt == 1)
1955 subtype |= ARGUS_TIME_ABSOLUTE_TIMESTAMP;
1956 else
1957 subtype |= ARGUS_TIME_ABSOLUTE_RANGE;
1958 } else {
1959 if (cnt < num)
1960 subtype |= ARGUS_TIME_ABSOLUTE_RANGE;
1961 else {
1962 if (cnt == 1)
1963 subtype |= ARGUS_TIME_RELATIVE_TIMESTAMP;
1964 else {
1965 if (time->hdr.argus_dsrvl8.len == (1 + (cnt + 1)))
1966 subtype |= ARGUS_TIME_RELATIVE_RANGE;
1967 else
1968 subtype |= ARGUS_TIME_ABSOLUTE_TIMESTAMP;
1969 }
1970 }
1971 }
1972
1973 time->hdr.subtype = subtype;
1974 ctime->hdr = time->hdr;
1975
1976 sindex = (subtype & ARGUS_TIME_SRC_START) ? 0 : 2;
1977
1978 for (i = 0; i < 4; i++) {
1979 if (subtype & (ARGUS_TIME_SRC_START << i)) {
1980 switch (ARGUS_TIME_SRC_START << i) {
1981 case ARGUS_TIME_SRC_START: {
1982 tval = (unsigned int *)&ctime->src.start;
1983 break;
1984 }
1985 case ARGUS_TIME_SRC_END: {
1986 tval = (unsigned int *)&ctime->src.end;
1987 break;
1988 }
1989 case ARGUS_TIME_DST_START: {
1990 tval = (unsigned int *)&ctime->dst.start;
1991 break;
1992 }
1993 case ARGUS_TIME_DST_END: {
1994 tval = (unsigned int *)&ctime->dst.end;
1995 break;
1996 }
1997 }
1998
1999 if (tval && tlen) {
2000 switch (subtype & 0x07) {
2001 case ARGUS_TIME_ABSOLUTE_RANGE:
2002 case ARGUS_TIME_ABSOLUTE_TIMESTAMP: {
2003 int y;
2004 for (y = 0; y < tlen; y++)
2005 *tval++ = (*(unsigned int *)tptr++);
2006 break;
2007 }
2008
2009 case ARGUS_TIME_RELATIVE_TIMESTAMP:
2010 case ARGUS_TIME_RELATIVE_RANGE:
2011 case ARGUS_TIME_ABSOLUTE_RELATIVE_RANGE: {
2012 int y;
2013 if (i == sindex) {
2014 for (y = 0; y < tlen; y++)
2015 *tval++ = (*(unsigned int *)tptr++);
2016
2017 } else {
2018 struct ArgusTime tbuf, *tvp = &tbuf;
2019 long long stime, secs, usecs;
2020 int rtime = *(int *)tptr++;
2021
2022 stime = (tstart->tv_sec * 1000000LL) + tstart->tv_usec;
2023
2024 stime += rtime;
2025 secs = stime / 1000000LL;
2026 usecs = stime - (secs * 1000000LL);
2027 tvp->tv_sec = secs;
2028 tvp->tv_usec = usecs;
2029
2030 bcopy(tvp, tval, sizeof(*tvp));
2031 }
2032 break;
2033 }
2034 }
2035 }
2036 }
2037 }
2038
2039 if (ctime->src.end.tv_sec == 0) {
2040 ctime->src.end = ctime->src.start;
2041 } else {
2042 long long svalue = (ctime->src.start.tv_sec * 1000000LL);
2043 long long evalue = (ctime->src.end.tv_sec * 1000000LL);
2044 if (ctime->hdr.argus_dsrvl8.qual == ARGUS_TYPE_UTC_NANOSECONDS) {
2045 svalue += (ctime->src.start.tv_usec)/1000;
2046 evalue += (ctime->src.end.tv_usec)/1000;
2047 } else {
2048 svalue += (ctime->src.start.tv_usec);
2049 evalue += (ctime->src.end.tv_usec);
2050 }
2051
2052 if (svalue > evalue) {
2053 struct ArgusTime tbuf, *tvp = &tbuf;
2054 *tvp = ctime->src.start;
2055 ctime->src.start = ctime->src.end;
2056 ctime->src.end = *tvp;
2057 }
2058 }
2059 if (ctime->dst.end.tv_sec == 0) {
2060 if (ctime->dst.start.tv_sec != 0) {
2061 ctime->dst.end = ctime->dst.start;
2062 }
2063 } else {
2064 long long svalue = (ctime->dst.start.tv_sec * 1000000LL);
2065 long long evalue = (ctime->dst.end.tv_sec * 1000000LL);
2066 if (ctime->hdr.argus_dsrvl8.qual == ARGUS_TYPE_UTC_NANOSECONDS) {
2067 svalue += (ctime->dst.start.tv_usec)/1000;
2068 evalue += (ctime->dst.end.tv_usec)/1000;
2069 } else {
2070 svalue += (ctime->dst.start.tv_usec);
2071 evalue += (ctime->dst.end.tv_usec);
2072 }
2073 if (svalue > evalue) {
2074 struct ArgusTime tbuf, *tvp = &tbuf;
2075 *tvp = ctime->dst.start;
2076 ctime->dst.start = ctime->dst.end;
2077 ctime->dst.end = *tvp;
2078 }
2079 }
2080
2081 } else {
2082 bcopy((char *)dsr, (char *)&canon->time, cnt);
2083
2084 switch (subtype & 0x3F) { // subtype set at top of loop
2085 case ARGUS_TIME_ABSOLUTE_TIMESTAMP:
2086 case ARGUS_TIME_ABSOLUTE_RANGE:
2087 break;
2088 case ARGUS_TIME_ABSOLUTE_RELATIVE_RANGE: // end.tv_sec is delta uSec
2089 ctime->src.end.tv_sec = ctime->src.start.tv_sec + (time->src.end.tv_sec / 1000000);
2090 ctime->src.end.tv_usec = ctime->src.start.tv_usec + (time->src.end.tv_sec % 1000000);
2091 if (ctime->src.end.tv_usec > 1000000) {
2092 ctime->src.end.tv_sec++;
2093 ctime->src.end.tv_usec -= 1000000;
2094 }
2095 break;
2096 case ARGUS_TIME_RELATIVE_TIMESTAMP:
2097 break;
2098 case ARGUS_TIME_RELATIVE_RANGE:
2099 break;
2100 }
2101
2102 if (cnt < sizeof(struct ArgusTimeObject))
2103 bzero (&((char *)&canon->time)[cnt], sizeof(struct ArgusTimeObject) - cnt);
2104
2105 canon->time.hdr.subtype &= ~(ARGUS_TIME_MASK);
2106
2107 if (canon->time.src.start.tv_sec)
2108 canon->time.hdr.subtype |= ARGUS_TIME_SRC_START;
2109 if (canon->time.src.end.tv_sec)
2110 canon->time.hdr.subtype |= ARGUS_TIME_SRC_END;
2111
2112 switch (subtype & 0x3F) {
2113 case ARGUS_TIME_ABSOLUTE_TIMESTAMP:
2114 case ARGUS_TIME_ABSOLUTE_RANGE:
2115 case ARGUS_TIME_ABSOLUTE_RELATIVE_RANGE:
2116 if (!(ctime->src.start.tv_sec))
2117 ctime->src.start = ctime->src.end;
2118 if (!(ctime->src.end.tv_sec))
2119 ctime->src.end = ctime->src.start;
2120 break;
2121 }
2122 }
2123
2124 if (ctime->hdr.argus_dsrvl8.qual == ARGUS_TYPE_UTC_NANOSECONDS) {
2125 ctime->hdr.argus_dsrvl8.qual = 0;
2126 ctime->src.start.tv_usec /= 1000;
2127 ctime->src.end.tv_usec /= 1000;
2128 ctime->dst.start.tv_usec /= 1000;
2129 ctime->dst.end.tv_usec /= 1000;
2130 }
2131
2132 if (ctime->src.start.tv_usec > 1000000)
2133 ctime->src.start.tv_usec = 999999;
2134 if (ctime->src.end.tv_usec > 1000000)
2135 ctime->src.end.tv_usec = 999999;
2136
2137 ctime->hdr.argus_dsrvl8.len = (sizeof(*time) + 3)/4;
2138 retn->dsrs[ARGUS_TIME_INDEX] = (struct ArgusDSRHeader*) &ctime->hdr;
2139 retn->dsrindex |= (0x01 << ARGUS_TIME_INDEX);
2140 break;
2141 }
2142
2143 case ARGUS_METER_DSR: {
2144 int offset = 1;
2145 if (subtype & ARGUS_METER_PKTS_BYTES) {
2146 canon->metric.src.appbytes = 0;
2147 canon->metric.dst.appbytes = 0;
2148
2149 switch (dsr->argus_dsrvl8.qual & 0x0F) {
2150 case ARGUS_SRCDST_BYTE:
2151 canon->metric.src.pkts = ((unsigned char *)(dsr + 1))[0];
2152 canon->metric.src.bytes = ((unsigned char *)(dsr + 1))[1];
2153 canon->metric.dst.pkts = ((unsigned char *)(dsr + 1))[2];
2154 canon->metric.dst.bytes = ((unsigned char *)(dsr + 1))[3];
2155 offset++;
2156 break;
2157 case ARGUS_SRCDST_SHORT:
2158 canon->metric.src.pkts = (((unsigned short *)(dsr + 1))[0]);
2159 canon->metric.src.bytes = (((unsigned short *)(dsr + 1))[1]);
2160 canon->metric.dst.pkts = (((unsigned short *)(dsr + 1))[2]);
2161 canon->metric.dst.bytes = (((unsigned short *)(dsr + 1))[3]);
2162 offset += 2;
2163 break;
2164 case ARGUS_SRCDST_INT:
2165 canon->metric.src.pkts = (((unsigned int *)(dsr + 1))[0]);
2166 canon->metric.src.bytes = (((unsigned int *)(dsr + 1))[1]);
2167 canon->metric.dst.pkts = (((unsigned int *)(dsr + 1))[2]);
2168 canon->metric.dst.bytes = (((unsigned int *)(dsr + 1))[3]);
2169 offset += 4;
2170 break;
2171 case ARGUS_SRCDST_LONGLONG:
2172 #if defined(LBL_ALIGN)
2173 bcopy ((char *)(dsr + 1), (char *)&canon->metric.src.pkts, 16);
2174 #else
2175 canon->metric.src.pkts = (((unsigned long long *)(dsr + 1))[0]);
2176 canon->metric.src.bytes = (((unsigned long long *)(dsr + 1))[1]);
2177 #endif
2178 #if defined(LBL_ALIGN)
2179 bcopy ((char *)(dsr + 5), (char *)&canon->metric.dst.pkts, 16);
2180 #else
2181 canon->metric.dst.pkts = (((unsigned long long *)(dsr + 1))[2]);
2182 canon->metric.dst.bytes = (((unsigned long long *)(dsr + 1))[3]);
2183 #endif
2184 offset += 8;
2185 break;
2186 case ARGUS_SRC_SHORT:
2187 canon->metric.src.pkts = (((unsigned short *)(dsr + 1))[0]);
2188 canon->metric.src.bytes = (((unsigned short *)(dsr + 1))[1]);
2189 canon->metric.dst.pkts = 0;
2190 canon->metric.dst.bytes = 0;
2191 offset++;
2192 break;
2193 case ARGUS_SRC_INT:
2194 canon->metric.src.pkts = (((unsigned int *)(dsr + 1))[0]);
2195 canon->metric.src.bytes = (((unsigned int *)(dsr + 1))[1]);
2196 canon->metric.dst.pkts = 0;
2197 canon->metric.dst.bytes = 0;
2198 offset += 2;
2199 break;
2200 case ARGUS_SRC_LONGLONG:
2201 bcopy((char *)(dsr + 1), (char *)&canon->metric.src, 16);
2202 canon->metric.dst.pkts = 0;
2203 canon->metric.dst.bytes = 0;
2204 offset += 4;
2205 break;
2206 case ARGUS_DST_SHORT:
2207 canon->metric.src.pkts = 0;
2208 canon->metric.src.bytes = 0;
2209 canon->metric.dst.pkts = (((unsigned short *)(dsr + 1))[0]);
2210 canon->metric.dst.bytes = (((unsigned short *)(dsr + 1))[1]);
2211 offset++;
2212 break;
2213 case ARGUS_DST_INT:
2214 canon->metric.src.pkts = 0;
2215 canon->metric.src.bytes = 0;
2216 canon->metric.dst.pkts = (((unsigned int *)(dsr + 1))[0]);
2217 canon->metric.dst.bytes = (((unsigned int *)(dsr + 1))[1]);
2218 offset += 2;
2219 break;
2220 case ARGUS_DST_LONGLONG:
2221 canon->metric.src.pkts = 0;
2222 canon->metric.src.bytes = 0;
2223 bcopy((char *)(dsr + 1), (char *)&canon->metric.dst, 16);
2224 offset += 4;
2225 break;
2226 }
2227
2228 } else
2229 if (subtype & ARGUS_METER_PKTS_BYTES_APP) {
2230 switch (dsr->argus_dsrvl8.qual & 0x0F) {
2231 case ARGUS_SRCDST_BYTE:
2232 canon->metric.src.pkts = ((unsigned char *)(dsr + 1))[0];
2233 canon->metric.src.bytes = ((unsigned char *)(dsr + 1))[1];
2234 canon->metric.src.appbytes = ((unsigned char *)(dsr + 1))[2];
2235 canon->metric.dst.pkts = ((unsigned char *)(dsr + 1))[3];
2236 canon->metric.dst.bytes = ((unsigned char *)(dsr + 1))[4];
2237 canon->metric.dst.appbytes = ((unsigned char *)(dsr + 1))[5];
2238 offset++;
2239 break;
2240 case ARGUS_SRCDST_SHORT:
2241 canon->metric.src.pkts = (((unsigned short *)(dsr + 1))[0]);
2242 canon->metric.src.bytes = (((unsigned short *)(dsr + 1))[1]);
2243 canon->metric.src.appbytes = (((unsigned short *)(dsr + 1))[2]);
2244 canon->metric.dst.pkts = (((unsigned short *)(dsr + 1))[3]);
2245 canon->metric.dst.bytes = (((unsigned short *)(dsr + 1))[4]);
2246 canon->metric.dst.appbytes = (((unsigned short *)(dsr + 1))[5]);
2247 offset += 2;
2248 break;
2249 case ARGUS_SRCDST_INT:
2250 canon->metric.src.pkts = (((unsigned int *)(dsr + 1))[0]);
2251 canon->metric.src.bytes = (((unsigned int *)(dsr + 1))[1]);
2252 canon->metric.src.appbytes = (((unsigned int *)(dsr + 1))[2]);
2253 canon->metric.dst.pkts = (((unsigned int *)(dsr + 1))[3]);
2254 canon->metric.dst.bytes = (((unsigned int *)(dsr + 1))[4]);
2255 canon->metric.dst.appbytes = (((unsigned int *)(dsr + 1))[5]);
2256 offset += 4;
2257 break;
2258 case ARGUS_SRCDST_LONGLONG:
2259 #if defined(LBL_ALIGN)
2260 bcopy ((char *)(dsr + 1), (char *)&canon->metric.src.pkts, 48);
2261 #else
2262 canon->metric.src.pkts = (((long long *)(dsr + 1))[0]);
2263 canon->metric.src.bytes = (((long long *)(dsr + 1))[1]);
2264 canon->metric.src.appbytes = (((long long *)(dsr + 1))[2]);
2265 canon->metric.dst.pkts = (((long long *)(dsr + 1))[3]);
2266 canon->metric.dst.bytes = (((long long *)(dsr + 1))[4]);
2267 canon->metric.dst.appbytes = (((long long *)(dsr + 1))[5]);
2268 #endif
2269 offset += 8;
2270 break;
2271 case ARGUS_SRC_BYTE:
2272 canon->metric.src.pkts = (((unsigned char *)(dsr + 1))[0]);
2273 canon->metric.src.bytes = (((unsigned char *)(dsr + 1))[1]);
2274 canon->metric.src.appbytes = (((unsigned char *)(dsr + 1))[2]);
2275 canon->metric.dst.pkts = 0;
2276 canon->metric.dst.bytes = 0;
2277 canon->metric.dst.appbytes = 0;
2278 offset++;
2279 break;
2280 case ARGUS_SRC_SHORT:
2281 canon->metric.src.pkts = (((unsigned short *)(dsr + 1))[0]);
2282 canon->metric.src.bytes = (((unsigned short *)(dsr + 1))[1]);
2283 canon->metric.src.appbytes = (((unsigned short *)(dsr + 1))[2]);
2284 canon->metric.dst.pkts = 0;
2285 canon->metric.dst.bytes = 0;
2286 canon->metric.dst.appbytes = 0;
2287 offset++;
2288 break;
2289 case ARGUS_SRC_INT:
2290 canon->metric.src.pkts = (((unsigned int *)(dsr + 1))[0]);
2291 canon->metric.src.bytes = (((unsigned int *)(dsr + 1))[1]);
2292 canon->metric.src.appbytes = (((unsigned int *)(dsr + 1))[2]);
2293 canon->metric.dst.pkts = 0;
2294 canon->metric.dst.bytes = 0;
2295 canon->metric.dst.appbytes = 0;
2296 offset += 2;
2297 break;
2298 case ARGUS_SRC_LONGLONG:
2299 bcopy((char *)(dsr + 1), (char *)&canon->metric.src, 24);
2300 canon->metric.dst.pkts = 0;
2301 canon->metric.dst.bytes = 0;
2302 canon->metric.dst.appbytes = 0;
2303 offset += 4;
2304 break;
2305 case ARGUS_DST_BYTE:
2306 canon->metric.src.pkts = 0;
2307 canon->metric.src.bytes = 0;
2308 canon->metric.src.appbytes = 0;
2309 canon->metric.dst.pkts = (((unsigned char *)(dsr + 1))[0]);
2310 canon->metric.dst.bytes = (((unsigned char *)(dsr + 1))[1]);
2311 canon->metric.dst.appbytes = (((unsigned char *)(dsr + 1))[2]);
2312 offset++;
2313 break;
2314 case ARGUS_DST_SHORT:
2315 canon->metric.src.pkts = 0;
2316 canon->metric.src.bytes = 0;
2317 canon->metric.src.appbytes = 0;
2318 canon->metric.dst.pkts = (((unsigned short *)(dsr + 1))[0]);
2319 canon->metric.dst.bytes = (((unsigned short *)(dsr + 1))[1]);
2320 canon->metric.dst.appbytes = (((unsigned short *)(dsr + 1))[2]);
2321 offset++;
2322 break;
2323 case ARGUS_DST_INT:
2324 canon->metric.src.pkts = 0;
2325 canon->metric.src.bytes = 0;
2326 canon->metric.src.appbytes = 0;
2327 canon->metric.dst.pkts = (((unsigned int *)(dsr + 1))[0]);
2328 canon->metric.dst.bytes = (((unsigned int *)(dsr + 1))[1]);
2329 canon->metric.dst.appbytes = (((unsigned int *)(dsr + 1))[2]);
2330 offset += 2;
2331 break;
2332 case ARGUS_DST_LONGLONG:
2333 canon->metric.src.pkts = 0;
2334 canon->metric.src.bytes = 0;
2335 canon->metric.src.appbytes = 0;
2336 bcopy((char *)(dsr + 1), (char *)&canon->metric.dst, 24);
2337 offset += 4;
2338 break;
2339 }
2340 }
2341
2342 bcopy((char *)dsr, (char *)&canon->metric.hdr, sizeof(*dsr));
2343 canon->metric.hdr.argus_dsrvl8.len = sizeof(canon->metric)/4;
2344
2345 retn->dsrs[ARGUS_METRIC_INDEX] = (struct ArgusDSRHeader*) &canon->metric;
2346 retn->dsrindex |= (0x01 << ARGUS_METRIC_INDEX);
2347 break;
2348 }
2349
2350 case ARGUS_PSIZE_DSR: {
2351 int i, offset = 0;
2352 switch (dsr->argus_dsrvl8.qual & 0x0F) {
2353 case ARGUS_SRCDST_SHORT:
2354 dsr->subtype |= ARGUS_PSIZE_SRC_MAX_MIN | ARGUS_PSIZE_DST_MAX_MIN;
2355 canon->psize.src.psizemin = (((unsigned short *)(dsr + 1))[0]);
2356 canon->psize.src.psizemax = (((unsigned short *)(dsr + 1))[1]);
2357 canon->psize.dst.psizemin = (((unsigned short *)(dsr + 1))[2]);
2358 canon->psize.dst.psizemax = (((unsigned short *)(dsr + 1))[3]);
2359 offset = 3;
2360 break;
2361
2362 case ARGUS_SRC_SHORT:
2363 dsr->subtype |= ARGUS_PSIZE_SRC_MAX_MIN;
2364 canon->psize.src.psizemin = (((unsigned short *)(dsr + 1))[0]);
2365 canon->psize.src.psizemax = (((unsigned short *)(dsr + 1))[1]);
2366 canon->psize.dst.psizemin = 0;
2367 canon->psize.dst.psizemax = 0;
2368 offset = 2;
2369 break;
2370
2371 case ARGUS_DST_SHORT:
2372 dsr->subtype |= ARGUS_PSIZE_DST_MAX_MIN;
2373 canon->psize.src.psizemin = 0;
2374 canon->psize.src.psizemax = 0;
2375 canon->psize.dst.psizemin = (((unsigned short *)(dsr + 1))[0]);
2376 canon->psize.dst.psizemax = (((unsigned short *)(dsr + 1))[1]);
2377 offset = 2;
2378 break;
2379 }
2380
2381 if (dsr->subtype & ARGUS_PSIZE_HISTO) {
2382 if (dsr->subtype & ARGUS_PSIZE_SRC_MAX_MIN) {
2383 unsigned char *ptr = (unsigned char *)(dsr + offset);
2384 for (i = 0; i < 4; i++) {
2385 unsigned char value = *ptr++;
2386 canon->psize.src.psize[(i*2)] = (value & 0xF0) >> 4;
2387 canon->psize.src.psize[(i*2)+1] = (value & 0x0F);
2388 }
2389 offset++;
2390 } else
2391 bzero(&canon->psize.src.psize, sizeof(canon->psize.src.psize));
2392
2393 if (dsr->subtype & ARGUS_PSIZE_DST_MAX_MIN) {
2394 unsigned char *ptr = (unsigned char *)(dsr + offset);
2395 for (i = 0; i < 4; i++) {
2396 unsigned char value = *ptr++;
2397 canon->psize.dst.psize[(i*2)] = (value & 0xF0) >> 4;
2398 canon->psize.dst.psize[(i*2)+1] = (value & 0x0F);
2399 }
2400 } else
2401 bzero(&canon->psize.dst.psize, sizeof(canon->psize.dst.psize));
2402 }
2403
2404 bcopy((char *)dsr, (char *)&canon->psize.hdr, sizeof(*dsr));
2405 canon->psize.hdr.argus_dsrvl8.len = sizeof(canon->psize)/4;
2406 retn->dsrs[ARGUS_PSIZE_INDEX] = (struct ArgusDSRHeader*) &canon->psize;
2407 retn->dsrindex |= (0x01 << ARGUS_PSIZE_INDEX);
2408 break;
2409 }
2410
2411 case ARGUS_NETWORK_DSR: {
2412 struct ArgusNetworkStruct *net = (struct ArgusNetworkStruct *) dsr;
2413 retn->dsrs[ARGUS_NETWORK_INDEX] = (struct ArgusDSRHeader*) &canon->net;
2414 retn->dsrindex |= (0x01 << ARGUS_NETWORK_INDEX);
2415
2416 switch (subtype) {
2417 case 0:
2418 retn->dsrs[ARGUS_NETWORK_INDEX] = NULL;
2419 retn->dsrindex &= ~(0x01 << ARGUS_NETWORK_INDEX);
2420 break;
2421
2422 case ARGUS_RTP_FLOW: {
2423 struct ArgusRTPObject *rtp = (void *) &net->net_union.rtp;
2424 if (cnt == (sizeof(*rtp) + 4))
2425 bcopy((char *)net, (char *)&canon->net, cnt);
2426 else {
2427 retn->dsrs[ARGUS_NETWORK_INDEX] = NULL;
2428 retn->dsrindex &= ~(0x01 << ARGUS_NETWORK_INDEX);
2429 }
2430 break;
2431 }
2432 case ARGUS_RTCP_FLOW: {
2433 struct ArgusRTCPObject *rtcp = (void *) &net->net_union.rtcp;
2434 if (cnt == (sizeof(*rtcp) + 4))
2435 bcopy((char *)net, (char *)&canon->net, cnt);
2436 else {
2437 retn->dsrs[ARGUS_NETWORK_INDEX] = NULL;
2438 retn->dsrindex &= ~(0x01 << ARGUS_NETWORK_INDEX);
2439 }
2440 break;
2441 }
2442
2443 default:
2444 case ARGUS_NETWORK_SUBTYPE_FRAG: {
2445 bcopy((char *)net, (char *)&canon->net, cnt);
2446 break;
2447 }
2448
2449 case ARGUS_TCP_INIT: {
2450 struct ArgusTCPInitStatus *tcpinit = (void *) &net->net_union.tcpinit;
2451 struct ArgusTCPObject *tcp = (void *) &canon->net.net_union.tcp;
2452 bcopy((char *)&net->hdr, (char *)&canon->net.hdr, sizeof(net->hdr));
2453 memset(tcp, 0, sizeof(*tcp));
2454 tcp->status = tcpinit->status;
2455 tcp->src.seqbase = tcpinit->seqbase;
2456 tcp->options = tcpinit->options;
2457 tcp->src.win = tcpinit->win;
2458 tcp->src.flags = tcpinit->flags;
2459 tcp->src.winshift = tcpinit->winshift;
2460 canon->net.hdr.argus_dsrvl8.len = ((sizeof(*tcp) + 3)/4) + 1;
2461 break;
2462 }
2463 case ARGUS_TCP_STATUS: {
2464 struct ArgusTCPStatus *tcpstatus = (void *) &net->net_union.tcpstatus;
2465 struct ArgusTCPObject *tcp = (void *) &canon->net.net_union.tcp;
2466 bcopy((char *)&net->hdr, (char *)&canon->net.hdr, sizeof(net->hdr));
2467
2468 memset(tcp, 0, sizeof(*tcp));
2469 tcp->status = tcpstatus->status;
2470 tcp->src.flags = tcpstatus->src;
2471 tcp->dst.flags = tcpstatus->dst;
2472
2473 if (!canon->metric.src.pkts) {
2474 tcp->src.flags = 0;
2475 }
2476 if (!canon->metric.dst.pkts) {
2477 tcp->dst.flags = 0;
2478 }
2479 canon->net.hdr.argus_dsrvl8.len = ((sizeof(*tcp) + 3)/4) + 1;
2480 break;
2481 }
2482 case ARGUS_TCP_PERF: {
2483 struct ArgusTCPObject *tcp = (struct ArgusTCPObject *) &canon->net.net_union.tcp;
2484 bcopy((char *)net, (char *)&canon->net, cnt);
2485
2486 if (!canon->metric.src.pkts) {
2487 tcp->src.win = 0;
2488 tcp->src.flags = 0;
2489 }
2490 if (!canon->metric.dst.pkts) {
2491 tcp->dst.win = 0;
2492 tcp->dst.flags = 0;
2493 }
2494 canon->net.hdr.argus_dsrvl8.len = ((sizeof(*tcp) + 3)/4) + 1;
2495 break;
2496 }
2497 }
2498 break;
2499 }
2500
2501 case ARGUS_MAC_DSR: {
2502 struct ArgusMacStruct *mac = (struct ArgusMacStruct *) dsr;
2503
2504 switch (mac->hdr.subtype & 0x3F) {
2505 default:
2506 case ARGUS_TYPE_ETHER: {
2507 bcopy((char *)mac, (char *)&canon->mac, cnt);
2508 break;
2509 }
2510 }
2511 retn->dsrs[ARGUS_MAC_INDEX] = (struct ArgusDSRHeader*) &canon->mac;
2512 retn->dsrindex |= (0x01 << ARGUS_MAC_INDEX);
2513 break;
2514 }
2515
2516 case ARGUS_VLAN_DSR: {
2517 struct ArgusVlanStruct *vlan = (struct ArgusVlanStruct *) dsr;
2518
2519 bcopy((char *)vlan, (char *)&canon->vlan, cnt);
2520 retn->dsrs[ARGUS_VLAN_INDEX] = (struct ArgusDSRHeader*) &canon->vlan;
2521 retn->dsrindex |= (0x01 << ARGUS_VLAN_INDEX);
2522 break;
2523 }
2524
2525 case ARGUS_MPLS_DSR: {
2526 struct ArgusMplsStruct *mpls = (struct ArgusMplsStruct *) dsr;
2527 unsigned int *mlabel = (unsigned int *)(dsr + 1);
2528
2529 // bzero((char *)&canon->mpls, sizeof(*mpls));
2530 bcopy((char *)&mpls->hdr, (char *)&canon->mpls.hdr, 4);
2531 canon->mpls.slabel = *mlabel++;
2532 canon->mpls.dlabel = *mlabel++;
2533 retn->dsrs[ARGUS_MPLS_INDEX] = (struct ArgusDSRHeader*) &canon->mpls;
2534 retn->dsrindex |= (0x01 << ARGUS_MPLS_INDEX);
2535 break;
2536 }
2537
2538 case ARGUS_ICMP_DSR: {
2539 struct ArgusIcmpStruct *icmp = (struct ArgusIcmpStruct *) dsr;
2540 int icmpLen = sizeof(*icmp);
2541
2542 bcopy((char *)icmp, (char *)&canon->icmp, (cnt > icmpLen) ? icmpLen : cnt);
2543 retn->dsrs[ARGUS_ICMP_INDEX] = (struct ArgusDSRHeader*) &canon->icmp;
2544 retn->dsrindex |= (0x01 << ARGUS_ICMP_INDEX);
2545 break;
2546 }
2547
2548 case ARGUS_COR_DSR: {
2549 struct ArgusCorrelateStruct *cor = (struct ArgusCorrelateStruct *) dsr;
2550 int corLen = sizeof(*cor);
2551
2552 bcopy((char *)cor, (char *)&canon->cor, (cnt > corLen) ? corLen : cnt);
2553 retn->dsrs[ARGUS_COR_INDEX] = (struct ArgusDSRHeader*) &canon->cor;
2554 retn->dsrindex |= (0x01 << ARGUS_COR_INDEX);
2555 break;
2556 }
2557
2558 case ARGUS_AGR_DSR: {
2559 struct ArgusOutputAgrStruct *agr = (struct ArgusOutputAgrStruct *) dsr;
2560 int agrLen = sizeof(*agr);
2561
2562 if (agrLen == sizeof(struct ArgusAgrStruct)) {
2563 bcopy (agr, &canon->agr, agrLen);
2564 } else {
2565 canon->agr.hdr = agr->hdr;
2566 canon->agr.hdr.argus_dsrvl8.len = sizeof(struct ArgusAgrStruct)/4;
2567
2568 canon->agr.count = agr->count;
2569 canon->agr.laststartime = agr->laststartime;
2570 canon->agr.lasttime = agr->lasttime;
2571
2572 canon->agr.act.n = agr->act.n;
2573 canon->agr.act.minval = agr->act.minval;
2574 canon->agr.act.meanval = agr->act.meanval;
2575 canon->agr.act.stdev = agr->act.stdev;
2576 canon->agr.act.maxval = agr->act.maxval;
2577
2578 canon->agr.idle.n = agr->idle.n;
2579 canon->agr.idle.minval = agr->idle.minval;
2580 canon->agr.idle.meanval = agr->idle.meanval;
2581 canon->agr.idle.stdev = agr->idle.stdev;
2582 canon->agr.idle.maxval = agr->idle.maxval;
2583
2584 retn->dsrs[ARGUS_AGR_INDEX] = (struct ArgusDSRHeader*) &canon->agr;
2585 retn->dsrindex |= (0x01 << ARGUS_AGR_INDEX);
2586 }
2587 break;
2588 }
2589
2590 case ARGUS_JITTER_DSR: {
2591 #if defined(HAVE_XDR)
2592 struct ArgusJitterStruct *jitter = &canon->jitter;
2593 struct ArgusStatsObject *tjit = (struct ArgusStatsObject *) (dsr + 1);
2594 struct ArgusOutputStatObject *stat;
2595 XDR xdrbuf, *xdrs = &xdrbuf;
2596 unsigned int fdist, i;
2597
2598 jitter->hdr = *dsr;
2599
2600 if (dsr->argus_dsrvl8.qual & ARGUS_SRC_ACTIVE_JITTER) {
2601 stat = &jitter->src.act;
2602 xdrmem_create(xdrs, (char *)tjit, sizeof(*stat), XDR_DECODE);
2603 xdr_int(xdrs, &stat->n);
2604 xdr_float(xdrs, &stat->minval);
2605 xdr_float(xdrs, &stat->meanval);
2606 xdr_float(xdrs, &stat->stdev);
2607 xdr_float(xdrs, &stat->maxval);
2608
2609 switch (jitter->hdr.subtype & (ARGUS_HISTO_EXP | ARGUS_HISTO_LINEAR)) {
2610 case ARGUS_HISTO_EXP: {
2611 unsigned char *ptr = (unsigned char *)&fdist;
2612
2613 xdr_u_int(xdrs, &fdist);
2614 for (i = 0; i < 4; i++) {
2615 unsigned char value = *ptr++;
2616 stat->dist_union.fdist[(i*2)] = (value & 0xF0) >> 4;
2617 stat->dist_union.fdist[(i*2)+1] = (value & 0x0F);
2618 }
2619 tjit = (struct ArgusStatsObject *)((char *)tjit + 6*4);
2620 break;
2621 }
2622 case ARGUS_HISTO_LINEAR: {
2623 struct ArgusHistoObject *histo = (struct ArgusHistoObject *)&tjit->dist_union.linear;
2624 int len = 4;
2625
2626 if (histo->hdr.type == ARGUS_HISTO_DSR) {
2627 bcopy((char *)histo, &stat->dist_union.linear, sizeof (*histo));
2628 if (histo->hdr.argus_dsrvl8.len > sizeof(*histo)/4) {
2629 len = ((histo->hdr.argus_dsrvl8.len - sizeof(*histo)/4) + 1) * 4;
2630 stat->dist_union.linear.data = input->ArgusSrcActDist;
2631 bcopy((char *)&histo->data, (char *)stat->dist_union.linear.data, len);
2632 }
2633 }
2634 tjit = (struct ArgusStatsObject *)((char *)tjit + 6*4);
2635 tjit = (void *)((char *) tjit - 4 + (sizeof(*histo) + (len - 4)));
2636 break;
2637 }
2638
2639 default:
2640 tjit = (struct ArgusStatsObject *)(&tjit->dist_union);
2641 break;
2642 }
2643 } else
2644 bzero((char *)&jitter->src.act, sizeof(jitter->src.act));
2645
2646 if (dsr->argus_dsrvl8.qual & ARGUS_SRC_IDLE_JITTER) {
2647 stat = &jitter->src.idle;
2648 xdrmem_create(xdrs, (char *)tjit, sizeof(*stat), XDR_DECODE);
2649 xdr_int(xdrs, &stat->n);
2650 xdr_float(xdrs, &stat->minval);
2651 xdr_float(xdrs, &stat->meanval);
2652 xdr_float(xdrs, &stat->stdev);
2653 xdr_float(xdrs, &stat->maxval);
2654
2655 switch (jitter->hdr.subtype & (ARGUS_HISTO_EXP | ARGUS_HISTO_LINEAR)) {
2656 case ARGUS_HISTO_EXP: {
2657 unsigned char *ptr = (unsigned char *)&fdist;
2658 xdr_u_int(xdrs, &fdist);
2659 for (i = 0; i < 4; i++) {
2660 unsigned char value = *ptr++;
2661 stat->dist_union.fdist[(i*2)] = (value & 0xF0) >> 4;
2662 stat->dist_union.fdist[(i*2)+1] = (value & 0x0F);
2663 }
2664 tjit = (struct ArgusStatsObject *)((char *)tjit + 6*4);
2665 break;
2666 }
2667 case ARGUS_HISTO_LINEAR: {
2668 struct ArgusHistoObject *histo = (struct ArgusHistoObject *)&tjit->dist_union.linear;
2669 int len = 4;
2670 if (histo->hdr.type == ARGUS_HISTO_DSR) {
2671 bcopy((char *)histo, &stat->dist_union.linear, sizeof (*histo));
2672 if (histo->hdr.argus_dsrvl8.len > sizeof(*histo)/4) {
2673 len = ((histo->hdr.argus_dsrvl8.len - sizeof(*histo)/4) + 1) * 4;
2674 stat->dist_union.linear.data = input->ArgusSrcIdleDist;
2675 bcopy((char *)&histo->data, (char *)stat->dist_union.linear.data, len);
2676 }
2677 }
2678 tjit = (struct ArgusStatsObject *)((char *)tjit + 6*4);
2679 tjit = (void *)((char *) tjit - 4 + (sizeof(*histo) + (len - 4)));
2680 break;
2681 }
2682
2683 default:
2684 tjit = (struct ArgusStatsObject *)(&tjit->dist_union);
2685 break;
2686 }
2687 } else
2688 bzero((char *)&jitter->src.idle, sizeof(jitter->src.idle));
2689
2690 if (dsr->argus_dsrvl8.qual & ARGUS_DST_ACTIVE_JITTER) {
2691 stat = &jitter->dst.act;
2692 xdrmem_create(xdrs, (char *)tjit, sizeof(*stat), XDR_DECODE);
2693 xdr_int(xdrs, &stat->n);
2694 xdr_float(xdrs, &stat->minval);
2695 xdr_float(xdrs, &stat->meanval);
2696 xdr_float(xdrs, &stat->stdev);
2697 xdr_float(xdrs, &stat->maxval);
2698
2699 switch (jitter->hdr.subtype & (ARGUS_HISTO_EXP | ARGUS_HISTO_LINEAR)) {
2700 case ARGUS_HISTO_EXP: {
2701 unsigned char *ptr = (unsigned char *)&fdist;
2702 xdr_u_int(xdrs, &fdist);
2703 for (i = 0; i < 4; i++) {
2704 unsigned char value = *ptr++;
2705 stat->dist_union.fdist[(i*2)] = (value & 0xF0) >> 4;
2706 stat->dist_union.fdist[(i*2)+1] = (value & 0x0F);
2707 }
2708 tjit = (struct ArgusStatsObject *)((char *)tjit + 6*4);
2709 break;
2710 }
2711 case ARGUS_HISTO_LINEAR: {
2712 struct ArgusHistoObject *histo = (struct ArgusHistoObject *)&tjit->dist_union.linear;
2713 int len = 4;
2714 if (histo->hdr.type == ARGUS_HISTO_DSR) {
2715 bcopy((char *)histo, &stat->dist_union.linear, sizeof (*histo));
2716 if (histo->hdr.argus_dsrvl8.len > sizeof(*histo)/4) {
2717 len = ((histo->hdr.argus_dsrvl8.len - sizeof(*histo)/4) + 1) * 4;
2718 stat->dist_union.linear.data = input->ArgusDstActDist;
2719 bcopy((char *)&histo->data, (char *)stat->dist_union.linear.data, len);
2720 }
2721 }
2722 tjit = (struct ArgusStatsObject *)((char *)tjit + 6*4);
2723 tjit = (void *)((char *) tjit - 4 + (sizeof(*histo) + (len - 4)));
2724 break;
2725 }
2726
2727 default:
2728 tjit = (struct ArgusStatsObject *)(&tjit->dist_union);
2729 break;
2730 }
2731 } else
2732 bzero((char *)&jitter->dst.act, sizeof(jitter->dst.act));
2733
2734 if (dsr->argus_dsrvl8.qual & ARGUS_DST_IDLE_JITTER) {
2735 stat = &jitter->dst.idle;
2736 xdrmem_create(xdrs, (char *)tjit, sizeof(*stat), XDR_DECODE);
2737 xdr_int(xdrs, &stat->n);
2738 xdr_float(xdrs, &stat->minval);
2739 xdr_float(xdrs, &stat->meanval);
2740 xdr_float(xdrs, &stat->stdev);
2741 xdr_float(xdrs, &stat->maxval);
2742
2743 switch (jitter->hdr.subtype & (ARGUS_HISTO_EXP | ARGUS_HISTO_LINEAR)) {
2744 case ARGUS_HISTO_EXP: {
2745 unsigned char *ptr = (unsigned char *)&fdist;
2746 xdr_u_int(xdrs, &fdist);
2747 for (i = 0; i < 4; i++) {
2748 unsigned char value = *ptr++;
2749 stat->dist_union.fdist[(i*2)] = (value & 0xF0) >> 4;
2750 stat->dist_union.fdist[(i*2)+1] = (value & 0x0F);
2751 }
2752 tjit = (struct ArgusStatsObject *)((char *)tjit + 6*4);
2753 break;
2754 }
2755 case ARGUS_HISTO_LINEAR: {
2756 struct ArgusHistoObject *histo = (struct ArgusHistoObject *)&tjit->dist_union.linear;
2757 int len = 4;
2758 if (histo->hdr.type == ARGUS_HISTO_DSR) {
2759 bcopy((char *)histo, &stat->dist_union.linear, sizeof (*histo));
2760 if (histo->hdr.argus_dsrvl8.len > sizeof(*histo)/4) {
2761 len = ((histo->hdr.argus_dsrvl8.len - sizeof(*histo)/4) + 1) * 4;
2762 stat->dist_union.linear.data = input->ArgusDstIdleDist;
2763 bcopy((char *)&histo->data, (char *)stat->dist_union.linear.data, len);
2764 }
2765 }
2766 tjit = (struct ArgusStatsObject *)((char *)tjit + 6*4);
2767 tjit = (void *)((char *) tjit - 4 + (sizeof(*histo) + (len - 4)));
2768 break;
2769 }
2770
2771 default:
2772 tjit = (struct ArgusStatsObject *)(&tjit->dist_union);
2773 break;
2774 }
2775 } else
2776 bzero((char *)&jitter->dst.idle, sizeof(jitter->dst.idle));
2777
2778 canon->jitter.hdr.argus_dsrvl8.len = (sizeof(struct ArgusJitterStruct) + 3)/4;
2779 retn->dsrs[ARGUS_JITTER_INDEX] = (struct ArgusDSRHeader*) &canon->jitter;
2780 retn->dsrindex |= (0x01 << ARGUS_JITTER_INDEX);
2781 #endif
2782 break;
2783 }
2784
2785 case ARGUS_IPATTR_DSR: {
2786 struct ArgusIPAttrStruct *attr = (struct ArgusIPAttrStruct *) dsr;
2787 unsigned int *ptr = (unsigned int *)(dsr + 1);
2788
2789 bzero((char *)&canon->attr, sizeof(*attr));
2790 bcopy((char *)&attr->hdr, (char *)&canon->attr.hdr, 4);
2791
2792 if (attr->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_SRC)
2793 *(unsigned int *)&canon->attr.src = *ptr++;
2794
2795 if (attr->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_SRC_OPTIONS)
2796 canon->attr.src.options = *ptr++;
2797
2798 if (attr->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_DST)
2799 *(unsigned int *)&canon->attr.dst = *ptr++;
2800
2801 if (attr->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_DST_OPTIONS)
2802 canon->attr.dst.options = *ptr++;
2803
2804 canon->attr.hdr.argus_dsrvl8.len = (sizeof(struct ArgusIPAttrStruct) + 3)/4;
2805 retn->dsrs[ARGUS_IPATTR_INDEX] = (struct ArgusDSRHeader*) &canon->attr;
2806 retn->dsrindex |= (0x01 << ARGUS_IPATTR_INDEX);
2807 break;
2808 }
2809
2810 case ARGUS_ASN_DSR: {
2811 struct ArgusAsnStruct *asn = (struct ArgusAsnStruct *) dsr;
2812
2813 // bzero((char *)&canon->asn, sizeof(*asn));
2814 bcopy((char *)asn, (char *)&canon->asn, cnt);
2815
2816 canon->asn.hdr.argus_dsrvl8.len = (sizeof(struct ArgusAsnStruct) + 3)/4;
2817 retn->dsrs[ARGUS_ASN_INDEX] = (struct ArgusDSRHeader*) &canon->asn;
2818 retn->dsrindex |= (0x01 << ARGUS_ASN_INDEX);
2819 break;
2820 }
2821
2822 case ARGUS_BEHAVIOR_DSR: {
2823 struct ArgusBehaviorStruct *actor = (struct ArgusBehaviorStruct *) dsr;
2824 bcopy((char *)actor, (char *)&canon->actor, sizeof(*actor));
2825 retn->dsrs[ARGUS_BEHAVIOR_INDEX] = (struct ArgusDSRHeader*) &canon->actor;
2826 retn->dsrindex |= (0x01 << ARGUS_BEHAVIOR_INDEX);
2827 break;
2828 }
2829
2830 case ARGUS_COCODE_DSR: {
2831 struct ArgusCountryCodeStruct *cocode = (struct ArgusCountryCodeStruct *) dsr;
2832 bcopy((char *)cocode, (char *)&canon->cocode, sizeof(*cocode));
2833 retn->dsrs[ARGUS_COCODE_INDEX] = (struct ArgusDSRHeader*) &canon->cocode;
2834 retn->dsrindex |= (0x01 << ARGUS_COCODE_INDEX);
2835 break;
2836 }
2837
2838 case ARGUS_LABEL_DSR: {
2839 struct ArgusLabelStruct *tlabel = (struct ArgusLabelStruct *) dsr;
2840 int llen = ((tlabel->hdr.argus_dsrvl8.len - 1) * 4);
2841
2842 if (tlabel->hdr.argus_dsrvl8.len <= 0) {
2843 retn = NULL;
2844 break;
2845 }
2846 bzero((char *)&canon->label, sizeof(*tlabel));
2847 bzero((char *)label, llen + 1);
2848 bcopy((char *)&tlabel->hdr, (char *)&canon->label.hdr, 4);
2849 canon->label.l_un.label = label;
2850 bcopy((char *)&tlabel->l_un.label, (char *)canon->label.l_un.label, llen);
2851 retn->dsrs[ARGUS_LABEL_INDEX] = (struct ArgusDSRHeader*) &canon->label;
2852 retn->dsrindex |= (0x01 << ARGUS_LABEL_INDEX);
2853 break;
2854 }
2855
2856 case ARGUS_DATA_DSR: {
2857 struct ArgusDataStruct *user = (struct ArgusDataStruct *) dsr;
2858
2859 if (subtype & ARGUS_LEN_16BITS) {
2860 if (user->hdr.argus_dsrvl16.len == 0)
2861 ArgusLog (LOG_ERR, "ArgusGenerateRecordStruct: pre ARGUS_DATA_DSR len is zero");
2862
2863 if (subtype & ARGUS_SRC_DATA) {
2864 bzero(input->ArgusSrcUserData, sizeof(input->ArgusSrcUserData));
2865 retn->dsrs[ARGUS_SRCUSERDATA_INDEX] = (struct ArgusDSRHeader *)input->ArgusSrcUserData;
2866 bcopy (user, retn->dsrs[ARGUS_SRCUSERDATA_INDEX], cnt);
2867 retn->dsrindex |= (0x01 << ARGUS_SRCUSERDATA_INDEX);
2868 } else {
2869 bzero(input->ArgusDstUserData, sizeof(input->ArgusDstUserData));
2870 retn->dsrs[ARGUS_DSTUSERDATA_INDEX] = (struct ArgusDSRHeader *)input->ArgusDstUserData;
2871 bcopy (user, retn->dsrs[ARGUS_DSTUSERDATA_INDEX], cnt);
2872 retn->dsrindex |= (0x01 << ARGUS_DSTUSERDATA_INDEX);
2873 }
2874
2875 } else {
2876 if (user->hdr.argus_dsrvl8.len == 0)
2877 ArgusLog (LOG_ERR, "ArgusGenerateRecordStruct: pre ARGUS_DATA_DSR len is zero");
2878
2879 if (user->hdr.argus_dsrvl8.qual & ARGUS_SRC_DATA) {
2880 bzero(input->ArgusSrcUserData, sizeof(input->ArgusSrcUserData));
2881 retn->dsrs[ARGUS_SRCUSERDATA_INDEX] = (struct ArgusDSRHeader *)input->ArgusSrcUserData;
2882 retn->dsrindex |= (0x01 << ARGUS_SRCUSERDATA_INDEX);
2883 user->hdr.subtype = ARGUS_LEN_16BITS;
2884 user->hdr.subtype |= ARGUS_SRC_DATA;
2885 user->hdr.argus_dsrvl16.len = cnt / 4;
2886 bcopy (user, retn->dsrs[ARGUS_SRCUSERDATA_INDEX], cnt);
2887 } else {
2888 bzero(input->ArgusDstUserData, sizeof(input->ArgusDstUserData));
2889 retn->dsrs[ARGUS_DSTUSERDATA_INDEX] = (struct ArgusDSRHeader *)input->ArgusDstUserData;
2890 retn->dsrindex |= (0x01 << ARGUS_DSTUSERDATA_INDEX);
2891 user->hdr.subtype = ARGUS_LEN_16BITS;
2892 user->hdr.subtype |= ARGUS_DST_DATA;
2893 user->hdr.argus_dsrvl16.len = cnt / 4;
2894 bcopy (user, retn->dsrs[ARGUS_DSTUSERDATA_INDEX], cnt);
2895 }
2896 }
2897
2898 if (subtype & ARGUS_LEN_16BITS) {
2899 if (user->hdr.argus_dsrvl16.len == 0)
2900 ArgusLog (LOG_ERR, "ArgusGenerateRecordStruct: post ARGUS_DATA_DSR len is zero");
2901
2902 } else {
2903 if (user->hdr.argus_dsrvl8.len == 0)
2904 ArgusLog (LOG_ERR, "ArgusGenerateRecordStruct: post ARGUS_DATA_DSR len is zero");
2905 }
2906 break;
2907 }
2908
2909 default:
2910 break;
2911 }
2912
2913 dsr = (struct ArgusDSRHeader *)((char *)dsr + cnt);
2914
2915 } else {
2916 /*
2917 if (retn->dsrs[ARGUS_TIME_INDEX] == NULL)
2918 retn = NULL;
2919 */
2920 break;
2921 }
2922 }
2923
2924 if (parser->ArgusStripFields) {
2925 int x;
2926 for (x = 0; x < ARGUSMAXDSRTYPE; x++) {
2927 if (!(parser->ArgusDSRFields[x])) {
2928 retn->dsrs[x] = NULL;
2929 retn->dsrindex &= ~(0x01 << x);
2930 } else {
2931 switch (x) {
2932 case ARGUS_JITTER_INDEX: {
2933 if (parser->ArgusDSRFields[x] > 1) {
2934 struct ArgusJitterStruct *jitter = &canon->jitter;
2935
2936 jitter->hdr.type = ARGUS_JITTER_DSR;
2937 jitter->hdr.subtype = 0;
2938 jitter->hdr.argus_dsrvl8.qual = (ARGUS_SRC_ACTIVE_JITTER | ARGUS_DST_ACTIVE_JITTER |
2939 ARGUS_SRC_IDLE_JITTER | ARGUS_DST_IDLE_JITTER );
2940 jitter->hdr.argus_dsrvl8.len = sizeof(*jitter) >> 2;
2941
2942 retn->dsrs[ARGUS_JITTER_INDEX] = (struct ArgusDSRHeader*) &canon->jitter;
2943 retn->dsrindex |= (0x01 << ARGUS_JITTER_INDEX);
2944 }
2945 break;
2946 }
2947 }
2948 }
2949 }
2950 }
2951
2952
2953 if (retn != NULL) {
2954 struct ArgusFlow *flow = (struct ArgusFlow *) retn->dsrs[ARGUS_FLOW_INDEX];
2955
2956 if (!(retn->dsrindex & (0x01 << ARGUS_METRIC_INDEX))) {
2957 canon->metric.src.pkts = 0;
2958 canon->metric.src.bytes = 0;
2959 canon->metric.src.appbytes = 0;
2960 canon->metric.dst.pkts = 0;
2961 canon->metric.dst.bytes = 0;
2962 canon->metric.dst.appbytes = 0;
2963 }
2964
2965 if (!retn->dsrs[ARGUS_AGR_INDEX]) {
2966 if ((canon->metric.src.pkts + canon->metric.dst.pkts) > 0) {
2967 struct ArgusAgrStruct *agr = &canon->agr;
2968 double value;
2969
2970 // bzero(agr, sizeof(*agr));
2971 agr->hdr.type = ARGUS_AGR_DSR;
2972 agr->hdr.argus_dsrvl8.qual = 0x01;
2973 agr->hdr.argus_dsrvl8.len = (sizeof(*agr) + 3)/4;
2974 agr->count = 1;
2975 agr->act.minval = 10000000000.0;
2976 agr->idle.minval = 10000000000.0;
2977
2978 if ((parser->ArgusAggregator != NULL) && (parser->ArgusAggregator->RaMetricFetchAlgorithm != NULL)) {
2979 value = parser->ArgusAggregator->RaMetricFetchAlgorithm(retn);
2980 agr->hdr.subtype = parser->ArgusAggregator->ArgusMetricIndex;
2981 } else {
2982 value = ArgusFetchDuration(retn);
2983 agr->hdr.subtype = ARGUSMETRICDURATION;
2984 }
2985
2986 agr->act.maxval = value;
2987 agr->act.minval = value;
2988 agr->act.meanval = value;
2989 agr->act.n = 1;
2990 bzero ((char *)&agr->idle, sizeof(agr->idle));
2991
2992 retn->dsrs[ARGUS_AGR_INDEX] = (struct ArgusDSRHeader *) agr;
2993 retn->dsrindex |= (0x01 << ARGUS_AGR_INDEX);
2994 }
2995 }
2996
2997 // correct for time problems.
2998 // adjust subtype when time values are zero.
2999 // or adjust time where there is not packet activity.
3000 // adjust start and stop times if they are negative.
3001
3002 {
3003 float stime = 0, ltime = 0;
3004 struct ArgusTimeObject *dtime = (struct ArgusTimeObject *)retn->dsrs[ARGUS_TIME_INDEX];
3005
3006 if (dtime != NULL) {
3007 if ((canon->metric.src.pkts > 0) && (canon->metric.dst.pkts > 0)) {
3008
3009 // ok both sides have activity, so the start and end timestamps or src and dst should have a value
3010 // the assumption here is that a seconds time of 0 is incorrect.
3011
3012 if ((canon->metric.src.pkts == 1) && (canon->metric.dst.pkts == 1)) {
3013 if ((dtime->src.start.tv_sec == 0) && (dtime->dst.start.tv_sec != 0)) {
3014 dtime->src.start = dtime->dst.end;
3015 dtime->src.end = dtime->dst.end;
3016 dtime->dst.end = dtime->dst.start;
3017 } else
3018 if ((dtime->src.start.tv_sec != 0) && (dtime->dst.start.tv_sec == 0)) {
3019 dtime->dst.start = dtime->src.end;
3020 dtime->dst.end = dtime->src.end;
3021 dtime->src.end = dtime->src.start;
3022 }
3023
3024 } else {
3025 if ((dtime->src.start.tv_sec == 0) && (dtime->dst.start.tv_sec != 0)) {
3026 dtime->src = dtime->dst;
3027 } else
3028 if ((dtime->src.start.tv_sec != 0) && (dtime->dst.start.tv_sec == 0)) {
3029 dtime->dst = dtime->src;
3030 }
3031
3032 if (canon->metric.src.pkts == 1) {
3033 if ((dtime->src.start.tv_sec != dtime->src.end.tv_sec) ||
3034 (dtime->src.start.tv_sec != dtime->src.end.tv_sec)) {
3035 if ((dtime->src.end.tv_sec == 0) && (dtime->src.start.tv_sec != 0))
3036 dtime->src.end = dtime->src.start;
3037 else
3038 if ((dtime->src.start.tv_sec == 0) && (dtime->src.end.tv_sec != 0))
3039 dtime->src.start = dtime->src.end;
3040 else
3041 dtime->src.end = dtime->src.start;
3042 }
3043 }
3044
3045 if (canon->metric.dst.pkts == 1) {
3046 if ((dtime->dst.start.tv_sec != dtime->dst.end.tv_sec) ||
3047 (dtime->dst.start.tv_sec != dtime->dst.end.tv_sec)) {
3048 if ((dtime->dst.end.tv_sec == 0) && (dtime->dst.start.tv_sec != 0))
3049 dtime->dst.end = dtime->dst.start;
3050 else
3051 if ((dtime->dst.start.tv_sec == 0) && (dtime->dst.end.tv_sec != 0))
3052 dtime->dst.start = dtime->dst.end;
3053 else
3054 dtime->dst.end = dtime->dst.start;
3055 }
3056 }
3057 }
3058 dtime->hdr.subtype |= ARGUS_TIME_MASK;
3059
3060 } else {
3061 if (canon->metric.src.pkts > 0) {
3062 if (dtime->src.start.tv_sec == 0) {
3063 if (dtime->dst.start.tv_sec != 0) {
3064 dtime->src = dtime->dst;
3065 bzero ((char *)&dtime->dst, sizeof(dtime->dst));
3066 dtime->hdr.subtype &= ~(ARGUS_TIME_DST_START | ARGUS_TIME_DST_END);
3067 dtime->hdr.subtype |= (ARGUS_TIME_SRC_START | ARGUS_TIME_SRC_END);
3068 }
3069 }
3070 } else
3071 if (canon->metric.dst.pkts > 0) {
3072 if (dtime->dst.start.tv_sec == 0) {
3073 if (dtime->src.start.tv_sec != 0) {
3074 dtime->dst = dtime->src;
3075 bzero ((char *)&dtime->src, sizeof(dtime->src));
3076 dtime->hdr.subtype &= ~(ARGUS_TIME_SRC_START | ARGUS_TIME_SRC_END);
3077 dtime->hdr.subtype |= (ARGUS_TIME_DST_START | ARGUS_TIME_DST_END);
3078 }
3079 }
3080 }
3081 }
3082
3083 if (!(dtime->hdr.subtype & (ARGUS_TIME_SRC_START | ARGUS_TIME_DST_START))) {
3084 dtime->hdr.subtype &= ~(ARGUS_TIME_MASK);
3085 if (dtime->src.start.tv_sec)
3086 dtime->hdr.subtype |= ARGUS_TIME_SRC_START;
3087 if (dtime->src.end.tv_sec)
3088 dtime->hdr.subtype |= ARGUS_TIME_SRC_END;
3089 if (dtime->dst.start.tv_sec)
3090 dtime->hdr.subtype |= ARGUS_TIME_DST_START;
3091 if (dtime->dst.end.tv_sec)
3092 dtime->hdr.subtype |= ARGUS_TIME_DST_END;
3093 }
3094
3095 if ((dtime->hdr.subtype & ARGUS_TIME_SRC_START) && (dtime->hdr.subtype & ARGUS_TIME_SRC_END)) {
3096 if ((dtime->src.start.tv_sec == dtime->src.end.tv_sec) &&
3097 (dtime->src.start.tv_usec == dtime->src.end.tv_usec))
3098 dtime->hdr.subtype &= ~ARGUS_TIME_SRC_END;
3099 }
3100
3101 if ((dtime->hdr.subtype & ARGUS_TIME_DST_START) && (dtime->hdr.subtype & ARGUS_TIME_DST_END)) {
3102 if ((dtime->dst.start.tv_sec == dtime->dst.end.tv_sec) &&
3103 (dtime->dst.start.tv_usec == dtime->dst.end.tv_usec))
3104 dtime->hdr.subtype &= ~ARGUS_TIME_DST_END;
3105 }
3106
3107 if (canon->metric.src.pkts == 0)
3108 dtime->hdr.subtype &= ~(ARGUS_TIME_SRC_START | ARGUS_TIME_SRC_END);
3109
3110 if (canon->metric.dst.pkts == 0)
3111 dtime->hdr.subtype &= ~(ARGUS_TIME_DST_START | ARGUS_TIME_DST_END);
3112
3113 if ((dtime->src.start.tv_sec != 0) && (dtime->src.end.tv_sec == 0))
3114 dtime->src.end = dtime->src.start;
3115 if ((dtime->dst.start.tv_sec != 0) && (dtime->dst.end.tv_sec == 0))
3116 dtime->dst.end = dtime->dst.start;
3117
3118 stime = RaGetFloatSrcDuration(retn);
3119 ltime = RaGetFloatDstDuration(retn);
3120
3121 if (!(stime >= 0) || (!(ltime >= 0))) {
3122 struct timeval tvbuf, *tvp = &tvbuf;
3123 if (stime < 0) {
3124 tvp->tv_sec = dtime->src.start.tv_sec;
3125 tvp->tv_usec = dtime->src.start.tv_usec;
3126 dtime->src.start = dtime->src.end;
3127 dtime->src.end.tv_sec = tvp->tv_sec;
3128 dtime->src.end.tv_usec = tvp->tv_usec;
3129 stime = RaGetFloatSrcDuration(retn);
3130 }
3131 if (ltime < 0) {
3132 tvp->tv_sec = dtime->dst.start.tv_sec;
3133 tvp->tv_usec = dtime->dst.start.tv_usec;
3134 dtime->dst.start = dtime->src.end;
3135 dtime->dst.end.tv_sec = tvp->tv_sec;
3136 dtime->dst.end.tv_usec = tvp->tv_usec;
3137 ltime = RaGetFloatSrcDuration(retn);
3138 }
3139 }
3140
3141 if ((stime > 0) && (canon->metric.src.pkts == 0)) {
3142 if ((ltime == 0) && (canon->metric.dst.pkts > 0)) {
3143 dtime->dst = dtime->src;
3144 bzero(&dtime->src, sizeof(dtime->src));
3145 dtime->hdr.subtype &= ~(ARGUS_TIME_SRC_START | ARGUS_TIME_SRC_END);
3146 }
3147 }
3148 if ((ltime > 0) && (canon->metric.dst.pkts == 0)) {
3149 if ((stime == 0) && (canon->metric.src.pkts > 0)) {
3150 dtime->src = dtime->dst;
3151 bzero(&dtime->dst, sizeof(dtime->dst));
3152 dtime->hdr.subtype &= ~(ARGUS_TIME_DST_START | ARGUS_TIME_DST_END);
3153 }
3154 }
3155 if ((canon->metric.src.pkts + canon->metric.dst.pkts) == 1) {
3156 if ((canon->metric.src.pkts == 1) && ((stime = RaGetFloatSrcDuration(retn)) != 0)) {
3157 if (retn->dsrs[ARGUS_ICMP_INDEX] == NULL)
3158 dtime->src.start = dtime->src.end;
3159 } else
3160 if ((canon->metric.dst.pkts == 1) && ((ltime = RaGetFloatDstDuration(retn)) != 0)) {
3161 dtime->dst.start = dtime->dst.end;
3162 }
3163 }
3164 }
3165 }
3166
3167 retn->dur = RaGetFloatDuration(retn);
3168
3169 if (!((seconds = RaGetFloatSrcDuration(retn)) > 0))
3170 seconds = retn->dur;
3171
3172 if (seconds > 0) {
3173 long long pkts = canon->metric.src.pkts;
3174 if (pkts > 1) {
3175 long long bppkts = canon->metric.src.bytes / pkts;
3176 retn->srate = (float)((pkts - 1) * 1.0) / seconds;
3177 retn->sload = (float)((canon->metric.src.bytes - bppkts) * 8.0) / seconds;
3178 }
3179 }
3180
3181 if (!((seconds = RaGetFloatDstDuration(retn)) > 0))
3182 seconds = retn->dur;
3183
3184 if (seconds > 0) {
3185 long long pkts = canon->metric.dst.pkts;
3186 if (pkts > 1) {
3187 long long bppkts = canon->metric.dst.bytes / pkts;
3188 retn->drate = (float)((pkts - 1) * 1.0) / seconds;
3189 retn->dload = (float)((canon->metric.dst.bytes - bppkts) * 8.0) / seconds;
3190 }
3191 }
3192
3193 retn->offset = input->offset;
3194
3195 if (flow != NULL) {
3196 switch (canon->flow.hdr.subtype & 0x3F) {
3197 case ARGUS_FLOW_LAYER_3_MATRIX:
3198 case ARGUS_FLOW_CLASSIC5TUPLE: {
3199 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
3200 case ARGUS_TYPE_IPV4: {
3201 if (parser->ArgusPerformCorrection) {
3202 switch (canon->flow.ip_flow.ip_p) {
3203 case IPPROTO_TCP: {
3204 struct ArgusTCPStatus *tcp = (struct ArgusTCPStatus *) &canon->net.net_union.tcpstatus;
3205 char TcpShouldReverse = 0;
3206
3207 if (!(status & ARGUS_DIRECTION)) {
3208 if ((tcp->status & ARGUS_SAW_SYN) || (tcp->status & ARGUS_SAW_SYN_SENT)) {
3209 if (!(tcp->status & ARGUS_SAW_SYN) && (tcp->status & ARGUS_SAW_SYN_SENT)) {
3210 switch (canon->net.hdr.subtype) {
3211 case ARGUS_TCP_INIT: {
3212 struct ArgusTCPInitStatus *tcp = (struct ArgusTCPInitStatus *) &canon->net.net_union.tcp;
3213 if (tcp->flags & TH_SYN)
3214 TcpShouldReverse = 1;
3215 break;
3216 }
3217 case ARGUS_TCP_STATUS: {
3218 struct ArgusTCPStatus *tcp = (struct ArgusTCPStatus *) &canon->net.net_union.tcp;
3219
3220 if ((tcp->status & ARGUS_SAW_SYN_SENT) && ((tcp->status & ARGUS_CON_ESTABLISHED) || (tcp->status & ARGUS_NORMAL_CLOSE) || (tcp->status & ARGUS_FIN) || (tcp->status & ARGUS_FIN_ACK)))
3221 TcpShouldReverse = 1;
3222
3223 if ((tcp->src & TH_SYN) && !(tcp->dst & TH_RST)) {
3224 if ((canon->metric.src.pkts > 5) && (canon->metric.dst.pkts > 5)) {
3225 TcpShouldReverse = 1;
3226 } else {
3227 if (canon->metric.src.pkts && (canon->metric.dst.pkts == 0))
3228 if ((tcp->src & TH_SYN) && (tcp->src & TH_FIN))
3229 if ((canon->metric.src.bytes / canon->metric.src.pkts) > 60)
3230 TcpShouldReverse = 1;
3231 }
3232 }
3233 break;
3234 }
3235 case ARGUS_TCP_PERF: {
3236 struct ArgusTCPObject *tcp = (struct ArgusTCPObject *) &canon->net.net_union.tcp;
3237 if ((tcp->status & ARGUS_SAW_SYN_SENT) &&
3238 ((tcp->status & ARGUS_CON_ESTABLISHED) ||
3239 (tcp->status & ARGUS_NORMAL_CLOSE) ||
3240 (tcp->status & ARGUS_FIN) ||
3241 (tcp->status & ARGUS_FIN_ACK)))
3242 TcpShouldReverse = 1;
3243
3244 if ((tcp->src.flags & TH_SYN) && !(tcp->dst.flags & TH_RST)) {
3245 if ((canon->metric.src.pkts > 5) && (canon->metric.dst.pkts > 5)) {
3246 TcpShouldReverse = 1;
3247 } else {
3248 if (canon->metric.src.pkts && (canon->metric.dst.pkts == 0))
3249 if ((tcp->src.flags & TH_SYN) && (tcp->src.flags & TH_FIN))
3250 if ((canon->metric.src.bytes / canon->metric.src.pkts) > 60)
3251 TcpShouldReverse = 1;
3252 }
3253 }
3254 break;
3255 }
3256 }
3257 }
3258 #define TCPPORT_FTP_DATA 20
3259 } else {
3260 if ((((flow->ip_flow.sport <= IPPORT_RESERVED) &&
3261 (flow->ip_flow.dport > IPPORT_RESERVED)) &&
3262 (flow->ip_flow.sport != TCPPORT_FTP_DATA)) && !(parser->nflag)) {
3263 u_int sfnd = 0, i;
3264 extern struct hnamemem tporttable[];
3265 struct hnamemem *tp;
3266 i = flow->ip_flow.sport;
3267 for (tp = &tporttable[i % (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
3268 if (tp->addr == i)
3269 sfnd = 1;
3270
3271 if (sfnd)
3272 TcpShouldReverse = 1;
3273 }
3274 }
3275 }
3276
3277 if (TcpShouldReverse) {
3278 ArgusReverseRecord (retn);
3279 tcp->status |= ARGUS_DIRECTION;
3280 flow->hdr.argus_dsrvl8.qual |= ARGUS_DIRECTION;
3281 }
3282 break;
3283 }
3284
3285 case IPPROTO_ICMP: {
3286 if (status & ARGUS_DIRECTION) {
3287 if (canon->metric.src.pkts && !canon->metric.dst.pkts) {
3288 struct ArgusICMPObject *icmp = &canon->net.net_union.icmp;
3289 canon->flow.icmp_flow.type = icmp->icmp_type;
3290 canon->flow.icmp_flow.code = icmp->icmp_code;
3291
3292 switch (icmp->icmp_type) {
3293 case ICMP_MASKREPLY:
3294 case ICMP_ECHOREPLY:
3295 case ICMP_TSTAMPREPLY:
3296 case ICMP_IREQREPLY: {
3297 ArgusReverseRecord (retn);
3298 break;
3299 }
3300 }
3301 }
3302 }
3303 break;
3304 }
3305 case IPPROTO_UDP: {
3306 struct ArgusNetworkStruct *net;
3307 if ((net = (struct ArgusNetworkStruct *) retn->dsrs[ARGUS_NETWORK_INDEX]) != NULL) {
3308 switch (net->hdr.subtype) {
3309 case ARGUS_RTP_FLOW: {
3310 break;
3311 }
3312 case ARGUS_RTCP_FLOW:
3313 break;
3314 }
3315 }
3316
3317 // if (!(IN_MULTICAST(flow->ip_flow.ip_dst) || (INADDR_BROADCAST == flow->ip_flow.ip_dst))) {
3318 // if ((flow->ip_flow.sport <= IPPORT_RESERVED) || (flow->ip_flow.dport <= IPPORT_RESERVED)) {
3319 // if ((flow->ip_flow.sport <= IPPORT_RESERVED) && (flow->ip_flow.dport <= IPPORT_RESERVED)) {
3320 // if (flow->ip_flow.sport < flow->ip_flow.dport) {
3321 // ArgusReverseRecord (retn);
3322 // }
3323 // } else {
3324 // if (flow->ip_flow.sport <= IPPORT_RESERVED)
3325 // ArgusReverseRecord (retn);
3326 // }
3327 // }
3328 // }
3329
3330 break;
3331 }
3332 }
3333 }
3334 break;
3335 }
3336
3337 case ARGUS_TYPE_IPV6: {
3338 if (parser->ArgusPerformCorrection) {
3339 switch (canon->flow.ipv6_flow.ip_p) {
3340 case IPPROTO_ICMP: {
3341 struct ArgusICMPv6Flow *icmpv6 = (struct ArgusICMPv6Flow *) &canon->flow;
3342 if (!(icmpv6->type) && !(icmpv6->type)) {
3343 struct ArgusICMPObject *icmp = &canon->net.net_union.icmp;
3344 icmpv6->type = icmp->icmp_type;
3345 icmpv6->code = icmp->icmp_code;
3346 }
3347 break;
3348 }
3349 case IPPROTO_UDP: {
3350 struct ArgusNetworkStruct *net;
3351 if ((net = (struct ArgusNetworkStruct *) retn->dsrs[ARGUS_NETWORK_INDEX]) != NULL) {
3352 switch (net->hdr.subtype) {
3353 case ARGUS_RTP_FLOW: {
3354 break;
3355 }
3356
3357 case ARGUS_RTCP_FLOW: {
3358 if (flow->ipv6_flow.sport > flow->ipv6_flow.dport) {
3359 ArgusReverse = 1;
3360 status |= ARGUS_DIRECTION;
3361 }
3362 break;
3363 }
3364 }
3365 }
3366 break;
3367 }
3368 }
3369 }
3370 break;
3371 }
3372
3373 case ARGUS_TYPE_RARP:
3374 case ARGUS_TYPE_ARP: {
3375 if (flow->hdr.subtype & ARGUS_REVERSE) {
3376 struct ArgusFlow flowbuf;
3377 bcopy(flow, &flowbuf, sizeof(flowbuf));
3378 ArgusReverseRecord (retn);
3379 bcopy(&flowbuf, flow, sizeof(flowbuf));
3380 }
3381 break;
3382 }
3383 }
3384 break;
3385 }
3386
3387 case ARGUS_FLOW_ARP: {
3388 struct ArgusFlow *flow = (struct ArgusFlow *) retn->dsrs[ARGUS_FLOW_INDEX];
3389
3390 if (flow->hdr.subtype & ARGUS_REVERSE) {
3391 struct ArgusFlow flowbuf;
3392 bcopy(flow, &flowbuf, sizeof(flowbuf));
3393 ArgusReverseRecord (retn);
3394 bcopy(&flowbuf, flow, sizeof(flowbuf));
3395 }
3396 break;
3397 }
3398 }
3399
3400 if (flow->hdr.subtype & ARGUS_REVERSE)
3401 flow->hdr.subtype &= ~ARGUS_REVERSE;
3402 }
3403 }
3404
3405 if (retn != NULL) {
3406 if ((ArgusFetchPktsCount(retn) > 1000.0) && (ArgusFetchDuration(retn) == 0.0)) {
3407 retn->hdr.cause = ARGUS_ERROR;
3408 canon->metric.src.pkts = 0;
3409 canon->metric.src.bytes = 0;
3410 canon->metric.src.appbytes = 0;
3411 canon->metric.dst.pkts = 0;
3412 canon->metric.dst.bytes = 0;
3413 canon->metric.dst.appbytes = 0;
3414 } else
3415 if (retn->hdr.len < 1)
3416 retn = NULL;
3417 }
3418
3419 if ((parser != NULL) && (retn != NULL)) {
3420 struct ArgusNetworkStruct *net = &canon->net;
3421
3422 switch (net->hdr.subtype) {
3423 case ARGUS_TCP_INIT:
3424 break;
3425
3426 case ARGUS_TCP_STATUS:
3427 break;
3428
3429 case ARGUS_TCP_PERF:
3430 break;
3431
3432 case ARGUS_RTP_FLOW: {
3433 if ((canon->flow.ip_flow.ip_p != IPPROTO_UDP) ||
3434 (((canon->metric.src.pkts < 5)) && ((canon->metric.dst.pkts < 5))))
3435 retn->dsrs[ARGUS_NETWORK_INDEX] = NULL;
3436 break;
3437 }
3438 }
3439
3440 if (ArgusReverse && (status & ARGUS_DIRECTION))
3441 ArgusReverseRecord (retn);
3442
3443 retn->pcr = ArgusFetchAppByteRatio(retn);
3444
3445 }
3446
3447 break;
3448 }
3449
3450 default:
3451 retn = NULL;
3452 break;
3453 }
3454 if (retn != NULL)
3455 retn->status |= ARGUS_RECORD_MODIFIED;
3456 }
3457
3458 return (retn);
3459 }
3460
3461
3462 struct ArgusRecordStruct *
ArgusCopyRecordStruct(struct ArgusRecordStruct * rec)3463 ArgusCopyRecordStruct (struct ArgusRecordStruct *rec)
3464 {
3465 struct ArgusRecordStruct *retn = NULL;
3466
3467 if (rec) {
3468 if ((retn = (struct ArgusRecordStruct *) ArgusCalloc (1, sizeof(*retn))) != NULL) {
3469 retn->status = rec->status;
3470 retn->input = rec->input;
3471 bcopy ((char *)&rec->hdr, (char *)&retn->hdr, sizeof (rec->hdr));
3472
3473 switch (rec->hdr.type & 0xF0) {
3474 case ARGUS_MAR: {
3475 struct ArgusRecord *ns = (struct ArgusRecord *) rec->dsrs[0];
3476 int len = ns->hdr.len * 4;
3477
3478 if ((retn->dsrs[0] = ArgusCalloc(1, len)) != NULL) {
3479 bcopy((char *)ns, (char *)retn->dsrs[0], len);
3480 } else {
3481 ArgusFree(retn);
3482 retn = NULL;
3483 }
3484 break;
3485 }
3486
3487 case ARGUS_EVENT:
3488 case ARGUS_NETFLOW:
3489 case ARGUS_FAR: {
3490 if ((retn->dsrindex = rec->dsrindex)) {
3491 int i;
3492 for (i = 0; i < ARGUSMAXDSRTYPE; i++) {
3493 struct ArgusDSRHeader *dsr;
3494 if ((dsr = rec->dsrs[i]) != NULL) {
3495 if (dsr->type) {
3496 int len = (((dsr->type & ARGUS_IMMEDIATE_DATA) ? 1 :
3497 ((dsr->subtype & ARGUS_LEN_16BITS) ? dsr->argus_dsrvl16.len :
3498 dsr->argus_dsrvl8.len)));
3499 if (len == 0)
3500 ArgusLog (LOG_ERR, "ArgusCopyRecordStruct: dsr %d len is zero\n", i);
3501
3502 switch (i) {
3503 case ARGUS_TRANSPORT_INDEX:
3504 case ARGUS_TIME_INDEX:
3505 case ARGUS_METRIC_INDEX:
3506 case ARGUS_PSIZE_INDEX:
3507 case ARGUS_IPATTR_INDEX:
3508 case ARGUS_ICMP_INDEX:
3509 case ARGUS_ENCAPS_INDEX:
3510 case ARGUS_MAC_INDEX:
3511 case ARGUS_VLAN_INDEX:
3512 case ARGUS_MPLS_INDEX:
3513 case ARGUS_ASN_INDEX:
3514 case ARGUS_AGR_INDEX:
3515 case ARGUS_BEHAVIOR_INDEX:
3516 case ARGUS_COCODE_INDEX:
3517 case ARGUS_COR_INDEX: {
3518 if ((retn->dsrs[i] = ArgusCalloc(1, len * 4)) == NULL)
3519 ArgusLog (LOG_ERR, "ArgusCopyRecordStruct: ArgusCalloc error %s\n", strerror(errno));
3520 bcopy((char *)rec->dsrs[i], (char *)retn->dsrs[i], len * 4);
3521 break;
3522 }
3523
3524 case ARGUS_FLOW_INDEX: {
3525 if ((retn->dsrs[i] = ArgusCalloc(1, sizeof(struct ArgusFlow))) == NULL)
3526 ArgusLog (LOG_ERR, "ArgusCopyRecordStruct: ArgusCalloc error %s\n", strerror(errno));
3527 bcopy((char *)rec->dsrs[i], (char *)retn->dsrs[i], len * 4);
3528 break;
3529 }
3530
3531 case ARGUS_NETWORK_INDEX: {
3532 struct ArgusNetworkStruct *net = (struct ArgusNetworkStruct *) dsr;
3533 switch (net->hdr.subtype) {
3534 case ARGUS_TCP_INIT:
3535 case ARGUS_TCP_STATUS:
3536 case ARGUS_TCP_PERF: {
3537 if ((retn->dsrs[i] = ArgusCalloc(1, sizeof(struct ArgusTCPObject) + 4)) == NULL)
3538 ArgusLog (LOG_ERR, "ArgusCopyRecordStruct: ArgusCalloc error %s\n", strerror(errno));
3539 break;
3540 }
3541 default: {
3542 if ((retn->dsrs[i] = ArgusCalloc(1, len * 4)) == NULL)
3543 ArgusLog (LOG_ERR, "ArgusCopyRecordStruct: ArgusCalloc error %s\n", strerror(errno));
3544 break;
3545 }
3546 }
3547 bcopy((char *)rec->dsrs[i], (char *)retn->dsrs[i], len * 4);
3548 break;
3549 }
3550
3551 case ARGUS_JITTER_INDEX: {
3552 struct ArgusJitterStruct *tjit, *jitter = (void *)rec->dsrs[i];
3553
3554 if ((retn->dsrs[i] = ArgusCalloc(1, len * 4)) == NULL)
3555 ArgusLog (LOG_ERR, "ArgusCopyRecordStruct: ArgusCalloc error %s\n", strerror(errno));
3556
3557 tjit = (void *)retn->dsrs[i];
3558 bcopy((char *)rec->dsrs[i], (char *)tjit, len * 4);
3559
3560 if (jitter->hdr.subtype & ARGUS_HISTO_LINEAR) {
3561 struct ArgusHistoObject *histo = &jitter->src.act.dist_union.linear;
3562 struct ArgusHistoObject *thisto = &tjit->src.act.dist_union.linear;
3563
3564 if (histo->hdr.type == ARGUS_HISTO_DSR)
3565 if (histo->hdr.argus_dsrvl8.len > sizeof(histo)/4) {
3566 int len = ((histo->hdr.argus_dsrvl8.len - sizeof(histo)/4) + 1) * 4;
3567 thisto->data = ArgusCalloc(1, len);
3568 bcopy((char *)histo->data, thisto->data, len);
3569 }
3570
3571 histo = &jitter->src.idle.dist_union.linear;
3572 thisto = &tjit->src.idle.dist_union.linear;
3573 if (histo->hdr.type == ARGUS_HISTO_DSR)
3574 if (histo->hdr.argus_dsrvl8.len > sizeof(histo)/4) {
3575 int len = ((histo->hdr.argus_dsrvl8.len - sizeof(histo)/4) + 1) * 4;
3576 thisto->data = ArgusCalloc(1, len);
3577 bcopy((char *)histo->data, thisto->data, len);
3578 }
3579
3580 histo = &jitter->dst.act.dist_union.linear;
3581 thisto = &tjit->dst.act.dist_union.linear;
3582 if (histo->hdr.type == ARGUS_HISTO_DSR)
3583 if (histo->hdr.argus_dsrvl8.len > sizeof(histo)/4) {
3584 int len = ((histo->hdr.argus_dsrvl8.len - sizeof(histo)/4) + 1) * 4;
3585 thisto->data = ArgusCalloc(1, len);
3586 bcopy((char *)histo->data, thisto->data, len);
3587 }
3588
3589 histo = &jitter->dst.idle.dist_union.linear;
3590 thisto = &tjit->dst.idle.dist_union.linear;
3591 if (histo->hdr.type == ARGUS_HISTO_DSR)
3592 if (histo->hdr.argus_dsrvl8.len > sizeof(histo)/4) {
3593 int len = ((histo->hdr.argus_dsrvl8.len - sizeof(histo)/4) + 1) * 4;
3594 thisto->data = ArgusCalloc(1, len);
3595 bcopy((char *)histo->data, thisto->data, len);
3596 }
3597 }
3598 break;
3599 }
3600
3601 case ARGUS_LABEL_INDEX: {
3602 struct ArgusLabelStruct *label = (void *)rec->dsrs[i];
3603 int slen;
3604
3605 if ((retn->dsrs[i] = ArgusCalloc(1, sizeof(struct ArgusLabelStruct))) == NULL)
3606 ArgusLog (LOG_ERR, "ArgusCopyRecordStruct: ArgusCalloc error %s\n", strerror(errno));
3607
3608 bcopy((char *)rec->dsrs[i], (char *)retn->dsrs[i], sizeof(struct ArgusLabelStruct));
3609
3610 if (label->l_un.label != NULL) {
3611 struct ArgusLabelStruct *tlabel = (void *)retn->dsrs[i];
3612
3613 if ((slen = strlen(label->l_un.label)) > 0) {
3614 int blen = (label->hdr.argus_dsrvl8.len - 1) * 4;
3615
3616 tlabel->l_un.label = calloc(1, blen + 1);
3617 bcopy((char *)label->l_un.label, tlabel->l_un.label, (blen > slen) ? slen : blen);
3618
3619 } else
3620 tlabel->l_un.label = NULL;
3621 }
3622 break;
3623 }
3624
3625 case ARGUS_SRCUSERDATA_INDEX:
3626 case ARGUS_DSTUSERDATA_INDEX: {
3627 struct ArgusDataStruct *user = (struct ArgusDataStruct *) rec->dsrs[i];
3628 len = ((user->size + 8) + 3) / 4;
3629 if ((retn->dsrs[i] = (struct ArgusDSRHeader *) ArgusCalloc(1, len * 4)) == NULL)
3630 ArgusLog (LOG_ERR, "ArgusCopyRecordStruct: ArgusCalloc error %s\n", strerror(errno));
3631
3632 bcopy (rec->dsrs[i], retn->dsrs[i], len * 4);
3633 break;
3634 }
3635 }
3636 }
3637 }
3638 }
3639 }
3640
3641 retn->dur = rec->dur;
3642 retn->srate = rec->srate;
3643 retn->drate = rec->drate;
3644 retn->sload = rec->sload;
3645 retn->dload = rec->dload;
3646 retn->sploss = ArgusFetchPercentSrcLoss(retn);
3647 retn->dploss = ArgusFetchPercentDstLoss(retn);
3648 retn->pcr = ArgusFetchAppByteRatio(retn);
3649 retn->bins = NULL;
3650 retn->htblhdr = NULL;
3651 retn->nsq = NULL;
3652 break;
3653 }
3654 }
3655
3656 if (retn->hdr.type & (ARGUS_FAR | ARGUS_NETFLOW))
3657 retn->rank = rec->rank;
3658
3659 if (rec->correlates) {
3660 int i;
3661
3662 if ((retn->correlates = (void *) ArgusCalloc (1, sizeof(*rec->correlates))) == NULL)
3663 ArgusLog (LOG_ERR, "ArgusCopyRecordStruct: ArgusCalloc error %s\n", strerror(errno));
3664 if ((retn->correlates->array = (void *) ArgusCalloc (rec->correlates->size, sizeof(rec))) == NULL)
3665 ArgusLog (LOG_ERR, "ArgusCopyRecordStruct: ArgusCalloc error %s\n", strerror(errno));
3666
3667 retn->correlates->count = rec->correlates->count;
3668 retn->correlates->size = rec->correlates->size;
3669
3670 for (i = 0; i < rec->correlates->count; i++)
3671 if (rec->correlates->array[i] != NULL)
3672 retn->correlates->array[i] = ArgusCopyRecordStruct(rec->correlates->array[i]);
3673 }
3674
3675 retn->timeout = rec->timeout;
3676
3677 } else
3678 ArgusLog (LOG_ERR, "ArgusCopyRecordStruct: ArgusCalloc error %s\n", strerror(errno));
3679
3680 #ifdef ARGUSDEBUG
3681 ArgusDebug (9, "ArgusCopyRecordStruct (%p) retn %p\n", rec, retn);
3682 #endif
3683 } else {
3684 #ifdef ARGUSDEBUG
3685 ArgusDebug (9, "ArgusCopyRecordStruct (%p) retn %p\n", rec, retn);
3686 #endif
3687 }
3688
3689 return (retn);
3690 }
3691
3692
3693 void
ArgusDeleteRecordStruct(struct ArgusParserStruct * parser,struct ArgusRecordStruct * ns)3694 ArgusDeleteRecordStruct (struct ArgusParserStruct *parser, struct ArgusRecordStruct *ns)
3695 {
3696 struct ArgusRecordStruct *tsns = NULL;
3697 int i;
3698
3699 if (ns != NULL) {
3700 if (ns->qhdr.queue != NULL)
3701 ArgusRemoveFromQueue(ns->qhdr.queue, &ns->qhdr, ARGUS_LOCK);
3702
3703 if (ns->disp.str)
3704 free (ns->disp.str);
3705
3706 if (ns->bins) {
3707 int i;
3708 if (ns->bins->array != NULL) {
3709 for (i = 0; i < ns->bins->len; i++)
3710 if (ns->bins->array[i] != NULL) {
3711 RaDeleteBin (parser, ns->bins->array[i]);
3712 ns->bins->array[i] = NULL;
3713 }
3714
3715 ArgusFree (ns->bins->array);
3716 ns->bins->array = NULL;
3717 }
3718
3719 ArgusFree (ns->bins);
3720 ns->bins = NULL;
3721 }
3722
3723 if (ns->htblhdr != NULL)
3724 ArgusRemoveHashEntry(&ns->htblhdr);
3725
3726 if (ns->hinthdr != NULL)
3727 ArgusRemoveHashEntry(&ns->hinthdr);
3728
3729 if (ns->nsq != NULL) {
3730 while ((tsns = (struct ArgusRecordStruct *) ArgusPopQueue(ns->nsq, ARGUS_LOCK)) != NULL)
3731 ArgusDeleteRecordStruct (parser, tsns);
3732 ArgusDeleteQueue (ns->nsq);
3733 ns->nsq = NULL;
3734 }
3735
3736 for (i = 0; i < ARGUSMAXDSRTYPE; i++) {
3737 switch (i) {
3738 case ARGUS_LABEL_INDEX: {
3739 struct ArgusLabelStruct *label = (void *)ns->dsrs[i];
3740 if (label != NULL)
3741 if (label->l_un.label != NULL) {
3742 free(label->l_un.label);
3743 label->l_un.label = NULL;
3744 }
3745 break;
3746 }
3747
3748 case ARGUS_JITTER_INDEX: {
3749 struct ArgusJitterStruct *jitter = (void *)ns->dsrs[i];
3750
3751 if (jitter != NULL) {
3752 if (jitter->hdr.subtype & ARGUS_HISTO_LINEAR) {
3753 struct ArgusHistoObject *histo = &jitter->src.act.dist_union.linear;
3754 if (histo->hdr.type == ARGUS_HISTO_DSR)
3755 if (histo->hdr.argus_dsrvl8.len > sizeof(histo)/4)
3756 ArgusFree((char *)histo->data);
3757
3758 histo = &jitter->src.idle.dist_union.linear;
3759 if (histo->hdr.type == ARGUS_HISTO_DSR)
3760 if (histo->hdr.argus_dsrvl8.len > sizeof(histo)/4)
3761 ArgusFree((char *)histo->data);
3762
3763 histo = &jitter->dst.act.dist_union.linear;
3764 if (histo->hdr.type == ARGUS_HISTO_DSR)
3765 if (histo->hdr.argus_dsrvl8.len > sizeof(histo)/4)
3766 ArgusFree((char *)histo->data);
3767
3768 histo = &jitter->dst.idle.dist_union.linear;
3769 if (histo->hdr.type == ARGUS_HISTO_DSR)
3770 if (histo->hdr.argus_dsrvl8.len > sizeof(histo)/4)
3771 ArgusFree((char *)histo->data);
3772 }
3773 }
3774 break;
3775 }
3776 }
3777
3778 if (ns->dsrs[i] != NULL) {
3779 ArgusFree (ns->dsrs[i]);
3780 ns->dsrs[i] = NULL;
3781 }
3782 }
3783
3784 if (ns->correlates) {
3785 for (i = 0; i < ns->correlates->count; i++)
3786 ArgusDeleteRecordStruct(parser, ns->correlates->array[i]);
3787
3788 ArgusFree(ns->correlates->array);
3789 ns->correlates->array = NULL;
3790 ArgusFree(ns->correlates);
3791 }
3792
3793 if (ns->agg != NULL)
3794 ArgusDeleteAggregator (parser, ns->agg);
3795
3796
3797 ArgusFree(ns);
3798 }
3799 #ifdef ARGUSDEBUG
3800 ArgusDebug (9, "ArgusDeleteRecordStruct (%p, %p)", parser, ns);
3801 #endif
3802 }
3803
3804
3805 void ArgusGenerateCorrelateStruct(struct ArgusRecordStruct *);
3806
3807 struct ArgusRecord *
ArgusGenerateRecord(struct ArgusRecordStruct * rec,unsigned char state,char * buf)3808 ArgusGenerateRecord (struct ArgusRecordStruct *rec, unsigned char state, char *buf)
3809 {
3810 struct ArgusRecord *retn = (struct ArgusRecord *) buf;
3811 unsigned int ind, dsrlen = 1, dsrindex = 0;
3812 unsigned int *dsrptr = (unsigned int *)retn + 1;
3813 int x, y, len = 0, type = 0;
3814 struct ArgusDSRHeader *dsr;
3815
3816 if (rec) {
3817 if (rec->correlates != NULL)
3818 ArgusGenerateCorrelateStruct(rec);
3819
3820 switch (rec->hdr.type & 0xF0) {
3821 case ARGUS_MAR: {
3822 if (rec->dsrs[0] != NULL) {
3823 bcopy ((char *)rec->dsrs[0], (char *) retn, rec->hdr.len * 4);
3824 retn->hdr = rec->hdr;
3825 }
3826 break;
3827 }
3828
3829 case ARGUS_EVENT:
3830 case ARGUS_NETFLOW:
3831 case ARGUS_FAR: {
3832 retn->hdr = rec->hdr;
3833 retn->hdr.type |= ARGUS_VERSION;
3834
3835 dsrindex = rec->dsrindex;
3836 for (y = 0, ind = 1; (dsrindex && (y < ARGUSMAXDSRTYPE)); y++, ind <<= 1) {
3837 if ((dsr = rec->dsrs[y]) != NULL) {
3838 len = ((dsr->type & ARGUS_IMMEDIATE_DATA) ? 1 :
3839 ((dsr->subtype & ARGUS_LEN_16BITS) ? dsr->argus_dsrvl16.len :
3840 dsr->argus_dsrvl8.len));
3841 switch (y) {
3842 case ARGUS_NETWORK_INDEX: {
3843 struct ArgusNetworkStruct *net = (struct ArgusNetworkStruct *) dsr;
3844 switch (net->hdr.subtype) {
3845 case ARGUS_TCP_INIT: {
3846 struct ArgusNetworkStruct *net = (struct ArgusNetworkStruct *)dsr;
3847 struct ArgusTCPObject *tcp = &net->net_union.tcp;
3848 struct ArgusTCPInitStatus tcpinit;
3849 tcpinit.status = tcp->status;
3850 tcpinit.seqbase = tcp->src.seqbase;
3851 tcpinit.options = tcp->options;
3852 tcpinit.win = tcp->src.win;
3853 tcpinit.flags = tcp->src.flags;
3854 tcpinit.winshift = tcp->src.winshift;
3855
3856 net->hdr.argus_dsrvl8.len = 5;
3857
3858 *dsrptr++ = *(unsigned int *)&net->hdr;
3859 *dsrptr++ = ((unsigned int *)&tcpinit)[0];
3860 *dsrptr++ = ((unsigned int *)&tcpinit)[1];
3861 *dsrptr++ = ((unsigned int *)&tcpinit)[2];
3862 *dsrptr++ = ((unsigned int *)&tcpinit)[3];
3863 len = 5;
3864 break;
3865 }
3866 case ARGUS_TCP_STATUS: {
3867 struct ArgusNetworkStruct *net = (struct ArgusNetworkStruct *)dsr;
3868 struct ArgusTCPObject *tcp = &net->net_union.tcp;
3869 struct ArgusTCPStatus tcpstatus;
3870 tcpstatus.status = tcp->status;
3871 tcpstatus.src = tcp->src.flags;
3872 tcpstatus.dst = tcp->dst.flags;
3873 tcpstatus.pad[0] = 0;
3874 tcpstatus.pad[1] = 0;
3875 net->hdr.argus_dsrvl8.len = 3;
3876 *dsrptr++ = *(unsigned int *)&net->hdr;
3877 *dsrptr++ = ((unsigned int *)&tcpstatus)[0];
3878 *dsrptr++ = ((unsigned int *)&tcpstatus)[1];
3879 len = 3;
3880 break;
3881 }
3882
3883 case ARGUS_TCP_PERF:
3884 default: {
3885 for (x = 0; x < len; x++)
3886 *dsrptr++ = ((unsigned int *)dsr)[x];
3887 break;
3888 }
3889 }
3890 break;
3891 }
3892
3893 case ARGUS_AGR_INDEX: {
3894 struct ArgusAgrStruct *agr = (struct ArgusAgrStruct *) dsr;
3895 if ((ArgusParser->ArgusAggregator) != NULL) {
3896 if (ArgusParser->ArgusAggregator->RaMetricFetchAlgorithm == ArgusFetchDuration) {
3897 if (agr->count == 1) {
3898 len = 0;
3899 break;
3900 }
3901 }
3902 }
3903 // Deliberately fall through
3904 }
3905
3906 default:
3907 for (x = 0; x < len; x++)
3908 *dsrptr++ = ((unsigned int *)rec->dsrs[y])[x];
3909 break;
3910
3911 case ARGUS_TIME_INDEX: {
3912 struct ArgusMetricStruct *metric = (struct ArgusMetricStruct *) rec->dsrs[ARGUS_METRIC_INDEX];
3913 struct ArgusTimeObject *dtime = (struct ArgusTimeObject *) dsr;
3914 struct ArgusTimeObject *dsrtime = (struct ArgusTimeObject *) dsrptr;
3915 unsigned char subtype = 0;
3916 long long dur = RaGetuSecDuration(rec);
3917 unsigned char tlen = 1;
3918 int cnt = 0;
3919
3920 if (dtime->src.start.tv_sec > 0)
3921 subtype |= ARGUS_TIME_SRC_START;
3922 if (dtime->src.end.tv_sec > 0)
3923 subtype |= ARGUS_TIME_SRC_END;
3924
3925 if ((subtype & ARGUS_TIME_SRC_START) && (subtype & ARGUS_TIME_SRC_END)) {
3926 if ((dtime->src.start.tv_sec == dtime->src.end.tv_sec) &&
3927 (dtime->src.start.tv_usec == dtime->src.end.tv_usec))
3928 subtype &= ~ARGUS_TIME_SRC_END;
3929 }
3930
3931 if (dtime->dst.start.tv_sec > 0)
3932 subtype |= ARGUS_TIME_DST_START;
3933 if (dtime->dst.end.tv_sec > 0)
3934 subtype |= ARGUS_TIME_DST_END;
3935
3936 if ((subtype & ARGUS_TIME_DST_START) && (subtype & ARGUS_TIME_DST_END)) {
3937 if ((dtime->dst.start.tv_sec == dtime->dst.end.tv_sec) &&
3938 (dtime->dst.start.tv_usec == dtime->dst.end.tv_usec))
3939 subtype &= ~ARGUS_TIME_DST_END;
3940 }
3941
3942 if (metric && (metric->src.pkts == 0))
3943 subtype &= ~(ARGUS_TIME_SRC_START | ARGUS_TIME_SRC_END);
3944
3945 if (metric && (metric->dst.pkts == 0))
3946 subtype &= ~(ARGUS_TIME_DST_START | ARGUS_TIME_DST_END);
3947
3948 for (x = 0; x < 4; x++)
3949 if (subtype & (ARGUS_TIME_SRC_START << x))
3950 cnt++;
3951
3952 if (cnt && (dtime->hdr.argus_dsrvl8.qual != ARGUS_TYPE_UTC_NANOSECONDS)) {
3953 if (cnt == 1)
3954 subtype |= ARGUS_TIME_ABSOLUTE_TIMESTAMP;
3955 else if (dur > 0x7fffffff)
3956 subtype |= ARGUS_TIME_ABSOLUTE_RANGE;
3957 else
3958 subtype |= ARGUS_TIME_RELATIVE_RANGE;
3959 } else
3960 subtype |= ARGUS_TIME_ABSOLUTE_TIMESTAMP;
3961
3962 dtime->hdr.subtype = subtype;
3963
3964 // We'd like to use relative uSec or nSec timestamps if there are more
3965 // than one timestamp in the record. ARGUS_TIME_RELATIVE_TIMESTAMP
3966 // So lets test uSec deltas, and report for time.
3967
3968 //#define ARGUS_TIME_ABSOLUTE_TIMESTAMP 0x01 // All time indicators are 64-bit sec, usec values, implies more than 2
3969 //#define ARGUS_TIME_ABSOLUTE_RANGE 0x02 // All timestamp are absolute, and the second timestamp is the flow range
3970 //#define ARGUS_TIME_ABSOLUTE_RELATIVE_RANGE 0x03 // First timestamp is absolute, the second indicator is a range offset
3971 //#define ARGUS_TIME_RELATIVE_TIMESTAMP 0x04 // First timestamp is absolute, all others are relative, uSec or nSec
3972 //#define ARGUS_TIME_RELATIVE_RANGE 0x05 // First timestamp is absolute, only one other value is flow range, uSec or nSec
3973
3974
3975 if (subtype & ARGUS_TIME_RELATIVE_RANGE) {
3976 *dsrptr++ = *(unsigned int *)dsr;
3977
3978 if (subtype & ARGUS_TIME_SRC_START) { // assume at this point that all indicators are reasonable
3979 *dsrptr++ = dtime->src.start.tv_sec; // if there is not a src start, then there is not a src end
3980 *dsrptr++ = dtime->src.start.tv_usec;
3981 tlen += 2;
3982
3983 for (x = 1; x < 4; x++) {
3984 if (subtype & (ARGUS_TIME_SRC_START << x)) {
3985 switch (ARGUS_TIME_SRC_START << x) {
3986 case ARGUS_TIME_SRC_END: {
3987 int value = ((dtime->src.end.tv_sec - dtime->src.start.tv_sec) * 1000000) +
3988 (dtime->src.end.tv_usec - dtime->src.start.tv_usec);
3989 *dsrptr++ = value;
3990 tlen += 1;
3991 break;
3992 }
3993 case ARGUS_TIME_DST_START: {
3994 int value = ((dtime->dst.start.tv_sec - dtime->src.start.tv_sec) * 1000000) +
3995 (dtime->dst.start.tv_usec - dtime->src.start.tv_usec);
3996 *dsrptr++ = value;
3997 tlen += 1;
3998 break;
3999 }
4000 case ARGUS_TIME_DST_END: {
4001 int value = ((dtime->dst.end.tv_sec - dtime->src.start.tv_sec) * 1000000) +
4002 (dtime->dst.end.tv_usec - dtime->src.start.tv_usec);
4003 *dsrptr++ = value;
4004 tlen += 1;
4005 break;
4006 }
4007 }
4008 }
4009 }
4010 } else {
4011 if (subtype & ARGUS_TIME_DST_START) { // assume its just dst start and possibly end.
4012 *dsrptr++ = dtime->dst.start.tv_sec;
4013 *dsrptr++ = dtime->dst.start.tv_usec;
4014 tlen += 2;
4015
4016 if (subtype & ARGUS_TIME_DST_END) {
4017 *dsrptr++ = dur; // the dur at this point is the difference
4018 tlen += 1;
4019 }
4020 }
4021 }
4022
4023 } else {
4024 *dsrptr++ = *(unsigned int *)&dtime->hdr;
4025
4026 for (x = 0; x < 4; x++) {
4027 if (subtype & (ARGUS_TIME_SRC_START << x)) {
4028 switch (ARGUS_TIME_SRC_START << x) {
4029 case ARGUS_TIME_SRC_START:
4030 *dsrptr++ = dtime->src.start.tv_sec;
4031 *dsrptr++ = dtime->src.start.tv_usec;
4032 tlen += 2;
4033 break;
4034 case ARGUS_TIME_SRC_END:
4035 *dsrptr++ = dtime->src.end.tv_sec;
4036 *dsrptr++ = dtime->src.end.tv_usec;
4037 tlen += 2;
4038 break;
4039 case ARGUS_TIME_DST_START:
4040 *dsrptr++ = dtime->dst.start.tv_sec;
4041 *dsrptr++ = dtime->dst.start.tv_usec;
4042 tlen += 2;
4043 break;
4044 case ARGUS_TIME_DST_END:
4045 *dsrptr++ = dtime->dst.end.tv_sec;
4046 *dsrptr++ = dtime->dst.end.tv_usec;
4047 tlen += 2;
4048 break;
4049 }
4050 }
4051 }
4052 }
4053
4054 dsrtime->hdr.argus_dsrvl8.len = tlen;
4055 len = tlen;
4056 break;
4057 }
4058
4059 case ARGUS_METRIC_INDEX: {
4060 struct ArgusMetricStruct *metric = (struct ArgusMetricStruct *) dsr;
4061
4062 if (((metric->src.pkts + metric->dst.pkts) > 0) ||
4063 ((metric->src.bytes + metric->dst.bytes) > 0)) {
4064 if (((metric->src.pkts) && (metric->dst.pkts)) ||
4065 ((metric->src.bytes) && (metric->dst.bytes))) {
4066 if ((0xFF >= metric->src.pkts) && (0xFF >= metric->dst.pkts) &&
4067 (0xFF >= metric->src.bytes) && (0xFF >= metric->dst.bytes))
4068 type = ARGUS_SRCDST_BYTE;
4069 else
4070 if ((0xFFFF >= metric->src.bytes) && (0xFFFF >= metric->dst.bytes))
4071 type = ARGUS_SRCDST_SHORT;
4072 else
4073 if ((0xFFFFFFFF >= metric->src.bytes) && (0xFFFFFFFF >= metric->dst.bytes))
4074 type = ARGUS_SRCDST_INT;
4075 else
4076 type = ARGUS_SRCDST_LONGLONG;
4077
4078 } else {
4079 if ((metric->src.pkts) || (metric->src.bytes)) {
4080 if (0xFFFF >= metric->src.bytes)
4081 type = ARGUS_SRC_SHORT;
4082 else
4083 if (0xFFFFFFFF >= metric->src.bytes)
4084 type = ARGUS_SRC_INT;
4085 else
4086 type = ARGUS_SRC_LONGLONG;
4087 } else {
4088 if (0xFFFF >= metric->dst.bytes)
4089 type = ARGUS_DST_SHORT;
4090 else
4091 if (0xFFFFFFFF >= metric->dst.bytes)
4092 type = ARGUS_DST_INT;
4093 else
4094 type = ARGUS_DST_LONGLONG;
4095 }
4096 }
4097 } else {
4098 type = ARGUS_SRCDST_BYTE;
4099 }
4100
4101 dsr = (struct ArgusDSRHeader *)dsrptr;
4102 dsr->type = ARGUS_METER_DSR;
4103
4104 if (metric->src.appbytes || metric->dst.appbytes) {
4105 dsr->subtype = ARGUS_METER_PKTS_BYTES_APP;
4106 switch (type) {
4107 case ARGUS_SRCDST_BYTE:
4108 dsr->argus_dsrvl8.qual = type;
4109 dsr->argus_dsrvl8.len = 3;
4110 ((unsigned char *)(dsr + 1))[0] = (unsigned char) metric->src.pkts;
4111 ((unsigned char *)(dsr + 1))[1] = (unsigned char) metric->src.bytes;
4112 ((unsigned char *)(dsr + 1))[2] = (unsigned char) metric->src.appbytes;
4113 ((unsigned char *)(dsr + 1))[3] = (unsigned char) metric->dst.pkts;
4114 ((unsigned char *)(dsr + 1))[4] = (unsigned char) metric->dst.bytes;
4115 ((unsigned char *)(dsr + 1))[5] = (unsigned char) metric->dst.appbytes;
4116 ((unsigned char *)(dsr + 1))[6] = 0;
4117 ((unsigned char *)(dsr + 1))[7] = 0;
4118 break;
4119 case ARGUS_SRCDST_SHORT:
4120 dsr->argus_dsrvl8.qual = type;
4121 dsr->argus_dsrvl8.len = 4;
4122 ((unsigned short *)(dsr + 1))[0] = ((unsigned short) metric->src.pkts);
4123 ((unsigned short *)(dsr + 1))[1] = ((unsigned short) metric->src.bytes);
4124 ((unsigned short *)(dsr + 1))[2] = ((unsigned short) metric->src.appbytes);
4125 ((unsigned short *)(dsr + 1))[3] = ((unsigned short) metric->dst.pkts);
4126 ((unsigned short *)(dsr + 1))[4] = ((unsigned short) metric->dst.bytes);
4127 ((unsigned short *)(dsr + 1))[5] = ((unsigned short) metric->dst.appbytes);
4128 break;
4129 case ARGUS_SRCDST_INT:
4130 dsr->argus_dsrvl8.qual = type;
4131 dsr->argus_dsrvl8.len = 7;
4132 ((unsigned int *)(dsr + 1))[0] = ((unsigned int) metric->src.pkts);
4133 ((unsigned int *)(dsr + 1))[1] = ((unsigned int) metric->src.bytes);
4134 ((unsigned int *)(dsr + 1))[2] = ((unsigned int) metric->src.appbytes);
4135 ((unsigned int *)(dsr + 1))[3] = ((unsigned int) metric->dst.pkts);
4136 ((unsigned int *)(dsr + 1))[4] = ((unsigned int) metric->dst.bytes);
4137 ((unsigned int *)(dsr + 1))[5] = ((unsigned int) metric->dst.appbytes);
4138 break;
4139 case ARGUS_SRCDST_LONGLONG:
4140 dsr->argus_dsrvl8.qual = type;
4141 dsr->argus_dsrvl8.len = 13;
4142 ((unsigned int *)(dsr + 1))[0] = (((unsigned int *)&metric->src.pkts)[0]);
4143 ((unsigned int *)(dsr + 1))[1] = (((unsigned int *)&metric->src.pkts)[1]);
4144 ((unsigned int *)(dsr + 1))[2] = (((unsigned int *)&metric->src.bytes)[0]);
4145 ((unsigned int *)(dsr + 1))[3] = (((unsigned int *)&metric->src.bytes)[1]);
4146 ((unsigned int *)(dsr + 1))[4] = (((unsigned int *)&metric->src.appbytes)[0]);
4147 ((unsigned int *)(dsr + 1))[5] = (((unsigned int *)&metric->src.appbytes)[1]);
4148 ((unsigned int *)(dsr + 1))[6] = (((unsigned int *)&metric->dst.pkts)[0]);
4149 ((unsigned int *)(dsr + 1))[7] = (((unsigned int *)&metric->dst.pkts)[1]);
4150 ((unsigned int *)(dsr + 1))[8] = (((unsigned int *)&metric->dst.bytes)[0]);
4151 ((unsigned int *)(dsr + 1))[9] = (((unsigned int *)&metric->dst.bytes)[1]);
4152 ((unsigned int *)(dsr + 1))[10] = (((unsigned int *)&metric->dst.appbytes)[0]);
4153 ((unsigned int *)(dsr + 1))[11] = (((unsigned int *)&metric->dst.appbytes)[1]);
4154 break;
4155
4156 case ARGUS_SRC_BYTE:
4157 dsr->argus_dsrvl8.qual = type;
4158 dsr->argus_dsrvl8.len = 2;
4159 ((unsigned char *)(dsr + 1))[0] = ((unsigned char) metric->src.pkts);
4160 ((unsigned char *)(dsr + 1))[1] = ((unsigned char) metric->src.bytes);
4161 ((unsigned char *)(dsr + 1))[2] = ((unsigned char) metric->src.appbytes);
4162 ((unsigned char *)(dsr + 1))[3] = 0;
4163 break;
4164 case ARGUS_SRC_SHORT:
4165 dsr->argus_dsrvl8.qual = type;
4166 dsr->argus_dsrvl8.len = 3;
4167 ((unsigned short *)(dsr + 1))[0] = ((unsigned short) metric->src.pkts);
4168 ((unsigned short *)(dsr + 1))[1] = ((unsigned short) metric->src.bytes);
4169 ((unsigned short *)(dsr + 1))[2] = ((unsigned short) metric->src.appbytes);
4170 ((unsigned short *)(dsr + 1))[3] = 0;
4171 break;
4172 case ARGUS_SRC_INT:
4173 dsr->argus_dsrvl8.qual = type;
4174 dsr->argus_dsrvl8.len = 4;
4175 ((unsigned int *)(dsr + 1))[0] = ((unsigned int) metric->src.pkts);
4176 ((unsigned int *)(dsr + 1))[1] = ((unsigned int) metric->src.bytes);
4177 ((unsigned int *)(dsr + 1))[2] = ((unsigned int) metric->src.appbytes);
4178 break;
4179 case ARGUS_SRC_LONGLONG:
4180 dsr->argus_dsrvl8.qual = type;
4181 dsr->argus_dsrvl8.len = 7;
4182 ((unsigned int *)(dsr + 1))[0] = (((unsigned int *)&metric->src.pkts)[0]);
4183 ((unsigned int *)(dsr + 1))[1] = (((unsigned int *)&metric->src.pkts)[1]);
4184 ((unsigned int *)(dsr + 1))[2] = (((unsigned int *)&metric->src.bytes)[0]);
4185 ((unsigned int *)(dsr + 1))[3] = (((unsigned int *)&metric->src.bytes)[1]);
4186 ((unsigned int *)(dsr + 1))[4] = (((unsigned int *)&metric->src.appbytes)[0]);
4187 ((unsigned int *)(dsr + 1))[5] = (((unsigned int *)&metric->src.appbytes)[1]);
4188 break;
4189
4190 case ARGUS_DST_BYTE:
4191 dsr->argus_dsrvl8.qual = type;
4192 dsr->argus_dsrvl8.len = 2;
4193 ((unsigned char *)(dsr + 1))[0] = ((unsigned char) metric->dst.pkts);
4194 ((unsigned char *)(dsr + 1))[1] = ((unsigned char) metric->dst.bytes);
4195 ((unsigned char *)(dsr + 1))[2] = ((unsigned char) metric->dst.appbytes);
4196 ((unsigned char *)(dsr + 1))[3] = 0;
4197 break;
4198 case ARGUS_DST_SHORT:
4199 dsr->argus_dsrvl8.qual = type;
4200 dsr->argus_dsrvl8.len = 3;
4201 ((unsigned short *)(dsr + 1))[0] = ((unsigned short) metric->dst.pkts);
4202 ((unsigned short *)(dsr + 1))[1] = ((unsigned short) metric->dst.bytes);
4203 ((unsigned short *)(dsr + 1))[2] = ((unsigned short) metric->dst.appbytes);
4204 ((unsigned short *)(dsr + 1))[3] = 0;
4205 break;
4206 case ARGUS_DST_INT:
4207 dsr->argus_dsrvl8.qual = type;
4208 dsr->argus_dsrvl8.len = 4;
4209 ((unsigned int *)(dsr + 1))[0] = ((unsigned int) metric->dst.pkts);
4210 ((unsigned int *)(dsr + 1))[1] = ((unsigned int) metric->dst.bytes);
4211 ((unsigned int *)(dsr + 1))[2] = ((unsigned int) metric->dst.appbytes);
4212 break;
4213 case ARGUS_DST_LONGLONG:
4214 dsr->argus_dsrvl8.qual = type;
4215 dsr->argus_dsrvl8.len = 7;
4216 ((unsigned int *)(dsr + 1))[0] = (((unsigned int *)&metric->dst.pkts)[0]);
4217 ((unsigned int *)(dsr + 1))[1] = (((unsigned int *)&metric->dst.pkts)[1]);
4218 ((unsigned int *)(dsr + 1))[2] = (((unsigned int *)&metric->dst.bytes)[0]);
4219 ((unsigned int *)(dsr + 1))[3] = (((unsigned int *)&metric->dst.bytes)[1]);
4220 ((unsigned int *)(dsr + 1))[4] = (((unsigned int *)&metric->dst.appbytes)[0]);
4221 ((unsigned int *)(dsr + 1))[5] = (((unsigned int *)&metric->dst.appbytes)[1]);
4222 break;
4223 }
4224 } else {
4225 dsr->subtype = ARGUS_METER_PKTS_BYTES;
4226 switch (type) {
4227 case ARGUS_SRCDST_BYTE:
4228 dsr->argus_dsrvl8.qual = type;
4229 dsr->argus_dsrvl8.len = 2;
4230 ((unsigned char *)(dsr + 1))[0] = (unsigned char) metric->src.pkts;
4231 ((unsigned char *)(dsr + 1))[1] = (unsigned char) metric->src.bytes;
4232 ((unsigned char *)(dsr + 1))[2] = (unsigned char) metric->dst.pkts;
4233 ((unsigned char *)(dsr + 1))[3] = (unsigned char) metric->dst.bytes;
4234 break;
4235 case ARGUS_SRCDST_SHORT:
4236 dsr->argus_dsrvl8.qual = type;
4237 dsr->argus_dsrvl8.len = 3;
4238 ((unsigned short *)(dsr + 1))[0] = ((unsigned short) metric->src.pkts);
4239 ((unsigned short *)(dsr + 1))[1] = ((unsigned short) metric->src.bytes);
4240 ((unsigned short *)(dsr + 1))[2] = ((unsigned short) metric->dst.pkts);
4241 ((unsigned short *)(dsr + 1))[3] = ((unsigned short) metric->dst.bytes);
4242 break;
4243 case ARGUS_SRCDST_INT:
4244 dsr->argus_dsrvl8.qual = type;
4245 dsr->argus_dsrvl8.len = 5;
4246 ((unsigned int *)(dsr + 1))[0] = ((unsigned int) metric->src.pkts);
4247 ((unsigned int *)(dsr + 1))[1] = ((unsigned int) metric->src.bytes);
4248 ((unsigned int *)(dsr + 1))[2] = ((unsigned int) metric->dst.pkts);
4249 ((unsigned int *)(dsr + 1))[3] = ((unsigned int) metric->dst.bytes);
4250 break;
4251 case ARGUS_SRCDST_LONGLONG:
4252 dsr->argus_dsrvl8.qual = type;
4253 dsr->argus_dsrvl8.len = 9;
4254 ((unsigned int *)(dsr + 1))[0] = (((unsigned int *)&metric->src.pkts)[0]);
4255 ((unsigned int *)(dsr + 1))[1] = (((unsigned int *)&metric->src.pkts)[1]);
4256 ((unsigned int *)(dsr + 1))[2] = (((unsigned int *)&metric->src.bytes)[0]);
4257 ((unsigned int *)(dsr + 1))[3] = (((unsigned int *)&metric->src.bytes)[1]);
4258 ((unsigned int *)(dsr + 1))[4] = (((unsigned int *)&metric->dst.pkts)[0]);
4259 ((unsigned int *)(dsr + 1))[5] = (((unsigned int *)&metric->dst.pkts)[1]);
4260 ((unsigned int *)(dsr + 1))[6] = (((unsigned int *)&metric->dst.bytes)[0]);
4261 ((unsigned int *)(dsr + 1))[7] = (((unsigned int *)&metric->dst.bytes)[1]);
4262 break;
4263
4264 case ARGUS_SRC_SHORT:
4265 dsr->argus_dsrvl8.qual = type;
4266 dsr->argus_dsrvl8.len = 2;
4267 ((unsigned short *)(dsr + 1))[0] = ((unsigned short) metric->src.pkts);
4268 ((unsigned short *)(dsr + 1))[1] = ((unsigned short) metric->src.bytes);
4269 break;
4270 case ARGUS_SRC_INT:
4271 dsr->argus_dsrvl8.qual = type;
4272 dsr->argus_dsrvl8.len = 3;
4273 ((unsigned int *)(dsr + 1))[0] = ((unsigned int) metric->src.pkts);
4274 ((unsigned int *)(dsr + 1))[1] = ((unsigned int) metric->src.bytes);
4275 break;
4276 case ARGUS_SRC_LONGLONG:
4277 dsr->argus_dsrvl8.qual = type;
4278 dsr->argus_dsrvl8.len = 5;
4279 ((unsigned int *)(dsr + 1))[0] = (((unsigned int *)&metric->src.pkts)[0]);
4280 ((unsigned int *)(dsr + 1))[1] = (((unsigned int *)&metric->src.pkts)[1]);
4281 ((unsigned int *)(dsr + 1))[2] = (((unsigned int *)&metric->src.bytes)[0]);
4282 ((unsigned int *)(dsr + 1))[3] = (((unsigned int *)&metric->src.bytes)[1]);
4283 break;
4284
4285 case ARGUS_DST_SHORT:
4286 dsr->argus_dsrvl8.qual = type;
4287 dsr->argus_dsrvl8.len = 2;
4288 ((unsigned short *)(dsr + 1))[0] = ((unsigned short) metric->dst.pkts);
4289 ((unsigned short *)(dsr + 1))[1] = ((unsigned short) metric->dst.bytes);
4290 break;
4291 case ARGUS_DST_INT:
4292 dsr->argus_dsrvl8.qual = type;
4293 dsr->argus_dsrvl8.len = 3;
4294 ((unsigned int *)(dsr + 1))[0] = ((unsigned int) metric->dst.pkts);
4295 ((unsigned int *)(dsr + 1))[1] = ((unsigned int) metric->dst.bytes);
4296 break;
4297 case ARGUS_DST_LONGLONG:
4298 dsr->argus_dsrvl8.qual = type;
4299 dsr->argus_dsrvl8.len = 5;
4300 ((unsigned int *)(dsr + 1))[0] = (((unsigned int *)&metric->dst.pkts)[0]);
4301 ((unsigned int *)(dsr + 1))[1] = (((unsigned int *)&metric->dst.pkts)[1]);
4302 ((unsigned int *)(dsr + 1))[2] = (((unsigned int *)&metric->dst.bytes)[0]);
4303 ((unsigned int *)(dsr + 1))[3] = (((unsigned int *)&metric->dst.bytes)[1]);
4304 break;
4305 }
4306 }
4307 len = dsr->argus_dsrvl8.len;
4308 dsrptr += len;
4309 break;
4310 }
4311
4312 case ARGUS_PSIZE_INDEX: {
4313 struct ArgusPacketSizeStruct *psize = (struct ArgusPacketSizeStruct *) dsr;
4314
4315 if ((psize->src.psizemax > 0) && (psize->dst.psizemax > 0))
4316 type = ARGUS_SRCDST_SHORT;
4317 else
4318 if (psize->src.psizemax > 0)
4319 type = ARGUS_SRC_SHORT;
4320 else
4321 if (psize->dst.psizemax > 0)
4322 type = ARGUS_DST_SHORT;
4323 else
4324 type = 0;
4325
4326 if (type) {
4327 unsigned char value = 0, tmp = 0, *ptr;
4328 int max, i, cnt;
4329
4330 dsr = (struct ArgusDSRHeader *)dsrptr;
4331 dsr->type = ARGUS_PSIZE_DSR;
4332
4333 switch (type) {
4334 case ARGUS_SRCDST_SHORT:
4335 dsr->subtype = ARGUS_PSIZE_SRC_MAX_MIN | ARGUS_PSIZE_DST_MAX_MIN;
4336 dsr->argus_dsrvl8.qual = type;
4337 dsr->argus_dsrvl8.len = 3;
4338 ((unsigned short *)(dsr + 1))[0] = psize->src.psizemin;
4339 ((unsigned short *)(dsr + 1))[1] = psize->src.psizemax;
4340 ((unsigned short *)(dsr + 1))[2] = psize->dst.psizemin;
4341 ((unsigned short *)(dsr + 1))[3] = psize->dst.psizemax;
4342 break;
4343
4344 case ARGUS_SRC_SHORT:
4345 dsr->subtype = ARGUS_PSIZE_SRC_MAX_MIN;
4346 dsr->argus_dsrvl8.qual = type;
4347 dsr->argus_dsrvl8.len = 2;
4348 ((unsigned short *)(dsr + 1))[0] = psize->src.psizemin;
4349 ((unsigned short *)(dsr + 1))[1] = psize->src.psizemax;
4350 break;
4351
4352 case ARGUS_DST_SHORT:
4353 dsr->subtype = ARGUS_PSIZE_DST_MAX_MIN;
4354 dsr->argus_dsrvl8.qual = type;
4355 dsr->argus_dsrvl8.len = 2;
4356 ((unsigned short *)(dsr + 1))[0] = psize->dst.psizemin;
4357 ((unsigned short *)(dsr + 1))[1] = psize->dst.psizemax;
4358 break;
4359
4360 default:
4361 break;
4362 }
4363
4364 if (dsr->subtype & ARGUS_PSIZE_SRC_MAX_MIN) {
4365 ptr = (unsigned char *)(dsr + dsr->argus_dsrvl8.len);
4366
4367 for (cnt = 0, i = 0; i < 8; i++)
4368 cnt += psize->src.psize[i];
4369
4370 dsr->subtype |= ARGUS_PSIZE_HISTO;
4371
4372 dsr->argus_dsrvl8.len++;
4373 *((unsigned int *)(dsr + dsr->argus_dsrvl8.len)) = 0;
4374
4375 for (i = 0, max = 0; i < 8; i++)
4376 if (max < psize->src.psize[i])
4377 max = psize->src.psize[i];
4378
4379 for (i = 0; i < 8; i++) {
4380 if ((tmp = psize->src.psize[i])) {
4381 if (i & 0x01) {
4382 if (max > 15)
4383 tmp = ((tmp * 15)/max);
4384 if (!tmp) tmp++;
4385 value |= tmp;
4386 *ptr++ = value;
4387 } else {
4388 if (max > 15)
4389 tmp = ((tmp * 15)/max);
4390 if (!tmp) tmp++;
4391 value = (tmp << 4);
4392 }
4393 } else {
4394 if (i & 0x01) {
4395 value &= 0xF0;
4396 *ptr++ = value;
4397 } else {
4398 value = 0;
4399 }
4400 }
4401 }
4402 }
4403
4404 if (dsr->subtype & ARGUS_PSIZE_DST_MAX_MIN) {
4405 ptr = (unsigned char *)(dsr + dsr->argus_dsrvl8.len);
4406
4407 for (cnt = 0, i = 0; i < 8; i++)
4408 cnt += psize->dst.psize[i];
4409
4410 dsr->subtype |= ARGUS_PSIZE_HISTO;
4411
4412 dsr->argus_dsrvl8.len++;
4413 *((unsigned int *)(dsr + dsr->argus_dsrvl8.len)) = 0;
4414
4415 for (i = 0, max = 0; i < 8; i++)
4416 if (max < psize->dst.psize[i])
4417 max = psize->dst.psize[i];
4418
4419 for (i = 0; i < 8; i++) {
4420 if ((tmp = psize->dst.psize[i])) {
4421 if (i & 0x01) {
4422 if (max > 15)
4423 tmp = ((tmp * 15)/max);
4424 if (!tmp) tmp++;
4425 value |= tmp;
4426 *ptr++ = value;
4427 } else {
4428 if (max > 15)
4429 tmp = ((tmp * 15)/max);
4430 if (!tmp) tmp++;
4431 value = (tmp << 4);
4432 }
4433 } else {
4434 if (i & 0x01) {
4435 value &= 0xF0;
4436 *ptr++ = value;
4437 } else {
4438 value = 0;
4439 }
4440 }
4441 }
4442 }
4443
4444 dsr->argus_dsrvl8.qual = type;
4445 len = dsr->argus_dsrvl8.len;
4446 dsrptr += len;
4447 } else
4448 len = 0;
4449
4450 break;
4451 }
4452
4453 case ARGUS_MPLS_INDEX: {
4454 struct ArgusMplsStruct *mpls = (struct ArgusMplsStruct *) dsr;
4455 struct ArgusMplsStruct *tmpls = (struct ArgusMplsStruct *) dsrptr;
4456 unsigned char subtype = tmpls->hdr.subtype & ~(ARGUS_MPLS_SRC_LABEL | ARGUS_MPLS_DST_LABEL);
4457
4458 *dsrptr++ = *(unsigned int *)dsr;
4459 len = 1;
4460
4461 if (((mpls->hdr.argus_dsrvl8.qual & 0xF0) >> 4) > 0) {
4462 subtype |= ARGUS_MPLS_SRC_LABEL;
4463 *dsrptr++ = mpls->slabel;
4464 len++;
4465 }
4466 if (((mpls->hdr.argus_dsrvl8.qual & 0x0F)) > 0) {
4467 subtype |= ARGUS_MPLS_DST_LABEL;
4468 *dsrptr++ = mpls->dlabel;
4469 len++;
4470 }
4471 tmpls->hdr.subtype = subtype;
4472 tmpls->hdr.argus_dsrvl8.len = len;
4473 break;
4474 }
4475
4476 case ARGUS_JITTER_INDEX: {
4477 #if defined(HAVE_XDR)
4478 struct ArgusJitterStruct *jitter = (struct ArgusJitterStruct *) dsr;
4479 struct ArgusJitterStruct *tjit = (struct ArgusJitterStruct *) dsrptr;
4480
4481 int size = (sizeof(struct ArgusOutputStatObject) + 3) / 4;
4482 XDR xdrbuf, *xdrs = &xdrbuf;
4483
4484 unsigned char value = 0, tmp = 0, *ptr;
4485 unsigned int fdist = 0;
4486 int max, i, cnt;
4487
4488 *dsrptr++ = *(unsigned int *)dsr;
4489 tjit->hdr.argus_dsrvl8.len = 1;
4490
4491 if (jitter->hdr.argus_dsrvl8.qual & ARGUS_SRC_ACTIVE_JITTER) {
4492 xdrmem_create(xdrs, (char *)dsrptr, sizeof(struct ArgusOutputStatObject), XDR_ENCODE);
4493 xdr_int(xdrs, &jitter->src.act.n);
4494 xdr_float(xdrs, &jitter->src.act.minval);
4495 xdr_float(xdrs, &jitter->src.act.meanval);
4496 xdr_float(xdrs, &jitter->src.act.stdev);
4497 xdr_float(xdrs, &jitter->src.act.maxval);
4498
4499 switch (jitter->hdr.subtype & (ARGUS_HISTO_EXP | ARGUS_HISTO_LINEAR)) {
4500 case ARGUS_HISTO_EXP: {
4501 value = 0;
4502 ptr = (unsigned char *)&fdist;
4503 for (cnt = 0, i = 0; i < 8; i++)
4504 cnt += jitter->src.act.dist_union.fdist[i];
4505
4506 for (i = 0, max = 0; i < 8; i++)
4507 if (max < jitter->src.act.dist_union.fdist[i])
4508 max = jitter->src.act.dist_union.fdist[i];
4509
4510 for (i = 0; i < 8; i++) {
4511 if ((tmp = jitter->src.act.dist_union.fdist[i])) {
4512 if (i & 0x01) {
4513 if (max > 15)
4514 tmp = ((tmp * 15)/max);
4515 if (!tmp) tmp++;
4516 value |= tmp;
4517 *ptr++ = value;
4518 } else {
4519 if (max > 15)
4520 tmp = ((tmp * 15)/max);
4521 if (!tmp) tmp++;
4522 value = (tmp << 4);
4523 }
4524 } else {
4525 if (i & 0x01) {
4526 value &= 0xF0;
4527 *ptr++ = value;
4528 } else {
4529 value = 0;
4530 }
4531 }
4532 }
4533 xdr_u_int(xdrs, &fdist);
4534 dsrptr += size;
4535 tjit->hdr.argus_dsrvl8.len += size;
4536 break;
4537 }
4538
4539 default:
4540 case ARGUS_HISTO_LINEAR:
4541 dsrptr += 5;
4542 tjit->hdr.argus_dsrvl8.len += 5;
4543 break;
4544 }
4545 }
4546
4547 if (jitter->hdr.argus_dsrvl8.qual & ARGUS_SRC_IDLE_JITTER) {
4548 xdrmem_create(xdrs, (char *)dsrptr, sizeof(struct ArgusOutputStatObject), XDR_ENCODE);
4549 xdr_int(xdrs, &jitter->src.idle.n);
4550 xdr_float(xdrs, &jitter->src.idle.minval);
4551 xdr_float(xdrs, &jitter->src.idle.meanval);
4552 xdr_float(xdrs, &jitter->src.idle.stdev);
4553 xdr_float(xdrs, &jitter->src.idle.maxval);
4554
4555 switch (jitter->hdr.subtype & (ARGUS_HISTO_EXP | ARGUS_HISTO_LINEAR)) {
4556 case ARGUS_HISTO_EXP: {
4557 value = 0;
4558 ptr = (unsigned char *)&fdist;
4559 for (cnt = 0, i = 0; i < 8; i++)
4560 cnt += jitter->src.idle.dist_union.fdist[i];
4561
4562 for (i = 0, max = 0; i < 8; i++)
4563 if (max < jitter->src.idle.dist_union.fdist[i])
4564 max = jitter->src.idle.dist_union.fdist[i];
4565
4566 for (i = 0; i < 8; i++) {
4567 if ((tmp = jitter->src.idle.dist_union.fdist[i])) {
4568 if (i & 0x01) {
4569 if (max > 15)
4570 tmp = ((tmp * 15)/max);
4571 if (!tmp) tmp++;
4572 value |= tmp;
4573 *ptr++ = value;
4574 } else {
4575 if (max > 15)
4576 tmp = ((tmp * 15)/max);
4577 if (!tmp) tmp++;
4578 value = (tmp << 4);
4579 }
4580 } else {
4581 if (i & 0x01) {
4582 value &= 0xF0;
4583 *ptr++ = value;
4584 } else {
4585 value = 0;
4586 }
4587 }
4588 }
4589
4590 xdr_u_int(xdrs, &fdist);
4591 dsrptr += size;
4592 tjit->hdr.argus_dsrvl8.len += size;
4593 break;
4594 }
4595
4596 default:
4597 case ARGUS_HISTO_LINEAR: {
4598 dsrptr += 5;
4599 tjit->hdr.argus_dsrvl8.len += 5;
4600 break;
4601 }
4602 }
4603 }
4604 if (jitter->hdr.argus_dsrvl8.qual & ARGUS_DST_ACTIVE_JITTER) {
4605 xdrmem_create(xdrs, (char *)dsrptr, sizeof(struct ArgusOutputStatObject), XDR_ENCODE);
4606 xdr_int(xdrs, &jitter->dst.act.n);
4607 xdr_float(xdrs, &jitter->dst.act.minval);
4608 xdr_float(xdrs, &jitter->dst.act.meanval);
4609 xdr_float(xdrs, &jitter->dst.act.stdev);
4610 xdr_float(xdrs, &jitter->dst.act.maxval);
4611 switch (jitter->hdr.subtype & (ARGUS_HISTO_EXP | ARGUS_HISTO_LINEAR)) {
4612 case ARGUS_HISTO_EXP: {
4613 value = 0;
4614 ptr = (unsigned char *)&fdist;
4615 for (cnt = 0, i = 0; i < 8; i++)
4616 cnt += jitter->dst.act.dist_union.fdist[i];
4617
4618 for (i = 0, max = 0; i < 8; i++)
4619 if (max < jitter->dst.act.dist_union.fdist[i])
4620 max = jitter->dst.act.dist_union.fdist[i];
4621
4622 for (i = 0; i < 8; i++) {
4623 if ((tmp = jitter->dst.act.dist_union.fdist[i])) {
4624 if (i & 0x01) {
4625 if (max > 15)
4626 tmp = ((tmp * 15)/max);
4627 if (!tmp) tmp++;
4628 value |= tmp;
4629 *ptr++ = value;
4630 } else {
4631 if (max > 15)
4632 tmp = ((tmp * 15)/max);
4633 if (!tmp) tmp++;
4634 value = (tmp << 4);
4635 }
4636 } else {
4637 if (i & 0x01) {
4638 value &= 0xF0;
4639 *ptr++ = value;
4640 } else {
4641 value = 0;
4642 }
4643 }
4644 }
4645
4646 xdr_u_int(xdrs, &fdist);
4647 dsrptr += size;
4648 tjit->hdr.argus_dsrvl8.len += size;
4649 break;
4650 }
4651
4652 default:
4653 case ARGUS_HISTO_LINEAR: {
4654 dsrptr += 5;
4655 tjit->hdr.argus_dsrvl8.len += 5;
4656 break;
4657 }
4658 }
4659 }
4660 if (jitter->hdr.argus_dsrvl8.qual & ARGUS_DST_IDLE_JITTER) {
4661 xdrmem_create(xdrs, (char *)dsrptr, sizeof(struct ArgusOutputStatObject), XDR_ENCODE);
4662 xdr_int(xdrs, &jitter->dst.idle.n);
4663 xdr_float(xdrs, &jitter->dst.idle.minval);
4664 xdr_float(xdrs, &jitter->dst.idle.meanval);
4665 xdr_float(xdrs, &jitter->dst.idle.stdev);
4666 xdr_float(xdrs, &jitter->dst.idle.maxval);
4667 switch (jitter->hdr.subtype & (ARGUS_HISTO_EXP | ARGUS_HISTO_LINEAR)) {
4668 case ARGUS_HISTO_EXP: {
4669 value = 0;
4670 ptr = (unsigned char *)&fdist;
4671 for (cnt = 0, i = 0; i < 8; i++)
4672 cnt += jitter->dst.idle.dist_union.fdist[i];
4673
4674 for (i = 0, max = 0; i < 8; i++)
4675 if (max < jitter->dst.idle.dist_union.fdist[i])
4676 max = jitter->dst.idle.dist_union.fdist[i];
4677
4678 for (i = 0; i < 8; i++) {
4679 if ((tmp = jitter->dst.idle.dist_union.fdist[i])) {
4680 if (i & 0x01) {
4681 if (max > 15)
4682 tmp = ((tmp * 15)/max);
4683 if (!tmp) tmp++;
4684 value |= tmp;
4685 *ptr++ = value;
4686 } else {
4687 if (max > 15)
4688 tmp = ((tmp * 15)/max);
4689 if (!tmp) tmp++;
4690 value = (tmp << 4);
4691 }
4692 } else {
4693 if (i & 0x01) {
4694 value &= 0xF0;
4695 *ptr++ = value;
4696 } else {
4697 value = 0;
4698 }
4699 }
4700 }
4701
4702 xdr_u_int(xdrs, &fdist);
4703 dsrptr += size;
4704 tjit->hdr.argus_dsrvl8.len += size;
4705 break;
4706 }
4707
4708 default:
4709 case ARGUS_HISTO_LINEAR: {
4710 dsrptr += 5;
4711 tjit->hdr.argus_dsrvl8.len += 5;
4712 break;
4713 }
4714 }
4715 }
4716
4717 len = tjit->hdr.argus_dsrvl8.len;
4718 #endif
4719 break;
4720 }
4721
4722 case ARGUS_IPATTR_INDEX: {
4723 struct ArgusIPAttrStruct *attr = (struct ArgusIPAttrStruct *) dsr;
4724 struct ArgusIPAttrStruct *tattr = (struct ArgusIPAttrStruct *) dsrptr;
4725
4726 *dsrptr++ = *(unsigned int *)dsr;
4727 len = 1;
4728
4729 if (attr->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_SRC) {
4730 *dsrptr++ = *(unsigned int *)&attr->src;
4731 len++;
4732 }
4733 if (attr->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_SRC_OPTIONS) {
4734 *dsrptr++ = attr->src.options;
4735 len++;
4736 }
4737 if (attr->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_DST) {
4738 *dsrptr++ = *(unsigned int *)&attr->dst;
4739 len++;
4740 }
4741 if (attr->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_DST_OPTIONS) {
4742 *dsrptr++ = attr->dst.options;
4743 len++;
4744 }
4745 tattr->hdr.argus_dsrvl8.len = len;
4746 break;
4747 }
4748
4749 case ARGUS_LABEL_INDEX: {
4750 struct ArgusLabelStruct *label = (struct ArgusLabelStruct *) dsr;
4751 int labelen = 0, slen = 0;
4752
4753 if (label->l_un.label != NULL)
4754 slen = strlen(label->l_un.label);
4755
4756 if (slen > 0) {
4757 labelen = (label->hdr.argus_dsrvl8.len - 1) * 4;
4758 *dsrptr++ = *(unsigned int *)dsr;
4759 bcopy ((char *)label->l_un.label, (char *)dsrptr, slen);
4760 if (labelen > slen)
4761 bzero(&((char *)dsrptr)[slen], labelen - slen);
4762 dsrptr += (labelen + 3)/4;
4763 len = 1 + ((labelen + 3)/4);
4764 } else
4765 len = 0;
4766 break;
4767 }
4768 }
4769
4770 dsrlen += len;
4771 dsrindex &= ~ind;
4772 }
4773 }
4774
4775 if (retn->hdr.len != 0) {
4776 if (!(rec->status & ARGUS_RECORD_MODIFIED) && (retn->hdr.len != dsrlen)) {
4777 if (retn->hdr.len > dsrlen) {
4778 int i, cnt = retn->hdr.len - dsrlen;
4779 #ifdef ARGUSDEBUG
4780 ArgusDebug (6, "ArgusGenerateRecord (%p, %d) old len %d new len %d\n",
4781 rec, state, retn->hdr.len * 4, dsrlen * 4);
4782 #endif
4783 for (i = 0; i < cnt; i++) {
4784 dsr = (void *) dsrptr++;
4785 dsr->type = 0; dsr->subtype = 0;
4786 dsr->argus_dsrvl8.qual = 0;
4787 dsr->argus_dsrvl8.len = 1;
4788 dsrlen++;
4789 }
4790 }
4791 }
4792 }
4793
4794 retn->hdr.len = dsrlen;
4795
4796 if (((char *)dsrptr - (char *)retn) != (dsrlen * 4))
4797 ArgusLog (LOG_ERR, "ArgusGenerateRecord: parse length error %d:%d", ((char *)dsrptr - (char *)retn), dsrlen);
4798
4799 break;
4800 }
4801
4802 default:
4803 retn = NULL;
4804 break;
4805 }
4806
4807 } else {
4808 retn->hdr.type = ARGUS_MAR;
4809 retn->hdr.type |= ARGUS_VERSION;
4810 retn->hdr.cause = state & 0xF0;
4811 retn->hdr.len = dsrlen;
4812 }
4813
4814 #ifdef ARGUSDEBUG
4815 ArgusDebug (6, "ArgusGenerateRecord (%p, %d) len %d\n", rec, state, dsrlen * 4);
4816 #endif
4817 return (retn);
4818 }
4819
4820
4821 int
ArgusGenerateCiscoRecord(struct ArgusRecordStruct * rec,unsigned char state,char * buf)4822 ArgusGenerateCiscoRecord (struct ArgusRecordStruct *rec, unsigned char state, char *buf)
4823 {
4824 int retn = 0;
4825 #ifdef ARGUSDEBUG
4826 int len = 0;
4827 #endif
4828
4829 if (rec) {
4830 switch (rec->hdr.type & 0xF0) {
4831 case ARGUS_EVENT:
4832 case ARGUS_MAR:
4833 default:
4834 break;
4835
4836 case ARGUS_NETFLOW:
4837 case ARGUS_FAR: {
4838 struct ArgusDSRHeader *dsr;
4839 int y, ind, dsrindex = 0;
4840 retn = 1;
4841
4842 dsrindex = rec->dsrindex;
4843 for (y = 0, ind = 1; (dsrindex && (y < ARGUSMAXDSRTYPE)); y++, ind <<= 1) {
4844 if ((dsr = rec->dsrs[y]) != NULL) {
4845 #ifdef ARGUDEBUG
4846 len = ((dsr->type & ARGUS_IMMEDIATE_DATA) ? 1 :
4847 ((dsr->subtype & ARGUS_LEN_16BITS) ? dsr->argus_dsrvl16.len :
4848 dsr->argus_dsrvl8.len));
4849 #endif
4850 switch (y) {
4851 case ARGUS_NETWORK_INDEX: {
4852 struct ArgusNetworkStruct *net = (struct ArgusNetworkStruct *) dsr;
4853 switch (net->hdr.subtype) {
4854 case ARGUS_TCP_INIT: {
4855 break;
4856 }
4857 case ARGUS_TCP_STATUS: {
4858 break;
4859 }
4860 case ARGUS_TCP_PERF:
4861 default: {
4862 break;
4863 }
4864 }
4865 break;
4866 }
4867
4868 case ARGUS_SRCUSERDATA_INDEX:
4869 case ARGUS_DSTUSERDATA_INDEX:
4870 case ARGUS_AGR_INDEX:
4871 case ARGUS_PSIZE_INDEX:
4872 case ARGUS_MPLS_INDEX:
4873 case ARGUS_JITTER_INDEX:
4874 case ARGUS_IPATTR_INDEX:
4875 case ARGUS_LABEL_INDEX:
4876 default: {
4877 break;
4878 }
4879
4880 case ARGUS_TIME_INDEX: {
4881 break;
4882 }
4883
4884 case ARGUS_METRIC_INDEX: {
4885 break;
4886 }
4887 }
4888 }
4889 }
4890 break;
4891 }
4892 }
4893 }
4894
4895 #ifdef ARGUSDEBUG
4896 ArgusDebug (6, "ArgusGenerateCiscoRecord (%p, %d) len %d\n", rec, state, len);
4897 #endif
4898 return (retn);
4899 }
4900
4901
4902 void
ArgusGenerateCorrelateStruct(struct ArgusRecordStruct * ns)4903 ArgusGenerateCorrelateStruct(struct ArgusRecordStruct *ns)
4904 {
4905 int i, clen = 0;
4906 struct ArgusCorStruct *cor;
4907
4908 if ((cor = ns->correlates) != NULL) {
4909 struct ArgusCorrelateStruct *scor = NULL;
4910 struct ArgusCorMetrics *met = NULL;
4911 struct ArgusRecordStruct *sns;
4912
4913 clen = sizeof(struct ArgusDSRHeader)/4 + (cor->count * sizeof(struct ArgusCorMetrics)/4);
4914 if ((scor = ArgusCalloc(4, clen)) == NULL)
4915 ArgusLog (LOG_ERR, "ArgusGenerateCorrelateStruct ArgusCalloc error %s", strerror(errno));
4916
4917 scor->hdr.type = ARGUS_COR_DSR;
4918 scor->hdr.subtype = 0;
4919 scor->hdr.argus_dsrvl8.qual = 0;
4920 scor->hdr.argus_dsrvl8.len = clen;
4921
4922 ns->dsrs[ARGUS_COR_INDEX] = &scor->hdr;
4923 ns->dsrindex |= 0x01 << ARGUS_COR_INDEX;
4924
4925 met = &scor->metrics;
4926
4927 for (i = 0; i < ns->correlates->count; i++) {
4928 if ((sns = ns->correlates->array[i]) != NULL) {
4929 struct ArgusTransportStruct *trans = (void *)sns->dsrs[ARGUS_TRANSPORT_INDEX];
4930 long long stime, ltime;
4931
4932 if (trans != NULL)
4933 met->srcid.a_un.value = trans->srcid.a_un.value;
4934
4935 stime = RaGetuSecDuration (sns);
4936 ltime = RaGetuSecDuration (ns);
4937
4938 met->deltaDur = stime - ltime;
4939 met->deltaStart = (ArgusFetchStartuSecTime(sns) - ArgusFetchStartuSecTime(ns));
4940 met->deltaLast = (ArgusFetchLastuSecTime(sns) - ArgusFetchLastuSecTime(ns));
4941 met->deltaSrcPkts = (ArgusFetchSrcPktsCount(sns) - ArgusFetchSrcPktsCount(ns));
4942 met->deltaDstPkts = (ArgusFetchDstPktsCount(sns) - ArgusFetchDstPktsCount(ns));
4943 met++;
4944 }
4945 }
4946 }
4947 }
4948
4949
4950
4951 struct ArgusHashTableHdr *ArgusFindHashEntry (struct ArgusHashTable *, struct ArgusHashStruct *);
4952 struct ArgusHashTable *ArgusNewHashTable (size_t);
4953 void ArgusDeleteHashTable (struct ArgusHashTable *);
4954
4955 struct RaBinStruct *
RaNewBin(struct ArgusParserStruct * parser,struct RaBinProcessStruct * rbps,struct ArgusRecordStruct * ns,long long startpt,int sindex)4956 RaNewBin (struct ArgusParserStruct *parser, struct RaBinProcessStruct *rbps, struct ArgusRecordStruct *ns, long long startpt, int sindex)
4957 {
4958 struct RaBinStruct *retn = NULL;
4959
4960 if ((retn = (struct RaBinStruct *) ArgusCalloc (1, sizeof(*retn))) == NULL)
4961 ArgusLog (LOG_ERR, "RaNewBin: ArgusCalloc error %s\n", strerror(errno));
4962
4963 if ((retn->agg = ArgusCopyAggregator(parser->ArgusAggregator)) == NULL)
4964 ArgusLog (LOG_ERR, "ArgusClientInit: ArgusNewAggregator error");
4965
4966 switch (rbps->nadp.mode) {
4967 default:
4968 case ARGUSSPLITTIME: {
4969 retn->value = startpt;
4970 retn->stime.tv_sec = startpt / 1000000;
4971 retn->stime.tv_usec = startpt % 1000000;
4972
4973 startpt += rbps->size;
4974
4975 retn->etime.tv_sec = startpt / 1000000;
4976 retn->etime.tv_usec = startpt % 1000000;
4977 break;
4978 }
4979
4980 case ARGUSSPLITSIZE:
4981 case ARGUSSPLITCOUNT:
4982 retn->value = rbps->start + (rbps->size * (rbps->index - sindex));
4983 break;
4984 }
4985
4986 retn->size = rbps->size;
4987
4988 #ifdef ARGUSDEBUG
4989 ArgusDebug (2, "RaNewBin(%p, %p, %p, %lld, %d) returns %p\n", parser, rbps, ns, startpt, sindex, retn);
4990 #endif
4991 return (retn);
4992 }
4993
4994 void
RaDeleteBin(struct ArgusParserStruct * parser,struct RaBinStruct * bin)4995 RaDeleteBin (struct ArgusParserStruct *parser, struct RaBinStruct *bin)
4996 {
4997 if (bin != NULL) {
4998 if (bin->agg != NULL)
4999 ArgusDeleteAggregator (parser, bin->agg);
5000 ArgusFree(bin);
5001 }
5002
5003 #ifdef ARGUSDEBUG
5004 ArgusDebug (5, "RaDeleteBin(%p)\n", bin);
5005 #endif
5006 return;
5007 }
5008
5009 struct ArgusMaskStruct *
ArgusSelectMaskDefs(struct ArgusRecordStruct * ns)5010 ArgusSelectMaskDefs(struct ArgusRecordStruct *ns)
5011 {
5012 struct ArgusMaskStruct *mask = NULL;
5013
5014 switch (ns->hdr.type & 0xF0) {
5015 case ARGUS_EVENT: {
5016 mask = ArgusIpV4MaskDefs;
5017 break;
5018 }
5019
5020 default: {
5021 struct ArgusNetworkStruct *net = NULL;
5022 struct ArgusFlow *flow = NULL;
5023
5024 if ((flow = (struct ArgusFlow *)ns->dsrs[ARGUS_FLOW_INDEX]) != NULL) {
5025 if (flow->hdr.subtype == ARGUS_FLOW_ARP) {
5026 mask = ArgusArpMaskDefs;
5027 } else {
5028 net = (void *)ns->dsrs[ARGUS_NETWORK_INDEX];
5029 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
5030 case ARGUS_TYPE_IPV6: {
5031 if (net != NULL) {
5032 switch (net->hdr.argus_dsrvl8.qual) {
5033 default:
5034 mask = ArgusIpV6MaskDefs;
5035 break;
5036 }
5037
5038 } else
5039 mask = ArgusIpV6MaskDefs;
5040 break;
5041 }
5042
5043 case ARGUS_TYPE_IPV4: {
5044 if (net != NULL) {
5045 switch (net->hdr.argus_dsrvl8.qual) {
5046 default:
5047 mask = ArgusIpV4MaskDefs;
5048 break;
5049 }
5050 } else
5051 mask = ArgusIpV4MaskDefs;
5052 break;
5053 }
5054
5055 case ARGUS_TYPE_ISIS: {
5056 struct ArgusIsisFlow *isis = (struct ArgusIsisFlow *) &flow->isis_flow;
5057
5058 switch (isis->pdu_type) {
5059 default:
5060 case L1_LAN_IIH:
5061 case L2_LAN_IIH: mask = ArgusIsisHelloMaskDefs; break;
5062 case L1_LSP:
5063 case L2_LSP: mask = ArgusIsisLspMaskDefs; break;
5064 case L1_CSNP:
5065 case L2_CSNP: mask = ArgusIsisCsnpMaskDefs; break;
5066 case L1_PSNP:
5067 case L2_PSNP: mask = ArgusIsisPsnpMaskDefs; break;
5068 }
5069
5070 break;
5071 }
5072
5073 case ARGUS_TYPE_RARP:
5074 case ARGUS_TYPE_ARP:
5075 mask = ArgusArpMaskDefs;
5076 break;
5077
5078 case ARGUS_TYPE_WLAN:
5079 mask = ArgusWlanMaskDefs;
5080 break;
5081
5082 default:
5083 case ARGUS_TYPE_ETHER:
5084 mask = ArgusEtherMaskDefs;
5085 break;
5086 }
5087 }
5088 }
5089 }
5090 }
5091
5092 return mask;
5093 }
5094
5095
5096 struct ArgusMaskStruct *
ArgusSelectRevMaskDefs(struct ArgusRecordStruct * ns)5097 ArgusSelectRevMaskDefs(struct ArgusRecordStruct *ns)
5098 {
5099 struct ArgusMaskStruct *mask = NULL;
5100 struct ArgusNetworkStruct *net;
5101 struct ArgusFlow *flow;
5102
5103 flow = (struct ArgusFlow *)ns->dsrs[ARGUS_FLOW_INDEX];
5104 net = (struct ArgusNetworkStruct *)ns->dsrs[ARGUS_NETWORK_INDEX];
5105
5106 if (flow != NULL) {
5107 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
5108 case ARGUS_TYPE_IPV6: {
5109 mask = ArgusIpV6RevMaskDefs;
5110 if (net != NULL) {
5111 switch (net->hdr.argus_dsrvl8.qual) {
5112 default:
5113 break;
5114 }
5115 }
5116 break;
5117 }
5118
5119 case ARGUS_TYPE_IPV4: {
5120 mask = ArgusIpV4RevMaskDefs;
5121 if (net != NULL) {
5122 switch (net->hdr.argus_dsrvl8.qual) {
5123 default:
5124 break;
5125 }
5126 }
5127 break;
5128 }
5129
5130 case ARGUS_TYPE_RARP:
5131 case ARGUS_TYPE_ARP:
5132 mask = ArgusArpRevMaskDefs;
5133 break;
5134
5135 case ARGUS_TYPE_WLAN:
5136 mask = ArgusWlanRevMaskDefs;
5137 break;
5138
5139 default:
5140 case ARGUS_TYPE_ETHER:
5141 mask = ArgusEtherRevMaskDefs;
5142 break;
5143 }
5144 }
5145 return mask;
5146 }
5147
5148
5149 struct ArgusHashStruct *
ArgusGenerateHashStruct(struct ArgusAggregatorStruct * na,struct ArgusRecordStruct * ns,struct ArgusFlow * flow)5150 ArgusGenerateHashStruct (struct ArgusAggregatorStruct *na, struct ArgusRecordStruct *ns, struct ArgusFlow *flow)
5151 {
5152 struct ArgusHashStruct *retn = NULL;
5153 char *ptr = NULL;
5154
5155 if (na != NULL) {
5156 if (na->hstruct.buf == NULL) {
5157 if ((na->hstruct.buf = (unsigned int *) ArgusCalloc(1, RA_HASHSIZE)) == NULL)
5158 ArgusLog (LOG_ERR, "ArgusGenerateHashStruct(%p, %p, %p) ArgusCalloc returned error %s\n", na, ns, flow, strerror(errno));
5159 } else
5160 bzero(na->hstruct.buf, RA_HASHSIZE);
5161
5162 ptr = (char *) na->hstruct.buf;
5163
5164 switch (ns->hdr.type & 0xF0) {
5165 case ARGUS_MAR: {
5166 if (na->mask & ARGUS_MASK_SRCID_INDEX) {
5167 struct ArgusRecord *rec = (struct ArgusRecord *) ns->dsrs[0];
5168 int i, len, s = sizeof(unsigned short);
5169 unsigned int thisid;
5170 unsigned short *sptr;
5171
5172 if (rec != NULL) {
5173 switch (ns->hdr.cause & 0xF0) {
5174 case ARGUS_START: thisid = rec->argus_mar.thisid; break;
5175 case ARGUS_STATUS: thisid = rec->argus_mar.argusid; break;
5176 case ARGUS_STOP: thisid = rec->argus_mar.argusid; break;
5177 case ARGUS_SHUTDOWN: thisid = rec->argus_mar.argusid; break;
5178 case ARGUS_ERROR: thisid = rec->argus_mar.argusid; break;
5179 }
5180 }
5181
5182 retn = &na->hstruct;
5183
5184 retn->hash = 0;
5185 retn->len = 4;
5186
5187 bcopy(&thisid, ptr, 4);
5188
5189 sptr = (unsigned short *)&retn->buf[0];
5190
5191 for (i = 0, len = retn->len / s; i < len; i++)
5192 retn->hash += *sptr++;
5193 }
5194 break;
5195 }
5196
5197 case ARGUS_EVENT:
5198 case ARGUS_NETFLOW:
5199 case ARGUS_FAR: {
5200 struct ArgusFlow *tflow = (struct ArgusFlow *) ns->dsrs[ARGUS_FLOW_INDEX];
5201 int i, len, tlen = 0, s = sizeof(unsigned short);
5202 unsigned short *sptr;
5203
5204 retn = &na->hstruct;
5205
5206 retn->hash = 0;
5207 retn->len = 0;
5208
5209 if (na->mask) {
5210 if (flow == NULL)
5211 flow = tflow;
5212
5213 if (na->ArgusMaskDefs == NULL)
5214 if ((na->ArgusMaskDefs = ArgusSelectMaskDefs(ns)) == NULL)
5215 return(retn);
5216
5217
5218 if ((flow != NULL)) {
5219 if (na->mask & ((0x01LL << ARGUS_MASK_SADDR) | (0x01LL << ARGUS_MASK_DADDR))) {
5220 bcopy ((char *)&flow->hdr, ptr, sizeof(flow->hdr));
5221 ((struct ArgusFlow *)ptr)->hdr.subtype &= 0x3F;
5222 ((struct ArgusFlow *)ptr)->hdr.argus_dsrvl8.qual &= 0x1F;
5223 ((struct ArgusFlow *)ptr)->hdr.argus_dsrvl8.len = 0;
5224 ptr += sizeof(flow->hdr);
5225 tlen += sizeof(flow->hdr);
5226 }
5227 }
5228
5229 for (i = 0; ((i < ARGUS_MAX_MASK_LIST) && (tlen < RA_HASHSIZE)); i++) {
5230 if (na->mask < (0x01LL << i))
5231 break;
5232 if (na->mask & (0x01LL << i)) {
5233 char *p = (char *)ns->dsrs[na->ArgusMaskDefs[i].dsr];
5234
5235 if (p != NULL) {
5236 int offset = 0, slen = 0;
5237
5238 switch (i) {
5239 case ARGUS_MASK_SMPLS:
5240 case ARGUS_MASK_DMPLS: {
5241 unsigned int label = (*(unsigned int *)&((char *) p)[na->ArgusMaskDefs[i].offset]) >> 12;
5242 bcopy ((char *)&label, ptr, na->ArgusMaskDefs[i].len);
5243 ptr += na->ArgusMaskDefs[i].len;
5244 tlen += na->ArgusMaskDefs[i].len;
5245 break;
5246 }
5247
5248 case ARGUS_MASK_SPORT:
5249 case ARGUS_MASK_DPORT: {
5250 if (flow != NULL) {
5251 switch (flow->hdr.subtype & 0x3F) {
5252 case ARGUS_FLOW_CLASSIC5TUPLE: {
5253 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
5254 case ARGUS_TYPE_IPV4:
5255 switch (flow->ip_flow.ip_p) {
5256 case IPPROTO_ESP: {
5257 slen = (i == ARGUS_MASK_SPORT) ? -1 : 4;
5258 offset = (i == ARGUS_MASK_SPORT) ? -1 : na->ArgusMaskDefs[i].offset;
5259 break;
5260 }
5261
5262 // case IPPROTO_ICMP: {
5263 // if (i == ARGUS_MASK_SPORT) {
5264 // slen = 1;
5265 // offset = na->ArgusMaskDefs[i].offset;
5266 // } else {
5267 // switch (flow->icmp_flow.type) {
5268 // case ICMP_MASKREQ:
5269 // case ICMP_ECHO:
5270 // case ICMP_TSTAMP:
5271 // case ICMP_IREQ:
5272 // case ICMP_MASKREPLY:
5273 // case ICMP_ECHOREPLY:
5274 // case ICMP_TSTAMPREPLY:
5275 // case ICMP_IREQREPLY:
5276 // offset = na->ArgusMaskDefs[i].offset - 1;
5277 // slen = 5;
5278 // break;
5279 //
5280 // default:
5281 // offset = na->ArgusMaskDefs[i].offset - 1;
5282 // slen = 1;
5283 // }
5284 // }
5285 // break;
5286 // }
5287 }
5288 break;
5289 }
5290 }
5291 }
5292 }
5293 }
5294
5295 default: {
5296 if (slen < 0) {
5297 slen = 0;
5298 break;
5299 }
5300
5301 if (na->ArgusMaskDefs[i].len > 0) {
5302 if (!slen) {
5303 slen = na->ArgusMaskDefs[i].len;
5304 offset = na->ArgusMaskDefs[i].offset;
5305 }
5306
5307 if (offset == NLI) {
5308 unsigned char *cptr = NULL, cbuf;
5309 unsigned short sbuf;
5310 switch (slen) {
5311 case 0: cbuf = na->ArgusMaskDefs[i].index; cptr = &cbuf; break;
5312 case 1: cbuf = na->ArgusMaskDefs[i].index; cptr = &cbuf; break;
5313 case 2: sbuf = na->ArgusMaskDefs[i].index; cptr = (unsigned char *)&sbuf; break;
5314 case 4:
5315 default:
5316 cptr = (unsigned char *)&na->ArgusMaskDefs[i].index;
5317 break;
5318 }
5319
5320 bcopy (cptr, ptr, slen);
5321
5322 } else {
5323 bcopy (&((char *) p)[offset], ptr, slen);
5324 }
5325 }
5326 break;
5327 }
5328
5329 case ARGUS_MASK_INODE: {
5330 if (na->ArgusMaskDefs[i].len > 0) {
5331 unsigned int iaddr[4];
5332 slen = na->ArgusMaskDefs[i].len;
5333 offset = na->ArgusMaskDefs[i].offset;
5334 bcopy (&((char *) p)[offset], iaddr, slen);
5335
5336 if (na->iaddrlen > 0)
5337 iaddr[0] &= na->imask.addr_un.ipv4;
5338
5339 bcopy (iaddr, ptr, slen);
5340 }
5341 break;
5342 }
5343 }
5344
5345 ptr += slen;
5346 tlen += slen;
5347 }
5348 }
5349 }
5350
5351 retn->len = s * ((tlen + (s - 1))/ s);
5352 if (retn->len > RA_HASHSIZE)
5353 retn->len = RA_HASHSIZE;
5354 sptr = (unsigned short *)&retn->buf[0];
5355
5356 for (i = 0, len = retn->len / s; i < len; i++)
5357 retn->hash += *sptr++;
5358
5359 na->ArgusMaskDefs = NULL;
5360 }
5361 break;
5362 }
5363 }
5364 }
5365
5366 return (retn);
5367 }
5368
5369
5370 struct ArgusHashStruct *
ArgusGenerateReverseHashStruct(struct ArgusAggregatorStruct * na,struct ArgusRecordStruct * ns,struct ArgusFlow * flow)5371 ArgusGenerateReverseHashStruct (struct ArgusAggregatorStruct *na, struct ArgusRecordStruct *ns, struct ArgusFlow *flow)
5372 {
5373 struct ArgusHashStruct *retn = &na->hstruct;
5374 struct ArgusFlow *tflow = (struct ArgusFlow *) ns->dsrs[ARGUS_FLOW_INDEX];
5375 char *ptr = (char *) na->hstruct.buf;
5376 int i, len, tlen = 0, s = sizeof(unsigned short);
5377 unsigned short *sptr;
5378
5379 if (ptr == NULL) {
5380 if ((na->hstruct.buf = (unsigned int *) ArgusCalloc(1, RA_HASHSIZE)) == NULL)
5381 ArgusLog (LOG_ERR, "ArgusGenerateHashStruct(%p, %p, %p) ArgusCalloc returned error %s\n", na, ns, flow, strerror(errno));
5382
5383 ptr = (char *) na->hstruct.buf;
5384
5385 } else
5386 bzero ((char *)ptr, retn->len);
5387
5388 retn->hash = 0;
5389 retn->len = 0;
5390
5391 if (na->mask && (tflow != NULL)) {
5392 if (flow == NULL)
5393 flow = tflow;
5394
5395 if ((flow != NULL)) {
5396 // if (na->ArgusMaskDefs == NULL)
5397 na->ArgusMaskDefs = ArgusSelectRevMaskDefs(ns);
5398
5399 if (na->mask & ((0x01LL << ARGUS_MASK_SADDR) | (0x01LL << ARGUS_MASK_DADDR))) {
5400 bcopy ((char *)&flow->hdr, ptr, sizeof(flow->hdr));
5401 ((struct ArgusFlow *)ptr)->hdr.subtype &= 0x3F;
5402 ((struct ArgusFlow *)ptr)->hdr.argus_dsrvl8.qual &= 0x1F;
5403 ((struct ArgusFlow *)ptr)->hdr.argus_dsrvl8.len = 0;
5404 ptr += sizeof(flow->hdr);
5405 tlen += sizeof(flow->hdr);
5406 }
5407
5408 for (i = 0; ((i < ARGUS_MAX_MASK_LIST) && (tlen < RA_HASHSIZE)); i++) {
5409 if (na->mask < (0x01LL << i))
5410 break;
5411
5412 if (na->mask & (0x01LL << i)) {
5413 int offset = 0, slen = 0;
5414 char *p = (char *)ns->dsrs[na->ArgusMaskDefs[i].dsr];
5415
5416 if (p != NULL) {
5417 switch (i) {
5418 case ARGUS_MASK_SMPLS:
5419 case ARGUS_MASK_DMPLS: {
5420 unsigned int label = (*(unsigned int *)&((char *) p)[na->ArgusMaskDefs[i].offset]) >> 12;
5421 bcopy ((char *)&label, ptr, na->ArgusMaskDefs[i].len);
5422 ptr += na->ArgusMaskDefs[i].len;
5423 tlen += na->ArgusMaskDefs[i].len;
5424 break;
5425 }
5426
5427 case ARGUS_MASK_SPORT:
5428 case ARGUS_MASK_DPORT:
5429 switch (flow->hdr.subtype & 0x3F) {
5430 case ARGUS_FLOW_CLASSIC5TUPLE: {
5431 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
5432 case ARGUS_TYPE_IPV4:
5433 switch (flow->ip_flow.ip_p) {
5434 case IPPROTO_ESP: {
5435 slen = (i == ARGUS_MASK_SPORT) ? -1 : 4;
5436 offset = (i == ARGUS_MASK_SPORT) ? -1 : na->ArgusMaskDefs[i].offset;
5437 break;
5438 }
5439
5440 case IPPROTO_ICMP: {
5441 slen = 1;
5442 offset = (i == ARGUS_MASK_SPORT) ? na->ArgusMaskDefs[i].offset :
5443 na->ArgusMaskDefs[i].offset - 1;
5444 break;
5445 }
5446 }
5447 break;
5448 }
5449 }
5450 }
5451
5452 default: {
5453 if (slen < 0) {
5454 slen = 0;
5455 break;
5456 }
5457
5458 if (na->ArgusMaskDefs[i].len > 0) {
5459 if (!slen) {
5460 slen = na->ArgusMaskDefs[i].len;
5461 offset = na->ArgusMaskDefs[i].offset;
5462 }
5463
5464 if (offset == NLI) {
5465 unsigned char *cptr = NULL, cbuf;
5466 unsigned short sbuf;
5467 switch (slen) {
5468 case 0: cbuf = na->ArgusMaskDefs[i].index; cptr = &cbuf; break;
5469 case 1: cbuf = na->ArgusMaskDefs[i].index; cptr = &cbuf; break;
5470 case 2: sbuf = na->ArgusMaskDefs[i].index; cptr = (unsigned char *)&sbuf; break;
5471 case 4:
5472 default:
5473 cptr = (unsigned char *)&na->ArgusMaskDefs[i].index;
5474 break;
5475 }
5476
5477 bcopy (cptr, ptr, slen);
5478
5479 } else {
5480 bcopy (&((char *) p)[offset], ptr, slen);
5481 }
5482 }
5483 break;
5484 }
5485 }
5486
5487 ptr += slen;
5488 tlen += slen;
5489 }
5490 }
5491 }
5492
5493 retn->len = s * ((tlen + (s - 1))/ s);
5494 if (retn->len > RA_HASHSIZE)
5495 retn->len = RA_HASHSIZE;
5496 sptr = (unsigned short *)&retn->buf[0];
5497
5498 for (i = 0, len = retn->len / s; i < len; i++)
5499 retn->hash += *sptr++;
5500
5501 na->ArgusMaskDefs = NULL;
5502 }
5503 }
5504
5505 return (retn);
5506 }
5507
5508
5509 struct ArgusHashStruct *
ArgusGenerateHintStruct(struct ArgusAggregatorStruct * na,struct ArgusRecordStruct * ns)5510 ArgusGenerateHintStruct (struct ArgusAggregatorStruct *na, struct ArgusRecordStruct *ns)
5511 {
5512 struct ArgusHashStruct *retn = NULL;
5513
5514 if (na != NULL) {
5515 struct ArgusFlow *flow = (struct ArgusFlow *) ns->dsrs[ARGUS_FLOW_INDEX];
5516 int i, len = 0, s = sizeof(unsigned short);
5517 char *ptr = (char *) na->hstruct.buf;
5518 unsigned short *sptr;
5519
5520 retn = &na->hstruct;
5521
5522 if (ptr == NULL) {
5523 if ((na->hstruct.buf = (unsigned int *) ArgusCalloc(1, RA_HASHSIZE)) == NULL)
5524 ArgusLog (LOG_ERR, "ArgusGenerateHashStruct(%p, %p, %p) ArgusCalloc returned error %s\n", na, ns, flow, strerror(errno));
5525
5526 ptr = (char *) na->hstruct.buf;
5527
5528 } else
5529 bzero ((char *)ptr, retn->len);
5530
5531 retn->hash = 0;
5532 retn->len = 0;
5533
5534 if (na->mask && (flow != NULL)) {
5535 switch (flow->hdr.subtype & 0x3F) {
5536 case ARGUS_FLOW_CLASSIC5TUPLE: {
5537 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
5538 case ARGUS_TYPE_IPV4: {
5539 switch (flow->ip_flow.ip_p) {
5540 case IPPROTO_TCP: {
5541 struct ArgusNetworkStruct *net = (void *)ns->dsrs[ARGUS_NETWORK_INDEX];
5542
5543 if (net != NULL) {
5544 switch (net->hdr.subtype) {
5545 case ARGUS_TCP_INIT:
5546 case ARGUS_TCP_STATUS:
5547 case ARGUS_TCP_PERF: {
5548 struct ArgusTCPObject *tcp = (struct ArgusTCPObject *)&net->net_union.tcp;
5549 if (tcp->src.seqbase != 0) {
5550 bcopy((char *)&tcp->src.seqbase, ptr, sizeof(tcp->src.seqbase));
5551 ptr += sizeof(tcp->src.seqbase);
5552 bcopy((char *)&flow->ip_flow.ip_dst, ptr, 4);
5553 len = 8;
5554 }
5555 break;
5556 }
5557 }
5558 break;
5559 }
5560 }
5561
5562 case IPPROTO_UDP: {
5563 struct ArgusIPAttrStruct *attr = (void *) ns->dsrs[ARGUS_IPATTR_INDEX];
5564 if (attr != NULL) {
5565 bcopy((char *)&attr->src.ip_id, ptr, sizeof(attr->src.ip_id));
5566 ptr += sizeof(attr->src.ip_id);
5567 len += sizeof(attr->src.ip_id);
5568 }
5569 bcopy((char *)&flow->ip_flow.ip_dst, ptr, 4);
5570 len += 4;
5571 ptr += 4;
5572 bcopy((char *)&flow->ip_flow.dport, ptr, sizeof(flow->ip_flow.dport));
5573 len += sizeof(flow->ip_flow.dport);
5574 ptr += sizeof(flow->ip_flow.dport);
5575 break;
5576 }
5577
5578 case IPPROTO_ICMP: {
5579 int ilen = (sizeof(struct ArgusICMPFlow) - sizeof(flow->icmp_flow.ip_src));
5580 bcopy((char *)&flow->icmp_flow.ip_dst, ptr, ilen);
5581 len += ilen;
5582 ptr += ilen;
5583 break;
5584 }
5585 }
5586 break;
5587 }
5588 }
5589 }
5590 }
5591 }
5592
5593 if (len > 0) {
5594 retn->len = s * ((len + (s - 1))/ s);
5595 sptr = (unsigned short *)&retn->buf[0];
5596
5597 for (i = 0, len = retn->len / s; i < len; i++)
5598 retn->hash += *sptr++;
5599
5600 } else
5601 retn = NULL;
5602 }
5603
5604 return (retn);
5605 }
5606
5607
5608 struct ArgusRecordStruct *
ArgusFindRecord(struct ArgusHashTable * htable,struct ArgusHashStruct * hstruct)5609 ArgusFindRecord (struct ArgusHashTable *htable, struct ArgusHashStruct *hstruct)
5610 {
5611 struct ArgusRecordStruct *retn = NULL;
5612 struct ArgusHashTableHdr *hashEntry = NULL, *target, *head;
5613 unsigned int ind = (hstruct->hash % htable->size), i, len;
5614
5615 #if defined(ARGUS_THREADS)
5616 pthread_mutex_lock(&htable->lock);
5617 #endif
5618 if ((target = htable->array[ind]) != NULL) {
5619 head = target;
5620 do {
5621 unsigned short *ptr1 = (unsigned short *) hstruct->buf;
5622 unsigned short *ptr2 = (unsigned short *) target->hstruct.buf;
5623
5624 if (ptr1 && ptr2) {
5625 for (i = 0, len = hstruct->len/sizeof(unsigned short); i < len; i++)
5626 if (*ptr1++ != *ptr2++)
5627 break;
5628 if (i == len) {
5629 hashEntry = target;
5630 break;
5631 }
5632
5633 } else
5634 if (!(ptr1 || ptr2) || ((hstruct->len == 0) && (target->hstruct.len == 0))) {
5635 hashEntry = target;
5636 break;
5637 }
5638
5639 target = target->nxt;
5640 } while (target != head);
5641
5642 if (hashEntry != NULL) {
5643 if (hashEntry != head)
5644 htable->array[ind] = hashEntry;
5645 retn = hashEntry->object;
5646 }
5647 }
5648
5649 #if defined(ARGUS_THREADS)
5650 pthread_mutex_unlock(&htable->lock);
5651 #endif
5652
5653 #ifdef ARGUSDEBUG
5654 ArgusDebug (6, "ArgusFindRecord () returning %p\n", retn);
5655 #endif
5656
5657 return (retn);
5658 }
5659
5660
5661 void ArgusEmptyHashTable (struct ArgusHashTable *htbl);
5662
5663 struct ArgusHashTable *
ArgusNewHashTable(size_t size)5664 ArgusNewHashTable (size_t size)
5665 {
5666 struct ArgusHashTable *retn = NULL;
5667
5668 if ((retn = (struct ArgusHashTable *) ArgusCalloc (1, sizeof(*retn))) == NULL)
5669 ArgusLog (LOG_ERR, "ArgusNewHashTable: ArgusCalloc(1, %d) error %s\n", size, strerror(errno));
5670
5671 if ((retn->array = (struct ArgusHashTableHdr **) ArgusCalloc (size,
5672 sizeof (struct ArgusHashTableHdr *))) == NULL)
5673 ArgusLog (LOG_ERR, "RaMergeQueue: ArgusCalloc error %s\n", strerror(errno));
5674
5675 retn->size = size;
5676
5677 #if defined(ARGUS_THREADS)
5678 pthread_mutex_init(&retn->lock, NULL);
5679 #endif
5680
5681 #ifdef ARGUSDEBUG
5682 ArgusDebug (4, "ArgusNewHashTable (%d) returning %p\n", size, retn);
5683 #endif
5684
5685 return (retn);
5686 }
5687
5688 void
ArgusDeleteHashTable(struct ArgusHashTable * htbl)5689 ArgusDeleteHashTable (struct ArgusHashTable *htbl)
5690 {
5691
5692 if (htbl != NULL) {
5693 ArgusEmptyHashTable (htbl);
5694
5695 if (htbl->array != NULL)
5696 ArgusFree(htbl->array);
5697
5698 ArgusFree(htbl);
5699 }
5700
5701 #ifdef ARGUSDEBUG
5702 ArgusDebug (4, "ArgusDeleteHashTable (%p)\n", htbl);
5703 #endif
5704 }
5705
5706 void
ArgusEmptyHashTable(struct ArgusHashTable * htbl)5707 ArgusEmptyHashTable (struct ArgusHashTable *htbl)
5708 {
5709 struct ArgusHashTableHdr *htblhdr = NULL, *tmp;
5710 int i;
5711
5712 #if defined(ARGUS_THREADS)
5713 pthread_mutex_lock(&htbl->lock);
5714 #endif
5715 for (i = 0; i < htbl->size; i++) {
5716 if ((htblhdr = htbl->array[i]) != NULL) {
5717 htblhdr->prv->nxt = NULL;
5718 while ((tmp = htblhdr) != NULL) {
5719 htblhdr = htblhdr->nxt;
5720 if (tmp->hstruct.buf != NULL)
5721 ArgusFree (tmp->hstruct.buf);
5722 ArgusFree (tmp);
5723 }
5724 htbl->array[i] = NULL;
5725 }
5726 }
5727 #if defined(ARGUS_THREADS)
5728 pthread_mutex_unlock(&htbl->lock);
5729 #endif
5730
5731 #ifdef ARGUSDEBUG
5732 ArgusDebug (6, "ArgusEmptyHashTable (%p) returning\n", htbl);
5733 #endif
5734 }
5735
5736
5737 struct ArgusHashTableHdr *
ArgusFindHashEntry(struct ArgusHashTable * htable,struct ArgusHashStruct * hstruct)5738 ArgusFindHashEntry (struct ArgusHashTable *htable, struct ArgusHashStruct *hstruct)
5739 {
5740 struct ArgusHashTableHdr *retn = NULL, *target, *head;
5741 unsigned int ind = (hstruct->hash % htable->size), i, len;
5742
5743 #if defined(ARGUS_THREADS)
5744 pthread_mutex_lock(&htable->lock);
5745 #endif
5746
5747 if ((target = htable->array[ind]) != NULL) {
5748 head = target;
5749 do {
5750 unsigned short *ptr1 = (unsigned short *) hstruct->buf;
5751 unsigned short *ptr2 = (unsigned short *) target->hstruct.buf;
5752
5753 for (i = 0, len = hstruct->len/sizeof(unsigned short); i < len; i++)
5754 if (*ptr1++ != *ptr2++)
5755 break;
5756 if (i == len) {
5757 retn = target;
5758 break;
5759 }
5760 target = target->nxt;
5761 } while (target != head);
5762
5763 if (retn != NULL) {
5764 if (retn != head)
5765 htable->array[ind] = retn;
5766 }
5767 }
5768
5769 #if defined(ARGUS_THREADS)
5770 pthread_mutex_unlock(&htable->lock);
5771 #endif
5772
5773 #ifdef ARGUSDEBUG
5774 ArgusDebug (6, "ArgusFindHashEntry () returning %p\n", retn);
5775 #endif
5776
5777 return (retn);
5778 }
5779
5780
5781 struct ArgusHashTableHdr *
ArgusAddHashEntry(struct ArgusHashTable * table,void * ns,struct ArgusHashStruct * hstruct)5782 ArgusAddHashEntry (struct ArgusHashTable *table, void *ns, struct ArgusHashStruct *hstruct)
5783 {
5784 struct ArgusHashTableHdr *retn = NULL, *start = NULL;
5785 int ind;
5786
5787 if (hstruct != NULL) {
5788 if ((retn = (struct ArgusHashTableHdr *) ArgusCalloc (1, sizeof (struct ArgusHashTableHdr))) == NULL)
5789 ArgusLog (LOG_ERR, "ArgusAddHashEntry(%p, %p, %d) ArgusCalloc returned error %s\n", table, ns, hstruct, strerror(errno));
5790
5791 retn->object = ns;
5792
5793 if (hstruct->len > 0) {
5794 retn->hstruct = *hstruct;
5795 if ((retn->hstruct.buf = (unsigned int *) ArgusCalloc (1, hstruct->len)) == NULL)
5796 ArgusLog (LOG_ERR, "ArgusAddHashEntry(%p, %p, %d) ArgusCalloc returned error %s\n", table, ns, hstruct, strerror(errno));
5797
5798 bcopy (hstruct->buf, retn->hstruct.buf, hstruct->len);
5799 }
5800
5801 ind = (hstruct->hash % table->size);
5802
5803 #if defined(ARGUS_THREADS)
5804 pthread_mutex_lock(&table->lock);
5805 #endif
5806
5807 if ((start = table->array[ind]) != NULL) {
5808 retn->nxt = start;
5809 retn->prv = start->prv;
5810 retn->prv->nxt = retn;
5811 retn->nxt->prv = retn;
5812 } else
5813 retn->prv = retn->nxt = retn;
5814
5815 table->array[ind] = retn;
5816
5817 #if defined(ARGUS_THREADS)
5818 pthread_mutex_unlock(&table->lock);
5819 #endif
5820 retn->htbl = table;
5821
5822 } else {
5823 #ifdef ARGUSDEBUG
5824 ArgusDebug (6, "ArgusAddHashEntry (%p) no hash struct: returning %p\n", ns, retn);
5825 #endif
5826 }
5827
5828 #ifdef ARGUSDEBUG
5829 ArgusDebug (6, "ArgusAddHashEntry (%p) returning %p\n", ns, retn);
5830 #endif
5831
5832 return (retn);
5833 }
5834
5835 void
ArgusRemoveHashEntry(struct ArgusHashTableHdr ** htblhdr)5836 ArgusRemoveHashEntry (struct ArgusHashTableHdr **htblhdr)
5837 {
5838 unsigned int hash = (*htblhdr)->hstruct.hash;
5839 struct ArgusHashTable *table = (*htblhdr)->htbl;
5840 int ind = hash % table->size;
5841
5842 if (htblhdr && *htblhdr) {
5843 #ifdef ARGUSDEBUG
5844 ArgusDebug (6, "ArgusRemoveHashEntry (%p)\n", *htblhdr);
5845 #endif
5846
5847 #if defined(ARGUS_THREADS)
5848 pthread_mutex_lock(&table->lock);
5849 #endif
5850 if ((*htblhdr)->nxt == *htblhdr) {
5851 (*htblhdr)->nxt = NULL;
5852 (*htblhdr)->prv = NULL;
5853 if (*htblhdr == table->array[ind])
5854 table->array[ind] = NULL;
5855
5856 } else {
5857 (*htblhdr)->prv->nxt = (*htblhdr)->nxt;
5858 (*htblhdr)->nxt->prv = (*htblhdr)->prv;
5859
5860 if (*htblhdr == table->array[ind])
5861 table->array[ind] = (*htblhdr)->nxt;
5862 }
5863
5864 if ((*htblhdr)->hstruct.buf != NULL)
5865 ArgusFree ((*htblhdr)->hstruct.buf);
5866 ArgusFree (*htblhdr);
5867 *htblhdr = NULL;
5868
5869 #if defined(ARGUS_THREADS)
5870 pthread_mutex_unlock(&table->lock);
5871 #endif
5872 } else {
5873 #ifdef ARGUSDEBUG
5874 if (htblhdr == NULL)
5875 ArgusDebug (6, "ArgusRemoveHashEntry (NULL)\n");
5876 else
5877 ArgusDebug (6, "ArgusRemoveHashEntry (%p) passes NULL\n", htblhdr);
5878 #endif
5879 }
5880 }
5881
5882
5883 int
ArgusCheckTimeout(struct ArgusParserStruct * parser,struct ArgusRecordStruct * ns1,struct ArgusRecordStruct * ns2)5884 ArgusCheckTimeout (struct ArgusParserStruct *parser, struct ArgusRecordStruct *ns1, struct ArgusRecordStruct *ns2)
5885 {
5886 int retn = 0, lapseTime;
5887 struct timeval *tvp = &parser->ArgusGlobalTime;
5888
5889 int lapseTimeSecs, lapseTimeuSecs;
5890 int starTimeSecs, starTimeuSecs;
5891 int lastTimeSecs, lastTimeuSecs;
5892
5893 if (ns1->timeout > 0) {
5894 lapseTime = ns1->qhdr.lasttime.tv_sec + ns1->timeout;
5895
5896 if ((tvp->tv_sec > lapseTime) || ((tvp->tv_sec == lapseTime) &&
5897 (tvp->tv_usec > ns1->qhdr.lasttime.tv_usec))) {
5898 ns1->status |= ARGUS_STATUS;
5899 RaSendArgusRecord(ns1);
5900
5901 } else {
5902 starTimeSecs = ((struct ArgusTimeObject *)ns1->dsrs[ARGUS_TIME_INDEX])->src.start.tv_sec;
5903 starTimeuSecs = ((struct ArgusTimeObject *)ns1->dsrs[ARGUS_TIME_INDEX])->src.start.tv_usec;
5904
5905 if ((((struct ArgusTimeObject *)ns2->dsrs[ARGUS_TIME_INDEX])->src.end.tv_sec >
5906 ((struct ArgusTimeObject *)ns1->dsrs[ARGUS_TIME_INDEX])->src.end.tv_sec) ||
5907 ((((struct ArgusTimeObject *)ns2->dsrs[ARGUS_TIME_INDEX])->src.end.tv_sec ==
5908 ((struct ArgusTimeObject *)ns1->dsrs[ARGUS_TIME_INDEX])->src.end.tv_sec) &&
5909 (((struct ArgusTimeObject *)ns2->dsrs[ARGUS_TIME_INDEX])->src.end.tv_usec >
5910 ((struct ArgusTimeObject *)ns1->dsrs[ARGUS_TIME_INDEX])->src.end.tv_usec))) {
5911 lastTimeSecs = ((struct ArgusTimeObject *)ns2->dsrs[ARGUS_TIME_INDEX])->src.start.tv_sec;
5912 lastTimeuSecs = ((struct ArgusTimeObject *)ns2->dsrs[ARGUS_TIME_INDEX])->src.start.tv_usec;
5913
5914 } else {
5915 lastTimeSecs = ((struct ArgusTimeObject *)ns1->dsrs[ARGUS_TIME_INDEX])->src.start.tv_sec;
5916 lastTimeuSecs = ((struct ArgusTimeObject *)ns1->dsrs[ARGUS_TIME_INDEX])->src.start.tv_usec;
5917 }
5918
5919 lapseTimeSecs = (lastTimeSecs - starTimeSecs);
5920 lapseTimeuSecs = (lastTimeuSecs - starTimeuSecs);
5921
5922 if (lapseTimeuSecs < 0) {
5923 lapseTimeSecs--;
5924 lapseTimeuSecs += 1000000;
5925 }
5926
5927 if (lapseTimeSecs >= ns1->timeout) {
5928 ns1->status |= ARGUS_STATUS;
5929 RaSendArgusRecord(ns1);
5930 }
5931 }
5932 }
5933
5934 if (ns1->idle > 0) {
5935 lastTimeSecs = ((struct ArgusTimeObject *)ns1->dsrs[ARGUS_TIME_INDEX])->src.end.tv_sec;
5936 lastTimeuSecs = ((struct ArgusTimeObject *)ns1->dsrs[ARGUS_TIME_INDEX])->src.end.tv_usec;
5937
5938 if (lastTimeSecs > 0) {
5939 lapseTimeSecs = (tvp->tv_sec - lastTimeSecs);
5940 lapseTimeuSecs = (tvp->tv_usec - lastTimeuSecs);
5941
5942 if (lapseTimeSecs >= ns1->idle) {
5943 ns1->status |= ARGUS_TIMEOUT;
5944 retn++;
5945 }
5946 }
5947 }
5948
5949 #ifdef ARGUSDEBUG
5950 ArgusDebug (8, "RaCheckTimeout: returning %d \n", retn);
5951 #endif
5952
5953 return (retn);
5954 }
5955
5956 int ArgusProcessServiceAvailability (struct ArgusParserStruct *, struct ArgusRecordStruct *);
5957 int ArgusProcessTCPAvailability (struct ArgusParserStruct *, struct ArgusRecordStruct *);
5958 int ArgusProcessUDPAvailability (struct ArgusParserStruct *, struct ArgusRecordStruct *);
5959 int ArgusProcessESPAvailability (struct ArgusParserStruct *, struct ArgusRecordStruct *);
5960 int ArgusProcessICMPAvailability (struct ArgusParserStruct *, struct ArgusRecordStruct *);
5961 int ArgusProcessIPAvailability (struct ArgusParserStruct *, struct ArgusRecordStruct *);
5962 int ArgusProcessARPAvailability (struct ArgusParserStruct *, struct ArgusRecordStruct *);
5963
5964 int
ArgusProcessServiceAvailability(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus)5965 ArgusProcessServiceAvailability (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus)
5966 {
5967 struct ArgusFlow *flow = (struct ArgusFlow *)argus->dsrs[ARGUS_FLOW_INDEX];
5968 int retn = 1;
5969
5970 argus->status &= ~(RA_SVCPASSED | RA_SVCFAILED);
5971 if (flow == NULL)
5972 return retn;
5973
5974 switch (flow->hdr.subtype & 0x3F) {
5975 case ARGUS_FLOW_CLASSIC5TUPLE: {
5976 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
5977 case ARGUS_TYPE_IPV4: {
5978 switch (flow->ip_flow.ip_p) {
5979 case IPPROTO_TCP:
5980 argus->status |= ArgusProcessTCPAvailability (parser, argus);
5981 break;
5982 case IPPROTO_ICMP:
5983 argus->status |= ArgusProcessICMPAvailability (parser, argus);
5984 break;
5985 case IPPROTO_UDP:
5986 argus->status |= ArgusProcessUDPAvailability (parser, argus);
5987 break;
5988 case IPPROTO_ESP:
5989 argus->status |= ArgusProcessESPAvailability (parser, argus);
5990 break;
5991 default:
5992 argus->status |= ArgusProcessIPAvailability (parser, argus);
5993 break;
5994 }
5995 break;
5996 }
5997 case ARGUS_TYPE_IPV6: {
5998 switch (flow->ipv6_flow.ip_p) {
5999 case IPPROTO_TCP:
6000 argus->status |= ArgusProcessTCPAvailability (parser, argus);
6001 break;
6002 case IPPROTO_ICMP:
6003 argus->status |= ArgusProcessICMPAvailability (parser, argus);
6004 break;
6005 case IPPROTO_UDP:
6006 argus->status |= ArgusProcessUDPAvailability (parser, argus);
6007 break;
6008 default:
6009 argus->status |= ArgusProcessIPAvailability (parser, argus);
6010 break;
6011 }
6012 break;
6013 }
6014 case ARGUS_TYPE_RARP:
6015 case ARGUS_TYPE_ARP:
6016 argus->status |= ArgusProcessARPAvailability (parser, argus);
6017 break;
6018
6019 case ARGUS_TYPE_ETHER:
6020 break;
6021 }
6022 break;
6023 }
6024
6025 case ARGUS_FLOW_ARP: {
6026 argus->status |= ArgusProcessARPAvailability (parser, argus);
6027 break;
6028 }
6029
6030 default:
6031 break;
6032 }
6033
6034
6035 #ifdef ARGUSDEBUG
6036 ArgusDebug (8, "ArgusProcessServiceAvailability: returning %d \n", retn);
6037 #endif
6038
6039 return (retn);
6040 }
6041
6042
6043 int
ArgusProcessTCPAvailability(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus)6044 ArgusProcessTCPAvailability (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus)
6045 {
6046 struct ArgusMetricStruct *metric = (struct ArgusMetricStruct *)argus->dsrs[ARGUS_METRIC_INDEX];
6047 struct ArgusNetworkStruct *net = (struct ArgusNetworkStruct *)argus->dsrs[ARGUS_NETWORK_INDEX];
6048 int retn = RA_SVCPASSED, status = 0;
6049
6050 if (net == NULL)
6051 return retn;
6052
6053 switch (net->hdr.subtype) {
6054 case ARGUS_TCP_INIT:
6055 case ARGUS_TCP_STATUS:
6056 case ARGUS_TCP_PERF: {
6057 struct ArgusTCPObject *tcp = (struct ArgusTCPObject *)&net->net_union.tcp;
6058 status = tcp->status;
6059 break;
6060 }
6061
6062 default:
6063 return(retn);
6064 }
6065
6066 if (status & ARGUS_SAW_SYN) {
6067 if (status & ARGUS_RESET) {
6068 if (status & ARGUS_DST_RESET) {
6069 if (!(status & ARGUS_SAW_SYN_SENT))
6070 retn = RA_SVCFAILED;
6071 } else {
6072 if (metric->src.pkts && !(metric->dst.pkts))
6073 retn = RA_SVCFAILED;
6074 }
6075 } else {
6076 if (!(status & (ARGUS_SAW_SYN_SENT | ARGUS_CON_ESTABLISHED)))
6077 retn = RA_SVCFAILED;
6078 }
6079
6080 } else {
6081 if (status & (ARGUS_SAW_SYN | ARGUS_SAW_SYN_SENT)) {
6082 if (metric->src.pkts && !(metric->dst.pkts))
6083 retn = RA_SVCFAILED;
6084 }
6085 }
6086
6087 if (status & ARGUS_TIMEOUT)
6088 if (metric->src.pkts && !(metric->dst.pkts))
6089 retn = RA_SVCFAILED;
6090
6091 #ifdef ARGUSDEBUG
6092 ArgusDebug (8, "ArgusProcessTCPAvailability: returning %d \n", retn);
6093 #endif
6094
6095 return (retn);
6096 }
6097
6098 int ArgusTestMulticast( struct ArgusInput *input, unsigned int);
6099
6100 int
ArgusTestMulticast(struct ArgusInput * input,unsigned int addr)6101 ArgusTestMulticast( struct ArgusInput *input, unsigned int addr)
6102 {
6103 int retn = 0;
6104
6105 if (input != NULL) {
6106 if (input->ArgusLocalNet || input->ArgusNetMask) {
6107 u_int netaddr = 0xffffffffL;
6108
6109 netaddr = input->ArgusLocalNet & input->ArgusNetMask;
6110
6111 if (netaddr)
6112 if ((addr & netaddr) == netaddr)
6113 retn = ((addr & ~input->ArgusNetMask) == (INADDR_BROADCAST & ~input->ArgusNetMask));
6114 }
6115 }
6116
6117 if (retn)
6118 return (retn);
6119
6120 if (IN_MULTICAST(addr))
6121 return 1;
6122
6123 if (INADDR_BROADCAST == addr)
6124 return 1;
6125
6126 if (IN_CLASSA(addr))
6127 return ((addr & IN_CLASSA_HOST) == (INADDR_BROADCAST & IN_CLASSA_HOST));
6128
6129 if (IN_CLASSB(addr))
6130 return ((addr & IN_CLASSB_HOST) == (INADDR_BROADCAST & IN_CLASSB_HOST));
6131
6132 if (IN_CLASSC(addr))
6133 return ((addr & IN_CLASSC_HOST) == (INADDR_BROADCAST & IN_CLASSC_HOST));
6134
6135 #if defined(IN_CLASSD) && defined(IN_CLASSD_HOST)
6136 if (IN_CLASSD(addr))
6137 return ((addr & IN_CLASSD_HOST) == (INADDR_BROADCAST & IN_CLASSD_HOST));
6138 #endif
6139
6140 return 0;
6141 }
6142
6143 int
ArgusProcessESPAvailability(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus)6144 ArgusProcessESPAvailability (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus)
6145 {
6146 return RA_SVCPASSED;
6147 }
6148
6149 #define UDP_PORT_BOOTPS 67
6150 #define UDP_PORT_BOOTPC 68
6151
6152 int
ArgusProcessUDPAvailability(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus)6153 ArgusProcessUDPAvailability (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus)
6154 {
6155 struct ArgusMetricStruct *metric = (struct ArgusMetricStruct *)argus->dsrs[ARGUS_METRIC_INDEX];
6156 struct ArgusFlow *flow = (struct ArgusFlow *)argus->dsrs[ARGUS_FLOW_INDEX];
6157 int retn = RA_SVCPASSED;
6158
6159 switch (flow->hdr.subtype & 0x3F) {
6160 case ARGUS_FLOW_CLASSIC5TUPLE: {
6161 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
6162 case ARGUS_TYPE_IPV4: {
6163 if (!(ArgusTestMulticast(argus->input, flow->ip_flow.ip_dst))) {
6164 switch (flow->ip_flow.dport) {
6165 case UDP_PORT_BOOTPS:
6166 if (flow->ip_flow.sport == UDP_PORT_BOOTPC)
6167 return retn;
6168 case UDP_PORT_BOOTPC:
6169 if (flow->ip_flow.sport == UDP_PORT_BOOTPS)
6170 return retn;
6171 }
6172
6173 if (!metric->src.pkts || !metric->dst.pkts) {
6174 retn = RA_SVCFAILED;
6175 }
6176 }
6177 break;
6178 }
6179
6180 case ARGUS_TYPE_IPV6: {
6181 break;
6182 }
6183 }
6184 }
6185 }
6186
6187
6188
6189 #ifdef ARGUSDEBUG
6190 ArgusDebug (8, "ArgusProcessUDPAvailability: returning %d \n", retn);
6191 #endif
6192
6193 return (retn);
6194 }
6195
6196 int
ArgusProcessICMPAvailability(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus)6197 ArgusProcessICMPAvailability (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus)
6198 {
6199 struct ArgusMetricStruct *metric = (struct ArgusMetricStruct *)argus->dsrs[ARGUS_METRIC_INDEX];
6200 struct ArgusFlow *flow = (struct ArgusFlow *)argus->dsrs[ARGUS_FLOW_INDEX];
6201 int retn = RA_SVCPASSED;
6202
6203 switch (flow->hdr.subtype & 0x3F) {
6204 case ARGUS_FLOW_CLASSIC5TUPLE: {
6205 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
6206 case ARGUS_TYPE_IPV4: {
6207 struct ArgusICMPFlow *icmp = (struct ArgusICMPFlow *) &flow->icmp_flow;
6208 switch (icmp->type) {
6209 case ICMP_UNREACH:
6210 case ICMP_REDIRECT:
6211 case ICMP_ROUTERADVERT:
6212 case ICMP_TIMXCEED:
6213 case ICMP_PARAMETERPROB:
6214 break;
6215
6216 default:
6217 if (!metric->src.pkts || !metric->dst.pkts)
6218 retn = RA_SVCFAILED;
6219
6220 if (parser->vflag && (metric->src.pkts != metric->dst.pkts))
6221 retn = RA_SVCFAILED;
6222 break;
6223 }
6224 break;
6225 }
6226
6227 case ARGUS_TYPE_IPV6: {
6228 // struct ArgusICMPv6Flow *icmpv6 = (struct ArgusICMPv6Flow *) flow;
6229 break;
6230 }
6231 }
6232 }
6233 }
6234
6235 #ifdef ARGUSDEBUG
6236 ArgusDebug (8, "ArgusProcessICMPAvailability: returning %d \n", retn);
6237 #endif
6238
6239 return (retn);
6240 }
6241
6242 int
ArgusProcessIPAvailability(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus)6243 ArgusProcessIPAvailability (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus)
6244 {
6245 struct ArgusMetricStruct *metric = (struct ArgusMetricStruct *)argus->dsrs[ARGUS_METRIC_INDEX];
6246 int retn = RA_SVCPASSED;
6247
6248 if (metric->src.pkts && !metric->dst.pkts)
6249 retn = RA_SVCFAILED;
6250
6251 #ifdef ARGUSDEBUG
6252 ArgusDebug (8, "ArgusProcessIPAvailability: returning %d \n", retn);
6253 #endif
6254
6255 return (retn);
6256 }
6257
6258 int
ArgusProcessARPAvailability(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus)6259 ArgusProcessARPAvailability (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus)
6260 {
6261 // struct ArgusMetricStruct *metric = (struct ArgusMetricStruct *)argus->dsrs[ARGUS_METRIC_INDEX];
6262 int retn = RA_SVCPASSED;
6263
6264 // if (!metric->src.pkts || !metric->dst.pkts)
6265 // retn = RA_SVCFAILED;
6266
6267 #ifdef ARGUSDEBUG
6268 ArgusDebug (8, "ArgusProcessARPAvailability: returning %d \n", retn);
6269 #endif
6270
6271 return (retn);
6272 }
6273
6274 struct timeval *
RaGetStartTime(struct ArgusRecordStruct * argus,struct timeval * tvp)6275 RaGetStartTime (struct ArgusRecordStruct *argus, struct timeval *tvp)
6276 {
6277 if ((argus != NULL) && (tvp != NULL)) {
6278 double retn = ArgusFetchStartuSecTime(argus);
6279 tvp->tv_sec = retn / 1000000;
6280 tvp->tv_usec = retn - (tvp->tv_sec * 1000000LL);
6281 return (tvp);
6282 } else
6283 return (NULL);
6284 }
6285
6286 struct timeval *
RaGetLastTime(struct ArgusRecordStruct * argus,struct timeval * tvp)6287 RaGetLastTime (struct ArgusRecordStruct *argus, struct timeval *tvp)
6288 {
6289 if ((argus != NULL) && (tvp != NULL)) {
6290 double retn = ArgusFetchStartuSecTime(argus);
6291 tvp->tv_sec = retn / 1000000;
6292 tvp->tv_usec = retn - (tvp->tv_sec * 1000000LL);
6293 return (tvp);
6294 } else
6295 return (NULL);
6296 }
6297
6298 long long RaGetuSecMean (struct ArgusRecordStruct *);
6299 long long RaGetuSecDeltaDuration (struct ArgusRecordStruct *);
6300
6301 long long
RaGetActiveDuration(struct ArgusRecordStruct * argus)6302 RaGetActiveDuration (struct ArgusRecordStruct *argus)
6303 {
6304 long long retn = 0;
6305
6306 return (retn);
6307 }
6308
6309
6310 long long
RaGetuSecMean(struct ArgusRecordStruct * argus)6311 RaGetuSecMean (struct ArgusRecordStruct *argus)
6312 {
6313 long long retn = 0;
6314
6315 return (retn);
6316 }
6317
6318
6319 long long
RaGetuSecDeltaDuration(struct ArgusRecordStruct * argus)6320 RaGetuSecDeltaDuration (struct ArgusRecordStruct *argus)
6321 {
6322 long long retn = 0;
6323
6324 return (retn);
6325 }
6326
6327 long long
RaGetuSecDuration(struct ArgusRecordStruct * argus)6328 RaGetuSecDuration (struct ArgusRecordStruct *argus)
6329 {
6330 long long ltime = ArgusFetchLastuSecTime(argus);
6331 long long stime = ArgusFetchStartuSecTime(argus);
6332 return (ltime - stime);
6333 }
6334
6335 char RaUserDataStr[MAXBUFFERLEN];
6336
6337 char *
RaGetUserDataString(struct ArgusRecordStruct * argus)6338 RaGetUserDataString (struct ArgusRecordStruct *argus)
6339 {
6340 char *retn = RaUserDataStr;
6341 return (retn);
6342 }
6343
6344
6345 // Format is "[abs] metric bins[L][:range]" or "[abs] metric bins[:size]"
6346 // range is value-value and size if just a single number. Value is
6347 // %f[umsMHD] or %f[umKMG] depending on the type of metric used.
6348 //
6349 // If the format simply provides the number of bins, the range/size
6350 // part is determined from the data. When this occurs the routine returns
6351 //
6352 // ARGUS_HISTO_RANGE_UNSPECIFIED
6353 //
6354 // and the program needs to determine its own range.
6355 //
6356 // Appropriate metrics are any metrics support for sorting.
6357
6358
6359 int ArgusHistoMetricParse (struct ArgusParserStruct *, struct ArgusAggregatorStruct *);
6360
6361 int
ArgusHistoMetricParse(struct ArgusParserStruct * parser,struct ArgusAggregatorStruct * agr)6362 ArgusHistoMetricParse (struct ArgusParserStruct *parser, struct ArgusAggregatorStruct *agr)
6363 {
6364 char *ptr, *vptr, tmpbuf[128], *tmp = tmpbuf;
6365 char *str = parser->Hstr, *endptr = NULL;
6366 char *metric = NULL;
6367 int retn = 0, keyword;
6368
6369 bzero (tmpbuf, 128);
6370 snprintf (tmpbuf, 128, "%s", str);
6371
6372 if ((ptr = strstr (tmp, "abs ")) != NULL) {
6373 agr->AbsoluteValue++;
6374 tmp = ptr + 4;
6375 }
6376
6377 if ((ptr = strchr (tmp, ' ')) != NULL) {
6378 int x, found = 0;
6379 metric = tmp;
6380 *ptr++ = '\0';
6381 tmp = ptr;
6382
6383 for (x = 0; x < MAX_METRIC_ALG_TYPES; x++) {
6384 if (!strncmp(RaFetchAlgorithmTable[x].field, metric, strlen(metric))) {
6385 agr->RaMetricFetchAlgorithm = RaFetchAlgorithmTable[x].fetch;
6386 agr->ArgusMetricIndex = x;
6387 keyword = x;
6388 found++;
6389 break;
6390 }
6391 }
6392 if (!found)
6393 usage();
6394
6395 if ((ptr = strchr (tmp, ':')) != NULL) {
6396 *ptr++ = '\0';
6397 vptr = ptr;
6398
6399 if (strchr (tmp, 'L'))
6400 parser->RaHistoMetricLog++;
6401
6402 if (isdigit((int)*tmp))
6403 if ((parser->RaHistoBins = atoi(tmp)) < 0)
6404 return (retn);
6405
6406 // Need to add code to deal with ranges that include negative numbers
6407 // So parse a number, then check for the -, then parse another number
6408 // if needed.
6409
6410 parser->RaHistoStart = strtod(vptr, &endptr);
6411 if (endptr == vptr)
6412 return (retn);
6413
6414 vptr = endptr;
6415 if ((ptr = strchr (vptr, '-')) != NULL) {
6416 *ptr++ = '\0';
6417 parser->RaHistoEnd = strtod(ptr, &endptr);
6418 if (endptr == ptr)
6419 return (retn);
6420 } else {
6421 parser->RaHistoBinSize = parser->RaHistoStart;
6422 parser->RaHistoStart = 0.0;
6423 parser->RaHistoEnd = parser->RaHistoBinSize * (parser->RaHistoBins * 1.0);
6424 }
6425
6426 switch (*endptr) {
6427 case 'u': parser->RaHistoStart *= 0.000001;
6428 parser->RaHistoEnd *= 0.000001; break;
6429 case 'm': parser->RaHistoStart *= 0.001;
6430 parser->RaHistoEnd *= 0.001; break;
6431 case 's': parser->RaHistoStart *= 1.0;
6432 parser->RaHistoEnd *= 1.0; break;
6433 case 'M': {
6434 switch (keyword) {
6435 case ARGUSMETRICSTARTTIME:
6436 case ARGUSMETRICLASTTIME:
6437 case ARGUSMETRICDURATION:
6438 case ARGUSMETRICMEAN:
6439 case ARGUSMETRICMIN:
6440 case ARGUSMETRICMAX:
6441 parser->RaHistoStart *= 60.0;
6442 parser->RaHistoEnd *= 60.0;
6443 break;
6444
6445 default:
6446 parser->RaHistoStart *= 1000000.0;
6447 parser->RaHistoEnd *= 1000000.0;
6448 break;
6449 }
6450 break;
6451 }
6452 case 'H': parser->RaHistoStart *= 3600.0;
6453 parser->RaHistoEnd *= 3600.0; break;
6454 case 'D': parser->RaHistoStart *= 86400.0;
6455 parser->RaHistoEnd *= 86400.0; break;
6456 case 'K': parser->RaHistoStart *= 1000.0;
6457 parser->RaHistoEnd *= 1000.0; break;
6458 case 'G': parser->RaHistoStart *= 1000000000.0;
6459 parser->RaHistoEnd *= 1000000000.0; break;
6460 case ' ':
6461 case '\0': break;
6462
6463 default:
6464 return (retn);
6465 }
6466
6467 retn = 1;
6468
6469 } else {
6470 if (isdigit((int)*tmp))
6471 if ((parser->RaHistoBins = atoi(tmp)) < 0)
6472 return (retn);
6473
6474 retn = ARGUS_HISTO_RANGE_UNSPECIFIED;
6475 }
6476
6477 if ((parser->RaHistoRecords = (struct ArgusRecordStruct **) ArgusCalloc (parser->RaHistoBins + 2, sizeof(struct ArgusRecordStruct *))) != NULL) {
6478 parser->RaHistoRangeState = retn;
6479
6480 if (parser->RaHistoMetricLog) {
6481 parser->RaHistoEndLog = log10(parser->RaHistoEnd);
6482
6483 if (parser->RaHistoStart > 0) {
6484 parser->RaHistoStartLog = log10(parser->RaHistoStart);
6485 } else {
6486 parser->RaHistoLogInterval = (parser->RaHistoEndLog/(parser->RaHistoBins * 1.0));
6487 parser->RaHistoStartLog = parser->RaHistoEndLog - (parser->RaHistoLogInterval * parser->RaHistoBins);
6488 }
6489
6490 parser->RaHistoBinSize = (parser->RaHistoEndLog - parser->RaHistoStartLog) / parser->RaHistoBins * 1.0;
6491
6492 } else
6493 parser->RaHistoBinSize = ((parser->RaHistoEnd - parser->RaHistoStart) * 1.0) / parser->RaHistoBins * 1.0;
6494
6495 } else
6496 ArgusLog (LOG_ERR, "RaHistoMetricParse: ArgusCalloc %s\n", strerror(errno));
6497 }
6498
6499 #ifdef ARGUSDEBUG
6500 ArgusDebug (3, "ArgusHistoMetricParse(%p): returning %d \n", parser, retn);
6501 #endif
6502 return (retn);
6503 }
6504
6505
6506 int
ArgusHistoTallyMetric(struct ArgusParserStruct * parser,struct ArgusRecordStruct * ns,double value)6507 ArgusHistoTallyMetric (struct ArgusParserStruct *parser, struct ArgusRecordStruct *ns, double value)
6508 {
6509 int retn = 0, i = 0;
6510 double start, end, bsize;
6511 double iptr;
6512
6513 if (parser && (ns != NULL)) {
6514 bsize = parser->RaHistoBinSize;
6515
6516 if (parser->RaHistoMetricLog) {
6517 value = log10(value);
6518 start = parser->RaHistoStartLog;
6519 end = parser->RaHistoEndLog;
6520 } else {
6521 start = parser->RaHistoStart;
6522 end = parser->RaHistoEnd;
6523 }
6524
6525 if (value > start) {
6526 modf((value - start)/bsize, &iptr);
6527
6528 if ((i = iptr) > parser->RaHistoBins)
6529 i = parser->RaHistoBins + 1;
6530
6531 if (value < (end + bsize))
6532 i++;
6533 } else {
6534 i = 0;
6535 }
6536 }
6537
6538 if (parser->RaHistoRecords[i] != NULL) {
6539 ArgusMergeRecords (parser->ArgusAggregator, parser->RaHistoRecords[i], ns);
6540 } else
6541 parser->RaHistoRecords[i] = ArgusCopyRecordStruct(ns);
6542
6543 #ifdef ARGUSDEBUG
6544 ArgusDebug (3, "ArgusHistoTallyMetric(%p, %p): returning %d\n", parser, ns, retn);
6545 #endif
6546 return (retn);
6547 }
6548
6549 struct RaPolicyStruct *
RaFlowModelOverRides(struct ArgusAggregatorStruct * na,struct ArgusRecordStruct * ns)6550 RaFlowModelOverRides(struct ArgusAggregatorStruct *na, struct ArgusRecordStruct *ns)
6551 {
6552 struct RaPolicyStruct *retn = NULL;
6553
6554 return (retn);
6555 }
6556
6557
6558 void
ArgusGenerateNewFlow(struct ArgusAggregatorStruct * na,struct ArgusRecordStruct * ns)6559 ArgusGenerateNewFlow(struct ArgusAggregatorStruct *na, struct ArgusRecordStruct *ns)
6560 {
6561 struct ArgusFlow tflow, *flow = (struct ArgusFlow *)ns->dsrs[ARGUS_FLOW_INDEX];
6562 int i = 0, x = 0, len = 0;
6563
6564 bzero ((char *)&tflow, sizeof(tflow));
6565
6566 na->ArgusMaskDefs = ArgusSelectMaskDefs(ns);
6567
6568 if (na->mask && (flow != NULL)) {
6569 len = flow->hdr.argus_dsrvl8.len * 4;
6570
6571 if (na->pres == NULL)
6572 bcopy ((char *)&flow->hdr, (char *)&tflow.hdr, sizeof(flow->hdr));
6573 else
6574 bcopy ((char *)&flow->hdr, (char *)&tflow.hdr, len);
6575
6576 if (!(na->mask & (ARGUS_MASK_SADDR_INDEX | ARGUS_MASK_DADDR_INDEX | ARGUS_MASK_PROTO_INDEX | ARGUS_MASK_SPORT_INDEX | ARGUS_MASK_DPORT_INDEX))) {
6577 tflow.hdr.subtype &= 0x3F;
6578 tflow.hdr.argus_dsrvl8.qual &= 0x1F;
6579 }
6580 for (i = 0; i < ARGUS_MAX_MASK_LIST; i++) {
6581 if (na->mask < (0x01LL << i))
6582 break;
6583 if (na->mask & (0x01LL << i)) {
6584 switch(i) {
6585 case ARGUS_MASK_SADDR:
6586 switch(flow->hdr.subtype & 0x3F) {
6587 case ARGUS_FLOW_LAYER_3_MATRIX:
6588 case ARGUS_FLOW_CLASSIC5TUPLE: {
6589 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
6590 case ARGUS_TYPE_IPV4: {
6591 if (sizeof(tflow.ip_flow) > len)
6592 ArgusLog (LOG_ERR, "ArgusGenerateNewFlow: buf %d not big enough %d\n", len, sizeof(tflow.ip_flow));
6593
6594 tflow.ip_flow.ip_src = flow->ip_flow.ip_src;
6595 tflow.ip_flow.smask = flow->ip_flow.smask ;
6596 if ((na->saddrlen > 0) && (na->saddrlen < tflow.ip_flow.smask)) {
6597 tflow.ip_flow.ip_src &= na->smask.addr_un.ipv4;
6598 tflow.ip_flow.smask = na->saddrlen;
6599 }
6600 break;
6601 }
6602
6603 case ARGUS_TYPE_IPV6: {
6604 if (sizeof(tflow.ipv6_flow) > len)
6605 ArgusLog (LOG_ERR, "ArgusGenerateNewFlow: buf %d not big enough %d\n", len, sizeof(tflow.ipv6_flow));
6606 for (x = 0; x < 4; x++)
6607 tflow.ipv6_flow.ip_src[x] = flow->ipv6_flow.ip_src[x];
6608
6609 tflow.ipv6_flow.smask = flow->ipv6_flow.smask;
6610 if ((na->saddrlen > 0) && (na->saddrlen < tflow.ipv6_flow.smask)) {
6611 for (x = 0; x < 4; x++)
6612 tflow.ipv6_flow.ip_src[x] &= ntohl(na->smask.addr_un.ipv6[x]);
6613 tflow.ipv6_flow.smask = na->saddrlen;
6614 }
6615 break;
6616 }
6617
6618 case ARGUS_TYPE_RARP: {
6619 if (sizeof(tflow.rarp_flow) > len)
6620 ArgusLog (LOG_ERR, "ArgusGenerateNewFlow: buf %d not big enough %d\n", len, sizeof(tflow.rarp_flow));
6621 bcopy (&flow->rarp_flow.shaddr, &tflow.rarp_flow.shaddr, tflow.rarp_flow.hln);
6622 break;
6623 }
6624
6625 case ARGUS_TYPE_ETHER: {
6626 if (sizeof(tflow.mac_flow) > len)
6627 ArgusLog (LOG_ERR, "ArgusGenerateNewFlow: buf %d not big enough %d\n", len, sizeof(tflow.mac_flow));
6628 bcopy (&flow->mac_flow.mac_union.ether.ehdr.ether_shost,
6629 &tflow.mac_flow.mac_union.ether.ehdr.ether_shost,
6630 sizeof(tflow.mac_flow.mac_union.ether.ehdr.ether_shost));
6631 break;
6632 }
6633
6634 case ARGUS_TYPE_WLAN: {
6635 if (sizeof(tflow.wlan_flow) > len)
6636 ArgusLog (LOG_ERR, "ArgusGenerateNewFlow: buf %d not big enough %d\n", len, sizeof(tflow.wlan_flow));
6637 bcopy (&flow->wlan_flow.shost, &tflow.wlan_flow.shost, sizeof(tflow.wlan_flow.shost));
6638 break;
6639 }
6640
6641 case ARGUS_TYPE_ISIS: {
6642 struct ArgusIsisFlow *isis = (struct ArgusIsisFlow *) &flow->isis_flow;
6643 bcopy (flow->isis_flow.esrc, tflow.isis_flow.esrc, ETHER_ADDR_LEN);
6644 switch (isis->pdu_type) {
6645 case L1_LAN_IIH:
6646 case L2_LAN_IIH:
6647 bcopy (flow->isis_flow.isis_un.hello.srcid,
6648 tflow.isis_flow.isis_un.hello.srcid, SYSTEM_ID_LEN);
6649 break;
6650 case L1_CSNP:
6651 case L2_CSNP:
6652 bcopy (flow->isis_flow.isis_un.csnp.srcid,
6653 tflow.isis_flow.isis_un.csnp.srcid, NODE_ID_LEN);
6654 break;
6655 case L1_PSNP:
6656 case L2_PSNP:
6657 bcopy (flow->isis_flow.isis_un.psnp.srcid,
6658 tflow.isis_flow.isis_un.psnp.srcid, NODE_ID_LEN);
6659 break;
6660
6661 case L1_LSP:
6662 case L2_LSP:
6663 bcopy (flow->isis_flow.isis_un.lsp.lspid,
6664 tflow.isis_flow.isis_un.lsp.lspid, LSP_ID_LEN);
6665 break;
6666 }
6667 break;
6668 }
6669 }
6670 break;
6671 }
6672 case ARGUS_FLOW_ARP: {
6673 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
6674 case ARGUS_TYPE_RARP: {
6675 bcopy (&flow->rarp_flow.shaddr, &tflow.rarp_flow.shaddr, tflow.rarp_flow.hln);
6676 break;
6677 }
6678
6679 case ARGUS_TYPE_ARP: {
6680 tflow.arp_flow.pln = flow->arp_flow.pln;
6681 tflow.arp_flow.arp_spa = flow->arp_flow.arp_spa;
6682 break;
6683 }
6684 }
6685 break;
6686 }
6687 }
6688 break;
6689
6690 case ARGUS_MASK_DADDR:
6691 switch(flow->hdr.subtype & 0x3F) {
6692 case ARGUS_FLOW_LAYER_3_MATRIX:
6693 case ARGUS_FLOW_CLASSIC5TUPLE: {
6694 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
6695 case ARGUS_TYPE_IPV4:
6696 tflow.ip_flow.ip_dst = flow->ip_flow.ip_dst;
6697 tflow.ip_flow.dmask = flow->ip_flow.dmask;
6698 if ((na->daddrlen > 0) && (na->daddrlen < tflow.ip_flow.dmask)) {
6699 tflow.ip_flow.ip_dst &= na->dmask.addr_un.ipv4;
6700 tflow.ip_flow.dmask = na->daddrlen;
6701 }
6702
6703 break;
6704
6705 case ARGUS_TYPE_IPV6:
6706 if (sizeof(tflow.ipv6_flow) > len)
6707 ArgusLog (LOG_ERR, "ArgusGenerateNewFlow: buf %d not big enough %d\n", len, sizeof(tflow.ipv6_flow));
6708 for (x = 0; x < 4; x++)
6709 tflow.ipv6_flow.ip_dst[x] = flow->ipv6_flow.ip_dst[x];
6710
6711 tflow.ipv6_flow.dmask = flow->ipv6_flow.dmask;
6712 if ((na->daddrlen > 0) && (na->daddrlen < tflow.ipv6_flow.dmask)) {
6713 for (x = 0; x < 4; x++)
6714 tflow.ipv6_flow.ip_dst[x] &= ntohl(na->dmask.addr_un.ipv6[x]);
6715 tflow.ipv6_flow.dmask = na->daddrlen;
6716 }
6717 break;
6718
6719 case ARGUS_TYPE_RARP:
6720 bcopy (&flow->rarp_flow.dhaddr, &tflow.rarp_flow.dhaddr, tflow.rarp_flow.hln);
6721 break;
6722 case ARGUS_TYPE_ARP:
6723 tflow.arp_flow.arp_tpa = flow->arp_flow.arp_tpa;
6724 break;
6725
6726 case ARGUS_TYPE_ETHER:
6727 bcopy (&flow->mac_flow.mac_union.ether.ehdr.ether_dhost,
6728 &tflow.mac_flow.mac_union.ether.ehdr.ether_dhost,
6729 sizeof(tflow.mac_flow.mac_union.ether.ehdr.ether_dhost));
6730 break;
6731
6732 case ARGUS_TYPE_WLAN: {
6733 if (sizeof(tflow.wlan_flow) > len)
6734 ArgusLog (LOG_ERR, "ArgusGenerateNewFlow: buf %d not big enough %d\n", len, sizeof(tflow.wlan_flow));
6735 bcopy (&flow->wlan_flow.dhost, &tflow.wlan_flow.dhost, sizeof(tflow.wlan_flow.dhost));
6736 break;
6737 }
6738
6739 case ARGUS_TYPE_ISIS: {
6740 struct ArgusIsisFlow *isis = (struct ArgusIsisFlow *) &flow->isis_flow;
6741 bcopy (flow->isis_flow.edst, tflow.isis_flow.edst, ETHER_ADDR_LEN);
6742 switch (isis->pdu_type) {
6743 case L1_LAN_IIH:
6744 case L2_LAN_IIH:
6745 bcopy (flow->isis_flow.isis_un.hello.lanid,
6746 tflow.isis_flow.isis_un.hello.lanid, NODE_ID_LEN);
6747 break;
6748
6749 case L1_CSNP:
6750 case L2_CSNP:
6751 case L1_PSNP:
6752 case L2_PSNP:
6753 break;
6754
6755 case L1_LSP:
6756 case L2_LSP:
6757 tflow.isis_flow.isis_un.lsp.seqnum = flow->isis_flow.isis_un.lsp.seqnum;
6758 break;
6759 }
6760 break;
6761 }
6762 }
6763 break;
6764 }
6765
6766 case ARGUS_FLOW_ARP: {
6767 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
6768 case ARGUS_TYPE_RARP: {
6769 bcopy (&flow->rarp_flow.dhaddr, &tflow.rarp_flow.dhaddr, tflow.rarp_flow.hln);
6770 break;
6771 }
6772
6773 case ARGUS_TYPE_ARP: {
6774 tflow.arp_flow.arp_tpa = flow->arp_flow.arp_tpa;
6775 break;
6776 }
6777 }
6778 break;
6779
6780 }
6781 }
6782 break;
6783
6784 case ARGUS_MASK_PROTO:
6785 switch(flow->hdr.subtype & 0x3F) {
6786 case ARGUS_FLOW_CLASSIC5TUPLE: {
6787 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
6788 case ARGUS_TYPE_IPV4:
6789 tflow.ip_flow.ip_p = flow->ip_flow.ip_p;
6790 break;
6791 case ARGUS_TYPE_IPV6: {
6792 tflow.ipv6_flow.ip_p = flow->ipv6_flow.ip_p;
6793 break;
6794 }
6795 case ARGUS_TYPE_ETHER:
6796 tflow.mac_flow.mac_union.ether.ehdr.ether_type = flow->mac_flow.mac_union.ether.ehdr.ether_type;
6797 break;
6798
6799 case ARGUS_TYPE_ISIS:
6800 tflow.isis_flow.pdu_type = flow->isis_flow.pdu_type;
6801 break;
6802 }
6803 break;
6804 }
6805 case ARGUS_FLOW_ARP: {
6806 tflow.arp_flow.pro = flow->arp_flow.pro;
6807 break;
6808 }
6809 break;
6810 }
6811 break;
6812
6813 case ARGUS_MASK_SPORT:
6814 switch(flow->hdr.subtype & 0x3F) {
6815 case ARGUS_FLOW_CLASSIC5TUPLE: {
6816 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
6817 case ARGUS_TYPE_IPV4:
6818 switch (flow->ip_flow.ip_p) {
6819 case IPPROTO_ESP: {
6820 break;
6821 }
6822 default:
6823 tflow.ip_flow.sport = flow->ip_flow.sport;
6824 break;
6825 }
6826 break;
6827 case ARGUS_TYPE_IPV6: tflow.ipv6_flow.sport = flow->ipv6_flow.sport; break;
6828 case ARGUS_TYPE_ETHER:
6829 tflow.mac_flow.mac_union.ether.ssap = flow->mac_flow.mac_union.ether.ssap;
6830 break;
6831
6832 case ARGUS_TYPE_WLAN:
6833 bcopy(flow->wlan_flow.ssid, tflow.wlan_flow.ssid, sizeof(flow->wlan_flow.ssid));
6834 break;
6835
6836 case ARGUS_TYPE_ISIS:
6837 tflow.isis_flow.chksum = flow->isis_flow.chksum;
6838 break;
6839 }
6840 break;
6841 }
6842 case ARGUS_FLOW_ARP: {
6843 break;
6844 }
6845 break;
6846 }
6847 break;
6848
6849 case ARGUS_MASK_DPORT:
6850 switch(flow->hdr.subtype & 0x3F) {
6851 case ARGUS_FLOW_CLASSIC5TUPLE: {
6852 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
6853 case ARGUS_TYPE_IPV4:
6854 switch (flow->ip_flow.ip_p) {
6855 case IPPROTO_ESP: {
6856 tflow.esp_flow.spi = flow->esp_flow.spi;
6857 break;
6858 }
6859 default:
6860 tflow.ip_flow.dport = flow->ip_flow.dport;
6861 break;
6862 }
6863 break;
6864
6865 case ARGUS_TYPE_IPV6: tflow.ipv6_flow.dport = flow->ipv6_flow.dport; break;
6866 case ARGUS_TYPE_ETHER:
6867 tflow.mac_flow.mac_union.ether.dsap = flow->mac_flow.mac_union.ether.dsap;
6868 break;
6869
6870 case ARGUS_TYPE_WLAN:
6871 bcopy (flow->wlan_flow.bssid, tflow.wlan_flow.bssid, sizeof(flow->wlan_flow.bssid));
6872 break;
6873 }
6874 break;
6875 }
6876 case ARGUS_FLOW_ARP: {
6877 int hln = flow->arp_flow.hln;
6878
6879 if (hln > sizeof(flow->arp_flow.haddr))
6880 hln = sizeof(flow->arp_flow.haddr);
6881 tflow.arp_flow.hln = hln;
6882 bcopy((char *)&flow->arp_flow.haddr, (char *)&tflow.arp_flow.haddr, hln);
6883 break;
6884 }
6885 break;
6886 }
6887 break;
6888
6889 case ARGUS_MASK_SRCID:
6890 break;
6891
6892 default:
6893 break;
6894 }
6895 }
6896 }
6897
6898 bcopy ((char *)flow, (char *)&na->fstruct, len);
6899 bcopy ((char *)&tflow, (char *)flow, len);
6900 }
6901 }
6902
6903
6904 // ArgusMergeRecords
6905 // This routine takes 2 ArgusRecordStructs and merges each DSR,
6906 // leaving the resultant in ns1.
6907 //
6908 // ArgusMergeAddress
6909 // Given two non-equal addresses, ArgusMergeAddress() will do a MSB
6910 // run length compare, leaving the result in the first address passed.
6911 // If either the addrs are the broadcast address (0xFFFFFFFF) the
6912 // the result will be the other address.
6913 //
6914 // The masklen is the length of the CIDR mask, which is used to limit the
6915 // MSB test, and will be updated with the new CIDR mask length.
6916
6917
6918 unsigned int
ArgusMergeAddress(unsigned int * a1,unsigned int * a2,int type,int dir,unsigned char * masklen)6919 ArgusMergeAddress(unsigned int *a1, unsigned int *a2, int type, int dir, unsigned char *masklen)
6920 {
6921 unsigned int retn = 0;
6922
6923 switch (type) {
6924 case ARGUS_TYPE_IPV4: {
6925 if (*a1 != *a2) {
6926 unsigned int i = 32, value = 0, ind;
6927 ind = 0x80000000;
6928
6929 while (ind && ((*a1 & ind) == (*a2 & ind)) && (i > (32 - *masklen))) {
6930 value |= (*a1 & ind);
6931 ind >>= 1;
6932 i--;
6933 }
6934 *a1 = value;
6935 *masklen = (32 - i);
6936 }
6937 break;
6938 }
6939
6940 case ARGUS_TYPE_IPV6: {
6941 int z;
6942 for (z = 0; z < 4; z++) {
6943 if (a1[z] != a2[z]) {
6944 unsigned int i = 32, value = 0, ind;
6945 ind = 0x80000000;
6946
6947 while (ind && ((*a1 & ind) == (*a2 & ind)) && (i > (32 - *masklen))) {
6948 value |= (*a1 & ind);
6949 ind >>= 1;
6950 i--;
6951 }
6952 *masklen = (z * 32) + (32 - i);
6953 a1[z] = value;
6954 while ((z + 1) < 4) {
6955 a1[z + 1] = 0;
6956 z++;
6957 }
6958 break;
6959 }
6960 }
6961 break;
6962 }
6963
6964 case ARGUS_TYPE_WLAN:
6965 case ARGUS_TYPE_ETHER: {
6966 break;
6967 }
6968
6969 case ARGUS_TYPE_RARP:
6970 case ARGUS_TYPE_ARP: {
6971 break;
6972 }
6973 }
6974
6975 switch (dir) {
6976 case ARGUS_SRC:
6977 case ARGUS_DST:
6978 break;
6979 }
6980
6981 return (retn);
6982 }
6983
6984
6985 // Merging the label object is either an intersection of the label objects in
6986 // the two records, or a union of the two labels.
6987 //
6988 // OK, the label syntax is:
6989 // label[:label]
6990 // label :: [object=]word[,word[;[object=]word[,word]]]
6991 //
6992 // So when we merge these together, we'd like to preserve the labels and the object
6993 // specification, and by default we'll do the union, to see that that goes.
6994
6995
6996 #define ARGUS_MAX_LABEL_VALUES 32
6997 struct ArgusLabelObject {
6998 char *object;
6999 char *values[ARGUS_MAX_LABEL_VALUES];
7000 };
7001
7002
7003 char *ArgusMergeLabel(struct ArgusLabelStruct *, struct ArgusLabelStruct *, char *buf, int len, int type);
7004
7005 // char *ArgusMergeLabel(struct ArgusLabelStruct *l1, struct ArgusLabelStruct *l2, char *buf, int len, int type)
7006 //
7007 // This routine merges argus label meta-data. The types of merging possible are:
7008 // ARGUS_UNION Union - Where all the attributes and values are simple added to the label
7009 // ARGUS_INTER Intersection - Where only the attributes that are in common are retained
7010 // ARGUS_REPLACE Replace - When the attributes are in common, the values are replaced.
7011
7012
7013
7014 char *
ArgusMergeLabel(struct ArgusLabelStruct * l1,struct ArgusLabelStruct * l2,char * buf,int len,int type)7015 ArgusMergeLabel(struct ArgusLabelStruct *l1, struct ArgusLabelStruct *l2, char *buf, int len, int type)
7016 {
7017 struct ArgusLabelObject *l1labs = NULL, *l2labs = NULL;
7018 char *l1buf = NULL, *l2buf = NULL;
7019 int l1labsindex = 0, l2labsindex = 0;
7020 char *retn = NULL, *ptr, *sptr, *obj;
7021 int l1len, l2len;
7022 int i, y, z;
7023
7024 if (l1 != NULL) {
7025 if ((l1labs = calloc(256, sizeof(struct ArgusLabelObject))) == NULL)
7026 ArgusLog (LOG_ERR, "ArgusMergeLabel: calloc error %s", strerror(errno));
7027
7028 if ((l1buf = calloc(1, MAXBUFFERLEN)) == NULL)
7029 ArgusLog (LOG_ERR, "ArgusMergeLabel: calloc error %s", strerror(errno));
7030
7031 if (l1->l_un.label != NULL) {
7032 if ((l1len = strlen(l1->l_un.label)) > MAXBUFFERLEN)
7033 ArgusLog (LOG_ERR, "ArgusMergeLabel: l1len gt MAXBUFFERLEN");
7034
7035 bcopy(l1->l_un.label, l1buf, l1len);
7036 }
7037 }
7038 if (l2 != NULL) {
7039 if ((l2labs = calloc(256, sizeof(struct ArgusLabelObject))) == NULL)
7040 ArgusLog (LOG_ERR, "ArgusMergeLabel: calloc error %s", strerror(errno));
7041
7042 if ((l2buf = calloc(1, MAXBUFFERLEN)) == NULL)
7043 ArgusLog (LOG_ERR, "ArgusMergeLabel: calloc error %s", strerror(errno));
7044
7045 if (l2->l_un.label != NULL) {
7046 if ((l2len = strlen(l2->l_un.label)) > MAXBUFFERLEN)
7047 ArgusLog (LOG_ERR, "ArgusMergeLabel: l2len gt MAXBUFFERLEN");
7048
7049 bcopy(l2->l_un.label, l2buf, l2len);
7050 }
7051 }
7052
7053
7054 // first parse all the attributes and values. This system limits the
7055 // number of attributes to 256 and ARGUS_MAX_LABEL_VALUES per attribute.
7056
7057 if (l1 != NULL) {
7058 ptr = l1buf;
7059 while ((obj = strtok(ptr, ":")) != NULL) {
7060 if (l1labsindex < 256) {
7061 l1labs[l1labsindex].object = obj;
7062 l1labsindex++;
7063 }
7064 ptr = NULL;
7065 }
7066
7067 for (i = 0; i < l1labsindex; i++) {
7068 if ((obj = l1labs[i].object) != NULL) {
7069 if ((sptr = strchr(obj, '=')) != NULL) {
7070 int vind = 0;
7071 char *val;
7072
7073 *sptr++ = '\0';
7074 while ((val = strtok(sptr, ",")) != NULL) {
7075 l1labs[i].values[vind++] = val;
7076 sptr = NULL;
7077 }
7078 }
7079 }
7080 }
7081 }
7082
7083 if (l2 != NULL) {
7084 ptr = l2buf;
7085 while ((obj = strtok(ptr, ":")) != NULL) {
7086 if (l2labsindex < 256) {
7087 l2labs[l2labsindex].object = obj;
7088 l2labsindex++;
7089 }
7090 ptr = NULL;
7091 }
7092
7093 for (i = 0; i < l2labsindex; i++) {
7094 if ((obj = l2labs[i].object) != NULL) {
7095 if ((sptr = strchr(obj, '=')) != NULL) {
7096 int vind = 0;
7097 char *val;
7098
7099 *sptr++ = '\0';
7100 while ((val = strtok(sptr, ",")) != NULL) {
7101 l2labs[i].values[vind++] = val;
7102 sptr = NULL;
7103 }
7104 }
7105 }
7106 }
7107 }
7108
7109 // OK, now based on the merge type, setup l1abs to hold the
7110 // results of any union or replace operations for attributes
7111 // that l1 and l2 share. Leave attributes that l1 does not
7112 // contain in l2 for now..
7113
7114 // first gather entries from l2 into l1 for union or replace.
7115
7116 if ((l1 != NULL) && (l2 != NULL)) {
7117 for (i = 0; i < l2labsindex; i++) {
7118 int found = 0;
7119
7120 if (l2labs[i].object != NULL) {
7121 for (y = 0; y < l1labsindex && !found; y++) {
7122 if (l1labs[y].object != NULL) {
7123 if (!(strcmp(l1labs[y].object, l2labs[i].object))) {
7124 // we have matching attributes. based on type
7125 // add, replace or remove values in 1.
7126 switch (type) {
7127 case ARGUS_REPLACE: {
7128 bcopy(l2labs[i].values, l1labs[y].values, sizeof(l1labs[y].values));
7129 break;
7130 }
7131
7132 case ARGUS_INTERSECT:
7133 case ARGUS_UNION: {
7134 char *v1ptr, *v2ptr;
7135 int v2ind = 0;
7136 while ((v2ptr = l2labs[i].values[v2ind]) != NULL) {
7137 int v1ind = 0, vfound = 0;
7138 while (!vfound && ((v1ptr = l1labs[y].values[v1ind]) != NULL)) {
7139 if (!(strcmp(v1ptr, v2ptr))) {
7140 vfound = 1;
7141 break;
7142 }
7143 v1ind++;
7144 }
7145 if (!vfound) {
7146 if (type == ARGUS_UNION) {
7147 int xind = (v1ind < ARGUS_MAX_LABEL_VALUES) ? v1ind : ARGUS_MAX_LABEL_VALUES - 1;
7148 l1labs[y].values[xind] = v2ptr;
7149 } else
7150 bzero(l1labs[y].values, sizeof(l1labs[y].values));
7151 }
7152 v2ind++;
7153 }
7154 break;
7155 }
7156 }
7157 l2labs[i].object = NULL;
7158 found = 1;
7159 }
7160 }
7161 }
7162 }
7163 }
7164 }
7165
7166 // OK, at this point were ready to go, just go through all the attributes
7167 // first in l1 and then in l2, and create the actual label string.
7168
7169 z = 0;
7170 if (l1 != NULL) {
7171 for (i = 0; i < l1labsindex; i++) {
7172 if (l1labs[i].object != NULL) {
7173 if (z == 0)
7174 sprintf (&buf[strlen(buf)], "%s", l1labs[i].object);
7175 else
7176 sprintf (&buf[strlen(buf)], ":%s", l1labs[i].object);
7177
7178 if (l1labs[i].values[0] != NULL) {
7179 int y = 1;
7180 sprintf (&buf[strlen(buf)], "=%s", l1labs[i].values[0]);
7181 while ((y < ARGUS_MAX_LABEL_VALUES) && (l1labs[i].values[y] != NULL)) {
7182 sprintf (&buf[strlen(buf)], ",%s", l1labs[i].values[y]);
7183 y++;
7184 }
7185 }
7186 z++;
7187 }
7188 retn = buf;
7189 }
7190 free(l1labs);
7191 free(l1buf);
7192 }
7193
7194 if (l2 != NULL) {
7195 for (i = 0; i < l2labsindex; i++) {
7196 if (l2labs[i].object != NULL) {
7197 if (z == 0)
7198 sprintf (&buf[strlen(buf)], "%s", l2labs[i].object);
7199 else
7200 sprintf (&buf[strlen(buf)], ":%s", l2labs[i].object);
7201
7202 if (l2labs[i].values[0] != NULL) {
7203 int y = 1;
7204 sprintf (&buf[strlen(buf)], "=%s", l2labs[i].values[0]);
7205 while ((y < ARGUS_MAX_LABEL_VALUES) && (l2labs[i].values[y] != NULL)) {
7206 sprintf (&buf[strlen(buf)], ",%s", l2labs[i].values[y]);
7207 y++;
7208 }
7209 }
7210 z++;
7211 }
7212 retn = buf;
7213 }
7214 free(l2labs);
7215 free(l2buf);
7216 }
7217
7218 return (retn);
7219 }
7220
7221
7222 void
ArgusMergeRecords(struct ArgusAggregatorStruct * na,struct ArgusRecordStruct * ns1,struct ArgusRecordStruct * ns2)7223 ArgusMergeRecords (struct ArgusAggregatorStruct *na, struct ArgusRecordStruct *ns1, struct ArgusRecordStruct *ns2)
7224 {
7225 struct ArgusAgrStruct *agr = NULL;
7226 double seconds;
7227 int i;
7228
7229 if ((ns1 && ns2) && ((ns1->hdr.type & ARGUS_FAR) && (ns2->hdr.type & ARGUS_FAR))) {
7230 struct ArgusTimeObject *ns1time = (void *)ns1->dsrs[ARGUS_TIME_INDEX];
7231 struct ArgusTimeObject *ns2time = (void *)ns2->dsrs[ARGUS_TIME_INDEX];
7232 struct ArgusMetricStruct *ns1metric = (void *)ns1->dsrs[ARGUS_METRIC_INDEX];
7233 struct ArgusMetricStruct *ns2metric = (void *)ns2->dsrs[ARGUS_METRIC_INDEX];
7234
7235 double deltaTime = 0.0;
7236 double deltaSrcTime = 0.0;
7237 double deltaDstTime = 0.0;
7238
7239 if ((ns1time && ns2time) && (ns1metric && ns2metric)) {
7240 double nst1, nst2;
7241 nst1 = (ns1time->src.end.tv_sec * 1000000LL) + ns1time->src.end.tv_usec;
7242 nst2 = (ns2time->src.start.tv_sec * 1000000LL) + ns2time->src.start.tv_usec;
7243
7244 if ((deltaTime = (nst2 - nst1) * 1.00) < 0.0)
7245 deltaTime = -deltaTime;
7246
7247 if (ns1metric->src.pkts && ns2metric->src.pkts)
7248 if ((deltaSrcTime = (nst2 - nst1) * 1.00) < 0.0)
7249 deltaSrcTime = -deltaSrcTime;
7250
7251 nst1 = (ns1time->dst.end.tv_sec * 1000000LL) + ns1time->dst.end.tv_usec;
7252 nst2 = (ns2time->dst.start.tv_sec * 1000000LL) + ns2time->dst.start.tv_usec;
7253
7254 if (ns1metric->dst.pkts && ns2metric->dst.pkts)
7255 if ((deltaDstTime = (nst2 - nst1) * 1.00) < 0.0)
7256 deltaDstTime = -deltaDstTime;
7257 }
7258
7259 ns1->status &= ~ARGUS_RECORD_WRITTEN;
7260
7261 if ((agr = (struct ArgusAgrStruct *) ns1->dsrs[ARGUS_AGR_INDEX]) == NULL) {
7262 struct ArgusMetricStruct *metric = (void *)ns1->dsrs[ARGUS_METRIC_INDEX];
7263 if ((metric != NULL) && ((metric->src.pkts + metric->dst.pkts) > 0)) {
7264 double value = na->RaMetricFetchAlgorithm(ns1);
7265
7266 if ((agr = ArgusCalloc(1, sizeof(*agr))) == NULL)
7267 ArgusLog (LOG_ERR, "ArgusMergeRecords: ArgusCalloc error: %s", strerror(errno));
7268
7269 agr->hdr.type = ARGUS_AGR_DSR;
7270 agr->hdr.subtype = na->ArgusMetricIndex;
7271 agr->hdr.argus_dsrvl8.qual = 0x01;
7272 agr->hdr.argus_dsrvl8.len = (sizeof(*agr) + 3)/4;
7273 agr->count = 1;
7274 agr->act.maxval = value;
7275 agr->act.minval = value;
7276 agr->act.meanval = value;
7277 agr->act.n = 1;
7278 bzero ((char *)&agr->idle, sizeof(agr->idle));
7279 agr->idle.minval = 1000000000.0;
7280
7281 ns1->dsrs[ARGUS_AGR_INDEX] = (struct ArgusDSRHeader *) agr;
7282 ns1->dsrindex |= (0x01 << ARGUS_AGR_INDEX);
7283 }
7284 }
7285
7286 for (i = 0; i < ARGUSMAXDSRTYPE; i++) {
7287 switch (i) {
7288
7289 // Merging Flow records is a matter of testing each field and
7290 // transforming values that are not equal to either run length
7291 // and'ing or zeroing out the value. When a value is zero'ed
7292 // we need to indicate it in the status field of the flow
7293 // descriptor so that values resulting from merging are not
7294 // confused with values actually off the wire.
7295 //
7296 // run length and'ing is an attempt to preserve CIDR addresses.
7297 // any other value should be either preserved or invalidated.
7298
7299 case ARGUS_FLOW_INDEX: {
7300 struct ArgusFlow *f1 = (struct ArgusFlow *) ns1->dsrs[ARGUS_FLOW_INDEX];
7301 struct ArgusFlow *f2 = (struct ArgusFlow *) ns2->dsrs[ARGUS_FLOW_INDEX];
7302
7303 if (f1 && f2) {
7304 unsigned char masklen = 0;
7305 if (f1->hdr.subtype == f2->hdr.subtype) {
7306 char f1qual = f1->hdr.argus_dsrvl8.qual & 0x1F;
7307 char f2qual = f2->hdr.argus_dsrvl8.qual & 0x1F;
7308
7309 switch (f1->hdr.subtype & 0x3F) {
7310 case ARGUS_FLOW_LAYER_3_MATRIX: {
7311 if (f1qual == f2qual) {
7312 switch (f1qual) {
7313 case ARGUS_TYPE_IPV4: {
7314 masklen = (f1->ip_flow.smask > f2->ip_flow.smask) ? f2->ip_flow.smask : f1->ip_flow.smask;
7315 f1->hdr.argus_dsrvl8.qual |= ArgusMergeAddress(&f1->ip_flow.ip_src, &f2->ip_flow.ip_src, ARGUS_TYPE_IPV4, ARGUS_SRC, &masklen);
7316 f1->ip_flow.smask = masklen;
7317 masklen = (f1->ip_flow.dmask > f2->ip_flow.dmask) ? f2->ip_flow.dmask : f1->ip_flow.dmask;
7318 f1->hdr.argus_dsrvl8.qual |= ArgusMergeAddress(&f1->ip_flow.ip_dst, &f2->ip_flow.ip_dst, ARGUS_TYPE_IPV4, ARGUS_DST, &masklen);
7319 f1->ip_flow.dmask = masklen;
7320 f1->hdr.argus_dsrvl8.qual |= ARGUS_MASKLEN;
7321 break;
7322
7323 case ARGUS_TYPE_IPV6:
7324 masklen = (f1->ipv6_flow.smask > f2->ipv6_flow.smask) ? f2->ipv6_flow.smask : f1->ipv6_flow.smask;
7325 f1->hdr.argus_dsrvl8.qual |= ArgusMergeAddress(&f1->ipv6_flow.ip_src[0], &f2->ipv6_flow.ip_src[0], ARGUS_TYPE_IPV6, ARGUS_SRC, &masklen);
7326 f1->ip_flow.smask = masklen;
7327 masklen = (f1->ipv6_flow.dmask > f2->ipv6_flow.dmask) ? f2->ipv6_flow.dmask : f1->ipv6_flow.dmask;
7328 f1->hdr.argus_dsrvl8.qual |= ArgusMergeAddress(&f1->ipv6_flow.ip_dst[0], &f2->ipv6_flow.ip_dst[0], ARGUS_TYPE_IPV6, ARGUS_DST, &masklen);
7329 f1->ip_flow.dmask = masklen;
7330 f1->hdr.argus_dsrvl8.qual |= ARGUS_MASKLEN;
7331 break;
7332
7333 }
7334 }
7335 }
7336 break;
7337 }
7338
7339 case ARGUS_FLOW_CLASSIC5TUPLE: {
7340 switch (f1qual) {
7341 case ARGUS_TYPE_IPV4:
7342 if (f1qual == f2qual) {
7343 masklen = (f1->ip_flow.smask > f2->ip_flow.smask) ? f2->ip_flow.smask : f1->ip_flow.smask;
7344 ArgusMergeAddress(&f1->ip_flow.ip_src, &f2->ip_flow.ip_src, ARGUS_TYPE_IPV4, ARGUS_SRC, &masklen);
7345 f1->ip_flow.smask = masklen;
7346
7347 masklen = (f1->ip_flow.dmask > f2->ip_flow.dmask) ? f2->ip_flow.dmask : f1->ip_flow.dmask;
7348 ArgusMergeAddress(&f1->ip_flow.ip_dst, &f2->ip_flow.ip_dst, ARGUS_TYPE_IPV4, ARGUS_DST, &masklen);
7349 f1->ip_flow.dmask = masklen;
7350
7351 f1->hdr.argus_dsrvl8.qual |= ARGUS_MASKLEN;
7352
7353 if (f1->ip_flow.ip_p != f2->ip_flow.ip_p)
7354 f1->ip_flow.ip_p = 0;
7355 else {
7356 switch (f1->ip_flow.ip_p) {
7357 case IPPROTO_ESP: {
7358 if (f1->esp_flow.spi != f2->esp_flow.spi)
7359 f1->esp_flow.spi = 0;
7360 break;
7361 }
7362
7363 default: {
7364 if (f1->ip_flow.sport != f2->ip_flow.sport)
7365 f1->ip_flow.sport = 0;
7366 if (f1->ip_flow.dport != f2->ip_flow.dport)
7367 f1->ip_flow.dport = 0;
7368 break;
7369 }
7370 }
7371 }
7372
7373 } else {
7374 f1->ip_flow.ip_src = 0;
7375 f1->ip_flow.ip_dst = 0;
7376
7377 switch (f2qual) {
7378 case ARGUS_TYPE_IPV6:
7379 if (f1->ip_flow.ip_p != f2->ipv6_flow.ip_p)
7380 f1->ip_flow.ip_p = 0;
7381 if (f1->ip_flow.sport != f2->ipv6_flow.sport)
7382 f1->ip_flow.sport = 0;
7383 if (f1->ip_flow.dport != f2->ipv6_flow.dport)
7384 f1->ip_flow.dport = 0;
7385 break;
7386
7387 default:
7388 f1->ip_flow.ip_p = 0;
7389 f1->ip_flow.sport = 0;
7390 f1->ip_flow.dport = 0;
7391 break;
7392 }
7393 }
7394 break;
7395
7396 case ARGUS_TYPE_IPV6:
7397 if (f1qual == f2qual) {
7398 masklen = (f1->ipv6_flow.smask > f2->ipv6_flow.smask) ? f2->ipv6_flow.smask : f1->ipv6_flow.smask;
7399 f1->hdr.argus_dsrvl8.qual |= ArgusMergeAddress(&f1->ipv6_flow.ip_src[0], &f2->ipv6_flow.ip_src[0], ARGUS_TYPE_IPV6, ARGUS_SRC, &masklen);
7400 f1->ipv6_flow.smask = masklen;
7401 masklen = (f1->ipv6_flow.dmask > f2->ipv6_flow.dmask) ? f2->ipv6_flow.dmask : f1->ipv6_flow.dmask;
7402 f1->hdr.argus_dsrvl8.qual |= ArgusMergeAddress(&f1->ipv6_flow.ip_dst[0], &f2->ipv6_flow.ip_dst[0], ARGUS_TYPE_IPV6, ARGUS_DST, &masklen);
7403 f1->ipv6_flow.dmask = masklen;
7404
7405 f1->hdr.argus_dsrvl8.qual |= ARGUS_MASKLEN;
7406
7407 if (f1->ipv6_flow.ip_p != f2->ipv6_flow.ip_p) f1->ipv6_flow.ip_p = 0;
7408 if (f1->ipv6_flow.sport != f2->ipv6_flow.sport) f1->ipv6_flow.sport = 0;
7409 if (f1->ipv6_flow.dport != f2->ipv6_flow.dport) f1->ipv6_flow.dport = 0;
7410
7411 } else {
7412 bzero ((char *)&f1->ipv6_flow.ip_src[0], sizeof(f1->ipv6_flow.ip_src));
7413 bzero ((char *)&f1->ipv6_flow.ip_dst[0], sizeof(f1->ipv6_flow.ip_dst));
7414 if (f1->ipv6_flow.ip_p != f2->ip_flow.ip_p) f1->ipv6_flow.ip_p = 0;
7415 if (f1->ipv6_flow.sport != f2->ip_flow.sport) f1->ipv6_flow.sport = 0;
7416 if (f1->ipv6_flow.dport != f2->ip_flow.dport) f1->ipv6_flow.dport = 0;
7417 }
7418 break;
7419
7420 case ARGUS_TYPE_RARP:
7421 if (bcmp(&f1->rarp_flow.shaddr, &f2->rarp_flow.shaddr, 6))
7422 bzero(&f1->rarp_flow.shaddr, 6);
7423 if (bcmp(&f1->rarp_flow.dhaddr, &f2->rarp_flow.dhaddr, 6))
7424 bzero(&f1->rarp_flow.dhaddr, 6);
7425 break;
7426 case ARGUS_TYPE_ARP:
7427 f1->hdr.argus_dsrvl8.qual |= ArgusMergeAddress(&f1->arp_flow.arp_spa, &f2->arp_flow.arp_spa, ARGUS_TYPE_ARP, ARGUS_SRC, &masklen);
7428 f1->hdr.argus_dsrvl8.qual |= ArgusMergeAddress(&f1->arp_flow.arp_tpa, &f2->arp_flow.arp_tpa, ARGUS_TYPE_ARP, ARGUS_DST, &masklen);
7429 break;
7430 }
7431 break;
7432 }
7433
7434 case ARGUS_FLOW_ARP: {
7435 switch (f1qual) {
7436 case ARGUS_TYPE_RARP: {
7437 if (bcmp(&f1->rarp_flow.shaddr, &f2->rarp_flow.shaddr, 6))
7438 bzero(&f1->rarp_flow.shaddr, 6);
7439 if (bcmp(&f1->rarp_flow.dhaddr, &f2->rarp_flow.dhaddr, 6))
7440 bzero(&f1->rarp_flow.dhaddr, 6);
7441
7442 if (f1->arp_flow.pln == 4) {
7443 ArgusMergeAddress(&f1->arp_flow.arp_tpa, &f2->arp_flow.arp_tpa, ARGUS_TYPE_IPV4, ARGUS_DST, &masklen);
7444 }
7445 break;
7446 }
7447
7448 case ARGUS_TYPE_ARP: {
7449 if (bcmp(&f1->arp_flow.haddr, &f2->arp_flow.haddr, 6))
7450 bzero(&f1->arp_flow.haddr, 6);
7451
7452 if (f1->arp_flow.pln == 4) {
7453 ArgusMergeAddress(&f1->arp_flow.arp_spa, &f2->arp_flow.arp_spa, ARGUS_TYPE_IPV4, ARGUS_SRC, &masklen);
7454 ArgusMergeAddress(&f1->arp_flow.arp_tpa, &f2->arp_flow.arp_tpa, ARGUS_TYPE_IPV4, ARGUS_DST, &masklen);
7455 }
7456 break;
7457 }
7458 }
7459 break;
7460 }
7461 }
7462 }
7463 }
7464 }
7465 break;
7466
7467 // Merging Transport objects involves simply checking that the source
7468 // id and seqnum are the same, and if not, removing the fields until
7469 // we're actually removing the struct.
7470 //
7471 // struct ArgusTransportStruct {
7472 // struct ArgusDSRHeader hdr;
7473 // struct ArgusAddrStruct srcid;
7474 // unsigned int seqnum;
7475 // };
7476
7477 case ARGUS_TRANSPORT_INDEX: {
7478 struct ArgusTransportStruct *t1 = (struct ArgusTransportStruct *) ns1->dsrs[ARGUS_TRANSPORT_INDEX];
7479 struct ArgusTransportStruct *t2 = (struct ArgusTransportStruct *) ns2->dsrs[ARGUS_TRANSPORT_INDEX];
7480
7481 if ((t1 && t2) && (t1->hdr.argus_dsrvl8.qual == t2->hdr.argus_dsrvl8.qual)) {
7482 if (t1->hdr.argus_dsrvl8.qual == t2->hdr.argus_dsrvl8.qual) {
7483 if ((t1->hdr.subtype & ARGUS_SRCID) && (t2->hdr.subtype & ARGUS_SRCID)) {
7484 switch (t1->hdr.argus_dsrvl8.qual) {
7485 case ARGUS_TYPE_INT:
7486 case ARGUS_TYPE_IPV4:
7487 if (t1->srcid.a_un.ipv4 != t2->srcid.a_un.ipv4) {
7488 ArgusFree(ns1->dsrs[ARGUS_TRANSPORT_INDEX]);
7489 ns1->dsrs[ARGUS_TRANSPORT_INDEX] = NULL;
7490 ns1->dsrindex &= ~(0x1 << ARGUS_TRANSPORT_INDEX);
7491 }
7492 break;
7493
7494 case ARGUS_TYPE_IPV6:
7495 case ARGUS_TYPE_ETHER:
7496 case ARGUS_TYPE_STRING:
7497 break;
7498 }
7499 }
7500
7501 } else {
7502 ArgusFree(ns1->dsrs[ARGUS_TRANSPORT_INDEX]);
7503 ns1->dsrs[ARGUS_TRANSPORT_INDEX] = NULL;
7504 ns1->dsrindex &= ~(0x1 << ARGUS_TRANSPORT_INDEX);
7505 }
7506 }
7507
7508 break;
7509 }
7510
7511 // Merging Time objects may result in a change in the storage
7512 // type of the time structure, from an ABSOLUTE_TIMESTAMP
7513 // to an ABSOLUTE_RANGE, to hold the new ending time.
7514
7515 case ARGUS_TIME_INDEX: {
7516 struct ArgusTimeObject *t1 = (struct ArgusTimeObject *) ns1->dsrs[ARGUS_TIME_INDEX];
7517 struct ArgusTimeObject *t2 = (struct ArgusTimeObject *) ns2->dsrs[ARGUS_TIME_INDEX];
7518
7519 if (t1 && t2) {
7520 unsigned int st1, st2;
7521
7522 if (t1->hdr.argus_dsrvl8.len == 0) {
7523 bcopy ((char *) t2, (char *) t1, sizeof (*t1));
7524 break;
7525 }
7526
7527 st1 = t1->hdr.subtype & (ARGUS_TIME_SRC_START | ARGUS_TIME_DST_START |
7528 ARGUS_TIME_SRC_END | ARGUS_TIME_DST_END);
7529
7530 st2 = t2->hdr.subtype & (ARGUS_TIME_SRC_START | ARGUS_TIME_DST_START |
7531 ARGUS_TIME_SRC_END | ARGUS_TIME_DST_END);
7532
7533 if (st2) {
7534 if (st2 & ARGUS_TIME_SRC_START) {
7535 if (st1 & ARGUS_TIME_SRC_START) {
7536 if ((t1->src.start.tv_sec > t2->src.start.tv_sec) ||
7537 ((t1->src.start.tv_sec == t2->src.start.tv_sec) &&
7538 (t1->src.start.tv_usec > t2->src.start.tv_usec))) {
7539 t1->src.start = t2->src.start;
7540 t1->hdr.subtype |= ARGUS_TIME_SRC_START;
7541 } else {
7542 if ((t1->src.end.tv_sec < t2->src.start.tv_sec) ||
7543 ((t1->src.end.tv_sec == t2->src.start.tv_sec) &&
7544 (t1->src.end.tv_usec > t2->src.start.tv_usec))) {
7545 t1->src.end = t2->src.start;
7546 t1->hdr.subtype |= ARGUS_TIME_SRC_END;
7547 }
7548 }
7549 } else {
7550 t1->src = t2->src;
7551 t1->hdr.subtype |= st2 & (ARGUS_TIME_SRC_START |
7552 ARGUS_TIME_SRC_END);
7553 }
7554 }
7555 if (st2 & (ARGUS_TIME_SRC_START | ARGUS_TIME_SRC_END)) {
7556 if (st1 & (ARGUS_TIME_SRC_START | ARGUS_TIME_SRC_END)) {
7557 if (t2->src.end.tv_sec) {
7558 if ((t1->src.end.tv_sec < t2->src.end.tv_sec) ||
7559 ((t1->src.end.tv_sec == t2->src.end.tv_sec) &&
7560 (t1->src.end.tv_usec < t2->src.end.tv_usec))) {
7561 t1->src.end = t2->src.end;
7562 t1->hdr.subtype |= ARGUS_TIME_SRC_END;
7563 }
7564 } else {
7565 if ((t1->src.end.tv_sec < t2->src.start.tv_sec) ||
7566 ((t1->src.end.tv_sec == t2->src.start.tv_sec) &&
7567 (t1->src.end.tv_usec < t2->src.start.tv_usec))) {
7568 t1->src.end = t2->src.end;
7569 t1->hdr.subtype |= ARGUS_TIME_SRC_END;
7570 }
7571 }
7572
7573 } else {
7574 t1->src.end = t2->src.end;
7575 t1->hdr.subtype |= st2 & (ARGUS_TIME_SRC_START |
7576 ARGUS_TIME_SRC_END);
7577 }
7578 }
7579 if (st2 & ARGUS_TIME_DST_START) {
7580 if (st1 & ARGUS_TIME_DST_START) {
7581 if ((t1->dst.start.tv_sec > t2->dst.start.tv_sec) ||
7582 ((t1->dst.start.tv_sec == t2->dst.start.tv_sec) &&
7583 (t1->dst.start.tv_usec > t2->dst.start.tv_usec))) {
7584 t1->dst.start = t2->dst.start;
7585 t1->hdr.subtype |= ARGUS_TIME_DST_START;
7586 }
7587 } else {
7588 t1->dst = t2->dst;
7589 t1->hdr.subtype |= st2 & (ARGUS_TIME_DST_START |
7590 ARGUS_TIME_DST_END);
7591 }
7592 }
7593 if (st2 & (ARGUS_TIME_DST_START | ARGUS_TIME_DST_END)) {
7594 if (st1 & (ARGUS_TIME_DST_START | ARGUS_TIME_DST_END)) {
7595 if ((t1->dst.end.tv_sec < t2->dst.end.tv_sec) ||
7596 ((t1->dst.end.tv_sec == t2->dst.end.tv_sec) &&
7597 (t1->dst.end.tv_usec < t2->dst.end.tv_usec))) {
7598 t1->dst.end = t2->dst.end;
7599 t1->hdr.subtype |= ARGUS_TIME_DST_END;
7600 }
7601 } else {
7602 t1->dst = t2->dst;
7603 t1->hdr.subtype |= st2 & (ARGUS_TIME_DST_START |
7604 ARGUS_TIME_DST_END);
7605 }
7606 }
7607
7608 } else {
7609
7610 if (t1->src.start.tv_sec == 0) {
7611 bcopy ((char *)t2, (char *)t1, sizeof (*t1));
7612 } else {
7613 if ((t1->src.start.tv_sec > t2->src.start.tv_sec) ||
7614 ((t1->src.start.tv_sec == t2->src.start.tv_sec) &&
7615 (t1->src.start.tv_usec > t2->src.start.tv_usec)))
7616 t1->src.start = t2->src.start;
7617
7618 if ((t1->src.end.tv_sec == 0) || (t1->hdr.subtype == ARGUS_TIME_ABSOLUTE_TIMESTAMP)) {
7619 t1->src.end = t1->src.start;
7620 t1->hdr.subtype = ARGUS_TIME_ABSOLUTE_RANGE;
7621 t1->hdr.argus_dsrvl8.len = sizeof(*t1);
7622 }
7623 if ((t2->src.end.tv_sec == 0) || (t2->hdr.subtype == ARGUS_TIME_ABSOLUTE_TIMESTAMP)) {
7624 t2->src.end = t2->src.start;
7625 t2->hdr.subtype = ARGUS_TIME_ABSOLUTE_RANGE;
7626 t2->hdr.argus_dsrvl8.len = sizeof(*t1);
7627 }
7628 if ((t1->src.end.tv_sec < t2->src.end.tv_sec) ||
7629 ((t1->src.end.tv_sec == t2->src.end.tv_sec) &&
7630 (t1->src.end.tv_usec < t2->src.end.tv_usec)))
7631 t1->src.end = t2->src.end;
7632 }
7633 }
7634 }
7635 break;
7636 }
7637
7638 case ARGUS_TIME_ADJ_INDEX: {
7639 break;
7640 }
7641
7642 // Merging networks objects involve copying and masking
7643 // various protocol specific network structs together.
7644 // First test for the protocols, and if they are the same,
7645 // then merge, if not, just remove the dsrs[] pointers;
7646
7647 case ARGUS_NETWORK_INDEX: {
7648 struct ArgusNetworkStruct *n1 = (void *)ns1->dsrs[ARGUS_NETWORK_INDEX];
7649 struct ArgusNetworkStruct *n2 = (void *)ns2->dsrs[ARGUS_NETWORK_INDEX];
7650
7651 if ((n1 != NULL) && (n2 != NULL)) {
7652 if (n1->hdr.subtype != n2->hdr.subtype) {
7653 if (!(((n1->hdr.subtype == ARGUS_TCP_INIT) || (n1->hdr.subtype == ARGUS_TCP_STATUS) || (n1->hdr.subtype == ARGUS_TCP_PERF)) &&
7654 ((n2->hdr.subtype == ARGUS_TCP_INIT) || (n2->hdr.subtype == ARGUS_TCP_STATUS) || (n2->hdr.subtype == ARGUS_TCP_PERF)))) {
7655 ArgusFree(ns1->dsrs[i]);
7656 ns1->dsrs[i] = NULL;
7657 ns1->dsrindex &= ~(0x01 << i);
7658 n1 = NULL;
7659 break;
7660 }
7661 }
7662
7663 if ((n1 != NULL) && (n2 != NULL)) {
7664 switch (n1->hdr.subtype) {
7665 case ARGUS_TCP_INIT: {
7666 struct ArgusTCPObject *t1 = (struct ArgusTCPObject *)&n1->net_union.tcp;
7667 struct ArgusTCPObject *t2 = (struct ArgusTCPObject *)&n2->net_union.tcp;
7668
7669 switch (n2->hdr.subtype) {
7670 case ARGUS_TCP_INIT: {
7671 t1->status |= t2->status;
7672 t1->options |= t2->options;
7673 t1->src.flags |= t2->src.flags;
7674
7675 break;
7676 }
7677 case ARGUS_TCP_STATUS: {
7678 n1->hdr.subtype = ARGUS_TCP_PERF;
7679 n1->hdr.argus_dsrvl8.len = 1 + sizeof(*t1)/4;
7680 t1->status = t2->status;
7681 t1->options = t2->options;
7682 t1->src.status = t2->src.status;
7683 t1->src.seqbase = t2->src.seqbase;
7684 t1->src.win = t2->src.win;
7685 t1->src.flags = t2->src.flags;
7686 t1->src.winshift = t2->src.winshift;
7687 t1->dst.flags = t2->dst.flags;
7688 break;
7689 }
7690 case ARGUS_TCP_PERF: {
7691 struct ArgusTCPObject *t2 = (struct ArgusTCPObject *)&n2->net_union.tcp;
7692 struct ArgusTCPObject *tobj = (struct ArgusTCPObject *)&n1->net_union.tcp;
7693
7694 bcopy(t2, tobj, sizeof(*t2));
7695 t1->status |= t2->status;
7696 t1->options |= t2->options;
7697 t1->src.status |= t2->src.status;
7698 t1->src.seqbase = t2->src.seqbase;
7699 t1->src.win = t2->src.win;
7700 t1->src.flags |= t2->src.flags;
7701 t1->src.winshift = t2->src.winshift;
7702 break;
7703 }
7704 }
7705 break;
7706 }
7707
7708 case ARGUS_TCP_STATUS: {
7709 struct ArgusTCPStatus *t1 = (struct ArgusTCPStatus *)&n1->net_union.tcp;
7710 struct ArgusTCPStatus tcpstatusbuf, *tcps = &tcpstatusbuf;
7711 bcopy(t1, tcps, sizeof(*t1));
7712 switch (n2->hdr.subtype) {
7713 case ARGUS_TCP_INIT: {
7714 struct ArgusTCPInitStatus *t2 = (struct ArgusTCPInitStatus *)&n2->net_union.tcp;
7715 struct ArgusTCPObject *tobj = (struct ArgusTCPObject *)&n1->net_union.tcp;
7716
7717 bzero(tobj, sizeof(*tobj));
7718 n1->hdr.subtype = ARGUS_TCP_PERF;
7719 n1->hdr.argus_dsrvl8.len = 1 + sizeof(*tobj)/4;
7720 tobj->status = tcps->status | t2->status;
7721 tobj->options = t2->options;
7722 tobj->src.status = t2->status;
7723 tobj->src.seqbase = t2->seqbase;
7724 tobj->src.win = t2->win;
7725 tobj->src.flags = t2->flags | tcps->src;
7726 tobj->src.winshift = t2->winshift;
7727 tobj->dst.flags = tcps->dst;
7728
7729 break;
7730 }
7731 case ARGUS_TCP_STATUS: {
7732 struct ArgusTCPStatus *t2 = (struct ArgusTCPStatus *)&n2->net_union.tcp;
7733 t1->status |= t2->status;
7734 break;
7735 }
7736 case ARGUS_TCP_PERF: {
7737 struct ArgusTCPObject *t2 = (struct ArgusTCPObject *)&n2->net_union.tcp;
7738 struct ArgusTCPObject *tobj = (struct ArgusTCPObject *)&n1->net_union.tcp;
7739
7740 bcopy(t2, tobj, sizeof(*t2));
7741 tobj->status |= tcps->status;
7742 tobj->src.status |= tcps->status;
7743 tobj->src.flags |= tcps->src;
7744 tobj->dst.flags |= tcps->dst;
7745 break;
7746 }
7747 }
7748 break;
7749 }
7750
7751 case ARGUS_TCP_PERF: {
7752 struct ArgusTCPObject *t1 = (struct ArgusTCPObject *)&n1->net_union.tcp;
7753 switch (n2->hdr.subtype) {
7754 case ARGUS_TCP_INIT: {
7755 break;
7756 }
7757 case ARGUS_TCP_STATUS: {
7758 break;
7759 }
7760 case ARGUS_TCP_PERF: {
7761 struct ArgusTCPObject *t2 = (struct ArgusTCPObject *)&n2->net_union.tcp;
7762
7763 if (n1->hdr.argus_dsrvl8.len == 0) {
7764 bcopy ((char *) n2, (char *) n1, sizeof (*n1));
7765 } else {
7766 t1->status |= t2->status;
7767 t1->state |= t2->state;
7768 t1->options |= t2->options;
7769
7770 if (t1->synAckuSecs == 0)
7771 t1->synAckuSecs = t2->synAckuSecs;
7772 if (t1->ackDatauSecs == 0)
7773 t1->ackDatauSecs = t2->ackDatauSecs;
7774
7775 t1->src.status |= t2->src.status;
7776 t1->src.ack = t2->src.ack;
7777
7778 if (t1->src.seqbase > t2->src.seqbase) { // potential roll over
7779
7780 #define TCP_MAX_WINDOWSIZE 65536
7781 if ((t1->src.seqbase - t2->src.seqbase) > TCP_MAX_WINDOWSIZE) { // roll over
7782 t1->src.ackbytes += (t2->src.seq + (0xffffffff - t2->src.seqbase));
7783 } else
7784 t1->src.seqbase = t2->src.seqbase;
7785 } else
7786 t1->src.seq = t2->src.seq;
7787
7788 t1->src.winnum += t2->src.winnum;
7789 t1->src.bytes += t2->src.bytes;
7790 t1->src.retrans += t2->src.retrans;
7791
7792 t1->src.win = t2->src.win;
7793 t1->src.winbytes = t2->src.winbytes;
7794 t1->src.flags |= t2->src.flags;
7795
7796 t1->dst.status |= t2->dst.status;
7797 t1->dst.ack = t2->dst.ack;
7798
7799 if (t1->dst.seqbase > t2->dst.seqbase) { // potential roll over
7800 if ((t1->dst.seqbase - t2->dst.seqbase) > TCP_MAX_WINDOWSIZE) { // roll over
7801 t1->dst.ackbytes += (t2->dst.seq + (0xffffffff - t2->dst.seqbase));
7802 } else
7803 t1->dst.seqbase = t2->dst.seqbase;
7804 } else
7805 t1->dst.seq = t2->dst.seq;
7806
7807 t1->dst.winnum += t2->dst.winnum;
7808 t1->dst.bytes += t2->dst.bytes;
7809 t1->dst.retrans += t2->dst.retrans;
7810
7811 t1->dst.win = t2->dst.win;
7812 t1->dst.winbytes = t2->dst.winbytes;
7813 t1->dst.flags |= t2->dst.flags;
7814
7815 if (n1->hdr.subtype != n2->hdr.subtype) {
7816 if (n1->hdr.subtype == ARGUS_TCP_INIT) {
7817 n1->hdr.subtype = ARGUS_TCP_PERF;
7818 n1->hdr.argus_dsrvl8.len = (sizeof(*t1) + 3) / 4;
7819 }
7820 }
7821 }
7822 break;
7823 }
7824
7825 break;
7826 }
7827 }
7828
7829 case ARGUS_RTP_FLOW: {
7830 struct ArgusRTPObject *r1 = &n1->net_union.rtp;
7831 struct ArgusRTPObject *r2 = &n2->net_union.rtp;
7832 r1->sdrop += r2->sdrop;
7833 r1->ddrop += r2->ddrop;
7834 r1->src = r2->src;
7835 r1->dst = r2->dst;
7836 break;
7837 }
7838
7839 case ARGUS_UDT_FLOW: {
7840 struct ArgusUDTObject *u1 = &n1->net_union.udt;
7841 struct ArgusUDTObject *u2 = &n2->net_union.udt;
7842
7843 if (u1->hshake.version != u2->hshake.version)
7844 u1->hshake.version = 0;
7845 if (u1->hshake.socktype != u2->hshake.socktype)
7846 u1->hshake.version = 0;
7847 if (u1->hshake.conntype != u2->hshake.conntype)
7848 u1->hshake.conntype = 0;
7849 if (u1->hshake.sockid != u2->hshake.sockid)
7850 u1->hshake.sockid = 0;
7851
7852 u1->src.solo += u2->src.solo;
7853 u1->src.first += u2->src.first;
7854 u1->src.middle += u2->src.middle;
7855 u1->src.last += u2->src.last;
7856 u1->src.drops += u2->src.drops;
7857 u1->src.retrans += u2->src.retrans;
7858 u1->src.nacked += u2->src.nacked;
7859 break;
7860 }
7861
7862 case ARGUS_ESP_DSR: {
7863 struct ArgusESPObject *e1 = &n1->net_union.esp;
7864 struct ArgusESPObject *e2 = &n2->net_union.esp;
7865
7866 n1->hdr.argus_dsrvl8.qual |= n2->hdr.argus_dsrvl8.qual;
7867
7868 e1->lastseq = e2->lastseq;
7869 e1->lostseq += e2->lostseq;
7870 if (e1->spi != e2->spi) {
7871 e1->spi = 0;
7872 }
7873 }
7874 }
7875
7876 }
7877 }
7878 break;
7879 }
7880
7881 // Merging IP Attribute objects involves
7882 // of rollover any time soon, as we're working with 64 bit
7883 // ints with the canonical DSR. We should test for rollover
7884 // but lets do that later - cb
7885
7886 case ARGUS_IPATTR_INDEX: {
7887 struct ArgusIPAttrStruct *attr1 = (struct ArgusIPAttrStruct *)ns1->dsrs[ARGUS_IPATTR_INDEX];
7888 struct ArgusIPAttrStruct *attr2 = (struct ArgusIPAttrStruct *)ns2->dsrs[ARGUS_IPATTR_INDEX];
7889
7890 if (attr1 && attr2) {
7891 if (attr1->hdr.argus_dsrvl8.len == 0) {
7892 bcopy ((char *) attr2, (char *) attr1, sizeof (*attr1));
7893 break;
7894 }
7895
7896 if ((attr1->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_SRC) &&
7897 (attr2->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_SRC)) {
7898 if (attr1->src.tos != attr2->src.tos)
7899 attr1->src.tos = 0;
7900
7901 if (attr1->src.ttl != attr2->src.ttl)
7902 if ((attr2->src.ttl > 0) && (attr1->src.ttl > attr2->src.ttl))
7903 attr1->src.ttl = attr2->src.ttl;
7904
7905 attr1->src.options ^= attr2->src.options;
7906 if (attr2->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_SRC_FRAGMENTS)
7907 attr1->hdr.argus_dsrvl8.qual |= ARGUS_IPATTR_SRC_FRAGMENTS;
7908
7909 } else
7910 if (!(attr1->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_SRC) &&
7911 (attr2->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_SRC)) {
7912 bcopy ((char *)&attr2->src, (char *)&attr1->src, sizeof(attr1->src));
7913 attr1->hdr.argus_dsrvl8.qual |= ARGUS_IPATTR_SRC;
7914 if (attr2->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_SRC_OPTIONS)
7915 attr1->hdr.argus_dsrvl8.qual |= ARGUS_IPATTR_SRC_OPTIONS;
7916 if (attr2->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_SRC_FRAGMENTS)
7917 attr1->hdr.argus_dsrvl8.qual |= ARGUS_IPATTR_SRC_FRAGMENTS;
7918 }
7919
7920 if ((attr1->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_DST) &&
7921 (attr2->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_DST)) {
7922 if (attr1->dst.tos != attr2->dst.tos)
7923 attr1->dst.tos = 0;
7924
7925 if (attr1->dst.ttl != attr2->dst.ttl)
7926 if ((attr2->dst.ttl > 0) && (attr1->dst.ttl > attr2->dst.ttl))
7927 attr1->dst.ttl = attr2->dst.ttl;
7928
7929 attr1->dst.options ^= attr2->dst.options;
7930 if (attr2->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_DST_FRAGMENTS)
7931 attr1->hdr.argus_dsrvl8.qual |= ARGUS_IPATTR_DST_FRAGMENTS;
7932
7933 } else
7934 if (!(attr1->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_DST) &&
7935 (attr2->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_DST)) {
7936 bcopy ((char *)&attr2->dst, (char *)&attr1->dst, sizeof(attr1->dst));
7937 attr1->hdr.argus_dsrvl8.qual |= ARGUS_IPATTR_DST;
7938 if (attr2->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_DST_OPTIONS)
7939 attr1->hdr.argus_dsrvl8.qual |= ARGUS_IPATTR_DST_OPTIONS;
7940 if (attr2->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_DST_FRAGMENTS)
7941 attr1->hdr.argus_dsrvl8.qual |= ARGUS_IPATTR_DST_FRAGMENTS;
7942 }
7943 }
7944 break;
7945 }
7946
7947 // Merging metrics data involves accumulating counters.
7948
7949 case ARGUS_METRIC_INDEX: {
7950 struct ArgusMetricStruct *m1 = (struct ArgusMetricStruct *) ns1->dsrs[ARGUS_METRIC_INDEX];
7951 struct ArgusMetricStruct *m2 = (struct ArgusMetricStruct *) ns2->dsrs[ARGUS_METRIC_INDEX];
7952 if (m1 && m2) {
7953 if (m1->hdr.argus_dsrvl8.len == 0) {
7954 bcopy ((char *) m2, (char *) m1, sizeof (*m1));
7955 break;
7956 }
7957
7958 m1->src.pkts += m2->src.pkts;
7959 m1->src.bytes += m2->src.bytes;
7960 m1->src.appbytes += m2->src.appbytes;
7961 m1->dst.pkts += m2->dst.pkts;
7962 m1->dst.bytes += m2->dst.bytes;
7963 m1->dst.appbytes += m2->dst.appbytes;
7964 }
7965 break;
7966 }
7967
7968
7969 // Merging packet size data involves max min comparisons
7970 // as well as a reformulation of the histogram if being used.
7971
7972 case ARGUS_PSIZE_INDEX: {
7973 struct ArgusPacketSizeStruct *p1 = (struct ArgusPacketSizeStruct *) ns1->dsrs[ARGUS_PSIZE_INDEX];
7974 struct ArgusPacketSizeStruct *p2 = (struct ArgusPacketSizeStruct *) ns2->dsrs[ARGUS_PSIZE_INDEX];
7975
7976 if (p1 && p2) {
7977 if (p1->hdr.argus_dsrvl8.len == 0) {
7978 bcopy ((char *) p2, (char *) p1, sizeof (*p1));
7979 } else {
7980 if ((p1->hdr.subtype & ARGUS_PSIZE_SRC_MAX_MIN) &&
7981 (p2->hdr.subtype & ARGUS_PSIZE_SRC_MAX_MIN)) {
7982 if (p1->src.psizemax < p2->src.psizemax)
7983 p1->src.psizemax = p2->src.psizemax;
7984 if (p1->src.psizemin > p2->src.psizemin)
7985 p1->src.psizemin = p2->src.psizemin;
7986
7987 if (p1->hdr.subtype & ARGUS_PSIZE_HISTO) {
7988 int x, max, tot, val[8];
7989 for (x = 0, max = 0, tot = 0; x < 8; x++) {
7990 val[x] = (p1->src.psize[x] + p2->src.psize[x]);
7991 tot += val[x];
7992 if (max < val[x])
7993 max = val[x];
7994 }
7995 for (x = 0; x < 8; x++) {
7996 if (val[x]) {
7997 if (max > 255)
7998 val[x] = (val[x] * 255)/max;
7999 if (val[x] == 0)
8000 val[x] = 1;
8001 }
8002 p1->src.psize[x] = val[x];
8003 }
8004 }
8005
8006 } else {
8007 if (p2->hdr.subtype & ARGUS_PSIZE_SRC_MAX_MIN) {
8008 p1->hdr.subtype |= ARGUS_PSIZE_SRC_MAX_MIN;
8009 bcopy (&p2->src, &p1->src, sizeof(p1->src));
8010 }
8011 }
8012 if ((p1->hdr.subtype & ARGUS_PSIZE_DST_MAX_MIN) &&
8013 (p2->hdr.subtype & ARGUS_PSIZE_DST_MAX_MIN)) {
8014 if (p1->dst.psizemax < p2->dst.psizemax)
8015 p1->dst.psizemax = p2->dst.psizemax;
8016 if (p1->dst.psizemin > p2->dst.psizemin)
8017 p1->dst.psizemin = p2->dst.psizemin;
8018
8019 if (p1->hdr.subtype & ARGUS_PSIZE_HISTO) {
8020 int x, max, tot, val[8];
8021 for (x = 0, max = 0, tot = 0; x < 8; x++) {
8022 val[x] = (p1->dst.psize[x] + p2->dst.psize[x]);
8023 tot += val[x];
8024 if (max < val[x])
8025 max = val[x];
8026 }
8027 for (x = 0; x < 8; x++) {
8028 if (val[x]) {
8029 if (max > 255)
8030 val[x] = (val[x] * 255)/max;
8031 if (val[x] == 0)
8032 val[x] = 1;
8033 }
8034 p1->dst.psize[x] = val[x];
8035 }
8036 }
8037 } else {
8038 if (p2->hdr.subtype & ARGUS_PSIZE_DST_MAX_MIN) {
8039 p1->hdr.subtype |= ARGUS_PSIZE_DST_MAX_MIN;
8040 bcopy (&p2->dst, &p1->dst, sizeof(p1->dst));
8041 }
8042 }
8043 }
8044 }
8045 break;
8046 }
8047
8048
8049 // Merging the aggregation object results in ns1 having
8050 // a valid aggregation object, with updates to the various
8051 // aggregation metrics. So, ns1 should have a valid agr,
8052 // as prior merging of the metrics fields will have
8053 // generated it if ns1 did not have an agr. If ns2 does
8054 // not have an agr, then merge into ns1's agr the values
8055 // for ns2's metrics. If ns2 does exist, then just merge
8056 // the two agr's.
8057
8058 case ARGUS_AGR_INDEX: {
8059 struct ArgusAgrStruct *a1 = (struct ArgusAgrStruct *) ns1->dsrs[ARGUS_AGR_INDEX];
8060 struct ArgusAgrStruct *a2 = (struct ArgusAgrStruct *) ns2->dsrs[ARGUS_AGR_INDEX];
8061 struct ArgusAgrStruct databuf, *data = &databuf;
8062 double ss1 = 0, ss2 = 0, sum1 = 0, sum2 = 0, value = 0;
8063 int x = 0, n = 0, items = 0;
8064
8065 if (a1 && a2) {
8066 if ((a1->hdr.subtype == a2->hdr.subtype) ||
8067 (((a1->hdr.subtype == ARGUSMETRICDURATION) || (a1->hdr.subtype == 0x01)) &&
8068 ((a2->hdr.subtype == ARGUSMETRICDURATION) || (a2->hdr.subtype == 0x01)))) {
8069
8070 double tvalstd = 0, tvalmean = 0, meansqrd = 0;
8071
8072 bzero(data, sizeof(*data));
8073
8074 if (a1->hdr.argus_dsrvl8.len == 0) {
8075 bcopy ((char *) a2, (char *) a1, sizeof (*a1));
8076 break;
8077 }
8078
8079 bcopy ((char *)&a1->hdr, (char *)&data->hdr, sizeof(data->hdr));
8080
8081 data->count = a1->count + a2->count;
8082
8083 if (data->count) {
8084 data->act.maxval = (a1->act.maxval > a2->act.maxval) ? a1->act.maxval : a2->act.maxval;
8085 data->act.minval = (a1->act.minval < a2->act.minval) ? a1->act.minval : a2->act.minval;
8086 data->act.n = a1->act.n + a2->act.n;
8087
8088 sum1 = (a1->act.n > 1) ? (a1->act.meanval * a1->act.n) : a1->act.meanval;
8089 sum2 = (a2->act.n > 1) ? (a2->act.meanval * a2->act.n) : a2->act.meanval;
8090
8091 if (a1->act.n > 1) {
8092 tvalstd = pow(a1->act.stdev, 2.0);
8093 tvalmean = pow(a1->act.meanval, 2.0);
8094
8095 ss1 = a1->act.n * (tvalstd + tvalmean);
8096 } else {
8097 ss1 = pow(a1->act.meanval, 2.0);
8098 }
8099 if (a2->act.n > 1) {
8100 tvalstd = pow(a2->act.stdev, 2.0);
8101 tvalmean = pow(a2->act.meanval, 2.0);
8102 ss2 = a2->act.n * (tvalstd + tvalmean);
8103
8104 } else {
8105 ss2 = pow(a2->act.meanval, 2.0);
8106 }
8107
8108 if (data->act.n > 0) {
8109 data->act.meanval = (sum1 + sum2) / data->act.n;
8110 meansqrd = pow(data->act.meanval, 2.0);
8111 data->act.stdev = sqrt(fabs(((ss1 + ss2)/(data->act.n)) - meansqrd));
8112 }
8113
8114 value = 0.0;
8115 ss1 = 0.0;
8116
8117 sum1 = (a1->idle.n > 1) ? (a1->idle.meanval * a1->idle.n) : a1->idle.meanval;
8118 sum2 = (a2->idle.n > 1) ? (a2->idle.meanval * a2->idle.n) : a2->idle.meanval;
8119
8120 if (a1->idle.stdev != 0) {
8121 tvalstd = pow(a1->idle.stdev, 2.0);
8122 ss1 = a1->idle.n * (tvalstd + pow(a1->idle.meanval, 2.0));
8123
8124 } else
8125 ss1 = pow(a1->idle.meanval, 2.0);
8126
8127 ss1 += pow(deltaSrcTime, 2.0) + pow(deltaDstTime, 2.0);
8128
8129 if (a2->idle.stdev != 0) {
8130 tvalstd = pow(a2->idle.stdev, 2.0);
8131 ss2 = a2->idle.n * (tvalstd + pow(a2->idle.meanval, 2.0));
8132
8133 } else
8134 ss2 = pow(a2->idle.meanval, 2.0);
8135
8136 ss2 += pow(deltaSrcTime, 2.0) + pow(deltaDstTime, 2.0);
8137
8138 if ((items = (a1->idle.n + a2->idle.n)) > 0) {
8139 for (n = 0; n < 8; n++) {
8140 int value = ((a1->idle.fdist[n] * a1->idle.n) + (a2->idle.fdist[n] * a2->idle.n)) / items;
8141 data->idle.fdist[n] = (value > 0xFF) ? 0xFF : value;
8142 if (data->idle.fdist[n] == 0) {
8143 if (a1->idle.fdist[n] || a2->idle.fdist[n])
8144 data->idle.fdist[n] = 1;
8145 }
8146 }
8147 }
8148 }
8149
8150 if (deltaSrcTime || deltaDstTime) {
8151 if (deltaSrcTime) {
8152 value += deltaSrcTime;
8153 if (deltaSrcTime > a1->idle.maxval) a1->idle.maxval = deltaSrcTime;
8154 if (deltaSrcTime < a1->idle.minval) a1->idle.minval = deltaSrcTime;
8155 a1->idle.n++;
8156 }
8157 if (deltaDstTime) {
8158 value += deltaDstTime;
8159 if (deltaDstTime > a1->idle.maxval) a1->idle.maxval = deltaDstTime;
8160 if (deltaDstTime < a1->idle.minval) a1->idle.minval = deltaDstTime;
8161 a1->idle.n++;
8162 }
8163
8164 sum1 += value;
8165
8166 data->idle.maxval = (a1->idle.maxval > a2->idle.maxval) ? a1->idle.maxval : a2->idle.maxval;
8167 data->idle.minval = (a1->idle.minval < a2->idle.minval) ? a1->idle.minval : a2->idle.minval;
8168
8169 if ((data->idle.n = a1->idle.n + a2->idle.n) > 0) {
8170 data->idle.meanval = (sum1 + sum2) / data->idle.n;
8171
8172 if (data->idle.n > 1)
8173 data->idle.stdev = sqrt (fabs(((ss1 + ss2)/(data->idle.n)) - pow(data->idle.meanval, 2.0)));
8174 }
8175
8176 for (n = 0, x = 10; (n < 8) && (deltaSrcTime || deltaDstTime); n++) {
8177 if (deltaSrcTime && (deltaSrcTime < x)) {
8178 if (data->idle.fdist[n] < 0xFF)
8179 data->idle.fdist[n]++;
8180 deltaSrcTime = 0;
8181 }
8182 if (deltaDstTime && (deltaDstTime < x)) {
8183 if (data->idle.fdist[n] < 0xFF)
8184 data->idle.fdist[n]++;
8185 deltaDstTime = 0;
8186 }
8187 x *= 10;
8188 }
8189
8190 data->laststartime = ((a1->laststartime.tv_sec > a2->laststartime.tv_sec) ||
8191 ((a1->laststartime.tv_sec == a2->laststartime.tv_sec) &&
8192 (a1->laststartime.tv_usec > a2->laststartime.tv_usec))) ?
8193 a1->laststartime : a2->laststartime;
8194
8195 data->lasttime = ((a1->lasttime.tv_sec > a2->lasttime.tv_sec) ||
8196 ((a1->lasttime.tv_sec == a2->lasttime.tv_sec) &&
8197 (a1->lasttime.tv_usec > a2->lasttime.tv_usec))) ?
8198 a1->lasttime : a2->lasttime;
8199 } else {
8200 // looks like we're completing the first two records, so merge into active.
8201
8202 }
8203
8204 bcopy ((char *)data, (char *) a1, sizeof (databuf));
8205 }
8206
8207 } else {
8208 if (a1 && !(a2)) {
8209 double value = na->RaMetricFetchAlgorithm(ns2);
8210 double tvalstd = 0, meansqrd = 0;
8211
8212 a1->count++;
8213
8214 if (a1->act.maxval < value) a1->act.maxval = value;
8215
8216 if (value != 0)
8217 if (a1->act.minval > value)
8218 a1->act.minval = value;
8219
8220 sum1 = a1->act.meanval * a1->act.n;
8221 sum1 += value;
8222
8223 if (a1->act.stdev != 0) {
8224 tvalstd = pow(a1->act.stdev, 2.0);
8225 ss1 = a1->act.n * (tvalstd + pow(a1->act.meanval, 2.0));
8226
8227 } else
8228 ss1 = pow(a1->act.meanval, 2.0);
8229
8230 ss1 += pow(value, 2.0);
8231
8232 a1->act.n++;
8233 a1->act.meanval = sum1 / a1->act.n;
8234 meansqrd = pow(a1->act.meanval, 2.0);
8235
8236 a1->act.stdev = sqrt(fabs((ss1/(a1->act.n)) - meansqrd));
8237
8238 } else {
8239 if (!(a1) && a2) {
8240 if ((a1 = ArgusCalloc(1, sizeof(*a1))) == NULL)
8241 ArgusLog (LOG_ERR, "ArgusMergeRecords: ArgusCalloc error %s", strerror(errno));
8242 bcopy ((char *)a2, (char *)a1, sizeof(*a2));
8243 ns1->dsrs[ARGUS_AGR_INDEX] = (struct ArgusDSRHeader *) a1;
8244 ns1->dsrindex |= (0x01 << ARGUS_AGR_INDEX);
8245 }
8246 }
8247 }
8248 break;
8249 }
8250
8251 // Merging the jitter object involves both records having
8252 // a valid jitter object. If they don't just drop the dsr;
8253
8254
8255 case ARGUS_JITTER_INDEX: {
8256 struct ArgusJitterStruct *j1 = (struct ArgusJitterStruct *) ns1->dsrs[ARGUS_JITTER_INDEX];
8257 struct ArgusJitterStruct *j2 = (struct ArgusJitterStruct *) ns2->dsrs[ARGUS_JITTER_INDEX];
8258
8259 if (j1 && j2) {
8260 if (j1->hdr.argus_dsrvl8.len == 0) {
8261 bcopy ((char *) j2, (char *) j1, sizeof (*j1));
8262 break;
8263 }
8264
8265 if (j2->src.act.n > 0) {
8266 unsigned int n, stdev = 0;
8267 double meanval, sumsqrd = 0.0;
8268
8269 n = (j1->src.act.n + j2->src.act.n);
8270 meanval = (((double)j1->src.act.meanval * (double)j1->src.act.n) +
8271 ((double)j2->src.act.meanval * (double)j2->src.act.n)) / n;
8272
8273 if (j1->src.act.n) {
8274 double sum = (double)j1->src.act.meanval * (double)j1->src.act.n;
8275 sumsqrd += (j1->src.act.n * ((double)j1->src.act.stdev * (double)j1->src.act.stdev)) +
8276 (sum * sum)/j1->src.act.n;
8277 }
8278
8279 if (j2->src.act.n) {
8280 double sum = (double)j2->src.act.meanval * (double)j2->src.act.n;
8281 sumsqrd += (j2->src.act.n * ((double)j2->src.act.stdev * (double)j2->src.act.stdev)) +
8282 (sum * sum)/j2->src.act.n;
8283 }
8284 stdev = (int) sqrt (fabs((sumsqrd/n) - ((double)meanval * (double)meanval)));
8285
8286 j1->src.act.n = n;
8287 j1->src.act.meanval = (unsigned int) meanval;
8288 j1->src.act.stdev = stdev;
8289 if (j1->src.act.minval > j2->src.act.minval)
8290 j1->src.act.minval = j2->src.act.minval;
8291 if (j1->src.act.maxval < j2->src.act.maxval)
8292 j1->src.act.maxval = j2->src.act.maxval;
8293
8294 switch (j1->hdr.subtype & (ARGUS_HISTO_EXP | ARGUS_HISTO_LINEAR)) {
8295 case ARGUS_HISTO_EXP: {
8296 int x, max, tot, val[8];
8297
8298 for (x = 0, max = 0, tot = 0; x < 8; x++) {
8299 val[x] = (j1->src.act.dist_union.fdist[x] + j2->src.act.dist_union.fdist[x]);
8300 tot += val[x];
8301 if (max < val[x])
8302 max = val[x];
8303 }
8304 for (x = 0; x < 8; x++) {
8305 if (val[x]) {
8306 if (max > 255)
8307 val[x] = (val[x] * 255)/max;
8308 if (val[x] == 0)
8309 val[x] = 1;
8310 }
8311 j1->src.act.dist_union.fdist[x] = val[x];
8312 }
8313 break;
8314 }
8315 case ARGUS_HISTO_LINEAR: {
8316 break;
8317 }
8318 }
8319 }
8320
8321 if (j2->src.idle.n > 0) {
8322 unsigned int n, stdev = 0;
8323 double meanval, sumsqrd = 0.0;
8324
8325 n = (j1->src.idle.n + j2->src.idle.n);
8326 meanval = (((double) j1->src.idle.meanval * (double) j1->src.idle.n) +
8327 ((double) j2->src.idle.meanval * (double) j2->src.idle.n)) / n;
8328
8329 if (j1->src.idle.n) {
8330 double sum = (double) j1->src.idle.meanval * (double) j1->src.idle.n;
8331 sumsqrd += (j1->src.idle.n * ((double)j1->src.idle.stdev * (double)j1->src.idle.stdev)) +
8332 ((double)sum *(double)sum)/j1->src.idle.n;
8333 }
8334
8335 if (j2->src.idle.n) {
8336 double sum = (double) j2->src.idle.meanval * (double) j2->src.idle.n;
8337 sumsqrd += (j2->src.idle.n * ((double)j2->src.idle.stdev * (double)j2->src.idle.stdev)) +
8338 ((double)sum *(double)sum)/j2->src.idle.n;
8339 }
8340 stdev = (int) sqrt (fabs((sumsqrd/n) - ((double)meanval * (double)meanval)));
8341
8342 j1->src.idle.n = n;
8343 j1->src.idle.meanval = (unsigned int) meanval;
8344 j1->src.idle.stdev = stdev;
8345 if (j1->src.idle.minval > j2->src.idle.minval)
8346 j1->src.idle.minval = j2->src.idle.minval;
8347 if (j1->src.idle.maxval < j2->src.idle.maxval)
8348 j1->src.idle.maxval = j2->src.idle.maxval;
8349
8350 switch (j1->hdr.subtype & (ARGUS_HISTO_EXP | ARGUS_HISTO_LINEAR)) {
8351 case ARGUS_HISTO_EXP: {
8352 int x, max, tot, val[8];
8353
8354 for (x = 0, max = 0, tot = 0; x < 8; x++) {
8355 val[x] = (j1->src.idle.dist_union.fdist[x] + j2->src.idle.dist_union.fdist[x]);
8356 tot += val[x];
8357 if (max < val[x])
8358 max = val[x];
8359 }
8360 for (x = 0; x < 8; x++) {
8361 if (val[x]) {
8362 if (max > 255)
8363 val[x] = (val[x] * 255)/max;
8364 if (val[x] == 0)
8365 val[x] = 1;
8366 }
8367 j1->src.idle.dist_union.fdist[x] = val[x];
8368 }
8369 break;
8370 }
8371 case ARGUS_HISTO_LINEAR: {
8372 break;
8373 }
8374 }
8375 }
8376
8377 if (j2->dst.act.n > 0) {
8378 unsigned int n, stdev = 0;
8379 double meanval, sumsqrd = 0.0;
8380
8381 n = (j1->dst.act.n + j2->dst.act.n);
8382 meanval = (((double) j1->dst.act.meanval * (double) j1->dst.act.n) +
8383 ((double) j2->dst.act.meanval * (double) j2->dst.act.n)) / n;
8384
8385 if (j1->dst.act.n) {
8386 double sum = j1->dst.act.meanval * j1->dst.act.n;
8387 sumsqrd += (j1->dst.act.n * ((double)j1->dst.act.stdev * (double)j1->dst.act.stdev)) +
8388 (sum * sum)/j1->dst.act.n;
8389 }
8390
8391 if (j2->dst.act.n) {
8392 double sum = (double) j2->dst.act.meanval * (double) j2->dst.act.n;
8393 sumsqrd += (j2->dst.act.n * ((double)j2->dst.act.stdev * (double)j2->dst.act.stdev)) +
8394 ((double)sum *(double)sum)/j2->dst.act.n;
8395 }
8396 stdev = (int) sqrt (fabs((sumsqrd/n) - ((double)meanval * (double)meanval)));
8397
8398 j1->dst.act.n = n;
8399 j1->dst.act.meanval = (unsigned int) meanval;
8400 j1->dst.act.stdev = stdev;
8401 if (j1->dst.act.minval > j2->dst.act.minval)
8402 j1->dst.act.minval = j2->dst.act.minval;
8403 if (j1->dst.act.maxval < j2->dst.act.maxval)
8404 j1->dst.act.maxval = j2->dst.act.maxval;
8405
8406 switch (j1->hdr.subtype & (ARGUS_HISTO_EXP | ARGUS_HISTO_LINEAR)) {
8407 case ARGUS_HISTO_EXP: {
8408 int x, max, tot, val[8];
8409
8410 for (x = 0, max = 0, tot = 0; x < 8; x++) {
8411 val[x] = (j1->dst.act.dist_union.fdist[x] + j2->dst.act.dist_union.fdist[x]);
8412 tot += val[x];
8413 if (max < val[x])
8414 max = val[x];
8415 }
8416 for (x = 0; x < 8; x++) {
8417 if (val[x]) {
8418 if (max > 255)
8419 val[x] = (val[x] * 255)/max;
8420 if (val[x] == 0)
8421 val[x] = 1;
8422 }
8423 j1->dst.act.dist_union.fdist[x] = val[x];
8424 }
8425 break;
8426 }
8427 case ARGUS_HISTO_LINEAR: {
8428 break;
8429 }
8430 }
8431 }
8432
8433 if (j2->dst.idle.n > 0) {
8434 unsigned int n, stdev = 0;
8435 double meanval, sumsqrd = 0.0;
8436
8437 n = (j1->dst.idle.n + j2->dst.idle.n);
8438 meanval = (((double) j1->dst.idle.meanval * (double) j1->dst.idle.n) +
8439 ((double) j2->dst.idle.meanval * (double) j2->dst.idle.n)) / n;
8440
8441 if (j1->dst.idle.n) {
8442 int sum = (double) j1->dst.idle.meanval * (double) j1->dst.idle.n;
8443 sumsqrd += (j1->dst.idle.n * ((double)j1->dst.idle.stdev * (double)j1->dst.idle.stdev)) +
8444 ((double)sum *(double)sum)/j1->dst.idle.n;
8445 }
8446
8447 if (j2->dst.idle.n) {
8448 double sum = (double) j2->dst.idle.meanval * (double) j2->dst.idle.n;
8449 sumsqrd += (j2->dst.idle.n * ((double)j2->dst.idle.stdev * (double)j2->dst.idle.stdev)) +
8450 ((double)sum *(double)sum)/j2->dst.idle.n;
8451 }
8452 stdev = (int) sqrt (fabs((sumsqrd/n) - ((double)meanval * (double)meanval)));
8453
8454 j1->dst.idle.n = n;
8455 j1->dst.idle.meanval = (unsigned int) meanval;
8456 j1->dst.idle.stdev = stdev;
8457 if (j1->dst.idle.minval > j2->dst.idle.minval)
8458 j1->dst.idle.minval = j2->dst.idle.minval;
8459 if (j1->dst.idle.maxval < j2->dst.idle.maxval)
8460 j1->dst.idle.maxval = j2->dst.idle.maxval;
8461
8462 switch (j1->hdr.subtype & (ARGUS_HISTO_EXP | ARGUS_HISTO_LINEAR)) {
8463 case ARGUS_HISTO_EXP: {
8464 int x, max, tot, val[8];
8465
8466 for (x = 0, max = 0, tot = 0; x < 8; x++) {
8467 val[x] = (j1->dst.idle.dist_union.fdist[x] + j2->dst.idle.dist_union.fdist[x]);
8468 tot += val[x];
8469 if (max < val[x])
8470 max = val[x];
8471 }
8472 for (x = 0; x < 8; x++) {
8473 if (val[x]) {
8474 if (max > 255)
8475 val[x] = (val[x] * 255)/max;
8476 if (val[x] == 0)
8477 val[x] = 1;
8478 }
8479 j1->dst.idle.dist_union.fdist[x] = val[x];
8480 }
8481 break;
8482 }
8483 case ARGUS_HISTO_LINEAR: {
8484 break;
8485 }
8486 }
8487 }
8488
8489 } else {
8490 if (!j1 && j2) {
8491 if ((j1 = (void *) ArgusCalloc (1, sizeof(*j1))) == NULL)
8492 ArgusLog (LOG_ERR, "ArgusMergeRecords: ArgusCalloc error %s", strerror(errno));
8493 bcopy ((char *) j2, (char *)j1, sizeof (*j1));
8494 ns1->dsrs[i] = (struct ArgusDSRHeader *) j1;
8495 ns1->dsrindex |= (0x01 << i);
8496 }
8497 }
8498 break;
8499 }
8500
8501 // Merging the user data object involves leaving the ns1 buffer,
8502 // or making the ns2 buffer, ns1's. Since these are allocated
8503 // objects, make sure you deal with them as such.
8504
8505
8506 case ARGUS_SRCUSERDATA_INDEX:
8507 case ARGUS_DSTUSERDATA_INDEX: {
8508 struct ArgusDataStruct *d1 = (struct ArgusDataStruct *) ns1->dsrs[i];
8509 struct ArgusDataStruct *d2 = (struct ArgusDataStruct *) ns2->dsrs[i];
8510
8511 if (d1 && d2) {
8512 int tlen = d1->size - d1->count;
8513 tlen = (tlen > d2->count) ? d2->count : tlen;
8514 if (tlen > 0) {
8515 bcopy(d2->array, &d1->array[d1->count], tlen);
8516 d1->count += tlen;
8517 }
8518 } else
8519 if (!d1 && d2) {
8520 struct ArgusDataStruct *t2;
8521 int len = (((d2->hdr.type & ARGUS_IMMEDIATE_DATA) ? 1 :
8522 ((d2->hdr.subtype & ARGUS_LEN_16BITS) ? d2->hdr.argus_dsrvl16.len :
8523 d2->hdr.argus_dsrvl8.len)));
8524 if ((t2 = (struct ArgusDataStruct *) ArgusCalloc((2 + len), 4)) == NULL)
8525 ArgusLog (LOG_ERR, "ArgusMergeRecords: ArgusCalloc error %s", strerror(errno));
8526
8527 bcopy ((char *)d2, (char *)t2, len * 4);
8528 t2->size = (len - 2) * 4;
8529 ns1->dsrs[i] = (struct ArgusDSRHeader *) t2;
8530 ns1->dsrindex |= (0x01 << i);
8531 }
8532 break;
8533 }
8534
8535
8536 // Merging the MAC data object involves comparing the ns1 buffer,
8537 // leaving them if they are equal and blowing away the value if they
8538 // are different.
8539
8540 case ARGUS_ENCAPS_INDEX: {
8541 struct ArgusEncapsStruct *e1 = (struct ArgusEncapsStruct *) ns1->dsrs[ARGUS_ENCAPS_INDEX];
8542 struct ArgusEncapsStruct *e2 = (struct ArgusEncapsStruct *) ns2->dsrs[ARGUS_ENCAPS_INDEX];
8543
8544 if (e1 && e2) {
8545 if (e1->src != e2->src) {
8546 e1->hdr.argus_dsrvl8.qual |= ARGUS_SRC_CHANGED;
8547 e1->src |= e2->src;
8548 }
8549 if (e1->dst != e2->dst) {
8550 e1->hdr.argus_dsrvl8.qual |= ARGUS_DST_CHANGED;
8551 e1->dst |= e2->dst;
8552 }
8553 }
8554 break;
8555 }
8556
8557 case ARGUS_MAC_INDEX: {
8558 struct ArgusMacStruct *m1 = (struct ArgusMacStruct *) ns1->dsrs[ARGUS_MAC_INDEX];
8559 struct ArgusMacStruct *m2 = (struct ArgusMacStruct *) ns2->dsrs[ARGUS_MAC_INDEX];
8560
8561 if (m1 && m2) {
8562 if (m1->hdr.subtype == m2->hdr.subtype) {
8563 switch (m1->hdr.subtype) {
8564 case ARGUS_TYPE_ETHER: {
8565 struct ether_header *e1 = &m1->mac.mac_union.ether.ehdr;
8566 struct ether_header *e2 = &m2->mac.mac_union.ether.ehdr;
8567
8568 if (bcmp(&e1->ether_shost, &e2->ether_shost, sizeof(e1->ether_shost)))
8569 bzero ((char *)&e1->ether_shost, sizeof(e1->ether_shost));
8570
8571 if (bcmp(&e1->ether_dhost, &e2->ether_dhost, sizeof(e1->ether_dhost)))
8572 bzero ((char *)&e1->ether_dhost, sizeof(e1->ether_dhost));
8573 break;
8574 }
8575 }
8576
8577 } else {
8578 ArgusFree(ns1->dsrs[ARGUS_MAC_INDEX]);
8579 ns1->dsrs[ARGUS_MAC_INDEX] = NULL;
8580 ns1->dsrindex &= ~(0x01 << i);
8581 }
8582
8583 } else {
8584 if (ns1->dsrs[ARGUS_MAC_INDEX] != NULL) {
8585 ArgusFree(ns1->dsrs[ARGUS_MAC_INDEX]);
8586 ns1->dsrs[ARGUS_MAC_INDEX] = NULL;
8587 ns1->dsrindex &= ~(0x01 << i);
8588 }
8589 }
8590 break;
8591 }
8592
8593 // Merging vlan and mpls tags needs a bit of work.
8594
8595 case ARGUS_VLAN_INDEX:
8596 case ARGUS_MPLS_INDEX: {
8597 break;
8598 }
8599
8600 case ARGUS_ICMP_INDEX: {
8601 struct ArgusIcmpStruct *i1 = (struct ArgusIcmpStruct *) ns1->dsrs[ARGUS_ICMP_INDEX];
8602 struct ArgusIcmpStruct *i2 = (struct ArgusIcmpStruct *) ns2->dsrs[ARGUS_ICMP_INDEX];
8603
8604 if (i1 && i2) {
8605 if ((i1->hdr.argus_dsrvl8.qual & ARGUS_ICMP_MAPPED) &&
8606 (i2->hdr.argus_dsrvl8.qual & ARGUS_ICMP_MAPPED)) {
8607 struct ArgusFlow *flow = (void *)ns1->dsrs[ARGUS_FLOW_INDEX];
8608 int type = 0;
8609
8610 if (flow != NULL) {
8611 switch (flow->hdr.subtype & 0x3F) {
8612 case ARGUS_FLOW_CLASSIC5TUPLE:
8613 case ARGUS_FLOW_LAYER_3_MATRIX: {
8614 switch (type = (flow->hdr.argus_dsrvl8.qual & 0x1F)) {
8615 case ARGUS_TYPE_IPV4: {
8616 unsigned char masklen = 32;
8617 ArgusMergeAddress(&i1->osrcaddr, &i2->osrcaddr, ARGUS_TYPE_IPV4, ARGUS_SRC, &masklen);
8618 break;
8619 }
8620
8621 case ARGUS_TYPE_IPV6:
8622 break;
8623 }
8624 break;
8625 }
8626 }
8627 }
8628 }
8629 }
8630
8631 if (!i1 && i2) {
8632 int len = i2->hdr.argus_dsrvl8.len;
8633
8634 if (len > 0) {
8635 if ((i1 = ArgusCalloc(1, len * 4)) == NULL)
8636 ArgusLog (LOG_ERR, "ArgusMergeRecords: ArgusCalloc error %s", strerror(errno));
8637 bcopy ((char *)i2, (char *)i1, len * 4);
8638
8639 ns1->dsrs[ARGUS_ICMP_INDEX] = (struct ArgusDSRHeader *) i1;
8640 ns1->dsrindex |= (0x01 << ARGUS_ICMP_INDEX);
8641 }
8642 }
8643 break;
8644 }
8645
8646 case ARGUS_COCODE_INDEX: {
8647 struct ArgusCountryCodeStruct *c1 = (void *) ns1->dsrs[ARGUS_COCODE_INDEX];
8648 struct ArgusCountryCodeStruct *c2 = (void *) ns2->dsrs[ARGUS_COCODE_INDEX];
8649
8650 if (c1 && c2) {
8651 if (bcmp(c1->src, c2->src, sizeof(c1->src)))
8652 bzero(&c1->src, sizeof(c1->src));
8653 if (bcmp(c1->dst, c2->dst, sizeof(c1->dst)))
8654 bzero(&c1->dst, sizeof(c1->dst));
8655
8656 } else
8657 if (c2) {
8658 int len = c2->hdr.argus_dsrvl8.len;
8659
8660 if (len > 0) {
8661 if ((c1 = ArgusCalloc(1, len * 4)) == NULL)
8662 ArgusLog (LOG_ERR, "ArgusMergeRecords: ArgusCalloc error %s", strerror(errno));
8663 bcopy ((char *)c2, (char *)c2, len * 4);
8664
8665 ns1->dsrs[ARGUS_COCODE_INDEX] = (struct ArgusDSRHeader *) c1;
8666 ns1->dsrindex |= (0x01 << ARGUS_COCODE_INDEX);
8667 }
8668 }
8669 break;
8670 }
8671
8672 case ARGUS_LABEL_INDEX: {
8673 struct ArgusLabelStruct *l1 = (void *) ns1->dsrs[ARGUS_LABEL_INDEX];
8674 struct ArgusLabelStruct *l2 = (void *) ns2->dsrs[ARGUS_LABEL_INDEX];
8675
8676 if (l1 && l2) {
8677 if (l1->l_un.label && l2->l_un.label) {
8678 if (strcmp(l1->l_un.label, l2->l_un.label)) {
8679 char *buf = calloc(1, MAXBUFFERLEN);
8680
8681 if ((ArgusMergeLabel(l1, l2, buf, MAXBUFFERLEN, ARGUS_UNION)) != NULL) {
8682 free(l1->l_un.label);
8683 l1->l_un.label = strdup(buf);
8684 }
8685 free(buf);
8686 }
8687 } else {
8688 if (l2->l_un.label)
8689 l1->l_un.label = strdup(l2->l_un.label);
8690 }
8691
8692 } else {
8693 if (l2 && (l1 == NULL)) {
8694 ns1->dsrs[ARGUS_LABEL_INDEX] = calloc(1, sizeof(struct ArgusLabelStruct));
8695 l1 = (void *) ns1->dsrs[ARGUS_LABEL_INDEX];
8696
8697 bcopy(l2, l1, sizeof(*l2));
8698
8699 if (l2->l_un.label)
8700 l1->l_un.label = strdup(l2->l_un.label);
8701 }
8702 }
8703 break;
8704 }
8705
8706 // Merging the behavioral dsr's currently involve just accumulating the counters.
8707
8708 case ARGUS_BEHAVIOR_INDEX: {
8709 struct ArgusBehaviorStruct *a1 = (void *) ns1->dsrs[ARGUS_BEHAVIOR_INDEX];
8710 struct ArgusBehaviorStruct *a2 = (void *) ns2->dsrs[ARGUS_BEHAVIOR_INDEX];
8711
8712 if (a1 && a2) {
8713 a1->keyStroke.src.n_strokes += a2->keyStroke.src.n_strokes;
8714 a1->keyStroke.dst.n_strokes += a2->keyStroke.dst.n_strokes;
8715
8716 } else {
8717 if (a2 && (a1 == NULL)) {
8718 ns1->dsrs[ARGUS_BEHAVIOR_INDEX] = calloc(1, sizeof(struct ArgusBehaviorStruct));
8719 a1 = (void *) ns1->dsrs[ARGUS_BEHAVIOR_INDEX];
8720
8721 bcopy(a2, a1, sizeof(*a2));
8722 }
8723 }
8724 break;
8725 }
8726 }
8727 }
8728
8729 if ((seconds = RaGetFloatDuration(ns1)) > 0) {
8730 struct ArgusMetricStruct *metric = (void *)ns1->dsrs[ARGUS_METRIC_INDEX];
8731 if (metric != NULL) {
8732 ns1->srate = (float) (metric->src.pkts * 1.0)/seconds;
8733 ns1->drate = (float) (metric->dst.pkts * 1.0)/seconds;
8734 ns1->sload = (float) (metric->src.bytes*8 * 1.0)/seconds;
8735 ns1->dload = (float) (metric->dst.bytes*8 * 1.0)/seconds;
8736 ns1->pcr = (float) ArgusFetchAppByteRatio(ns1);
8737 ns1->dur = seconds;
8738 }
8739 }
8740 }
8741
8742 return;
8743 }
8744
8745
8746 void
ArgusIntersectRecords(struct ArgusAggregatorStruct * na,struct ArgusRecordStruct * ns1,struct ArgusRecordStruct * ns2)8747 ArgusIntersectRecords (struct ArgusAggregatorStruct *na, struct ArgusRecordStruct *ns1, struct ArgusRecordStruct *ns2)
8748 {
8749 struct ArgusAgrStruct *agr = NULL;
8750 int i;
8751
8752 if ((ns1 && ns2) && ((ns1->hdr.type & ARGUS_FAR) && (ns2->hdr.type & ARGUS_FAR))) {
8753 if ((agr = (struct ArgusAgrStruct *) ns1->dsrs[ARGUS_AGR_INDEX]) == NULL) {
8754 double value = na->RaMetricFetchAlgorithm(ns1);
8755
8756 if ((agr = ArgusCalloc(1, sizeof(*agr))) == NULL)
8757 ArgusLog (LOG_ERR, "ArgusIntersectRecords: ArgusCalloc error %s", strerror(errno));
8758
8759 agr->hdr.type = ARGUS_AGR_DSR;
8760 agr->hdr.subtype = na->ArgusMetricIndex;
8761 agr->hdr.argus_dsrvl8.qual = 0x01;
8762 agr->hdr.argus_dsrvl8.len = (sizeof(*agr) + 3)/4;
8763 agr->count = 1;
8764 agr->act.maxval = value;
8765 agr->act.minval = value;
8766 agr->act.meanval = value;
8767 agr->act.n = 1;
8768 ns1->dsrs[ARGUS_AGR_INDEX] = (struct ArgusDSRHeader *) agr;
8769 ns1->dsrindex |= (0x01 << ARGUS_AGR_INDEX);
8770 }
8771
8772 for (i = 0; i < ARGUSMAXDSRTYPE; i++) {
8773 switch (i) {
8774 case ARGUS_FLOW_INDEX: {
8775
8776 // Intersecting Flow records is a matter of testing each field and
8777 // transforming values that are not equal to either run length
8778 // and'ing or zeroing out the value. When a value is zero'ed
8779 // we need to indicate it in the status field of the flow
8780 // descriptor so that values resulting from merging are not
8781 // confused with values actually off the wire.
8782
8783 // run length and'ing is an attempt to preserve CIDR addresses.
8784 // any other value should be either preserved or invalidated.
8785
8786 struct ArgusFlow *f1 = (struct ArgusFlow *) ns1->dsrs[ARGUS_FLOW_INDEX];
8787 struct ArgusFlow *f2 = (struct ArgusFlow *) ns2->dsrs[ARGUS_FLOW_INDEX];
8788
8789 if (f1 && f2) {
8790 unsigned char masklen = 0;
8791 if (f1->hdr.subtype == f2->hdr.subtype) {
8792 switch (f1->hdr.subtype & 0x3F) {
8793 case ARGUS_FLOW_LAYER_3_MATRIX: {
8794 if ((f1->hdr.argus_dsrvl8.qual & 0x1F) == (f2->hdr.argus_dsrvl8.qual & 0x1F)) {
8795 switch (f1->hdr.argus_dsrvl8.qual & 0x1F) {
8796 case ARGUS_TYPE_IPV4:
8797 masklen = (f1->ip_flow.smask > f2->ip_flow.smask) ? f2->ip_flow.smask : f1->ip_flow.smask;
8798 f1->hdr.argus_dsrvl8.qual |= ArgusMergeAddress(&f1->ip_flow.ip_src, &f2->ip_flow.ip_src, ARGUS_TYPE_IPV4, ARGUS_SRC, &masklen);
8799 f1->ip_flow.smask = masklen;
8800
8801 masklen = (f1->ip_flow.dmask > f2->ip_flow.dmask) ? f2->ip_flow.dmask : f1->ip_flow.dmask;
8802 f1->hdr.argus_dsrvl8.qual |= ArgusMergeAddress(&f1->ip_flow.ip_dst, &f2->ip_flow.ip_dst, ARGUS_TYPE_IPV4, ARGUS_DST, &masklen);
8803 f1->ip_flow.dmask = masklen;
8804 break;
8805
8806 case ARGUS_TYPE_IPV6:
8807 masklen = (f1->ipv6_flow.smask > f2->ipv6_flow.smask) ? f2->ipv6_flow.smask : f1->ipv6_flow.smask;
8808 f1->hdr.argus_dsrvl8.qual |= ArgusMergeAddress(&f1->ipv6_flow.ip_src[0], &f2->ipv6_flow.ip_src[0], ARGUS_TYPE_IPV6, ARGUS_SRC, &masklen);
8809 f1->ipv6_flow.smask = masklen;
8810
8811 masklen = (f1->ipv6_flow.dmask > f2->ipv6_flow.dmask) ? f2->ipv6_flow.dmask : f1->ipv6_flow.dmask;
8812 f1->hdr.argus_dsrvl8.qual |= ArgusMergeAddress(&f1->ipv6_flow.ip_dst[0], &f2->ipv6_flow.ip_dst[0], ARGUS_TYPE_IPV6, ARGUS_DST, &masklen);
8813 f1->ipv6_flow.dmask = masklen;
8814 break;
8815
8816 case ARGUS_TYPE_RARP:
8817 if (bcmp(&f1->rarp_flow.shaddr, &f2->rarp_flow.shaddr, 6))
8818 bzero(&f1->rarp_flow.shaddr, 6);
8819 if (bcmp(&f1->rarp_flow.dhaddr, &f2->rarp_flow.dhaddr, 6))
8820 bzero(&f1->rarp_flow.dhaddr, 6);
8821 break;
8822 case ARGUS_TYPE_ARP:
8823 f1->hdr.argus_dsrvl8.qual |= ArgusMergeAddress(&f1->arp_flow.arp_spa, &f2->arp_flow.arp_spa, ARGUS_TYPE_ARP, ARGUS_SRC, &masklen);
8824 f1->hdr.argus_dsrvl8.qual |= ArgusMergeAddress(&f1->arp_flow.arp_tpa, &f2->arp_flow.arp_tpa, ARGUS_TYPE_ARP, ARGUS_DST, &masklen);
8825 break;
8826 }
8827 }
8828 break;
8829 }
8830
8831 case ARGUS_FLOW_CLASSIC5TUPLE: {
8832 switch (f1->hdr.argus_dsrvl8.qual & 0x1F) {
8833 case ARGUS_TYPE_IPV4:
8834 if ((f1->hdr.argus_dsrvl8.qual & 0x1F) == (f2->hdr.argus_dsrvl8.qual & 0x1F)) {
8835 ArgusMergeAddress(&f1->ip_flow.ip_src, &f2->ip_flow.ip_src, ARGUS_TYPE_IPV4, ARGUS_SRC, &masklen);
8836 ArgusMergeAddress(&f1->ip_flow.ip_dst, &f2->ip_flow.ip_dst, ARGUS_TYPE_IPV4, ARGUS_DST, &masklen);
8837 if (f1->ip_flow.ip_p != f2->ip_flow.ip_p)
8838 f1->ip_flow.ip_p = 0;
8839 if (f1->ip_flow.sport != f2->ip_flow.sport)
8840 f1->ip_flow.sport = 0;
8841 if (f1->ip_flow.dport != f2->ip_flow.dport)
8842 f1->ip_flow.dport = 0;
8843
8844 } else {
8845 f1->ip_flow.ip_src = 0;
8846 f1->ip_flow.ip_dst = 0;
8847
8848 switch (f2->hdr.argus_dsrvl8.qual & 0x1F) {
8849 case ARGUS_TYPE_IPV6:
8850 if (f1->ip_flow.ip_p != f2->ipv6_flow.ip_p)
8851 f1->ip_flow.ip_p = 0;
8852 if (f1->ip_flow.sport != f2->ipv6_flow.sport)
8853 f1->ip_flow.sport = 0;
8854 if (f1->ip_flow.dport != f2->ipv6_flow.dport)
8855 f1->ip_flow.dport = 0;
8856 break;
8857
8858 default:
8859 f1->ip_flow.ip_p = 0;
8860 f1->ip_flow.sport = 0;
8861 f1->ip_flow.dport = 0;
8862 break;
8863 }
8864 }
8865 break;
8866
8867 case ARGUS_TYPE_IPV6:
8868 if ((f1->hdr.argus_dsrvl8.qual & 0x1F) == (f2->hdr.argus_dsrvl8.qual & 0x1F)) {
8869 f1->hdr.argus_dsrvl8.qual |= ArgusMergeAddress(&f1->ipv6_flow.ip_src[0],
8870 &f2->ipv6_flow.ip_src[0], ARGUS_TYPE_IPV6, ARGUS_SRC, &masklen);
8871 f1->hdr.argus_dsrvl8.qual |= ArgusMergeAddress(&f1->ipv6_flow.ip_dst[0],
8872 &f2->ipv6_flow.ip_dst[0], ARGUS_TYPE_IPV6, ARGUS_DST, &masklen);
8873
8874 if (f1->ipv6_flow.ip_p != f2->ipv6_flow.ip_p) f1->ipv6_flow.ip_p = 0;
8875 if (f1->ipv6_flow.sport != f2->ipv6_flow.sport) f1->ipv6_flow.sport = 0;
8876 if (f1->ipv6_flow.dport != f2->ipv6_flow.dport) f1->ipv6_flow.dport = 0;
8877
8878 } else {
8879 bzero ((char *)&f1->ipv6_flow.ip_src[0], sizeof(f1->ipv6_flow.ip_src));
8880 bzero ((char *)&f1->ipv6_flow.ip_dst[0], sizeof(f1->ipv6_flow.ip_dst));
8881 if (f1->ipv6_flow.ip_p != f2->ip_flow.ip_p) f1->ipv6_flow.ip_p = 0;
8882 if (f1->ipv6_flow.sport != f2->ip_flow.sport) f1->ipv6_flow.sport = 0;
8883 if (f1->ipv6_flow.dport != f2->ip_flow.dport) f1->ipv6_flow.dport = 0;
8884 }
8885 break;
8886
8887 case ARGUS_TYPE_RARP:
8888 if (bcmp(&f1->rarp_flow.shaddr, &f2->rarp_flow.shaddr, 6))
8889 bzero(&f1->rarp_flow.shaddr, 6);
8890 if (bcmp(&f1->rarp_flow.dhaddr, &f2->rarp_flow.dhaddr, 6))
8891 bzero(&f1->rarp_flow.dhaddr, 6);
8892 case ARGUS_TYPE_ARP:
8893 f1->hdr.argus_dsrvl8.qual |= ArgusMergeAddress(&f1->arp_flow.arp_spa, &f2->arp_flow.arp_spa, ARGUS_TYPE_ARP, ARGUS_SRC, &masklen);
8894 f1->hdr.argus_dsrvl8.qual |= ArgusMergeAddress(&f1->arp_flow.arp_tpa, &f2->arp_flow.arp_tpa, ARGUS_TYPE_ARP, ARGUS_DST, &masklen);
8895 break;
8896 }
8897 break;
8898 }
8899
8900 case ARGUS_FLOW_ARP: {
8901 break;
8902 }
8903 }
8904 }
8905 }
8906 }
8907 break;
8908
8909 // Intersecting Transport objects involves simply checking that the source
8910 // id and seqnum are the same, and if not, removing the fields until
8911 // we're actually removing the struct.
8912
8913 // struct ArgusTransportStruct {
8914 // struct ArgusDSRHeader hdr;
8915 // struct ArgusAddrStruct srcid;
8916 // unsigned int seqnum;
8917 // };
8918
8919 case ARGUS_TRANSPORT_INDEX: {
8920 struct ArgusTransportStruct *t1 = (struct ArgusTransportStruct *) ns1->dsrs[ARGUS_TRANSPORT_INDEX];
8921 struct ArgusTransportStruct *t2 = (struct ArgusTransportStruct *) ns2->dsrs[ARGUS_TRANSPORT_INDEX];
8922
8923 if ((t1 && t2) && (t1->hdr.argus_dsrvl8.qual == t2->hdr.argus_dsrvl8.qual)) {
8924 if (t1->hdr.argus_dsrvl8.qual == t2->hdr.argus_dsrvl8.qual) {
8925 if ((t1->hdr.subtype & ARGUS_SRCID) && (t2->hdr.subtype & ARGUS_SRCID)) {
8926 switch (t1->hdr.argus_dsrvl8.qual) {
8927 case ARGUS_TYPE_INT:
8928 case ARGUS_TYPE_IPV4:
8929 if (t1->srcid.a_un.ipv4 != t2->srcid.a_un.ipv4) {
8930 ns1->dsrs[ARGUS_TRANSPORT_INDEX] = NULL;
8931 ns1->dsrindex &= ~(0x1 << ARGUS_TRANSPORT_INDEX);
8932 }
8933 break;
8934
8935 case ARGUS_TYPE_IPV6:
8936 case ARGUS_TYPE_ETHER:
8937 case ARGUS_TYPE_STRING:
8938 break;
8939 }
8940 }
8941
8942 } else {
8943 ns1->dsrs[ARGUS_TRANSPORT_INDEX] = NULL;
8944 ns1->dsrindex &= ~(0x1 << ARGUS_TRANSPORT_INDEX);
8945 }
8946 }
8947
8948 break;
8949 }
8950
8951 // Intersecting Time objects may result in a change in the storage
8952 // type of the time structure, from an ABSOLUTE_TIMESTAMP
8953 // to an ABSOLUTE_RANGE, to hold the new ending time.
8954
8955 case ARGUS_TIME_INDEX: {
8956 struct ArgusTimeObject *t1 = (struct ArgusTimeObject *) ns1->dsrs[ARGUS_TIME_INDEX];
8957 struct ArgusTimeObject *t2 = (struct ArgusTimeObject *) ns2->dsrs[ARGUS_TIME_INDEX];
8958
8959 if (t1 && t2) {
8960 if ((t1->hdr.argus_dsrvl8.len = 0) || (t1->src.start.tv_sec == 0)) {
8961 bcopy ((char *)t2, (char *)t1, sizeof (*t1));
8962 } else {
8963 if ((t1->src.start.tv_sec > t2->src.start.tv_sec) ||
8964 ((t1->src.start.tv_sec == t2->src.start.tv_sec) &&
8965 (t1->src.start.tv_usec > t2->src.start.tv_usec)))
8966 t1->src.start = t2->src.start;
8967
8968 if ((t1->src.end.tv_sec == 0) || (t1->hdr.subtype == ARGUS_TIME_ABSOLUTE_TIMESTAMP)) {
8969 t1->src.end = t1->src.start;
8970 t1->hdr.subtype = ARGUS_TIME_ABSOLUTE_RANGE;
8971 t1->hdr.argus_dsrvl8.len = 5;
8972 }
8973 if ((t2->src.end.tv_sec == 0) || (t2->hdr.subtype == ARGUS_TIME_ABSOLUTE_TIMESTAMP)) {
8974 t2->src.end = t2->src.start;
8975 t2->hdr.subtype = ARGUS_TIME_ABSOLUTE_RANGE;
8976 t2->hdr.argus_dsrvl8.len = 5;
8977 }
8978 if ((t1->src.end.tv_sec < t2->src.end.tv_sec) ||
8979 ((t1->src.end.tv_sec == t2->src.end.tv_sec) &&
8980 (t1->src.end.tv_usec < t2->src.end.tv_usec)))
8981 t1->src.end = t2->src.end;
8982 }
8983 }
8984 break;
8985 }
8986
8987 // Intersecting metric objects should not result in any type
8988 // of rollover any time soon, as we're working with 64 bit
8989 // ints with the canonical DSR. We should test for rollover
8990 // but lets do that later - cb
8991
8992 case ARGUS_METRIC_INDEX: {
8993 struct ArgusMetricStruct *m1 = (struct ArgusMetricStruct *) ns1->dsrs[ARGUS_METRIC_INDEX];
8994 struct ArgusMetricStruct *m2 = (struct ArgusMetricStruct *) ns2->dsrs[ARGUS_METRIC_INDEX];
8995
8996 if (m1 && m2) {
8997 if (m1->hdr.type == 0) {
8998 bcopy ((char *) m2, (char *) m1, sizeof (*m1));
8999 break;
9000 }
9001
9002 m1->src.pkts -= m2->src.pkts;
9003 m1->src.bytes -= m2->src.bytes;
9004 m1->src.appbytes -= m2->src.appbytes;
9005 m1->dst.pkts -= m2->dst.pkts;
9006 m1->dst.bytes -= m2->dst.bytes;
9007 m1->dst.appbytes -= m2->dst.appbytes;
9008 }
9009 break;
9010 }
9011
9012
9013 // Intersecting packet size object choses the smaller of the
9014 // two values for psizemax and psizemin. opposite of merge - cb
9015
9016 case ARGUS_PSIZE_INDEX: {
9017 struct ArgusPacketSizeStruct *p1 = (struct ArgusPacketSizeStruct *) ns1->dsrs[ARGUS_PSIZE_INDEX];
9018 struct ArgusPacketSizeStruct *p2 = (struct ArgusPacketSizeStruct *) ns2->dsrs[ARGUS_PSIZE_INDEX];
9019
9020 if (p1 && p2) {
9021 if (p1->src.psizemax > p2->src.psizemax)
9022 p1->src.psizemax = p2->src.psizemax;
9023
9024 if (p1->src.psizemin < p2->src.psizemin)
9025 p1->src.psizemin = p2->src.psizemin;
9026 }
9027 break;
9028 }
9029
9030 // Intersecting the aggregation object results in ns1 having
9031 // a valid aggregation object, but without the updates
9032 // from this merger. So, if ns1 and ns2 have valid
9033 // agr's, then just update ns1 fields. If ns2 has an
9034 // agr, but ns1 does not, then move ns2's agr to ns1.
9035 // Do this by updating the canonical agr struct and
9036 // then putting the pointer into the dsrs[].
9037
9038 // if neither, then add one to ns1 with a count of 1.
9039
9040 case ARGUS_AGR_INDEX: {
9041 struct ArgusAgrStruct *a1 = (struct ArgusAgrStruct *) ns1->dsrs[ARGUS_AGR_INDEX];
9042 struct ArgusAgrStruct *a2 = (struct ArgusAgrStruct *) ns2->dsrs[ARGUS_AGR_INDEX];
9043
9044 if (a1 && a2) {
9045 a1->count += a2->count;
9046 } else {
9047 if (!(a1 || a2)) {
9048 if ((a1 = ArgusCalloc(1, sizeof(*a1))) == NULL)
9049 ArgusLog (LOG_ERR, "ArgusMergeRecords: ArgusCalloc error %s", strerror(errno));
9050
9051 a1->hdr.type = ARGUS_AGR_DSR;
9052 a1->hdr.subtype = 0x01;
9053 a1->hdr.argus_dsrvl8.qual = 0x01;
9054 a1->hdr.argus_dsrvl8.len = (sizeof(*agr) + 3)/4;
9055 a1->count = 1;
9056 ns1->dsrs[ARGUS_AGR_INDEX] = (struct ArgusDSRHeader *) a1;
9057 } else
9058 if (a2) {
9059 if ((a1 = ArgusCalloc(1, sizeof(*a1))) == NULL)
9060 ArgusLog (LOG_ERR, "ArgusMergeRecords: ArgusCalloc error %s", strerror(errno));
9061
9062 bcopy((char *)a2, (char *)a1, sizeof(*a1));
9063 a1->count++;
9064 }
9065 }
9066 break;
9067 }
9068
9069 case ARGUS_JITTER_INDEX: {
9070 struct ArgusJitterStruct *j1 = (struct ArgusJitterStruct *) ns1->dsrs[ARGUS_JITTER_INDEX];
9071 struct ArgusJitterStruct *j2 = (struct ArgusJitterStruct *) ns2->dsrs[ARGUS_JITTER_INDEX];
9072
9073 if (j1 && j2) {
9074 if (j2->src.act.n > 0) {
9075 unsigned int n, stdev = 0;
9076 double meanval, sumsqrd = 0.0;
9077
9078 n = (j1->src.act.n + j2->src.act.n);
9079 meanval = (((double)j1->src.act.meanval * (double)j1->src.act.n) +
9080 ((double)j2->src.act.meanval * (double)j2->src.act.n)) / n;
9081
9082 if (j1->src.act.n) {
9083 double sum = (double)j1->src.act.meanval * (double)j1->src.act.n;
9084 sumsqrd += (j1->src.act.n * ((double)j1->src.act.stdev * (double)j1->src.act.stdev)) +
9085 (sum * sum)/j1->src.act.n;
9086 }
9087
9088 if (j2->src.act.n) {
9089 double sum = (double)j2->src.act.meanval * (double)j2->src.act.n;
9090 sumsqrd += (j2->src.act.n * ((double)j2->src.act.stdev * (double)j2->src.act.stdev)) +
9091 (sum * sum)/j2->src.act.n;
9092 }
9093 stdev = (int) sqrt (fabs((sumsqrd/n) - ((double)meanval * (double)meanval)));
9094
9095 j1->src.act.n = n;
9096 j1->src.act.meanval = (unsigned int) meanval;
9097 j1->src.act.stdev = stdev;
9098 if (j1->src.act.minval > j2->src.act.minval)
9099 j1->src.act.minval = j2->src.act.minval;
9100 if (j1->src.act.maxval < j2->src.act.maxval)
9101 j1->src.act.maxval = j2->src.act.maxval;
9102 }
9103
9104 if (j2->src.idle.n > 0) {
9105 unsigned int n, stdev = 0;
9106 double meanval, sumsqrd = 0.0;
9107
9108 n = (j1->src.idle.n + j2->src.idle.n);
9109 meanval = (((double) j1->src.idle.meanval * (double) j1->src.idle.n) +
9110 ((double) j2->src.idle.meanval * (double) j2->src.idle.n)) / n;
9111
9112 if (j1->src.idle.n) {
9113 double sum = (double) j1->src.idle.meanval * (double) j1->src.idle.n;
9114 sumsqrd += (j1->src.idle.n * ((double)j1->src.idle.stdev * (double)j1->src.idle.stdev)) +
9115 ((double)sum *(double)sum)/j1->src.idle.n;
9116 }
9117
9118 if (j2->src.idle.n) {
9119 double sum = (double) j2->src.idle.meanval * (double) j2->src.idle.n;
9120 sumsqrd += (j2->src.idle.n * ((double)j2->src.idle.stdev * (double)j2->src.idle.stdev)) +
9121 ((double)sum *(double)sum)/j2->src.idle.n;
9122 }
9123 stdev = (int) sqrt (fabs((sumsqrd/n) - ((double)meanval * (double)meanval)));
9124
9125 j1->src.idle.n = n;
9126 j1->src.idle.meanval = (unsigned int) meanval;
9127 j1->src.idle.stdev = stdev;
9128 if (j1->src.idle.minval > j2->src.idle.minval)
9129 j1->src.idle.minval = j2->src.idle.minval;
9130 if (j1->src.idle.maxval < j2->src.idle.maxval)
9131 j1->src.idle.maxval = j2->src.idle.maxval;
9132 }
9133
9134 if (j2->dst.act.n > 0) {
9135 unsigned int n, stdev = 0;
9136 double meanval, sumsqrd = 0.0;
9137
9138 n = (j1->dst.act.n + j2->dst.act.n);
9139 meanval = (((double) j1->dst.act.meanval * (double) j1->dst.act.n) +
9140 ((double) j2->dst.act.meanval * (double) j2->dst.act.n)) / n;
9141
9142 if (j1->dst.act.n) {
9143 double sum = j1->dst.act.meanval * j1->dst.act.n;
9144 sumsqrd += (j1->dst.act.n * ((double)j1->dst.act.stdev * (double)j1->dst.act.stdev)) +
9145 (sum * sum)/j1->dst.act.n;
9146 }
9147
9148 if (j2->dst.act.n) {
9149 double sum = (double) j2->dst.act.meanval * (double) j2->dst.act.n;
9150 sumsqrd += (j2->dst.act.n * ((double)j2->dst.act.stdev * (double)j2->dst.act.stdev)) +
9151 ((double)sum *(double)sum)/j2->dst.act.n;
9152 }
9153 stdev = (int) sqrt (fabs((sumsqrd/n) - ((double)meanval * (double)meanval)));
9154
9155 j1->dst.act.n = n;
9156 j1->dst.act.meanval = (unsigned int) meanval;
9157 j1->dst.act.stdev = stdev;
9158 if (j1->dst.act.minval > j2->dst.act.minval)
9159 j1->dst.act.minval = j2->dst.act.minval;
9160 if (j1->dst.act.maxval < j2->dst.act.maxval)
9161 j1->dst.act.maxval = j2->dst.act.maxval;
9162 }
9163
9164 if (j2->dst.idle.n > 0) {
9165 unsigned int n, stdev = 0;
9166 double meanval, sumsqrd = 0.0;
9167
9168 n = (j1->dst.idle.n + j2->dst.idle.n);
9169 meanval = (((double) j1->dst.idle.meanval * (double) j1->dst.idle.n) +
9170 ((double) j2->dst.idle.meanval * (double) j2->dst.idle.n)) / n;
9171
9172 if (j1->dst.idle.n) {
9173 int sum = (double) j1->dst.idle.meanval * (double) j1->dst.idle.n;
9174 sumsqrd += (j1->dst.idle.n * ((double)j1->dst.idle.stdev * (double)j1->dst.idle.stdev)) +
9175 ((double)sum *(double)sum)/j1->dst.idle.n;
9176 }
9177
9178 if (j2->dst.idle.n) {
9179 double sum = (double) j2->dst.idle.meanval * (double) j2->dst.idle.n;
9180 sumsqrd += (j2->dst.idle.n * ((double)j2->dst.idle.stdev * (double)j2->dst.idle.stdev)) +
9181 ((double)sum *(double)sum)/j2->dst.idle.n;
9182 }
9183 stdev = (int) sqrt (fabs((sumsqrd/n) - ((double)meanval * (double)meanval)));
9184
9185 j1->dst.idle.n = n;
9186 j1->dst.idle.meanval = (unsigned int) meanval;
9187 j1->dst.idle.stdev = stdev;
9188 if (j1->dst.idle.minval > j2->dst.idle.minval)
9189 j1->dst.idle.minval = j2->dst.idle.minval;
9190 if (j1->dst.idle.maxval < j2->dst.idle.maxval)
9191 j1->dst.idle.maxval = j2->dst.idle.maxval;
9192 }
9193
9194 } else
9195 ns1->dsrs[ARGUS_JITTER_INDEX] = NULL;
9196
9197 break;
9198 }
9199
9200 case ARGUS_MAC_INDEX: {
9201 struct ArgusMacStruct *m1 = (struct ArgusMacStruct *) ns1->dsrs[ARGUS_MAC_INDEX];
9202 struct ArgusMacStruct *m2 = (struct ArgusMacStruct *) ns2->dsrs[ARGUS_MAC_INDEX];
9203
9204 if (m1 && m2) {
9205 struct ether_header *e1 = &m1->mac.mac_union.ether.ehdr;
9206 struct ether_header *e2 = &m2->mac.mac_union.ether.ehdr;
9207
9208 if (bcmp(&e1->ether_shost, &e2->ether_shost, sizeof(e1->ether_shost)))
9209 bzero ((char *)&e1->ether_shost, sizeof(e1->ether_shost));
9210
9211 if (bcmp(&e1->ether_dhost, &e2->ether_dhost, sizeof(e1->ether_dhost)))
9212 bzero ((char *)&e1->ether_dhost, sizeof(e1->ether_dhost));
9213
9214 } else {
9215 ns1->dsrs[ARGUS_MAC_INDEX] = NULL;
9216 }
9217 break;
9218 }
9219 }
9220 }
9221 }
9222
9223 return;
9224 }
9225
9226 struct ArgusRecordStruct *ArgusSubtractRecord (struct ArgusRecordStruct *, struct ArgusRecordStruct *);
9227
9228 struct ArgusRecordStruct *
ArgusSubtractRecord(struct ArgusRecordStruct * ns1,struct ArgusRecordStruct * ns2)9229 ArgusSubtractRecord (struct ArgusRecordStruct *ns1, struct ArgusRecordStruct *ns2)
9230 {
9231 struct ArgusRecordStruct *retn = ns1;
9232
9233 if ((ns1 && ns2) && ((ns1->hdr.type & ARGUS_FAR) && (ns2->hdr.type & ARGUS_FAR))) {
9234 int i;
9235 for (i = 0; i < ARGUSMAXDSRTYPE; i++) {
9236 switch (i) {
9237
9238 // Subtracting Flow records is a matter of testing each field and
9239 // providing delta values where appropriate. These apply to time,
9240 // attributes, and metrics. but not things like flows.
9241 //
9242 // Subtracting Transport objects is tricky, since we normally subtract
9243 // records from different probes. So just leave this alone.
9244
9245 case ARGUS_FLOW_INDEX:
9246 case ARGUS_TRANSPORT_INDEX:
9247 break;
9248
9249 // Subtracing time objects may result in a change in the storage
9250 // type of the time structure, from an ABSOLUTE_TIMESTAMP
9251 // to an ABSOLUTE_RANGE, to hold the new ending time.
9252
9253 case ARGUS_TIME_INDEX: {
9254 struct ArgusTimeObject *t1 = (struct ArgusTimeObject *) ns1->dsrs[ARGUS_TIME_INDEX];
9255 struct ArgusTimeObject *t2 = (struct ArgusTimeObject *) ns2->dsrs[ARGUS_TIME_INDEX];
9256
9257 if (t1 && t2) {
9258 t1->src.start.tv_sec -= t2->src.start.tv_sec;
9259 t1->src.start.tv_usec -= t2->src.start.tv_usec;
9260 t1->src.end.tv_sec -= t2->src.end.tv_sec;
9261 t1->src.end.tv_usec -= t2->src.end.tv_usec;
9262 t1->dst.start.tv_sec -= t2->dst.start.tv_sec;
9263 t1->dst.start.tv_usec -= t2->dst.start.tv_usec;
9264 t1->dst.end.tv_sec -= t2->dst.end.tv_sec;
9265 t1->dst.end.tv_usec -= t2->dst.end.tv_usec;
9266 }
9267 break;
9268 }
9269
9270 // Subtracting metric objects is straight forward for all values.
9271
9272 case ARGUS_METRIC_INDEX: {
9273 struct ArgusMetricStruct *m1 = (struct ArgusMetricStruct *) ns1->dsrs[ARGUS_METRIC_INDEX];
9274 struct ArgusMetricStruct *m2 = (struct ArgusMetricStruct *) ns2->dsrs[ARGUS_METRIC_INDEX];
9275
9276 if (m1 && m2) {
9277 m1->src.pkts -= m2->src.pkts;
9278 m1->src.bytes -= m2->src.bytes;
9279 m1->src.appbytes -= m2->src.appbytes;
9280 m1->dst.pkts -= m2->dst.pkts;
9281 m1->dst.bytes -= m2->dst.bytes;
9282 m1->dst.appbytes -= m2->dst.appbytes;
9283 }
9284 break;
9285 }
9286
9287
9288 // Subtracting networks objects involve subtracting the metrics
9289 // that are embedded in the network dsrs.
9290
9291
9292 case ARGUS_NETWORK_INDEX: {
9293 struct ArgusNetworkStruct *n1 = (void *)ns1->dsrs[ARGUS_NETWORK_INDEX];
9294 struct ArgusNetworkStruct *n2 = (void *)ns2->dsrs[ARGUS_NETWORK_INDEX];
9295
9296 if ((n1 != NULL) && (n2 != NULL)) {
9297 if (n1->hdr.subtype == n2->hdr.subtype)
9298 switch (n1->hdr.subtype) {
9299 case ARGUS_TCP_INIT:
9300 case ARGUS_TCP_STATUS:
9301 case ARGUS_TCP_PERF: {
9302 struct ArgusTCPObject *t1 = (struct ArgusTCPObject *)&n1->net_union.tcp;
9303 struct ArgusTCPObject *t2 = (struct ArgusTCPObject *)&n2->net_union.tcp;
9304
9305 if (n1->hdr.argus_dsrvl8.len == 0) {
9306 bcopy ((char *) n2, (char *) n1, sizeof (*n1));
9307 break;
9308 }
9309
9310 t1->src.ack -= t2->src.ack;
9311 t1->src.seq -= t2->src.seq;
9312
9313 t1->src.winnum -= t2->src.winnum;
9314 t1->src.bytes -= t2->src.bytes;
9315 t1->src.retrans -= t2->src.retrans;
9316
9317 t1->src.ackbytes -= t2->src.ackbytes;
9318 t1->src.win -= t2->src.win;
9319 t1->src.winbytes -= t2->src.winbytes;
9320
9321 t1->dst.winnum -= t2->dst.winnum;
9322 t1->dst.bytes -= t2->dst.bytes;
9323 t1->dst.retrans -= t2->dst.retrans;
9324 t1->dst.ackbytes -= t2->dst.ackbytes;
9325 t1->dst.win -= t2->dst.win;
9326 t1->dst.winbytes -= t2->dst.winbytes;
9327
9328 if (n1->hdr.subtype != n2->hdr.subtype) {
9329 n1->hdr.subtype = ARGUS_TCP_PERF;
9330 n1->hdr.argus_dsrvl8.len = (sizeof(*t1) + 3) / 4;
9331 }
9332 break;
9333 }
9334
9335 case ARGUS_RTP_FLOW: {
9336 struct ArgusRTPObject *r1 = &n1->net_union.rtp;
9337 struct ArgusRTPObject *r2 = &n2->net_union.rtp;
9338 r1->sdrop -= r2->sdrop;
9339 r1->ddrop -= r2->ddrop;
9340 break;
9341 }
9342
9343 case ARGUS_ESP_DSR: {
9344 struct ArgusESPObject *e1 = &n1->net_union.esp;
9345 struct ArgusESPObject *e2 = &n2->net_union.esp;
9346
9347 e1->lastseq -= e2->lastseq;
9348 e1->lostseq -= e2->lostseq;
9349 if (e1->spi != e2->spi) {
9350 e1->spi = 0;
9351 }
9352 }
9353 }
9354 }
9355 break;
9356 }
9357
9358 // Subtracting packet size object is straightforward for each value.
9359
9360 case ARGUS_PSIZE_INDEX: {
9361 struct ArgusPacketSizeStruct *p1 = (struct ArgusPacketSizeStruct *) ns1->dsrs[ARGUS_PSIZE_INDEX];
9362 struct ArgusPacketSizeStruct *p2 = (struct ArgusPacketSizeStruct *) ns2->dsrs[ARGUS_PSIZE_INDEX];
9363
9364 if (p1 && p2) {
9365 p1->src.psizemax -= p2->src.psizemax;
9366 p1->src.psizemin -= p2->src.psizemin;
9367 }
9368 break;
9369 }
9370
9371 case ARGUS_IPATTR_INDEX: {
9372 struct ArgusIPAttrStruct *attr1 = (struct ArgusIPAttrStruct *)ns1->dsrs[ARGUS_IPATTR_INDEX];
9373 struct ArgusIPAttrStruct *attr2 = (struct ArgusIPAttrStruct *)ns2->dsrs[ARGUS_IPATTR_INDEX];
9374
9375 if (attr1 && attr2) {
9376 attr1->src.tos -= attr2->src.tos;
9377 attr1->src.ttl -= attr2->src.ttl;
9378 attr1->dst.tos -= attr2->dst.tos;
9379 attr1->dst.ttl -= attr2->dst.ttl;
9380 }
9381 break;
9382 }
9383
9384 // Subtracting the aggregation object seems interesting,
9385 // but don't know what this means yet.
9386
9387 case ARGUS_AGR_INDEX: {
9388 struct ArgusAgrStruct *a1 = (struct ArgusAgrStruct *) ns1->dsrs[ARGUS_AGR_INDEX];
9389 struct ArgusAgrStruct *a2 = (struct ArgusAgrStruct *) ns2->dsrs[ARGUS_AGR_INDEX];
9390
9391 if (a1 && a2) {
9392 }
9393 ns1->dsrs[ARGUS_AGR_INDEX] = NULL;
9394 break;
9395 }
9396
9397 case ARGUS_JITTER_INDEX: {
9398 struct ArgusJitterStruct *j1 = (struct ArgusJitterStruct *) ns1->dsrs[ARGUS_JITTER_INDEX];
9399 struct ArgusJitterStruct *j2 = (struct ArgusJitterStruct *) ns2->dsrs[ARGUS_JITTER_INDEX];
9400
9401 if (j1 && j2) {
9402 }
9403 ns1->dsrs[ARGUS_JITTER_INDEX] = NULL;
9404 break;
9405 }
9406
9407 case ARGUS_MAC_INDEX:
9408 break;
9409 }
9410 }
9411 }
9412
9413 #ifdef ARGUSDEBUG
9414 ArgusDebug (10, "ArgusSubtractRecord (%p, %p) returning %p", ns1, ns2, retn);
9415 #endif
9416
9417 return (retn);
9418 }
9419
9420 #define RATOPSTARTINGINDEX 0
9421
9422 void
ArgusCalculatePeriod(struct ArgusRecordStruct * ns,struct ArgusAdjustStruct * nadp)9423 ArgusCalculatePeriod (struct ArgusRecordStruct *ns, struct ArgusAdjustStruct *nadp)
9424 {
9425 struct ArgusMetricStruct *metric = (void *)ns->dsrs[ARGUS_METRIC_INDEX];
9426 struct ArgusTimeObject *time = (void *)ns->dsrs[ARGUS_TIME_INDEX];
9427
9428 if ((nadp->stperiod == 0.0) && (nadp->dtperiod == 0.0)) {
9429 if ((metric != NULL) && (time != NULL)) {
9430 long long sstime = (time->src.start.tv_sec * 1000000LL) + time->src.start.tv_usec;
9431 long long dstime = (time->dst.start.tv_sec * 1000000LL) + time->dst.start.tv_usec;
9432 long long setime = (time->src.end.tv_sec * 1000000LL) + time->src.end.tv_usec;
9433 long long detime = (time->dst.end.tv_sec * 1000000LL) + time->dst.end.tv_usec;
9434
9435 nadp->stperiod = ((setime - sstime) * 1.0) / (nadp->size * 1.0);
9436 nadp->dtperiod = ((detime - dstime) * 1.0) / (nadp->size * 1.0);
9437
9438 // linear model
9439 if (nadp->stperiod < 1.0) nadp->stperiod = 1.0;
9440 if (nadp->dtperiod < 1.0) nadp->dtperiod = 1.0;
9441
9442 nadp->spkts = (metric->src.pkts / nadp->stperiod);
9443 nadp->sbytes = (metric->src.bytes / nadp->stperiod);
9444 nadp->sappbytes = (metric->src.appbytes / nadp->stperiod);
9445
9446 nadp->dpkts = (metric->dst.pkts / nadp->dtperiod);
9447 nadp->dbytes = (metric->dst.bytes / nadp->dtperiod);
9448 nadp->dappbytes = (metric->dst.appbytes / nadp->dtperiod);
9449 }
9450 }
9451 }
9452
9453
9454 // ArgusAlignRecord is designed to snip records on hard time boundaries.
9455 // What those time boundary's are, are specified in the ArgusAdjustStruct.
9456 // The idea is that one specifies a time interval, and we try to find
9457 // a time boundary to snip the records to. If the bin size is 60s, we
9458 // will clip on 1 minute boundaries.
9459 //
9460 // A problem arises, when the boundary does not coincide with minute boundaries,
9461 // as we have to decide where the starting boundary is, and then clip accordingly.
9462 // So, as an example, if we are aligning on 90s boundaries (1.5m). What is
9463 // the correct starting point for the clipping? Can't be on the hour, as 90s
9464 // boundaries don't conincide with hourly boundaries.
9465 //
9466 // As a convention, if the boundary does not align well on minutes, we shall
9467 // start on the yearly boundary, and adjust accordingly, so we find our
9468 // current time, and adjust it so that the alignment bin is aligned with the
9469 // beginning of the year.
9470 //
9471 // For intervals that are a fraction of a second, if the fraction is not
9472 // an integral fraction, we need to do the same thing.
9473
9474
9475 struct ArgusRecordStruct *ArgusAlignRecord(struct ArgusParserStruct *parser, struct ArgusRecordStruct *, struct ArgusAdjustStruct *);
9476
9477 void
ArgusAlignConfig(struct ArgusParserStruct * parser,struct ArgusAdjustStruct * nadp)9478 ArgusAlignConfig(struct ArgusParserStruct *parser, struct ArgusAdjustStruct *nadp)
9479 {
9480
9481 }
9482
9483
9484
9485 // Load up the ArgusAdjustStruct to deal with this specific record.
9486
9487
9488 void
ArgusAlignInit(struct ArgusParserStruct * parser,struct ArgusRecordStruct * ns,struct ArgusAdjustStruct * nadp)9489 ArgusAlignInit(struct ArgusParserStruct *parser, struct ArgusRecordStruct *ns, struct ArgusAdjustStruct *nadp)
9490 {
9491 struct timeval *start = &nadp->start;
9492 struct timeval *end = &nadp->end;
9493 long long startusec = 0;
9494 time_t tsec = 0;
9495
9496 nadp->stperiod = 0.0;
9497 nadp->dtperiod = 0.0;
9498 nadp->trperiod = 0.0;
9499
9500 nadp->startuSecs = ArgusFetchStartuSecTime(ns);
9501 nadp->enduSecs = ArgusFetchLastuSecTime(ns);
9502
9503 nadp->sploss = ArgusFetchPercentSrcLoss(ns);
9504 nadp->dploss = ArgusFetchPercentDstLoss(ns);
9505
9506 if (start->tv_sec == 0) {
9507 if (parser->tflag) {
9508 start->tv_sec = parser->startime_t.tv_sec;
9509 start->tv_usec = parser->startime_t.tv_usec;
9510
9511 end->tv_sec = parser->lasttime_t.tv_sec;
9512 end->tv_usec = parser->lasttime_t.tv_usec;
9513
9514 startusec = (start->tv_sec * 1000000LL) + start->tv_usec;
9515
9516 } else {
9517 start->tv_sec = nadp->startuSecs / 1000000;
9518 start->tv_usec = nadp->startuSecs % 1000000;
9519
9520 end->tv_sec = nadp->enduSecs / 1000000;
9521 end->tv_usec = nadp->enduSecs % 1000000;
9522
9523 startusec = nadp->startuSecs;
9524 }
9525 }
9526
9527 tsec = start->tv_sec;
9528
9529 if (nadp->value != 0) {
9530 switch (nadp->qual) {
9531 case ARGUSSPLITSECOND: {
9532 localtime_r(&tsec, &nadp->RaStartTmStruct);
9533 nadp->start.tv_sec = mktime(&nadp->RaStartTmStruct);
9534 nadp->size = nadp->value * 1000000LL;
9535 break;
9536 }
9537 case ARGUSSPLITMINUTE: {
9538 long long val = tsec / (nadp->value * 60);
9539 tsec = val * (nadp->value * 60.0);
9540 localtime_r(&tsec, &nadp->RaStartTmStruct);
9541 nadp->start.tv_sec = mktime(&nadp->RaStartTmStruct);
9542
9543 nadp->size = nadp->value*60.0*1000000;
9544 break;
9545 }
9546 case ARGUSSPLITHOUR: {
9547 localtime_r(&tsec, &nadp->RaStartTmStruct);
9548 nadp->RaStartTmStruct.tm_sec = 0;
9549 nadp->RaStartTmStruct.tm_min = 0;
9550 nadp->start.tv_sec = mktime(&nadp->RaStartTmStruct);
9551
9552 nadp->size = nadp->value*3600.0*1000000LL;
9553 break;
9554 }
9555 case ARGUSSPLITDAY: {
9556 localtime_r(&tsec, &nadp->RaStartTmStruct);
9557 nadp->RaStartTmStruct.tm_sec = 0;
9558 nadp->RaStartTmStruct.tm_min = 0;
9559 nadp->RaStartTmStruct.tm_hour = 0;
9560 nadp->start.tv_sec = mktime(&nadp->RaStartTmStruct);
9561
9562 nadp->size = nadp->value*3600.0*24.0*1000000LL;
9563 break;
9564 }
9565
9566 case ARGUSSPLITWEEK: {
9567 localtime_r(&tsec, &nadp->RaStartTmStruct);
9568 nadp->RaStartTmStruct.tm_sec = 0;
9569 nadp->RaStartTmStruct.tm_min = 0;
9570 nadp->RaStartTmStruct.tm_hour = 0;
9571 nadp->RaStartTmStruct.tm_mday = 1;
9572 nadp->RaStartTmStruct.tm_mon = 0;
9573 nadp->start.tv_sec = mktime(&nadp->RaStartTmStruct);
9574
9575 nadp->size = nadp->value*3600.0*24.0*7.0*1000000LL;
9576 break;
9577 }
9578
9579 case ARGUSSPLITMONTH: {
9580 localtime_r(&tsec, &nadp->RaStartTmStruct);
9581 nadp->RaStartTmStruct.tm_sec = 0;
9582 nadp->RaStartTmStruct.tm_min = 0;
9583 nadp->RaStartTmStruct.tm_hour = 0;
9584 nadp->RaStartTmStruct.tm_mday = 1;
9585 nadp->RaStartTmStruct.tm_mon = 0;
9586 nadp->start.tv_sec = mktime(&nadp->RaStartTmStruct);
9587
9588 nadp->size = nadp->value*3600.0*24.0*7.0*4.0*1000000LL;
9589 break;
9590 }
9591
9592 case ARGUSSPLITYEAR:
9593 localtime_r(&tsec, &nadp->RaStartTmStruct);
9594 nadp->RaStartTmStruct.tm_sec = 0;
9595 nadp->RaStartTmStruct.tm_min = 0;
9596 nadp->RaStartTmStruct.tm_hour = 0;
9597 nadp->RaStartTmStruct.tm_mday = 1;
9598 nadp->RaStartTmStruct.tm_mon = 0;
9599 nadp->start.tv_sec = mktime(&nadp->RaStartTmStruct);
9600
9601 nadp->size = nadp->value*3600.0*24.0*7.0*52.0*1000000LL;
9602 break;
9603 }
9604 }
9605
9606 if (nadp->size > 0) {
9607 switch (nadp->qual) {
9608 case ARGUSSPLITDAY: {
9609 time_t fileSecs = startusec / 1000000;
9610 struct tm tmval;
9611
9612 localtime_r(&fileSecs, &tmval);
9613
9614 #if defined(HAVE_TM_GMTOFF)
9615 fileSecs += tmval.tm_gmtoff;
9616 #endif
9617 fileSecs = fileSecs / (nadp->size / 1000000);
9618 fileSecs = fileSecs * (nadp->size / 1000000);
9619 #if defined(HAVE_TM_GMTOFF)
9620 fileSecs -= tmval.tm_gmtoff;
9621 #endif
9622
9623 nadp->startuSecs = fileSecs * 1000000LL;
9624 nadp->start.tv_sec = fileSecs;
9625 nadp->start.tv_usec = 0;
9626 break;
9627 }
9628
9629 case ARGUSSPLITHOUR:
9630 case ARGUSSPLITMINUTE:
9631 case ARGUSSPLITSECOND: {
9632 nadp->startuSecs = (startusec / nadp->size) * nadp->size;
9633 nadp->start.tv_sec = nadp->startuSecs / 1000000;
9634 nadp->start.tv_usec = nadp->startuSecs % 1000000;
9635 break;
9636 }
9637 }
9638 }
9639 }
9640
9641 struct ArgusRecordStruct *
ArgusAlignRecord(struct ArgusParserStruct * parser,struct ArgusRecordStruct * ns,struct ArgusAdjustStruct * nadp)9642 ArgusAlignRecord(struct ArgusParserStruct *parser, struct ArgusRecordStruct *ns, struct ArgusAdjustStruct *nadp)
9643 {
9644 struct ArgusRecordStruct *retn = NULL;
9645 struct ArgusMetricStruct *metric;
9646 struct ArgusTimeObject *time;
9647 struct ArgusAgrStruct *agr;
9648 long long startusec = 0, endusec = 0;
9649
9650 if ((time = (void *)ns->dsrs[ARGUS_TIME_INDEX]) != NULL) {
9651 startusec = ArgusFetchStartuSecTime(ns);
9652 endusec = ArgusFetchLastuSecTime(ns);
9653
9654 if (nadp->startuSecs == 0) {
9655 if (nadp->size > 0) {
9656 switch (nadp->qual) {
9657 case ARGUSSPLITDAY: {
9658 time_t fileSecs = startusec / 1000000;
9659 struct tm tmval;
9660
9661 localtime_r(&fileSecs, &tmval);
9662
9663 #if defined(HAVE_TM_GMTOFF)
9664 fileSecs += tmval.tm_gmtoff;
9665 #endif
9666 fileSecs = fileSecs / (nadp->size / 1000000);
9667 fileSecs = fileSecs * (nadp->size / 1000000);
9668 #if defined(HAVE_TM_GMTOFF)
9669 fileSecs -= tmval.tm_gmtoff;
9670 #endif
9671
9672 nadp->startuSecs = fileSecs * 1000000LL;
9673 nadp->start.tv_sec = fileSecs;
9674 nadp->start.tv_usec = 0;
9675 break;
9676 }
9677
9678 case ARGUSSPLITHOUR:
9679 case ARGUSSPLITMINUTE:
9680 case ARGUSSPLITSECOND: {
9681 nadp->startuSecs = (startusec / nadp->size) * nadp->size;
9682 nadp->start.tv_sec = nadp->startuSecs / 1000000;
9683 nadp->start.tv_usec = nadp->startuSecs % 1000000;
9684 break;
9685 }
9686 }
9687 }
9688 }
9689
9690 switch (ns->hdr.type & 0xF0) {
9691 case ARGUS_EVENT:
9692 case ARGUS_MAR: {
9693 break;
9694 }
9695
9696 case ARGUS_NETFLOW:
9697 case ARGUS_FAR: {
9698 agr = (void *)ns->dsrs[ARGUS_AGR_INDEX];
9699 if ((metric = (void *)ns->dsrs[ARGUS_METRIC_INDEX]) != NULL) {
9700 if ((metric->src.pkts + metric->dst.pkts) > 0) {
9701 if (!(nadp->modify)) {
9702 retn = ArgusCopyRecordStruct(ns);
9703 metric->src.pkts = 0;
9704 metric->dst.pkts = 0;
9705
9706 } else {
9707 struct ArgusMetricStruct *rmetric = NULL;
9708 struct ArgusTimeObject *rtime = NULL;
9709 struct ArgusAgrStruct *ragr = NULL;
9710 struct timeval sSecs, eSecs;
9711 long long ssecs = 0, esecs = 0;
9712
9713 long long value = (startusec - nadp->startuSecs) / nadp->size;
9714
9715 ssecs = (nadp->startuSecs + (value * nadp->size));
9716 sSecs.tv_sec = ssecs / 1000000;
9717 sSecs.tv_usec = ssecs % 1000000;
9718
9719 esecs = (nadp->startuSecs + ((value + 1) * nadp->size));
9720 eSecs.tv_sec = esecs / 1000000;
9721 eSecs.tv_usec = esecs % 1000000;
9722
9723 if ((metric->src.pkts + metric->dst.pkts) > 1) {
9724 int count = 0, bytes = 0;
9725
9726 nadp->turns++;
9727
9728 if (nadp->size) {
9729 if ((retn = ArgusCopyRecordStruct (ns)) == NULL)
9730 return(retn);
9731
9732 rmetric = (void *)retn->dsrs[ARGUS_METRIC_INDEX];
9733 rtime = (void *)retn->dsrs[ARGUS_TIME_INDEX];
9734 ragr = (void *)retn->dsrs[ARGUS_AGR_INDEX];
9735
9736 // if this record doesn't extend beyound the boundary, then we're done.
9737 if (endusec > esecs) {
9738 if ((rmetric != NULL) && (rtime != NULL)) {
9739
9740 // if pkt count is 2, we split record into 2, with start and end time
9741 // coming from the original packet so rtime get startime, and time
9742 // gets endtime. Need to adjust for whether packets are in the src or dst
9743
9744 if ((count = (metric->src.pkts + metric->dst.pkts)) == 2) {
9745 if (metric->src.pkts == 1) {
9746
9747 // in this record, we will end up with two records, each with one packet each. we don't
9748 // worry which one is first, so just prepare the src flow, and leave the dst flow record for
9749 // the next pass. the rtime->src.start has the correct timestamp. just need to zero out
9750 // the other values. leave the time->dst intact, as that is what is needed for the next record
9751
9752 rtime->hdr.subtype &= ~(ARGUS_TIME_MASK);
9753 rtime->hdr.subtype |= ARGUS_TIME_SRC_START;
9754
9755 rtime->dst.start.tv_sec = 0;
9756 rtime->dst.start.tv_usec = 0;
9757 rtime->dst.end.tv_sec = 0;
9758 rtime->dst.end.tv_usec = 0;
9759
9760 time->hdr.subtype &= ~(ARGUS_TIME_MASK);
9761 time->hdr.subtype |= ARGUS_TIME_DST_START;
9762
9763 time->src.start.tv_sec = 0;
9764 time->src.start.tv_usec = 0;
9765 time->src.end.tv_sec = 0;
9766 time->src.end.tv_usec = 0;
9767
9768 rmetric->dst.pkts = 0;
9769 rmetric->dst.bytes = 0;
9770 rmetric->dst.appbytes = 0;
9771
9772 } else {
9773 // in this record, we have either 2 src pkts or 2 dst pkts.
9774 rtime->hdr.subtype &= ~(ARGUS_TIME_MASK);
9775 time->hdr.subtype &= ~(ARGUS_TIME_MASK);
9776
9777 if (rmetric->src.pkts) {
9778 rtime->hdr.subtype |= ARGUS_TIME_SRC_START;
9779 time->hdr.subtype |= ARGUS_TIME_SRC_START;
9780 rmetric->src.pkts = 1;
9781 bytes = rmetric->src.bytes;
9782 rmetric->src.bytes /= 2;
9783 if (bytes & 0x01)
9784 rmetric->src.bytes += 1;
9785 bytes = rmetric->src.appbytes;
9786 rmetric->src.appbytes /= 2;
9787
9788 if (bytes & 0x01)
9789 rmetric->src.appbytes += 1;
9790 rmetric->dst.pkts = 0;
9791 rmetric->dst.bytes = 0;
9792 rmetric->dst.appbytes = 0;
9793
9794 rtime->src.end = rtime->src.start;
9795 time->src.start = time->src.end;
9796
9797 } else {
9798 rtime->hdr.subtype |= ARGUS_TIME_DST_START;
9799 time->hdr.subtype |= ARGUS_TIME_DST_START;
9800 rmetric->dst.pkts = 1;
9801 bytes = rmetric->dst.bytes;
9802 rmetric->dst.bytes /= 2;
9803 if (bytes & 0x01)
9804 rmetric->dst.bytes += 1;
9805 bytes = rmetric->dst.appbytes;
9806 rmetric->dst.appbytes /= 2;
9807 if (bytes & 0x01)
9808 rmetric->dst.appbytes += 1;
9809
9810 rtime->dst.end = rtime->dst.start;
9811 time->dst.start = time->dst.end;
9812 }
9813 }
9814
9815 metric->src.pkts -= rmetric->src.pkts;
9816 metric->src.bytes -= rmetric->src.bytes;
9817 metric->src.appbytes -= rmetric->src.appbytes;
9818 metric->dst.pkts -= rmetric->dst.pkts;
9819 metric->dst.bytes -= rmetric->dst.bytes;
9820 metric->dst.appbytes -= rmetric->dst.appbytes;
9821
9822 if ((ragr != NULL) && (ragr->count >= 1)) {
9823 ragr->count = 1;
9824 agr->count = 1;
9825 }
9826
9827 } else {
9828
9829 // OK, so this isn't a simple split, so we'll need to distributed stats between
9830 // the two resulting records. Here we need to pay a lot of attention to the timestamps
9831
9832 long long sstime = (rtime->src.start.tv_sec * 1000000LL) + rtime->src.start.tv_usec;
9833 long long dstime = (rtime->dst.start.tv_sec* 1000000LL) + rtime->dst.start.tv_usec;
9834 long long setime = (rtime->src.end.tv_sec* 1000000LL) + rtime->src.end.tv_usec;
9835 long long detime = (rtime->dst.end.tv_sec* 1000000LL) + rtime->dst.end.tv_usec;
9836 double agrRatio;
9837
9838 if ((nadp->stperiod == 0.0) && (nadp->dtperiod == 0.0)) {
9839 ArgusCalculatePeriod (ns, nadp);
9840 if (metric->src.pkts > 1)
9841 nadp->stduration = (nadp->stperiod)/(metric->src.pkts - 1);
9842 else
9843 nadp->stduration = 0.0;
9844
9845 if (metric->dst.pkts > 1)
9846 nadp->dtduration = (nadp->dtperiod)/(metric->dst.pkts - 1);
9847 else
9848 nadp->stduration = 0.0;
9849
9850 nadp->scpkts = 0.0;
9851 nadp->dcpkts = 0.0;
9852 }
9853
9854 // first does this direction need adjustment, if xstime > esecs then we need to pass.
9855 if (sstime > esecs) {
9856 rtime->src.start.tv_sec = 0;
9857 rtime->src.start.tv_usec = 0;
9858 rtime->src.end.tv_sec = 0;
9859 rtime->src.end.tv_usec = 0;
9860 rmetric->src.pkts = 0;
9861 rmetric->src.bytes = 0;
9862 rmetric->src.appbytes = 0;
9863 rtime->hdr.subtype &= ~(ARGUS_TIME_SRC_START | ARGUS_TIME_SRC_END);
9864 } else {
9865 if (setime > esecs) {
9866 rtime->src.end.tv_sec = eSecs.tv_sec;
9867 rtime->src.end.tv_usec = eSecs.tv_usec;
9868 rtime->hdr.subtype |= (ARGUS_TIME_SRC_START | ARGUS_TIME_SRC_END);
9869 time->src.start = rtime->src.end;
9870 time->hdr.subtype |= (ARGUS_TIME_SRC_START | ARGUS_TIME_SRC_END);
9871 } else {
9872 time->src.start.tv_sec = 0;
9873 time->src.start.tv_usec = 0;
9874 time->src.end.tv_sec = 0;
9875 time->src.end.tv_usec = 0;
9876 time->hdr.subtype &= ~(ARGUS_TIME_SRC_START | ARGUS_TIME_SRC_END);
9877 nadp->stduration = 0;
9878 }
9879 }
9880
9881 if (dstime > esecs) {
9882 rtime->dst.start.tv_sec = 0;
9883 rtime->dst.start.tv_usec = 0;
9884 rtime->dst.end.tv_sec = 0;
9885 rtime->dst.end.tv_usec = 0;
9886 rmetric->dst.pkts = 0;
9887 rmetric->dst.bytes = 0;
9888 rmetric->dst.appbytes = 0;
9889 rtime->hdr.subtype &= ~(ARGUS_TIME_DST_START | ARGUS_TIME_DST_END);
9890
9891 } else {
9892 if (detime > esecs) {
9893 rtime->dst.end.tv_sec = eSecs.tv_sec;
9894 rtime->dst.end.tv_usec = eSecs.tv_usec;
9895 rtime->hdr.subtype |= (ARGUS_TIME_DST_START | ARGUS_TIME_DST_END);
9896 time->dst.start = rtime->dst.end;
9897 time->hdr.subtype |= (ARGUS_TIME_DST_START | ARGUS_TIME_DST_END);
9898
9899 } else {
9900 time->dst.start.tv_sec = 0;
9901 time->dst.start.tv_usec = 0;
9902 time->dst.end = time->dst.start;
9903 time->hdr.subtype &= ~(ARGUS_TIME_DST_START | ARGUS_TIME_DST_END);
9904 nadp->dtduration = 0;
9905 }
9906 }
9907
9908 if (rtime->src.start.tv_sec && rmetric->src.pkts) {
9909 int thisBytes = 0, thisAppBytes = 0, thisCount = 0;
9910 long long tduration, rduration;
9911 long long tsstime, tsetime;
9912 double pkts, ratio;
9913 double iptr;
9914
9915 tsstime = (rtime->src.start.tv_sec * 1000000LL) + rtime->src.start.tv_usec;
9916 tsetime = (rtime->src.end.tv_sec * 1000000LL) + rtime->src.end.tv_usec;
9917
9918 if ((tduration = (tsetime - tsstime)) > nadp->size)
9919 tduration = nadp->size;
9920
9921 if ((rduration = (setime - sstime)) > nadp->size)
9922 rduration = nadp->size;
9923
9924 pkts = ((nadp->spkts + nadp->scpkts) * (tduration * 1.0))/(rduration * 1.0);
9925
9926 // add carry from last accumluation
9927 modf(pkts, &iptr);
9928
9929 thisCount = iptr;
9930
9931 if (thisCount > rmetric->src.pkts)
9932 thisCount = rmetric->src.pkts;
9933
9934 if (thisCount < 1)
9935 thisCount = 1;
9936
9937 if (thisCount == 0) {
9938 if (nadp->turns == 1) {
9939 thisCount = 1;
9940 nadp->scpkts += (thisCount * 1.0) - nadp->spkts;
9941 } else {
9942 nadp->scpkts += nadp->spkts;
9943 }
9944
9945 } else
9946 nadp->scpkts += ((nadp->spkts * (tduration * 1.0))/(rduration * 1.0)) - (thisCount * 1.0);
9947
9948 ratio = ((thisCount * 1.0)/nadp->spkts);
9949 thisBytes = nadp->sbytes * ratio;
9950 thisAppBytes = nadp->sappbytes * ratio;
9951
9952 rmetric->src.pkts = thisCount;
9953 rmetric->src.bytes = thisBytes;
9954 rmetric->src.appbytes = thisAppBytes;
9955 }
9956
9957 if (rtime->dst.start.tv_sec && rmetric->dst.pkts) {
9958 int thisBytes = 0, thisAppBytes = 0, thisCount = 0;
9959 long long tduration, rduration;
9960 long long tdstime, tdetime;
9961 double ratio, pkts;
9962 double iptr;
9963
9964 tdstime = (rtime->dst.start.tv_sec * 1000000LL) + rtime->dst.start.tv_usec;
9965 tdetime = (rtime->dst.end.tv_sec * 1000000LL) + rtime->dst.end.tv_usec;
9966
9967 if ((tduration = (tdetime - tdstime)) > nadp->size)
9968 tduration = nadp->size;
9969
9970 if ((rduration = (detime - dstime)) > nadp->size)
9971 rduration = nadp->size;
9972
9973
9974 pkts = ((nadp->dpkts + nadp->dcpkts) * (tduration * 1.0))/(rduration * 1.0);
9975 // add carry from last accumluation
9976 modf(pkts, &iptr);
9977
9978 thisCount = iptr;
9979
9980 if (thisCount > rmetric->dst.pkts)
9981 thisCount = rmetric->dst.pkts;
9982
9983 if ((thisCount < 1))
9984 thisCount = 1;
9985
9986 if (thisCount == 0) {
9987 if (nadp->turns == 1) {
9988 thisCount = 1;
9989 nadp->dcpkts += (thisCount * 1.0) - nadp->dpkts;
9990 } else {
9991 nadp->dcpkts += nadp->dpkts;
9992 }
9993
9994 } else
9995 nadp->dcpkts += ((nadp->dpkts * (tduration * 1.0))/(rduration * 1.0)) - (thisCount * 1.0);
9996
9997 ratio = ((thisCount * 1.0)/nadp->dpkts);
9998 thisBytes = nadp->dbytes * ratio;
9999 thisAppBytes = nadp->dappbytes * ratio;
10000
10001 rmetric->dst.pkts = thisCount;
10002 rmetric->dst.bytes = thisBytes;
10003 rmetric->dst.appbytes = thisAppBytes;
10004 }
10005
10006 agrRatio = ((rmetric->src.pkts + rmetric->dst.pkts) * 1.0)/((metric->src.pkts + metric->dst.pkts) * 1.0);
10007
10008 if ((ragr != NULL) && (agr != NULL)) {
10009 if (agr->count > 1) {
10010 ragr->count = agr->count * agrRatio;
10011 if (ragr->count == 0) {
10012 if ((rmetric->src.pkts + rmetric->dst.pkts) > 0)
10013 ragr->count = 1;
10014 }
10015 agr->count -= ragr->count;
10016 } else {
10017 ragr->count = agr->count;
10018 }
10019 }
10020
10021 metric->src.pkts -= rmetric->src.pkts;
10022 metric->src.bytes -= rmetric->src.bytes;
10023 metric->src.appbytes -= rmetric->src.appbytes;
10024
10025 metric->dst.pkts -= rmetric->dst.pkts;
10026 metric->dst.bytes -= rmetric->dst.bytes;
10027 metric->dst.appbytes -= rmetric->dst.appbytes;
10028
10029 if ((metric->src.pkts == 0) && (metric->src.bytes > 0)) {
10030 if (rmetric->src.pkts > 1) {
10031 rmetric->src.pkts--;
10032 metric->src.pkts++;
10033 } else {
10034 rmetric->src.bytes += metric->src.bytes;
10035 rmetric->src.appbytes += metric->src.appbytes;
10036 }
10037 }
10038
10039 if ((metric->dst.pkts == 0) && (metric->dst.bytes > 0)) {
10040 if (rmetric->dst.pkts > 1) {
10041 rmetric->dst.pkts--;
10042 metric->dst.pkts++;
10043 } else {
10044 rmetric->dst.bytes += metric->dst.bytes;
10045 rmetric->dst.appbytes += metric->dst.appbytes;
10046 }
10047 }
10048
10049 if ((rmetric->src.pkts + rmetric->dst.pkts) == 1) {
10050 rtime->src.end = rtime->src.start;
10051 rtime->dst.end = rtime->dst.start;
10052 }
10053
10054 if ((metric->src.pkts > 1) && nadp->stduration) {
10055 struct timeval dtime, diff;
10056 long long tratio, useconds;
10057
10058 tratio = (nadp->stduration * rmetric->src.pkts) * nadp->size;
10059 sstime += tratio;
10060 dtime.tv_sec = sstime / 1000000;
10061 dtime.tv_usec = sstime % 1000000;
10062
10063 RaDiffTime(&dtime, (struct timeval *)&time->src.start, &diff);
10064 useconds = (diff.tv_sec * 1000000) + diff.tv_usec;
10065
10066 if (useconds >= nadp->size) {
10067 time->src.start.tv_sec = dtime.tv_sec;
10068 time->src.start.tv_usec = dtime.tv_usec;
10069 }
10070
10071 } else {
10072 if (metric->src.pkts == 1) {
10073 time->src.start.tv_sec = time->src.end.tv_sec;
10074 time->src.start.tv_usec = time->src.end.tv_usec;
10075 }
10076 }
10077 if ((metric->dst.pkts > 1) && nadp->dtduration) {
10078 struct timeval dtime, diff;
10079 long long tratio, useconds;
10080
10081 tratio = (nadp->dtduration * rmetric->dst.pkts) * nadp->size;
10082 dstime += tratio;
10083 dtime.tv_sec = dstime / 1000000;
10084 dtime.tv_usec = dstime % 1000000;
10085
10086 RaDiffTime(&dtime, (struct timeval *)&time->dst.start, &diff);
10087 useconds = diff.tv_sec * 1000000 + diff.tv_usec;
10088 if (useconds >= nadp->size) {
10089 time->dst.start.tv_sec = dtime.tv_sec;
10090 time->dst.start.tv_usec = dtime.tv_usec;
10091 }
10092 } else {
10093 if (metric->dst.pkts == 1) {
10094 time->dst.start.tv_sec = time->dst.end.tv_sec;
10095 time->dst.start.tv_usec = time->dst.end.tv_usec;
10096 }
10097 }
10098 }
10099 }
10100
10101 } else {
10102 metric->src.pkts = 0;
10103 metric->dst.pkts = 0;
10104 }
10105 }
10106
10107 } else {
10108 if ((metric->src.pkts + metric->dst.pkts) == 1) {
10109 if ((retn = ArgusCopyRecordStruct (ns)) == NULL)
10110 return(retn);
10111
10112 rmetric = (void *)retn->dsrs[ARGUS_METRIC_INDEX];
10113 rtime = (void *)retn->dsrs[ARGUS_TIME_INDEX];
10114 ragr = (void *)retn->dsrs[ARGUS_AGR_INDEX];
10115
10116 nadp->turns++;
10117 metric->src.pkts = 0;
10118 metric->dst.pkts = 0;
10119 }
10120 }
10121
10122 if (nadp->hard) {
10123 rtime->src.start.tv_sec = sSecs.tv_sec;
10124 rtime->src.start.tv_usec = sSecs.tv_usec;
10125 rtime->dst.start = rtime->src.start;
10126
10127 rtime->src.end.tv_sec = eSecs.tv_sec;
10128 rtime->src.end.tv_usec = eSecs.tv_usec;
10129 rtime->dst.end = rtime->src.end;
10130 rtime->hdr.argus_dsrvl8.len = (sizeof(*rtime) + 3)/4;
10131
10132 rtime->hdr.subtype |= (ARGUS_TIME_SRC_START | ARGUS_TIME_SRC_END);
10133 }
10134 }
10135 if (nadp->sploss > 0)
10136 ArgusAdjustSrcLoss(ns, retn, nadp->sploss);
10137 if (nadp->dploss > 0)
10138 ArgusAdjustDstLoss(ns, retn, nadp->dploss);
10139
10140 } else
10141 nadp->turns = 0;
10142 } else
10143 nadp->turns = 0;
10144 }
10145 }
10146 }
10147
10148 #ifdef ARGUSDEBUG
10149 ArgusDebug (6, "ArgusAlignRecord () returning %p\n", retn);
10150 #endif
10151 return(retn);
10152 }
10153
10154
10155 // ArgusInsertRecord (struct ArgusParserStruct *parser, struct ArgusRecordStruct *ns)
10156 // This routine takes an ArgusRecordStruct and inserts it into the current
10157 // array structure that is held in the RaBinProcessStruct *RaBinProcess.
10158 //
10159 // If the structure has not been initialized, this routines initializes
10160 // the RaBinProcess by allocating an array of sufficient size in order
10161 // to accomodate a number of insertions, ARGUSMINARRAYSIZE. If the mode
10162 // is ARGUSSPLITTIME, then the start value will be the start time in seconds
10163 // of the first record seen. If any adjustments need to be made, they
10164 // need to be done prior to calling ArgusInsertRecord().
10165 //
10166 // The array strategy is to assume that records will not come in order,
10167 // so we'll allocate a number of slots for a negative index insertion.
10168 // If the array is not large enough, we'll allocate more space as we go.
10169 //
10170 // struct RaBinStruct {
10171 // int status, timeout;
10172 // double value, size;
10173 // struct ArgusQueueStruct *queue;
10174 // struct ArgusHashTable hashtable;
10175 // };
10176 //
10177 // struct RaBinProcessStruct {
10178 // unsigned int status, start, end, size;
10179 // int arraylen, len, count, index;
10180 // struct RaBinStruct **array;
10181 //
10182 // struct ArgusAdjustStruct *nadp;
10183 // };
10184 //
10185 // The concept here is to insert a record into an array, based on an aggregation
10186 // strategy. There are two strategies, one where a bin is defined by mode
10187 // specifiers on the command line, and the other is where there is no
10188 // definition, and you want to insert the record into a one second bin
10189 // specified by the starting seconds in the record.
10190 //
10191 // So the issues are to create the array using the rbps to provide hints.
10192 // Indicate the starting and ending points for the array, and then insert
10193 // the record so that it is in the 'bin' it belongs.
10194 //
10195 // Depending on the mode of operation, use either the rbps->nadp to tell
10196 // us which time bin were in (nadp.RaStartTmStruct and nadp.RaEndTmStruct),
10197 // or use the ns->canon.time.src.start.tv_sec to determine the bin.
10198 //
10199 // Usually the TmStructs do the right thing, as the program has called
10200 // routines like ArgusAlignRecord() which sets up the TmStructs to
10201 // be the bounding regions for the bin the record should go in.
10202 //
10203
10204
10205 #define ARGUSMINARRAYSIZE 0x400
10206 void ArgusShiftArray (struct ArgusParserStruct *, struct RaBinProcessStruct *, int, int);
10207
10208 void
ArgusShiftArray(struct ArgusParserStruct * parser,struct RaBinProcessStruct * rbps,int num,int lock)10209 ArgusShiftArray (struct ArgusParserStruct *parser, struct RaBinProcessStruct *rbps, int num, int lock)
10210 {
10211 if (num > 0) {
10212 struct RaBinStruct *bin;
10213 int i, step;
10214
10215 #if defined(ARGUS_THREADS)
10216 if (lock == ARGUS_LOCK)
10217 pthread_mutex_lock(&rbps->lock);
10218 #endif
10219
10220 for (i = 0; i < num; i++)
10221 if ((bin = rbps->array[rbps->index + i]) != NULL)
10222 RaDeleteBin(parser, (struct RaBinStruct *) bin);
10223
10224 for (i = rbps->index, step = (rbps->arraylen - num); i < step; i++)
10225 rbps->array[i] = rbps->array[i + num];
10226
10227 for (i = rbps->arraylen - num; i < rbps->arraylen; i++)
10228 rbps->array[i] = NULL;
10229
10230 rbps->start += rbps->size * num;
10231 rbps->end += rbps->size * num;
10232
10233 rbps->startpt.tv_sec = rbps->start / 1000000;
10234 rbps->startpt.tv_usec = rbps->start % 1000000;
10235
10236 rbps->endpt.tv_sec = rbps->end / 1000000;
10237 rbps->endpt.tv_usec = rbps->end % 1000000;
10238
10239 rbps->max -= num;
10240
10241 #if defined(ARGUS_THREADS)
10242 if (lock == ARGUS_LOCK)
10243 pthread_mutex_unlock(&rbps->lock);
10244 #endif
10245 }
10246
10247 #ifdef ARGUSDEBUG
10248 ArgusDebug (3, "ArgusShiftArray (%p, %p) shifted array %d slot(s)\n", parser, rbps, num);
10249 #endif
10250 }
10251
10252
10253 // ArgusInsertRecord - this routine takes an rbps structure with an argus record and an offset
10254 // and inserts it into a time based array. The rbps holds the notion of the
10255 // start and end range of the array, and the size of the bins. From this
10256 // you should be able to figure out if there is an index to put the
10257 // record in, or if we need to adjust the array to accept the record.
10258 //
10259 // ArgusInsertRecord returns 1 for an insertion, 0 for an update.
10260
10261
10262 int
ArgusInsertRecord(struct ArgusParserStruct * parser,struct RaBinProcessStruct * rbps,struct ArgusRecordStruct * argus,int offset)10263 ArgusInsertRecord (struct ArgusParserStruct *parser, struct RaBinProcessStruct *rbps, struct ArgusRecordStruct *argus, int offset)
10264 {
10265 struct ArgusAggregatorStruct *agg = NULL;
10266 struct RaBinStruct *bin = NULL;
10267 long long val = 0;
10268 int ind = 0;
10269 int retn = 0;
10270
10271 #if defined(ARGUS_THREADS)
10272 pthread_mutex_lock(&rbps->lock);
10273 #endif
10274
10275 if (rbps && argus) {
10276 if (rbps->array == NULL) {
10277 if ((rbps->arraylen = rbps->nadp.count + offset + RATOPSTARTINGINDEX + 1) == 0)
10278 rbps->arraylen = ARGUSMINARRAYSIZE;
10279
10280 rbps->len = rbps->arraylen;
10281 rbps->index = offset;
10282 rbps->max = 0;
10283
10284 if ((rbps->array = (struct RaBinStruct **) ArgusCalloc(sizeof(void *), rbps->len + 1)) == NULL)
10285 ArgusLog (LOG_ERR, "ArgusInsertRecord: ArgusCalloc error %s", strerror(errno));
10286 }
10287
10288 if (rbps->startpt.tv_sec == 0) {
10289 if (rbps->nadp.start.tv_sec == 0) {
10290 if (rbps->nadp.RaStartTmStruct.tm_year == 0) {
10291 time_t tsec = parser->ArgusGlobalTime.tv_sec;
10292
10293 localtime_r(&tsec, &rbps->nadp.RaStartTmStruct);
10294 }
10295
10296 rbps->startpt.tv_sec = mktime(&rbps->nadp.RaStartTmStruct);
10297 rbps->endpt.tv_sec = rbps->startpt.tv_sec + (rbps->nadp.count * rbps->nadp.size)/1000000;
10298
10299 } else {
10300 rbps->startpt = rbps->nadp.start;
10301 if ((rbps->nadp.end.tv_sec) == 0) {
10302 rbps->endpt.tv_sec = rbps->startpt.tv_sec + (rbps->nadp.count * rbps->nadp.size)/1000000;
10303 } else {
10304 rbps->endpt = rbps->nadp.end;
10305 }
10306 }
10307
10308 #ifdef ARGUSDEBUG
10309 ArgusDebug (3, "ArgusInsertRecord (%p, %p) initializing array\n", rbps, argus);
10310 #endif
10311 }
10312
10313 if (rbps->start == 0.0) {
10314 long long tval = 0;
10315 switch (rbps->nadp.qual) {
10316 case ARGUSSPLITDAY: {
10317 time_t fileSecs = rbps->startpt.tv_sec;
10318 struct tm tmval;
10319
10320 localtime_r(&fileSecs, &tmval);
10321 #if defined(HAVE_TM_GMTOFF)
10322 fileSecs += tmval.tm_gmtoff;
10323 #endif
10324 fileSecs = fileSecs / (rbps->nadp.size / 1000000);
10325 fileSecs = fileSecs * (rbps->nadp.size / 1000000);
10326 #if defined(HAVE_TM_GMTOFF)
10327 fileSecs -= tmval.tm_gmtoff;
10328 #endif
10329 rbps->start = fileSecs * 1000000LL;
10330 rbps->end = rbps->start + rbps->nadp.size;
10331 break;
10332 }
10333
10334 case ARGUSSPLITHOUR:
10335 case ARGUSSPLITMINUTE:
10336 case ARGUSSPLITSECOND: {
10337 tval = ((rbps->startpt.tv_sec * 1000000LL) + rbps->startpt.tv_usec) / rbps->nadp.size;
10338 rbps->start = tval * rbps->nadp.size;
10339 tval = ((rbps->endpt.tv_sec * 1000000LL) + rbps->endpt.tv_usec) / rbps->nadp.size;
10340 rbps->end = tval * rbps->nadp.size;
10341 break;
10342 }
10343 }
10344 }
10345
10346 // set the current records value and index for insertion into array.
10347
10348 switch (rbps->nadp.mode) {
10349 default:
10350 case ARGUSSPLITRATE:
10351 case ARGUSSPLITTIME: {
10352
10353 if (parser->RaWildCardDate) {
10354 struct tm stmbuf, *stm;
10355 time_t tsec;
10356 int i = 0;
10357
10358 val = ArgusFetchStartTime(argus);
10359 tsec = val;
10360 stm = localtime_r (&tsec, &stmbuf);
10361
10362 for (i = 0; i < RAMAXWILDCARDFIELDS; i++) {
10363 if (parser->RaWildCardDate & (1 << i)) {
10364 switch (i) {
10365 case RAWILDCARDYEAR: {
10366 stm->tm_year = 70;
10367 break;
10368 }
10369 case RAWILDCARDMONTH: {
10370 stm->tm_mon = 0;
10371 break;
10372 }
10373 case RAWILDCARDDAY: {
10374 stm->tm_mday = 1;
10375 break;
10376 }
10377 case RAWILDCARDHOUR: {
10378 stm->tm_hour = 0;
10379 break;
10380 }
10381 case RAWILDCARDMIN: {
10382 stm->tm_min = 0;
10383 break;
10384 }
10385 case RAWILDCARDSEC: {
10386 stm->tm_sec = 0;
10387 break;
10388 }
10389 }
10390 }
10391 }
10392
10393 tsec = mktime (stm);
10394 val = (tsec * 1000000LL);
10395
10396 } else
10397 val = ArgusFetchStartuSecTime(argus);
10398
10399 break;
10400 }
10401
10402 case ARGUSSPLITSIZE:
10403 case ARGUSSPLITCOUNT: {
10404 val = rbps->start + (rbps->size * (rbps->index - RATOPSTARTINGINDEX));
10405 break;
10406 }
10407 }
10408
10409 // using val, calculate the index offset for this record
10410
10411 switch (rbps->nadp.mode) {
10412 default:
10413 case ARGUSSPLITRATE:
10414 case ARGUSSPLITTIME:
10415 case ARGUSSPLITSIZE: {
10416 if ((val - rbps->start) >= 0) {
10417 int i = ((val - rbps->start)/rbps->size);
10418 ind = rbps->index + i;
10419 #ifdef ARGUSDEBUG
10420 ArgusDebug (2, "ArgusInsertRecord (%p, %p, %p) val %lld, start %lld, size %lld, calculated ind %d\n", parser, rbps, argus, val, rbps->start, rbps->size, ind);
10421 #endif
10422 } else
10423 ind = -1;
10424 break;
10425 }
10426 case ARGUSSPLITCOUNT: {
10427 double frac, iptr, val = ((rbps->count + 1) / rbps->size);
10428
10429 frac = modf(val, &iptr);
10430
10431 if (!(frac))
10432 rbps->index++;
10433
10434 ind = rbps->index + ((val - rbps->start) / rbps->size);
10435 break;
10436 }
10437 }
10438
10439 if (ind < 0) {
10440 #ifdef ARGUSDEBUG
10441 ArgusDebug (2, "ArgusInsertRecord (%p, %p) array too short ind %d index %d", rbps, argus, ind, rbps->index);
10442 #endif
10443 } else {
10444
10445 // here is where we do a lot of array and queue management. we want
10446 // to get the rbps->array set up right, as it is our time series
10447 // buffer, so we want to shift the record so that it represents
10448 // now, and however many seconds back is needed to cover the period
10449 // of the "-M rate %d:%d[smhdwMy]" needed.
10450 //
10451 // So in ArgusProcessQueue(), we will manage the arrays but that is
10452 // in a periodic fashion. Here, we have data, and so it is also
10453 // a driver for correcting the array series. We need to shift array
10454 // members, and delete bins to get the current time correct.
10455 //
10456 // We could use this as a hint to correct the array to current time,
10457 // but because ArgusGlobalTime and ArgusLastTime are not necessarily
10458 // in sync, go ahead and let the actual data drive the array corrections,
10459 // and let ArgusProcessQueue, do its thing to get the array aligned with
10460 // ArgusGlobalTime.
10461 //
10462 // at this point we're ready to add the record to the array.
10463 // test if the array has a bin struct, if not add one, then
10464 // add the record to the bin struct, based on the split mode.
10465
10466 if (ind >= rbps->arraylen) {
10467 struct RaBinStruct **newarray;
10468 int i, cnt = ((ind + ARGUSMINARRAYSIZE)/ARGUSMINARRAYSIZE) * ARGUSMINARRAYSIZE;
10469
10470 #ifdef ARGUSDEBUG
10471 ArgusDebug (2, "ArgusInsertRecord (%p, %p, %p) ind %d greater than arraylen %d adjusting\n", parser, rbps, argus, ind, rbps->arraylen);
10472 #endif
10473 if ((newarray = (void *) ArgusCalloc (sizeof(struct RaBinStruct *), cnt)) == NULL)
10474 ArgusLog (LOG_ERR, "ArgusInsertRecord: ArgusCalloc error %s", strerror(errno));
10475
10476 for (i = 0; i < rbps->arraylen; i++)
10477 newarray[i] = rbps->array[i];
10478
10479 ArgusFree(rbps->array);
10480 rbps->array = newarray;
10481 rbps->arraylen = cnt;
10482 rbps->len = cnt;
10483 }
10484
10485 if ((bin = rbps->array[ind]) == NULL) {
10486 if (ind > rbps->max)
10487 rbps->max = ind;
10488
10489 if ((rbps->array[ind] = RaNewBin(parser, rbps, argus, (rbps->start + (ind * rbps->size)), RATOPSTARTINGINDEX)) == NULL)
10490 ArgusLog (LOG_ERR, "ArgusInsertRecord: RaNewBin error %s", strerror(errno));
10491
10492 bin = rbps->array[ind];
10493
10494 if (rbps->end < bin->value) {
10495 rbps->end = bin->value;
10496
10497 if ((rbps->endpt.tv_sec < bin->etime.tv_sec) ||
10498 ((rbps->endpt.tv_sec == bin->etime.tv_sec) &&
10499 (rbps->endpt.tv_usec < bin->etime.tv_usec)))
10500 rbps->endpt = bin->etime;
10501 }
10502 }
10503
10504 if ((agg = bin->agg) != NULL) {
10505 int found = 0;
10506
10507 while (agg && !found) {
10508 struct nff_insn *fcode = agg->filter.bf_insns;
10509 struct ArgusHashStruct *hstruct = NULL;
10510
10511 if (ArgusFilterRecord (fcode, argus) != 0) {
10512 switch (argus->hdr.type & 0xF0) {
10513 case ARGUS_MAR:
10514 case ARGUS_EVENT: {
10515 ArgusAddToQueue (agg->queue, &argus->qhdr, ARGUS_NOLOCK);
10516 agg->status |= ARGUS_AGGREGATOR_DIRTY;
10517 retn = 1;
10518 found++;
10519 break;
10520 }
10521
10522 case ARGUS_NETFLOW:
10523 case ARGUS_FAR: {
10524 struct ArgusRecordStruct *tns;
10525
10526 if (ArgusParser->RaCumulativeMerge == 0) {
10527 ArgusAddToQueue (agg->queue, &argus->qhdr, ARGUS_NOLOCK);
10528 agg->status |= ARGUS_AGGREGATOR_DIRTY;
10529 retn = 1;
10530 found++;
10531
10532 } else {
10533 if (agg->mask) {
10534 if ((agg->rap = RaFlowModelOverRides(agg, argus)) == NULL)
10535 agg->rap = agg->drap;
10536
10537 ArgusGenerateNewFlow(agg, argus);
10538
10539 if ((hstruct = ArgusGenerateHashStruct(agg, argus, NULL)) == NULL)
10540 ArgusLog (LOG_ERR, "ArgusInsertRecord: ArgusGenerateHashStruct error %s", strerror(errno));
10541
10542 if ((tns = ArgusFindRecord(agg->htable, hstruct)) != NULL) {
10543 double dur, nsst, tnsst, nslt, tnslt;
10544 if (parser->Aflag) {
10545 if ((tns->status & RA_SVCTEST) != (argus->status & RA_SVCTEST)) {
10546 RaSendArgusRecord(tns);
10547 ArgusZeroRecord(tns);
10548 tns->status &= ~(RA_SVCTEST);
10549 tns->status |= (argus->status & RA_SVCTEST);
10550 }
10551 }
10552
10553 nsst = ArgusFetchStartTime(argus);
10554 tnsst = ArgusFetchStartTime(tns);
10555 nslt = ArgusFetchLastTime(argus);
10556 tnslt = ArgusFetchLastTime(tns);
10557
10558 dur = ((tnslt > nslt) ? tnslt : nslt) - ((nsst < tnsst) ? nsst : tnsst);
10559
10560 if (agg->statusint && (dur >= agg->statusint)) {
10561 RaSendArgusRecord(tns);
10562 ArgusZeroRecord(tns);
10563 } else {
10564 dur = ((tnslt > nslt) ? tnslt : nslt) - ((nsst < tnsst) ? nsst : tnsst);
10565 if (agg->idleint && (dur >= agg->idleint)) {
10566 RaSendArgusRecord(tns);
10567 ArgusZeroRecord(tns);
10568 }
10569 }
10570
10571 ArgusMergeRecords (agg, tns, argus);
10572
10573 } else {
10574 struct ArgusFlow *flow = (struct ArgusFlow *) argus->dsrs[ARGUS_FLOW_INDEX];
10575 if (!parser->RaMonMode && parser->ArgusReverse) {
10576 int tryreverse = 0;
10577
10578 if (flow != NULL) {
10579 if (agg->correct != NULL)
10580 tryreverse = 1;
10581
10582 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
10583 case ARGUS_TYPE_IPV4: {
10584 switch (flow->ip_flow.ip_p) {
10585 case IPPROTO_ESP:
10586 tryreverse = 0;
10587 break;
10588 }
10589 break;
10590 }
10591 case ARGUS_TYPE_IPV6: {
10592 switch (flow->ipv6_flow.ip_p) {
10593 case IPPROTO_ESP:
10594 tryreverse = 0;
10595 break;
10596 }
10597 break;
10598 }
10599 }
10600 } else
10601 tryreverse = 0;
10602
10603 if (tryreverse) {
10604 if (hstruct != NULL) {
10605 }
10606
10607 if ((hstruct = ArgusGenerateReverseHashStruct(agg, argus, (struct ArgusFlow *)&agg->fstruct)) == NULL)
10608 ArgusLog (LOG_ERR, "RaProcessThisRecord: ArgusGenerateHashStruct error %s", strerror(errno));
10609
10610 if ((tns = ArgusFindRecord(agg->htable, hstruct)) == NULL) {
10611 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
10612 case ARGUS_TYPE_IPV4: {
10613 switch (flow->ip_flow.ip_p) {
10614 case IPPROTO_ICMP: {
10615 struct ArgusICMPFlow *icmpFlow = &flow->flow_un.icmp;
10616
10617 if (ICMP_INFOTYPE(icmpFlow->type)) {
10618 switch (icmpFlow->type) {
10619 case ICMP_ECHO:
10620 case ICMP_ECHOREPLY:
10621 icmpFlow->type = (icmpFlow->type == ICMP_ECHO) ? ICMP_ECHOREPLY : ICMP_ECHO;
10622 if ((hstruct = ArgusGenerateReverseHashStruct(agg, argus, (struct ArgusFlow *)&agg->fstruct)) != NULL)
10623 tns = ArgusFindRecord(agg->htable, hstruct);
10624 icmpFlow->type = (icmpFlow->type == ICMP_ECHO) ? ICMP_ECHOREPLY : ICMP_ECHO;
10625 if (tns)
10626 ArgusReverseRecord (argus);
10627 break;
10628
10629 case ICMP_ROUTERADVERT:
10630 case ICMP_ROUTERSOLICIT:
10631 icmpFlow->type = (icmpFlow->type == ICMP_ROUTERADVERT) ? ICMP_ROUTERSOLICIT : ICMP_ROUTERADVERT;
10632 if ((hstruct = ArgusGenerateReverseHashStruct(agg, argus, (struct ArgusFlow *)&agg->fstruct)) != NULL)
10633 tns = ArgusFindRecord(agg->htable, hstruct);
10634 icmpFlow->type = (icmpFlow->type == ICMP_ROUTERADVERT) ? ICMP_ROUTERSOLICIT : ICMP_ROUTERADVERT;
10635 if (tns)
10636 ArgusReverseRecord (argus);
10637 break;
10638
10639 case ICMP_TSTAMP:
10640 case ICMP_TSTAMPREPLY:
10641 icmpFlow->type = (icmpFlow->type == ICMP_TSTAMP) ? ICMP_TSTAMPREPLY : ICMP_TSTAMP;
10642 if ((hstruct = ArgusGenerateReverseHashStruct(agg, argus, (struct ArgusFlow *)&agg->fstruct)) != NULL)
10643 tns = ArgusFindRecord(agg->htable, hstruct);
10644 icmpFlow->type = (icmpFlow->type == ICMP_TSTAMP) ? ICMP_TSTAMPREPLY : ICMP_TSTAMP;
10645 if (tns)
10646 ArgusReverseRecord (argus);
10647 break;
10648
10649 case ICMP_IREQ:
10650 case ICMP_IREQREPLY:
10651 icmpFlow->type = (icmpFlow->type == ICMP_IREQ) ? ICMP_IREQREPLY : ICMP_IREQ;
10652 if ((hstruct = ArgusGenerateReverseHashStruct(agg, argus, (struct ArgusFlow *)&agg->fstruct)) != NULL)
10653 tns = ArgusFindRecord(agg->htable, hstruct);
10654 icmpFlow->type = (icmpFlow->type == ICMP_IREQ) ? ICMP_IREQREPLY : ICMP_IREQ;
10655 if (tns)
10656 ArgusReverseRecord (argus);
10657 break;
10658
10659 case ICMP_MASKREQ:
10660 case ICMP_MASKREPLY:
10661 icmpFlow->type = (icmpFlow->type == ICMP_MASKREQ) ? ICMP_MASKREPLY : ICMP_MASKREQ;
10662 if ((hstruct = ArgusGenerateReverseHashStruct(agg, argus, (struct ArgusFlow *)&agg->fstruct)) != NULL)
10663 tns = ArgusFindRecord(agg->htable, hstruct);
10664 icmpFlow->type = (icmpFlow->type == ICMP_MASKREQ) ? ICMP_MASKREPLY : ICMP_MASKREQ;
10665 if (tns)
10666 ArgusReverseRecord (argus);
10667 break;
10668 }
10669 }
10670 break;
10671 }
10672 }
10673 }
10674 }
10675 if ((hstruct = ArgusGenerateHashStruct(agg, argus, (struct ArgusFlow *)&agg->fstruct)) == NULL)
10676 ArgusLog (LOG_ERR, "RaProcessThisRecord: ArgusGenerateHashStruct error %s", strerror(errno));
10677
10678 } else {
10679 struct ArgusNetworkStruct *nnet = (struct ArgusNetworkStruct *)argus->dsrs[ARGUS_NETWORK_INDEX];
10680 struct ArgusNetworkStruct *tnet = (struct ArgusNetworkStruct *)tns->dsrs[ARGUS_NETWORK_INDEX];
10681
10682 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
10683 case ARGUS_TYPE_IPV4: {
10684 switch (flow->ip_flow.ip_p) {
10685 case IPPROTO_TCP: {
10686 if ((nnet != NULL) && (tnet != NULL)) {
10687 struct ArgusTCPObject *ntcp = &nnet->net_union.tcp;
10688 struct ArgusTCPObject *ttcp = &tnet->net_union.tcp;
10689
10690 // first if both flows have syn, then don't merge;
10691 if ((ntcp->status & ARGUS_SAW_SYN) && (ttcp->status & ARGUS_SAW_SYN)) {
10692 tns = NULL;
10693 } else {
10694 if ((ntcp->status & ARGUS_SAW_SYN) ||
10695 ((ntcp->status & ARGUS_SAW_SYN_SENT) && (ntcp->status & ARGUS_CON_ESTABLISHED))) {
10696 struct ArgusFlow *tflow = (struct ArgusFlow *) tns->dsrs[ARGUS_FLOW_INDEX];
10697 ArgusRemoveHashEntry(&tns->htblhdr);
10698 ArgusReverseRecord (tns);
10699 hstruct = ArgusGenerateHashStruct(agg, tns, (struct ArgusFlow *)&agg->fstruct);
10700 tns->htblhdr = ArgusAddHashEntry (agg->htable, tns, hstruct);
10701 tflow->hdr.subtype &= ~ARGUS_REVERSE;
10702 tflow->hdr.argus_dsrvl8.qual &= ~ARGUS_DIRECTION;
10703 } else
10704 ArgusReverseRecord (argus);
10705 }
10706 }
10707 break;
10708 }
10709
10710 default:
10711 ArgusReverseRecord (argus);
10712 break;
10713 }
10714 }
10715 break;
10716
10717 case ARGUS_TYPE_IPV6: {
10718 switch (flow->ipv6_flow.ip_p) {
10719 case IPPROTO_TCP: {
10720 if ((nnet != NULL) && (tnet != NULL)) {
10721 struct ArgusTCPObject *ntcp = &nnet->net_union.tcp;
10722 struct ArgusTCPObject *ttcp = &tnet->net_union.tcp;
10723
10724 // first if both flows have syn, then don't merge;
10725 if ((ntcp->status & ARGUS_SAW_SYN) && (ttcp->status & ARGUS_SAW_SYN)) {
10726 tns = NULL;
10727 } else {
10728 if ((ntcp->status & ARGUS_SAW_SYN) ||
10729 ((ntcp->status & ARGUS_SAW_SYN_SENT) && (ntcp->status & ARGUS_CON_ESTABLISHED))) {
10730 struct ArgusFlow *tflow = (struct ArgusFlow *) tns->dsrs[ARGUS_FLOW_INDEX];
10731 ArgusRemoveHashEntry(&tns->htblhdr);
10732 ArgusReverseRecord (tns);
10733 hstruct = ArgusGenerateHashStruct(agg, tns, (struct ArgusFlow *)&agg->fstruct);
10734 tns->htblhdr = ArgusAddHashEntry (agg->htable, tns, hstruct);
10735 tflow->hdr.subtype &= ~ARGUS_REVERSE;
10736 tflow->hdr.argus_dsrvl8.qual &= ~ARGUS_DIRECTION;
10737 } else
10738 ArgusReverseRecord (argus);
10739 }
10740 }
10741 }
10742
10743 default:
10744 ArgusReverseRecord (argus);
10745 break;
10746 }
10747 }
10748 break;
10749
10750 default:
10751 ArgusReverseRecord (argus);
10752 }
10753 }
10754 }
10755 }
10756
10757 if (tns != NULL) {
10758 if (parser->Aflag) {
10759 if ((tns->status & RA_SVCTEST) != (argus->status & RA_SVCTEST)) {
10760 RaSendArgusRecord(tns);
10761 ArgusZeroRecord(tns);
10762 }
10763 tns->status &= ~(RA_SVCTEST);
10764 tns->status |= (argus->status & RA_SVCTEST);
10765 }
10766
10767 if (ArgusParser->RaCumulativeMerge != 0)
10768 ArgusMergeRecords (agg, tns, argus);
10769 else {
10770 RaSendArgusRecord(tns);
10771 ArgusZeroRecord(tns);
10772 ArgusMergeRecords (agg, tns, argus);
10773 }
10774
10775 ArgusRemoveFromQueue (agg->queue, &tns->qhdr, ARGUS_NOLOCK);
10776 ArgusAddToQueue (agg->queue, &tns->qhdr, ARGUS_NOLOCK);
10777 agg->status |= ARGUS_AGGREGATOR_DIRTY;
10778
10779 } else {
10780 argus->htblhdr = ArgusAddHashEntry (agg->htable, argus, hstruct);
10781 ArgusAddToQueue (agg->queue, &argus->qhdr, ARGUS_NOLOCK);
10782 agg->status |= ARGUS_AGGREGATOR_DIRTY;
10783 retn = 1;
10784 }
10785 }
10786
10787 } else {
10788 ArgusAddToQueue (agg->queue, &argus->qhdr, ARGUS_NOLOCK);
10789 agg->status |= ARGUS_AGGREGATOR_DIRTY;
10790 retn = 1;
10791 }
10792 found++;
10793 }
10794 break;
10795 }
10796 }
10797 }
10798 agg = agg->nxt;
10799 }
10800 }
10801
10802 rbps->scalesecs = rbps->endpt.tv_sec - rbps->startpt.tv_sec;
10803 }
10804 }
10805
10806 #ifdef ARGUSDEBUG
10807 {
10808 int vSec = val / 1000000;
10809 int vuSec = val % 1000000;
10810 int sSec = rbps->startpt.tv_sec;
10811 int suSec = rbps->startpt.tv_usec;
10812 int eSec = rbps->endpt.tv_sec;
10813 int euSec = rbps->endpt.tv_usec;
10814
10815 ArgusDebug (3, "ArgusInsertRecord (%p, %p, %p, %d) ind %d val %d.%6.6d bin start %d.%6.6d end %d.%6.6d", parser, rbps, argus, offset,
10816 ind, vSec, vuSec, sSec, suSec, eSec, euSec);
10817 }
10818 #endif
10819
10820 #if defined(ARGUS_THREADS)
10821 pthread_mutex_unlock(&rbps->lock);
10822 #endif
10823
10824 return (retn);
10825 }
10826
10827
10828 void ArgusInitAggregatorStructs(struct ArgusAggregatorStruct *);
10829
10830 void
ArgusInitAggregatorStructs(struct ArgusAggregatorStruct * nag)10831 ArgusInitAggregatorStructs(struct ArgusAggregatorStruct *nag)
10832 {
10833 struct ArgusFlow flowbuf, *flow = &flowbuf;
10834 int i;
10835
10836 for (i = 0; i < ARGUS_MAX_MASK_LIST; i++) {
10837 switch (i) {
10838 case ARGUS_MASK_PROTO:
10839 ArgusIpV4MaskDefs[i].offset = ((char *)&flow->ip_flow.ip_p - (char *)flow);
10840 ArgusIpV4RevMaskDefs[i].offset = ((char *)&flow->ip_flow.ip_p - (char *)flow);
10841
10842 #if defined(_LITTLE_ENDIAN)
10843 ArgusIpV6MaskDefs[i].offset = 39;
10844 ArgusIpV6RevMaskDefs[i].offset = 39;
10845 #else
10846 ArgusIpV6MaskDefs[i].offset = 36;
10847 ArgusIpV6RevMaskDefs[i].offset = 36;
10848 #endif
10849 ArgusIsisHelloMaskDefs[i].offset = ((char *)&flow->isis_flow.pdu_type - (char *)flow);
10850 ArgusIsisLspMaskDefs[i].offset = ((char *)&flow->isis_flow.pdu_type - (char *)flow);
10851 ArgusIsisCsnpMaskDefs[i].offset = ((char *)&flow->isis_flow.pdu_type - (char *)flow);
10852 ArgusIsisPsnpMaskDefs[i].offset = ((char *)&flow->isis_flow.pdu_type - (char *)flow);
10853 ArgusIsisRevMaskDefs[i].offset = ((char *)&flow->isis_flow.pdu_type - (char *)flow);
10854
10855 ArgusEtherMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_type - (char *)flow);
10856 ArgusEtherRevMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_type - (char *)flow);
10857 ArgusArpMaskDefs[i].len = 2;
10858 ArgusArpRevMaskDefs[i].len = 2;
10859 break;
10860
10861 case ARGUS_MASK_SNET:
10862 case ARGUS_MASK_SADDR:
10863 ArgusIpV4MaskDefs[i].offset = ((char *)&flow->ip_flow.ip_src - (char *)flow);
10864 ArgusIpV4RevMaskDefs[i].offset = ((char *)&flow->ip_flow.ip_dst - (char *)flow);
10865 ArgusIpV6MaskDefs[i].offset = ((char *)&flow->ipv6_flow.ip_src - (char *)flow);
10866 ArgusIpV6RevMaskDefs[i].offset = ((char *)&flow->ipv6_flow.ip_dst - (char *)flow);
10867 ArgusIsisHelloMaskDefs[i].offset = ((char *)&flow->isis_flow.isis_un.hello.srcid - (char *)flow);
10868 ArgusIsisLspMaskDefs[i].offset = ((char *)&flow->isis_flow.isis_un.lsp.lspid - (char *)flow);
10869 ArgusIsisCsnpMaskDefs[i].offset = ((char *)&flow->isis_flow.isis_un.csnp.srcid - (char *)flow);
10870 ArgusIsisPsnpMaskDefs[i].offset = ((char *)&flow->isis_flow.isis_un.psnp.srcid - (char *)flow);
10871 ArgusEtherMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_shost - (char *)flow);
10872 ArgusEtherRevMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_dhost - (char *)flow);
10873 ArgusWlanMaskDefs[i].offset = ((char *)&flow->wlan_flow.shost - (char *)flow);
10874 ArgusWlanRevMaskDefs[i].offset = ((char *)&flow->wlan_flow.dhost - (char *)flow);
10875 break;
10876
10877 case ARGUS_MASK_DNET:
10878 case ARGUS_MASK_DADDR:
10879 ArgusIpV4MaskDefs[i].offset = ((char *)&flow->ip_flow.ip_dst - (char *)flow);
10880 ArgusIpV4RevMaskDefs[i].offset = ((char *)&flow->ip_flow.ip_src - (char *)flow);
10881 ArgusIpV6MaskDefs[i].offset = ((char *)&flow->ipv6_flow.ip_dst - (char *)flow);
10882 ArgusIpV6RevMaskDefs[i].offset = ((char *)&flow->ipv6_flow.ip_src - (char *)flow);
10883 ArgusIsisHelloMaskDefs[i].offset = ((char *)&flow->isis_flow.isis_un.hello.lanid - (char *)flow);
10884 ArgusIsisLspMaskDefs[i].offset = ((char *)&flow->isis_flow.isis_un.lsp.seqnum - (char *)flow);
10885 ArgusIsisCsnpMaskDefs[i].len = 0;
10886 ArgusIsisPsnpMaskDefs[i].len = 0;
10887
10888 ArgusEtherMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_dhost - (char *)flow);
10889 ArgusEtherRevMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_shost - (char *)flow);
10890 ArgusWlanMaskDefs[i].offset = ((char *)&flow->wlan_flow.shost - (char *)flow);
10891 ArgusWlanRevMaskDefs[i].offset = ((char *)&flow->wlan_flow.dhost - (char *)flow);
10892 break;
10893
10894 case ARGUS_MASK_SPORT:
10895 ArgusIpV4MaskDefs[i].offset = ((char *)&flow->ip_flow.sport - (char *)flow);
10896 ArgusIpV4RevMaskDefs[i].offset = ((char *)&flow->ip_flow.dport - (char *)flow);
10897 ArgusIpV6MaskDefs[i].offset = ((char *)&flow->ipv6_flow.sport - (char *)flow);
10898 ArgusIpV6RevMaskDefs[i].offset = ((char *)&flow->ipv6_flow.dport - (char *)flow);
10899
10900 ArgusIsisHelloMaskDefs[i].offset = ((char *)&flow->isis_flow.chksum - (char *)flow);
10901 ArgusIsisLspMaskDefs[i].offset = ((char *)&flow->isis_flow.chksum - (char *)flow);
10902 ArgusIsisCsnpMaskDefs[i].offset = ((char *)&flow->isis_flow.chksum - (char *)flow);
10903 ArgusIsisPsnpMaskDefs[i].offset = ((char *)&flow->isis_flow.chksum - (char *)flow);
10904 ArgusIsisRevMaskDefs[i].offset = ((char *)&flow->isis_flow.chksum - (char *)flow);
10905
10906 ArgusEtherMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ssap - (char *)flow);
10907 ArgusEtherRevMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.dsap - (char *)flow);
10908 ArgusWlanMaskDefs[i].offset = ((char *)&flow->wlan_flow.ssid - (char *)flow);
10909 ArgusWlanRevMaskDefs[i].offset = ((char *)&flow->wlan_flow.ssid - (char *)flow);
10910 break;
10911
10912 case ARGUS_MASK_DPORT:
10913 ArgusIpV4MaskDefs[i].offset = ((char *)&flow->ip_flow.dport - (char *)flow);
10914 ArgusIpV4RevMaskDefs[i].offset = ((char *)&flow->ip_flow.sport - (char *)flow);
10915 ArgusIpV6MaskDefs[i].offset = ((char *)&flow->ipv6_flow.dport - (char *)flow);
10916 ArgusIpV6RevMaskDefs[i].offset = ((char *)&flow->ipv6_flow.sport - (char *)flow);
10917 ArgusEtherMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.dsap - (char *)flow);
10918 ArgusEtherRevMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ssap - (char *)flow);
10919 ArgusWlanMaskDefs[i].offset = ((char *)&flow->wlan_flow.bssid - (char *)flow);
10920 ArgusWlanRevMaskDefs[i].offset = ((char *)&flow->wlan_flow.bssid - (char *)flow);
10921 break;
10922
10923 case ARGUS_MASK_SMAC:
10924 ArgusIpV4MaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_shost - (char *)flow);
10925 ArgusIpV4RevMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_dhost - (char *)flow);
10926 ArgusIpV6MaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_shost - (char *)flow);
10927 ArgusIpV6RevMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_dhost - (char *)flow);
10928
10929 ArgusIsisHelloMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_shost - (char *)flow);
10930 ArgusIsisLspMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_shost - (char *)flow);
10931 ArgusIsisCsnpMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_shost - (char *)flow);
10932 ArgusIsisPsnpMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_shost - (char *)flow);
10933 ArgusIsisRevMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_dhost - (char *)flow);
10934
10935 ArgusEtherMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_shost - (char *)flow);
10936 ArgusEtherRevMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_dhost - (char *)flow);
10937 break;
10938
10939 case ARGUS_MASK_DMAC:
10940 ArgusIpV4MaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_dhost - (char *)flow);
10941 ArgusIpV4RevMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_shost - (char *)flow);
10942 ArgusIpV6MaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_dhost - (char *)flow);
10943 ArgusIpV6RevMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_shost - (char *)flow);
10944
10945 ArgusIsisHelloMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_dhost - (char *)flow);
10946 ArgusIsisLspMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_dhost - (char *)flow);
10947 ArgusIsisCsnpMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_dhost - (char *)flow);
10948 ArgusIsisPsnpMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_dhost - (char *)flow);
10949 ArgusIsisRevMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_shost - (char *)flow);
10950
10951 ArgusEtherMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_dhost - (char *)flow);
10952 ArgusEtherRevMaskDefs[i].offset = ((char *)&flow->mac_flow.mac_union.ether.ehdr.ether_shost - (char *)flow);
10953 break;
10954 }
10955 }
10956 }
10957
10958
10959 struct ArgusAggregatorStruct *
ArgusNewAggregator(struct ArgusParserStruct * parser,char * masklist,int type)10960 ArgusNewAggregator (struct ArgusParserStruct *parser, char *masklist, int type)
10961 {
10962 struct ArgusAggregatorStruct *retn = NULL;
10963 struct ArgusModeStruct *mode = NULL, *modelist = NULL, *list;
10964 char *mptr, *ptr, *tok;
10965 int i;
10966
10967 if ((retn = (struct ArgusAggregatorStruct *) ArgusCalloc (1, sizeof(*retn))) == NULL)
10968 ArgusLog (LOG_ERR, "ArgusNewAggregator: ArgusCalloc error %s", strerror(errno));
10969
10970 ArgusInitAggregatorStructs(retn);
10971
10972 retn->status = type;
10973
10974 if (masklist != NULL) {
10975 mptr = strdup(masklist);
10976 ptr = mptr;
10977 while ((tok = strtok (ptr, " \t")) != NULL) {
10978 if ((mode = (struct ArgusModeStruct *) ArgusCalloc (1, sizeof(struct ArgusModeStruct))) != NULL) {
10979 if ((list = modelist) != NULL) {
10980 while (list->nxt)
10981 list = list->nxt;
10982 list->nxt = mode;
10983 } else
10984 modelist = mode;
10985
10986 mode->mode = strdup(tok);
10987 }
10988 ptr = NULL;
10989 }
10990 free(mptr);
10991
10992 } else {
10993 if (parser->ArgusMaskList == NULL) {
10994 if (parser->RaMonMode) {
10995 retn->mask = ( ARGUS_MASK_SRCID_INDEX | ARGUS_MASK_PROTO_INDEX |
10996 ARGUS_MASK_SADDR_INDEX | ARGUS_MASK_SPORT_INDEX );
10997 } else {
10998 retn->mask = ( ARGUS_MASK_SRCID_INDEX | ARGUS_MASK_PROTO_INDEX |
10999 ARGUS_MASK_SADDR_INDEX | ARGUS_MASK_SPORT_INDEX |
11000 ARGUS_MASK_DADDR_INDEX | ARGUS_MASK_DPORT_INDEX );
11001 }
11002 }
11003
11004 modelist = parser->ArgusMaskList;
11005 }
11006
11007 if ((mode = modelist) != NULL) {
11008 while (mode) {
11009 char *ptr = NULL, *endptr = NULL;
11010 struct ArgusIPAddrStruct mask;
11011 char *sptr = strdup(mode->mode);
11012 int len = 0, x = 0, maskset = 0;
11013
11014 bzero((char *)&mask, sizeof(mask));
11015
11016 if ((ptr = strchr(sptr, '/')) != NULL) {
11017 *ptr++ = '\0';
11018 if (strchr(ptr, ':')) {
11019 if (!(inet_pton(AF_INET6, (const char *) ptr, &mask.addr_un.ipv6) > 0))
11020 ArgusLog (LOG_ERR, "syntax error: %s %s", ptr, strerror(errno));
11021 #if defined(_LITTLE_ENDIAN)
11022 for (x = 0 ; x < 4 ; x++)
11023 mask.addr_un.ipv6[x] = htonl(mask.addr_un.ipv6[x]);
11024 #endif
11025 len = 128;
11026 } else
11027 if (strchr(ptr, '.')) {
11028 if (!(inet_pton(AF_INET, (const char *) ptr, &mask.addr_un.ipv4) > 0))
11029 ArgusLog (LOG_ERR, "syntax error: %s %s", ptr, strerror(errno));
11030 #if defined(_LITTLE_ENDIAN)
11031 mask.addr_un.ipv4 = htonl(mask.addr_un.ipv4);
11032 #endif
11033 len = 32;
11034 } else {
11035 if ((len = strtol(ptr, &endptr, 10)) == 0)
11036 if (endptr == ptr)
11037 ArgusLog (LOG_ERR, "syntax error: %s %s", ptr, strerror(errno));
11038
11039 if (len <= 32)
11040 mask.addr_un.ipv4 = (0xFFFFFFFF << (32 - len));
11041 else {
11042 int tlen = len;
11043 x = 0;
11044 while (tlen) {
11045 if (tlen > 32) {
11046 mask.addr_un.ipv6[x] = 0xFFFFFFFF;;
11047 tlen -= 32;
11048 } else {
11049 mask.addr_un.ipv6[x] = htonl(0xFFFFFFFF << (32 - tlen));
11050 tlen = 0;
11051 }
11052 x++;
11053 }
11054 }
11055 }
11056 maskset = 1;
11057 }
11058
11059 if (!(strncasecmp (sptr, "none", 4))) {
11060 retn->mask = 0;
11061 } else
11062 if (!(strncasecmp (sptr, "macmatrix", 9))) {
11063 retn->ArgusMatrixMode++;
11064 retn->mask |= (0x01LL << ARGUS_MASK_SMAC);
11065 retn->mask |= (0x01LL << ARGUS_MASK_DMAC);
11066 if (len > 0) {
11067 retn->saddrlen = len;
11068 retn->daddrlen = len;
11069 }
11070 } else
11071 if (!(strncasecmp (sptr, "mac", 3))) {
11072 parser->RaMonMode++;
11073 retn->mask |= (0x01LL << ARGUS_MASK_SMAC);
11074 if (len > 0) {
11075 retn->saddrlen = len;
11076 }
11077 } else
11078 if (!(strncasecmp (sptr, "addr", 4))) {
11079 parser->RaMonMode++;
11080 retn->mask |= (0x01LL << ARGUS_MASK_SADDR);
11081 if (len > 0) {
11082 retn->saddrlen = len;
11083 bcopy((char *)&mask, (char *)&retn->smask, sizeof(mask));
11084 }
11085 } else
11086 if (!(strncasecmp (sptr, "port", 4))) {
11087 parser->RaMonMode++;
11088 retn->mask |= (0x01LL << ARGUS_MASK_SPORT);
11089 retn->mask |= (0x01LL << ARGUS_MASK_PROTO);
11090 } else
11091 if (!(strncasecmp (sptr, "matrix", 6))) {
11092 retn->ArgusMatrixMode++;
11093 retn->mask |= (0x01LL << ARGUS_MASK_SADDR);
11094 retn->mask |= (0x01LL << ARGUS_MASK_DADDR);
11095 if (len > 0) {
11096 retn->saddrlen = len;
11097 retn->daddrlen = len;
11098 bcopy((char *)&mask, (char *)&retn->smask, sizeof(mask));
11099 bcopy((char *)&mask, (char *)&retn->dmask, sizeof(mask));
11100 }
11101
11102 } else {
11103
11104 struct ArgusMaskStruct *ArgusMaskDefs = ArgusIpV4MaskDefs;
11105
11106 for (i = 0; i < ARGUS_MAX_MASK_LIST; i++) {
11107 if (!(strncasecmp (sptr, ArgusMaskDefs[i].name, ArgusMaskDefs[i].slen))) {
11108 retn->mask |= (0x01LL << i);
11109 switch (i) {
11110 case ARGUS_MASK_SADDR:
11111 if (len > 0) {
11112 retn->saddrlen = len;
11113 if (!maskset)
11114 mask.addr_un.ipv4 = (0xFFFFFFFF << (32 - len));
11115 bcopy((char *)&mask, (char *)&retn->smask, sizeof(mask));
11116 }
11117 break;
11118 case ARGUS_MASK_DADDR:
11119 if (len > 0) {
11120 retn->daddrlen = len;
11121 if (!maskset)
11122 mask.addr_un.ipv4 = (0xFFFFFFFF << (32 - len));
11123 bcopy((char *)&mask, (char *)&retn->dmask, sizeof(mask));
11124 }
11125 break;
11126
11127 case ARGUS_MASK_INODE:
11128 if (len > 0) {
11129 retn->iaddrlen = len;
11130 if (!maskset)
11131 mask.addr_un.ipv4 = (0xFFFFFFFF << (32 - len));
11132 bcopy((char *)&mask, (char *)&retn->imask, sizeof(mask));
11133 }
11134 break;
11135
11136 case ARGUS_MASK_SMPLS:
11137 case ARGUS_MASK_DMPLS: {
11138 int x, RaNewIndex = 0;
11139 char *ptr;
11140
11141 if ((ptr = strchr(sptr, '[')) != NULL) {
11142 char *cptr = NULL;
11143 int sind = -1, dind = -1;
11144 *ptr++ = '\0';
11145 while (*ptr != ']') {
11146 if (isdigit((int)*ptr)) {
11147 dind = strtol(ptr, (char **)&cptr, 10);
11148 if (cptr == ptr)
11149 usage ();
11150
11151 if (sind < 0)
11152 sind = dind;
11153
11154 for (x = sind; x <= dind; x++)
11155 RaNewIndex |= 0x01 << x;
11156
11157 ptr = cptr;
11158 if (*ptr != ']')
11159 ptr++;
11160 if (*cptr != '-')
11161 sind = -1;
11162 } else
11163 usage ();
11164 }
11165 ArgusIpV4MaskDefs[i].index = RaNewIndex;
11166 ArgusIpV6MaskDefs[i].index = RaNewIndex;
11167 ArgusEtherMaskDefs[i].index = RaNewIndex;
11168 }
11169 break;
11170 }
11171
11172 case ARGUS_MASK_SPORT:
11173 case ARGUS_MASK_DPORT:
11174 retn->mask |= (0x01LL << ARGUS_MASK_PROTO);
11175 break;
11176 }
11177 break;
11178 }
11179 }
11180 }
11181 free(sptr);
11182 mode = mode->nxt;
11183 }
11184
11185 retn->ArgusModeList = modelist;
11186 }
11187
11188 if (retn->mask == 0) {
11189 if ((retn->queue = ArgusNewQueue()) == NULL)
11190 ArgusLog (LOG_ERR, "ArgusNewAggregator: ArgusNewQueue error %s", strerror(errno));
11191
11192 if (retn->correct != NULL)
11193 free (retn->correct);
11194
11195 parser->ArgusPerformCorrection = 0;
11196
11197 } else {
11198 if ((retn->drap = (struct RaPolicyStruct *) ArgusCalloc(1, sizeof(*retn->drap))) == NULL)
11199 ArgusLog (LOG_ERR, "ArgusNewAggregator: ArgusCalloc error %s", strerror(errno));
11200
11201 if ((retn->queue = ArgusNewQueue()) == NULL)
11202 ArgusLog (LOG_ERR, "ArgusNewAggregator: ArgusNewQueue error %s", strerror(errno));
11203
11204 if ((retn->htable = ArgusNewHashTable (RA_HASHTABLESIZE)) == NULL)
11205 ArgusLog (LOG_ERR, "ArgusNewAggregator: ArgusNewHashTable error %s", strerror(errno));
11206
11207 retn->RaMetricFetchAlgorithm = ArgusFetchDuration;
11208 retn->ArgusMetricIndex = ARGUSMETRICDURATION;
11209
11210 #define ARGUS_STANDARD_MASK (ARGUS_MASK_PROTO_INDEX | ARGUS_MASK_SADDR_INDEX | ARGUS_MASK_SPORT_INDEX | ARGUS_MASK_DADDR_INDEX | ARGUS_MASK_DPORT_INDEX)
11211
11212 if ((retn->mask & ARGUS_STANDARD_MASK) != ARGUS_STANDARD_MASK)
11213 parser->ArgusPerformCorrection = 0;
11214 }
11215
11216 return (retn);
11217 }
11218
11219
11220 struct ArgusAggregatorStruct *
ArgusCopyAggregator(struct ArgusAggregatorStruct * agg)11221 ArgusCopyAggregator (struct ArgusAggregatorStruct *agg)
11222 {
11223 struct ArgusAggregatorStruct *retn = NULL, *tagg = NULL, *pagg = NULL;
11224
11225 while (agg != NULL) {
11226 if ((tagg = (struct ArgusAggregatorStruct *) ArgusMalloc (sizeof(*tagg))) == NULL)
11227 ArgusLog (LOG_ERR, "ArgusCopyAggregator: ArgusMalloc error %s", strerror(errno));
11228
11229 bcopy(agg, tagg, sizeof(*agg));
11230 tagg->nxt = NULL;
11231
11232 if (agg->name != NULL) tagg->name = strdup(agg->name);
11233 if (agg->pres != NULL) tagg->pres = strdup(agg->pres);
11234 if (agg->report != NULL) tagg->report = strdup(agg->report);
11235 if (agg->correct != NULL) tagg->correct = strdup(agg->correct);
11236 if (agg->modeStr != NULL) tagg->modeStr = strdup(agg->modeStr);
11237
11238 if (agg->argus != NULL) tagg->argus = NULL;
11239
11240 bzero(&agg->hstruct, sizeof(agg->hstruct));
11241
11242 if (agg->drap != NULL) {
11243 if ((tagg->drap = (void *) ArgusCalloc (1, sizeof(*tagg->drap))) == NULL)
11244 ArgusLog (LOG_ERR, "ArgusCopyAggregator: ArgusCalloc error %s", strerror(errno));
11245 bcopy(agg->drap, tagg->drap, sizeof(*agg->drap));
11246 }
11247
11248 if (agg->rap != NULL) {
11249 if ((tagg->rap = (void *) ArgusCalloc (1, sizeof(*tagg->rap))) == NULL)
11250 ArgusLog (LOG_ERR, "ArgusCopyAggregator: ArgusCalloc error %s", strerror(errno));
11251 bcopy(agg->rap, tagg->rap, sizeof(*agg->rap));
11252 }
11253
11254 tagg->ArgusModeList = NULL;
11255 {
11256 struct ArgusModeStruct *mode = NULL;
11257
11258 if ((mode = agg->ArgusModeList) != NULL) {
11259 struct ArgusModeStruct *tmode, *prv = NULL;
11260 while (mode) {
11261 if ((tmode = (struct ArgusModeStruct *) ArgusCalloc (1, sizeof(struct ArgusModeStruct))) == NULL)
11262 ArgusLog (LOG_ERR, "ArgusCopyAggregator: ArgusCalloc error %s", strerror(errno));
11263
11264 if (tagg->ArgusModeList == NULL)
11265 tagg->ArgusModeList = tmode;
11266
11267 tmode->mode = strdup(mode->mode);
11268 if (prv != NULL) prv->nxt = tmode;
11269 prv = tmode;
11270
11271 mode = mode->nxt;
11272 }
11273 }
11274 }
11275
11276 tagg->ArgusMaskList = NULL;
11277 {
11278 struct ArgusModeStruct *mode = NULL;
11279
11280 if ((mode = agg->ArgusMaskList) != NULL) {
11281 struct ArgusModeStruct *tmode, *prv = NULL;
11282 while (mode) {
11283 if ((tmode = (struct ArgusModeStruct *) ArgusCalloc (1, sizeof(struct ArgusModeStruct))) == NULL)
11284 ArgusLog (LOG_ERR, "ArgusCopyAggregator: ArgusCalloc error %s", strerror(errno));
11285
11286 if (tagg->ArgusMaskList == NULL)
11287 tagg->ArgusMaskList = tmode;
11288
11289 tmode->mode = strdup(mode->mode);
11290 if (prv != NULL) prv->nxt = tmode;
11291 prv = tmode;
11292
11293 mode = mode->nxt;
11294 }
11295 }
11296 }
11297
11298 if ((tagg->queue = ArgusNewQueue()) == NULL)
11299 ArgusLog (LOG_ERR, "ArgusNewAggregator: ArgusNewQueue error %s", strerror(errno));
11300
11301 if ((tagg->htable = ArgusNewHashTable (RA_HASHTABLESIZE)) == NULL)
11302 ArgusLog (LOG_ERR, "ArgusNewAggregator: ArgusNewHashTable error %s", strerror(errno));
11303
11304 if (agg->filterstr != NULL) {
11305 tagg->filterstr = strdup(agg->filterstr);
11306 if (agg->filter.bf_insns != NULL) {
11307 tagg->filter.bf_insns = calloc(sizeof(*agg->filter.bf_insns), agg->filter.bf_len);
11308 bcopy(agg->filter.bf_insns, tagg->filter.bf_insns, sizeof(*agg->filter.bf_insns) * agg->filter.bf_len);
11309 }
11310 }
11311
11312 if (agg->modelstr != NULL) tagg->modelstr = strdup(agg->modelstr);
11313 if (agg->grepstr != NULL) tagg->grepstr = strdup(agg->grepstr);
11314 if (agg->labelstr != NULL) tagg->labelstr = strdup(agg->labelstr);
11315 if (agg->estr != NULL) tagg->estr = strdup(agg->estr);
11316
11317 tagg->RaMetricFetchAlgorithm = agg->RaMetricFetchAlgorithm;
11318
11319 if (retn == NULL)
11320 retn = tagg;
11321
11322 if (pagg != NULL)
11323 pagg->nxt = tagg;
11324
11325 agg = agg->nxt;
11326 pagg = tagg;
11327 }
11328 return retn;
11329 }
11330
11331
11332 void
ArgusDeleteAggregator(struct ArgusParserStruct * parser,struct ArgusAggregatorStruct * agg)11333 ArgusDeleteAggregator (struct ArgusParserStruct *parser, struct ArgusAggregatorStruct *agg)
11334 {
11335 struct ArgusModeStruct *mode = NULL, *prv;
11336
11337 if (agg->nxt != NULL) {
11338 ArgusDeleteAggregator (parser, agg->nxt);
11339 agg->nxt = NULL;
11340 }
11341
11342 if (agg->correct != NULL)
11343 free(agg->correct);
11344
11345 if (agg->pres != NULL)
11346 free(agg->pres);
11347
11348 if (agg->hstruct.buf != NULL)
11349 ArgusFree(agg->hstruct.buf);
11350
11351 if (agg->drap != NULL)
11352 ArgusFree(agg->drap);
11353
11354 if (agg->queue && agg->queue->count) {
11355 switch (agg->status & ( ARGUS_RECORD_AGGREGATOR | ARGUS_OBJ_AGGREGATOR)) {
11356 default:
11357 case ARGUS_RECORD_AGGREGATOR: {
11358 struct ArgusRecordStruct *argus;
11359 while ((argus = (struct ArgusRecordStruct *) ArgusPopQueue (agg->queue, ARGUS_LOCK)) != NULL)
11360 ArgusDeleteRecordStruct(ArgusParser, argus);
11361 break;
11362 }
11363
11364 case ARGUS_OBJ_AGGREGATOR: {
11365 struct ArgusObjectStruct *obj;
11366 while ((obj = (struct ArgusObjectStruct *) ArgusPopQueue (agg->queue, ARGUS_LOCK)) != NULL)
11367 ArgusFree(obj);
11368 break;
11369 }
11370 }
11371 }
11372
11373 if ((mode = agg->ArgusModeList) != NULL) {
11374 if (mode != parser->ArgusMaskList) {
11375 while ((prv = mode) != NULL) {
11376 if (mode->mode != NULL)
11377 free (mode->mode);
11378 mode = mode->nxt;
11379 ArgusFree(prv);
11380 }
11381 }
11382 }
11383
11384 if (agg->queue != NULL)
11385 ArgusDeleteQueue(agg->queue);
11386
11387 if (agg->htable != NULL)
11388 ArgusDeleteHashTable(agg->htable);
11389
11390 if (agg->modelstr)
11391 free(agg->modelstr);
11392
11393 if (agg->filterstr) {
11394 free(agg->filterstr);
11395 if (agg->filter.bf_insns != NULL)
11396 free(agg->filter.bf_insns);
11397 }
11398
11399 if (parser->ArgusAggregator == agg)
11400 parser->ArgusAggregator = NULL;
11401
11402 ArgusFree(agg);
11403
11404 #ifdef ARGUSDEBUG
11405 ArgusDebug (2, "ArgusDeleteAggregator(%p, %p) returned\n", parser, agg);
11406 #endif
11407 }
11408
11409
11410 #define ARGUS_RCITEMS 7
11411
11412 #define ARGUS_RC_FILTER 0
11413 #define ARGUS_RC_GREP 1
11414 #define ARGUS_RC_MODEL 2
11415 #define ARGUS_RC_STATUS 3
11416 #define ARGUS_RC_IDLE 4
11417 #define ARGUS_RC_LABEL 5
11418 #define ARGUS_RC_CONT 6
11419
11420 char *ArgusAggregatorFields[ARGUS_RCITEMS] = {
11421 "filter", "grep", "model", "status", "idle", "label", "cont",
11422 };
11423
11424 struct ArgusAggregatorStruct *
ArgusParseAggregator(struct ArgusParserStruct * parser,char * file,char * buf[])11425 ArgusParseAggregator (struct ArgusParserStruct *parser, char *file, char *buf[])
11426 {
11427 struct ArgusAggregatorStruct *retn = NULL, *agg;
11428 char strbuf[MAXSTRLEN], *sptr = strbuf;
11429 char *name = NULL, *pres = NULL;
11430 char *report = NULL, *correct = NULL;
11431 char *histo = NULL, *metric = NULL;
11432 char *ptr, *end, tmp;
11433 int i, tlines = 0;
11434 FILE *fd = NULL;
11435
11436 if ((buf == NULL) && (file == NULL))
11437 return NULL;
11438
11439 if (buf == NULL) {
11440 if ((fd = fopen (file, "r")) == NULL)
11441 ArgusLog (LOG_ERR, "%s: %s", file, strerror(errno));
11442 }
11443
11444 // Here we're either reading from a file or a buffer. Treat the strings the same.
11445 // Because we modify the strings, lets get a copy to work with, and free it up later.
11446
11447 while ((fd ? (sptr = fgets(strbuf, MAXSTRLEN, fd)) : (sptr = ((*buf != NULL) ? *buf++ : *buf))) != NULL) {
11448 char *pstr = strdup(sptr), *str = pstr;
11449 int done = 0, defined = 0;
11450 tlines++;
11451
11452 while (*str && isspace((int)*str)) str++;
11453 ptr = str;
11454
11455 if (*str && (*str != '#') && (*str != '\n') && (*str != '"') && (*str != '!')) {
11456 char *filter = NULL, *grep = NULL, *model = NULL, *label = NULL;
11457 char *status = NULL, *idle = NULL, *cptr = NULL;
11458 int cont = 0;
11459 while (!done) {
11460 if (!(strncmp(str, RA_MODELNAMETAGSTR, strlen(RA_MODELNAMETAGSTR)))) {
11461 name = strdup(&str[strlen(RA_MODELNAMETAGSTR)]);
11462 done++;
11463 } else
11464 if (!(strncmp(str, RA_PRESERVETAGSTR, strlen(RA_PRESERVETAGSTR)))) {
11465 pres = strdup(&str[strlen(RA_PRESERVETAGSTR)]);
11466 done++;
11467 } else
11468 if (!(strncmp(str, RA_REPORTTAGSTR, strlen(RA_REPORTTAGSTR)))) {
11469 report = strdup(&str[strlen(RA_REPORTTAGSTR)]);
11470 done++;
11471 } else
11472 if (!(strncmp(str, RA_AUTOCORRECTSTR, strlen(RA_AUTOCORRECTSTR)))) {
11473 correct = strdup(&str[strlen(RA_AUTOCORRECTSTR)]);
11474 if (!(strstr(correct, "yes"))) {
11475 free(correct);
11476 correct = NULL;
11477 }
11478 done++;
11479 } else
11480 if (!(strncmp(str, RA_HISTOGRAM, strlen(RA_HISTOGRAM)))) {
11481 histo = strdup(&str[strlen(RA_HISTOGRAM)]);
11482 done++;
11483 } else
11484 if (!(strncmp(str, RA_AGGMETRIC, strlen(RA_AGGMETRIC)))) {
11485 ptr = str + strlen(RA_AGGMETRIC);
11486 while (*ptr && (isspace((int)*ptr) || ispunct((int)*ptr))) ptr++;
11487 str = &ptr[strlen(ptr) - 1];
11488 while (*str && (isspace((int)*str) || ispunct((int)*str))) { *str = '\0'; str--;}
11489 metric = strdup(ptr);
11490 done++;
11491 } else
11492 for (i = 0; i < ARGUS_RCITEMS; i++) {
11493 if (!(strncmp(str, ArgusAggregatorFields[i], strlen(ArgusAggregatorFields[i])))) {
11494 char *value = NULL;
11495 ptr = str + strlen(ArgusAggregatorFields[i]);
11496 while (*ptr && isspace((int)*ptr)) ptr++;
11497
11498 if (!(*ptr == '=') && (i != ARGUS_RC_CONT))
11499 ArgusLog (LOG_ERR, "ArgusParseAggregator: syntax error line %d %s", tlines, str);
11500
11501 defined++;
11502
11503 ptr++;
11504 while (*ptr && isspace((int)*ptr)) ptr++;
11505
11506 switch (i) {
11507 case ARGUS_RC_FILTER:
11508 case ARGUS_RC_GREP:
11509 case ARGUS_RC_LABEL:
11510 case ARGUS_RC_MODEL: {
11511 if (*ptr == '\"') {
11512 ptr++;
11513 end = ptr;
11514 while (*end != '\"') end++;
11515 *end++ = '\0';
11516
11517 value = strdup(ptr);
11518 ptr = end;
11519 }
11520 break;
11521 }
11522
11523 case ARGUS_RC_STATUS:
11524 case ARGUS_RC_IDLE: {
11525 strtol(ptr, (char **)&end, 10);
11526 if (end == ptr)
11527 ArgusLog (LOG_ERR, "ArgusParseAggregator: syntax error line %d %s", tlines, str);
11528
11529 switch (*end) {
11530 case 's':
11531 case 'm':
11532 case 'h':
11533 case 'd':
11534 end++; break;
11535 }
11536 tmp = *end;
11537 *end = '\0';
11538 value = strdup(ptr);
11539 ptr = end;
11540 *ptr = tmp;
11541 break;
11542 }
11543 }
11544
11545 switch (i) {
11546 case ARGUS_RC_FILTER: filter = value; value = NULL; break;
11547 case ARGUS_RC_GREP: grep = value; value = NULL; break;
11548 case ARGUS_RC_MODEL: model = value; value = NULL; break;
11549 case ARGUS_RC_STATUS: status = value; value = NULL; break;
11550 case ARGUS_RC_IDLE: idle = value; value = NULL; break;
11551 case ARGUS_RC_LABEL: label = value; value = NULL; break;
11552 case ARGUS_RC_CONT: {
11553 cont++;
11554 done++;
11555 }
11556 default:
11557 if (value != NULL) {
11558 free (value);
11559 value = NULL;
11560 }
11561 break;
11562 }
11563
11564 while (*ptr && isspace((int)*ptr)) ptr++;
11565 str = ptr;
11566 }
11567 }
11568
11569 if (!(done || defined))
11570 ArgusLog (LOG_ERR, "ArgusParseAggregator: syntax error line %d: %s", tlines, str);
11571
11572 if (ptr && ((*ptr == '\n') || (*ptr == '\0')))
11573 done++;
11574 }
11575
11576 if (defined) {
11577 if ((agg = ArgusNewAggregator(parser, model, ARGUS_RECORD_AGGREGATOR)) == NULL)
11578 ArgusLog (LOG_ERR, "ArgusParseAggregator: ArgusNewAggregator returned NULL");
11579
11580 if (cont)
11581 agg->cont++;
11582
11583 if (name)
11584 agg->name = name;
11585
11586 if (pres) {
11587 if (!(strncasecmp(pres, "no", 2)))
11588 agg->pres = NULL;
11589 else
11590 agg->pres = strdup("yes");
11591
11592 free(pres);
11593 pres = NULL;
11594 }
11595
11596 if (histo) {
11597 free (histo);
11598 histo = NULL;
11599 }
11600
11601 if (report)
11602 agg->report = report;
11603
11604 if (correct)
11605 agg->correct = strdup(correct);
11606
11607 if (metric) {
11608 int x, found = 0;
11609 for (x = 0; (x < MAX_METRIC_ALG_TYPES) && (!(found)); x++) {
11610 struct ArgusFetchValueStruct *fetch = &RaFetchAlgorithmTable[x];
11611
11612 if (!strncmp (fetch->field, metric, strlen(metric))) {
11613 agg->RaMetricFetchAlgorithm = fetch->fetch;
11614 agg->ArgusMetricIndex = x;
11615 found++;
11616 break;
11617 }
11618 }
11619 if (!found)
11620 ArgusLog (LOG_ERR, "ArgusNewAggregator RA_AGG_METRIC %s not found", metric);
11621 }
11622
11623 if (filter) {
11624 if (strlen(filter)) {
11625 agg->filterstr = filter;
11626 filter = NULL;
11627 if (ArgusFilterCompile (&agg->filter, agg->filterstr, ArgusParser->Oflag) < 0)
11628 ArgusLog (LOG_ERR, "ArgusNewAggregator ArgusFilterCompile returned error");
11629 }
11630 }
11631
11632 if (model) {
11633 if (strlen(model)) {
11634 agg->modelstr = model;
11635 model = NULL;
11636 }
11637 }
11638
11639 if (grep) {
11640 int options;
11641 int rege;
11642
11643 #if defined(ARGUS_PCRE)
11644 options = 0;
11645 #else
11646 options = REG_EXTENDED | REG_NOSUB;
11647 #if defined(REG_ENHANCED)
11648 options |= REG_ENHANCED;
11649 #endif
11650 #endif
11651 if (parser->iflag)
11652 options |= REG_ICASE;
11653
11654 agg->grepstr = grep;
11655
11656 if ((rege = regcomp(&agg->lpreg, grep, options)) != 0) {
11657 char errbuf[MAXSTRLEN];
11658 if (regerror(rege, &parser->lpreg, errbuf, MAXSTRLEN))
11659 ArgusLog (LOG_ERR, "ArgusProcessLabelOption: grep regex error %s", errbuf);
11660 }
11661 }
11662
11663 if (status) {
11664 agg->statusint = strtol(status, (char **)&cptr, 10);
11665 switch(*cptr) {
11666 case 'm': agg->statusint *= 60; break;
11667 case 'h': agg->statusint *= 3600; break;
11668 case 'd': agg->statusint *= 86400; break;
11669 }
11670 }
11671 if (idle) {
11672 agg->idleint = strtol(idle, (char **)&cptr, 10);
11673 switch(*cptr) {
11674 case 'm': agg->idleint *= 60; break;
11675 case 'h': agg->idleint *= 3600; break;
11676 case 'd': agg->idleint *= 86400; break;
11677 }
11678 }
11679
11680 if (label) {
11681 if (strlen(label)) {
11682 agg->labelstr = label;
11683 label = NULL;
11684 }
11685 }
11686
11687 if (retn != NULL) {
11688 struct ArgusAggregatorStruct *tagg = retn;
11689 while (tagg->nxt != NULL)
11690 tagg = tagg->nxt;
11691 tagg->nxt = agg;
11692 } else
11693 retn = agg;
11694
11695 } else {
11696 if (!done)
11697 ArgusLog (LOG_ERR, "ArgusNewAggregator: line %d, syntax error %s", tlines, str);
11698 }
11699
11700 if (filter != NULL) { free (filter); filter = NULL; }
11701 if (grep != NULL) { free (grep); grep = NULL; }
11702 if (model != NULL) { free (model); model = NULL; }
11703 if (status != NULL) { free (status); status = NULL; }
11704 if (idle != NULL) { free (idle); idle = NULL; }
11705 }
11706
11707 if (pstr != NULL) {
11708 free(pstr);
11709 pstr = NULL;
11710 }
11711 }
11712
11713 if (fd != NULL) fclose(fd);
11714
11715 if ((agg = ArgusNewAggregator(parser, NULL, ARGUS_RECORD_AGGREGATOR)) == NULL)
11716 ArgusLog (LOG_ERR, "ArgusClientInit: ArgusNewAggregator error");
11717
11718 if (name)
11719 agg->name = name;
11720
11721 if (pres) {
11722 if (!(strncasecmp(pres, "no", 2)))
11723 agg->pres = NULL;
11724 else
11725 agg->pres = strdup("yes");
11726 }
11727
11728 if (report)
11729 agg->report = report;
11730
11731 if (correct) {
11732 agg->correct = strdup(correct);
11733 free(correct);
11734 correct = NULL;
11735 }
11736
11737 if (metric) {
11738 int x, found = 0;
11739 for (x = 0; (x < MAX_METRIC_ALG_TYPES) && (!(found)); x++) {
11740 struct ArgusFetchValueStruct *fetch = &RaFetchAlgorithmTable[x];
11741
11742 if (!strncmp (fetch->field, metric, strlen(metric))) {
11743 agg->RaMetricFetchAlgorithm = fetch->fetch;
11744 agg->ArgusMetricIndex = x;
11745 found++;
11746 break;
11747 }
11748 }
11749 if (!found)
11750 ArgusLog (LOG_ERR, "ArgusNewAggregator RA_AGG_METRIC %s not found", metric);
11751 }
11752
11753 if (retn != NULL) {
11754 struct ArgusAggregatorStruct *tagg = retn;
11755 while (tagg->nxt != NULL)
11756 tagg = tagg->nxt;
11757 tagg->nxt = agg;
11758 } else
11759 retn = agg;
11760
11761 return (retn);
11762 }
11763
11764
11765 int
RaParseType(char * str)11766 RaParseType (char *str)
11767 {
11768 return(argus_nametoeproto(str));
11769 }
11770
11771
11772
11773 double
ArgusFetchSrcId(struct ArgusRecordStruct * ns)11774 ArgusFetchSrcId (struct ArgusRecordStruct *ns)
11775 {
11776 double retn = 0;
11777
11778 struct ArgusTransportStruct *t = (struct ArgusTransportStruct *)ns->dsrs[ARGUS_TRANSPORT_INDEX];
11779 // int len;
11780
11781 if (t) {
11782 if (t->hdr.subtype & ARGUS_SRCID) {
11783 retn = t->srcid.a_un.value;
11784 /*
11785 switch (t->hdr.argus_dsrvl8.qual) {
11786 case ARGUS_TYPE_INT: len = 1; break;
11787 case ARGUS_TYPE_IPV4: len = 1; break;
11788 case ARGUS_TYPE_IPV6: len = 4; break;
11789 case ARGUS_TYPE_ETHER: len = 6; break;
11790 case ARGUS_TYPE_STRING: len = t->hdr.argus_dsrvl8.len - 2;
11791 }
11792 */
11793 }
11794 }
11795
11796 return (retn);
11797 }
11798
11799 long long
ArgusFetchStartuSecTime(struct ArgusRecordStruct * ns)11800 ArgusFetchStartuSecTime (struct ArgusRecordStruct *ns)
11801 {
11802 long long retn = 0;
11803 long long sec = 0, usec = 0;
11804
11805 switch (ns->hdr.type & 0xF0) {
11806 case ARGUS_MAR: {
11807 struct ArgusRecord *rec = (struct ArgusRecord *) ns->dsrs[0];
11808 if (rec != NULL) {
11809 sec = rec->argus_mar.now.tv_sec;
11810 usec = rec->argus_mar.now.tv_usec;
11811 }
11812 break;
11813 }
11814
11815 case ARGUS_EVENT: {
11816 struct ArgusTimeObject *time = (void *)ns->dsrs[ARGUS_TIME_INDEX];
11817 if (time != NULL) {
11818 sec = time->src.start.tv_sec;
11819 usec = time->src.start.tv_usec;
11820 }
11821 break;
11822 }
11823
11824 case ARGUS_NETFLOW:
11825 case ARGUS_FAR: {
11826 struct ArgusTimeObject *dtime = (void *)ns->dsrs[ARGUS_TIME_INDEX];
11827
11828 if (dtime != NULL) {
11829 unsigned int subtype = dtime->hdr.subtype & (ARGUS_TIME_SRC_START | ARGUS_TIME_DST_START);
11830 struct timeval stimebuf, *st = &stimebuf;
11831 struct timeval etimebuf, *et = &etimebuf;
11832 struct timeval *stime = NULL;
11833
11834 if (subtype) {
11835 switch (subtype) {
11836 case ARGUS_TIME_SRC_START | ARGUS_TIME_DST_START: {
11837 st->tv_sec = dtime->src.start.tv_sec;
11838 st->tv_usec = dtime->src.start.tv_usec;
11839 et->tv_sec = dtime->dst.start.tv_sec;
11840 et->tv_usec = dtime->dst.start.tv_usec;
11841
11842 if ((st->tv_sec > 0) && (et->tv_sec > 0)) {
11843 stime = RaMinTime(st, et);
11844 } else {
11845 stime = (st->tv_sec > 0) ? st : et;
11846 }
11847 break;
11848 }
11849
11850 case ARGUS_TIME_SRC_START: {
11851 st->tv_sec = dtime->src.start.tv_sec;
11852 st->tv_usec = dtime->src.start.tv_usec;
11853 stime = st;
11854 break;
11855 }
11856
11857 case ARGUS_TIME_DST_START: {
11858 st->tv_sec = dtime->dst.start.tv_sec;
11859 st->tv_usec = dtime->dst.start.tv_usec;
11860 stime = st;
11861 break;
11862 }
11863 }
11864
11865 } else {
11866 st->tv_sec = dtime->src.start.tv_sec;
11867 st->tv_usec = dtime->src.start.tv_usec;
11868 et->tv_sec = dtime->dst.start.tv_sec;
11869 et->tv_usec = dtime->dst.start.tv_usec;
11870
11871 if ((st->tv_sec > 0) && (et->tv_sec > 0)) {
11872 stime = RaMinTime(st, et);
11873 } else {
11874 stime = (st->tv_sec > 0) ? st : et;
11875 }
11876 }
11877
11878 sec = stime->tv_sec;
11879 usec = stime->tv_usec;
11880 }
11881 break;
11882 }
11883 }
11884
11885 retn = (sec * 1000000LL) + usec;
11886 return(retn);
11887 }
11888
11889 double
ArgusFetchStartTime(struct ArgusRecordStruct * ns)11890 ArgusFetchStartTime (struct ArgusRecordStruct *ns)
11891 {
11892 double retn = ArgusFetchStartuSecTime(ns) / 1000000.0;
11893 return (retn);
11894 }
11895
11896
11897 long long
ArgusFetchLastuSecTime(struct ArgusRecordStruct * ns)11898 ArgusFetchLastuSecTime (struct ArgusRecordStruct *ns)
11899 {
11900 long long retn = 0;
11901 long long sec = 0, usec = 0;
11902
11903 if (ns->hdr.type & ARGUS_MAR) {
11904 struct ArgusRecord *rec = (struct ArgusRecord *) ns->dsrs[0];
11905 if (rec != NULL) {
11906 sec = rec->argus_mar.now.tv_sec;
11907 usec = rec->argus_mar.now.tv_usec;
11908 }
11909
11910 } else {
11911 struct ArgusTimeObject *dtime = (void *)ns->dsrs[ARGUS_TIME_INDEX];
11912
11913 if (dtime != NULL) {
11914 unsigned int subtype = dtime->hdr.subtype & (ARGUS_TIME_SRC_END | ARGUS_TIME_DST_END);
11915 struct timeval stimebuf, *st = &stimebuf;
11916 struct timeval etimebuf, *et = &etimebuf;
11917 struct timeval *stime = NULL;
11918
11919 if (subtype) {
11920 switch (subtype) {
11921 case ARGUS_TIME_SRC_END | ARGUS_TIME_DST_END: {
11922 st->tv_sec = dtime->src.end.tv_sec;
11923 st->tv_usec = dtime->src.end.tv_usec;
11924 et->tv_sec = dtime->dst.end.tv_sec;
11925 et->tv_usec = dtime->dst.end.tv_usec;
11926
11927 stime = RaMaxTime(st, et);
11928 break;
11929 }
11930
11931 case ARGUS_TIME_SRC_END: {
11932 st->tv_sec = dtime->src.end.tv_sec;
11933 st->tv_usec = dtime->src.end.tv_usec;
11934 stime = st;
11935 break;
11936 }
11937
11938 case ARGUS_TIME_DST_END: {
11939 st->tv_sec = dtime->dst.end.tv_sec;
11940 st->tv_usec = dtime->dst.end.tv_usec;
11941 stime = st;
11942 break;
11943 }
11944 }
11945
11946 } else {
11947 st->tv_sec = dtime->src.end.tv_sec;
11948 st->tv_usec = dtime->src.end.tv_usec;
11949 et->tv_sec = dtime->dst.end.tv_sec;
11950 et->tv_usec = dtime->dst.end.tv_usec;
11951
11952 stime = RaMaxTime(st, et);
11953 }
11954
11955 sec = stime->tv_sec;
11956 usec = stime->tv_usec;
11957 }
11958 }
11959
11960 retn = (sec * 1000000LL) + usec;
11961 return(retn);
11962 }
11963
11964 double
ArgusFetchLastTime(struct ArgusRecordStruct * ns)11965 ArgusFetchLastTime (struct ArgusRecordStruct *ns)
11966 {
11967 double retn = ArgusFetchLastuSecTime(ns) / 1000000.0;
11968 return (retn);
11969 }
11970
11971 double
ArgusFetchMean(struct ArgusRecordStruct * ns)11972 ArgusFetchMean (struct ArgusRecordStruct *ns)
11973 {
11974 double retn = 0;
11975
11976 if (ns->hdr.type & ARGUS_MAR) {
11977 } else {
11978 struct ArgusAgrStruct *agr;
11979
11980 if ((agr = (struct ArgusAgrStruct *) ns->dsrs[ARGUS_AGR_INDEX]) != NULL)
11981 retn = agr->act.meanval;
11982 }
11983 return retn;
11984 }
11985
11986 double
ArgusFetchMin(struct ArgusRecordStruct * ns)11987 ArgusFetchMin (struct ArgusRecordStruct *ns)
11988 {
11989 double retn = 0;
11990
11991 if (ns->hdr.type & ARGUS_MAR) {
11992 } else {
11993 struct ArgusAgrStruct *agr;
11994
11995 if ((agr = (struct ArgusAgrStruct *) ns->dsrs[ARGUS_AGR_INDEX]) != NULL)
11996 retn = agr->act.minval;
11997 }
11998 return retn;
11999 }
12000
12001 double
ArgusFetchMax(struct ArgusRecordStruct * ns)12002 ArgusFetchMax (struct ArgusRecordStruct *ns)
12003 {
12004 double retn = 0;
12005
12006 if (ns->hdr.type & ARGUS_MAR) {
12007 } else {
12008 struct ArgusAgrStruct *agr;
12009
12010 if ((agr = (struct ArgusAgrStruct *) ns->dsrs[ARGUS_AGR_INDEX]) != NULL)
12011 retn = agr->act.maxval;
12012 }
12013 return (retn);
12014 }
12015
12016
12017 double
ArgusFetchAvgDuration(struct ArgusRecordStruct * ns)12018 ArgusFetchAvgDuration (struct ArgusRecordStruct *ns)
12019 {
12020 double retn = 0;
12021
12022 if (ns->hdr.type & ARGUS_MAR) {
12023 } else {
12024 struct ArgusAgrStruct *agr;
12025
12026 if ((agr = (struct ArgusAgrStruct *) ns->dsrs[ARGUS_AGR_INDEX]) != NULL)
12027 retn = agr->act.meanval;
12028 else
12029 retn = RaGetFloatDuration (ns);
12030 }
12031 return retn;
12032 }
12033
12034 double
ArgusFetchMinDuration(struct ArgusRecordStruct * ns)12035 ArgusFetchMinDuration (struct ArgusRecordStruct *ns)
12036 {
12037 double retn = 0;
12038
12039 if (ns->hdr.type & ARGUS_MAR) {
12040 } else {
12041 struct ArgusAgrStruct *agr;
12042
12043 if ((agr = (struct ArgusAgrStruct *) ns->dsrs[ARGUS_AGR_INDEX]) != NULL)
12044 retn = agr->act.minval;
12045 else
12046 retn = RaGetFloatDuration (ns);
12047 }
12048 return retn;
12049 }
12050
12051 double
ArgusFetchMaxDuration(struct ArgusRecordStruct * ns)12052 ArgusFetchMaxDuration (struct ArgusRecordStruct *ns)
12053 {
12054 double retn = 0;
12055
12056 if (ns->hdr.type & ARGUS_MAR) {
12057 } else {
12058 struct ArgusAgrStruct *agr;
12059
12060 if ((agr = (struct ArgusAgrStruct *) ns->dsrs[ARGUS_AGR_INDEX]) != NULL)
12061 retn = agr->act.maxval;
12062 else
12063 retn = RaGetFloatDuration (ns);
12064 }
12065 return (retn);
12066 }
12067
12068 double
ArgusFetchuSecDuration(struct ArgusRecordStruct * ns)12069 ArgusFetchuSecDuration (struct ArgusRecordStruct *ns)
12070 {
12071 float dur = RaGetuSecDuration(ns);
12072 double retn = dur;
12073 return (retn);
12074 }
12075
12076
12077 double
ArgusFetchDuration(struct ArgusRecordStruct * ns)12078 ArgusFetchDuration (struct ArgusRecordStruct *ns)
12079 {
12080 float dur = RaGetFloatDuration(ns);
12081 double retn = dur;
12082 return (retn);
12083 }
12084
12085 double
ArgusFetchSrcDuration(struct ArgusRecordStruct * ns)12086 ArgusFetchSrcDuration (struct ArgusRecordStruct *ns)
12087 {
12088 float dur = RaGetFloatDuration(ns);
12089 double retn = dur;
12090 return (retn);
12091 }
12092
12093 double
ArgusFetchDstDuration(struct ArgusRecordStruct * ns)12094 ArgusFetchDstDuration (struct ArgusRecordStruct *ns)
12095 {
12096 float dur = RaGetFloatDuration(ns);
12097 double retn = dur;
12098 return (retn);
12099 }
12100
12101 #if !defined(ntohll)
12102 #if defined(_LITTLE_ENDIAN)
12103 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__sun__)
12104 #include <argus/extract.h>
12105 #define ntohll(x) EXTRACT_64BITS(&x)
12106 #define htonll(x) EXTRACT_64BITS(&x)
12107 #else
12108 #include <byteswap.h>
12109 #define ntohll(x) bswap_64(x)
12110 #define htonll(x) bswap_64(x)
12111 #endif
12112 #else
12113 #define ntohll(x) x
12114 #define htonll(x) x
12115 #endif
12116 #endif
12117
12118
12119 double
ArgusFetchSrcMac(struct ArgusRecordStruct * ns)12120 ArgusFetchSrcMac (struct ArgusRecordStruct *ns)
12121 {
12122 struct ArgusMacStruct *m = (struct ArgusMacStruct *) ns->dsrs[ARGUS_MAC_INDEX];
12123 unsigned long long value = 0;
12124 double retn = 0;
12125
12126 if (m != NULL) {
12127 bcopy ((char *)&m->mac.mac_union.ether.ehdr.ether_shost, (char *)&value, ETH_ALEN);
12128 retn = ntohll(value);
12129 }
12130 return(retn);
12131 }
12132
12133 double
ArgusFetchDstMac(struct ArgusRecordStruct * ns)12134 ArgusFetchDstMac (struct ArgusRecordStruct *ns)
12135 {
12136 struct ArgusMacStruct *m = (struct ArgusMacStruct *) ns->dsrs[ARGUS_MAC_INDEX];
12137 unsigned long long value = 0;
12138 double retn = 0;
12139
12140 if (m != NULL) {
12141 bcopy ((char *)&m->mac.mac_union.ether.ehdr.ether_dhost, (char *)&value, ETH_ALEN);
12142 retn = ntohll(value);
12143 }
12144 return(retn);
12145 }
12146
12147 double
ArgusFetchSrcAddr(struct ArgusRecordStruct * argus)12148 ArgusFetchSrcAddr (struct ArgusRecordStruct *argus)
12149 {
12150 struct ArgusFlow *flow;
12151 void *addr = NULL;
12152 int objlen = 0, type = 0;
12153 double retn = 0;
12154
12155 switch (argus->hdr.type & 0xF0) {
12156 case ARGUS_MAR: {
12157 struct ArgusRecord *rec = (struct ArgusRecord *) argus->dsrs[0];
12158
12159 if (rec != NULL)
12160 retn = rec->argus_mar.queue;
12161
12162 break;
12163 }
12164
12165 case ARGUS_EVENT: {
12166 struct ArgusTransportStruct *trans = (void *) argus->dsrs[ARGUS_TRANSPORT_INDEX];
12167
12168 if (trans != NULL) {
12169 switch (trans->hdr.argus_dsrvl8.qual) {
12170 case ARGUS_TYPE_INT:
12171 retn = trans->srcid.a_un.value;
12172 break;
12173
12174 case ARGUS_TYPE_IPV4:
12175 retn = trans->srcid.a_un.ipv4;
12176 break;
12177
12178 // case ARGUS_TYPE_IPV6: value = ArgusGetV6Name(parser, (u_char *)&trans->srcid.ipv6); break;
12179 // case ARGUS_TYPE_ETHER: value = ArgusGetEtherName(parser, (u_char *)&trans->srcid.ether); break;
12180 // case ARGUS_TYPE_STRING: value = ArgusGetString(parser, (u_char *)&trans->srcid.string); break;
12181 }
12182 }
12183 break;
12184 }
12185
12186 case ARGUS_NETFLOW:
12187 case ARGUS_FAR: {
12188 if ((flow = (void *)argus->dsrs[ARGUS_FLOW_INDEX]) != NULL) {
12189 switch (flow->hdr.subtype & 0x3F) {
12190 case ARGUS_FLOW_CLASSIC5TUPLE:
12191 case ARGUS_FLOW_LAYER_3_MATRIX: {
12192 switch (type = (flow->hdr.argus_dsrvl8.qual & 0x1F)) {
12193 case ARGUS_TYPE_IPV4:
12194 addr = &flow->ip_flow.ip_src;
12195 objlen = 4;
12196 break;
12197 case ARGUS_TYPE_IPV6:
12198 addr = &flow->ipv6_flow.ip_src;
12199 objlen = 16;
12200 break;
12201
12202 case ARGUS_TYPE_RARP:
12203 type = ARGUS_TYPE_ETHER;
12204 addr = &flow->lrarp_flow.tareaddr;
12205 objlen = 6;
12206 break;
12207 case ARGUS_TYPE_ARP:
12208 type = ARGUS_TYPE_IPV4;
12209 addr = &flow->larp_flow.arp_spa;
12210 objlen = 4;
12211 break;
12212
12213 case ARGUS_TYPE_ETHER:
12214 addr = &flow->mac_flow.mac_union.ether.ehdr.ether_shost;
12215 objlen = 6;
12216 break;
12217
12218 case ARGUS_TYPE_WLAN:
12219 addr = &flow->wlan_flow.shost;
12220 objlen = 6;
12221 break;
12222 }
12223 break;
12224 }
12225
12226 case ARGUS_FLOW_ARP: {
12227 switch (type = (flow->hdr.argus_dsrvl8.qual & 0x1F)) {
12228 case ARGUS_TYPE_RARP:
12229 type = ARGUS_TYPE_ETHER;
12230 addr = &flow->rarp_flow.dhaddr;
12231 objlen = 6;
12232 break;
12233
12234 case ARGUS_TYPE_ARP:
12235 type = ARGUS_TYPE_IPV4;
12236 addr = &flow->arp_flow.arp_spa;
12237 objlen = 4;
12238 break;
12239 }
12240 break;
12241 }
12242
12243 default:
12244 break;
12245 }
12246 }
12247
12248 switch (objlen) {
12249 case 4:
12250 retn = *(unsigned int *)addr;
12251 break;
12252
12253 default:
12254 break;
12255 }
12256 break;
12257 }
12258 }
12259
12260 #ifdef ARGUSDEBUG
12261 ArgusDebug (10, "ArgusFetchSrcAddr (%p) returns %p", argus, retn);
12262 #endif
12263
12264 return(retn);
12265 }
12266
12267 double
ArgusFetchDstAddr(struct ArgusRecordStruct * argus)12268 ArgusFetchDstAddr (struct ArgusRecordStruct *argus)
12269 {
12270 struct ArgusFlow *flow;
12271 void *addr = NULL;
12272 int objlen = 0, type = 0;
12273 double retn = 0;
12274
12275 switch (argus->hdr.type & 0xF0) {
12276 case ARGUS_MAR: {
12277 struct ArgusRecord *rec = (struct ArgusRecord *) argus->dsrs[0];
12278
12279 if (rec != NULL)
12280 retn = rec->argus_mar.queue;
12281
12282 break;
12283 }
12284
12285 case ARGUS_EVENT: {
12286 struct ArgusTransportStruct *trans = (void *) argus->dsrs[ARGUS_TRANSPORT_INDEX];
12287
12288 if (trans != NULL) {
12289 switch (trans->hdr.argus_dsrvl8.qual) {
12290 case ARGUS_TYPE_INT:
12291 retn = trans->srcid.a_un.value;
12292 break;
12293
12294 case ARGUS_TYPE_IPV4:
12295 retn = trans->srcid.a_un.ipv4;
12296 break;
12297
12298 // case ARGUS_TYPE_IPV6: value = ArgusGetV6Name(parser, (u_char *)&trans->srcid.ipv6); break;
12299 // case ARGUS_TYPE_ETHER: value = ArgusGetEtherName(parser, (u_char *)&trans->srcid.ether); break;
12300 // case ARGUS_TYPE_STRING: value = ArgusGetString(parser, (u_char *)&trans->srcid.string); break;
12301
12302 }
12303 }
12304 break;
12305 }
12306
12307 case ARGUS_NETFLOW:
12308 case ARGUS_FAR: {
12309 if ((flow = (void *)argus->dsrs[ARGUS_FLOW_INDEX]) != NULL) {
12310 switch (flow->hdr.subtype & 0x3F) {
12311
12312 case ARGUS_FLOW_CLASSIC5TUPLE:
12313 case ARGUS_FLOW_LAYER_3_MATRIX: {
12314 switch (type = (flow->hdr.argus_dsrvl8.qual & 0x1F)) {
12315 case ARGUS_TYPE_IPV4:
12316 addr = &flow->ip_flow.ip_dst;
12317 objlen = 4;
12318 break;
12319 case ARGUS_TYPE_IPV6:
12320 addr = &flow->ipv6_flow.ip_dst;
12321 objlen = 16;
12322 break;
12323
12324 case ARGUS_TYPE_RARP:
12325 type = ARGUS_TYPE_ETHER;
12326 addr = &flow->lrarp_flow.srceaddr;
12327 objlen = 6;
12328 break;
12329 case ARGUS_TYPE_ARP:
12330 type = ARGUS_TYPE_IPV4;
12331 addr = &flow->larp_flow.arp_tpa;
12332 objlen = 4;
12333 break;
12334
12335 case ARGUS_TYPE_ETHER:
12336 addr = &flow->mac_flow.mac_union.ether.ehdr.ether_dhost;
12337 objlen = 6;
12338 break;
12339
12340 case ARGUS_TYPE_WLAN:
12341 addr = &flow->wlan_flow.dhost;
12342 objlen = 6;
12343 break;
12344 }
12345 break;
12346 }
12347
12348 case ARGUS_FLOW_ARP: {
12349 switch (type = (flow->hdr.argus_dsrvl8.qual & 0x1F)) {
12350 case ARGUS_TYPE_RARP:
12351 type = ARGUS_TYPE_ETHER;
12352 addr = &flow->rarp_flow.dhaddr;
12353 objlen = 6;
12354 break;
12355
12356 case ARGUS_TYPE_ARP:
12357 type = ARGUS_TYPE_IPV4;
12358 addr = &flow->arp_flow.arp_tpa;
12359 objlen = 4;
12360 break;
12361 }
12362 break;
12363 }
12364
12365 default:
12366 break;
12367 }
12368 }
12369
12370 switch (objlen) {
12371 case 4:
12372 retn = *(unsigned int *)addr;
12373 break;
12374
12375 default:
12376 break;
12377 }
12378 break;
12379 }
12380 }
12381
12382 #ifdef ARGUSDEBUG
12383 ArgusDebug (10, "ArgusFetchSrcAddr (%p) returns %p", argus, retn);
12384 #endif
12385
12386 return(retn);
12387 }
12388
12389 double
ArgusFetchProtocol(struct ArgusRecordStruct * ns)12390 ArgusFetchProtocol (struct ArgusRecordStruct *ns)
12391 {
12392 double retn = 0;
12393 struct ArgusFlow *f1 = (struct ArgusFlow *) ns->dsrs[ARGUS_FLOW_INDEX];
12394
12395 if (f1) {
12396 switch (f1->hdr.subtype & 0x3F) {
12397 case ARGUS_FLOW_CLASSIC5TUPLE: {
12398 switch (f1->hdr.argus_dsrvl8.qual & 0x1F) {
12399 case ARGUS_TYPE_IPV4:
12400 retn = f1->ip_flow.ip_p;
12401 break;
12402 case ARGUS_TYPE_IPV6:
12403 retn = f1->ipv6_flow.ip_p;
12404 break;
12405 }
12406 break;
12407 }
12408
12409 default:
12410 break;
12411 }
12412 }
12413
12414 return(retn);
12415 }
12416
12417 double
ArgusFetchSrcPort(struct ArgusRecordStruct * ns)12418 ArgusFetchSrcPort (struct ArgusRecordStruct *ns)
12419 {
12420 double retn = 0;
12421
12422 struct ArgusFlow *flow = (struct ArgusFlow *) ns->dsrs[ARGUS_FLOW_INDEX];
12423
12424 switch (flow->hdr.subtype & 0x3F) {
12425 case ARGUS_FLOW_CLASSIC5TUPLE: {
12426 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
12427 case ARGUS_TYPE_IPV4:
12428 if ((flow->ip_flow.ip_p == IPPROTO_TCP) || (flow->ip_flow.ip_p == IPPROTO_UDP))
12429 retn = (flow->hdr.subtype & ARGUS_REVERSE) ? flow->ip_flow.dport : flow->ip_flow.sport;
12430 break;
12431 case ARGUS_TYPE_IPV6:
12432 switch (flow->ipv6_flow.ip_p) {
12433 case IPPROTO_TCP:
12434 case IPPROTO_UDP: {
12435 retn = (flow->hdr.subtype & ARGUS_REVERSE) ? flow->ipv6_flow.dport : flow->ipv6_flow.sport;
12436 break;
12437 }
12438 }
12439
12440 break;
12441 }
12442 break;
12443 }
12444
12445 default:
12446 break;
12447 }
12448
12449 return(retn);
12450 }
12451
12452 double
ArgusFetchDstPort(struct ArgusRecordStruct * ns)12453 ArgusFetchDstPort (struct ArgusRecordStruct *ns)
12454 {
12455 double retn = 0;
12456
12457 struct ArgusFlow *flow = (struct ArgusFlow *) ns->dsrs[ARGUS_FLOW_INDEX];
12458
12459 switch (flow->hdr.subtype & 0x3F) {
12460 case ARGUS_FLOW_CLASSIC5TUPLE: {
12461 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
12462 case ARGUS_TYPE_IPV4:
12463 if ((flow->ip_flow.ip_p == IPPROTO_TCP) || (flow->ip_flow.ip_p == IPPROTO_UDP))
12464 retn = (flow->hdr.subtype & ARGUS_REVERSE) ? flow->ip_flow.sport : flow->ip_flow.dport;
12465 break;
12466 case ARGUS_TYPE_IPV6:
12467 switch (flow->ipv6_flow.ip_p) {
12468 case IPPROTO_TCP:
12469 case IPPROTO_UDP: {
12470 retn = (flow->hdr.subtype & ARGUS_REVERSE) ? flow->ipv6_flow.sport : flow->ipv6_flow.dport;
12471 break;
12472 }
12473 }
12474
12475 break;
12476 }
12477 break;
12478 }
12479
12480 default:
12481 break;
12482 }
12483
12484 return(retn);
12485 }
12486
12487
12488 double
ArgusFetchSrcMpls(struct ArgusRecordStruct * ns)12489 ArgusFetchSrcMpls (struct ArgusRecordStruct *ns)
12490 {
12491 struct ArgusMplsStruct *m1 = (struct ArgusMplsStruct *)ns->dsrs[ARGUS_MPLS_INDEX];
12492 double retn = 0;
12493
12494 if (m1 && (m1->hdr.subtype & ARGUS_MPLS_SRC_LABEL)) {
12495 unsigned char *p1 = (unsigned char *)&m1->slabel;
12496
12497 #if defined(_LITTLE_ENDIAN)
12498 retn = (p1[0] << 12) | (p1[1] << 4) | ((p1[2] >> 4) & 0xff);
12499 #else
12500 retn = (p1[3] << 12) | (p1[2] << 4) | ((p1[1] >> 4) & 0xff);
12501 #endif
12502 }
12503
12504 return (retn);
12505 }
12506
12507 double
ArgusFetchDstMpls(struct ArgusRecordStruct * ns)12508 ArgusFetchDstMpls (struct ArgusRecordStruct *ns)
12509 {
12510 struct ArgusMplsStruct *m1 = (struct ArgusMplsStruct *)ns->dsrs[ARGUS_MPLS_INDEX];
12511 double retn = 0;
12512
12513 if (m1 && (m1->hdr.subtype & ARGUS_MPLS_DST_LABEL)) {
12514 unsigned char *p1 = (unsigned char *)&m1->dlabel;
12515
12516 #if defined(_LITTLE_ENDIAN)
12517 retn = (p1[0] << 12) | (p1[1] << 4) | ((p1[2] >> 4) & 0xff);
12518 #else
12519 retn = (p1[3] << 12) | (p1[2] << 4) | ((p1[1] >> 4) & 0xff);
12520 #endif
12521 }
12522
12523 return (retn);
12524 }
12525
12526 double
ArgusFetchSrcVlan(struct ArgusRecordStruct * ns)12527 ArgusFetchSrcVlan (struct ArgusRecordStruct *ns)
12528 {
12529 struct ArgusVlanStruct *v1 = (struct ArgusVlanStruct *)ns->dsrs[ARGUS_VLAN_INDEX];
12530 double retn = 0;
12531
12532 if (v1 && (v1->hdr.argus_dsrvl8.qual & ARGUS_SRC_VLAN))
12533 retn = v1->sid & 0x0FFF;
12534
12535 return (retn);
12536 }
12537
12538 double
ArgusFetchDstVlan(struct ArgusRecordStruct * ns)12539 ArgusFetchDstVlan (struct ArgusRecordStruct *ns)
12540 {
12541 struct ArgusVlanStruct *v1 = (struct ArgusVlanStruct *)ns->dsrs[ARGUS_VLAN_INDEX];
12542 double retn = 0;
12543
12544 if (v1 && (v1->hdr.argus_dsrvl8.qual & ARGUS_DST_VLAN))
12545 retn = (v1->did & 0x0FFF);
12546
12547 return (retn);
12548 }
12549
12550 double
ArgusFetchSrcIpId(struct ArgusRecordStruct * ns)12551 ArgusFetchSrcIpId (struct ArgusRecordStruct *ns)
12552 {
12553 struct ArgusIPAttrStruct *ip1 = (struct ArgusIPAttrStruct *)ns->dsrs[ARGUS_IPATTR_INDEX];
12554 double retn = 0;
12555
12556 if (ip1)
12557 retn = ip1->src.ip_id;
12558
12559 return (retn);
12560 }
12561
12562
12563 double
ArgusFetchDstIpId(struct ArgusRecordStruct * ns)12564 ArgusFetchDstIpId (struct ArgusRecordStruct *ns)
12565 {
12566 struct ArgusIPAttrStruct *ip1 = (struct ArgusIPAttrStruct *)ns->dsrs[ARGUS_IPATTR_INDEX];
12567 double retn = 0;
12568
12569 if (ip1)
12570 retn = ip1->dst.ip_id;
12571
12572 return (retn);
12573 }
12574
12575 double
ArgusFetchSrcTos(struct ArgusRecordStruct * ns)12576 ArgusFetchSrcTos (struct ArgusRecordStruct *ns)
12577 {
12578 struct ArgusIPAttrStruct *ip1 = (struct ArgusIPAttrStruct *)ns->dsrs[ARGUS_IPATTR_INDEX];
12579 double retn = 0;
12580
12581 if (ip1)
12582 retn = ip1->src.tos;
12583
12584 return (retn);
12585 }
12586
12587 double
ArgusFetchDstTos(struct ArgusRecordStruct * ns)12588 ArgusFetchDstTos (struct ArgusRecordStruct *ns)
12589 {
12590 struct ArgusIPAttrStruct *ip1 = (struct ArgusIPAttrStruct *)ns->dsrs[ARGUS_IPATTR_INDEX];
12591 double retn = 0;
12592
12593 if (ip1)
12594 retn = ip1->dst.tos;
12595
12596 return (retn);
12597 }
12598
12599 double
ArgusFetchSrcTtl(struct ArgusRecordStruct * ns)12600 ArgusFetchSrcTtl (struct ArgusRecordStruct *ns)
12601 {
12602 struct ArgusIPAttrStruct *ip1 = (struct ArgusIPAttrStruct *)ns->dsrs[ARGUS_IPATTR_INDEX];
12603 double retn = 0;
12604
12605 if (ip1 && (ip1->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_SRC))
12606 retn = (ip1->src.ttl * 1.0);
12607
12608 return (retn);
12609 }
12610
12611 double
ArgusFetchDstTtl(struct ArgusRecordStruct * ns)12612 ArgusFetchDstTtl (struct ArgusRecordStruct *ns)
12613 {
12614 struct ArgusIPAttrStruct *ip1 = (struct ArgusIPAttrStruct *)ns->dsrs[ARGUS_IPATTR_INDEX];
12615 double retn = 0;
12616
12617 if (ip1 && (ip1->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_DST))
12618 retn = (ip1->dst.ttl * 1.0);
12619
12620 return (retn);
12621 }
12622
12623 double
ArgusFetchSrcHopCount(struct ArgusRecordStruct * ns)12624 ArgusFetchSrcHopCount (struct ArgusRecordStruct *ns)
12625 {
12626 struct ArgusIPAttrStruct *ip1 = (struct ArgusIPAttrStruct *)ns->dsrs[ARGUS_IPATTR_INDEX];
12627 int esthops = 1;
12628 double retn = 0;
12629
12630 if (ip1 && (ip1->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_SRC)) {
12631 while (esthops <= ip1->dst.ttl)
12632 esthops = esthops * 2;
12633
12634 retn = ((esthops - ip1->src.ttl) * 1.0);
12635 }
12636
12637 return (retn);
12638 }
12639
12640 double
ArgusFetchDstHopCount(struct ArgusRecordStruct * ns)12641 ArgusFetchDstHopCount (struct ArgusRecordStruct *ns)
12642 {
12643 struct ArgusIPAttrStruct *ip1 = (struct ArgusIPAttrStruct *)ns->dsrs[ARGUS_IPATTR_INDEX];
12644 int esthops = 1;
12645 double retn = 0;
12646
12647 if (ip1 && (ip1->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_DST)) {
12648 while (esthops <= ip1->dst.ttl)
12649 esthops = esthops * 2;
12650
12651 retn = ((esthops - ip1->dst.ttl) * 1.0);
12652 }
12653
12654 return (retn);
12655 }
12656
12657 double
ArgusFetchTransactions(struct ArgusRecordStruct * ns)12658 ArgusFetchTransactions (struct ArgusRecordStruct *ns)
12659 {
12660 struct ArgusAgrStruct *a1 = (struct ArgusAgrStruct *)ns->dsrs[ARGUS_AGR_INDEX];
12661 double retn = 1.0;
12662
12663 if (a1)
12664 retn = (a1->count * 1.0);
12665
12666 return (retn);
12667 }
12668
12669 double
ArgusFetchSrcLoad(struct ArgusRecordStruct * ns)12670 ArgusFetchSrcLoad (struct ArgusRecordStruct *ns)
12671 {
12672 double retn = ns->sload;
12673 return (retn);
12674 }
12675
12676 double
ArgusFetchDstLoad(struct ArgusRecordStruct * ns)12677 ArgusFetchDstLoad (struct ArgusRecordStruct *ns)
12678 {
12679 double retn = ns->dload;
12680 return (retn);
12681 }
12682
12683
12684 double
ArgusFetchLoad(struct ArgusRecordStruct * ns)12685 ArgusFetchLoad (struct ArgusRecordStruct *ns)
12686 {
12687 double retn = 0.0;
12688
12689 if (ns->hdr.type & ARGUS_MAR) {
12690
12691 } else {
12692 float sdur = RaGetFloatSrcDuration(ns);
12693 float ddur = RaGetFloatDstDuration(ns);
12694
12695 if (!(sdur > 0)) sdur = ns->dur;
12696 if (!(ddur > 0)) ddur = ns->dur;
12697
12698 if (ns->dur > 0.0)
12699 retn = ((ns->sload * sdur) + (ns->dload * ddur)) / ns->dur;
12700 }
12701
12702 return (retn);
12703 }
12704
12705 double
ArgusFetchLoss(struct ArgusRecordStruct * ns)12706 ArgusFetchLoss (struct ArgusRecordStruct *ns)
12707 {
12708 double retn = 0.0;
12709
12710 if (ns) {
12711 if (ns->hdr.type & ARGUS_MAR) {
12712 struct ArgusRecord *rec = (void *)ns->dsrs[0];
12713
12714 if (rec != NULL)
12715 retn = rec->argus_mar.dropped * 1.0;
12716 } else {
12717 struct ArgusFlow *flow = (struct ArgusFlow *)ns->dsrs[ARGUS_FLOW_INDEX];
12718 struct ArgusNetworkStruct *net = (void *) ns->dsrs[ARGUS_NETWORK_INDEX];
12719 struct ArgusMetricStruct *metric = (void *) ns->dsrs[ARGUS_METRIC_INDEX];
12720
12721 if (flow != NULL) {
12722 switch (flow->hdr.subtype & 0x3F) {
12723 case ARGUS_FLOW_CLASSIC5TUPLE: {
12724 switch ((flow->hdr.argus_dsrvl8.qual & 0x1F)) {
12725 case ARGUS_TYPE_IPV4: {
12726 switch (flow->ip_flow.ip_p) {
12727 case IPPROTO_UDP: {
12728 if ((net != NULL) && (net->hdr.subtype == ARGUS_RTP_FLOW)) {
12729 struct ArgusRTPObject *rtp = (void *)&net->net_union.rtp;
12730 retn = (rtp->sdrop + rtp->ddrop) * 1.0;
12731 } else
12732 if ((net != NULL) && (net->hdr.subtype == ARGUS_UDT_FLOW)) {
12733 struct ArgusUDTObject *udt = (void *)&net->net_union.udt;
12734 retn = (udt->src.drops) * 1.0;
12735 }
12736 break;
12737 }
12738
12739 case IPPROTO_ICMP: {
12740 break;
12741 }
12742 case IPPROTO_TCP: {
12743 if ((net != NULL) && (metric != NULL)) {
12744 struct ArgusTCPObject *tcp = (void *)&net->net_union.tcp;
12745
12746 if ((tcp != NULL) && (tcp->state != 0)) {
12747 if (metric->src.pkts)
12748 retn = (tcp->src.retrans + tcp->dst.retrans) * 1.0;
12749 }
12750 }
12751 break;
12752 }
12753 case IPPROTO_ESP: {
12754 if ((net != NULL) && (metric != NULL)) {
12755 struct ArgusESPObject *esp = (void *)&net->net_union.esp;
12756 if (esp != NULL) {
12757 if (metric->src.pkts)
12758 retn = esp->lostseq * 1.0;
12759 }
12760 }
12761 break;
12762 }
12763 }
12764 break;
12765 }
12766
12767 case ARGUS_TYPE_IPV6: {
12768 switch (flow->ipv6_flow.ip_p) {
12769 case IPPROTO_UDP: {
12770 if (net != NULL) {
12771 if (net->hdr.subtype == ARGUS_RTP_FLOW) {
12772 struct ArgusRTPObject *rtp = (void *)&net->net_union.rtp;
12773 retn = (rtp->sdrop + rtp->ddrop) * 1.0;
12774 } else
12775 if (net->hdr.subtype == ARGUS_UDT_FLOW) {
12776 struct ArgusUDTObject *udt = (void *)&net->net_union.udt;
12777 retn = (udt->src.drops) * 1.0;
12778 }
12779 }
12780 break;
12781 }
12782
12783 case IPPROTO_ICMP: {
12784 break;
12785 }
12786
12787 case IPPROTO_TCP: {
12788 if ((net != NULL) && (metric != NULL)) {
12789 struct ArgusTCPObject *tcp = (void *)&net->net_union.tcp;
12790
12791 if ((tcp != NULL) && (tcp->state != 0)) {
12792 if (metric->src.pkts)
12793 retn = (tcp->src.retrans + tcp->dst.retrans) * 1.0;
12794 }
12795 }
12796 break;
12797 }
12798 }
12799 }
12800 }
12801 break;
12802 }
12803 }
12804 }
12805 }
12806 }
12807
12808 return (retn);
12809 }
12810
12811 double
ArgusFetchSrcLoss(struct ArgusRecordStruct * ns)12812 ArgusFetchSrcLoss (struct ArgusRecordStruct *ns)
12813 {
12814 double retn = 0.0;
12815
12816 if (ns) {
12817 if (ns->hdr.type & ARGUS_MAR) {
12818 } else {
12819 struct ArgusFlow *flow = (struct ArgusFlow *)ns->dsrs[ARGUS_FLOW_INDEX];
12820 struct ArgusNetworkStruct *net = (void *) ns->dsrs[ARGUS_NETWORK_INDEX];
12821 struct ArgusMetricStruct *metric = (void *) ns->dsrs[ARGUS_METRIC_INDEX];
12822
12823 if (flow != NULL) {
12824 switch (flow->hdr.subtype & 0x3F) {
12825 case ARGUS_FLOW_CLASSIC5TUPLE: {
12826 switch ((flow->hdr.argus_dsrvl8.qual & 0x1F)) {
12827 case ARGUS_TYPE_IPV4: {
12828 switch (flow->ip_flow.ip_p) {
12829 case IPPROTO_UDP: {
12830 if (net != NULL) {
12831 if (net->hdr.subtype == ARGUS_RTP_FLOW) {
12832 struct ArgusRTPObject *rtp = (void *)&net->net_union.rtp;
12833 retn = rtp->sdrop * 1.0;
12834 } else
12835 if (net->hdr.subtype == ARGUS_UDT_FLOW) {
12836 struct ArgusUDTObject *udt = (void *)&net->net_union.udt;
12837 retn = (udt->src.drops) * 1.0;
12838 }
12839 }
12840 break;
12841 }
12842
12843 case IPPROTO_ICMP: {
12844 break;
12845 }
12846 case IPPROTO_TCP: {
12847 if ((net != NULL) && (metric != NULL)) {
12848 struct ArgusTCPObject *tcp = (void *)&net->net_union.tcp;
12849
12850 if (tcp->state != 0) {
12851 if (metric->src.pkts)
12852 retn = tcp->src.retrans * 1.0;
12853 }
12854 }
12855 break;
12856 }
12857 case IPPROTO_ESP: {
12858 if ((net != NULL) && (metric != NULL)) {
12859 struct ArgusESPObject *esp = (void *)&net->net_union.esp;
12860 if (metric->src.pkts)
12861 retn = esp->lostseq * 1.0;
12862 }
12863 break;
12864 }
12865 }
12866 break;
12867 }
12868
12869 case ARGUS_TYPE_IPV6: {
12870 switch (flow->ipv6_flow.ip_p) {
12871 case IPPROTO_UDP: {
12872 if (net != NULL) {
12873 if (net->hdr.subtype == ARGUS_RTP_FLOW) {
12874 struct ArgusRTPObject *rtp = (void *)&net->net_union.rtp;
12875 retn = rtp->sdrop * 1.0;
12876 } else
12877 if (net->hdr.subtype == ARGUS_UDT_FLOW) {
12878 struct ArgusUDTObject *udt = (void *)&net->net_union.udt;
12879 retn = (udt->src.drops) * 1.0;
12880 }
12881 }
12882 break;
12883 }
12884
12885 case IPPROTO_ICMP: {
12886 break;
12887 }
12888
12889 case IPPROTO_TCP: {
12890 if ((net != NULL) && (metric != NULL)) {
12891 struct ArgusTCPObject *tcp = (void *)&net->net_union.tcp;
12892
12893 if ((tcp != NULL) && (tcp->state != 0)) {
12894 if (metric->src.pkts)
12895 retn = tcp->src.retrans * 1.0;
12896 }
12897 }
12898 break;
12899 }
12900 }
12901 }
12902 }
12903 break;
12904 }
12905 }
12906 }
12907 }
12908 }
12909
12910 return (retn);
12911 }
12912
12913 double
ArgusFetchDstLoss(struct ArgusRecordStruct * ns)12914 ArgusFetchDstLoss (struct ArgusRecordStruct *ns)
12915 {
12916 double retn = 0.0;
12917
12918 if (ns) {
12919 if (ns->hdr.type & ARGUS_MAR) {
12920 } else {
12921 struct ArgusFlow *flow = (struct ArgusFlow *)ns->dsrs[ARGUS_FLOW_INDEX];
12922 struct ArgusNetworkStruct *net = (void *) ns->dsrs[ARGUS_NETWORK_INDEX];
12923 struct ArgusMetricStruct *metric = (void *) ns->dsrs[ARGUS_METRIC_INDEX];
12924
12925 if (flow != NULL) {
12926 switch (flow->hdr.subtype & 0x3F) {
12927 case ARGUS_FLOW_CLASSIC5TUPLE: {
12928 switch ((flow->hdr.argus_dsrvl8.qual & 0x1F)) {
12929 case ARGUS_TYPE_IPV4: {
12930 switch (flow->ip_flow.ip_p) {
12931 case IPPROTO_UDP: {
12932 if ((net != NULL) && (metric != NULL)) {
12933 if (net->hdr.subtype == ARGUS_RTP_FLOW) {
12934 struct ArgusRTPObject *rtp = (void *)&net->net_union.rtp;
12935 retn = rtp->ddrop * 1.0;
12936 }
12937 }
12938 }
12939
12940 case IPPROTO_ICMP: {
12941 break;
12942 }
12943 case IPPROTO_TCP: {
12944 if ((net != NULL) && (metric != NULL)) {
12945 struct ArgusTCPObject *tcp = (void *)&net->net_union.tcp;
12946 unsigned int status;
12947
12948 if ((tcp != NULL) && ((status = tcp->state) != 0)) {
12949 if (metric->dst.pkts)
12950 retn = tcp->dst.retrans * 1.0;
12951 }
12952 }
12953 break;
12954 }
12955 case IPPROTO_ESP: {
12956 if ((net != NULL) && (metric != NULL)) {
12957 struct ArgusESPObject *esp = (void *)&net->net_union.esp;
12958 if (metric->dst.pkts)
12959 retn = esp->lostseq * 1.0;
12960 }
12961 }
12962 }
12963 break;
12964 }
12965
12966 case ARGUS_TYPE_IPV6: {
12967 switch (flow->ipv6_flow.ip_p) {
12968 case IPPROTO_UDP: {
12969 if (net != NULL) {
12970 if (net->hdr.subtype == ARGUS_RTP_FLOW) {
12971 struct ArgusRTPObject *rtp = (void *)&net->net_union.rtp;
12972 retn = rtp->ddrop * 1.0;
12973 }
12974 }
12975 break;
12976 }
12977
12978 case IPPROTO_ICMP: {
12979 break;
12980 }
12981
12982 case IPPROTO_TCP: {
12983 if ((net != NULL) && (metric != NULL)) {
12984 struct ArgusTCPObject *tcp = (void *)&net->net_union.tcp;
12985 unsigned int status;
12986
12987 if ((status = tcp->state) != 0) {
12988 if (metric->dst.pkts)
12989 retn = tcp->dst.retrans * 1.0;
12990 }
12991 }
12992 break;
12993 }
12994 }
12995 }
12996 }
12997 break;
12998 }
12999 }
13000 }
13001 }
13002 }
13003
13004 return (retn);
13005 }
13006
13007
13008 void
ArgusAdjustTransactions(struct ArgusRecordStruct * ns,double ptrans,double ppkts)13009 ArgusAdjustTransactions (struct ArgusRecordStruct *ns, double ptrans, double ppkts)
13010 {
13011 switch (ns->hdr.type & 0xF0) {
13012 case ARGUS_EVENT:
13013 case ARGUS_MAR: {
13014 break;
13015 }
13016
13017 case ARGUS_NETFLOW:
13018 case ARGUS_FAR: {
13019 struct ArgusAgrStruct *agr = (void *)ns->dsrs[ARGUS_AGR_INDEX];
13020 double tpkts = ArgusFetchPktsCount(ns);
13021
13022 if (agr != NULL) {
13023 double trans = floor(ptrans * (tpkts/ppkts));
13024 agr->count = trans;
13025 }
13026 break;
13027 }
13028 }
13029 }
13030
13031 // the idea here is to use the percentage loss value to tweak the new record, so
13032 // that its source and dest loss counters represent what should be a good value.
13033 // rounding up, should get us there. and tracking the value to maintain the raminader
13034 // is very important.
13035
13036 void
ArgusAdjustSrcLoss(struct ArgusRecordStruct * ns,struct ArgusRecordStruct * retn,double percent)13037 ArgusAdjustSrcLoss (struct ArgusRecordStruct *ns, struct ArgusRecordStruct *retn, double percent)
13038 {
13039 if (ns && retn) {
13040 if (ns->hdr.type & ARGUS_MAR) {
13041 } else {
13042 struct ArgusFlow *flow = (struct ArgusFlow *)ns->dsrs[ARGUS_FLOW_INDEX];
13043 struct ArgusNetworkStruct *net = (void *) ns->dsrs[ARGUS_NETWORK_INDEX];
13044 struct ArgusMetricStruct *metric = (void *) ns->dsrs[ARGUS_METRIC_INDEX];
13045 double pkts = metric->src.pkts * 1.0;
13046
13047 struct ArgusNetworkStruct *rnet = (void *) retn->dsrs[ARGUS_NETWORK_INDEX];
13048 struct ArgusMetricStruct *rmetric = (void *) retn->dsrs[ARGUS_METRIC_INDEX];
13049 double rpkts = rmetric->src.pkts * 1.0;
13050 double tpkts = pkts + rpkts;
13051
13052 if (flow != NULL) {
13053 switch (flow->hdr.subtype & 0x3F) {
13054 case ARGUS_FLOW_CLASSIC5TUPLE: {
13055 switch ((flow->hdr.argus_dsrvl8.qual & 0x1F)) {
13056 case ARGUS_TYPE_IPV4: {
13057 switch (flow->ip_flow.ip_p) {
13058 case IPPROTO_UDP: {
13059 if (net != NULL) {
13060 if (net->hdr.subtype == ARGUS_RTP_FLOW) {
13061 struct ArgusRTPObject *nrtp = (void *)&net->net_union.rtp;
13062 struct ArgusRTPObject *rrtp = (void *)&rnet->net_union.rtp;
13063
13064 double drop = rint(rrtp->sdrop * (rpkts / tpkts));
13065
13066 if ((rrtp->sdrop = (unsigned short) drop) == 0) {
13067 } else {
13068 nrtp->sdrop -= rrtp->sdrop;
13069 }
13070
13071 } else
13072 if (net->hdr.subtype == ARGUS_UDT_FLOW) {
13073 struct ArgusUDTObject *nudt = (void *)&net->net_union.udt;
13074 struct ArgusUDTObject *rudt = (void *)&rnet->net_union.udt;
13075 double drop = rint(rudt->src.drops * (rpkts / tpkts));
13076
13077 if ((rudt->src.drops = (unsigned short) drop) == 0)
13078 rudt->status = ~(ARGUS_PKTS_RETRANS | ARGUS_PKTS_DROP);
13079 else
13080 nudt->src.drops -= rudt->src.drops;
13081 }
13082 }
13083 break;
13084 }
13085
13086 case IPPROTO_ICMP: {
13087 break;
13088 }
13089 case IPPROTO_TCP: {
13090 if ((net != NULL) && (metric != NULL)) {
13091 struct ArgusTCPObject *tcp = (void *)&net->net_union.tcp;
13092
13093 if (tcp->state != 0) {
13094 struct ArgusTCPObject *rtcp = (void *)&rnet->net_union.tcp;
13095
13096 double drop = rint(tcp->src.retrans * (rpkts / tpkts));
13097 if ((rtcp->src.retrans = (unsigned int) drop) == 0) {
13098 rtcp->src.status &= ~(ARGUS_PKTS_RETRANS | ARGUS_PKTS_DROP);
13099 rtcp->status &= ~(ARGUS_SRC_PKTS_RETRANS | ARGUS_SRC_PKTS_DROP);
13100
13101 } else
13102 tcp->src.retrans -= rtcp->src.retrans;
13103 }
13104 }
13105 break;
13106 }
13107 case IPPROTO_ESP: {
13108 if ((net != NULL) && (metric != NULL)) {
13109 struct ArgusESPObject *nesp = (void *)&net->net_union.esp;
13110 struct ArgusESPObject *resp = (void *)&rnet->net_union.esp;
13111
13112 double drop = rint(resp->lostseq * (rpkts / tpkts));
13113 if ((resp->lostseq = (unsigned int) drop) == 0)
13114 resp->status &= ~ARGUS_SRC_PKTS_DROP;
13115 else
13116 nesp->lostseq -= resp->lostseq;
13117 }
13118 break;
13119 }
13120 }
13121 break;
13122 }
13123
13124 case ARGUS_TYPE_IPV6: {
13125 switch (flow->ipv6_flow.ip_p) {
13126 case IPPROTO_UDP: {
13127 if (net != NULL) {
13128 if (net->hdr.subtype == ARGUS_RTP_FLOW) {
13129 struct ArgusRTPObject *nrtp = (void *)&net->net_union.rtp;
13130 struct ArgusRTPObject *rrtp = (void *)&rnet->net_union.rtp;
13131
13132 double drop = rint(rrtp->sdrop * (rpkts / tpkts));
13133
13134 if ((rrtp->sdrop = (unsigned short) drop) == 0) {
13135 } else {
13136 nrtp->sdrop -= rrtp->sdrop;
13137 }
13138
13139 } else
13140 if (net->hdr.subtype == ARGUS_UDT_FLOW) {
13141 struct ArgusUDTObject *nudt = (void *)&net->net_union.udt;
13142 struct ArgusUDTObject *rudt = (void *)&rnet->net_union.udt;
13143 double drop = rint(rudt->src.drops * (rpkts / tpkts));
13144
13145 if ((rudt->src.drops = (unsigned short) drop) == 0)
13146 rudt->status = ~(ARGUS_PKTS_RETRANS | ARGUS_PKTS_DROP);
13147 else
13148 nudt->src.drops -= rudt->src.drops;
13149 }
13150 }
13151 break;
13152 }
13153
13154 case IPPROTO_ICMP: {
13155 break;
13156 }
13157
13158 case IPPROTO_TCP: {
13159 if ((net != NULL) && (metric != NULL)) {
13160 struct ArgusTCPObject *tcp = (void *)&net->net_union.tcp;
13161
13162 if (tcp->state != 0) {
13163 struct ArgusTCPObject *rtcp = (void *)&rnet->net_union.tcp;
13164
13165 double drop = rint(tcp->src.retrans * (rpkts / tpkts));
13166 if ((rtcp->src.retrans = (unsigned int) drop) == 0) {
13167 rtcp->src.status &= ~(ARGUS_PKTS_RETRANS | ARGUS_PKTS_DROP);
13168 rtcp->status &= ~(ARGUS_SRC_PKTS_RETRANS | ARGUS_SRC_PKTS_DROP);
13169
13170 } else
13171 tcp->src.retrans -= rtcp->src.retrans;
13172 }
13173 }
13174 break;
13175 }
13176
13177 case IPPROTO_ESP: {
13178 if ((net != NULL) && (metric != NULL)) {
13179 struct ArgusESPObject *nesp = (void *)&net->net_union.esp;
13180 struct ArgusESPObject *resp = (void *)&rnet->net_union.esp;
13181
13182 double drop = rint(resp->lostseq * (rpkts / tpkts));
13183 if ((resp->lostseq = (unsigned int) drop) == 0)
13184 resp->status &= ~ARGUS_SRC_PKTS_DROP;
13185 else
13186 nesp->lostseq -= resp->lostseq;
13187 }
13188 break;
13189 }
13190 }
13191 }
13192 }
13193 break;
13194 }
13195 }
13196 }
13197 }
13198 }
13199 }
13200
13201
13202 void
ArgusAdjustDstLoss(struct ArgusRecordStruct * ns,struct ArgusRecordStruct * retn,double percent)13203 ArgusAdjustDstLoss (struct ArgusRecordStruct *ns, struct ArgusRecordStruct *retn, double percent)
13204 {
13205 if (ns && retn) {
13206 if (ns->hdr.type & ARGUS_MAR) {
13207 } else {
13208 struct ArgusFlow *flow = (struct ArgusFlow *)ns->dsrs[ARGUS_FLOW_INDEX];
13209 struct ArgusNetworkStruct *net = (void *) ns->dsrs[ARGUS_NETWORK_INDEX];
13210 struct ArgusMetricStruct *metric = (void *) ns->dsrs[ARGUS_METRIC_INDEX];
13211 double pkts = metric->dst.pkts * 1.0;
13212
13213 struct ArgusNetworkStruct *rnet = (void *) retn->dsrs[ARGUS_NETWORK_INDEX];
13214 struct ArgusMetricStruct *rmetric = (void *) retn->dsrs[ARGUS_METRIC_INDEX];
13215 double rpkts = rmetric->dst.pkts * 1.0;
13216 double tpkts = pkts + rpkts;
13217
13218 if (flow != NULL) {
13219 switch (flow->hdr.subtype & 0x3F) {
13220 case ARGUS_FLOW_CLASSIC5TUPLE: {
13221 switch ((flow->hdr.argus_dsrvl8.qual & 0x1F)) {
13222 case ARGUS_TYPE_IPV4: {
13223 switch (flow->ip_flow.ip_p) {
13224 case IPPROTO_UDP: {
13225 if (net != NULL) {
13226 if (net->hdr.subtype == ARGUS_RTP_FLOW) {
13227 struct ArgusRTPObject *nrtp = (void *)&net->net_union.rtp;
13228 struct ArgusRTPObject *rrtp = (void *)&rnet->net_union.rtp;
13229
13230 double drop = rint(rrtp->ddrop * (rpkts / tpkts));
13231
13232 if ((rrtp->ddrop = (unsigned short) drop) == 0) {
13233 } else {
13234 nrtp->ddrop -= rrtp->ddrop;
13235 }
13236
13237 }
13238 }
13239 break;
13240 }
13241
13242 case IPPROTO_ICMP: {
13243 break;
13244 }
13245 case IPPROTO_TCP: {
13246 if ((net != NULL) && (metric != NULL)) {
13247 struct ArgusTCPObject *tcp = (void *)&net->net_union.tcp;
13248
13249 if (tcp->state != 0) {
13250 struct ArgusTCPObject *rtcp = (void *)&rnet->net_union.tcp;
13251
13252 double drop = rint(tcp->dst.retrans * (rpkts / tpkts));
13253 if ((rtcp->dst.retrans = (unsigned int) drop) == 0) {
13254 rtcp->dst.status &= ~(ARGUS_PKTS_RETRANS | ARGUS_PKTS_DROP);
13255 rtcp->status &= ~(ARGUS_DST_PKTS_RETRANS | ARGUS_DST_PKTS_DROP);
13256
13257 } else
13258 tcp->dst.retrans -= rtcp->dst.retrans;
13259 }
13260 }
13261 break;
13262 }
13263 }
13264 break;
13265 }
13266
13267 case ARGUS_TYPE_IPV6: {
13268 switch (flow->ipv6_flow.ip_p) {
13269 case IPPROTO_UDP: {
13270 if (net != NULL) {
13271 if (net->hdr.subtype == ARGUS_RTP_FLOW) {
13272 struct ArgusRTPObject *nrtp = (void *)&net->net_union.rtp;
13273 struct ArgusRTPObject *rrtp = (void *)&rnet->net_union.rtp;
13274
13275 double drop = rint(rrtp->ddrop * (rpkts / tpkts));
13276
13277 if ((rrtp->ddrop = (unsigned short) drop) == 0) {
13278 } else {
13279 nrtp->ddrop -= rrtp->ddrop;
13280 }
13281
13282 } else
13283 if (net->hdr.subtype == ARGUS_UDT_FLOW) {
13284 }
13285 }
13286 break;
13287 }
13288
13289 case IPPROTO_ICMP: {
13290 break;
13291 }
13292
13293 case IPPROTO_TCP: {
13294 if ((net != NULL) && (metric != NULL)) {
13295 struct ArgusTCPObject *tcp = (void *)&net->net_union.tcp;
13296
13297 if (tcp->state != 0) {
13298 struct ArgusTCPObject *rtcp = (void *)&rnet->net_union.tcp;
13299
13300 double drop = rint(tcp->dst.retrans * (rpkts / tpkts));
13301 if ((rtcp->dst.retrans = (unsigned int) drop) == 0) {
13302 rtcp->dst.status &= ~(ARGUS_PKTS_RETRANS | ARGUS_PKTS_DROP);
13303 rtcp->status &= ~(ARGUS_DST_PKTS_RETRANS | ARGUS_DST_PKTS_DROP);
13304
13305 } else
13306 tcp->dst.retrans -= rtcp->dst.retrans;
13307 }
13308 }
13309 break;
13310 }
13311
13312 case IPPROTO_ESP: {
13313 if ((net != NULL) && (metric != NULL)) {
13314 struct ArgusESPObject *nesp = (void *)&net->net_union.esp;
13315 struct ArgusESPObject *resp = (void *)&rnet->net_union.esp;
13316
13317 double drop = rint(resp->lostseq * (rpkts / tpkts));
13318 if ((resp->lostseq = (unsigned int) drop) == 0)
13319 resp->status &= ~ARGUS_SRC_PKTS_DROP;
13320 else
13321 nesp->lostseq -= resp->lostseq;
13322 }
13323 break;
13324 }
13325 }
13326 }
13327 }
13328 break;
13329 }
13330 }
13331 }
13332 }
13333 }
13334 }
13335
13336
13337 double
ArgusFetchRetrans(struct ArgusRecordStruct * ns)13338 ArgusFetchRetrans (struct ArgusRecordStruct *ns)
13339 {
13340 double retn = 0.0;
13341
13342 if (ns) {
13343 if (ns->hdr.type & ARGUS_MAR) {
13344
13345 } else {
13346 struct ArgusNetworkStruct *net = (void *) ns->dsrs[ARGUS_NETWORK_INDEX];
13347
13348 if ((net != NULL) && (net->hdr.subtype == ARGUS_UDT_FLOW)) {
13349 struct ArgusUDTObject *udt = (void *)&net->net_union.udt;
13350 retn = (udt->src.retrans) * 1.0;
13351 }
13352 }
13353 }
13354
13355 return (retn);
13356 }
13357
13358 double
ArgusFetchSrcRetrans(struct ArgusRecordStruct * ns)13359 ArgusFetchSrcRetrans (struct ArgusRecordStruct *ns)
13360 {
13361 double retn = 0.0;
13362
13363 if (ns) {
13364 if (ns->hdr.type & ARGUS_MAR) {
13365
13366 } else {
13367 struct ArgusNetworkStruct *net = (void *) ns->dsrs[ARGUS_NETWORK_INDEX];
13368
13369 if ((net != NULL) && (net->hdr.subtype == ARGUS_UDT_FLOW)) {
13370 struct ArgusUDTObject *udt = (void *)&net->net_union.udt;
13371 retn = (udt->src.retrans) * 1.0;
13372 }
13373 }
13374 }
13375
13376 return (retn);
13377 }
13378
13379 double
ArgusFetchDstRetrans(struct ArgusRecordStruct * ns)13380 ArgusFetchDstRetrans (struct ArgusRecordStruct *ns)
13381 {
13382 double retn = 0.0;
13383
13384 if (ns) {
13385 if (ns->hdr.type & ARGUS_MAR) {
13386
13387 } else {
13388 struct ArgusNetworkStruct *net = (void *) ns->dsrs[ARGUS_NETWORK_INDEX];
13389
13390 if ((net != NULL) && (net->hdr.subtype == ARGUS_UDT_FLOW)) {
13391 }
13392 }
13393 }
13394
13395 return (retn);
13396 }
13397
13398
13399 double
ArgusFetchPercentRetrans(struct ArgusRecordStruct * ns)13400 ArgusFetchPercentRetrans (struct ArgusRecordStruct *ns)
13401 {
13402 double retn = 0.0;
13403 int pkts = 0;
13404
13405 if (ns) {
13406 struct ArgusMetricStruct *metric = (void *)ns->dsrs[ARGUS_METRIC_INDEX];
13407 if (metric != NULL) {
13408 retn = ArgusFetchRetrans(ns);
13409 pkts = metric->src.pkts + metric->dst.pkts;
13410 if (pkts > 0) {
13411 retn = (retn * 100.0)/(pkts * 1.0);
13412 } else
13413 retn = 0.0;
13414 }
13415 }
13416
13417 return (retn);
13418 }
13419
13420 double
ArgusFetchPercentSrcRetrans(struct ArgusRecordStruct * ns)13421 ArgusFetchPercentSrcRetrans (struct ArgusRecordStruct *ns)
13422 {
13423 double retn = 0.0;
13424 int pkts = 0;
13425
13426 if (ns) {
13427 struct ArgusMetricStruct *metric = (void *)ns->dsrs[ARGUS_METRIC_INDEX];
13428 if (metric != NULL) {
13429 retn = ArgusFetchSrcRetrans(ns);
13430 pkts = metric->src.pkts;
13431 if (pkts > 0) {
13432 retn = (retn * 100.0)/(pkts * 1.0);
13433 } else
13434 retn = 0.0;
13435 }
13436 }
13437
13438 return (retn);
13439 }
13440
13441 double
ArgusFetchPercentDstRetrans(struct ArgusRecordStruct * ns)13442 ArgusFetchPercentDstRetrans (struct ArgusRecordStruct *ns)
13443 {
13444 double retn = 0.0;
13445 int pkts = 0;
13446
13447 if (ns) {
13448 struct ArgusMetricStruct *metric = (void *)ns->dsrs[ARGUS_METRIC_INDEX];
13449 if (metric != NULL) {
13450 retn = ArgusFetchDstRetrans(ns);
13451 pkts = metric->dst.pkts;
13452 if (pkts > 0) {
13453 retn = (retn * 100.0)/(pkts * 1.0);
13454 } else
13455 retn = 0.0;
13456 }
13457 }
13458
13459 return (retn);
13460 }
13461
13462
13463 double
ArgusFetchNacks(struct ArgusRecordStruct * ns)13464 ArgusFetchNacks (struct ArgusRecordStruct *ns)
13465 {
13466 double retn = 0.0;
13467
13468 if (ns) {
13469 if (ns->hdr.type & ARGUS_MAR) {
13470
13471 } else {
13472 struct ArgusNetworkStruct *net = (void *) ns->dsrs[ARGUS_NETWORK_INDEX];
13473
13474 if ((net != NULL) && (net->hdr.subtype == ARGUS_UDT_FLOW)) {
13475 struct ArgusUDTObject *udt = (void *)&net->net_union.udt;
13476 retn = (udt->src.nacked) * 1.0;
13477 }
13478 }
13479 }
13480
13481 return (retn);
13482 }
13483
13484 double
ArgusFetchSrcNacks(struct ArgusRecordStruct * ns)13485 ArgusFetchSrcNacks (struct ArgusRecordStruct *ns)
13486 {
13487 double retn = 0.0;
13488
13489 if (ns) {
13490 if (ns->hdr.type & ARGUS_MAR) {
13491
13492 } else {
13493 struct ArgusNetworkStruct *net = (void *) ns->dsrs[ARGUS_NETWORK_INDEX];
13494
13495 if ((net != NULL) && (net->hdr.subtype == ARGUS_UDT_FLOW)) {
13496 struct ArgusUDTObject *udt = (void *)&net->net_union.udt;
13497 retn = (udt->src.nacked) * 1.0;
13498 }
13499 }
13500 }
13501
13502 return (retn);
13503 }
13504
13505 double
ArgusFetchDstNacks(struct ArgusRecordStruct * ns)13506 ArgusFetchDstNacks (struct ArgusRecordStruct *ns)
13507 {
13508 double retn = 0.0;
13509
13510 if (ns) {
13511 if (ns->hdr.type & ARGUS_MAR) {
13512
13513 } else {
13514 struct ArgusNetworkStruct *net = (void *) ns->dsrs[ARGUS_NETWORK_INDEX];
13515
13516 if ((net != NULL) && (net->hdr.subtype == ARGUS_UDT_FLOW)) {
13517 }
13518 }
13519 }
13520
13521 return (retn);
13522 }
13523
13524
13525 double
ArgusFetchPercentNacks(struct ArgusRecordStruct * ns)13526 ArgusFetchPercentNacks (struct ArgusRecordStruct *ns)
13527 {
13528 double retn = 0.0;
13529 int pkts = 0;
13530
13531 if (ns) {
13532 struct ArgusMetricStruct *metric = (void *)ns->dsrs[ARGUS_METRIC_INDEX];
13533 if (metric != NULL) {
13534 retn = ArgusFetchNacks(ns);
13535 pkts = metric->src.pkts + metric->dst.pkts;
13536 if (pkts > 0) {
13537 retn = (retn * 100.0)/(pkts * 1.0);
13538 } else
13539 retn = 0.0;
13540 }
13541 }
13542
13543 return (retn);
13544 }
13545
13546 double
ArgusFetchPercentSrcNacks(struct ArgusRecordStruct * ns)13547 ArgusFetchPercentSrcNacks (struct ArgusRecordStruct *ns)
13548 {
13549 double retn = 0.0;
13550 int pkts = 0;
13551
13552 if (ns) {
13553 struct ArgusMetricStruct *metric = (void *)ns->dsrs[ARGUS_METRIC_INDEX];
13554 if (metric != NULL) {
13555 retn = ArgusFetchSrcNacks(ns);
13556 pkts = metric->src.pkts;
13557 if (pkts > 0) {
13558 retn = (retn * 100.0)/(pkts * 1.0);
13559 } else
13560 retn = 0.0;
13561 }
13562 }
13563
13564 return (retn);
13565 }
13566
13567 double
ArgusFetchPercentDstNacks(struct ArgusRecordStruct * ns)13568 ArgusFetchPercentDstNacks (struct ArgusRecordStruct *ns)
13569 {
13570 double retn = 0.0;
13571 int pkts = 0;
13572
13573 if (ns) {
13574 struct ArgusMetricStruct *metric = (void *)ns->dsrs[ARGUS_METRIC_INDEX];
13575 if (metric != NULL) {
13576 retn = ArgusFetchDstNacks(ns);
13577 pkts = metric->dst.pkts;
13578 if (pkts > 0) {
13579 retn = (retn * 100.0)/(pkts * 1.0);
13580 } else
13581 retn = 0.0;
13582 }
13583 }
13584
13585 return (retn);
13586 }
13587
13588
13589 double
ArgusFetchSolo(struct ArgusRecordStruct * ns)13590 ArgusFetchSolo (struct ArgusRecordStruct *ns)
13591 {
13592 double retn = 0.0;
13593
13594 if (ns) {
13595 if (ns->hdr.type & ARGUS_MAR) {
13596
13597 } else {
13598 struct ArgusNetworkStruct *net = (void *) ns->dsrs[ARGUS_NETWORK_INDEX];
13599
13600 if ((net != NULL) && (net->hdr.subtype == ARGUS_UDT_FLOW)) {
13601 struct ArgusUDTObject *udt = (void *)&net->net_union.udt;
13602 retn = (udt->src.solo) * 1.0;
13603 }
13604 }
13605 }
13606
13607 return (retn);
13608 }
13609
13610 double
ArgusFetchSrcSolo(struct ArgusRecordStruct * ns)13611 ArgusFetchSrcSolo (struct ArgusRecordStruct *ns)
13612 {
13613 double retn = 0.0;
13614
13615 if (ns) {
13616 if (ns->hdr.type & ARGUS_MAR) {
13617
13618 } else {
13619 struct ArgusNetworkStruct *net = (void *) ns->dsrs[ARGUS_NETWORK_INDEX];
13620
13621 if ((net != NULL) && (net->hdr.subtype == ARGUS_UDT_FLOW)) {
13622 struct ArgusUDTObject *udt = (void *)&net->net_union.udt;
13623 retn = (udt->src.solo) * 1.0;
13624 }
13625 }
13626 }
13627
13628 return (retn);
13629 }
13630
13631 double
ArgusFetchDstSolo(struct ArgusRecordStruct * ns)13632 ArgusFetchDstSolo (struct ArgusRecordStruct *ns)
13633 {
13634 double retn = 0.0;
13635
13636 if (ns) {
13637 if (ns->hdr.type & ARGUS_MAR) {
13638
13639 } else {
13640 struct ArgusNetworkStruct *net = (void *) ns->dsrs[ARGUS_NETWORK_INDEX];
13641
13642 if ((net != NULL) && (net->hdr.subtype == ARGUS_UDT_FLOW)) {
13643 }
13644 }
13645 }
13646
13647 return (retn);
13648 }
13649
13650
13651 double
ArgusFetchPercentSolo(struct ArgusRecordStruct * ns)13652 ArgusFetchPercentSolo (struct ArgusRecordStruct *ns)
13653 {
13654 double retn = 0.0;
13655 int pkts = 0;
13656
13657 if (ns) {
13658 struct ArgusMetricStruct *metric = (void *)ns->dsrs[ARGUS_METRIC_INDEX];
13659 if (metric != NULL) {
13660 retn = ArgusFetchSolo(ns);
13661 pkts = metric->src.pkts + metric->dst.pkts;
13662 if (pkts > 0) {
13663 retn = (retn * 100.0)/(pkts * 1.0);
13664 } else
13665 retn = 0.0;
13666 }
13667 }
13668
13669 return (retn);
13670 }
13671
13672 double
ArgusFetchPercentSrcSolo(struct ArgusRecordStruct * ns)13673 ArgusFetchPercentSrcSolo (struct ArgusRecordStruct *ns)
13674 {
13675 double retn = 0.0;
13676 int pkts = 0;
13677
13678 if (ns) {
13679 struct ArgusMetricStruct *metric = (void *)ns->dsrs[ARGUS_METRIC_INDEX];
13680 if (metric != NULL) {
13681 retn = ArgusFetchSrcSolo(ns);
13682 pkts = metric->src.pkts;
13683 if (pkts > 0) {
13684 retn = (retn * 100.0)/(pkts * 1.0);
13685 } else
13686 retn = 0.0;
13687 }
13688 }
13689
13690 return (retn);
13691 }
13692
13693 double
ArgusFetchPercentDstSolo(struct ArgusRecordStruct * ns)13694 ArgusFetchPercentDstSolo (struct ArgusRecordStruct *ns)
13695 {
13696 double retn = 0.0;
13697 int pkts = 0;
13698
13699 if (ns) {
13700 struct ArgusMetricStruct *metric = (void *)ns->dsrs[ARGUS_METRIC_INDEX];
13701 if (metric != NULL) {
13702 retn = ArgusFetchDstSolo(ns);
13703 pkts = metric->dst.pkts;
13704 if (pkts > 0) {
13705 retn = (retn * 100.0)/(pkts * 1.0);
13706 } else
13707 retn = 0.0;
13708 }
13709 }
13710
13711 return (retn);
13712 }
13713
13714
13715 double
ArgusFetchFirst(struct ArgusRecordStruct * ns)13716 ArgusFetchFirst (struct ArgusRecordStruct *ns)
13717 {
13718 double retn = 0.0;
13719
13720 if (ns) {
13721 if (ns->hdr.type & ARGUS_MAR) {
13722
13723 } else {
13724 struct ArgusNetworkStruct *net = (void *) ns->dsrs[ARGUS_NETWORK_INDEX];
13725
13726 if ((net != NULL) && (net->hdr.subtype == ARGUS_UDT_FLOW)) {
13727 struct ArgusUDTObject *udt = (void *)&net->net_union.udt;
13728 retn = (udt->src.first) * 1.0;
13729 }
13730 }
13731 }
13732
13733 return (retn);
13734 }
13735
13736 double
ArgusFetchSrcFirst(struct ArgusRecordStruct * ns)13737 ArgusFetchSrcFirst (struct ArgusRecordStruct *ns)
13738 {
13739 double retn = 0.0;
13740
13741 if (ns) {
13742 if (ns->hdr.type & ARGUS_MAR) {
13743
13744 } else {
13745 struct ArgusNetworkStruct *net = (void *) ns->dsrs[ARGUS_NETWORK_INDEX];
13746
13747 if ((net != NULL) && (net->hdr.subtype == ARGUS_UDT_FLOW)) {
13748 struct ArgusUDTObject *udt = (void *)&net->net_union.udt;
13749 retn = (udt->src.first) * 1.0;
13750 }
13751 }
13752 }
13753
13754 return (retn);
13755 }
13756
13757 double
ArgusFetchDstFirst(struct ArgusRecordStruct * ns)13758 ArgusFetchDstFirst (struct ArgusRecordStruct *ns)
13759 {
13760 double retn = 0.0;
13761
13762 if (ns) {
13763 if (ns->hdr.type & ARGUS_MAR) {
13764
13765 } else {
13766 struct ArgusNetworkStruct *net = (void *) ns->dsrs[ARGUS_NETWORK_INDEX];
13767
13768 if ((net != NULL) && (net->hdr.subtype == ARGUS_UDT_FLOW)) {
13769 }
13770 }
13771 }
13772
13773 return (retn);
13774 }
13775
13776
13777 double
ArgusFetchPercentFirst(struct ArgusRecordStruct * ns)13778 ArgusFetchPercentFirst (struct ArgusRecordStruct *ns)
13779 {
13780 double retn = 0.0;
13781 int pkts = 0;
13782
13783 if (ns) {
13784 struct ArgusMetricStruct *metric = (void *)ns->dsrs[ARGUS_METRIC_INDEX];
13785 if (metric != NULL) {
13786 retn = ArgusFetchFirst(ns);
13787 pkts = metric->src.pkts + metric->dst.pkts;
13788 if (pkts > 0) {
13789 retn = (retn * 100.0)/(pkts * 1.0);
13790 } else
13791 retn = 0.0;
13792 }
13793 }
13794
13795 return (retn);
13796 }
13797
13798 double
ArgusFetchPercentSrcFirst(struct ArgusRecordStruct * ns)13799 ArgusFetchPercentSrcFirst (struct ArgusRecordStruct *ns)
13800 {
13801 double retn = 0.0;
13802 int pkts = 0;
13803
13804 if (ns) {
13805 struct ArgusMetricStruct *metric = (void *)ns->dsrs[ARGUS_METRIC_INDEX];
13806 if (metric != NULL) {
13807 retn = ArgusFetchSrcFirst(ns);
13808 pkts = metric->src.pkts;
13809 if (pkts > 0) {
13810 retn = (retn * 100.0)/(pkts * 1.0);
13811 } else
13812 retn = 0.0;
13813 }
13814 }
13815
13816 return (retn);
13817 }
13818
13819 double
ArgusFetchPercentDstFirst(struct ArgusRecordStruct * ns)13820 ArgusFetchPercentDstFirst (struct ArgusRecordStruct *ns)
13821 {
13822 double retn = 0.0;
13823 int pkts = 0;
13824
13825 if (ns) {
13826 struct ArgusMetricStruct *metric = (void *)ns->dsrs[ARGUS_METRIC_INDEX];
13827 if (metric != NULL) {
13828 retn = ArgusFetchDstFirst(ns);
13829 pkts = metric->dst.pkts;
13830 if (pkts > 0) {
13831 retn = (retn * 100.0)/(pkts * 1.0);
13832 } else
13833 retn = 0.0;
13834 }
13835 }
13836
13837 return (retn);
13838 }
13839
13840 double
ArgusFetchPercentLoss(struct ArgusRecordStruct * ns)13841 ArgusFetchPercentLoss (struct ArgusRecordStruct *ns)
13842 {
13843 double retn = 0.0;
13844 int pkts = 0;
13845
13846 if (ns) {
13847 struct ArgusMetricStruct *metric = (void *)ns->dsrs[ARGUS_METRIC_INDEX];
13848 if (metric != NULL) {
13849 retn = ArgusFetchLoss(ns);
13850 pkts = metric->src.pkts + metric->dst.pkts;
13851 if (pkts > 0) {
13852 retn = (retn * 100.0)/((pkts * 1.0 )+ retn);
13853 } else
13854 retn = 0.0;
13855 }
13856 }
13857
13858 return (retn);
13859 }
13860
13861 double
ArgusFetchPercentSrcLoss(struct ArgusRecordStruct * ns)13862 ArgusFetchPercentSrcLoss (struct ArgusRecordStruct *ns)
13863 {
13864 double retn = 0.0;
13865 int pkts = 0;
13866
13867 if (ns) {
13868 struct ArgusMetricStruct *metric = (void *)ns->dsrs[ARGUS_METRIC_INDEX];
13869 if (metric != NULL) {
13870 retn = ArgusFetchSrcLoss(ns);
13871 pkts = metric->src.pkts;
13872 if (pkts > 0) {
13873 retn = (retn * 100.0)/((pkts * 1.0) + retn);
13874 } else
13875 retn = 0.0;
13876 }
13877 }
13878
13879 return (retn);
13880 }
13881
13882 double
ArgusFetchPercentDstLoss(struct ArgusRecordStruct * ns)13883 ArgusFetchPercentDstLoss (struct ArgusRecordStruct *ns)
13884 {
13885 double retn = 0.0;
13886 int pkts = 0;
13887
13888 if (ns) {
13889 struct ArgusMetricStruct *metric = (void *)ns->dsrs[ARGUS_METRIC_INDEX];
13890 if (metric != NULL) {
13891 retn = ArgusFetchDstLoss(ns);
13892 pkts = metric->dst.pkts;
13893 if (pkts > 0) {
13894 retn = (retn * 100.0)/((pkts * 1.0) + retn);
13895 } else
13896 retn = 0.0;
13897 }
13898 }
13899
13900 return (retn);
13901 }
13902
13903 double
ArgusFetchSrcRate(struct ArgusRecordStruct * ns)13904 ArgusFetchSrcRate (struct ArgusRecordStruct *ns)
13905 {
13906 double retn = ns->srate;
13907 return (retn);
13908 }
13909
13910 double
ArgusFetchDstRate(struct ArgusRecordStruct * ns)13911 ArgusFetchDstRate (struct ArgusRecordStruct *ns)
13912 {
13913 double retn = ns->drate;
13914 return (retn);
13915 }
13916
13917 double
ArgusFetchRate(struct ArgusRecordStruct * ns)13918 ArgusFetchRate (struct ArgusRecordStruct *ns)
13919 {
13920 struct ArgusMetricStruct *m1 = NULL;
13921 float d1 = RaGetFloatDuration(ns);
13922 long long cnt1 = 0;
13923 double retn = 0.0;
13924
13925 if ((m1 = (struct ArgusMetricStruct *) ns->dsrs[ARGUS_METRIC_INDEX]) != NULL)
13926 cnt1 = (m1->src.pkts + m1->dst.pkts);
13927
13928 if ((cnt1 > 0) && (d1 > 0.0))
13929 retn = (cnt1 * 1.0)/d1;
13930
13931 return (retn);
13932
13933 }
13934
13935 double
ArgusFetchSrcMeanPktSize(struct ArgusRecordStruct * ns)13936 ArgusFetchSrcMeanPktSize (struct ArgusRecordStruct *ns)
13937 {
13938 struct ArgusMetricStruct *m1 = NULL;
13939 long long pkts = 0, bytes = 0;
13940 double retn = 0.0;
13941
13942 if ((m1 = (struct ArgusMetricStruct *) ns->dsrs[ARGUS_METRIC_INDEX]) != NULL) {
13943 pkts = m1->src.pkts;
13944 bytes = m1->src.bytes;
13945 }
13946
13947 if (pkts > 0)
13948 retn = (bytes * 1.0)/(pkts * 1.0);
13949
13950 return (retn);
13951 }
13952
13953 double
ArgusFetchDstMeanPktSize(struct ArgusRecordStruct * ns)13954 ArgusFetchDstMeanPktSize (struct ArgusRecordStruct *ns)
13955 {
13956 struct ArgusMetricStruct *m1 = NULL;
13957 long long pkts = 0, bytes = 0;
13958 double retn = 0.0;
13959
13960 if ((m1 = (struct ArgusMetricStruct *) ns->dsrs[ARGUS_METRIC_INDEX]) != NULL) {
13961 pkts = m1->dst.pkts;
13962 bytes = m1->dst.bytes;
13963 }
13964
13965 if (pkts > 0)
13966 retn = (bytes * 1.0)/(pkts * 1.0);
13967
13968 return (retn);
13969 }
13970
13971
13972 double
ArgusFetchTranRef(struct ArgusRecordStruct * ns)13973 ArgusFetchTranRef (struct ArgusRecordStruct *ns)
13974 {
13975 double retn = 0;
13976 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
13977 }
13978
13979 double
ArgusFetchSeq(struct ArgusRecordStruct * ns)13980 ArgusFetchSeq (struct ArgusRecordStruct *ns)
13981 {
13982 struct ArgusTransportStruct *t1 = (struct ArgusTransportStruct *)ns->dsrs[ARGUS_TRANSPORT_INDEX];
13983 double retn = 0;
13984
13985 if (t1->hdr.subtype & ARGUS_SEQ)
13986 retn = t1->seqnum;
13987 return (retn);
13988 }
13989
13990
13991 double
ArgusFetchByteCount(struct ArgusRecordStruct * ns)13992 ArgusFetchByteCount (struct ArgusRecordStruct *ns)
13993 {
13994 struct ArgusMetricStruct *m1 = NULL;
13995 double retn = 0;
13996
13997 if ((m1 = (struct ArgusMetricStruct *) ns->dsrs[ARGUS_METRIC_INDEX]) != NULL)
13998 retn = m1->src.bytes + m1->dst.bytes;
13999 return (retn);
14000 }
14001
14002 double
ArgusFetchSrcByteCount(struct ArgusRecordStruct * ns)14003 ArgusFetchSrcByteCount (struct ArgusRecordStruct *ns)
14004 {
14005 struct ArgusMetricStruct *m1 = NULL;
14006 double retn = 0;
14007
14008 if ((m1 = (struct ArgusMetricStruct *) ns->dsrs[ARGUS_METRIC_INDEX]) != NULL)
14009 retn = m1->src.bytes;
14010 return (retn);
14011 }
14012
14013 double
ArgusFetchDstByteCount(struct ArgusRecordStruct * ns)14014 ArgusFetchDstByteCount (struct ArgusRecordStruct *ns)
14015 {
14016 struct ArgusMetricStruct *m1 = NULL;
14017 double retn = 0;
14018
14019 if ((m1 = (struct ArgusMetricStruct *) ns->dsrs[ARGUS_METRIC_INDEX]) != NULL)
14020 retn = m1->dst.bytes;
14021
14022 return (retn);
14023 }
14024
14025
14026 double
ArgusFetchPktsCount(struct ArgusRecordStruct * ns)14027 ArgusFetchPktsCount (struct ArgusRecordStruct *ns)
14028 {
14029 struct ArgusMetricStruct *m1 = NULL;
14030 double retn = 0;
14031
14032 if ((m1 = (struct ArgusMetricStruct *) ns->dsrs[ARGUS_METRIC_INDEX]) != NULL)
14033 retn = m1->src.pkts + m1->dst.pkts;
14034 return (retn);
14035 }
14036
14037 double
ArgusFetchSrcPktsCount(struct ArgusRecordStruct * ns)14038 ArgusFetchSrcPktsCount (struct ArgusRecordStruct *ns)
14039 {
14040 struct ArgusMetricStruct *m1 = NULL;
14041 double retn = 0;
14042
14043 if ((m1 = (struct ArgusMetricStruct *) ns->dsrs[ARGUS_METRIC_INDEX]) != NULL)
14044 retn = m1->src.pkts;
14045 return (retn);
14046 }
14047
14048 double
ArgusFetchDstPktsCount(struct ArgusRecordStruct * ns)14049 ArgusFetchDstPktsCount (struct ArgusRecordStruct *ns)
14050 {
14051 struct ArgusMetricStruct *m1 = NULL;
14052 double retn = 0;
14053
14054 if ((m1 = (struct ArgusMetricStruct *) ns->dsrs[ARGUS_METRIC_INDEX]) != NULL)
14055 retn = m1->dst.pkts;
14056 return (retn);
14057 }
14058
14059 double
ArgusFetchAppByteCount(struct ArgusRecordStruct * ns)14060 ArgusFetchAppByteCount (struct ArgusRecordStruct *ns)
14061 {
14062 struct ArgusMetricStruct *m1 = NULL;
14063 double retn = 0;
14064
14065 if ((m1 = (struct ArgusMetricStruct *) ns->dsrs[ARGUS_METRIC_INDEX]) != NULL)
14066 retn = m1->src.appbytes + m1->dst.appbytes;
14067 return (retn);
14068 }
14069
14070 double
ArgusFetchSrcAppByteCount(struct ArgusRecordStruct * ns)14071 ArgusFetchSrcAppByteCount (struct ArgusRecordStruct *ns)
14072 {
14073 struct ArgusMetricStruct *m1 = NULL;
14074 double retn = 0;
14075
14076 if ((m1 = (struct ArgusMetricStruct *) ns->dsrs[ARGUS_METRIC_INDEX]) != NULL)
14077 retn = m1->src.appbytes;
14078 return (retn);
14079 }
14080
14081 double
ArgusFetchDstAppByteCount(struct ArgusRecordStruct * ns)14082 ArgusFetchDstAppByteCount (struct ArgusRecordStruct *ns)
14083 {
14084 struct ArgusMetricStruct *m1 = NULL;
14085 double retn = 0;
14086
14087 if ((m1 = (struct ArgusMetricStruct *) ns->dsrs[ARGUS_METRIC_INDEX]) != NULL)
14088 retn = m1->dst.appbytes;
14089
14090 return (retn);
14091 }
14092
14093 double
ArgusFetchAppByteRatio(struct ArgusRecordStruct * ns)14094 ArgusFetchAppByteRatio (struct ArgusRecordStruct *ns)
14095 {
14096 struct ArgusMetricStruct *m1 = NULL;
14097 double retn = 0.0;
14098
14099 if ((m1 = (struct ArgusMetricStruct *) ns->dsrs[ARGUS_METRIC_INDEX]) != NULL) {
14100 double nvalue = (m1->src.appbytes - m1->dst.appbytes) * 1.0;
14101 double dvalue = (m1->src.appbytes + m1->dst.appbytes) * 1.0;
14102
14103 if (dvalue > 0)
14104 retn = nvalue / dvalue;
14105 else
14106 retn = -0.0;
14107 }
14108 return (retn);
14109 }
14110
14111 double
ArgusFetchSrcTcpBase(struct ArgusRecordStruct * ns)14112 ArgusFetchSrcTcpBase (struct ArgusRecordStruct *ns)
14113 {
14114 struct ArgusNetworkStruct *net = (void *)ns->dsrs[ARGUS_NETWORK_INDEX];
14115 struct ArgusFlow *flow = (void *)ns->dsrs[ARGUS_FLOW_INDEX];
14116 unsigned int seq = 0;
14117 double retn = 0;
14118
14119 if ((flow != NULL) && (net != NULL)) {
14120 struct ArgusTCPObject *tcp = &net->net_union.tcp;
14121
14122 switch (flow->hdr.subtype & 0x3F) {
14123 case ARGUS_FLOW_CLASSIC5TUPLE: {
14124 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
14125 case ARGUS_TYPE_IPV4:
14126 switch (flow->ip_flow.ip_p) {
14127 case IPPROTO_TCP:
14128 seq = tcp->src.seqbase;
14129 break;
14130 }
14131 break;
14132
14133 case ARGUS_TYPE_IPV6:
14134 switch (flow->ipv6_flow.ip_p) {
14135 case IPPROTO_TCP:
14136 seq = tcp->src.seqbase;
14137 break;
14138 }
14139 break;
14140 }
14141 break;
14142 }
14143 }
14144 }
14145
14146 retn = seq;
14147 return (retn);
14148 }
14149
14150
14151 double
ArgusFetchDstTcpBase(struct ArgusRecordStruct * ns)14152 ArgusFetchDstTcpBase (struct ArgusRecordStruct *ns)
14153 {
14154 struct ArgusNetworkStruct *net = (void *)ns->dsrs[ARGUS_NETWORK_INDEX];
14155 struct ArgusFlow *flow = (void *)ns->dsrs[ARGUS_FLOW_INDEX];
14156 unsigned int seq = 0;
14157 double retn = 0;
14158
14159 if ((flow != NULL) && (net != NULL)) {
14160 struct ArgusTCPObject *tcp = &net->net_union.tcp;
14161
14162 switch (flow->hdr.subtype & 0x3F) {
14163 case ARGUS_FLOW_CLASSIC5TUPLE: {
14164 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
14165 case ARGUS_TYPE_IPV4:
14166 switch (flow->ip_flow.ip_p) {
14167 case IPPROTO_TCP:
14168 seq = tcp->dst.seqbase;
14169 break;
14170 }
14171 break;
14172
14173 case ARGUS_TYPE_IPV6:
14174 switch (flow->ipv6_flow.ip_p) {
14175 case IPPROTO_TCP:
14176 seq = tcp->dst.seqbase;
14177 break;
14178 }
14179 break;
14180 }
14181 break;
14182 }
14183 }
14184 }
14185
14186 retn = seq;
14187 return (retn);
14188 }
14189
14190 double
ArgusFetchTcpRtt(struct ArgusRecordStruct * ns)14191 ArgusFetchTcpRtt (struct ArgusRecordStruct *ns)
14192 {
14193 struct ArgusNetworkStruct *net = (void *)ns->dsrs[ARGUS_NETWORK_INDEX];
14194 struct ArgusFlow *flow = (void *)ns->dsrs[ARGUS_FLOW_INDEX];
14195 unsigned int rtt = 0;
14196 double retn = 0;
14197
14198 if ((flow != NULL) && (net != NULL)) {
14199 struct ArgusTCPObject *tcp = &net->net_union.tcp;
14200
14201 switch (flow->hdr.subtype & 0x3F) {
14202
14203
14204 case ARGUS_FLOW_CLASSIC5TUPLE: {
14205 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
14206 case ARGUS_TYPE_IPV4:
14207 switch (flow->ip_flow.ip_p) {
14208 case IPPROTO_TCP:
14209 rtt = tcp->synAckuSecs + tcp->ackDatauSecs;
14210 break;
14211 }
14212 break;
14213
14214 case ARGUS_TYPE_IPV6:
14215 switch (flow->ipv6_flow.ip_p) {
14216 case IPPROTO_TCP:
14217 rtt = tcp->synAckuSecs + tcp->ackDatauSecs;
14218 break;
14219 }
14220 break;
14221 }
14222 break;
14223 }
14224 }
14225 }
14226
14227 retn = (rtt * 1.0)/1000000.0;
14228 return (retn);
14229 }
14230
14231
14232 double
ArgusFetchTcpSynAck(struct ArgusRecordStruct * ns)14233 ArgusFetchTcpSynAck (struct ArgusRecordStruct *ns)
14234 {
14235 struct ArgusNetworkStruct *net = (void *)ns->dsrs[ARGUS_NETWORK_INDEX];
14236 struct ArgusFlow *flow = (void *)ns->dsrs[ARGUS_FLOW_INDEX];
14237 unsigned int value = 0;
14238 double retn = 0;
14239
14240 if ((flow != NULL) && (net != NULL)) {
14241 struct ArgusTCPObject *tcp = &net->net_union.tcp;
14242
14243 switch (flow->hdr.subtype & 0x3F) {
14244 case ARGUS_FLOW_CLASSIC5TUPLE: {
14245 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
14246 case ARGUS_TYPE_IPV4:
14247 switch (flow->ip_flow.ip_p) {
14248 case IPPROTO_TCP:
14249 value = tcp->synAckuSecs;
14250 break;
14251 }
14252 break;
14253
14254 case ARGUS_TYPE_IPV6:
14255 switch (flow->ipv6_flow.ip_p) {
14256 case IPPROTO_TCP:
14257 value = tcp->synAckuSecs;
14258 break;
14259 }
14260 break;
14261 }
14262 break;
14263 }
14264 }
14265 }
14266
14267 retn = (value * 1.0)/1000000.0;
14268 return (retn);
14269 }
14270
14271 double
ArgusFetchTcpAckDat(struct ArgusRecordStruct * ns)14272 ArgusFetchTcpAckDat (struct ArgusRecordStruct *ns)
14273 {
14274 struct ArgusNetworkStruct *net = (void *)ns->dsrs[ARGUS_NETWORK_INDEX];
14275 struct ArgusFlow *flow = (void *)ns->dsrs[ARGUS_FLOW_INDEX];
14276 unsigned int value = 0;
14277 double retn = 0;
14278
14279 if ((flow != NULL) && (net != NULL)) {
14280 struct ArgusTCPObject *tcp = &net->net_union.tcp;
14281
14282 switch (flow->hdr.subtype & 0x3F) {
14283 case ARGUS_FLOW_CLASSIC5TUPLE: {
14284 switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
14285 case ARGUS_TYPE_IPV4:
14286 switch (flow->ip_flow.ip_p) {
14287 case IPPROTO_TCP:
14288 value = tcp->ackDatauSecs;
14289 break;
14290 }
14291 break;
14292
14293 case ARGUS_TYPE_IPV6:
14294 switch (flow->ipv6_flow.ip_p) {
14295 case IPPROTO_TCP:
14296 value = tcp->ackDatauSecs;
14297 break;
14298 }
14299 break;
14300 }
14301 break;
14302 }
14303 }
14304 }
14305
14306 retn = (value * 1.0)/1000000.0;
14307 return (retn);
14308 }
14309
14310 double
ArgusFetchSrcTcpMax(struct ArgusRecordStruct * ns)14311 ArgusFetchSrcTcpMax (struct ArgusRecordStruct *ns)
14312 {
14313 struct ArgusNetworkStruct *net = (void *)ns->dsrs[ARGUS_NETWORK_INDEX];
14314 struct ArgusFlow *flow = (void *)ns->dsrs[ARGUS_FLOW_INDEX];
14315 double rtt = 0.0, retn = 0.0;
14316
14317 if ((flow != NULL) && (net != NULL)) {
14318 struct ArgusMetricStruct *metric = (void *)ns->dsrs[ARGUS_METRIC_INDEX];
14319 struct ArgusTCPObject *tcp = &net->net_union.tcp;
14320
14321 switch (flow->hdr.subtype & 0x3F) {
14322 case ARGUS_FLOW_CLASSIC5TUPLE: {
14323 switch ((flow->hdr.argus_dsrvl8.qual & 0x1F)) {
14324 case ARGUS_TYPE_IPV4:
14325 switch (flow->ip_flow.ip_p) {
14326 case IPPROTO_TCP: {
14327 if ((rtt = ArgusFetchTcpRtt(ns)) > 0.0) {
14328 double synack, ackdat;
14329 synack = ArgusFetchTcpSynAck(ns);
14330 ackdat = ArgusFetchTcpAckDat(ns);
14331 if (ackdat < 0.000100) {
14332 rtt = synack;
14333 } else
14334 if (synack < 0.000100) {
14335 rtt = ackdat;
14336 }
14337
14338 if ((metric != NULL) && (metric->dst.pkts > 0)) {
14339 unsigned int win = tcp->dst.win << tcp->dst.winshift;
14340 retn = (win * 8.0) / (rtt * 1000);
14341 }
14342 break;
14343 }
14344 }
14345 default:
14346 break;
14347 }
14348 break;
14349
14350 case ARGUS_TYPE_IPV6:
14351 switch (flow->ipv6_flow.ip_p) {
14352 case IPPROTO_TCP: {
14353 if ((rtt = ArgusFetchTcpRtt(ns)) > 0.0) {
14354 double synack, ackdat;
14355 synack = ArgusFetchTcpSynAck(ns);
14356 ackdat = ArgusFetchTcpAckDat(ns);
14357 if (ackdat < 0.000100) {
14358 rtt = synack;
14359 } else
14360 if (synack < 0.000100) {
14361 rtt = ackdat;
14362 }
14363 if ((metric != NULL) && (metric->dst.pkts > 0)) {
14364 unsigned int win = tcp->dst.win << tcp->dst.winshift;
14365 retn = (win * 8.0) / (rtt * 1000);
14366 }
14367 break;
14368 }
14369 }
14370 default:
14371 break;
14372 }
14373 break;
14374 }
14375 break;
14376 }
14377
14378 default:
14379 break;
14380 }
14381 }
14382 return (retn);
14383 }
14384
14385
14386 double
ArgusFetchDstTcpMax(struct ArgusRecordStruct * ns)14387 ArgusFetchDstTcpMax (struct ArgusRecordStruct *ns)
14388 {
14389 struct ArgusNetworkStruct *net = (void *)ns->dsrs[ARGUS_NETWORK_INDEX];
14390 struct ArgusFlow *flow = (void *)ns->dsrs[ARGUS_FLOW_INDEX];
14391 double rtt = 0.0, retn = 0.0;
14392
14393 if ((flow != NULL) && (net != NULL)) {
14394 struct ArgusMetricStruct *metric = (void *)ns->dsrs[ARGUS_METRIC_INDEX];
14395 struct ArgusTCPObject *tcp = &net->net_union.tcp;
14396
14397 switch (flow->hdr.subtype & 0x3F) {
14398 case ARGUS_FLOW_CLASSIC5TUPLE: {
14399 switch ((flow->hdr.argus_dsrvl8.qual & 0x1F)) {
14400 case ARGUS_TYPE_IPV4:
14401 switch (flow->ip_flow.ip_p) {
14402 case IPPROTO_TCP: {
14403 if ((rtt = ArgusFetchTcpRtt(ns)) > 0.0) {
14404 double synack, ackdat;
14405 synack = ArgusFetchTcpSynAck(ns);
14406 ackdat = ArgusFetchTcpAckDat(ns);
14407 if (ackdat < 0.000100) {
14408 rtt = synack;
14409 } else
14410 if (synack < 0.000100) {
14411 rtt = ackdat;
14412 }
14413
14414 if ((metric != NULL) && (metric->src.pkts > 0)) {
14415 unsigned int win = tcp->src.win << tcp->src.winshift;
14416 retn = (win * 8.0) / rtt;
14417 }
14418 }
14419 break;
14420 }
14421 default:
14422 break;
14423 }
14424 break;
14425
14426 case ARGUS_TYPE_IPV6:
14427 switch (flow->ipv6_flow.ip_p) {
14428 case IPPROTO_TCP: {
14429 if ((rtt = ArgusFetchTcpRtt(ns)) > 0.0) {
14430 double synack, ackdat;
14431 synack = ArgusFetchTcpSynAck(ns);
14432 ackdat = ArgusFetchTcpAckDat(ns);
14433 if (ackdat < 0.000100) {
14434 rtt = synack;
14435 } else
14436 if (synack < 0.000100) {
14437 rtt = ackdat;
14438 }
14439
14440 if ((metric != NULL) && (metric->src.pkts > 0)) {
14441 unsigned int win = tcp->src.win << tcp->src.winshift;
14442 retn = (win * 8.0) / rtt;
14443 }
14444 }
14445 break;
14446 }
14447 default:
14448 break;
14449 }
14450 break;
14451 }
14452 break;
14453 }
14454
14455 default:
14456 break;
14457 }
14458 }
14459 return (retn);
14460 }
14461
14462
14463 double
ArgusFetchSrcGap(struct ArgusRecordStruct * ns)14464 ArgusFetchSrcGap (struct ArgusRecordStruct *ns)
14465 {
14466 struct ArgusNetworkStruct *net = (void *)ns->dsrs[ARGUS_NETWORK_INDEX];
14467 struct ArgusFlow *flow = (void *)ns->dsrs[ARGUS_FLOW_INDEX];
14468 double retn = -1;
14469
14470 if ((flow != NULL) && (net != NULL)) {
14471 switch (flow->hdr.subtype & 0x3F) {
14472 case ARGUS_FLOW_CLASSIC5TUPLE: {
14473 switch ((flow->hdr.argus_dsrvl8.qual & 0x1F)) {
14474 case ARGUS_TYPE_IPV4:
14475 switch (flow->ip_flow.ip_p) {
14476 case IPPROTO_TCP: {
14477 retn = 0;
14478 switch (net->hdr.subtype) {
14479 case ARGUS_TCP_INIT:
14480 case ARGUS_TCP_STATUS:
14481 break;
14482
14483 case ARGUS_TCP_PERF: {
14484 struct ArgusTCPObject *tcp = (struct ArgusTCPObject *) &net->net_union.tcp;
14485 if ((tcp->src.seqbase == tcp->src.ackbytes) || (tcp->src.seq == 0)) // prior version of argus
14486 break;
14487
14488 if (!tcp->src.retrans) {
14489 retn = (tcp->src.seq - tcp->src.seqbase);
14490 if ((retn == tcp->src.bytes) || (retn == (tcp->src.bytes - tcp->src.winbytes)))
14491 retn = 0;
14492 else {
14493 if ((retn -= tcp->src.bytes) < 0)
14494 retn = 0;
14495 if (retn > 0) retn--;
14496 }
14497 }
14498 break;
14499 }
14500 }
14501 break;
14502 }
14503 default:
14504 break;
14505 }
14506 break;
14507
14508 case ARGUS_TYPE_IPV6:
14509 switch (flow->ipv6_flow.ip_p) {
14510 case IPPROTO_TCP: {
14511 retn = 0;
14512 switch (net->hdr.subtype) {
14513 case ARGUS_TCP_INIT:
14514 case ARGUS_TCP_STATUS:
14515 break;
14516
14517 case ARGUS_TCP_PERF: {
14518 struct ArgusTCPObject *tcp = (struct ArgusTCPObject *) &net->net_union.tcp;
14519 if ((tcp->src.seqbase == tcp->src.ackbytes) || (tcp->src.seq == 0)) // prior version of argus
14520 break;
14521
14522 if (!tcp->src.retrans) {
14523 retn = (tcp->src.seq - tcp->src.seqbase);
14524 if ((retn == tcp->src.bytes) || (retn == (tcp->src.bytes - tcp->src.winbytes)))
14525 retn = 0;
14526 else {
14527 if ((retn -= tcp->src.bytes) < 0)
14528 retn = 0;
14529 if (retn > 0) retn--;
14530 }
14531 }
14532 break;
14533 }
14534 }
14535 break;
14536 }
14537 default:
14538 break;
14539 }
14540 break;
14541 }
14542 break;
14543 }
14544
14545 default:
14546 break;
14547 }
14548 }
14549 return (retn);
14550 }
14551
14552 double
ArgusFetchDstGap(struct ArgusRecordStruct * ns)14553 ArgusFetchDstGap (struct ArgusRecordStruct *ns)
14554 {
14555 struct ArgusNetworkStruct *net = (void *)ns->dsrs[ARGUS_NETWORK_INDEX];
14556 struct ArgusFlow *flow = (void *)ns->dsrs[ARGUS_FLOW_INDEX];
14557 double retn = -1;
14558
14559 if ((flow != NULL) && (net != NULL)) {
14560 switch (flow->hdr.subtype & 0x3F) {
14561 case ARGUS_FLOW_CLASSIC5TUPLE: {
14562 switch ((flow->hdr.argus_dsrvl8.qual & 0x1F)) {
14563 case ARGUS_TYPE_IPV4:
14564 switch (flow->ip_flow.ip_p) {
14565 case IPPROTO_TCP: {
14566 retn = 0;
14567 switch (net->hdr.subtype) {
14568 case ARGUS_TCP_INIT:
14569 case ARGUS_TCP_STATUS:
14570 break;
14571
14572 case ARGUS_TCP_PERF: {
14573 struct ArgusTCPObject *tcp = (struct ArgusTCPObject *) &net->net_union.tcp;
14574 if ((tcp->dst.seqbase == tcp->dst.ackbytes) || (tcp->dst.seq == 0)) // prior version of argus
14575 break;
14576
14577 if (!tcp->dst.retrans) {
14578 retn = (tcp->dst.seq - tcp->dst.seqbase);
14579 if ((retn == tcp->dst.bytes) || (retn == (tcp->dst.bytes - tcp->dst.winbytes)))
14580 retn = 0;
14581 else {
14582 if ((retn -= tcp->dst.bytes) < 0)
14583 retn = 0;
14584 if (retn > 0) retn--;
14585 }
14586 }
14587 break;
14588 }
14589 }
14590 break;
14591 }
14592 default:
14593 break;
14594 }
14595 break;
14596
14597 case ARGUS_TYPE_IPV6:
14598 switch (flow->ipv6_flow.ip_p) {
14599 case IPPROTO_TCP: {
14600 retn = 0;
14601 switch (net->hdr.subtype) {
14602 case ARGUS_TCP_INIT:
14603 case ARGUS_TCP_STATUS:
14604 break;
14605
14606 case ARGUS_TCP_PERF: {
14607 struct ArgusTCPObject *tcp = (struct ArgusTCPObject *) &net->net_union.tcp;
14608 if ((tcp->dst.seqbase == tcp->dst.ackbytes) || (tcp->dst.seq == 0)) // prior version of argus
14609 break;
14610
14611 if (!tcp->dst.retrans) {
14612 retn = (tcp->dst.seq - tcp->dst.seqbase);
14613 if ((retn == tcp->dst.bytes) || (retn == (tcp->dst.bytes - tcp->dst.winbytes)))
14614 retn = 0;
14615 else {
14616 if ((retn -= tcp->dst.bytes) < 0)
14617 retn = 0;
14618 if (retn > 0) retn--;
14619 }
14620 }
14621 break;
14622 }
14623 }
14624 break;
14625 }
14626 default:
14627 break;
14628 }
14629 break;
14630 }
14631 break;
14632 }
14633
14634 default:
14635 break;
14636 }
14637 }
14638 return (retn);
14639 }
14640
14641 /*
14642 double
14643 ArgusFetchSrcDup (struct ArgusRecordStruct *ns)
14644 {
14645 struct ArgusNetworkStruct *net = (void *)ns->dsrs[ARGUS_NETWORK_INDEX];
14646 struct ArgusFlow *flow = (void *)ns->dsrs[ARGUS_FLOW_INDEX];
14647 double retn = -1;
14648
14649 if ((flow != NULL) && (net != NULL)) {
14650 switch (flow->hdr.subtype & 0x3F) {
14651 case ARGUS_FLOW_CLASSIC5TUPLE: {
14652 switch ((flow->hdr.argus_dsrvl8.qual & 0x1F)) {
14653 case ARGUS_TYPE_IPV4:
14654 switch (flow->ip_flow.ip_p) {
14655 case IPPROTO_TCP: {
14656 retn = 0;
14657 switch (net->hdr.subtype) {
14658 case ARGUS_TCP_INIT:
14659 case ARGUS_TCP_STATUS:
14660 break;
14661
14662 case ARGUS_TCP_PERF: {
14663 struct ArgusTCPObject *tcp = (struct ArgusTCPObject *) &net->net_union.tcp;
14664 retn = tcp->sdups;
14665 break;
14666 }
14667 }
14668 break;
14669 }
14670 default:
14671 break;
14672 }
14673 break;
14674
14675 case ARGUS_TYPE_IPV6:
14676 switch (flow->ipv6_flow.ip_p) {
14677 case IPPROTO_TCP: {
14678 retn = 0;
14679 switch (net->hdr.subtype) {
14680 case ARGUS_TCP_INIT:
14681 case ARGUS_TCP_STATUS:
14682 break;
14683
14684 case ARGUS_TCP_PERF: {
14685 struct ArgusTCPObject *tcp = (struct ArgusTCPObject *) &net->net_union.tcp;
14686 retn = tcp->sdups;
14687 break;
14688 }
14689 }
14690 break;
14691 }
14692 default:
14693 break;
14694 }
14695 break;
14696 }
14697 break;
14698 }
14699
14700 default:
14701 break;
14702 }
14703 }
14704 return (retn);
14705 }
14706
14707 double
14708 ArgusFetchDstDup (struct ArgusRecordStruct *ns)
14709 {
14710 struct ArgusNetworkStruct *net = (void *)ns->dsrs[ARGUS_NETWORK_INDEX];
14711 struct ArgusFlow *flow = (void *)ns->dsrs[ARGUS_FLOW_INDEX];
14712 double retn = -1;
14713
14714 if ((flow != NULL) && (net != NULL)) {
14715 switch (flow->hdr.subtype & 0x3F) {
14716 case ARGUS_FLOW_CLASSIC5TUPLE: {
14717 switch ((flow->hdr.argus_dsrvl8.qual & 0x1F)) {
14718 case ARGUS_TYPE_IPV4:
14719 switch (flow->ip_flow.ip_p) {
14720 case IPPROTO_TCP: {
14721 retn = 0;
14722 switch (net->hdr.subtype) {
14723 case ARGUS_TCP_INIT:
14724 case ARGUS_TCP_STATUS:
14725 break;
14726
14727 case ARGUS_TCP_PERF: {
14728 struct ArgusTCPObject *tcp = (struct ArgusTCPObject *) &net->net_union.tcp;
14729 retn = tcp->ddups;
14730 break;
14731 }
14732 }
14733 break;
14734 }
14735 default:
14736 break;
14737 }
14738 break;
14739
14740 case ARGUS_TYPE_IPV6:
14741 switch (flow->ipv6_flow.ip_p) {
14742 case IPPROTO_TCP: {
14743 retn = 0;
14744 switch (net->hdr.subtype) {
14745 case ARGUS_TCP_INIT:
14746 case ARGUS_TCP_STATUS:
14747 break;
14748
14749 case ARGUS_TCP_PERF: {
14750 struct ArgusTCPObject *tcp = (struct ArgusTCPObject *) &net->net_union.tcp;
14751 retn = tcp->ddups;
14752 break;
14753 }
14754 }
14755 break;
14756 }
14757 default:
14758 break;
14759 }
14760 break;
14761 }
14762 break;
14763 }
14764
14765 default:
14766 break;
14767 }
14768 }
14769 return (retn);
14770 }
14771 */
14772
14773
14774 double
ArgusFetchSrcIntPkt(struct ArgusRecordStruct * ns)14775 ArgusFetchSrcIntPkt (struct ArgusRecordStruct *ns)
14776 {
14777 double retn = 0.0;
14778 struct ArgusJitterStruct *jitter;
14779
14780 if (ns->hdr.type & ARGUS_MAR) {
14781
14782 } else {
14783 unsigned int n;
14784
14785 if ((jitter = (struct ArgusJitterStruct *)ns->dsrs[ARGUS_JITTER_INDEX]) != NULL) {
14786 if ((n = (jitter->src.act.n + jitter->src.idle.n)) > 0) {
14787 if (jitter->src.act.n && jitter->src.idle.n) {
14788 retn = ((jitter->src.act.meanval * jitter->src.act.n) +
14789 (jitter->src.idle.meanval * jitter->src.idle.n)) / n;
14790 } else {
14791 retn = (jitter->src.act.n) ? jitter->src.act.meanval : jitter->src.idle.meanval;
14792 }
14793 }
14794 }
14795 }
14796
14797 return (retn/1000.0);
14798 }
14799
14800 double
ArgusFetchSrcIntPktAct(struct ArgusRecordStruct * ns)14801 ArgusFetchSrcIntPktAct (struct ArgusRecordStruct *ns)
14802 {
14803 double retn = 0.0;
14804 struct ArgusJitterStruct *jitter;
14805
14806 if (ns->hdr.type & ARGUS_MAR) {
14807
14808 } else {
14809 if ((jitter = (struct ArgusJitterStruct *)ns->dsrs[ARGUS_JITTER_INDEX]) != NULL)
14810 if (jitter->src.act.n > 0)
14811 retn = jitter->src.act.meanval;
14812 }
14813
14814 return (retn/1000.0);
14815 }
14816
14817 double
ArgusFetchSrcIntPktActMin(struct ArgusRecordStruct * ns)14818 ArgusFetchSrcIntPktActMin (struct ArgusRecordStruct *ns)
14819 {
14820 double retn = 0.0;
14821 struct ArgusJitterStruct *jitter;
14822
14823 if (ns->hdr.type & ARGUS_MAR) {
14824
14825 } else {
14826 if ((jitter = (struct ArgusJitterStruct *)ns->dsrs[ARGUS_JITTER_INDEX]) != NULL)
14827 if (jitter->src.act.n > 0)
14828 retn = jitter->src.act.minval;
14829 }
14830
14831 return (retn/1000.0);
14832 }
14833
14834 double
ArgusFetchSrcIntPktActMax(struct ArgusRecordStruct * ns)14835 ArgusFetchSrcIntPktActMax (struct ArgusRecordStruct *ns)
14836 {
14837 double retn = 0.0;
14838 struct ArgusJitterStruct *jitter;
14839
14840 if (ns->hdr.type & ARGUS_MAR) {
14841
14842 } else {
14843 if ((jitter = (struct ArgusJitterStruct *)ns->dsrs[ARGUS_JITTER_INDEX]) != NULL)
14844 if (jitter->src.act.n > 0)
14845 retn = jitter->src.act.maxval;
14846 }
14847
14848 return (retn/1000.0);
14849 }
14850
14851 double
ArgusFetchSrcIntPktIdl(struct ArgusRecordStruct * ns)14852 ArgusFetchSrcIntPktIdl (struct ArgusRecordStruct *ns)
14853 {
14854 double retn = 0.0;
14855 struct ArgusJitterStruct *jitter;
14856
14857 if (ns->hdr.type & ARGUS_MAR) {
14858
14859 } else {
14860 if ((jitter = (struct ArgusJitterStruct *)ns->dsrs[ARGUS_JITTER_INDEX]) != NULL)
14861 if (jitter->src.idle.n > 0)
14862 retn = jitter->src.idle.meanval;
14863 }
14864
14865 return (retn/1000.0);
14866 }
14867
14868
14869 double
ArgusFetchSrcIntPktIdlMin(struct ArgusRecordStruct * ns)14870 ArgusFetchSrcIntPktIdlMin (struct ArgusRecordStruct *ns)
14871 {
14872 double retn = 0.0;
14873 struct ArgusJitterStruct *jitter;
14874
14875 if (ns->hdr.type & ARGUS_MAR) {
14876
14877 } else {
14878 if ((jitter = (struct ArgusJitterStruct *)ns->dsrs[ARGUS_JITTER_INDEX]) != NULL)
14879 if (jitter->src.idle.n > 0)
14880 retn = jitter->src.idle.minval;
14881 }
14882
14883 return (retn/1000.0);
14884 }
14885
14886 double
ArgusFetchSrcIntPktIdlMax(struct ArgusRecordStruct * ns)14887 ArgusFetchSrcIntPktIdlMax (struct ArgusRecordStruct *ns)
14888 {
14889 double retn = 0.0;
14890 struct ArgusJitterStruct *jitter;
14891
14892 if (ns->hdr.type & ARGUS_MAR) {
14893
14894 } else {
14895 if ((jitter = (struct ArgusJitterStruct *)ns->dsrs[ARGUS_JITTER_INDEX]) != NULL)
14896 if (jitter->src.idle.n > 0)
14897 retn = jitter->src.idle.maxval;
14898 }
14899
14900 return (retn/1000.0);
14901 }
14902
14903 double
ArgusFetchDstIntPkt(struct ArgusRecordStruct * ns)14904 ArgusFetchDstIntPkt (struct ArgusRecordStruct *ns)
14905 {
14906 double retn = 0.0;
14907 struct ArgusJitterStruct *jitter;
14908
14909 if (ns->hdr.type & ARGUS_MAR) {
14910
14911 } else {
14912 unsigned int n;
14913
14914 if ((jitter = (struct ArgusJitterStruct *)ns->dsrs[ARGUS_JITTER_INDEX]) != NULL) {
14915 if ((n = (jitter->src.act.n + jitter->src.idle.n)) > 0) {
14916 if (jitter->src.act.n && jitter->src.idle.n) {
14917 retn = ((jitter->src.act.meanval * jitter->src.act.n) +
14918 (jitter->src.idle.meanval * jitter->src.idle.n)) / n;
14919 } else {
14920 retn = (jitter->src.act.n) ? jitter->src.act.meanval : jitter->src.idle.meanval;
14921 }
14922 }
14923 }
14924 }
14925
14926 return (retn/1000.0);
14927 }
14928
14929 double
ArgusFetchDstIntPktAct(struct ArgusRecordStruct * ns)14930 ArgusFetchDstIntPktAct (struct ArgusRecordStruct *ns)
14931 {
14932 double retn = 0.0;
14933 struct ArgusJitterStruct *jitter;
14934
14935 if (ns->hdr.type & ARGUS_MAR) {
14936
14937 } else {
14938 if ((jitter = (struct ArgusJitterStruct *)ns->dsrs[ARGUS_JITTER_INDEX]) != NULL)
14939 if (jitter->dst.act.n > 0)
14940 retn = jitter->dst.act.meanval;
14941 }
14942
14943 return (retn/1000.0);
14944 }
14945
14946 double
ArgusFetchDstIntPktActMin(struct ArgusRecordStruct * ns)14947 ArgusFetchDstIntPktActMin (struct ArgusRecordStruct *ns)
14948 {
14949 double retn = 0.0;
14950 struct ArgusJitterStruct *jitter;
14951
14952 if (ns->hdr.type & ARGUS_MAR) {
14953
14954 } else {
14955 if ((jitter = (struct ArgusJitterStruct *)ns->dsrs[ARGUS_JITTER_INDEX]) != NULL)
14956 if (jitter->dst.act.n > 0)
14957 retn = jitter->dst.act.minval;
14958 }
14959
14960 return (retn/1000.0);
14961 }
14962
14963 double
ArgusFetchDstIntPktActMax(struct ArgusRecordStruct * ns)14964 ArgusFetchDstIntPktActMax (struct ArgusRecordStruct *ns)
14965 {
14966 double retn = 0.0;
14967 struct ArgusJitterStruct *jitter;
14968
14969 if (ns->hdr.type & ARGUS_MAR) {
14970
14971 } else {
14972 if ((jitter = (struct ArgusJitterStruct *)ns->dsrs[ARGUS_JITTER_INDEX]) != NULL)
14973 if (jitter->dst.act.n > 0)
14974 retn = jitter->dst.act.maxval;
14975 }
14976
14977 return (retn/1000.0);
14978 }
14979
14980
14981 double
ArgusFetchDstIntPktIdl(struct ArgusRecordStruct * ns)14982 ArgusFetchDstIntPktIdl (struct ArgusRecordStruct *ns)
14983 {
14984 double retn = 0.0;
14985 struct ArgusJitterStruct *jitter;
14986
14987 if (ns->hdr.type & ARGUS_MAR) {
14988
14989 } else {
14990 if ((jitter = (struct ArgusJitterStruct *)ns->dsrs[ARGUS_JITTER_INDEX]) != NULL)
14991 if (jitter->dst.idle.n > 0)
14992 retn = jitter->dst.idle.meanval;
14993 }
14994
14995 return (retn/1000.0);
14996 }
14997
14998 double
ArgusFetchDstIntPktIdlMin(struct ArgusRecordStruct * ns)14999 ArgusFetchDstIntPktIdlMin (struct ArgusRecordStruct *ns)
15000 {
15001 double retn = 0.0;
15002 struct ArgusJitterStruct *jitter;
15003
15004 if (ns->hdr.type & ARGUS_MAR) {
15005
15006 } else {
15007 if ((jitter = (struct ArgusJitterStruct *)ns->dsrs[ARGUS_JITTER_INDEX]) != NULL)
15008 if (jitter->dst.idle.n > 0)
15009 retn = jitter->dst.idle.minval;
15010 }
15011
15012 return (retn/1000.0);
15013 }
15014
15015 double
ArgusFetchDstIntPktIdlMax(struct ArgusRecordStruct * ns)15016 ArgusFetchDstIntPktIdlMax (struct ArgusRecordStruct *ns)
15017 {
15018 double retn = 0.0;
15019 struct ArgusJitterStruct *jitter;
15020
15021 if (ns->hdr.type & ARGUS_MAR) {
15022
15023 } else {
15024 if ((jitter = (struct ArgusJitterStruct *)ns->dsrs[ARGUS_JITTER_INDEX]) != NULL)
15025 if (jitter->dst.idle.n > 0)
15026 retn = jitter->dst.idle.maxval;
15027 }
15028
15029 return (retn/1000.0);
15030 }
15031
15032
15033 double
ArgusFetchSrcJitter(struct ArgusRecordStruct * ns)15034 ArgusFetchSrcJitter (struct ArgusRecordStruct *ns)
15035 {
15036 double retn = 0.0;
15037 struct ArgusJitterStruct *jitter;
15038
15039 if (ns->hdr.type & ARGUS_MAR) {
15040
15041 } else {
15042 if (ns && ((jitter = (void *)ns->dsrs[ARGUS_JITTER_INDEX]) != NULL)) {
15043 double stdev = 0.0, sumsqrd1 = 0.0, sumsqrd2 = 0.0, sumsqrd;
15044 unsigned int n;
15045 float meanval;
15046
15047 if ((n = (jitter->src.act.n + jitter->src.idle.n)) > 0) {
15048 if (jitter->src.act.n && jitter->src.idle.n) {
15049 meanval = ((jitter->src.act.meanval * jitter->src.act.n) +
15050 (jitter->src.idle.meanval * jitter->src.idle.n)) / n;
15051
15052 if (jitter->src.act.n) {
15053 stdev = jitter->src.act.stdev;
15054 sumsqrd1 = (jitter->src.act.n * pow(stdev, 2.0)) +
15055 pow((jitter->src.act.meanval * jitter->src.act.n), 2.0)/jitter->src.act.n;
15056 }
15057
15058 if (jitter->src.idle.n) {
15059 stdev = jitter->src.idle.stdev;
15060 sumsqrd2 = (jitter->src.idle.n * pow(stdev, 2.0)) +
15061 pow((jitter->src.idle.meanval * jitter->src.idle.n), 2.0)/jitter->src.idle.n;
15062 }
15063
15064 sumsqrd = sumsqrd1 + sumsqrd2;
15065 sumsqrd = sumsqrd / 1000;
15066 meanval = meanval / 1000.0;
15067 retn = ((sqrt ((sumsqrd/n) - pow (meanval, 2.0))) * 1);
15068
15069 } else {
15070 retn = (jitter->src.act.n) ? jitter->src.act.stdev : jitter->src.idle.stdev;
15071 retn = retn / 1000.0;
15072 }
15073 }
15074 }
15075 }
15076
15077 return (retn);
15078 }
15079
15080 double
ArgusFetchSrcJitterAct(struct ArgusRecordStruct * ns)15081 ArgusFetchSrcJitterAct (struct ArgusRecordStruct *ns)
15082 {
15083 double retn = 0.0;
15084 struct ArgusJitterStruct *jitter;
15085
15086 if (ns->hdr.type & ARGUS_MAR) {
15087
15088 } else {
15089 if (ns && ((jitter = (void *)ns->dsrs[ARGUS_JITTER_INDEX]) != NULL)) {
15090 if (jitter->src.act.n) {
15091 retn = jitter->src.act.stdev;
15092 retn = retn / 1000.0;
15093 }
15094 }
15095 }
15096
15097 return (retn);
15098 }
15099
15100 double
ArgusFetchSrcJitterIdl(struct ArgusRecordStruct * ns)15101 ArgusFetchSrcJitterIdl (struct ArgusRecordStruct *ns)
15102 {
15103 double retn = 0.0;
15104 struct ArgusJitterStruct *jitter;
15105
15106 if (ns->hdr.type & ARGUS_MAR) {
15107
15108 } else {
15109 if (ns && ((jitter = (void *)ns->dsrs[ARGUS_JITTER_INDEX]) != NULL)) {
15110 if (jitter->src.idle.n) {
15111 retn = jitter->src.idle.stdev;
15112 retn = retn / 1000.0;
15113 }
15114 }
15115 }
15116
15117 return (retn);
15118 }
15119
15120
15121 double
ArgusFetchDstJitter(struct ArgusRecordStruct * ns)15122 ArgusFetchDstJitter (struct ArgusRecordStruct *ns)
15123 {
15124 double retn = 0.0;
15125 struct ArgusJitterStruct *jitter;
15126
15127 if (ns->hdr.type & ARGUS_MAR) {
15128
15129 } else {
15130 if (ns && ((jitter = (void *)ns->dsrs[ARGUS_JITTER_INDEX]) != NULL)) {
15131 double stdev = 0.0, sumsqrd1 = 0.0, sumsqrd2 = 0.0, sumsqrd;
15132 unsigned int n;
15133 float meanval;
15134
15135 if ((n = (jitter->dst.act.n + jitter->dst.idle.n)) > 0) {
15136 if (jitter->dst.act.n && jitter->dst.idle.n) {
15137 meanval = ((jitter->dst.act.meanval * jitter->dst.act.n) +
15138 (jitter->dst.idle.meanval * jitter->dst.idle.n)) / n;
15139
15140 if (jitter->dst.act.n) {
15141 stdev = jitter->dst.act.stdev;
15142 sumsqrd1 = (jitter->dst.act.n * pow(stdev, 2.0)) +
15143 pow((jitter->dst.act.meanval * jitter->dst.act.n), 2.0)/jitter->dst.act.n;
15144 }
15145
15146 if (jitter->dst.idle.n) {
15147 stdev = jitter->dst.idle.stdev;
15148 sumsqrd2 = (jitter->dst.idle.n * pow(stdev, 2.0)) +
15149 pow((jitter->dst.idle.meanval * jitter->dst.idle.n), 2.0)/jitter->dst.idle.n;
15150 }
15151
15152 sumsqrd = sumsqrd1 + sumsqrd2;
15153 sumsqrd = sumsqrd / 1000;
15154 meanval = meanval / 1000.0;
15155 retn = ((sqrt ((sumsqrd/n) - pow (meanval, 2.0))) * 1);
15156
15157 } else {
15158 retn = (jitter->dst.act.n) ? jitter->dst.act.stdev : jitter->dst.idle.stdev;
15159 retn = retn / 1000.0;
15160 }
15161 }
15162 }
15163 }
15164
15165 return (retn);
15166 }
15167
15168
15169 double
ArgusFetchDstJitterAct(struct ArgusRecordStruct * ns)15170 ArgusFetchDstJitterAct (struct ArgusRecordStruct *ns)
15171 {
15172 double retn = 0.0;
15173 struct ArgusJitterStruct *jitter;
15174
15175 if (ns->hdr.type & ARGUS_MAR) {
15176
15177 } else {
15178 if (ns && ((jitter = (void *)ns->dsrs[ARGUS_JITTER_INDEX]) != NULL)) {
15179 if (jitter->dst.act.n) {
15180 retn = jitter->dst.act.stdev;
15181 retn = retn / 1000.0;
15182 }
15183 }
15184 }
15185
15186 return (retn);
15187 }
15188
15189 double
ArgusFetchDstJitterIdl(struct ArgusRecordStruct * ns)15190 ArgusFetchDstJitterIdl (struct ArgusRecordStruct *ns)
15191 {
15192 double retn = 0.0;
15193 struct ArgusJitterStruct *jitter;
15194
15195 if (ns->hdr.type & ARGUS_MAR) {
15196
15197 } else {
15198 if (ns && ((jitter = (void *)ns->dsrs[ARGUS_JITTER_INDEX]) != NULL)) {
15199 if (jitter->dst.idle.n) {
15200 retn = jitter->dst.idle.stdev;
15201 retn = retn / 1000.0;
15202 }
15203 }
15204 }
15205
15206 return (retn);
15207 }
15208
15209 double
ArgusFetchSrcWindow(struct ArgusRecordStruct * ns)15210 ArgusFetchSrcWindow (struct ArgusRecordStruct *ns)
15211 {
15212 double retn = 0.0;
15213
15214 if (ns->hdr.type & ARGUS_MAR) {
15215
15216 } else {
15217 struct ArgusNetworkStruct *net = (void *)ns->dsrs[ARGUS_NETWORK_INDEX];
15218 struct ArgusFlow *flow = (void *)ns->dsrs[ARGUS_FLOW_INDEX];
15219 unsigned int win = 0;
15220
15221 if (net && (net->hdr.subtype == ARGUS_UDT_FLOW)) {
15222 retn = net->net_union.udt.src.bsize;
15223
15224 } else {
15225 if ((flow != NULL) && (net != NULL)) {
15226 struct ArgusTCPObject *tcp = (struct ArgusTCPObject *)&net->net_union.tcp;
15227 struct ArgusMetricStruct *metric = (void *)ns->dsrs[ARGUS_METRIC_INDEX];
15228
15229 if ((metric != NULL) && (metric->src.pkts > 0)) {
15230 switch (flow->hdr.subtype & 0x3F) {
15231 case ARGUS_FLOW_CLASSIC5TUPLE: {
15232 switch ((flow->hdr.argus_dsrvl8.qual & 0x1F)) {
15233 case ARGUS_TYPE_IPV4:
15234 switch (flow->ip_flow.ip_p) {
15235 case IPPROTO_TCP: {
15236 win = tcp->src.win << tcp->src.winshift;
15237 break;
15238 }
15239 default:
15240 break;
15241 }
15242 break;
15243
15244 case ARGUS_TYPE_IPV6:
15245 switch (flow->ipv6_flow.ip_p) {
15246 case IPPROTO_TCP: {
15247 win = tcp->src.win << tcp->src.winshift;
15248 break;
15249 }
15250 default:
15251 break;
15252 }
15253 break;
15254 }
15255 break;
15256 }
15257
15258 default:
15259 break;
15260 }
15261
15262 retn = win;
15263 }
15264 }
15265 }
15266 }
15267
15268 return (retn);
15269 }
15270
15271
15272 double
ArgusFetchDstWindow(struct ArgusRecordStruct * ns)15273 ArgusFetchDstWindow (struct ArgusRecordStruct *ns)
15274 {
15275 double retn = 0.0;
15276
15277 if (ns->hdr.type & ARGUS_MAR) {
15278
15279 } else {
15280 struct ArgusNetworkStruct *net = (void *)ns->dsrs[ARGUS_NETWORK_INDEX];
15281 struct ArgusFlow *flow = (void *)ns->dsrs[ARGUS_FLOW_INDEX];
15282 unsigned int win = 0;
15283
15284 if (net && (net->hdr.subtype == ARGUS_UDT_FLOW)) {
15285
15286 } else {
15287 if ((flow != NULL) && (net != NULL)) {
15288 struct ArgusMetricStruct *metric = (void *)ns->dsrs[ARGUS_METRIC_INDEX];
15289 struct ArgusTCPObject *tcp = (struct ArgusTCPObject *)&net->net_union.tcp;
15290
15291 if ((metric != NULL) && (metric->dst.pkts > 0)) {
15292 switch (flow->hdr.subtype & 0x3F) {
15293 case ARGUS_FLOW_CLASSIC5TUPLE: {
15294 switch ((flow->hdr.argus_dsrvl8.qual & 0x1F)) {
15295 case ARGUS_TYPE_IPV4:
15296 switch (flow->ip_flow.ip_p) {
15297 case IPPROTO_TCP: {
15298 win = tcp->dst.win << tcp->dst.winshift;
15299 break;
15300 }
15301 default:
15302 break;
15303 }
15304 break;
15305
15306 case ARGUS_TYPE_IPV6:
15307 switch (flow->ipv6_flow.ip_p) {
15308 case IPPROTO_TCP: {
15309 win = tcp->dst.win << tcp->dst.winshift;
15310 break;
15311 }
15312 default:
15313 break;
15314 }
15315 break;
15316 }
15317 break;
15318 }
15319
15320 default:
15321 break;
15322 }
15323
15324 retn = win;
15325 }
15326 }
15327 }
15328 }
15329 return (retn);
15330 }
15331
15332 double
ArgusFetchDeltaDuration(struct ArgusRecordStruct * ns)15333 ArgusFetchDeltaDuration (struct ArgusRecordStruct *ns)
15334 {
15335 double retn = 0.0;
15336
15337 if (ns->hdr.type & ARGUS_MAR) {
15338
15339 } else {
15340 struct ArgusCorrelateStruct *cor = (void *)ns->dsrs[ARGUS_COR_INDEX];
15341 if (cor != NULL)
15342 retn = cor->metrics.deltaDur / 1000000.0;
15343 }
15344 return (retn);
15345 }
15346
15347 double
ArgusFetchDeltaStartTime(struct ArgusRecordStruct * ns)15348 ArgusFetchDeltaStartTime (struct ArgusRecordStruct *ns)
15349 {
15350 double retn = 0.0;
15351
15352 if (ns->hdr.type & ARGUS_MAR) {
15353
15354 } else {
15355 struct ArgusCorrelateStruct *cor = (void *)ns->dsrs[ARGUS_COR_INDEX];
15356 if (cor != NULL)
15357 retn = cor->metrics.deltaStart / 1000000.0;
15358 }
15359 return (retn);
15360 }
15361
15362 double
ArgusFetchDeltaLastTime(struct ArgusRecordStruct * ns)15363 ArgusFetchDeltaLastTime (struct ArgusRecordStruct *ns)
15364 {
15365 double retn = 0.0;
15366
15367 if (ns->hdr.type & ARGUS_MAR) {
15368
15369 } else {
15370 struct ArgusCorrelateStruct *cor = (void *)ns->dsrs[ARGUS_COR_INDEX];
15371 if (cor != NULL)
15372 retn = cor->metrics.deltaLast / 1000000.0;
15373 }
15374 return (retn);
15375 }
15376
15377 double
ArgusFetchDeltaSrcPkts(struct ArgusRecordStruct * ns)15378 ArgusFetchDeltaSrcPkts (struct ArgusRecordStruct *ns)
15379 {
15380 double retn = 0.0;
15381
15382 if (ns->hdr.type & ARGUS_MAR) {
15383
15384 } else {
15385 struct ArgusCorrelateStruct *cor = (void *)ns->dsrs[ARGUS_COR_INDEX];
15386 if (cor != NULL)
15387 retn = cor->metrics.deltaSrcPkts * 1.0;
15388 }
15389 return (retn);
15390 }
15391
15392 double
ArgusFetchDeltaDstPkts(struct ArgusRecordStruct * ns)15393 ArgusFetchDeltaDstPkts (struct ArgusRecordStruct *ns)
15394 {
15395 double retn = 0.0;
15396
15397 if (ns->hdr.type & ARGUS_MAR) {
15398
15399 } else {
15400 struct ArgusCorrelateStruct *cor = (void *)ns->dsrs[ARGUS_COR_INDEX];
15401 if (cor != NULL)
15402 retn = cor->metrics.deltaDstPkts * 1.0;
15403 }
15404 return (retn);
15405 }
15406
15407
15408 double
ArgusFetchIpId(struct ArgusRecordStruct * ns)15409 ArgusFetchIpId (struct ArgusRecordStruct *ns)
15410 {
15411 double retn = 0;
15412 return (retn);
15413 }
15414
15415 struct ArgusSorterStruct *ArgusNewSorter (struct ArgusParserStruct *parser);
15416
15417 struct ArgusSorterStruct *
ArgusNewSorter(struct ArgusParserStruct * parser)15418 ArgusNewSorter (struct ArgusParserStruct *parser)
15419 {
15420 struct ArgusSorterStruct *retn = NULL;
15421
15422 if ((retn = (struct ArgusSorterStruct *) ArgusCalloc (1, sizeof (*retn))) == NULL)
15423 ArgusLog (LOG_ERR, "ArgusNewSorter ArgusCalloc error %s", strerror(errno));
15424
15425 if ((retn->ArgusRecordQueue = ArgusNewQueue()) == NULL)
15426 ArgusLog (LOG_ERR, "ArgusNewSorter ArgusNewQueue error %s", strerror(errno));
15427
15428 if (parser && (parser->RaSortOptionIndex > 0)) {
15429 int i, x, s = 0;
15430
15431 for (i = 0; i < parser->RaSortOptionIndex; i++) {
15432 char *ptr, *str = parser->RaSortOptionStrings[i];
15433 for (x = 0; x < MAX_SORT_ALG_TYPES; x++) {
15434 if (!strncmp (ArgusSortKeyWords[x], str, strlen(ArgusSortKeyWords[x]))) {
15435 retn->ArgusSortAlgorithms[s++] = ArgusSortAlgorithmTable[x];
15436 if (ArgusSortAlgorithmTable[x] == ArgusSortSrcAddr) {
15437 if ((ptr = strchr(str, '/')) != NULL) {
15438 int cidr = 0;
15439 ptr++;
15440 cidr = atoi(ptr);
15441 ArgusSorter->ArgusSrcAddrCIDR = cidr;
15442 }
15443 }
15444 if (ArgusSortAlgorithmTable[x] == ArgusSortDstAddr) {
15445 if ((ptr = strchr(str, '/')) != NULL) {
15446 int cidr = 0;
15447 ptr++;
15448 cidr = atoi(ptr);
15449 retn->ArgusSrcAddrCIDR = cidr;
15450 }
15451 }
15452 break;
15453 }
15454 }
15455
15456 if (x == MAX_SORT_ALG_TYPES)
15457 ArgusLog (LOG_ERR, "sort syntax error. \'%s\' not supported", str);
15458 }
15459 }
15460
15461 return (retn);
15462 }
15463
15464 void
ArgusDeleteSorter(struct ArgusSorterStruct * sort)15465 ArgusDeleteSorter (struct ArgusSorterStruct *sort)
15466 {
15467 if (sort != NULL) {
15468 if (sort->ArgusRecordQueue != NULL)
15469 ArgusDeleteQueue(sort->ArgusRecordQueue);
15470
15471 ArgusFree (sort);
15472 ArgusSorter = NULL;
15473 }
15474 }
15475
15476
15477
15478 void
ArgusSortQueue(struct ArgusSorterStruct * sorter,struct ArgusQueueStruct * queue)15479 ArgusSortQueue (struct ArgusSorterStruct *sorter, struct ArgusQueueStruct *queue)
15480 {
15481 int i = 0, cnt;
15482
15483 #if defined(ARGUS_THREADS)
15484 pthread_mutex_lock(&queue->lock);
15485 #endif
15486
15487 if (queue->array != NULL) {
15488 ArgusFree(queue->array);
15489 queue->array = NULL;
15490 queue->arraylen = 0;
15491 }
15492
15493 cnt = queue->count;
15494
15495 if ((queue->array = (struct ArgusQueueHeader **) ArgusMalloc(sizeof(struct ArgusQueueHeader *) * (cnt + 1))) != NULL) {
15496 queue->arraylen = cnt;
15497
15498 for (i = 0; i < cnt; i++)
15499 queue->array[i] = ArgusPopQueue(queue, ARGUS_NOLOCK);
15500
15501 queue->array[i] = NULL;
15502
15503 if (cnt > 1)
15504 if (ArgusSorter->ArgusSortAlgorithms[0] != NULL)
15505 qsort ((char *) queue->array, cnt, sizeof (struct ArgusQueueHeader *), ArgusSortRoutine);
15506
15507 for (i = 0; i < cnt; i++)
15508 ArgusAddToQueue(queue, queue->array[i], ARGUS_NOLOCK);
15509
15510 } else
15511 ArgusLog (LOG_ERR, "ArgusSortQueue: ArgusMalloc %s\n", strerror(errno));
15512
15513 #if defined(ARGUS_THREADS)
15514 pthread_mutex_unlock(&queue->lock);
15515 #endif
15516
15517 #ifdef ARGUSDEBUG
15518 ArgusDebug (5, "ArgusSortQueue(%p) returned\n", queue);
15519 #endif
15520 }
15521
15522
15523
15524 int
ArgusSortRoutine(const void * void1,const void * void2)15525 ArgusSortRoutine (const void *void1, const void *void2)
15526 {
15527 int retn = 0, i = 0;
15528 struct ArgusRecordStruct *ns1 = *(struct ArgusRecordStruct **)void1;
15529 struct ArgusRecordStruct *ns2 = *(struct ArgusRecordStruct **)void2;
15530
15531 if (ns1 && ns2) {
15532 for (i = 0; i < ARGUS_MAX_SORT_ALG; i++)
15533 if (ArgusSorter->ArgusSortAlgorithms[i] != NULL) {
15534 if ((retn = ArgusSorter->ArgusSortAlgorithms[i](ns2, ns1)) != 0)
15535 break;
15536 } else
15537 break;
15538 }
15539
15540 return (retn);
15541 }
15542
15543
15544 int
ArgusSortSrcId(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)15545 ArgusSortSrcId (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
15546 {
15547 struct ArgusTransportStruct *t1 = (struct ArgusTransportStruct *)n1->dsrs[ARGUS_TRANSPORT_INDEX];
15548 struct ArgusTransportStruct *t2 = (struct ArgusTransportStruct *)n2->dsrs[ARGUS_TRANSPORT_INDEX];
15549 unsigned int *sid1 = NULL, *sid2 = NULL;
15550 int retn = 0, len, i;
15551
15552 if (t1 && t2) {
15553 if (t1->hdr.subtype & ARGUS_SRCID) {
15554 sid1 = &t1->srcid.a_un.ipv4;
15555 switch (t1->hdr.argus_dsrvl8.qual) {
15556 case ARGUS_TYPE_IPV4: len = 1; break;
15557 case ARGUS_TYPE_IPV6: len = 4; break;
15558 }
15559 }
15560 if (t2->hdr.subtype & ARGUS_SRCID) {
15561 sid2 = &t2->srcid.a_un.ipv4;
15562 switch (t2->hdr.argus_dsrvl8.qual) {
15563 case ARGUS_TYPE_IPV4: len = 1; break;
15564 case ARGUS_TYPE_IPV6: len = (len < 4) ? len : 4; break;
15565 }
15566 }
15567
15568 if (sid1 && sid2) {
15569 for (i = 0; i < len; i++, sid1++, sid2++) {
15570 if (*sid2 != *sid1) {
15571 retn = sid2[i] - sid1[i];
15572 break;
15573 }
15574 }
15575 }
15576 }
15577
15578 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
15579 }
15580
15581
15582 int
ArgusSortStartTime(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)15583 ArgusSortStartTime (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
15584 {
15585 double t1 = 0.0, t2 = 0.0;
15586 int retn = 0;
15587
15588 if (n1)
15589 t1 = ArgusFetchStartTime(n1);
15590
15591 if (n2)
15592 t2 = ArgusFetchStartTime(n2);
15593
15594 retn = (t2 > t1) ? 1 : ((t1 == t2) ? 0 : -1);
15595 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
15596 }
15597
15598 int
ArgusSortLastTime(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)15599 ArgusSortLastTime (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
15600 {
15601 double t1 = 0.0, t2 = 0.0;
15602 int retn = 0;
15603
15604 if (n1)
15605 t1 = ArgusFetchLastTime(n1);
15606
15607 if (n2)
15608 t2 = ArgusFetchLastTime(n2);
15609
15610 retn = (t2 > t1) ? 1 : ((t1 == t2) ? 0 : -1);
15611 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
15612 }
15613
15614
ArgusSortIdleTime(struct ArgusRecordStruct * n2,struct ArgusRecordStruct * n1)15615 int ArgusSortIdleTime (struct ArgusRecordStruct *n2, struct ArgusRecordStruct *n1)
15616 {
15617 float ad1 = 0.0, ad2 = 0.0;
15618 int retn = 0;
15619
15620 if (n1 && n2) {
15621 ad1 = RaGetFloatIdleTime(n1);
15622 ad2 = RaGetFloatIdleTime(n2);
15623 retn = (ad1 > ad2) ? 1 : ((ad1 == ad2) ? 0 : -1);
15624 }
15625
15626 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
15627 }
15628
15629
ArgusSortMean(struct ArgusRecordStruct * n2,struct ArgusRecordStruct * n1)15630 int ArgusSortMean (struct ArgusRecordStruct *n2, struct ArgusRecordStruct *n1)
15631 {
15632 float ad1 = 0.0, ad2 = 0.0;
15633 int retn = 0;
15634
15635 if (n1 && n2) {
15636 ad1 = RaGetFloatMean(n1);
15637 ad2 = RaGetFloatMean(n2);
15638 retn = (ad1 > ad2) ? 1 : ((ad1 == ad2) ? 0 : -1);
15639 }
15640
15641 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
15642 }
15643
ArgusSortSum(struct ArgusRecordStruct * n2,struct ArgusRecordStruct * n1)15644 int ArgusSortSum (struct ArgusRecordStruct *n2, struct ArgusRecordStruct *n1)
15645 {
15646 float ad1 = 0.0, ad2 = 0.0;
15647 int retn = 0;
15648
15649 if (n1 && n2) {
15650 ad1 = RaGetFloatSum(n1);
15651 ad2 = RaGetFloatSum(n2);
15652 retn = (ad1 > ad2) ? 1 : ((ad1 == ad2) ? 0 : -1);
15653 }
15654
15655 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
15656 }
15657
15658
ArgusSortMin(struct ArgusRecordStruct * n2,struct ArgusRecordStruct * n1)15659 int ArgusSortMin (struct ArgusRecordStruct *n2, struct ArgusRecordStruct *n1)
15660 {
15661 float ad1 = 0.0, ad2 = 0.0;
15662 int retn = 0;
15663
15664 if (n1 && n2) {
15665 ad1 = RaGetFloatMin(n1);
15666 ad2 = RaGetFloatMin(n2);
15667 retn = (ad1 > ad2) ? 1 : ((ad1 == ad2) ? 0 : -1);
15668 }
15669
15670 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
15671 }
15672
ArgusSortMax(struct ArgusRecordStruct * n2,struct ArgusRecordStruct * n1)15673 int ArgusSortMax (struct ArgusRecordStruct *n2, struct ArgusRecordStruct *n1)
15674 {
15675 float ad1 = 0.0, ad2 = 0.0;
15676 int retn = 0;
15677
15678 if (n1 && n2) {
15679 ad1 = RaGetFloatMax(n1);
15680 ad2 = RaGetFloatMax(n2);
15681 retn = (ad1 > ad2) ? 1 : ((ad1 == ad2) ? 0 : -1);
15682 }
15683
15684 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
15685 }
15686
15687 int
ArgusSortDuration(struct ArgusRecordStruct * n2,struct ArgusRecordStruct * n1)15688 ArgusSortDuration (struct ArgusRecordStruct *n2, struct ArgusRecordStruct *n1)
15689 {
15690 double d1 = 0.0, d2 = 0.0;
15691 int retn = 0;
15692
15693 if (n1)
15694 d1 = ArgusFetchDuration(n1);
15695
15696 if (n2)
15697 d2 = ArgusFetchDuration(n2);
15698
15699 retn = (d1 > d2) ? 1 : ((d1 == d2) ? 0 : -1);
15700 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
15701 }
15702
15703 int
ArgusSortSrcMac(struct ArgusRecordStruct * n2,struct ArgusRecordStruct * n1)15704 ArgusSortSrcMac (struct ArgusRecordStruct *n2, struct ArgusRecordStruct *n1)
15705 {
15706 struct ArgusMacStruct *m1 = (struct ArgusMacStruct *) n1->dsrs[ARGUS_MAC_INDEX];
15707 struct ArgusMacStruct *m2 = (struct ArgusMacStruct *) n2->dsrs[ARGUS_MAC_INDEX];
15708 int retn = 0;
15709
15710 if (m1 && m2) {
15711 retn = bcmp ((unsigned char *)&m1->mac.mac_union.ether.ehdr.ether_shost,
15712 (unsigned char *)&m2->mac.mac_union.ether.ehdr.ether_shost, 6);
15713 }
15714
15715
15716 return(ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
15717 }
15718
15719 int
ArgusSortDstMac(struct ArgusRecordStruct * n2,struct ArgusRecordStruct * n1)15720 ArgusSortDstMac (struct ArgusRecordStruct *n2, struct ArgusRecordStruct *n1)
15721 {
15722 struct ArgusMacStruct *m1 = (struct ArgusMacStruct *) n1->dsrs[ARGUS_MAC_INDEX];
15723 struct ArgusMacStruct *m2 = (struct ArgusMacStruct *) n2->dsrs[ARGUS_MAC_INDEX];
15724 int retn = 0;
15725
15726 if (m1 && m2) {
15727 retn = bcmp ((unsigned char *)&m1->mac.mac_union.ether.ehdr.ether_dhost,
15728 (unsigned char *)&m2->mac.mac_union.ether.ehdr.ether_dhost, 6);
15729 }
15730
15731 return(ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
15732 }
15733
15734 int
ArgusSortSrcOui(struct ArgusRecordStruct * n2,struct ArgusRecordStruct * n1)15735 ArgusSortSrcOui (struct ArgusRecordStruct *n2, struct ArgusRecordStruct *n1)
15736 {
15737 struct ArgusMacStruct *m1 = (struct ArgusMacStruct *) n1->dsrs[ARGUS_MAC_INDEX];
15738 struct ArgusMacStruct *m2 = (struct ArgusMacStruct *) n2->dsrs[ARGUS_MAC_INDEX];
15739 int retn = 0;
15740
15741 if (m1 && m2) {
15742 retn = strcmp (etheraddr_oui(ArgusParser, (unsigned char *)&m1->mac.mac_union.ether.ehdr.ether_shost),
15743 etheraddr_oui(ArgusParser, (unsigned char *)&m2->mac.mac_union.ether.ehdr.ether_shost));
15744 }
15745
15746 return(ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
15747 }
15748
15749 int
ArgusSortDstOui(struct ArgusRecordStruct * n2,struct ArgusRecordStruct * n1)15750 ArgusSortDstOui (struct ArgusRecordStruct *n2, struct ArgusRecordStruct *n1)
15751 {
15752 struct ArgusMacStruct *m1 = (struct ArgusMacStruct *) n1->dsrs[ARGUS_MAC_INDEX];
15753 struct ArgusMacStruct *m2 = (struct ArgusMacStruct *) n2->dsrs[ARGUS_MAC_INDEX];
15754 int retn = 0;
15755
15756 if (m1 && m2) {
15757 retn = strcmp (etheraddr_oui(ArgusParser, (unsigned char *)&m1->mac.mac_union.ether.ehdr.ether_dhost),
15758 etheraddr_oui(ArgusParser, (unsigned char *)&m2->mac.mac_union.ether.ehdr.ether_dhost));
15759 }
15760
15761 return(ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
15762 }
15763
15764 int
ArgusSortSrcAddr(struct ArgusRecordStruct * n2,struct ArgusRecordStruct * n1)15765 ArgusSortSrcAddr (struct ArgusRecordStruct *n2, struct ArgusRecordStruct *n1)
15766 {
15767 struct ArgusFlow *f1 = (struct ArgusFlow *) n1->dsrs[ARGUS_FLOW_INDEX];
15768 struct ArgusFlow *f2 = (struct ArgusFlow *) n2->dsrs[ARGUS_FLOW_INDEX];
15769 int retn = 0;
15770
15771 if (f1 && f2) {
15772 char scidr = 32 - ((ArgusSorter->ArgusSrcAddrCIDR > 0) ? ArgusSorter->ArgusSrcAddrCIDR : 32);
15773 int len = 0, i = 0;
15774 u_char f1qual, f2qual;
15775
15776 if ((f1->hdr.subtype & 0x3F) != (f2->hdr.subtype & 0x3F))
15777 return((f1->hdr.subtype & 0x3F) - (f2->hdr.subtype & 0x3F));
15778
15779 f1qual = f1->hdr.argus_dsrvl8.qual & 0x1F;
15780 f2qual = f2->hdr.argus_dsrvl8.qual & 0x1F;
15781
15782 if (f1qual != f2qual)
15783 return (f1qual - f2qual);
15784
15785 switch (f1->hdr.subtype & 0x3F) {
15786 case ARGUS_FLOW_CLASSIC5TUPLE: {
15787 switch (f1qual) {
15788 case ARGUS_TYPE_IPV4: {
15789 unsigned int *a1, *a2;
15790 unsigned int va1, va2;
15791
15792 a1 = (unsigned int *)&f1->ip_flow.ip_src;
15793 a2 = (unsigned int *)&f2->ip_flow.ip_src;
15794
15795 if (scidr) {
15796 va1 = (*a1 >> scidr) << scidr;
15797 va2 = (*a2 >> scidr) << scidr;
15798 } else {
15799 va1 = *a1;
15800 va2 = *a2;
15801 }
15802
15803 retn = (va1 > va2) ? 1 : ((va1 < va2) ? -1 : 0);
15804 break;
15805 }
15806 case ARGUS_TYPE_IPV6: {
15807 unsigned int *a1, *a2;
15808 a1 = (unsigned int *)&f1->ipv6_flow.ip_src;
15809 a2 = (unsigned int *)&f2->ipv6_flow.ip_src;
15810 len = 4;
15811 for (i = 0; i < len; i++)
15812 if (a1[i] != a2[i])
15813 break;
15814 if (i != len)
15815 retn = (a1[i] > a2[i]) ? 1 : ((a1[i] < a2[i]) ? -1 : 0);
15816 break;
15817 }
15818 case ARGUS_TYPE_RARP:
15819 retn = bcmp (&f1->rarp_flow.shaddr, &f2->rarp_flow.shaddr, 6);
15820 break;
15821 case ARGUS_TYPE_ARP: {
15822 unsigned int *a1, *a2;
15823 a1 = (unsigned int *)&f1->arp_flow.arp_spa;
15824 a2 = (unsigned int *)&f2->arp_flow.arp_spa;
15825 retn = (*a1 > *a2) ? 1 : ((*a1 < *a2) ? -1 : 0);
15826 break;
15827 }
15828 case ARGUS_TYPE_ETHER: {
15829 unsigned char *a1, *a2;
15830 a1 = (unsigned char *)&f1->mac_flow.mac_union.ether.ehdr.ether_shost;
15831 a2 = (unsigned char *)&f2->mac_flow.mac_union.ether.ehdr.ether_shost;
15832 len = 6;
15833 for (i = 0; i < len; i++)
15834 if (a1[i] != a2[i])
15835 break;
15836 if (i != len)
15837 retn = (a1[i] > a2[i]) ? 1 : ((a1[i] < a2[i]) ? -1 : 0);
15838 break;
15839 }
15840 case ARGUS_TYPE_WLAN: {
15841 unsigned char *a1, *a2;
15842 a1 = (unsigned char *)&f1->wlan_flow.shost;
15843 a2 = (unsigned char *)&f2->wlan_flow.shost;
15844 len = 6;
15845 for (i = 0; i < len; i++)
15846 if (a1[i] != a2[i])
15847 break;
15848 if (i != len)
15849 retn = (a1[i] > a2[i]) ? 1 : ((a1[i] < a2[i]) ? -1 : 0);
15850 break;
15851 }
15852 }
15853 break;
15854 }
15855
15856 case ARGUS_FLOW_ARP: {
15857 switch (f1qual) {
15858 case ARGUS_TYPE_RARP: {
15859 break;
15860 }
15861
15862 case ARGUS_TYPE_ARP: {
15863 unsigned int *a1, *a2;
15864 a1 = (unsigned int *)&f1->arp_flow.arp_spa;
15865 a2 = (unsigned int *)&f2->arp_flow.arp_spa;
15866 retn = (*a1 > *a2) ? 1 : ((*a1 < *a2) ? -1 : 0);
15867 break;
15868 }
15869
15870 default: {
15871 unsigned int *a1, *a2;
15872 a1 = (unsigned int *)&f1->iarp_flow.arp_spa;
15873 a2 = (unsigned int *)&f2->iarp_flow.arp_spa;
15874 retn = (*a1 > *a2) ? 1 : ((*a1 < *a2) ? -1 : 0);
15875 }
15876 }
15877 break;
15878 }
15879
15880 default:
15881 break;
15882 }
15883 }
15884
15885 return(ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
15886 }
15887
15888
ArgusSortDstAddr(struct ArgusRecordStruct * n2,struct ArgusRecordStruct * n1)15889 int ArgusSortDstAddr (struct ArgusRecordStruct *n2, struct ArgusRecordStruct *n1)
15890 {
15891 struct ArgusFlow *f1 = (struct ArgusFlow *) n1->dsrs[ARGUS_FLOW_INDEX];
15892 struct ArgusFlow *f2 = (struct ArgusFlow *) n2->dsrs[ARGUS_FLOW_INDEX];
15893 int retn = 0;
15894
15895 if (f1 && f2) {
15896 char scidr = 32 - ((ArgusSorter->ArgusSrcAddrCIDR > 0) ? ArgusSorter->ArgusSrcAddrCIDR : 32);
15897 int len = 0, i = 0;
15898 u_char f1qual, f2qual;
15899
15900 if ((f1->hdr.subtype & 0x3F) != (f2->hdr.subtype & 0x3F))
15901 return((f1->hdr.subtype & 0x3F) - (f2->hdr.subtype & 0x3F));
15902
15903 f1qual = f1->hdr.argus_dsrvl8.qual & 0x1F;
15904 f2qual = f2->hdr.argus_dsrvl8.qual & 0x1F;
15905
15906 if (f1qual != f2qual)
15907 return (f1qual - f2qual);
15908
15909 switch (f1->hdr.subtype & 0x3F) {
15910 case ARGUS_FLOW_CLASSIC5TUPLE: {
15911 switch (f1qual) {
15912 case ARGUS_TYPE_IPV4: {
15913 unsigned int *a1, *a2;
15914 unsigned int va1, va2;
15915
15916 a1 = (unsigned int *)&f1->ip_flow.ip_dst;
15917 a2 = (unsigned int *)&f2->ip_flow.ip_dst;
15918
15919 if (scidr) {
15920 va1 = (*a1 >> scidr) << scidr;
15921 va2 = (*a2 >> scidr) << scidr;
15922 } else {
15923 va1 = *a1;
15924 va2 = *a2;
15925 }
15926
15927 retn = (va1 > va2) ? 1 : ((va1 < va2) ? -1 : 0);
15928 break;
15929 }
15930 case ARGUS_TYPE_IPV6: {
15931 unsigned int *a1, *a2;
15932 a1 = (unsigned int *)&f1->ipv6_flow.ip_dst;
15933 a2 = (unsigned int *)&f2->ipv6_flow.ip_dst;
15934 len = 4;
15935 for (i = 0; i < len; i++)
15936 if (a1[i] != a2[i])
15937 break;
15938 if (i != len)
15939 retn = (a1[i] > a2[i]) ? 1 : ((a1[i] < a2[i]) ? -1 : 0);
15940 break;
15941 }
15942 case ARGUS_TYPE_RARP:
15943 retn = bcmp (&f1->rarp_flow.dhaddr, &f2->rarp_flow.dhaddr, 6);
15944 break;
15945 case ARGUS_TYPE_ARP: {
15946 unsigned int *a1, *a2;
15947 a1 = (unsigned int *)&f1->arp_flow.arp_tpa;
15948 a2 = (unsigned int *)&f2->arp_flow.arp_tpa;
15949 retn = (*a1 > *a2) ? 1 : ((*a1 < *a2) ? -1 : 0);
15950 break;
15951 }
15952 case ARGUS_TYPE_ETHER: {
15953 unsigned char *a1, *a2;
15954 a1 = (unsigned char *)&f1->mac_flow.mac_union.ether.ehdr.ether_shost;
15955 a2 = (unsigned char *)&f2->mac_flow.mac_union.ether.ehdr.ether_shost;
15956 len = 6;
15957 for (i = 0; i < len; i++)
15958 if (a1[i] != a2[i])
15959 break;
15960 if (i != len)
15961 retn = (a1[i] > a2[i]) ? 1 : ((a1[i] < a2[i]) ? -1 : 0);
15962 break;
15963 }
15964 case ARGUS_TYPE_WLAN: {
15965 unsigned char *a1, *a2;
15966 a1 = (unsigned char *)&f1->wlan_flow.dhost;
15967 a2 = (unsigned char *)&f2->wlan_flow.dhost;
15968 len = 6;
15969 for (i = 0; i < len; i++)
15970 if (a1[i] != a2[i])
15971 break;
15972 if (i != len)
15973 retn = (a1[i] > a2[i]) ? 1 : ((a1[i] < a2[i]) ? -1 : 0);
15974 break;
15975 }
15976 }
15977 break;
15978 }
15979
15980 case ARGUS_FLOW_ARP: {
15981 switch (f1qual) {
15982 case ARGUS_TYPE_RARP: {
15983 break;
15984 }
15985
15986 case ARGUS_TYPE_ARP: {
15987 unsigned int *a1, *a2;
15988 a1 = (unsigned int *)&f1->arp_flow.arp_tpa;
15989 a2 = (unsigned int *)&f2->arp_flow.arp_tpa;
15990 retn = (*a1 > *a2) ? 1 : ((*a1 < *a2) ? -1 : 0);
15991 break;
15992 }
15993
15994 default: {
15995 unsigned int *a1, *a2;
15996 a1 = (unsigned int *)&f1->iarp_flow.arp_tpa;
15997 a2 = (unsigned int *)&f2->iarp_flow.arp_tpa;
15998 retn = (*a1 > *a2) ? 1 : ((*a1 < *a2) ? -1 : 0);
15999 }
16000 }
16001 break;
16002 }
16003
16004 default:
16005 break;
16006 }
16007 }
16008
16009 return(ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16010 }
16011
16012
16013 int
ArgusSortInode(struct ArgusRecordStruct * n2,struct ArgusRecordStruct * n1)16014 ArgusSortInode (struct ArgusRecordStruct *n2, struct ArgusRecordStruct *n1)
16015 {
16016 struct ArgusIcmpStruct *i1 = (struct ArgusIcmpStruct *) n1->dsrs[ARGUS_ICMP_INDEX];
16017 struct ArgusIcmpStruct *i2 = (struct ArgusIcmpStruct *) n2->dsrs[ARGUS_ICMP_INDEX];
16018 int retn = 0;
16019
16020 if (i1 && i2) {
16021 unsigned int *a1, *a2;
16022
16023 if ((i1->hdr.argus_dsrvl8.qual & ARGUS_ICMP_MAPPED) &&
16024 (i2->hdr.argus_dsrvl8.qual & ARGUS_ICMP_MAPPED)) {
16025
16026 a1 = &i1->osrcaddr;
16027 a2 = &i2->osrcaddr;
16028 retn = (*a1 > *a2) ? 1 : ((*a1 < *a2) ? -1 : 0);
16029 }
16030 }
16031
16032 return(ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16033 }
16034
16035
ArgusSortProtocol(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16036 int ArgusSortProtocol (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16037 {
16038 struct ArgusFlow *f1 = (struct ArgusFlow *) n1->dsrs[ARGUS_FLOW_INDEX];
16039 struct ArgusFlow *f2 = (struct ArgusFlow *) n2->dsrs[ARGUS_FLOW_INDEX];
16040 unsigned char p1 = 0, p2 = 0;
16041 int retn = 0;
16042
16043 if (f1 && f2) {
16044 switch (f1->hdr.subtype & 0x3F) {
16045 case ARGUS_FLOW_CLASSIC5TUPLE: {
16046 switch (f1->hdr.argus_dsrvl8.qual & 0x1F) {
16047 case ARGUS_TYPE_IPV4:
16048 p1 = f1->ip_flow.ip_p;
16049 break;
16050 case ARGUS_TYPE_IPV6:
16051 p1 = f1->ipv6_flow.ip_p;
16052 break;
16053 }
16054 break;
16055 }
16056
16057 default:
16058 break;
16059 }
16060 switch (f2->hdr.subtype & 0x3F) {
16061 case ARGUS_FLOW_CLASSIC5TUPLE: {
16062 switch (f2->hdr.argus_dsrvl8.qual & 0x1F) {
16063 case ARGUS_TYPE_IPV4:
16064 p2 = f2->ip_flow.ip_p;
16065 break;
16066 case ARGUS_TYPE_IPV6:
16067 p2 = f2->ipv6_flow.ip_p;
16068 break;
16069 }
16070 break;
16071 }
16072
16073 default:
16074 break;
16075 }
16076 }
16077
16078 retn = p1 - p2;
16079 return(ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16080 }
16081
ArgusSortSrcPort(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16082 int ArgusSortSrcPort (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16083 {
16084 struct ArgusFlow *f1 = (struct ArgusFlow *) n1->dsrs[ARGUS_FLOW_INDEX];
16085 struct ArgusFlow *f2 = (struct ArgusFlow *) n2->dsrs[ARGUS_FLOW_INDEX];
16086 int retn = 0;
16087
16088 if (f1 && f2) {
16089 unsigned short p1 = 0, p2 = 0;
16090
16091 switch (f1->hdr.subtype & 0x3F) {
16092 case ARGUS_FLOW_CLASSIC5TUPLE: {
16093 switch (f1->hdr.argus_dsrvl8.qual & 0x1F) {
16094 case ARGUS_TYPE_IPV4:
16095 if ((f1->ip_flow.ip_p == IPPROTO_TCP) || (f1->ip_flow.ip_p == IPPROTO_UDP))
16096 p1 = (f1->hdr.subtype & ARGUS_REVERSE) ? f1->ip_flow.dport : f1->ip_flow.sport;
16097 break;
16098 case ARGUS_TYPE_IPV6:
16099 switch (f1->ipv6_flow.ip_p) {
16100 case IPPROTO_TCP:
16101 case IPPROTO_UDP: {
16102 p1 = (f1->hdr.subtype & ARGUS_REVERSE) ? f1->ipv6_flow.dport : f1->ipv6_flow.sport;
16103 break;
16104 }
16105 case IPPROTO_ICMPV6:
16106 p1 = f1->icmpv6_flow.type;
16107 break;
16108 }
16109 break;
16110 }
16111 break;
16112 }
16113
16114 default:
16115 break;
16116 }
16117 switch (f2->hdr.subtype & 0x3F) {
16118 case ARGUS_FLOW_CLASSIC5TUPLE: {
16119 switch (f2->hdr.argus_dsrvl8.qual & 0x1F) {
16120 case ARGUS_TYPE_IPV4:
16121 if ((f2->ip_flow.ip_p == IPPROTO_TCP) || (f2->ip_flow.ip_p == IPPROTO_UDP))
16122 p2 = (f2->hdr.subtype & ARGUS_REVERSE) ? f2->ip_flow.dport : f2->ip_flow.sport;
16123 break;
16124 case ARGUS_TYPE_IPV6:
16125 switch (f2->ipv6_flow.ip_p) {
16126 case IPPROTO_TCP:
16127 case IPPROTO_UDP: {
16128 p2 = (f2->hdr.subtype & ARGUS_REVERSE) ? f2->ipv6_flow.dport : f2->ipv6_flow.sport;
16129 break;
16130 }
16131 case IPPROTO_ICMPV6:
16132 p2 = f2->icmpv6_flow.type;
16133 break;
16134 }
16135 }
16136 break;
16137 }
16138 default:
16139 break;
16140 }
16141
16142 retn = p2 - p1;
16143 }
16144 return(ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16145 }
16146
ArgusSortDstPort(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16147 int ArgusSortDstPort (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16148 {
16149 struct ArgusFlow *f1 = (struct ArgusFlow *) n1->dsrs[ARGUS_FLOW_INDEX];
16150 struct ArgusFlow *f2 = (struct ArgusFlow *) n2->dsrs[ARGUS_FLOW_INDEX];
16151 int retn = 0;
16152
16153 if (f1 && f2) {
16154 unsigned short p1 = 0, p2 = 0;
16155
16156 switch (f1->hdr.subtype & 0x3F) {
16157 case ARGUS_FLOW_CLASSIC5TUPLE: {
16158 switch (f1->hdr.argus_dsrvl8.qual & 0x1F) {
16159 case ARGUS_TYPE_IPV4:
16160 if ((f1->ip_flow.ip_p == IPPROTO_TCP) || (f1->ip_flow.ip_p == IPPROTO_UDP))
16161 p1 = (f1->hdr.subtype & ARGUS_REVERSE) ? f1->ip_flow.sport : f1->ip_flow.dport;
16162 break;
16163 case ARGUS_TYPE_IPV6:
16164 switch (f1->ipv6_flow.ip_p) {
16165 case IPPROTO_TCP:
16166 case IPPROTO_UDP: {
16167 p1 = (f1->hdr.subtype & ARGUS_REVERSE) ? f1->ipv6_flow.sport : f1->ipv6_flow.dport;
16168 break;
16169 }
16170 case IPPROTO_ICMPV6:
16171 p1 = f1->icmpv6_flow.code;
16172 break;
16173 }
16174
16175 break;
16176 }
16177 break;
16178 }
16179
16180 default:
16181 break;
16182 }
16183 switch (f2->hdr.subtype & 0x3F) {
16184 case ARGUS_FLOW_CLASSIC5TUPLE: {
16185 switch (f2->hdr.argus_dsrvl8.qual & 0x1F) {
16186 case ARGUS_TYPE_IPV4:
16187 if ((f2->ip_flow.ip_p == IPPROTO_TCP) || (f2->ip_flow.ip_p == IPPROTO_UDP))
16188 p2 = (f2->hdr.subtype & ARGUS_REVERSE) ? f2->ip_flow.sport : f2->ip_flow.dport;
16189 break;
16190 case ARGUS_TYPE_IPV6:
16191 switch (f1->ipv6_flow.ip_p) {
16192 case IPPROTO_TCP:
16193 case IPPROTO_UDP: {
16194 p2 = (f2->hdr.subtype & ARGUS_REVERSE) ? f2->ipv6_flow.sport : f2->ipv6_flow.dport;
16195 break;
16196 }
16197 case IPPROTO_ICMPV6:
16198 p2 = f2->icmpv6_flow.code;
16199 break;
16200 }
16201 break;
16202 }
16203 break;
16204 }
16205
16206 default:
16207 break;
16208 }
16209
16210 retn = p2 - p1;
16211 }
16212 return(ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16213 }
16214
ArgusSortSrcMpls(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16215 int ArgusSortSrcMpls (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16216 {
16217 struct ArgusMplsStruct *m1 = (struct ArgusMplsStruct *)n1->dsrs[ARGUS_MPLS_INDEX];
16218 struct ArgusMplsStruct *m2 = (struct ArgusMplsStruct *)n2->dsrs[ARGUS_MPLS_INDEX];
16219 int retn = 0;
16220
16221 if (m1 && m2) {
16222 unsigned int l1, l2;
16223 if ((m1->hdr.subtype & ARGUS_MPLS_SRC_LABEL) && (m2->hdr.subtype & ARGUS_MPLS_SRC_LABEL)) {
16224 unsigned char *p1 = (unsigned char *)&m1->slabel;
16225 unsigned char *p2 = (unsigned char *)&m2->slabel;
16226
16227 #if defined(_LITTLE_ENDIAN)
16228 l1 = (p1[0] << 12) | (p1[1] << 4) | ((p1[2] >> 4) & 0xff);
16229 l2 = (p2[0] << 12) | (p2[1] << 4) | ((p2[2] >> 4) & 0xff);
16230 #else
16231 l1 = (p1[3] << 12) | (p1[2] << 4) | ((p1[1] >> 4) & 0xff);
16232 l2 = (p2[3] << 12) | (p2[2] << 4) | ((p2[1] >> 4) & 0xff);
16233 #endif
16234 retn = l1 - l2;
16235
16236 } else
16237 retn = (m1->hdr.subtype & ARGUS_MPLS_SRC_LABEL) ? 1 :
16238 ((m2->hdr.subtype & ARGUS_MPLS_SRC_LABEL) ? -1 : 0);
16239 } else
16240 retn = (m1) ? 1 : ((m2) ? -1 : 0);
16241
16242 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16243 }
16244
ArgusSortDstMpls(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16245 int ArgusSortDstMpls (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16246 {
16247 struct ArgusMplsStruct *m1 = (struct ArgusMplsStruct *)n1->dsrs[ARGUS_MPLS_INDEX];
16248 struct ArgusMplsStruct *m2 = (struct ArgusMplsStruct *)n2->dsrs[ARGUS_MPLS_INDEX];
16249 int retn = 0;
16250
16251 if (m1 && m2) {
16252 unsigned int l1, l2;
16253 if ((m1->hdr.subtype & ARGUS_MPLS_DST_LABEL) && (m2->hdr.subtype & ARGUS_MPLS_DST_LABEL)) {
16254 unsigned char *p1 = (unsigned char *)&m1->dlabel;
16255 unsigned char *p2 = (unsigned char *)&m2->dlabel;
16256
16257 #if defined(_LITTLE_ENDIAN)
16258 l1 = (p1[0] << 12) | (p1[1] << 4) | ((p1[2] >> 4) & 0xff);
16259 l2 = (p2[0] << 12) | (p2[1] << 4) | ((p2[2] >> 4) & 0xff);
16260 #else
16261 l1 = (p1[3] << 12) | (p1[2] << 4) | ((p1[1] >> 4) & 0xff);
16262 l2 = (p2[3] << 12) | (p2[2] << 4) | ((p2[1] >> 4) & 0xff);
16263 #endif
16264 retn = l1 - l2;
16265
16266 } else
16267 retn = (m1->hdr.subtype & ARGUS_MPLS_DST_LABEL) ? 1 :
16268 ((m2->hdr.subtype & ARGUS_MPLS_DST_LABEL) ? -1 : 0);
16269 } else
16270 retn = (m1) ? 1 : ((m2) ? -1 : 0);
16271
16272 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16273 }
16274
ArgusSortSrcVlan(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16275 int ArgusSortSrcVlan (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16276 {
16277 struct ArgusVlanStruct *v1 = (struct ArgusVlanStruct *)n1->dsrs[ARGUS_VLAN_INDEX];
16278 struct ArgusVlanStruct *v2 = (struct ArgusVlanStruct *)n2->dsrs[ARGUS_VLAN_INDEX];
16279 int retn = 0;
16280
16281 if (v1 && v2) {
16282 if ((v1->hdr.argus_dsrvl8.qual & ARGUS_SRC_VLAN) && (v2->hdr.argus_dsrvl8.qual & ARGUS_SRC_VLAN)) {
16283 retn = (v1->sid & 0x0FFF) - (v2->sid & 0x0FFF);
16284 } else {
16285 retn = (v1->hdr.argus_dsrvl8.qual & ARGUS_SRC_VLAN) ? 1 :
16286 ((v2->hdr.argus_dsrvl8.qual & ARGUS_SRC_VLAN) ? -1 : 0);
16287 }
16288 } else
16289 retn = (v1) ? 1 : ((v2) ? -1 : 0);
16290
16291 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16292 }
16293
ArgusSortDstVlan(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16294 int ArgusSortDstVlan (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16295 {
16296 struct ArgusVlanStruct *v1 = (struct ArgusVlanStruct *)n1->dsrs[ARGUS_VLAN_INDEX];
16297 struct ArgusVlanStruct *v2 = (struct ArgusVlanStruct *)n2->dsrs[ARGUS_VLAN_INDEX];
16298 int retn = 0;
16299
16300 if (v1 && v2) {
16301 if ((v1->hdr.argus_dsrvl8.qual & ARGUS_DST_VLAN) && (v2->hdr.argus_dsrvl8.qual & ARGUS_DST_VLAN)) {
16302 retn = (v1->did & 0x0FFF) - (v2->did & 0x0FFF);
16303 } else {
16304 retn = (v1->hdr.argus_dsrvl8.qual & ARGUS_DST_VLAN) ? 1 :
16305 ((v2->hdr.argus_dsrvl8.qual & ARGUS_DST_VLAN) ? -1 : 0);
16306 }
16307
16308 } else
16309 retn = (v1) ? 1 : ((v2) ? -1 : 0);
16310
16311 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16312 }
16313
ArgusSortSrcIpId(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16314 int ArgusSortSrcIpId (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16315 {
16316 struct ArgusIPAttrStruct *ip1 = (struct ArgusIPAttrStruct *)n1->dsrs[ARGUS_IPATTR_INDEX];
16317 struct ArgusIPAttrStruct *ip2 = (struct ArgusIPAttrStruct *)n2->dsrs[ARGUS_IPATTR_INDEX];
16318 unsigned short ipid1, ipid2;
16319 int retn = 0;
16320
16321 if (ip1 && ip2) {
16322 ipid1 = ip1->src.ip_id;
16323 ipid2 = ip2->src.ip_id;
16324 retn = ipid1 - ipid2;
16325 }
16326
16327 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16328 }
16329
ArgusSortDstIpId(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16330 int ArgusSortDstIpId (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16331 {
16332 struct ArgusIPAttrStruct *ip1 = (struct ArgusIPAttrStruct *)n1->dsrs[ARGUS_IPATTR_INDEX];
16333 struct ArgusIPAttrStruct *ip2 = (struct ArgusIPAttrStruct *)n2->dsrs[ARGUS_IPATTR_INDEX];
16334 int retn = 0;
16335
16336 if (ip1 && ip2) {
16337 unsigned char ipid1, ipid2;
16338
16339 ipid1 = ip1->src.ip_id;
16340 ipid2 = ip2->src.ip_id;
16341 retn = ipid1 - ipid2;
16342 }
16343
16344 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16345 }
16346
ArgusSortSrcTos(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16347 int ArgusSortSrcTos (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16348 {
16349 struct ArgusIPAttrStruct *ip1 = (struct ArgusIPAttrStruct *)n1->dsrs[ARGUS_IPATTR_INDEX];
16350 struct ArgusIPAttrStruct *ip2 = (struct ArgusIPAttrStruct *)n2->dsrs[ARGUS_IPATTR_INDEX];
16351 int retn = 0;
16352
16353 if (ip1 && ip2) {
16354 unsigned char tos1, tos2;
16355
16356 tos1 = ip1->src.tos;
16357 tos2 = ip2->src.tos;
16358 retn = tos1 - tos2;
16359 }
16360
16361 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16362 }
16363
ArgusSortDstTos(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16364 int ArgusSortDstTos (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16365 {
16366 struct ArgusIPAttrStruct *ip1 = (struct ArgusIPAttrStruct *)n1->dsrs[ARGUS_IPATTR_INDEX];
16367 struct ArgusIPAttrStruct *ip2 = (struct ArgusIPAttrStruct *)n2->dsrs[ARGUS_IPATTR_INDEX];
16368 int retn = 0;
16369
16370 if (ip1 && ip2) {
16371 unsigned char tos1, tos2;
16372
16373 tos1 = ip1->dst.tos;
16374 tos2 = ip2->dst.tos;
16375 retn = tos1 - tos2;
16376 }
16377
16378 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16379 }
16380
ArgusSortSrcDSByte(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16381 int ArgusSortSrcDSByte (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16382 {
16383 struct ArgusIPAttrStruct *ip1 = (struct ArgusIPAttrStruct *)n1->dsrs[ARGUS_IPATTR_INDEX];
16384 struct ArgusIPAttrStruct *ip2 = (struct ArgusIPAttrStruct *)n2->dsrs[ARGUS_IPATTR_INDEX];
16385 int retn = 0;
16386
16387 if (ip1 && ip2) {
16388 unsigned char dsb1, dsb2;
16389
16390 dsb1 = (ip1->src.tos >> 2);
16391 dsb2 = (ip2->src.tos >> 2);
16392 retn = dsb1 - dsb2;
16393 }
16394
16395 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16396 }
16397
ArgusSortDstDSByte(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16398 int ArgusSortDstDSByte (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16399 {
16400 struct ArgusIPAttrStruct *ip1 = (struct ArgusIPAttrStruct *)n1->dsrs[ARGUS_IPATTR_INDEX];
16401 struct ArgusIPAttrStruct *ip2 = (struct ArgusIPAttrStruct *)n2->dsrs[ARGUS_IPATTR_INDEX];
16402 int retn = 0;
16403
16404 if (ip1 && ip2) {
16405 unsigned char dsb1, dsb2;
16406 dsb1 = (ip1->dst.tos >> 2);
16407 dsb2 = (ip2->dst.tos >> 2);
16408 retn = dsb1 - dsb2;
16409 }
16410
16411 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16412 }
16413
ArgusSortSrcTtl(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16414 int ArgusSortSrcTtl (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16415 {
16416 struct ArgusIPAttrStruct *ip1 = (struct ArgusIPAttrStruct *)n1->dsrs[ARGUS_IPATTR_INDEX];
16417 struct ArgusIPAttrStruct *ip2 = (struct ArgusIPAttrStruct *)n2->dsrs[ARGUS_IPATTR_INDEX];
16418 int retn = 0;
16419
16420 if (ip1 && ip2) {
16421 if ((ip1->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_SRC) &&
16422 (ip2->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_SRC)) {
16423 unsigned char ttl1, ttl2;
16424
16425 ttl1 = ip1->src.ttl;
16426 ttl2 = ip2->src.ttl;
16427 retn = (ttl1 < ttl2) ? 1 : ((ttl1 == ttl2) ? 0 : -1);
16428 }
16429 }
16430
16431 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16432 }
16433
ArgusSortDstTtl(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16434 int ArgusSortDstTtl (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16435 {
16436 struct ArgusIPAttrStruct *ip1 = (struct ArgusIPAttrStruct *)n1->dsrs[ARGUS_IPATTR_INDEX];
16437 struct ArgusIPAttrStruct *ip2 = (struct ArgusIPAttrStruct *)n2->dsrs[ARGUS_IPATTR_INDEX];
16438 int retn = 0;
16439
16440 if (ip1 && ip2) {
16441 if ((ip1->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_DST) &&
16442 (ip2->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_DST)) {
16443 unsigned char ttl1, ttl2;
16444
16445 ttl1 = ip1->dst.ttl;
16446 ttl2 = ip2->dst.ttl;
16447 retn = (ttl1 < ttl2) ? 1 : ((ttl1 == ttl2) ? 0 : -1);
16448 }
16449 }
16450
16451 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16452 }
16453
ArgusSortTransactions(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16454 int ArgusSortTransactions (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16455 {
16456 struct ArgusAgrStruct *a1 = (struct ArgusAgrStruct *)n1->dsrs[ARGUS_AGR_INDEX];
16457 struct ArgusAgrStruct *a2 = (struct ArgusAgrStruct *)n2->dsrs[ARGUS_AGR_INDEX];
16458 int retn = 0;
16459
16460 if (a1 && a2)
16461 retn = (a1->count > a2->count) ? 1 : ((a1->count < a2->count) ? -1 : 0);
16462
16463 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16464 }
16465
16466 int
ArgusSortSrcLoad(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16467 ArgusSortSrcLoad (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16468 {
16469 double r1 = 0.0, r2 = 0.0;
16470 int retn = 0;
16471
16472 if (n1)
16473 r1 = ArgusFetchSrcLoad(n1);
16474 if (n2)
16475 r2 = ArgusFetchSrcLoad(n2);
16476 retn = (r1 > r2) ? 1 : ((r1 == r2) ? 0 : -1);
16477 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16478 }
16479
16480 int
ArgusSortDstLoad(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16481 ArgusSortDstLoad (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16482 {
16483 double r1 = 0.0, r2 = 0.0;
16484 int retn = 0;
16485
16486 if (n1)
16487 r1 = ArgusFetchDstLoad(n1);
16488 if (n2)
16489 r2 = ArgusFetchDstLoad(n2);
16490 retn = (r1 > r2) ? 1 : ((r1 == r2) ? 0 : -1);
16491 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16492 }
16493
16494
16495 int
ArgusSortLoad(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16496 ArgusSortLoad (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16497 {
16498 double r1 = 0.0, r2 = 0.0;
16499 int retn = 0;
16500
16501 if (n1)
16502 r1 = ArgusFetchLoad(n1);
16503 if (n2)
16504 r2 = ArgusFetchLoad(n2);
16505 retn = (r1 > r2) ? 1 : ((r1 == r2) ? 0 : -1);
16506 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16507 }
16508
16509
16510 int
ArgusSortLoss(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16511 ArgusSortLoss (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16512 {
16513 double l1 = 0.0, l2 = 0.0;
16514 int retn = 0;
16515
16516 if (n1)
16517 l1 = ArgusFetchLoss(n1);
16518
16519 if (n2)
16520 l2 = ArgusFetchLoss(n2);
16521
16522 retn = (l1 > l2) ? 1 : ((l1 == l2) ? 0 : -1);
16523 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16524 }
16525
16526
16527 int
ArgusSortSrcLoss(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16528 ArgusSortSrcLoss (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16529 {
16530 double l1 = 0.0, l2 = 0.0;
16531 int retn = 0;
16532
16533 if (n1)
16534 l1 = ArgusFetchSrcLoss(n1);
16535
16536 if (n2)
16537 l2 = ArgusFetchSrcLoss(n2);
16538
16539 retn = (l1 > l2) ? 1 : ((l1 == l2) ? 0 : -1);
16540 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16541 }
16542
ArgusSortDstLoss(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16543 int ArgusSortDstLoss (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16544 {
16545 double l1 = 0.0, l2 = 0.0;
16546 int retn = 0;
16547
16548 if (n1)
16549 l1 = ArgusFetchDstLoss(n1);
16550 if (n2)
16551 l2 = ArgusFetchDstLoss(n2);
16552 retn = (l1 > l2) ? 1 : ((l1 == l2) ? 0 : -1);
16553 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16554 }
16555
16556 int
ArgusSortPercentLoss(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16557 ArgusSortPercentLoss (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16558 {
16559 double l1 = 0.0, l2 = 0.0;
16560 int retn = 0;
16561
16562 if (n1)
16563 l1 = ArgusFetchPercentLoss(n1);
16564
16565 if (n2)
16566 l2 = ArgusFetchPercentLoss(n2);
16567
16568 retn = (l1 > l2) ? 1 : ((l1 == l2) ? 0 : -1);
16569 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16570 }
16571
16572
16573 int
ArgusSortPercentSrcLoss(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16574 ArgusSortPercentSrcLoss (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16575 {
16576 double l1 = 0.0, l2 = 0.0;
16577 int retn = 0;
16578
16579 if (n1)
16580 l1 = ArgusFetchPercentSrcLoss(n1);
16581
16582 if (n2)
16583 l2 = ArgusFetchPercentSrcLoss(n2);
16584
16585 retn = (l1 > l2) ? 1 : ((l1 == l2) ? 0 : -1);
16586 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16587 }
16588
ArgusSortPercentDstLoss(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16589 int ArgusSortPercentDstLoss (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16590 {
16591 double l1 = 0.0, l2 = 0.0;
16592 int retn = 0;
16593
16594 if (n1)
16595 l1 = ArgusFetchPercentDstLoss(n1);
16596 if (n2)
16597 l2 = ArgusFetchPercentDstLoss(n2);
16598 retn = (l1 > l2) ? 1 : ((l1 == l2) ? 0 : -1);
16599 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16600 }
16601
16602 int
ArgusSortSrcRate(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16603 ArgusSortSrcRate (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16604 {
16605 double r1 = 0.0, r2 = 0.0;
16606 int retn = 0;
16607
16608 if (n1)
16609 r1 = ArgusFetchSrcRate(n1);
16610 if (n2)
16611 r2 = ArgusFetchSrcRate(n2);
16612 retn = (r1 > r2) ? 1 : ((r1 == r2) ? 0 : -1);
16613 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16614 }
16615
16616 int
ArgusSortDstRate(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16617 ArgusSortDstRate (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16618 {
16619 double r1 = 0.0, r2 = 0.0;
16620 int retn = 0;
16621
16622 if (n1)
16623 r1 = ArgusFetchSrcRate(n1);
16624 if (n2)
16625 r2 = ArgusFetchSrcRate(n2);
16626 retn = (r1 > r2) ? 1 : ((r1 == r2) ? 0 : -1);
16627 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16628 }
16629
16630 int
ArgusSortRate(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16631 ArgusSortRate (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16632 {
16633 double r1 = 0.0, r2 = 0.0;
16634 int retn = 0;
16635
16636 if (n1)
16637 r1 = ArgusFetchRate(n1);
16638 if (n2)
16639 r2 = ArgusFetchRate(n2);
16640 retn = (r1 > r2) ? 1 : ((r1 == r2) ? 0 : -1);
16641 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16642 }
16643
16644 int
ArgusSortTranRef(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16645 ArgusSortTranRef (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16646 {
16647 int retn = 0;
16648 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16649 }
16650
16651 int
ArgusSortSeq(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16652 ArgusSortSeq (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16653 {
16654 struct ArgusTransportStruct *t1 = (struct ArgusTransportStruct *)n1->dsrs[ARGUS_TRANSPORT_INDEX];
16655 struct ArgusTransportStruct *t2 = (struct ArgusTransportStruct *)n2->dsrs[ARGUS_TRANSPORT_INDEX];
16656 int retn = 0;
16657
16658 if (t1 && t2) {
16659 unsigned int seq1 = 0, seq2 = 0;
16660
16661 if (t1->hdr.subtype & ARGUS_SEQ)
16662 seq1 = t1->seqnum;
16663
16664 if (t2->hdr.subtype & ARGUS_SEQ)
16665 seq2 = t2->seqnum;
16666
16667 retn = seq2 - seq1;
16668 }
16669 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16670 }
16671
16672
16673 int
ArgusSortSrcGap(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16674 ArgusSortSrcGap (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16675 {
16676 double l1 = 0.0, l2 = 0.0;
16677 int retn = 0;
16678
16679 if (n1)
16680 l1 = ArgusFetchSrcGap(n1);
16681
16682 if (n2)
16683 l2 = ArgusFetchSrcGap(n2);
16684
16685 retn = (l1 > l2) ? 1 : ((l1 == l2) ? 0 : -1);
16686 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16687 }
16688
ArgusSortDstGap(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16689 int ArgusSortDstGap (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16690 {
16691 double l1 = 0.0, l2 = 0.0;
16692 int retn = 0;
16693
16694 if (n1)
16695 l1 = ArgusFetchDstGap(n1);
16696 if (n2)
16697 l2 = ArgusFetchDstGap(n2);
16698 retn = (l1 > l2) ? 1 : ((l1 == l2) ? 0 : -1);
16699 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16700 }
16701
16702 /*
16703 int
16704 ArgusSortSrcDup (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16705 {
16706 double l1 = 0.0, l2 = 0.0;
16707 int retn = 0;
16708
16709 if (n1)
16710 l1 = ArgusFetchSrcDup(n1);
16711
16712 if (n2)
16713 l2 = ArgusFetchSrcDup(n2);
16714
16715 retn = (l1 > l2) ? 1 : ((l1 == l2) ? 0 : -1);
16716 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16717 }
16718
16719 int ArgusSortDstDup (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16720 {
16721 double l1 = 0.0, l2 = 0.0;
16722 int retn = 0;
16723
16724 if (n1)
16725 l1 = ArgusFetchDstDup(n1);
16726 if (n2)
16727 l2 = ArgusFetchDstDup(n2);
16728 retn = (l1 > l2) ? 1 : ((l1 == l2) ? 0 : -1);
16729 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16730 }
16731 */
16732
16733
16734
16735 int
ArgusSortByteCount(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16736 ArgusSortByteCount (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16737 {
16738 struct ArgusMetricStruct *m1 = NULL, *m2 = NULL;
16739 long long cnt1 = 0, cnt2 = 0;
16740 int retn = 0;
16741
16742 if ((m1 = (struct ArgusMetricStruct *) n1->dsrs[ARGUS_METRIC_INDEX]) != NULL)
16743 cnt1 = m1->src.bytes + m1->dst.bytes;
16744
16745 if ((m2 = (struct ArgusMetricStruct *) n2->dsrs[ARGUS_METRIC_INDEX]) != NULL)
16746 cnt2 = m2->src.bytes + m2->dst.bytes;
16747
16748 retn = ArgusReverseSortDir ? ((cnt1 < cnt2) ? 1 : ((cnt1 == cnt2) ? 0 : -1)) :
16749 ((cnt1 > cnt2) ? 1 : ((cnt1 == cnt2) ? 0 : -1)) ;
16750 return (retn);
16751 }
16752
16753 int
ArgusSortSrcByteCount(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16754 ArgusSortSrcByteCount (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16755 {
16756 struct ArgusMetricStruct *m1 = NULL, *m2 = NULL;
16757 long long cnt1 = 0, cnt2 = 0;
16758 int retn = 0;
16759
16760 if ((m1 = (struct ArgusMetricStruct *) n1->dsrs[ARGUS_METRIC_INDEX]) != NULL)
16761 cnt1 = m1->src.bytes;
16762
16763 if ((m2 = (struct ArgusMetricStruct *) n2->dsrs[ARGUS_METRIC_INDEX]) != NULL)
16764 cnt2 = m2->src.bytes;
16765
16766 retn = ArgusReverseSortDir ? ((cnt1 < cnt2) ? 1 : ((cnt1 == cnt2) ? 0 : -1)) :
16767 ((cnt1 > cnt2) ? 1 : ((cnt1 == cnt2) ? 0 : -1)) ;
16768 return (retn);
16769 }
16770
16771 int
ArgusSortDstByteCount(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16772 ArgusSortDstByteCount (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16773 {
16774 struct ArgusMetricStruct *m1 = NULL, *m2 = NULL;
16775 long long cnt1 = 0, cnt2 = 0;
16776 int retn = 0;
16777
16778 if ((m1 = (struct ArgusMetricStruct *) n1->dsrs[ARGUS_METRIC_INDEX]) != NULL)
16779 cnt1 = m1->dst.bytes;
16780
16781 if ((m2 = (struct ArgusMetricStruct *) n2->dsrs[ARGUS_METRIC_INDEX]) != NULL)
16782 cnt2 = m2->dst.bytes;
16783
16784 retn = ArgusReverseSortDir ? ((cnt1 < cnt2) ? 1 : ((cnt1 == cnt2) ? 0 : -1)) :
16785 ((cnt1 > cnt2) ? 1 : ((cnt1 == cnt2) ? 0 : -1)) ;
16786 return (retn);
16787 }
16788
16789 int
ArgusSortAppByteRatio(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16790 ArgusSortAppByteRatio (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16791 {
16792 double r1 = 0.0, r2 = 0.0;
16793 int retn = 0;
16794
16795 if (n1)
16796 r1 = ArgusFetchAppByteRatio(n1);
16797 if (n2)
16798 r2 = ArgusFetchAppByteRatio(n2);
16799
16800 retn = (r1 > r2) ? 1 : ((r1 == r2) ? 0 : -1);
16801 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
16802 }
16803
16804 int
ArgusSortPktsCount(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16805 ArgusSortPktsCount (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16806 {
16807 struct ArgusMetricStruct *m1 = NULL, *m2 = NULL;
16808 long long cnt1 = 0, cnt2 = 0;
16809 int retn = 0;
16810
16811 if ((m1 = (struct ArgusMetricStruct *) n1->dsrs[ARGUS_METRIC_INDEX]) != NULL)
16812 cnt1 = m1->src.pkts + m1->dst.pkts;
16813
16814 if ((m2 = (struct ArgusMetricStruct *) n2->dsrs[ARGUS_METRIC_INDEX]) != NULL)
16815 cnt2 = m2->src.pkts + m2->dst.pkts;
16816
16817 retn = ArgusReverseSortDir ? ((cnt1 < cnt2) ? 1 : ((cnt1 == cnt2) ? 0 : -1)) :
16818 ((cnt1 > cnt2) ? 1 : ((cnt1 == cnt2) ? 0 : -1)) ;
16819 return (retn);
16820 }
16821
16822 int
ArgusSortSrcPktsCount(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16823 ArgusSortSrcPktsCount (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16824 {
16825 struct ArgusMetricStruct *m1 = NULL, *m2 = NULL;
16826 long long cnt1 = 0, cnt2 = 0;
16827 int retn = 0;
16828
16829 if ((m1 = (struct ArgusMetricStruct *) n1->dsrs[ARGUS_METRIC_INDEX]) != NULL)
16830 cnt1 = m1->src.pkts;
16831
16832 if ((m2 = (struct ArgusMetricStruct *) n2->dsrs[ARGUS_METRIC_INDEX]) != NULL)
16833 cnt2 = m2->src.pkts;
16834
16835 retn = ArgusReverseSortDir ? ((cnt1 < cnt2) ? 1 : ((cnt1 == cnt2) ? 0 : -1)) :
16836 ((cnt1 > cnt2) ? 1 : ((cnt1 == cnt2) ? 0 : -1)) ;
16837 return (retn);
16838 }
16839
16840 int
ArgusSortDstPktsCount(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16841 ArgusSortDstPktsCount (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16842 {
16843 struct ArgusMetricStruct *m1 = NULL, *m2 = NULL;
16844 long long cnt1 = 0, cnt2 = 0;
16845 int retn = 0;
16846
16847 if ((m1 = (struct ArgusMetricStruct *) n1->dsrs[ARGUS_METRIC_INDEX]) != NULL)
16848 cnt1 = m1->dst.pkts;
16849
16850 if ((m2 = (struct ArgusMetricStruct *) n2->dsrs[ARGUS_METRIC_INDEX]) != NULL)
16851 cnt2 = m2->dst.pkts;
16852
16853 retn = ArgusReverseSortDir ? ((cnt1 < cnt2) ? 1 : ((cnt1 == cnt2) ? 0 : -1)) :
16854 ((cnt1 > cnt2) ? 1 : ((cnt1 == cnt2) ? 0 : -1)) ;
16855 return (retn);
16856 }
16857
16858 int
ArgusSortAppByteCount(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16859 ArgusSortAppByteCount (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16860 {
16861 struct ArgusMetricStruct *m1 = NULL, *m2 = NULL;
16862 long long cnt1 = 0, cnt2 = 0;
16863 int retn = 0;
16864
16865 if ((m1 = (struct ArgusMetricStruct *) n1->dsrs[ARGUS_METRIC_INDEX]) != NULL)
16866 cnt1 = m1->src.appbytes + m1->dst.appbytes;
16867
16868 if ((m2 = (struct ArgusMetricStruct *) n2->dsrs[ARGUS_METRIC_INDEX]) != NULL)
16869 cnt2 = m2->src.appbytes + m2->dst.appbytes;
16870
16871 retn = ArgusReverseSortDir ? ((cnt1 < cnt2) ? 1 : ((cnt1 == cnt2) ? 0 : -1)) :
16872 ((cnt1 > cnt2) ? 1 : ((cnt1 == cnt2) ? 0 : -1)) ;
16873 return (retn);
16874 }
16875
16876 int
ArgusSortSrcAppByteCount(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16877 ArgusSortSrcAppByteCount (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16878 {
16879 struct ArgusMetricStruct *m1 = NULL, *m2 = NULL;
16880 long long cnt1 = 0, cnt2 = 0;
16881 int retn = 0;
16882
16883 if ((m1 = (struct ArgusMetricStruct *) n1->dsrs[ARGUS_METRIC_INDEX]) != NULL)
16884 cnt1 = m1->src.appbytes;
16885
16886 if ((m2 = (struct ArgusMetricStruct *) n2->dsrs[ARGUS_METRIC_INDEX]) != NULL)
16887 cnt2 = m2->src.appbytes;
16888
16889 retn = ArgusReverseSortDir ? ((cnt1 < cnt2) ? 1 : ((cnt1 == cnt2) ? 0 : -1)) :
16890 ((cnt1 > cnt2) ? 1 : ((cnt1 == cnt2) ? 0 : -1)) ;
16891 return (retn);
16892 }
16893
16894 int
ArgusSortDstAppByteCount(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)16895 ArgusSortDstAppByteCount (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
16896 {
16897 struct ArgusMetricStruct *m1 = NULL, *m2 = NULL;
16898 long long cnt1 = 0, cnt2 = 0;
16899 int retn = 0;
16900
16901 if ((m1 = (struct ArgusMetricStruct *) n1->dsrs[ARGUS_METRIC_INDEX]) != NULL)
16902 cnt1 = m1->dst.appbytes;
16903
16904 if ((m2 = (struct ArgusMetricStruct *) n2->dsrs[ARGUS_METRIC_INDEX]) != NULL)
16905 cnt2 = m2->dst.appbytes;
16906
16907 retn = ArgusReverseSortDir ? ((cnt1 < cnt2) ? 1 : ((cnt1 == cnt2) ? 0 : -1)) :
16908 ((cnt1 > cnt2) ? 1 : ((cnt1 == cnt2) ? 0 : -1)) ;
16909 return (retn);
16910 }
16911
16912 int
ArgusSortSrvSignatures(struct ArgusRecordStruct * argus1,struct ArgusRecordStruct * argus2)16913 ArgusSortSrvSignatures (struct ArgusRecordStruct *argus1, struct ArgusRecordStruct *argus2)
16914 {
16915 struct RaSrvSignature *data1 = *(struct RaSrvSignature **)argus1;
16916 struct RaSrvSignature *data2 = *(struct RaSrvSignature **)argus2;
16917 int cnt1 = data1->count;
16918 int cnt2 = data2->count;
16919 int retn = 0;
16920
16921 retn = ArgusReverseSortDir ? ((cnt1 < cnt2) ? 1 : ((cnt1 == cnt2) ? 0 : -1)) :
16922 ((cnt1 > cnt2) ? 1 : ((cnt1 == cnt2) ? 0 : -1)) ;
16923 return (retn);
16924 }
16925
16926
16927 int
ArgusSortSrcTcpBase(struct ArgusRecordStruct * argus1,struct ArgusRecordStruct * argus2)16928 ArgusSortSrcTcpBase (struct ArgusRecordStruct *argus1, struct ArgusRecordStruct *argus2)
16929 {
16930 struct ArgusNetworkStruct *net1 = (void *)argus1->dsrs[ARGUS_NETWORK_INDEX];
16931 struct ArgusNetworkStruct *net2 = (void *)argus2->dsrs[ARGUS_NETWORK_INDEX];
16932 int retn = 0;
16933
16934 if (net1 && net2) {
16935 struct ArgusTCPObject *tcp1 = &net1->net_union.tcp;
16936 struct ArgusTCPObject *tcp2 = &net2->net_union.tcp;
16937 struct ArgusFlow *flow1 = (void *)argus1->dsrs[ARGUS_FLOW_INDEX];
16938 struct ArgusFlow *flow2 = (void *)argus2->dsrs[ARGUS_FLOW_INDEX];
16939
16940 unsigned int seq1 = 0;
16941 unsigned int seq2 = 0;
16942
16943 if (flow1 != NULL) {
16944 switch (flow1->hdr.subtype & 0x3F) {
16945 case ARGUS_FLOW_CLASSIC5TUPLE: {
16946 switch (flow1->hdr.argus_dsrvl8.qual & 0x1F) {
16947 case ARGUS_TYPE_IPV4:
16948 switch (flow1->ip_flow.ip_p) {
16949 case IPPROTO_TCP:
16950 seq1 = tcp1->src.seqbase;
16951 break;
16952 }
16953 break;
16954
16955 case ARGUS_TYPE_IPV6:
16956 switch (flow1->ipv6_flow.ip_p) {
16957 case IPPROTO_TCP:
16958 seq1 = tcp1->src.seqbase;
16959 break;
16960 }
16961 break;
16962 }
16963 break;
16964 }
16965 }
16966 }
16967
16968 if (flow2 != NULL) {
16969 switch (flow2->hdr.subtype & 0x3F) {
16970 case ARGUS_FLOW_CLASSIC5TUPLE: {
16971 switch (flow2->hdr.argus_dsrvl8.qual & 0x1F) {
16972 case ARGUS_TYPE_IPV4:
16973 switch (flow2->ip_flow.ip_p) {
16974 case IPPROTO_TCP:
16975 seq2 = tcp2->src.seqbase;
16976 break;
16977 }
16978 break;
16979
16980 case ARGUS_TYPE_IPV6:
16981 switch (flow2->ipv6_flow.ip_p) {
16982 case IPPROTO_TCP:
16983 seq2 = tcp2->src.seqbase;
16984 break;
16985 }
16986 break;
16987 }
16988 break;
16989 }
16990 }
16991 }
16992
16993 retn = ArgusReverseSortDir ? ((seq1 < seq2) ? 1 : ((seq1 == seq2) ? 0 : -1)) :
16994 ((seq1 > seq2) ? 1 : ((seq1 == seq2) ? 0 : -1)) ;
16995 }
16996
16997 return (retn);
16998 }
16999
17000
17001 int
ArgusSortDstTcpBase(struct ArgusRecordStruct * argus1,struct ArgusRecordStruct * argus2)17002 ArgusSortDstTcpBase (struct ArgusRecordStruct *argus1, struct ArgusRecordStruct *argus2)
17003 {
17004 struct ArgusNetworkStruct *net1 = (void *)argus1->dsrs[ARGUS_NETWORK_INDEX];
17005 struct ArgusNetworkStruct *net2 = (void *)argus2->dsrs[ARGUS_NETWORK_INDEX];
17006 int retn = 0;
17007
17008 if (net1 && net2) {
17009 struct ArgusTCPObject *tcp1 = &net1->net_union.tcp;
17010 struct ArgusTCPObject *tcp2 = &net2->net_union.tcp;
17011
17012 struct ArgusFlow *flow1 = (void *)argus1->dsrs[ARGUS_FLOW_INDEX];
17013 struct ArgusFlow *flow2 = (void *)argus2->dsrs[ARGUS_FLOW_INDEX];
17014
17015 unsigned int seq1 = 0;
17016 unsigned int seq2 = 0;
17017
17018 if (flow1 != NULL) {
17019 switch (flow1->hdr.subtype & 0x3F) {
17020 case ARGUS_FLOW_CLASSIC5TUPLE: {
17021 switch (flow1->hdr.argus_dsrvl8.qual & 0x1F) {
17022 case ARGUS_TYPE_IPV4:
17023 switch (flow1->ip_flow.ip_p) {
17024 case IPPROTO_TCP:
17025 seq1 = tcp1->dst.seqbase;
17026 break;
17027 }
17028 break;
17029
17030 case ARGUS_TYPE_IPV6:
17031 switch (flow1->ipv6_flow.ip_p) {
17032 case IPPROTO_TCP:
17033 seq1 = tcp1->dst.seqbase;
17034 break;
17035 }
17036 break;
17037 }
17038 break;
17039 }
17040 }
17041 }
17042
17043 if (flow2 != NULL) {
17044 switch (flow2->hdr.subtype & 0x3F) {
17045 case ARGUS_FLOW_CLASSIC5TUPLE: {
17046 switch (flow2->hdr.argus_dsrvl8.qual & 0x1F) {
17047 case ARGUS_TYPE_IPV4:
17048 switch (flow2->ip_flow.ip_p) {
17049 case IPPROTO_TCP:
17050 seq2 = tcp2->dst.seqbase;
17051 break;
17052 }
17053 break;
17054
17055 case ARGUS_TYPE_IPV6:
17056 switch (flow2->ipv6_flow.ip_p) {
17057 case IPPROTO_TCP:
17058 seq2 = tcp2->dst.seqbase;
17059 break;
17060 }
17061 break;
17062 }
17063 break;
17064 }
17065 }
17066 }
17067
17068 retn = ArgusReverseSortDir ? ((seq1 < seq2) ? 1 : ((seq1 == seq2) ? 0 : -1)) :
17069 ((seq1 > seq2) ? 1 : ((seq1 == seq2) ? 0 : -1)) ;
17070 }
17071 return (retn);
17072 }
17073
17074 int
ArgusSortTcpRtt(struct ArgusRecordStruct * argus1,struct ArgusRecordStruct * argus2)17075 ArgusSortTcpRtt (struct ArgusRecordStruct *argus1, struct ArgusRecordStruct *argus2)
17076 {
17077 struct ArgusNetworkStruct *net1 = (void *)argus1->dsrs[ARGUS_NETWORK_INDEX];
17078 struct ArgusNetworkStruct *net2 = (void *)argus2->dsrs[ARGUS_NETWORK_INDEX];
17079 int retn = 0;
17080
17081 if (net1 && net2) {
17082 struct ArgusFlow *flow1 = (void *)argus1->dsrs[ARGUS_FLOW_INDEX];
17083 struct ArgusFlow *flow2 = (void *)argus2->dsrs[ARGUS_FLOW_INDEX];
17084 unsigned int rtt1 = 0;
17085 unsigned int rtt2 = 0;
17086
17087 struct ArgusTCPObject *tcp1 = &net1->net_union.tcp;
17088 struct ArgusTCPObject *tcp2 = &net2->net_union.tcp;
17089
17090 if (flow1 != NULL) {
17091 switch (flow1->hdr.subtype & 0x3F) {
17092 case ARGUS_FLOW_CLASSIC5TUPLE: {
17093 switch (flow1->hdr.argus_dsrvl8.qual & 0x1F) {
17094 case ARGUS_TYPE_IPV4:
17095 switch (flow1->ip_flow.ip_p) {
17096 case IPPROTO_TCP:
17097 rtt1 = tcp1->synAckuSecs + tcp1->ackDatauSecs;
17098 break;
17099 }
17100 break;
17101
17102 case ARGUS_TYPE_IPV6:
17103 switch (flow1->ipv6_flow.ip_p) {
17104 case IPPROTO_TCP:
17105 rtt1 = tcp1->synAckuSecs + tcp1->ackDatauSecs;
17106 break;
17107 }
17108 break;
17109 }
17110 break;
17111 }
17112 }
17113 }
17114
17115 if (flow2 != NULL) {
17116 switch (flow2->hdr.subtype & 0x3F) {
17117 case ARGUS_FLOW_CLASSIC5TUPLE: {
17118 switch (flow2->hdr.argus_dsrvl8.qual & 0x1F) {
17119 case ARGUS_TYPE_IPV4:
17120 switch (flow2->ip_flow.ip_p) {
17121 case IPPROTO_TCP:
17122 rtt2 = tcp2->synAckuSecs + tcp2->ackDatauSecs;
17123 break;
17124 }
17125 break;
17126
17127 case ARGUS_TYPE_IPV6:
17128 switch (flow2->ipv6_flow.ip_p) {
17129 case IPPROTO_TCP:
17130 rtt2 = tcp2->synAckuSecs + tcp2->ackDatauSecs;
17131 break;
17132 }
17133 break;
17134 }
17135 break;
17136 }
17137 }
17138 }
17139
17140 retn = ArgusReverseSortDir ? ((rtt1 < rtt2) ? 1 : ((rtt1 == rtt2) ? 0 : -1)) :
17141 ((rtt1 > rtt2) ? 1 : ((rtt1 == rtt2) ? 0 : -1)) ;
17142 }
17143 return (retn);
17144 }
17145
17146
17147 int
ArgusSortSrcMaxPktSize(struct ArgusRecordStruct * argus1,struct ArgusRecordStruct * argus2)17148 ArgusSortSrcMaxPktSize (struct ArgusRecordStruct *argus1, struct ArgusRecordStruct *argus2)
17149 {
17150 struct ArgusPacketSizeStruct *ps1 = (void *)argus1->dsrs[ARGUS_PSIZE_INDEX];
17151 struct ArgusPacketSizeStruct *ps2 = (void *)argus2->dsrs[ARGUS_PSIZE_INDEX];
17152 int retn = 0;
17153
17154 if (ps1 && ps2) {
17155 unsigned short smaxsz1 = 0, smaxsz2 = 0;
17156
17157 smaxsz1 = ps1->src.psizemax;
17158 smaxsz2 = ps2->src.psizemax;
17159
17160 retn = ArgusReverseSortDir ? ((smaxsz1 < smaxsz2) ? 1 : ((smaxsz1 == smaxsz2) ? 0 : -1)) :
17161 ((smaxsz1 > smaxsz2) ? 1 : ((smaxsz1 == smaxsz2) ? 0 : -1)) ;
17162 }
17163 return (retn);
17164 }
17165
17166
17167 int
ArgusSortSrcMinPktSize(struct ArgusRecordStruct * argus1,struct ArgusRecordStruct * argus2)17168 ArgusSortSrcMinPktSize (struct ArgusRecordStruct *argus1, struct ArgusRecordStruct *argus2)
17169 {
17170 struct ArgusPacketSizeStruct *ps1 = (void *)argus1->dsrs[ARGUS_PSIZE_INDEX];
17171 struct ArgusPacketSizeStruct *ps2 = (void *)argus2->dsrs[ARGUS_PSIZE_INDEX];
17172 int retn = 0;
17173
17174 if (ps1 && ps2) {
17175 unsigned short smiargusz1 = 0, smiargusz2 = 0;
17176
17177 smiargusz1 = ps1->src.psizemin;
17178 smiargusz2 = ps2->src.psizemin;
17179
17180 retn = ArgusReverseSortDir ? ((smiargusz1 > smiargusz2) ? 1 : ((smiargusz1 == smiargusz2) ? 0 : -1)) :
17181 ((smiargusz1 < smiargusz2) ? 1 : ((smiargusz1 == smiargusz2) ? 0 : -1)) ;
17182 }
17183 return (retn);
17184 }
17185
17186 int
ArgusSortSrcMeanPktSize(struct ArgusRecordStruct * n1,struct ArgusRecordStruct * n2)17187 ArgusSortSrcMeanPktSize (struct ArgusRecordStruct *n1, struct ArgusRecordStruct *n2)
17188 {
17189 double r1 = 0.0, r2 = 0.0;
17190 int retn = 0;
17191
17192 if (n1)
17193 r1 = ArgusFetchSrcMeanPktSize(n1);
17194 if (n2)
17195 r2 = ArgusFetchSrcMeanPktSize(n2);
17196 retn = (r1 > r2) ? 1 : ((r1 == r2) ? 0 : -1);
17197 return (ArgusReverseSortDir ? ((retn > 0) ? -1 : ((retn == 0) ? 0 : 1)) : retn);
17198 }
17199
17200
17201
17202 int
ArgusSortDstMaxPktSize(struct ArgusRecordStruct * argus1,struct ArgusRecordStruct * argus2)17203 ArgusSortDstMaxPktSize (struct ArgusRecordStruct *argus1, struct ArgusRecordStruct *argus2)
17204 {
17205 struct ArgusPacketSizeStruct *ps1 = (void *)argus1->dsrs[ARGUS_PSIZE_INDEX];
17206 struct ArgusPacketSizeStruct *ps2 = (void *)argus2->dsrs[ARGUS_PSIZE_INDEX];
17207 int retn = 0;
17208
17209 if (ps1 && ps2) {
17210 unsigned short dmaxsz1 = 0, dmaxsz2 = 0;
17211
17212 dmaxsz1 = ps1->dst.psizemax;
17213 dmaxsz2 = ps2->dst.psizemax;
17214
17215 retn = ArgusReverseSortDir ? ((dmaxsz1 < dmaxsz2) ? 1 : ((dmaxsz1 == dmaxsz2) ? 0 : -1)) :
17216 ((dmaxsz1 > dmaxsz2) ? 1 : ((dmaxsz1 == dmaxsz2) ? 0 : -1)) ;
17217 }
17218 return (retn);
17219 }
17220
17221 int
ArgusSortDstMinPktSize(struct ArgusRecordStruct * argus1,struct ArgusRecordStruct * argus2)17222 ArgusSortDstMinPktSize (struct ArgusRecordStruct *argus1, struct ArgusRecordStruct *argus2)
17223 {
17224 struct ArgusPacketSizeStruct *ps1 = (void *)argus1->dsrs[ARGUS_PSIZE_INDEX];
17225 struct ArgusPacketSizeStruct *ps2 = (void *)argus2->dsrs[ARGUS_PSIZE_INDEX];
17226 int retn = 0;
17227
17228 if (ps1 && ps2) {
17229 unsigned short dmiargusz1 = 0, dmiargusz2 = 0;
17230
17231 dmiargusz1 = ps1->dst.psizemin;
17232 dmiargusz2 = ps2->dst.psizemin;
17233
17234 retn = ArgusReverseSortDir ? ((dmiargusz1 > dmiargusz2) ? 1 : ((dmiargusz1 == dmiargusz2) ? 0 : -1)) :
17235 ((dmiargusz1 < dmiargusz2) ? 1 : ((dmiargusz1 == dmiargusz2) ? 0 : -1)) ;
17236 }
17237 return (retn);
17238 }
17239
17240 int
ArgusSortSrcCountryCode(struct ArgusRecordStruct * argus1,struct ArgusRecordStruct * argus2)17241 ArgusSortSrcCountryCode (struct ArgusRecordStruct *argus1, struct ArgusRecordStruct *argus2)
17242 {
17243 struct ArgusCountryCodeStruct *sco1 = (void *)argus1->dsrs[ARGUS_COCODE_INDEX];
17244 struct ArgusCountryCodeStruct *sco2 = (void *)argus2->dsrs[ARGUS_COCODE_INDEX];
17245 int retn = 0;
17246
17247 if (sco1 && sco2) {
17248 retn = strcmp(sco1->src, sco2->src);
17249 retn = ArgusReverseSortDir ? ((retn < 0) ? 1 : ((retn == 0) ? 0 : -1)) : retn;
17250 }
17251 return (retn);
17252 }
17253
17254 int
ArgusSortDstCountryCode(struct ArgusRecordStruct * argus1,struct ArgusRecordStruct * argus2)17255 ArgusSortDstCountryCode (struct ArgusRecordStruct *argus1, struct ArgusRecordStruct *argus2)
17256 {
17257 struct ArgusCountryCodeStruct *sco1 = (void *)argus1->dsrs[ARGUS_COCODE_INDEX];
17258 struct ArgusCountryCodeStruct *sco2 = (void *)argus2->dsrs[ARGUS_COCODE_INDEX];
17259 int retn = 0;
17260
17261 if (sco1 && sco2) {
17262 retn = strcmp(sco1->dst, sco2->dst);
17263 retn = ArgusReverseSortDir ? ((retn < 0) ? 1 : ((retn == 0) ? 0 : -1)) : retn;
17264 }
17265 return (retn);
17266 }
17267
17268 int
ArgusSortSrcASNum(struct ArgusRecordStruct * argus1,struct ArgusRecordStruct * argus2)17269 ArgusSortSrcASNum (struct ArgusRecordStruct *argus1, struct ArgusRecordStruct *argus2)
17270 {
17271 struct ArgusAsnStruct *asn1 = (void *)argus1->dsrs[ARGUS_ASN_INDEX];
17272 struct ArgusAsnStruct *asn2 = (void *)argus2->dsrs[ARGUS_ASN_INDEX];
17273 int retn = 0;
17274
17275 if (asn1 && asn2) {
17276 int value = (asn1->src_as - asn2->src_as);
17277 retn = (value < 0) ? 1 : ((value == 0) ? 0 : -1);
17278 retn = ArgusReverseSortDir ? ((retn < 0) ? 1 : ((retn == 0) ? 0 : -1)) : retn;
17279 }
17280
17281 return (retn);
17282 }
17283
17284 int
ArgusSortDstASNum(struct ArgusRecordStruct * argus1,struct ArgusRecordStruct * argus2)17285 ArgusSortDstASNum (struct ArgusRecordStruct *argus1, struct ArgusRecordStruct *argus2)
17286 {
17287 struct ArgusAsnStruct *asn1 = (void *)argus1->dsrs[ARGUS_ASN_INDEX];
17288 struct ArgusAsnStruct *asn2 = (void *)argus2->dsrs[ARGUS_ASN_INDEX];
17289 int retn = 0;
17290
17291 if (asn1 && asn2) {
17292 int value = (asn1->dst_as - asn2->dst_as);
17293 retn = (value < 0) ? 1 : ((value == 0) ? 0 : -1);
17294 retn = ArgusReverseSortDir ? ((retn < 0) ? 1 : ((retn == 0) ? 0 : -1)) : retn;
17295 }
17296
17297 return (retn);
17298 }
17299
17300