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  * rauserdata - formulate the service signature file.
24  *
25  * written by Carter Bullard
26  * QoSient, LLC
27  *
28  *
29  * $Id: //depot/argus/clients/examples/raservices/rauserdata.c#12 $
30  * $DateTime: 2016/06/01 15:17:28 $
31  * $Change: 3148 $
32  */
33 
34 #ifdef HAVE_CONFIG_H
35 #include "argus_config.h"
36 #endif
37 
38 #include <unistd.h>
39 #include <stdlib.h>
40 #include <signal.h>
41 #include <ctype.h>
42 
43 #include <rabins.h>
44 #include <argus_util.h>
45 #include <argus_label.h>
46 #include <argus_client.h>
47 #include <argus_main.h>
48 #include <argus_sort.h>
49 
50 #include <argus_cluster.h>
51 #include <argus_filter.h>
52 
53 int RaSignatureLength = 16;
54 int RaSrcSig = 1;
55 int RaDstSig = 1;
56 
57 int RaTestUserData(struct RaBinStruct *, struct ArgusRecordStruct *, struct ArgusRecordStruct *, int);
58 void ArgusMergeUserData(struct RaBinStruct *, struct ArgusRecordStruct *, struct ArgusRecordStruct *);
59 
60 void RaProcessSrvRecord (struct ArgusParserStruct *, struct ArgusRecordStruct *);
61 struct RaBinProcessStruct *RaNewBinProcess (struct ArgusParserStruct *, int);
62 void RaPrintOutQueue (struct RaBinStruct *, struct ArgusQueueStruct *, int);
63 
64 
65 char *ArgusAggregationConfig[2] = {
66    "filter=\"ip\" model=\"proto dport\"  status=120 idle=3600\n",
67    NULL,
68 };
69 
70 
71 int RaSrcTestThreshold  = 10;
72 int RaDstTestThreshold  = 10;
73 int RaMinStartThreshold = 4;
74 
75 void
ArgusClientInit(struct ArgusParserStruct * parser)76 ArgusClientInit (struct ArgusParserStruct *parser)
77 {
78    struct ArgusModeStruct *mode = NULL;
79    int i;
80 
81    parser->RaWriteOut = 0;
82 
83    if (!(parser->RaInitialized)) {
84       (void) signal (SIGHUP,  (void (*)(int)) RaParseComplete);
85 
86       if ((parser->ArgusLabeler = ArgusNewLabeler(parser, 0L)) == NULL)
87          ArgusLog (LOG_ERR, "ArgusClientInit: ArgusNewLabeler error");
88 
89       if (parser->ArgusFlowModelFile) {
90          RaReadSrvSignature (parser, parser->ArgusLabeler, parser->ArgusFlowModelFile);
91          parser->ArgusFlowModelFile = NULL;
92       }
93 
94       if ((mode = parser->ArgusModeList) != NULL) {
95          while (mode) {
96             if (!(strncasecmp (mode->mode, "Src", 3))) {
97                RaSrcSig = 1;
98                RaDstSig = 0;
99             }
100 
101             if (!(strncasecmp (mode->mode, "Dst", 3))) {
102                RaSrcSig = 0;
103                RaDstSig = 1;
104             }
105 
106             mode = mode->nxt;
107          }
108       }
109 
110       if ((parser->ArgusAggregator = ArgusParseAggregator(parser, NULL, ArgusAggregationConfig)) == NULL)
111          ArgusLog (LOG_ERR, "ArgusClientInit: ArgusParseAggregator error");
112 
113       for (i = 0; i < MAX_PRINT_ALG_TYPES; i++) {
114          if (parser->RaPrintAlgorithmList[i] != NULL) {
115             if (parser->RaPrintAlgorithmList[i]->print == ArgusPrintSrcUserData) {
116                if (RaSignatureLength < parser->RaPrintAlgorithmList[i]->length)
117                   RaSignatureLength = parser->RaPrintAlgorithmList[i]->length;
118             }
119 
120             if (parser->RaPrintAlgorithmList[i]->print == ArgusPrintDstUserData) {
121                if (RaSignatureLength < parser->RaPrintAlgorithmList[i]->length)
122                   RaSignatureLength = parser->RaPrintAlgorithmList[i]->length;
123             }
124 
125          } else
126             break;
127       }
128       parser->RaInitialized++;
129    }
130 }
131 
RaArgusInputComplete(struct ArgusInput * input)132 void RaArgusInputComplete (struct ArgusInput *input) {};
133 
134 #define ARGUS_MAXFLOWDEFS	3
135 #define ARGUS_SERVICE		0
136 #define ARGUS_SERVER		1
137 #define ARGUS_CLIENT		2
138 
139 int RaTotals[ARGUS_MAXFLOWDEFS] = {0, 0, 0};
140 
141 void
RaParseComplete(int sig)142 RaParseComplete (int sig)
143 {
144    struct ArgusModeStruct *mode = NULL;
145 
146    if (sig >= 0) {
147       if (!ArgusParser->RaParseCompleting++) {
148 
149          if (!(ArgusSorter))
150             if ((ArgusSorter = ArgusNewSorter(ArgusParser)) == NULL)
151                ArgusLog (LOG_ERR, "RaParseComplete: ArgusNewSorter error %s", strerror(errno));
152 
153          if ((mode = ArgusParser->ArgusMaskList) != NULL) {
154             int x = 0, i = 0;
155             while (mode) {
156                for (x = 0; x < MAX_SORT_ALG_TYPES; x++) {
157                   if (!strncmp (ArgusSortKeyWords[x], mode->mode, strlen(ArgusSortKeyWords[x]))) {
158                      ArgusSorter->ArgusSortAlgorithms[i++] = ArgusSortAlgorithmTable[x];
159                      break;
160                   }
161                }
162 
163                mode = mode->nxt;
164             }
165          }
166 
167          if (ArgusParser->ArgusAggregator->queue && (ArgusParser->ArgusAggregator->queue->count)) {
168 #if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__APPLE_CC__) || defined(__APPLE__) || defined(ARGUS_SOLARIS)
169             printf ("Total Records %lld SrcThreshold %d Dst Threshold %d ", ArgusParser->ArgusTotalRecords, RaSrcTestThreshold, RaDstTestThreshold);
170 #else
171             printf ("Total Records %Ld SrcThreshold %d Dst Threshold %d ", ArgusParser->ArgusTotalRecords, RaSrcTestThreshold, RaDstTestThreshold);
172 #endif
173             if (ArgusParser->Lflag > 0) printf ("Total Services %d  ", RaTotals[ARGUS_SERVICE]);
174             if (ArgusParser->Lflag > 1) printf ("Total Servers  %d  ", RaTotals[ARGUS_SERVER]);
175             if (ArgusParser->Lflag > 2) printf ("Total Clients  %d  ", RaTotals[ARGUS_CLIENT]);
176             printf ("\n");
177 
178             ArgusSortQueue (ArgusSorter, ArgusParser->ArgusAggregator->queue);
179             RaPrintOutQueue (NULL, ArgusParser->ArgusAggregator->queue, 0);
180          }
181 
182          ArgusShutDown(sig);
183 
184          if ((ArgusParser->ArgusWfileList != NULL) && (!(ArgusListEmpty(ArgusParser->ArgusWfileList)))) {
185             struct ArgusWfileStruct *wfile = NULL, *start = NULL;
186 
187             if ((wfile = (struct ArgusWfileStruct *) ArgusFrontList(ArgusParser->ArgusWfileList)) != NULL) {
188                start = wfile;
189                fflush(wfile->fd);
190                ArgusPopFrontList(ArgusParser->ArgusWfileList, ARGUS_NOLOCK);
191                ArgusPushBackList(ArgusParser->ArgusWfileList, (struct ArgusListRecord *) wfile, ARGUS_NOLOCK);
192                wfile = (struct ArgusWfileStruct *) ArgusFrontList(ArgusParser->ArgusWfileList);
193             } while (wfile != start);
194 
195          } else {
196          }
197       }
198 
199       fflush(stdout);
200       exit(0);
201    }
202 
203 #ifdef ARGUSDEBUG
204    ArgusDebug (1, "RaParseComplete (%d) returning\n", sig);
205 #endif
206 }
207 
208 
209 void
ArgusClientTimeout()210 ArgusClientTimeout ()
211 {
212 
213 #ifdef ARGUSDEBUG
214    ArgusDebug (4, "ArgusClientTimeout: returning\n");
215 #endif
216 }
217 
218 void
parse_arg(int argc,char ** argv)219 parse_arg (int argc, char**argv)
220 {
221 
222 #ifdef ARGUSDEBUG
223    ArgusDebug (6, "parse_arg (%d, 0x%x) returning\n", argc, argv);
224 #endif
225 }
226 
227 
228 void
usage()229 usage ()
230 {
231    extern char version[];
232    fprintf (stdout, "Ratemplate Version %s\n", version);
233    fprintf (stdout, "usage: %s \n", ArgusParser->ArgusProgramName);
234    fprintf (stdout, "usage: %s [options] -S remoteServer  [- filter-expression]\n", ArgusParser->ArgusProgramName);
235    fprintf (stdout, "usage: %s [options] -r argusDataFile [- filter-expression]\n\n", ArgusParser->ArgusProgramName);
236 
237    fprintf (stdout, "options: -f <conffile>     read service signatures from <conffile>.\n");
238    fflush (stdout);
239 
240    exit(1);
241 }
242 
243 void
RaProcessRecord(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus)244 RaProcessRecord (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus)
245 {
246    struct ArgusDataStruct *d1 = (struct ArgusDataStruct *) argus->dsrs[ARGUS_SRCUSERDATA_INDEX];
247    struct ArgusDataStruct *d2 = (struct ArgusDataStruct *) argus->dsrs[ARGUS_DSTUSERDATA_INDEX];
248 
249    struct ArgusFlow *flow = (struct ArgusFlow *) argus->dsrs[ARGUS_FLOW_INDEX];
250    struct RaSrvSignature *sig;
251    int process= 0;
252 
253    switch (argus->hdr.type & 0xF0) {
254       case ARGUS_MAR:
255       case ARGUS_EVENT: {
256          break;
257       }
258       case ARGUS_NETFLOW:
259       case ARGUS_FAR: {
260          if (flow) {
261             switch (flow->hdr.subtype & 0x3F) {
262                case ARGUS_FLOW_CLASSIC5TUPLE: {
263                   switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
264                      case ARGUS_TYPE_IPV4:
265                         switch (flow->ip_flow.ip_p) {
266                            case IPPROTO_TCP: {
267                               process++;
268                               break;
269                            }
270                            case IPPROTO_UDP: {
271                               process++;
272                               break;
273                            }
274                         }
275                         break;
276 
277                      case ARGUS_TYPE_IPV6: {
278                         switch (flow->ipv6_flow.ip_p) {
279                            case IPPROTO_TCP: {
280                               process++;
281                               break;
282                            }
283                            case IPPROTO_UDP: {
284                               process++;
285                               break;
286                            }
287                         }
288                         break;
289                      }
290                   }
291                   break;
292                }
293             }
294 
295             if (process) {
296 #ifdef ARGUSDEBUG
297                ArgusDebug (5, "RaProcessRecord (0x%x) validating service", argus);
298 #endif
299                if (!(sig = RaValidateService (parser, argus))) {
300                   ArgusReverseRecord(argus);
301                   if (!(sig = RaValidateService (parser, argus)))
302                      ArgusReverseRecord(argus);
303                }
304 
305                if (sig == NULL) {
306                   if (((d1 != NULL) && (d1->count > RaSignatureLength)) ||
307                       ((d2 != NULL) && (d2->count > RaSignatureLength)))
308                   RaProcessSrvRecord (parser, argus);
309                } else
310                   sig->count++;
311             }
312 
313          } else {
314 #ifdef ARGUSDEBUG
315             ArgusDebug (5, "RaProcessRecord (0x%x) record not validated\n", argus);
316 #endif
317          }
318          break;
319       }
320    }
321 
322 #ifdef ARGUSDEBUG
323    ArgusDebug (5, "RaProcessRecord (0x%x) returning\n", argus);
324 #endif
325 }
326 
327 
328 void ArgusPruneSignatures (struct ArgusParserStruct *, struct ArgusRecordStruct *, struct RaBinStruct *);
329 
330 void
ArgusPruneSignatures(struct ArgusParserStruct * parser,struct ArgusRecordStruct * tns,struct RaBinStruct * bin)331 ArgusPruneSignatures (struct ArgusParserStruct *parser, struct ArgusRecordStruct *tns, struct RaBinStruct *bin)
332 {
333    struct ArgusQueueStruct *queue;
334    struct ArgusRecordStruct *ans, *pns;
335    int deleted = 0;
336 
337 
338    if (bin == NULL)
339       return;
340 
341    if ((ans = (struct ArgusRecordStruct *)bin->agg->queue->start) == NULL)
342       return;
343 
344    if (tns->bins) {
345       int i = 0;
346 
347       for (i = 0; i < tns->bins->arraylen; i++) {
348          struct RaBinStruct *tbin;
349 
350          if ((tbin = tns->bins->array[i]) != NULL) {
351             if (tbin != bin) {
352                queue = tbin->agg->queue;
353 
354                if ((pns = (struct ArgusRecordStruct *)queue->start) != NULL) {
355                   if (RaTestUserData(tbin, ans, pns, ARGUS_LONGEST_MATCH)) {
356                      ArgusMergeUserData (bin, pns, ans);
357                      ArgusMergeRecords (parser->ArgusAggregator, pns, ans);
358                      deleted++;
359                   }
360                }
361             }
362          }
363       }
364 
365       if (deleted) {
366          for (i = 0; i < tns->bins->arraylen; i++) {
367             if (tns->bins->array[i] == bin) {
368                tns->bins->array[i] = NULL;
369                tns->bins->count--;
370                RaDeleteBin(parser, bin);
371                break;
372             }
373          }
374 
375          for (i = 0; i < tns->bins->arraylen; i++) {
376             int x;
377             if (i < (tns->bins->count - 1)) {
378                while (tns->bins->array[i] == NULL) {
379                   for (x = i; x < tns->bins->arraylen; x++) {
380                      if (x == tns->bins->arraylen - 1) {
381                         tns->bins->array[x] = NULL;
382                      } else {
383                         tns->bins->array[x] = tns->bins->array[x + 1];
384                      }
385                   }
386                }
387             }
388          }
389       }
390    }
391 }
392 
393 
394 void
RaProcessSrvRecord(struct ArgusParserStruct * parser,struct ArgusRecordStruct * ns)395 RaProcessSrvRecord (struct ArgusParserStruct *parser, struct ArgusRecordStruct *ns)
396 {
397    struct ArgusAggregatorStruct *agg = parser->ArgusAggregator;
398    struct ArgusHashStruct *hstruct = NULL;
399    struct ArgusRecordStruct *tns;
400    int retn, found = 0;
401 
402    while (agg && !found) {
403       struct nff_insn *fcode = agg->filter.bf_insns;
404 
405       if ((retn = ArgusFilterRecord (fcode, ns)) != 0) {
406          struct ArgusRecordStruct *ans = NULL;
407 
408          if ((agg->rap = RaFlowModelOverRides(agg, ns)) == NULL)
409             agg->rap = agg->drap;
410 
411          ArgusGenerateNewFlow(agg, ns);
412 
413          if ((hstruct = ArgusGenerateHashStruct(agg, ns, (struct ArgusFlow *)&agg->fstruct)) == NULL)
414             ArgusLog (LOG_ERR, "RaProcessThisRecord: ArgusGenerateHashStruct error %s", strerror(errno));
415 
416          if ((tns = ArgusFindRecord(agg->htable, hstruct)) != NULL) {
417             if (parser->Aflag) {
418                if ((tns->status & RA_SVCTEST) != (ns->status & RA_SVCTEST)) {
419                   RaSendArgusRecord(tns);
420                   ArgusZeroRecord(tns);
421                   tns->status &= ~(RA_SVCTEST);
422                   tns->status |= (ns->status & RA_SVCTEST);
423                }
424             }
425 
426          } else {
427             struct ArgusFlow *flow = (struct ArgusFlow *) ns->dsrs[ARGUS_FLOW_INDEX];
428 
429             if (!parser->RaMonMode) {
430                int tryreverse = 1;
431 
432                if (flow != NULL) {
433                   switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
434                      case ARGUS_TYPE_IPV4: {
435                         switch (flow->ip_flow.ip_p) {
436                            case IPPROTO_ESP:
437                               tryreverse = 0;
438                               break;
439                         }
440                      }
441                   }
442                }
443 
444                if (tryreverse) {
445                   if ((hstruct = ArgusGenerateReverseHashStruct(agg, ns, (struct ArgusFlow *)&agg->fstruct)) == NULL)
446                      ArgusLog (LOG_ERR, "RaProcessThisRecord: ArgusGenerateHashStruct error %s", strerror(errno));
447 
448                   if ((tns = ArgusFindRecord(agg->htable, hstruct)) == NULL) {
449                      if ((hstruct = ArgusGenerateHashStruct(agg, ns, (struct ArgusFlow *)&agg->fstruct)) == NULL)
450                         ArgusLog (LOG_ERR, "RaProcessThisRecord: ArgusGenerateHashStruct error %s", strerror(errno));
451 
452                   } else {
453                      ArgusReverseRecord (ns);
454                   }
455                }
456             }
457 
458             if (tns != NULL) {
459                if (parser->Aflag) {
460                   if ((tns->status & RA_SVCTEST) != (ns->status & RA_SVCTEST)) {
461                      RaSendArgusRecord(tns);
462                      ArgusZeroRecord(tns);
463                   }
464                   tns->status &= ~(RA_SVCTEST);
465                   tns->status |= (ns->status & RA_SVCTEST);
466                }
467 
468             } else {
469                tns = ArgusCopyRecordStruct(ns);
470                ArgusAddHashEntry (agg->htable, tns, hstruct);
471                ArgusAddToQueue (agg->queue, &tns->qhdr, ARGUS_LOCK);
472             }
473          }
474 
475          if (tns->bins) {
476             struct RaBinStruct *bin;
477             int i, merged = 0;
478 
479             for (i = 0; i < tns->bins->arraylen; i++) {
480                if ((bin = tns->bins->array[i]) != NULL) {
481                   if ((ans = (struct ArgusRecordStruct *)bin->agg->queue->start) != NULL) {
482                      if (RaTestUserData(bin, ans, ns, ARGUS_LONGEST_MATCH)) {
483                         ArgusMergeUserData (bin, ans, ns);
484                         ArgusMergeRecords (parser->ArgusAggregator, tns, ns);
485                         merged++;
486                         break;
487                      }
488                   }
489 
490                } else {
491                   tns->bins->array[i] = RaNewBin (parser, tns->bins, ns, 0, i);
492                   tns->bins->count++;
493 
494                   if ((ans =  ArgusCopyRecordStruct(ns)) != NULL) {
495                      if (agg != NULL) {
496                         struct ArgusHashStruct *hstruct = NULL;
497 
498                         if ((hstruct = ArgusGenerateHashStruct(agg, ans, NULL)) == NULL)
499                            ArgusLog (LOG_ERR, "RaNewBin: ArgusGenerateHashStruct error %s", strerror(errno));
500 
501                         ArgusAddHashEntry (tns->bins->array[i]->agg->htable, ans, hstruct);
502                         ArgusAddToQueue (tns->bins->array[i]->agg->queue, &ans->qhdr, ARGUS_LOCK);
503                      }
504                   }
505 
506                   break;
507                }
508             }
509 
510             if (merged)
511                ArgusPruneSignatures (parser, tns, bin);
512 
513          } else {
514             if ((tns->bins = RaNewBinProcess(parser, 32)) == NULL)
515                ArgusLog (LOG_ERR, "RaProcessSrvRecord: RaNewBinProcess error: %s", strerror(errno));
516 
517             tns->bins->array[0] = RaNewBin (parser, tns->bins, ns, 0, 0);
518             tns->bins->count = 1;
519 
520             if ((ans =  ArgusCopyRecordStruct(ns)) != NULL) {
521                if ((agg = tns->bins->array[0]->agg) != NULL) {
522                   struct ArgusHashStruct *hstruct = NULL;
523 
524                   if ((hstruct = ArgusGenerateHashStruct(agg, ans, NULL)) == NULL)
525                      ArgusLog (LOG_ERR, "RaNewBin: ArgusGenerateHashStruct error %s", strerror(errno));
526 
527                   ArgusAddHashEntry (agg->htable, ans, hstruct);
528                   ArgusAddToQueue (agg->queue, &ans->qhdr, ARGUS_LOCK);
529                }
530             }
531          }
532 
533          found++;
534 
535       } else
536          agg = agg->nxt;
537    }
538 
539 #ifdef ARGUSDEBUG
540    ArgusDebug (5, "RaProcessSrvRecord (0x%x, 0x%x) returning\n", parser, ns);
541 #endif
542 }
543 
544 int
RaSendArgusRecord(struct ArgusRecordStruct * argus)545 RaSendArgusRecord(struct ArgusRecordStruct *argus)
546 {
547 
548 #ifdef ARGUSDEBUG
549    ArgusDebug (6, "RaSendArgusRecord (0x%x) returning\n", argus);
550 #endif
551    return 1;
552 }
553 
554 
ArgusWindowClose(void)555 void ArgusWindowClose(void) { }
556 
557 int
RaTestUserData(struct RaBinStruct * bin,struct ArgusRecordStruct * ns1,struct ArgusRecordStruct * ns2,int type)558 RaTestUserData(struct RaBinStruct *bin, struct ArgusRecordStruct *ns1, struct ArgusRecordStruct *ns2, int type)
559 {
560    struct ArgusAgrStruct *agr = (struct ArgusAgrStruct *) ns1->dsrs[ARGUS_AGR_INDEX];
561    int retn = 0, len, len1 = 0, len2 = 0, x, count, weight;
562    unsigned char thisdatamask[16];
563 
564    if (RaSrcSig) {
565       struct ArgusDataStruct *d1 = (struct ArgusDataStruct *) ns1->dsrs[ARGUS_SRCUSERDATA_INDEX];
566       struct ArgusDataStruct *d2 = (struct ArgusDataStruct *) ns2->dsrs[ARGUS_SRCUSERDATA_INDEX];
567 
568       if (d1 && d2) {
569          retn = 0;
570          count = 0;
571          if (!(RaSrcTestThreshold)) {
572             retn++;
573 
574          } else {
575             len1 = d1->count;
576             len2 = d2->count;
577 
578             len = (len1 > len2) ? len2 : len1;
579             len = (len > RaSignatureLength) ? RaSignatureLength : len;
580 
581             bcopy (&bin->ArgusSrcDataMask, thisdatamask, sizeof(thisdatamask));
582 
583             for (x = 0, weight = 5; x < len; x++) {
584                if (!(thisdatamask[x/8] & (0x80 >> (x % 8)))) {
585                   if (d2->array[x] == d1->array[x])
586                      count += (weight >= 1) ? weight : 1;
587                   else {
588                      if (type == ARGUS_EXACT_MATCH) {
589                         return(0);
590                      } else {
591                         if (agr->count > 1) {
592                            if (x < ((RaSrcTestThreshold > RaMinStartThreshold) ? RaMinStartThreshold : RaSrcTestThreshold) - 1) {
593                               retn = 0;
594                            }
595                         }
596                         count -= (weight >= 1) ? weight : 1;
597                      }
598                   }
599                }
600                weight--;
601             }
602 
603             if (count >= RaSrcTestThreshold)
604                retn++;
605          }
606 
607       } else
608          retn++;
609    }
610 
611    if (RaDstSig && (!RaSrcSig || (RaSrcSig && retn))) {
612       struct ArgusDataStruct *d1 = (struct ArgusDataStruct *) ns1->dsrs[ARGUS_DSTUSERDATA_INDEX];
613       struct ArgusDataStruct *d2 = (struct ArgusDataStruct *) ns2->dsrs[ARGUS_DSTUSERDATA_INDEX];
614 
615       if (d1 && d2) {
616          retn = 0;
617          count = 0;
618          if (!(RaDstTestThreshold)) {
619             retn++;
620 
621          } else {
622             len1 = d1->count;
623             len2 = d2->count;
624 
625             len = (len1 > len2) ? len2 : len1;
626             len = (len > RaSignatureLength) ? RaSignatureLength : len;
627 
628             bcopy (&bin->ArgusDstDataMask, thisdatamask, sizeof(thisdatamask));
629 
630             for (x = 0, weight = 5; x < len; x++) {
631                if (!(thisdatamask[x/8] & (0x80 >> (x % 8)))) {
632                   if (d2->array[x] == d1->array[x])
633                      count += (weight >= 1) ? weight : 1;
634                   else {
635                      if (agr->count > 1) {
636                         if (x < ((RaDstTestThreshold > RaMinStartThreshold) ? RaMinStartThreshold : RaDstTestThreshold) - 1) {
637                            retn = 0;
638                         }
639                      }
640                      count -= (weight >= 1) ? weight : 1;
641                   }
642                }
643                weight--;
644             }
645 
646             if (count >= RaDstTestThreshold)
647                retn++;
648          }
649 
650       } else
651          retn++;
652    }
653 
654    return(retn);
655 }
656 
657 
658 void
ArgusMergeUserData(struct RaBinStruct * bin,struct ArgusRecordStruct * ns1,struct ArgusRecordStruct * ns2)659 ArgusMergeUserData(struct RaBinStruct *bin, struct ArgusRecordStruct *ns1, struct ArgusRecordStruct *ns2)
660 {
661    struct ArgusAgrStruct *agr = (struct ArgusAgrStruct *) ns1->dsrs[ARGUS_AGR_INDEX];
662    unsigned char thisdatamask[16];
663 
664    if (RaSrcSig) {
665       struct ArgusDataStruct *d1 = (struct ArgusDataStruct *) ns1->dsrs[ARGUS_SRCUSERDATA_INDEX];
666       struct ArgusDataStruct *d2 = (struct ArgusDataStruct *) ns2->dsrs[ARGUS_SRCUSERDATA_INDEX];
667       int x, count;
668 
669       if (d1 && d2) {
670          int len, len1 = d1->count, len2 = d2->count;
671 
672          len = (len1 > len2) ? len2 : len1;
673          len = (len > RaSignatureLength) ? RaSignatureLength : len;
674 
675          bcopy (&bin->ArgusSrcDataMask, thisdatamask, sizeof(thisdatamask));
676 
677          for (x = 0; x < len; x++)
678             if (d2->array[x] != d1->array[x])
679                thisdatamask[x/8] |= (0x80 >> (x % 8));
680 
681          for (; x < 128; x++) {
682             thisdatamask[x/8] |= (0x80 >> (x % 8));
683          }
684 
685          for (x = 0, count = 0; x < 128; x++) {
686             if (thisdatamask[x/8] & (0x80 >> (x % 8)))
687                count++;
688          }
689 
690          if ((128 - count) < RaSrcTestThreshold) {
691 #ifdef ARGUSDEBUG
692             ArgusDebug (2, "RaMergeUserData Src Threshold failed\n");
693 #endif
694          }
695 
696          bcopy (thisdatamask, &bin->ArgusSrcDataMask, sizeof(thisdatamask));
697       }
698    }
699 
700    if (RaDstSig) {
701       struct ArgusDataStruct *d1 = (struct ArgusDataStruct *) ns1->dsrs[ARGUS_DSTUSERDATA_INDEX];
702       struct ArgusDataStruct *d2 = (struct ArgusDataStruct *) ns2->dsrs[ARGUS_DSTUSERDATA_INDEX];
703       int x, count;
704 
705       if (d1 && d2) {
706          int len, len1 = d1->count, len2 = d2->count;
707 
708          len = (len1 > len2) ? len2 : len1;
709          len = (len > RaSignatureLength) ? RaSignatureLength : len;
710 
711          bcopy (&bin->ArgusDstDataMask, thisdatamask, sizeof(thisdatamask));
712 
713          for (x = 0; x < len; x++)
714             if (d2->array[x] != d1->array[x])
715                thisdatamask[x/8] |= (0x80 >> (x % 8));
716 
717          for (; x < 128; x++) {
718             thisdatamask[x/8] |= (0x80 >> (x % 8));
719          }
720 
721          for (x = 0, count = 0; x < 128; x++) {
722             if (thisdatamask[x/8] & (0x80 >> (x % 8)))
723                count++;
724          }
725 
726          if ((128 - count) < RaDstTestThreshold) {
727 #ifdef ARGUSDEBUG
728             ArgusDebug (2, "RaMergeUserData Dst Threshold failed\n");
729 #endif
730          }
731 
732          bcopy (thisdatamask, &bin->ArgusDstDataMask, sizeof(thisdatamask));
733       }
734    }
735 
736    if (agr != NULL)
737       agr->count++;
738 
739 #ifdef ARGUSDEBUG
740    ArgusDebug (6, "ArgusMergeUserData (0x%x, 0x%x) returning\n", ns1, ns2);
741 #endif
742 }
743 
744 
745 struct RaBinProcessStruct *
RaNewBinProcess(struct ArgusParserStruct * parser,int size)746 RaNewBinProcess (struct ArgusParserStruct *parser, int size)
747 {
748    struct RaBinProcessStruct *retn = NULL;
749    struct ArgusAdjustStruct *tnadp;
750 
751    parser->ArgusReverse = 0;
752 
753    if ((retn = (struct RaBinProcessStruct *)ArgusCalloc(1, sizeof(*retn))) == NULL)
754       ArgusLog (LOG_ERR, "ArgusNewBinProcess: ArgusCalloc error %s", strerror(errno));
755 
756 #if defined(ARGUS_THREADS)
757    pthread_mutex_init(&retn->lock, NULL);
758 #endif
759 
760    tnadp = &retn->nadp;
761    tnadp->mode    = -1;
762    tnadp->modify  =  1;
763    tnadp->slen    =  2;
764    tnadp->count   = 1;
765    tnadp->value   = 1;
766 
767    if ((retn->array = (struct RaBinStruct **)ArgusCalloc(size, sizeof(struct RaBinStruct *))) == NULL)
768       ArgusLog (LOG_ERR, "ArgusNewBinProcess: ArgusCalloc error %s", strerror(errno));
769 
770    retn->arraylen = size;
771    return (retn);
772 }
773 
774 
775 int RaSortUserDataBins (const void *, const void *);
776 
777 int
RaSortUserDataBins(const void * item1,const void * item2)778 RaSortUserDataBins (const void *item1, const void *item2)
779 {
780    int retn = 0;
781    struct RaBinStruct *b1 = *(struct RaBinStruct **) item1;
782    struct RaBinStruct *b2 = *(struct RaBinStruct **) item2;
783 
784    if (b1 && b2) {
785       struct ArgusAgrStruct *a1 = NULL, *a2 = NULL;
786 
787       if (b1->agg && b1->agg->queue && b1->agg->queue->start)
788          a1 = (void *)((struct ArgusRecordStruct *)b1->agg->queue->start)->dsrs[ARGUS_AGR_INDEX];
789 
790       if (b2->agg && b2->agg->queue && b2->agg->queue->start)
791          a2 = (void *)((struct ArgusRecordStruct *)b2->agg->queue->start)->dsrs[ARGUS_AGR_INDEX];
792 
793       if ((a1 != NULL) && (a2 != NULL)) {
794          retn = (a2->count - a1->count);
795       } else {
796          retn = a1 ? -1 : +1;
797       }
798 
799    } else {
800       retn = b1 ? -1 : +1;
801    }
802 
803    return (retn);
804 }
805 
806 
807 void
RaPrintOutQueue(struct RaBinStruct * bin,struct ArgusQueueStruct * queue,int level)808 RaPrintOutQueue (struct RaBinStruct *bin, struct ArgusQueueStruct *queue, int level)
809 {
810    struct ArgusRecordStruct *obj = NULL;
811    int print, n, num = ArgusParser->eNflag;
812    char buf[MAXSTRLEN];
813 
814    if (ArgusParser->eNflag <= 0)
815       num = queue->count;
816 
817    for (n = 0; n < num; n++) {
818       if ((obj = (struct ArgusRecordStruct *) queue->array[n]) != NULL) {
819          bzero(buf, sizeof(buf));
820          print = 0;
821 
822          if (obj->bins) {
823             int i = 0;
824 
825             qsort (obj->bins->array, obj->bins->count, sizeof(struct RaBinStruct *), RaSortUserDataBins);
826 
827             for (i = 0; i < obj->bins->arraylen; i++) {
828                if ((bin = obj->bins->array[i]) != NULL) {
829                   struct ArgusQueueStruct *q = bin->agg->queue;
830 
831                   if (q->count > 0) {
832                      ArgusSortQueue (ArgusSorter, bin->agg->queue);
833                      RaPrintOutQueue (bin, bin->agg->queue, level);
834                      print = 1;
835                   }
836                } else
837                   break;
838             }
839 
840             if (print)
841                sprintf (buf, "\n");
842 
843          } else {
844             struct ArgusFlow *flow = (struct ArgusFlow *) obj->dsrs[ARGUS_FLOW_INDEX];
845             struct ArgusAgrStruct *agr = (struct ArgusAgrStruct *) obj->dsrs[ARGUS_AGR_INDEX];
846 
847             int i, slen = 16, dlen = 16;
848             char pbuf[64];
849 
850             for (i = 0; i < MAX_PRINT_ALG_TYPES; i++) {
851                if (ArgusParser->RaPrintAlgorithmList[i] != NULL) {
852                   if (ArgusParser->RaPrintAlgorithmList[i]->print == ArgusPrintSrcUserData)
853                      slen = ArgusParser->RaPrintAlgorithmList[i]->length;
854                   if (ArgusParser->RaPrintAlgorithmList[i]->print == ArgusPrintDstUserData)
855                      dlen = ArgusParser->RaPrintAlgorithmList[i]->length;
856                } else
857                   break;
858             }
859 
860             bzero (pbuf, 64);
861             ArgusPrintDstPort (ArgusParser, pbuf, obj, 16);
862             if (flow != NULL) {
863                switch (flow->flow_un.ip.ip_p) {
864                   case IPPROTO_TCP: sprintf(buf, "Service: %s tcp port %-5d", pbuf, flow->flow_un.ip.dport); break;
865                   case IPPROTO_UDP: sprintf(buf, "Service: %s udp port %-5d", pbuf, flow->flow_un.ip.dport); break;
866                }
867             }
868 
869             if (agr != NULL)
870                sprintf (&buf[strlen(buf)], " n = %5d ", agr->count);
871 
872             if (RaSrcSig && (slen > 0)) {
873                struct ArgusDataStruct *d1 = (struct ArgusDataStruct *) obj->dsrs[ARGUS_SRCUSERDATA_INDEX];
874                int exlen = slen;
875 
876                switch (ArgusParser->eflag) {
877                   case ARGUS_ENCODE_ASCII:
878                      break;
879 
880                   case ARGUS_ENCODE_32:
881                   case ARGUS_ENCODE_64:
882                      exlen *= 2;
883                      break;
884                }
885 
886                if (d1 != NULL) {
887                   int len = d1->count > slen ? slen : d1->count;
888                   char strbuf[128], *str = strbuf;
889 
890                   bzero (strbuf, sizeof(strbuf));
891                   if ((len = ArgusEncode (ArgusParser, d1->array, (char *)bin->ArgusSrcDataMask, len, str, 128)) != 0)
892                      sprintf(&buf[strlen(buf)], "src = \"%*.*s\"  ", len, len, str);
893 
894                } else {
895                   sprintf(&buf[strlen(buf)], "src = \"%-*s\"  ", exlen," ");
896                }
897             }
898 
899             if (RaDstSig && (dlen > 0)) {
900                struct ArgusDataStruct *d1 = (struct ArgusDataStruct *) obj->dsrs[ARGUS_DSTUSERDATA_INDEX];
901                int exlen = dlen;
902 
903                switch (ArgusParser->eflag) {
904                   case ARGUS_ENCODE_ASCII:
905                      break;
906 
907                   case ARGUS_ENCODE_32:
908                   case ARGUS_ENCODE_64:
909                      exlen *= 2;
910                      break;
911                }
912 
913                if (d1 != NULL) {
914                   int len = d1->count > dlen ? dlen : d1->count;
915                   char strbuf[128], *str = strbuf;
916                   bzero (strbuf, sizeof(strbuf));
917                   if ((len = ArgusEncode (ArgusParser, d1->array, (char *)bin->ArgusDstDataMask, len, str, 128)) != 0)
918                      sprintf(&buf[strlen(buf)], "dst = \"%*.*s\"  ", len, len, str);
919 
920                } else {
921                   sprintf(&buf[strlen(buf)], "dst = \"%-*s\"  ", exlen," ");
922                }
923             }
924 /*
925             sprintf(&buf[strlen(buf)], "sintdist = ");
926             ArgusPrintSrcIntPktDist (ArgusParser, &buf[strlen(buf)], obj, 8);
927 
928             sprintf(&buf[strlen(buf)], "dintdist = ");
929             ArgusPrintDstIntPktDist (ArgusParser, &buf[strlen(buf)], obj, 8);
930 */
931             sprintf(&buf[strlen(buf)], "\n");
932          }
933          printf("%s", buf);
934       }
935 
936       fflush(stdout);
937    }
938 }
939