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