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