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  * rafilteraddr - filter records based on an address list.  bypasses
24  *                standard filter compiler.
25  *
26  * written by Carter Bullard
27  * QoSient, LLC
28  *
29  * $Id: //depot/argus/clients/examples/rafilter/rafilteraddr.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 #if defined(CYGWIN)
39 #define USE_IPV6
40 #endif
41 
42 #include <unistd.h>
43 #include <stdlib.h>
44 #include <signal.h>
45 #include <ctype.h>
46 
47 #if defined(ARGUS_SOLARIS)
48 #include <strings.h>
49 #include <string.h>
50 #endif
51 
52 #include <math.h>
53 
54 #include <rabins.h>
55 #include <argus_util.h>
56 #include <argus_label.h>
57 #include <argus_client.h>
58 #include <argus_filter.h>
59 #include <argus_main.h>
60 #include <argus_cluster.h>
61 
62 
63 /*
64    IANA style address label configuration file syntax is:
65       addr "label"
66 
67       where addr is:
68          %d[[[.%d].%d].%d]/%d   CIDR address
69          CIDR - CIDR            Address range
70 
71    The Regional Internet Registries (RIR) database support allows for
72    country codes to be associated with address prefixes.  We'll treat
73    them as simple labels.   The file syntax is:
74 
75       rir|co|[asn|ipv4|ipv6]|#allocatable|[allocated | assigned]
76 
77    so if we find '|', we know the format.
78 
79 */
80 
81 
82 void
ArgusClientInit(struct ArgusParserStruct * parser)83 ArgusClientInit (struct ArgusParserStruct *parser)
84 {
85    struct ArgusLabelerStruct *labeler = NULL;
86    struct ArgusModeStruct *mode = NULL;
87    parser->RaWriteOut = 0;
88 
89    if (!(parser->RaInitialized)) {
90       int ArgusLabelerStatus = ARGUS_LABELER_ADDRESS;
91 
92       (void) signal (SIGHUP,  (void (*)(int)) RaParseComplete);
93 
94       if ((parser->ArgusAggregator = ArgusNewAggregator(parser, NULL, ARGUS_RECORD_AGGREGATOR)) == NULL)
95          ArgusLog (LOG_ERR, "ArgusClientInit: ArgusNewAggregator error");
96 
97       if ((mode = parser->ArgusModeList) != NULL) {
98          while (mode) {
99             if (!(strncasecmp (mode->mode, "debug.mol", 9))) {
100                ArgusLabelerStatus |= ARGUS_MOL;
101 
102                exit(0);
103             }
104             if (!(strncasecmp (mode->mode, "debug", 5))) {
105                ArgusLabelerStatus |= ARGUS_TREE_DEBUG;
106 
107                if (!(strncasecmp (mode->mode, "debug.node", 10)))
108                   ArgusLabelerStatus |= ARGUS_TREE_DEBUG_NODE;
109             }
110 
111             mode = mode->nxt;
112          }
113       }
114 
115       if (!(parser->ArgusFlowModelFile))
116          ArgusLog (LOG_ERR, "ArgusClientInit: no address list, use -f");
117 
118       if ((parser->ArgusLabeler = ArgusNewLabeler(parser, ArgusLabelerStatus)) == NULL)
119          ArgusLog (LOG_ERR, "ArgusClientInit: ArgusNewLabeler error");
120 
121       labeler = parser->ArgusLabeler;
122 
123       if (ArgusLabelerStatus & (ARGUS_TREE_DEBUG | ARGUS_TREE_DEBUG_NODE)) {
124          if (!(ArgusLabelerStatus & ARGUS_TREE_DEBUG_NODE))
125             RaPrintLabelTree (labeler, labeler->ArgusAddrTree[AF_INET], 0, 0);
126          exit(0);
127       }
128 
129       parser->RaInitialized++;
130    }
131 }
132 
RaArgusInputComplete(struct ArgusInput * input)133 void RaArgusInputComplete (struct ArgusInput *input) { return; }
134 
135 
136 int RaParseCompleting = 0;
137 
138 void
RaParseComplete(int sig)139 RaParseComplete (int sig)
140 {
141    if (sig >= 0) {
142       if (!ArgusParser->RaParseCompleting++) {
143          if ((ArgusParser->ArgusWfileList != NULL) && (!(ArgusListEmpty(ArgusParser->ArgusWfileList)))) {
144             struct ArgusWfileStruct *wfile = NULL, *start = NULL;
145 
146             if ((wfile = (struct ArgusWfileStruct *) ArgusFrontList(ArgusParser->ArgusWfileList)) != NULL) {
147                start = wfile;
148                fflush(wfile->fd);
149                ArgusPopFrontList(ArgusParser->ArgusWfileList, ARGUS_NOLOCK);
150                ArgusPushBackList(ArgusParser->ArgusWfileList, (struct ArgusListRecord *) wfile, ARGUS_NOLOCK);
151                wfile = (struct ArgusWfileStruct *) ArgusFrontList(ArgusParser->ArgusWfileList);
152             } while (wfile != start);
153          }
154 
155          fflush(stdout);
156          ArgusShutDown(sig);
157          exit(0);
158       }
159    }
160 
161 #ifdef ARGUSDEBUG
162    ArgusDebug (1, "RaParseComplete (%d) returning\n", sig);
163 #endif
164 }
165 
166 void
ArgusClientTimeout()167 ArgusClientTimeout ()
168 {
169 
170 #ifdef ARGUSDEBUG
171    ArgusDebug (4, "ArgusClientTimeout: returning\n");
172 #endif
173 }
174 
175 void
parse_arg(int argc,char ** argv)176 parse_arg (int argc, char**argv)
177 {
178 
179 #ifdef ARGUSDEBUG
180    ArgusDebug (6, "parse_arg (%d, 0x%x) returning\n", argc, argv);
181 #endif
182 }
183 
184 
185 void
usage()186 usage ()
187 {
188    extern char version[];
189    fprintf (stdout, "rafilteraddr Version %s\n", version);
190    fprintf (stdout, "usage: %s \n", ArgusParser->ArgusProgramName);
191    fprintf (stdout, "usage: %s [-v] -f address.file [raoptions] \n", ArgusParser->ArgusProgramName);
192    fprintf (stdout, "options: -f          specify file containing address(es).\n");
193    fprintf (stdout, "         -v          invert the logic and print flows that don't match.\n");
194    fflush (stdout);
195    exit(1);
196 }
197 
198 /*
199 extern struct RaAddressStruct *RaFindAddress (struct ArgusParserStruct *, struct RaAddressStruct *, struct RaAddressStruct *, int);
200 int RaProcessAddress (struct ArgusParserStruct *, struct ArgusRecordStruct *, unsigned int *, int);
201 
202 int
203 RaProcessAddress (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus, unsigned int *addr, int type)
204 {
205    struct ArgusLabelerStruct *labeler = NULL;
206    struct RaAddressStruct *raddr;
207    int retn = 0;
208 
209    if ((labeler = parser->ArgusLabeler) == NULL)
210       ArgusLog (LOG_ERR, "RaProcessAddress: No labeler\n");
211 
212    switch (type) {
213       case ARGUS_TYPE_IPV4: {
214          struct RaAddressStruct node;
215          bzero ((char *)&node, sizeof(node));
216 
217          node.addr.type = AF_INET;
218          node.addr.len = 4;
219          node.addr.addr[0] = *addr;
220          node.addr.masklen = 32;
221 
222          if ((raddr = RaFindAddress (parser, labeler->ArgusAddrTree[AF_INET], &node, ARGUS_NODE_MATCH)) != NULL) {
223             retn++;
224          }
225          break;
226       }
227 
228       case ARGUS_TYPE_IPV6:
229          break;
230    }
231 
232 #ifdef ARGUSDEBUG
233    ArgusDebug (5, "RaProcessAddress (0x%x, 0x%x, 0x%x, %d) returning %d\n", parser, argus, addr, type, retn);
234 #endif
235 
236    return (retn);
237 }
238 */
239 
240 void
RaProcessRecord(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus)241 RaProcessRecord (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus)
242 {
243    struct ArgusFlow *flow = (struct ArgusFlow *) argus->dsrs[ARGUS_FLOW_INDEX];
244    struct ArgusLabelerStruct *labeler = parser->ArgusLabeler;
245 
246    int retn = 0;
247 
248    switch (argus->hdr.type & 0xF0) {
249       case ARGUS_MAR:
250       case ARGUS_EVENT: {
251          break;
252       }
253 
254       case ARGUS_NETFLOW:
255       case ARGUS_FAR: {
256          if (flow) {
257             switch (flow->hdr.subtype & 0x3F) {
258                case ARGUS_FLOW_CLASSIC5TUPLE:
259                case ARGUS_FLOW_LAYER_3_MATRIX: {
260                   switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
261                      case ARGUS_TYPE_IPV4:
262                         if ((!retn && parser->ArgusAggregator->mask & ARGUS_MASK_SADDR_INDEX))
263                            retn = RaProcessAddress(parser, labeler, &flow->ip_flow.ip_src, 32, ARGUS_TYPE_IPV4);
264                         if (!retn && (parser->ArgusAggregator->mask & ARGUS_MASK_DADDR_INDEX))
265                            retn = RaProcessAddress(parser, labeler, &flow->ip_flow.ip_dst, 32, ARGUS_TYPE_IPV4);
266                         break;
267                      case ARGUS_TYPE_IPV6:
268                         if (!retn && (parser->ArgusAggregator->mask & ARGUS_MASK_SADDR_INDEX))
269                            retn = RaProcessAddress(parser, labeler, (unsigned int *) &flow->ipv6_flow.ip_src, 128, ARGUS_TYPE_IPV6);
270                         if (!retn && (parser->ArgusAggregator->mask & ARGUS_MASK_DADDR_INDEX))
271                            retn = RaProcessAddress(parser, labeler, (unsigned int *) &flow->ipv6_flow.ip_dst, 128, ARGUS_TYPE_IPV6);
272                         break;
273                   }
274                   break;
275                }
276             }
277          }
278 
279          if (parser->vflag)
280             retn = (retn) ? 0 : 1;
281 
282          if (parser->ArgusWfileList != NULL) {
283             struct ArgusWfileStruct *wfile = NULL;
284             struct ArgusListObjectStruct *lobj = NULL;
285             int i, count = parser->ArgusWfileList->count;
286 
287             if ((lobj = parser->ArgusWfileList->start) != NULL) {
288                for (i = 0; i < count; i++) {
289                   if ((wfile = (struct ArgusWfileStruct *) lobj) != NULL) {
290                      struct ArgusRecord *argusrec = NULL;
291                      static char sbuf[0x10000];
292 
293                      if ((argusrec = ArgusGenerateRecord (argus, 0L, sbuf)) != NULL) {
294 #ifdef _LITTLE_ENDIAN
295                         ArgusHtoN(argusrec);
296 #endif
297                         if (parser->exceptfile != NULL) {
298                            if (retn && strcmp(wfile->filename, parser->exceptfile))
299                               ArgusWriteNewLogfile (parser, argus->input, wfile, argusrec);
300                            else
301                               if (!retn && !strcmp(wfile->filename, parser->exceptfile))
302                                  ArgusWriteNewLogfile (parser, argus->input, wfile, argusrec);
303 
304                         } else {
305                            if (retn)
306                               ArgusWriteNewLogfile (parser, argus->input, wfile, argusrec);
307                         }
308                      }
309                   }
310 
311                   lobj = lobj->nxt;
312                }
313             }
314 
315          } else {
316             if (retn) {
317                char buf[MAXSTRLEN];
318                if (!parser->qflag) {
319                   if (parser->Lflag) {
320                      if (parser->RaLabel == NULL)
321                         parser->RaLabel = ArgusGenerateLabel(parser, argus);
322 
323                      if (!(parser->RaLabelCounter++ % parser->Lflag))
324                         printf ("%s\n", parser->RaLabel);
325 
326                      if (parser->Lflag < 0)
327                         parser->Lflag = 0;
328                   }
329 
330                   *(int *)&buf = 0;
331                   ArgusPrintRecord(parser, buf, argus, MAXSTRLEN);
332                   if (fprintf (stdout, "%s ", buf) < 0)
333                      RaParseComplete(SIGQUIT);
334                }
335                if (parser->ArgusWfileList == NULL)
336                   if (fprintf (stdout, "\n") < 0)
337                      RaParseComplete(SIGQUIT);
338             }
339          }
340 
341          break;
342       }
343    }
344 
345 #ifdef ARGUSDEBUG
346    ArgusDebug (5, "RaProcessRecord (0x%x) returning\n", argus);
347 #endif
348 }
349 
350 
351 int
RaSendArgusRecord(struct ArgusRecordStruct * argus)352 RaSendArgusRecord(struct ArgusRecordStruct *argus)
353 {
354 
355 #ifdef ARGUSDEBUG
356    ArgusDebug (6, "RaSendArgusRecord (0x%x) returning\n", argus);
357 #endif
358    return 1;
359 }
360 
ArgusWindowClose(void)361 void ArgusWindowClose(void) { }
362 
363