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 * raservices - discover and validate network services.
24 * add ArgusLabelStruct to the argus record
25 * if writing the record out.
26 *
27 * written by Carter Bullard
28 * QoSient, LLC
29 *
30 *
31 * $Id: //depot/argus/clients/examples/raservices/raservices.c#12 $
32 * $DateTime: 2016/06/01 15:17:28 $
33 * $Change: 3148 $
34 */
35
36 #ifdef HAVE_CONFIG_H
37 #include "argus_config.h"
38 #endif
39
40 #include <unistd.h>
41 #include <stdlib.h>
42 #include <signal.h>
43 #include <ctype.h>
44
45 #include <rabins.h>
46 #include <argus_util.h>
47 #include <argus_label.h>
48 #include <argus_client.h>
49 #include <argus_filter.h>
50 #include <argus_main.h>
51
52
53 int ArgusReplace = 0;
54 int ArgusExtend = 0;
55 int ArgusDiff = 0;
56
57
58 void
ArgusClientInit(struct ArgusParserStruct * parser)59 ArgusClientInit (struct ArgusParserStruct *parser)
60 {
61 struct ArgusModeStruct *mode = NULL;
62 parser->RaWriteOut = 0;
63
64 if (!(parser->RaInitialized)) {
65 (void) signal (SIGHUP, (void (*)(int)) RaParseComplete);
66
67 if ((ArgusLabeler = ArgusNewLabeler(parser, 0L)) == NULL)
68 ArgusLog (LOG_ERR, "ArgusClientInit: ArgusNewLabeler error");
69
70 parser->ArgusLabeler = ArgusLabeler;
71
72 if (parser->ArgusFlowModelFile) {
73 RaReadSrvSignature (parser, parser->ArgusLabeler, parser->ArgusFlowModelFile);
74 parser->ArgusFlowModelFile = NULL;
75 }
76
77 if ((mode = parser->ArgusModeList) != NULL) {
78 while (mode) {
79 if (!(strncasecmp (mode->mode, "replace", 7)))
80 ArgusReplace = 1;
81 if (!(strncasecmp (mode->mode, "extend", 6)))
82 ArgusExtend = 1;
83 if (!(strncasecmp (mode->mode, "diff", 4)))
84 ArgusDiff = 1;
85
86 mode = mode->nxt;
87 }
88 }
89 parser->RaInitialized++;
90 }
91 }
92
RaArgusInputComplete(struct ArgusInput * input)93 void RaArgusInputComplete (struct ArgusInput *input) {};
94
95 void
RaParseComplete(int sig)96 RaParseComplete (int sig)
97 {
98 if (sig >= 0) {
99 if (!ArgusParser->RaParseCompleting++) {
100 if ((ArgusParser->ArgusWfileList != NULL) && (!(ArgusListEmpty(ArgusParser->ArgusWfileList)))) {
101 struct ArgusWfileStruct *wfile = NULL, *start = NULL;
102
103 if ((wfile = (struct ArgusWfileStruct *) ArgusFrontList(ArgusParser->ArgusWfileList)) != NULL) {
104 start = wfile;
105 fflush(wfile->fd);
106 ArgusPopFrontList(ArgusParser->ArgusWfileList, ARGUS_NOLOCK);
107 ArgusPushBackList(ArgusParser->ArgusWfileList, (struct ArgusListRecord *) wfile, ARGUS_NOLOCK);
108 wfile = (struct ArgusWfileStruct *) ArgusFrontList(ArgusParser->ArgusWfileList);
109 } while (wfile != start);
110 }
111
112 ArgusShutDown(sig);
113 }
114
115 fflush(stdout);
116 exit(0);
117 }
118
119 #ifdef ARGUSDEBUG
120 ArgusDebug (1, "RaParseComplete (%d) returning\n", sig);
121 #endif
122 }
123
124 void
ArgusClientTimeout()125 ArgusClientTimeout ()
126 {
127
128 #ifdef ARGUSDEBUG
129 ArgusDebug (4, "ArgusClientTimeout: returning\n");
130 #endif
131 }
132
133 void
parse_arg(int argc,char ** argv)134 parse_arg (int argc, char**argv)
135 {
136
137 #ifdef ARGUSDEBUG
138 ArgusDebug (6, "parse_arg (%d, 0x%x) returning\n", argc, argv);
139 #endif
140 }
141
142
143 void
usage()144 usage ()
145 {
146 extern char version[];
147 fprintf (stdout, "%s Version %s\n", ArgusParser->ArgusProgramName, version);
148 fprintf (stdout, "usage: %s \n", ArgusParser->ArgusProgramName);
149 fprintf (stdout, "usage: %s [options] -S remoteServer [- filter-expression]\n", ArgusParser->ArgusProgramName);
150 fprintf (stdout, "usage: %s [options] -r argusDataFile [- filter-expression]\n\n", ArgusParser->ArgusProgramName);
151
152 fprintf (stdout, "options: -f <conffile> read service signatures from <conffile>.\n");
153 fflush (stdout);
154
155 exit(1);
156 }
157
158
159
160
161 void
RaProcessRecord(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus)162 RaProcessRecord (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus)
163 {
164 struct ArgusFlow *flow = (struct ArgusFlow *) argus->dsrs[ARGUS_FLOW_INDEX];
165 // unsigned short sport = 0, dport = 0;
166 // int type, proto, process = 0, found = 0;
167 int type, process = 0, found = 0;
168 struct RaSrvSignature *sig;
169 char buf[MAXSTRLEN], name[128];
170
171 bzero (name, sizeof(name));
172
173 switch (argus->hdr.type & 0xF0) {
174 case ARGUS_MAR:
175 case ARGUS_EVENT: {
176 break;
177 }
178
179 case ARGUS_NETFLOW:
180 case ARGUS_FAR: {
181 if (flow) {
182 if (argus->dsrs[ARGUS_SRCUSERDATA_INDEX] || argus->dsrs[ARGUS_DSTUSERDATA_INDEX]) {
183 switch (flow->hdr.subtype & 0x3F) {
184 case ARGUS_FLOW_CLASSIC5TUPLE: {
185 struct ArgusNetworkStruct *net = (struct ArgusNetworkStruct *) argus->dsrs[ARGUS_NETWORK_INDEX];
186
187 switch (type = (flow->hdr.argus_dsrvl8.qual & 0x1F)) {
188 case ARGUS_TYPE_IPV4:
189 switch (flow->ip_flow.ip_p) {
190 case IPPROTO_TCP:
191 case IPPROTO_UDP: {
192 // proto = flow->ip_flow.ip_p;
193 // sport = flow->ip_flow.sport;
194 // dport = flow->ip_flow.dport;
195 process++;
196 break;
197 }
198 }
199 break;
200
201 case ARGUS_TYPE_IPV6: {
202 switch (flow->ipv6_flow.ip_p) {
203 case IPPROTO_TCP:
204 case IPPROTO_UDP: {
205 // proto = flow->ipv6_flow.ip_p;
206 // sport = flow->ipv6_flow.sport;
207 // dport = flow->ipv6_flow.dport;
208 process++;
209 break;
210 }
211 }
212 break;
213 }
214 }
215 if (net && (net->hdr.subtype == ARGUS_RTP_FLOW)) {
216 snprintf (name, 128, "%s", "rtp");
217 found++;
218 } else
219 if (net && (net->hdr.subtype == ARGUS_RTCP_FLOW)) {
220 snprintf (name, 128, "%s", "rtcp");
221 found++;
222 }
223 break;
224 }
225 }
226
227 if (process) {
228 int length = 0;
229
230 if ((length = strlen(name)) == 0) {
231 #ifdef ARGUSDEBUG
232 ArgusDebug (5, "RaProcessRecord (0x%x) validating service", argus);
233 #endif
234 if (!(sig = RaValidateService (parser, argus))) {
235 struct ArgusMetricStruct *metric = (void *)argus->dsrs[ARGUS_METRIC_INDEX];
236 if ((metric != NULL) && (metric->dst.pkts)) {
237 ArgusReverseRecord(argus);
238 sig = RaValidateService (parser, argus);
239 ArgusReverseRecord(argus);
240 }
241 }
242
243 if (sig != NULL) {
244 length = strlen(sig->name) + 1;
245 length = ((length > 16) ? 16 : length);
246 snprintf ((char *)name, length, "%s", sig->name);
247 found++;
248
249 } else {
250 /*
251 if ((dport > 0) && (dport < 1024)) {
252 int len = RaPrintAlgorithmTable[ARGUSPRINTDSTPORT].length;
253 len = ((len > 16) ? 16 : len);
254 ArgusPrintPort (parser, (char *) name, argus, type, proto, dport, len);
255 } else
256 if ((sport > 0) && (sport < 1024)) {
257 int len = RaPrintAlgorithmTable[ARGUSPRINTDSTPORT].length;
258 len = ((len > 16) ? 16 : len);
259 ArgusPrintPort (parser, (char *) name, argus, type, proto, sport, len);
260
261 } else
262 found = 0;
263 */
264 }
265 }
266
267 if (found) {
268 struct ArgusLabelStruct labelbuf, *label = &labelbuf;
269 int len = strlen(name) + 4;
270
271 bzero((char *)label, sizeof(label));
272
273 label->hdr.type = ARGUS_LABEL_DSR;
274 label->hdr.subtype = ARGUS_SVC_LABEL;
275 label->hdr.argus_dsrvl8.len = 1 + ((len + 3)/4);
276
277 if (argus->dsrs[ARGUS_LABEL_INDEX] == NULL) { // working with the canonical record here
278 struct ArgusCanonRecord *canon = &parser->canon;
279
280 if (argus->input != NULL) {
281 label->l_un.svc = argus->input->ArgusGenerateRecordLabelBuf;
282 } else {
283 extern char ArgusCanonLabelBuffer[MAXBUFFERLEN];
284 label->l_un.svc = ArgusCanonLabelBuffer;
285 }
286
287 sprintf(label->l_un.svc, "srv=%s", name);
288 bcopy((char *)label, (char *)&canon->label, sizeof(*label));
289
290 argus->dsrs[ARGUS_LABEL_INDEX] = (struct ArgusDSRHeader*) &canon->label;
291 argus->dsrindex |= (0x01 << ARGUS_LABEL_INDEX);
292
293 } else {
294 struct ArgusLabelStruct *l1 = (void *) argus->dsrs[ARGUS_LABEL_INDEX];
295 char RaServicesCanonLabelBuffer[MAXSTRLEN];
296 char buf[MAXSTRLEN];
297 int blen;
298
299 RaServicesCanonLabelBuffer[0] = '\0';
300 label->l_un.svc = RaServicesCanonLabelBuffer;
301 sprintf(label->l_un.svc, "srv=%s", name);
302
303 bzero(buf, 4);
304
305 ArgusMergeLabel(l1, label, buf, MAXSTRLEN, ARGUS_UNION);
306
307 if ((blen = strlen(buf)) > 0) {
308 int len = (blen >= (MAXSTRLEN - 1)) ? MAXSTRLEN - 1 : blen;
309 bcopy(buf, l1->l_un.label, len);
310 l1->l_un.label[len] = '\0';
311 } else
312 *l1->l_un.label = '\0';
313 }
314 }
315 }
316 }
317
318 } else {
319 #ifdef ARGUSDEBUG
320 ArgusDebug (5, "RaProcessRecord (0x%x) record not validated\n", argus);
321 #endif
322 }
323 break;
324 }
325 }
326
327
328 if (parser->ArgusWfileList != NULL) {
329 struct ArgusWfileStruct *wfile = NULL;
330 struct ArgusListObjectStruct *lobj = NULL;
331 int i, count = parser->ArgusWfileList->count;
332
333 if ((lobj = parser->ArgusWfileList->start) != NULL) {
334 for (i = 0; i < count; i++) {
335 if ((wfile = (struct ArgusWfileStruct *) lobj) != NULL) {
336 struct ArgusRecord *argusrec = NULL;
337 static char sbuf[0x10000];
338
339 if ((argusrec = ArgusGenerateRecord (argus, 0L, sbuf)) != NULL) {
340 #ifdef _LITTLE_ENDIAN
341 ArgusHtoN(argusrec);
342 #endif
343 if (parser->exceptfile != NULL) {
344 if (strlen (name) && strcmp(wfile->filename, parser->exceptfile))
345 ArgusWriteNewLogfile (parser, argus->input, wfile, argusrec);
346 else
347 if (!strlen (name) && !strcmp(wfile->filename, parser->exceptfile))
348 ArgusWriteNewLogfile (parser, argus->input, wfile, argusrec);
349
350 } else
351 ArgusWriteNewLogfile (parser, argus->input, wfile, argusrec);
352 }
353 }
354 lobj = lobj->nxt;
355 }
356 }
357
358 } else {
359 if (!parser->qflag) {
360 if (parser->Lflag) {
361 if (parser->RaLabel == NULL)
362 parser->RaLabel = ArgusGenerateLabel(parser, argus);
363
364 if (!(parser->RaLabelCounter++ % parser->Lflag))
365 printf ("%s\n", parser->RaLabel);
366
367 if (parser->Lflag < 0)
368 parser->Lflag = 0;
369 }
370
371 *(int *)&buf = 0;
372 ArgusPrintRecord(parser, buf, argus, MAXSTRLEN);
373 if (fprintf (stdout, "%s\n", buf) < 0)
374 RaParseComplete(SIGQUIT);
375 }
376 }
377
378 #ifdef ARGUSDEBUG
379 ArgusDebug (5, "RaProcessRecord (0x%x) returning\n", argus);
380 #endif
381 }
382
383
384 int
RaSendArgusRecord(struct ArgusRecordStruct * argus)385 RaSendArgusRecord(struct ArgusRecordStruct *argus)
386 {
387
388 #ifdef ARGUSDEBUG
389 ArgusDebug (6, "RaSendArgusRecord (0x%x) returning\n", argus);
390 #endif
391 return 1;
392 }
393
ArgusWindowClose(void)394 void ArgusWindowClose(void) { }
395