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