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  * $Id: //depot/argus/clients/examples/ragrep/ragrep.c#7 $
22  * $DateTime: 2016/06/01 15:17:28 $
23  * $Change: 3148 $
24  */
25 
26 /*
27  *
28  * ragrep.c  - grep () implementation for argus user data searching.
29  *
30  */
31 
32 #ifdef HAVE_CONFIG_H
33 #include "argus_config.h"
34 #endif
35 
36 #if defined(CYGWIN)
37 #define USE_IPV6
38 #endif
39 
40 #include <unistd.h>
41 #include <stdlib.h>
42 
43 #include <argus_compat.h>
44 
45 #include <rabins.h>
46 #include <argus_util.h>
47 #include <argus_client.h>
48 #include <argus_main.h>
49 #include <argus_filter.h>
50 
51 #include <argus_grep.h>
52 
53 #include <signal.h>
54 #include <ctype.h>
55 
56 extern int ArgusTotalMarRecords;
57 extern int ArgusTotalFarRecords;
58 
59 extern struct ArgusParserStruct *ArgusParser;
60 
61 int ArgusParseGrepExpressionFile(struct ArgusParserStruct *, char *);
62 
63 #define ARGUS_GREP_BUFFER	1048576
64 #define ARGUS_GREP_STRLEN	65536
65 
66 char *ArgusGrepBuffer = NULL;
67 int ArgusRecordMatches = 0;
68 int ArgusTotalMatches = 0;
69 int ArgusTotalFiles = 0;
70 
71 int
ArgusParseGrepExpressionFile(struct ArgusParserStruct * parser,char * file)72 ArgusParseGrepExpressionFile(struct ArgusParserStruct *parser, char *file) {
73    char buffer [ARGUS_GREP_STRLEN];
74    int eop = 0, retn = 0, linenum = 0;
75    char *sptr = NULL, *eptr = NULL;
76    FILE *fd;
77 
78    if (file) {
79       if ((fd = fopen (file, "r")) != NULL) {
80          while (fgets (buffer, ARGUS_GREP_STRLEN, fd)) {
81             linenum++;
82             if ((*buffer != '#') && (*buffer != '\n') && (*buffer != '!') && strlen(buffer)) {
83                int slen = strlen(buffer);
84 
85                while (buffer[slen - 1] == '\n') {
86                   buffer[slen - 1] = '\0';
87                   slen--;
88                }
89 
90                if (buffer[slen - 1] == '\\') {
91                   buffer[slen - 1] = '\0';
92                   slen--;
93                } else {
94                   eop++;
95                }
96 
97                if (ArgusGrepBuffer == NULL) {
98                   if ((ArgusGrepBuffer = calloc(1, ARGUS_GREP_BUFFER)) == NULL)
99                      ArgusLog (LOG_ERR, "ArgusCalloc error %s\n", strerror(errno));
100 
101                   sptr = ArgusGrepBuffer;
102                   eptr = ArgusGrepBuffer + ARGUS_GREP_BUFFER;
103                   parser->estr = ArgusGrepBuffer;
104                }
105 
106                if ((sptr + slen) < eptr) {
107                   bcopy(buffer, sptr, slen);
108                   sptr += slen;
109                }
110 
111                if (eop) {
112                   if (*ArgusGrepBuffer != '\0') {
113                      ArgusInitializeGrep(parser);
114                      bzero(ArgusGrepBuffer, ARGUS_GREP_BUFFER);
115                      sptr = ArgusGrepBuffer;
116                   }
117                }
118             }
119 
120             eop = 0;
121          }
122 
123          if (*ArgusGrepBuffer != '\0')
124             ArgusInitializeGrep(parser);
125 
126          fclose (fd);
127 
128 
129       } else {
130          retn = 1;
131          ArgusLog (LOG_ERR, "%s %s\n", file,  strerror(errno));
132       }
133    }
134 
135 #ifdef ARGUSDEBUG
136    ArgusDebug (2, "ArgusParseGrepExpressionFile(0x%x, %s) done\n", parser, file);
137 #endif
138    return (retn);
139 }
140 
141 void
ArgusClientInit(struct ArgusParserStruct * parser)142 ArgusClientInit (struct ArgusParserStruct *parser)
143 {
144    struct ArgusInput *list;
145 
146    parser->RaWriteOut = 0;
147    parser->ArgusPrintMan = 0;
148 
149    if (!(parser->RaInitialized)) {
150 
151       (void) signal (SIGHUP,  (void (*)(int)) RaParseComplete);
152 
153       if (parser->ArgusFlowModelFile) {
154          parser->ArgusGrepSource++;
155          parser->ArgusGrepDestination++;
156 
157          if (ArgusParseGrepExpressionFile (parser, parser->ArgusFlowModelFile) != 0)
158             ArgusLog (LOG_ERR, "ArgusClientInit: ArgusParseGrepExpression error");
159       }
160 
161 
162       if ((list = parser->ArgusInputFileList) != NULL) {
163          while (list->qhdr.nxt) {
164             list = (struct ArgusInput *)list->qhdr.nxt;
165             ArgusTotalFiles++;
166          }
167       }
168 
169 
170       if (parser->Lflag < 0)
171          parser->Lflag = 0;
172 
173       parser->RaInitialized++;
174    }
175 }
176 
RaArgusInputComplete(struct ArgusInput * input)177 void RaArgusInputComplete (struct ArgusInput *input) {
178    if (input->major_version > 0) {
179       if (ArgusParser->Lflag) {
180          if (ArgusRecordMatches == 0) {
181             printf ("%s\n", input->filename);
182          }
183       } else
184       if (ArgusParser->lflag) {
185          if (ArgusRecordMatches > 0) {
186             printf ("%s\n", input->filename);
187          }
188       } else
189       if (ArgusParser->cflag)
190          printf ("%s:%d\n", input->filename, ArgusRecordMatches);
191    }
192 
193    ArgusTotalMatches += ArgusRecordMatches;
194    ArgusRecordMatches = 0;
195 
196    return;
197 }
198 
199 
200 void
RaParseComplete(int sig)201 RaParseComplete (int sig)
202 {
203    if (sig >= 0) {
204       if (!ArgusParser->RaParseCompleting++) {
205 #ifdef ARGUSDEBUG
206          ArgusDebug (2, "RaParseComplete(caught signal %d)\n", sig);
207 #endif
208          switch (sig) {
209             case SIGHUP:
210             case SIGINT:
211             case SIGTERM:
212             case SIGQUIT: {
213                struct ArgusWfileStruct *wfile = NULL;
214 
215                ArgusShutDown(0);
216 
217                if (ArgusParser->ArgusWfileList != NULL) {
218                   struct ArgusListObjectStruct *lobj = NULL;
219                   int i, count = ArgusParser->ArgusWfileList->count;
220 
221                   if ((lobj = ArgusParser->ArgusWfileList->start) != NULL) {
222                      for (i = 0; i < count; i++) {
223                         if ((wfile = (struct ArgusWfileStruct *) lobj) != NULL) {
224                            if (wfile->fd != NULL) {
225 #ifdef ARGUSDEBUG
226                               ArgusDebug (2, "RaParseComplete: closing %s\n", wfile->filename);
227 #endif
228                               fflush (wfile->fd);
229                               fclose (wfile->fd);
230                               wfile->fd = NULL;
231                            }
232                         }
233                         lobj = lobj->nxt;
234                      }
235                   }
236                }
237 
238                if (ArgusTotalMatches > 0)
239                   exit(0);
240                else
241                   exit(1);
242                break;
243             }
244          }
245       }
246    }
247 }
248 
249 
250 void
ArgusClientTimeout()251 ArgusClientTimeout ()
252 {
253 #ifdef ARGUSDEBUG
254    ArgusDebug (6, "ArgusClientTimeout()\n");
255 #endif
256 }
257 
258 void
parse_arg(int argc,char ** argv)259 parse_arg (int argc, char**argv)
260 {}
261 
262 void
usage()263 usage ()
264 {
265    extern char version[];
266 
267    fprintf (stdout, "Ragrep Version %s\n", version);
268    fprintf (stdout, "usage: %s -bcHhiLnqv [-e regex] [-f regex.file] [raoptions]\n", ArgusParser->ArgusProgramName);
269 
270    fprintf (stdout, "options: -b                 print the byte offset within the input file before each record of output.\n");
271    fprintf (stdout, "         -c <char>          Suppress normal output, print a count of matching records for each input file.\n");
272 #if defined (ARGUSDEBUG)
273    fprintf (stdout, "         -D <level>         specify debug level\n");
274 #endif
275    fprintf (stdout, "         -e <regex>         match regular expression in flow user data fields.\n");
276    fprintf (stdout, "                            Prepend the regex with either \"s:\" or \"d:\" to limit the match\n");
277    fprintf (stdout, "                            to either the source or destination user data fields.\n");
278    fprintf (stdout, "         -f <regex.file>    Obtain patterns from regex.file, one per line.\n");
279    fprintf (stdout, "         -H                 print the filename for each record match.\n");
280    fprintf (stdout, "         -h                 suppress the prefixing of filenames on output when multiple files are searched.\n");
281    fprintf (stdout, "         -i                 ignore case distinctions in both the pattern and the input files.\n");
282    fprintf (stdout, "         -L                 Suppress normal output, print the name of each input file from which no output would normally have been printed.\n");
283    fprintf (stdout, "         -l                 Suppress normal output, print the name of each input file from which output would normally have been printed.\n");
284    fprintf (stdout, "         -q                 quiet mode. don't print record outputs.\n");
285    fprintf (stdout, "         -v                 invert the sense of matching, to select non-matching records.\n");
286    fflush (stdout);
287    exit(1);
288 }
289 
290 
291 void RaProcessThisRecord (struct ArgusParserStruct *, struct ArgusRecordStruct *);
292 
293 void
RaProcessRecord(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus)294 RaProcessRecord (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus)
295 {
296    switch (argus->hdr.type & 0xF0) {
297       case ARGUS_MAR:
298          RaProcessManRecord (parser, argus);
299          break;
300 
301       case ARGUS_EVENT:
302          RaProcessEventRecord (parser, argus);
303          break;
304 
305       case ARGUS_NETFLOW:
306       case ARGUS_FAR: {
307          if (parser->qflag) {
308             exit(0);
309          } else {
310             struct ArgusMetricStruct *metric = (void *)argus->dsrs[ARGUS_METRIC_INDEX];
311             ArgusRecordMatches++;
312 
313             if (metric != NULL) {
314                parser->ArgusTotalPkts  += metric->src.pkts;
315                parser->ArgusTotalPkts  += metric->dst.pkts;
316                parser->ArgusTotalBytes += metric->src.bytes;
317                parser->ArgusTotalBytes += metric->dst.bytes;
318             }
319 
320             if (parser->RaMonMode) {
321                struct ArgusRecordStruct *tns = ArgusCopyRecordStruct(argus);
322                struct ArgusFlow *flow;
323 
324                if ((flow = (void *)argus->dsrs[ARGUS_FLOW_INDEX]) != NULL) {
325                   flow->hdr.subtype &= ~ARGUS_REVERSE;
326                   flow->hdr.argus_dsrvl8.qual &= ~ARGUS_DIRECTION;
327                }
328 
329                RaProcessThisRecord(parser, argus);
330                ArgusReverseRecord(tns);
331 
332                if ((flow = (void *)tns->dsrs[ARGUS_FLOW_INDEX]) != NULL) {
333                   flow->hdr.subtype &= ~ARGUS_REVERSE;
334                   flow->hdr.argus_dsrvl8.qual &= ~ARGUS_DIRECTION;
335                }
336 
337                RaProcessThisRecord(parser, tns);
338                ArgusDeleteRecordStruct(parser, tns);
339 
340             } else {
341                RaProcessThisRecord(parser, argus);
342             }
343          }
344       }
345 
346       if (parser->mflag && (parser->mflag <= ArgusRecordMatches)) {
347          parser->RaParseDone++;
348       }
349    }
350 }
351 
352 
353 void
RaProcessThisRecord(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus)354 RaProcessThisRecord (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus)
355 {
356    static char buf[MAXSTRLEN];
357 
358    switch (parser->ArgusPassNum)  {
359       case 2: {
360          if (parser->Pctflag) {
361             if (parser->ns == NULL) {
362                parser->ns = ArgusCopyRecordStruct(argus);
363             } else {
364                ArgusMergeRecords (parser->ArgusAggregator, parser->ns, argus);
365             }
366          }
367          break;
368       }
369 
370       case 1: {
371          if (parser->ArgusWfileList != NULL) {
372             struct ArgusWfileStruct *wfile = NULL;
373             struct ArgusListObjectStruct *lobj = NULL;
374             int i, count = parser->ArgusWfileList->count;
375 
376             if ((lobj = parser->ArgusWfileList->start) != NULL) {
377                for (i = 0; i < count; i++) {
378                   if ((wfile = (struct ArgusWfileStruct *) lobj) != NULL) {
379                      int retn = 1;
380                      if (wfile->filterstr) {
381                         struct nff_insn *wfcode = wfile->filter.bf_insns;
382                         retn = ArgusFilterRecord (wfcode, argus);
383                      }
384 
385                      if (retn != 0) {
386                         if ((parser->exceptfile == NULL) || strcmp(wfile->filename, parser->exceptfile)) {
387                            struct ArgusRecord *argusrec = NULL;
388                            static char sbuf[0x10000];
389                            if ((argusrec = ArgusGenerateRecord (argus, 0L, sbuf)) != NULL) {
390       #ifdef _LITTLE_ENDIAN
391                               ArgusHtoN(argusrec);
392       #endif
393                               ArgusWriteNewLogfile (parser, argus->input, wfile, argusrec);
394                            }
395                         }
396                      }
397                   }
398 
399                   lobj = lobj->nxt;
400                }
401             }
402 
403          } else {
404             if (!(parser->qflag || parser->Lflag || parser->lflag || parser->cflag)) {
405                if (!(parser->ArgusPrintXml)) {
406                   if (parser->RaLabel == NULL)
407                      parser->RaLabel = ArgusGenerateLabel(parser, argus);
408                }
409 
410                bzero (buf, sizeof(buf));
411                ArgusPrintRecord(parser, buf, argus, MAXSTRLEN);
412 
413 
414                if (argus->input->filename != NULL)
415                   if (((ArgusTotalFiles > 1) || parser->Hflag) && !(parser->hflag))
416                      fprintf (stdout, "%s:", argus->input->filename);
417 
418                if (parser->bflag)
419                   fprintf (stdout, "%lld:", argus->offset);
420 
421                if (fprintf (stdout, "%s", buf) < 0)
422                   RaParseComplete(SIGQUIT);
423 
424                if (parser->eflag == ARGUS_HEXDUMP) {
425                   int i;
426                   for (i = 0; i < MAX_PRINT_ALG_TYPES; i++) {
427                      if (parser->RaPrintAlgorithmList[i] != NULL) {
428                         struct ArgusDataStruct *user = NULL;
429                         if (parser->RaPrintAlgorithmList[i]->print == ArgusPrintSrcUserData) {
430                            int slen = 0, len = parser->RaPrintAlgorithmList[i]->length;
431                            if (len > 0) {
432                               if ((user = (struct ArgusDataStruct *)argus->dsrs[ARGUS_SRCUSERDATA_INDEX]) != NULL) {
433                                  if (user->hdr.type == ARGUS_DATA_DSR) {
434                                     slen = (user->hdr.argus_dsrvl16.len - 2 ) * 4;
435                                  } else
436                                     slen = (user->hdr.argus_dsrvl8.len - 2 ) * 4;
437 
438                                  slen = (user->count < slen) ? user->count : slen;
439                                  slen = (slen > len) ? len : slen;
440                                  ArgusDump ((const u_char *) &user->array, slen, "      ");
441                               }
442                            }
443                         }
444                         if (parser->RaPrintAlgorithmList[i]->print == ArgusPrintDstUserData) {
445                            int slen = 0, len = parser->RaPrintAlgorithmList[i]->length;
446                            if (len > 0) {
447                               if ((user = (struct ArgusDataStruct *)argus->dsrs[ARGUS_DSTUSERDATA_INDEX]) != NULL) {
448                                  if (user->hdr.type == ARGUS_DATA_DSR) {
449                                     slen = (user->hdr.argus_dsrvl16.len - 2 ) * 4;
450                                  } else
451                                     slen = (user->hdr.argus_dsrvl8.len - 2 ) * 4;
452 
453                                  slen = (user->count < slen) ? user->count : slen;
454                                  slen = (slen > len) ? len : slen;
455                                  ArgusDump ((const u_char *) &user->array, slen, "      ");
456                               }
457                            }
458                         }
459                      } else
460                         break;
461                   }
462                }
463 
464                fprintf (stdout, "\n");
465                fflush (stdout);
466             }
467          }
468       }
469    }
470 }
471 
472 void
RaProcessManRecord(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus)473 RaProcessManRecord (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus)
474 {
475    static char buf[MAXSTRLEN];
476 
477    if (parser->ArgusWfileList != NULL) {
478       struct ArgusWfileStruct *wfile = NULL;
479       struct ArgusListObjectStruct *lobj = NULL;
480       int i, count = parser->ArgusWfileList->count;
481 
482       if ((lobj = parser->ArgusWfileList->start) != NULL) {
483          for (i = 0; i < count; i++) {
484             if ((wfile = (struct ArgusWfileStruct *) lobj) != NULL) {
485                int retn = 1;
486                if (wfile->filterstr) {
487                   struct nff_insn *wfcode = wfile->filter.bf_insns;
488                   retn = ArgusFilterRecord (wfcode, argus);
489                }
490 
491                if (retn != 0) {
492                   if ((parser->exceptfile == NULL) || strcmp(wfile->filename, parser->exceptfile)) {
493                      struct ArgusRecord *argusrec = NULL;
494                      static char sbuf[0x10000];
495                      if ((argusrec = ArgusGenerateRecord (argus, 0L, sbuf)) != NULL) {
496 #ifdef _LITTLE_ENDIAN
497                         ArgusHtoN(argusrec);
498 #endif
499                         ArgusWriteNewLogfile (parser, argus->input, wfile, argusrec);
500                      }
501                   }
502                }
503             }
504 
505             lobj = lobj->nxt;
506          }
507       }
508 
509    } else {
510 
511       if ((parser->ArgusPrintMan) && (!parser->qflag)) {
512          if (parser->Lflag && !(parser->ArgusPrintXml)) {
513             if (parser->RaLabel == NULL)
514                parser->RaLabel = ArgusGenerateLabel(parser, argus);
515 
516             if (!(parser->RaLabelCounter++ % parser->Lflag))
517                printf ("%s\n", parser->RaLabel);
518 
519             if (parser->Lflag < 0)
520                parser->Lflag = 0;
521          }
522 
523          bzero (buf, sizeof(buf));
524          if (argus->dsrs[0] != NULL) {
525             ArgusPrintRecord(parser, buf, argus, MAXSTRLEN);
526             if (fprintf (stdout, "%s\n", buf) < 0)
527                RaParseComplete(SIGQUIT);
528          }
529          fflush (stdout);
530       }
531    }
532 
533 #ifdef ARGUSDEBUG
534    {
535       struct ArgusRecord *rec = (struct ArgusRecord *)argus->dsrs[0];
536       if (rec != NULL) {
537          struct ArgusMarStruct *mar = &rec->ar_un.mar;
538          ArgusDebug (6, "RaProcessManRecord (0x%x, 0x%x) mar parsed 0x%x", parser, argus, mar);
539       }
540    }
541 #endif
542 }
543 
544 
545 void
RaProcessEventRecord(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus)546 RaProcessEventRecord (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus)
547 {
548    static char buf[MAXSTRLEN];
549 
550    if (parser->ArgusWfileList != NULL) {
551       struct ArgusWfileStruct *wfile = NULL;
552       struct ArgusListObjectStruct *lobj = NULL;
553       int i, count = parser->ArgusWfileList->count;
554 
555       if ((lobj = parser->ArgusWfileList->start) != NULL) {
556          for (i = 0; i < count; i++) {
557             if ((wfile = (struct ArgusWfileStruct *) lobj) != NULL) {
558                int retn = 1;
559                if (wfile->filterstr) {
560                   struct nff_insn *wfcode = wfile->filter.bf_insns;
561                   retn = ArgusFilterRecord (wfcode, argus);
562                }
563 
564                if (retn != 0) {
565                   if ((parser->exceptfile == NULL) || strcmp(wfile->filename, parser->exceptfile)) {
566                      struct ArgusRecord *argusrec = NULL;
567                      static char sbuf[0x10000];
568                      if ((argusrec = ArgusGenerateRecord (argus, 0L, sbuf)) != NULL) {
569 #ifdef _LITTLE_ENDIAN
570                         ArgusHtoN(argusrec);
571 #endif
572                         ArgusWriteNewLogfile (parser, argus->input, wfile, argusrec);
573                      }
574                   }
575                }
576             }
577 
578             lobj = lobj->nxt;
579          }
580       }
581 
582    } else {
583 
584       if ((parser->ArgusPrintEvent) && (!parser->qflag)) {
585          if (parser->Lflag && !(parser->ArgusPrintXml)) {
586             if (parser->RaLabel == NULL)
587                parser->RaLabel = ArgusGenerateLabel(parser, argus);
588 
589             if (!(parser->RaLabelCounter++ % parser->Lflag))
590                printf ("%s\n", parser->RaLabel);
591 
592             if (parser->Lflag < 0)
593                parser->Lflag = 0;
594          }
595 
596          bzero (buf, sizeof(buf));
597          ArgusPrintRecord(parser, buf, argus, MAXSTRLEN);
598 
599          if (fprintf (stdout, "%s\n", buf) < 0)
600             RaParseComplete(SIGQUIT);
601          fflush (stdout);
602       }
603    }
604 
605 #ifdef ARGUSDEBUG
606    {
607       struct ArgusRecord *rec = (struct ArgusRecord *)argus->dsrs[0];
608 
609       if (rec != NULL) {
610          struct ArgusEventStruct *event = &rec->ar_un.event;
611          ArgusDebug (6, "RaProcessEventRecord (0x%x, 0x%x) event parsed 0x%x", parser, argus, event);
612       }
613    }
614 #endif
615 }
616 
617 
RaSendArgusRecord(struct ArgusRecordStruct * argus)618 int RaSendArgusRecord(struct ArgusRecordStruct *argus) {return 0;}
619 
620 void ArgusWindowClose(void);
621 
ArgusWindowClose(void)622 void ArgusWindowClose(void) {
623 #ifdef ARGUSDEBUG
624    ArgusDebug (6, "ArgusWindowClose () returning\n");
625 #endif
626 }
627