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