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