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  * $Id: //depot/argus/clients/common/argus_label.c#77 $
24  * $DateTime: 2016/06/06 11:08:02 $
25  * $Change: 3155 $
26  */
27 
28 /*
29  * argus labeler/classifier library
30  *
31  * written by Carter Bullard
32  * QoSient, LLC
33  *
34  */
35 
36 #ifdef HAVE_CONFIG_H
37 #include "argus_config.h"
38 #endif
39 
40 #ifndef ArgusLabel
41 #define ArgusLabel
42 #endif
43 
44 #ifndef _REENTRANT
45 #define _REENTRANT
46 #endif
47 
48 #include <stdlib.h>
49 #include <syslog.h>
50 #include <errno.h>
51 
52 #include <math.h>
53 #include <ctype.h>
54 
55 #include <sys/types.h>
56 #include <argus_compat.h>
57 
58 #include <argus_def.h>
59 #include <argus_out.h>
60 #include <argus_util.h>
61 #include <argus_client.h>
62 #include <argus_sort.h>
63 #include <argus_metric.h>
64 #include <argus_histo.h>
65 #include <argus_label.h>
66 
67 #include <rasplit.h>
68 
69 
70 #include <rasplit.h>
71 
72 #if defined(__OpenBSD__)
73 #include <netinet/in_systm.h>
74 #include <netinet/ip.h>
75 #endif
76 
77 #include <netinet/ip_icmp.h>
78 #include <netinet/igmp.h>
79 #include <netinet/tcp.h>
80 
81 #include <ctype.h>
82 
83 #if defined(ARGUS_GEOIP)
84 #include <GeoIPCity.h>
85 #endif
86 
87 int RaReadAddressConfig (struct ArgusParserStruct *, struct ArgusLabelerStruct *, char *);
88 int RaReadIeeeAddressConfig (struct ArgusParserStruct *, struct ArgusLabelerStruct *, char *);
89 
90 void RaAddSrvTreeNode(struct RaSrvTreeNode *, struct RaSrvSignature *, int, int);
91 int ArgusSortSrvSignatures (struct ArgusRecordStruct *, struct ArgusRecordStruct *);
92 void RaAddToSrvTree (struct RaSrvSignature *, int);
93 int RaGenerateBinaryTrees(struct ArgusParserStruct *, struct ArgusLabelerStruct *);
94 int RaReadSrvSignature(struct ArgusParserStruct *, struct ArgusLabelerStruct *, char *);
95 struct RaSrvSignature *RaFindSrv (struct RaSrvTreeNode *, u_char *ptr, int, int);
96 
97 int ArgusAddToRecordLabel (struct ArgusParserStruct *, struct ArgusRecordStruct *, char *);
98 
99 int RaFindService(struct ArgusRecordStruct *);
100 struct RaSrvSignature *RaValidateService(struct ArgusParserStruct *, struct ArgusRecordStruct *);
101 
102 int ArgusNodesAreEqual (struct RaAddressStruct *, struct RaAddressStruct *);
103 void ArgusUpdateNode (struct RaAddressStruct *, struct RaAddressStruct *);
104 
105 struct RaSrvSignature *RaBestGuess = NULL;
106 int RaBestGuessScore = 0;
107 
108 
109 int RaPrintLabelTreeLevel = 1000000;
110 int RaPrintLabelTreeDebug = 0;
111 
112 #define RALABEL_RCITEMS                         24
113 
114 #define RALABEL_IANA_ADDRESS                    0
115 #define RALABEL_IANA_ADDRESS_FILE               1
116 #define RALABEL_IEEE_ADDRESS                    2
117 #define RALABEL_IEEE_ADDRESS_FILE               3
118 #define RALABEL_ARIN_COUNTRY_CODES              4
119 #define RA_DELEGATED_IP                         5
120 #define RALABEL_BIND_NAME                       6
121 #define RA_PRINT_DOMAINONLY                     7
122 #define RALABEL_IANA_PORT                       8
123 #define RALABEL_IANA_PORT_FILE                  9
124 #define RALABEL_ARGUS_FLOW                      10
125 #define RALABEL_ARGUS_FLOW_FILE                 11
126 #define RALABEL_GEOIP_ASN                       12
127 #define RALABEL_GEOIP_ASN_FILE                  13
128 #define RALABEL_GEOIP_V4_ASN_FILE               14
129 #define RALABEL_GEOIP_V6_ASN_FILE               15
130 #define RALABEL_GEOIP_CITY                      16
131 #define RALABEL_GEOIP_CITY_FILE                 17
132 #define RALABEL_GEOIP_V4_CITY_FILE              18
133 #define RALABEL_GEOIP_V6_CITY_FILE              19
134 #define RALABEL_PRINT_DOMAINONLY		20
135 #define RALABEL_PRINT_LOCALONLY			21
136 #define RALABEL_BIND_NON_BLOCKING		22
137 #define RALABEL_DNS_NAME_CACHE_TIMEOUT		23
138 
139 char *RaLabelResourceFileStr [] = {
140    "RALABEL_IANA_ADDRESS=",
141    "RALABEL_IANA_ADDRESS_FILE=",
142    "RALABEL_IEEE_ADDRESS=",
143    "RALABEL_IEEE_ADDRESS_FILE=",
144    "RALABEL_ARIN_COUNTRY_CODES=",
145    "RA_DELEGATED_IP=",
146    "RALABEL_BIND_NAME=",
147    "RA_PRINT_DOMAINONLY=",
148    "RALABEL_IANA_PORT=",
149    "RALABEL_IANA_PORT_FILE=",
150    "RALABEL_ARGUS_FLOW=",
151    "RALABEL_ARGUS_FLOW_FILE=",
152    "RALABEL_GEOIP_ASN=",
153    "RALABEL_GEOIP_ASN_FILE=",
154    "RALABEL_GEOIP_V4_ASN_FILE=",
155    "RALABEL_GEOIP_V6_ASN_FILE=",
156    "RALABEL_GEOIP_CITY=",
157    "RALABEL_GEOIP_CITY_FILE=",
158    "RALABEL_GEOIP_V4_CITY_FILE=",
159    "RALABEL_GEOIP_V6_CITY_FILE=",
160    "RALABEL_PRINT_DOMAINONLY=",
161    "RALABEL_PRINT_LOCALONLY=",
162    "RALABEL_BIND_NON_BLOCKING=",
163    "RALABEL_DNS_NAME_CACHE_TIMEOUT=",
164 };
165 
166 
167 
168 int
RaLabelParseResourceFile(struct ArgusParserStruct * parser,struct ArgusLabelerStruct * labeler,char * file)169 RaLabelParseResourceFile (struct ArgusParserStruct *parser, struct ArgusLabelerStruct *labeler, char *file)
170 {
171    int retn = 1, i, len, found = 0, lines = 0;
172    char strbuf[MAXSTRLEN], *str = strbuf, *optarg = NULL;
173    FILE *fd = NULL;
174 
175    if (file) {
176       if ((fd = fopen (file, "r")) != NULL) {
177          retn = 0;
178          while ((fgets(str, MAXSTRLEN, fd)) != NULL)  {
179             lines++;
180             while (*str && isspace((int)*str))
181                 str++;
182 
183             if (*str && (*str != '#') && (*str != '\n') && (*str != '!')) {
184                found = 0;
185                for (i = 0; i < RALABEL_RCITEMS; i++) {
186                   len = strlen(RaLabelResourceFileStr[i]);
187                   if (!(strncmp (str, RaLabelResourceFileStr[i], len))) {
188 
189                      optarg = &str[len];
190 
191                      if (optarg[strlen(optarg) - 1] == '\n')
192                         optarg[strlen(optarg) - 1] = '\0';
193 
194                      if (*optarg == '\"')
195                         optarg++;
196 
197                      if (optarg[strlen(optarg) - 1] == '\"')
198                         optarg[strlen(optarg) - 1] = '\0';
199 
200                      if (*optarg == '\0')
201                         optarg = NULL;
202 
203                      if (optarg) {
204                         switch (i) {
205                            case RALABEL_IANA_ADDRESS:
206                               if (!(strncasecmp(optarg, "yes", 3)))
207                                  labeler->RaLabelIanaAddress = 1;
208                               else
209                                  labeler->RaLabelIanaAddress = 0;
210                               break;
211 
212                            case RALABEL_IANA_ADDRESS_FILE:
213                               if (!(RaReadAddressConfig (parser, parser->ArgusLabeler, optarg) > 0))
214                                  ArgusLog (LOG_ERR, "RaLabelParseResourceFile: RaReadAddressConfig error");
215                               break;
216 
217                            case RALABEL_IEEE_ADDRESS:
218                               if (!(strncasecmp(optarg, "yes", 3)))
219                                  labeler->RaLabelIeeeAddress = 1;
220                               else
221                                  labeler->RaLabelIeeeAddress = 0;
222                               break;
223 
224                            case RALABEL_IEEE_ADDRESS_FILE:
225                               if (!(RaReadIeeeAddressConfig (parser, parser->ArgusLabeler, optarg) > 0))
226                                  ArgusLog (LOG_ERR, "RaLabelParseResourceFile: RaReadIeeeAddressConfig error");
227                               break;
228 
229                            case RALABEL_ARIN_COUNTRY_CODES:
230                               if (!(strncasecmp(optarg, "yes", 3)))
231                                  labeler->RaLabelCountryCode = 1;
232                               else
233                                  labeler->RaLabelCountryCode = 0;
234                               break;
235 
236                            case RA_DELEGATED_IP:
237                               if (!(RaReadAddressConfig (parser, parser->ArgusLabeler, optarg) > 0))
238                                  ArgusLog (LOG_ERR, "RaLabelParseResourceFile: RaReadAddressConfig error");
239                               break;
240 
241 
242                            case RALABEL_BIND_NAME:
243                               if (!(strncasecmp(optarg, "yes", 3))) labeler->RaLabelBindName = ARGUS_ADDR_MASK; else
244                               if (!(strncasecmp(optarg, "all", 3))) labeler->RaLabelBindName = ARGUS_ADDR_MASK; else
245                               if (!(strncasecmp(optarg, "saddr", 5))) labeler->RaLabelBindName = ARGUS_SRC_ADDR; else
246                               if (!(strncasecmp(optarg, "daddr", 5))) labeler->RaLabelBindName = ARGUS_DST_ADDR; else
247                               if (!(strncasecmp(optarg, "inode", 5))) labeler->RaLabelBindName = ARGUS_INODE_ADDR;
248 
249                               if (labeler->RaLabelBindName) {
250                                  parser->nflag = 0;
251 #if defined(ARGUS_THREADS)
252                                  if (ArgusParser->NonBlockingDNS) {
253                                     extern void *ArgusDNSProcess (void *);
254                                     if (ArgusParser->ArgusNameList == NULL) {
255                                        pthread_attr_t attrbuf, *attr = &attrbuf;
256 
257                                        pthread_attr_init(attr);
258                                        pthread_attr_setdetachstate(attr, PTHREAD_CREATE_JOINABLE);
259 
260                                        if (getuid() == 0)
261                                           pthread_attr_setschedpolicy(attr, SCHED_RR);
262                                        else
263                                           attr = NULL;
264 
265                                        ArgusParser->ArgusNameList = ArgusNewList();
266                                        if ((pthread_create(&ArgusParser->dns, attr, ArgusDNSProcess, NULL)) != 0)
267                                           ArgusLog (LOG_ERR, "ArgusGetName() pthread_create error %s\n", strerror(errno));
268                                     }
269                                  }
270 #endif
271                               } else
272                                  labeler->RaLabelBindName = 0;
273                               break;
274 
275                            case RALABEL_PRINT_DOMAINONLY:
276                               if (!(strncasecmp(optarg, "yes", 3)))
277                                  parser->domainonly = 1;
278                               else
279                                  parser->domainonly = 0;
280                               break;
281 
282                            case RALABEL_PRINT_LOCALONLY:
283                               if (!(strncasecmp(optarg, "yes", 3)))
284                                  ++parser->fflag;
285                               else
286                                  parser->fflag = 0;
287                               break;
288 
289                            case RALABEL_BIND_NON_BLOCKING:
290                               break;
291 
292                            case RALABEL_DNS_NAME_CACHE_TIMEOUT:
293                               if (isdigit((int)*optarg))
294                                  parser->RaDNSNameCacheTimeout = (int)strtol(optarg, NULL, 10);
295                               break;
296 
297                            case RALABEL_IANA_PORT:
298                               if (!(strncasecmp(optarg, "yes", 3))) {
299                                  labeler->RaLabelIanaPort = 1;
300                               } else {
301                                  labeler->RaLabelIanaPort = 0;
302                               }
303                               break;
304 
305                            case RALABEL_IANA_PORT_FILE:
306                               if (RaReadPortConfig (parser, parser->ArgusLabeler, optarg) != 0)
307                                  ArgusLog (LOG_ERR, "RaLabelParseResourceFile: RaReadPortConfig error");
308                               break;
309 
310                            case RALABEL_ARGUS_FLOW:
311                               if (!(strncasecmp(optarg, "yes", 3))) {
312                                  labeler->RaLabelArgusFlow = 1;
313                               } else {
314                                  labeler->RaLabelArgusFlow = 0;
315                               }
316                               break;
317 
318                            case RALABEL_ARGUS_FLOW_FILE:
319                               if (RaReadFlowLabels (parser, parser->ArgusLabeler, optarg) != 0)
320                                  ArgusLog (LOG_ERR, "RaLabelParseResourceFile: RaReadFlowLabels error");
321                               break;
322 #if defined(ARGUS_GEOIP)
323                            case RALABEL_GEOIP_ASN:
324                               if (!(strncasecmp(optarg, "yes", 3))) {
325                                  labeler->RaLabelGeoIPAsn = 1;
326                               } else {
327                                  labeler->RaLabelGeoIPAsn = 0;
328                               }
329                               break;
330 
331                            case RALABEL_GEOIP_ASN_FILE:
332                            case RALABEL_GEOIP_V4_ASN_FILE:
333                               if ((parser->ArgusLabeler->RaGeoIPv4AsnObject = GeoIP_open (optarg, GEOIP_INDEX_CACHE)) == NULL)
334                                  ArgusLog (LOG_ERR, "RaLabelParseResourceFile: RaReadGeoIPAsn database error");
335                               break;
336 
337                            case RALABEL_GEOIP_V6_ASN_FILE:
338                               if ((parser->ArgusLabeler->RaGeoIPv6AsnObject = GeoIP_open (optarg, GEOIP_INDEX_CACHE)) == NULL)
339                                  ArgusLog (LOG_ERR, "RaLabelParseResourceFile: RaReadGeoIPAsn database error");
340                               break;
341 
342                            case RALABEL_GEOIP_CITY: {
343                               if (!(strncasecmp(optarg, "no", 2))) {
344                                  labeler->RaLabelGeoIPCity = 0;
345                               } else {
346                                  char *sptr, *fptr, *tptr;
347                                  int ind = 0, x;
348 
349                                  bzero(parser->ArgusLabeler->RaLabelGeoIPCityLabels, sizeof(parser->ArgusLabeler->RaLabelGeoIPCityLabels));
350 
351                                  if ((tptr = strchr(optarg, ':')) != NULL) {
352                                     *tptr++ = '\0';
353 
354                                     while ((fptr = strtok(optarg, ",")) != NULL) {
355                                        if (!strncmp(fptr, "*", 1))     parser->ArgusLabeler->RaLabelGeoIPCity |= ARGUS_ADDR_MASK; else
356                                        if (!strncmp(fptr, "saddr", 5)) parser->ArgusLabeler->RaLabelGeoIPCity |= ARGUS_SRC_ADDR; else
357                                        if (!strncmp(fptr, "daddr", 5)) parser->ArgusLabeler->RaLabelGeoIPCity |= ARGUS_DST_ADDR; else
358                                        if (!strncmp(fptr, "inode", 5)) parser->ArgusLabeler->RaLabelGeoIPCity |= ARGUS_INODE_ADDR;
359                                        optarg = NULL;
360                                     }
361                                  } else
362                                     parser->ArgusLabeler->RaLabelGeoIPCity |= ARGUS_ADDR_MASK;
363 
364                                  while ((sptr = strtok(tptr, ",")) != NULL) {
365                                     for (x = 1; x < ARGUS_GEOIP_TOTAL_OBJECTS; x++) {
366                                        if (!(strncmp(sptr, ArgusGeoIPCityObjects[x].field, ArgusGeoIPCityObjects[x].length))) {
367                                           parser->ArgusLabeler->RaLabelGeoIPCityLabels[ind] = ArgusGeoIPCityObjects[x].value;
368                                           ind++;
369                                           break;
370                                        }
371                                     }
372                                     tptr = NULL;
373                                  }
374                               }
375                               break;
376                            }
377 
378                            case RALABEL_GEOIP_CITY_FILE:
379                            case RALABEL_GEOIP_V4_CITY_FILE:
380                               if ((parser->ArgusLabeler->RaGeoIPv4CityObject = GeoIP_open( optarg, GEOIP_INDEX_CACHE)) == NULL)
381                                  ArgusLog (LOG_ERR, "RaLabelParseResourceFile: RaReadGeoIPAsn database error");
382                               break;
383 
384                            case RALABEL_GEOIP_V6_CITY_FILE:
385                               if ((parser->ArgusLabeler->RaGeoIPv6CityObject = GeoIP_open( optarg, GEOIP_INDEX_CACHE)) == NULL)
386                                  ArgusLog (LOG_ERR, "RaLabelParseResourceFile: RaReadGeoIPAsn database error");
387                               break;
388 #endif
389                            default:
390                               break;
391                         }
392                      }
393                      found++;
394                      break;
395                   }
396                }
397                if (!found) {
398                   ArgusLog (LOG_ERR, "%s: syntax error line %d\n", file, lines);
399                }
400             }
401          }
402 
403          fclose(fd);
404 
405       } else {
406 #ifdef ARGUSDEBUG
407          ArgusDebug (2, "%s: %s\n", file, strerror(errno));
408 #endif
409       }
410    }
411 
412 #ifdef ARGUSDEBUG
413    ArgusDebug (1, "RaLabelParseResourceFile (%s) returning %d\n", file, retn);
414 #endif
415 
416    return (retn);
417 }
418 
419 #if defined(ARGUS_GEOIP)
420 int ArgusPrintGeoIPRecord (struct ArgusParserStruct *, GeoIPRecord *, char *, int, int, char*);
421 
422 int
ArgusPrintGeoIPRecord(struct ArgusParserStruct * parser,GeoIPRecord * gir,char * label,int len,int found,char * prefix)423 ArgusPrintGeoIPRecord (struct ArgusParserStruct *parser, GeoIPRecord *gir, char *label, int len, int found, char *prefix)
424 {
425    int slen = strlen(label), x, tf = 0;
426 
427    if (found) {
428       snprintf (&label[slen], len - slen, ":");
429       slen++;
430    }
431 
432    snprintf (&label[slen], len - slen, "%s", prefix);
433    slen = strlen(label);
434 
435    for (x = 0; x < ARGUS_GEOIP_TOTAL_OBJECTS; x++) {
436       struct ArgusGeoIPCityObject *obj;
437       int ind;
438       if ((ind = parser->ArgusLabeler->RaLabelGeoIPCityLabels[x]) > 0) {
439          if (tf) {
440             snprintf (&label[slen], len - slen, "%c", ',');
441             slen++;
442          }
443          obj = &ArgusGeoIPCityObjects[ind];
444          switch (obj->value) {
445             case ARGUS_GEOIP_COUNTRY_CODE:
446                snprintf (&label[slen], len - slen, obj->format, gir->country_code);
447                break;
448             case ARGUS_GEOIP_COUNTRY_CODE_3:
449                snprintf (&label[slen], len - slen, obj->format, gir->country_code3);
450                break;
451             case ARGUS_GEOIP_COUNTRY_NAME:
452                snprintf (&label[slen], len - slen, obj->format, gir->country_name);
453                break;
454             case ARGUS_GEOIP_REGION:
455                snprintf (&label[slen], len - slen, obj->format, gir->region);
456                break;
457             case ARGUS_GEOIP_CITY_NAME:
458                snprintf (&label[slen], len - slen, obj->format, gir->city);
459                break;
460             case ARGUS_GEOIP_POSTAL_CODE:
461                snprintf (&label[slen], len - slen, obj->format, gir->postal_code);
462                break;
463             case ARGUS_GEOIP_LATITUDE:
464                snprintf (&label[slen], len - slen, obj->format, gir->latitude);
465                break;
466             case ARGUS_GEOIP_LONGITUDE:
467                snprintf (&label[slen], len - slen, obj->format, gir->longitude);
468                break;
469             case ARGUS_GEOIP_METRO_CODE:
470                snprintf (&label[slen], len - slen, obj->format, gir->metro_code);
471                break;
472             case ARGUS_GEOIP_AREA_CODE:
473                snprintf (&label[slen], len - slen, obj->format, gir->area_code);
474                break;
475             case ARGUS_GEOIP_CHARACTER_SET:
476                snprintf (&label[slen], len - slen, obj->format, gir->charset);
477                break;
478             case ARGUS_GEOIP_CONTINENT_CODE:
479                snprintf (&label[slen], len - slen, obj->format, gir->continent_code);
480                break;
481 //          case ARGUS_GEOIP_NETMASK:
482 //             snprintf (&label[slen], len - slen, obj->format, gir->netmask);
483 //             break;
484          }
485          slen = strlen(label);
486          tf++;
487 
488       } else
489          break;
490    }
491 
492    return found;
493 }
494 #endif
495 
496 
497 int
ArgusAddToRecordLabel(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus,char * tlabel)498 ArgusAddToRecordLabel (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus, char *tlabel)
499 {
500    struct ArgusLabelStruct *l1 = (void *) argus->dsrs[ARGUS_LABEL_INDEX], *l2;
501    char buf[MAXBUFFERLEN], *label = NULL;
502    int len = 0, retn = 0, tlen = strlen(tlabel);
503 
504    len = 4 * ((tlen + 3)/4);
505    if ((l2 = ArgusCalloc(1, sizeof(*l2))) == NULL)
506       ArgusLog (LOG_ERR, "RaProcessRecord: ArgusCalloc error %s", strerror(errno));
507 
508    if ((l2->l_un.label = calloc(1, len + 4)) == NULL)
509       ArgusLog (LOG_ERR, "RaProcessRecord: calloc error %s", strerror(errno));
510 
511    l2->hdr.type             = ARGUS_LABEL_DSR;
512    l2->hdr.argus_dsrvl8.len = 1 + ((len + 3)/4);
513    bcopy (tlabel, l2->l_un.label, tlen);
514 
515    bzero (buf, sizeof(buf));
516 
517    if ((label = ArgusMergeLabel(l1, l2, buf, MAXBUFFERLEN, ARGUS_UNION)) != NULL) {
518       if (l1 != NULL) {
519          int slen = strlen(label);
520          int len = 4 * ((slen + 3)/4);
521 
522          if (l1->l_un.label != NULL)
523             free(l1->l_un.label);
524 
525          if ((l1->l_un.label = calloc(1, len)) == NULL)
526             ArgusLog (LOG_ERR, "RaProcessRecord: calloc error %s", strerror(errno));
527 
528          l1->hdr.argus_dsrvl8.len = 1 + ((len + 3)/4);
529          bcopy (label, l1->l_un.label, slen);
530 
531          free(l2->l_un.label);
532          ArgusFree(l2);
533 
534       } else {
535          argus->dsrs[ARGUS_LABEL_INDEX] = (struct ArgusDSRHeader*) l2;
536          argus->dsrindex |= (0x1 << ARGUS_LABEL_INDEX);
537       }
538    }
539 
540 #ifdef ARGUSDEBUG
541    ArgusDebug (1, "ArgusAddToRecordLabel (%p, %p, %s) returning %d\n", parser, argus, tlabel, retn);
542 #endif
543 
544    return retn;
545 }
546 
547 
548 struct ArgusRecordStruct *
ArgusLabelRecord(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus)549 ArgusLabelRecord (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus)
550 {
551    struct ArgusLabelerStruct *labeler = parser->ArgusLabeler;
552    struct ArgusRecordStruct *retn = argus;
553    char label[MAXBUFFERLEN];
554    int found = 0, slen = 0;
555    char *rstr = NULL;
556 
557    if (labeler == NULL)
558       return (retn);
559 
560    bzero(label, sizeof(MAXBUFFERLEN));
561 
562    if (labeler->RaLabelIanaAddress) {
563       if ((rstr = RaAddressLabel (parser, argus)) != NULL) {
564          if (found) {
565             snprintf (&label[slen], MAXBUFFERLEN - slen, ":");
566             slen++;
567          }
568          snprintf (&label[slen], MAXBUFFERLEN - slen, "%s", rstr);
569          found++;
570       }
571    }
572 
573    if (labeler->RaLabelCountryCode)
574       RaCountryCodeLabel (parser, argus);
575 
576    if (labeler->RaLabelBindName) {
577       struct ArgusFlow *flow = (struct ArgusFlow *) argus->dsrs[ARGUS_FLOW_INDEX];
578 
579       if (flow != NULL) {
580          char *addrstr;
581 
582          switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
583             case ARGUS_TYPE_IPV4: {
584                if (labeler->RaLabelBindName & ARGUS_SRC_ADDR) {
585                   slen = strlen(label);
586                   if ((addrstr = ArgusGetName (parser, (unsigned char *)&flow->ip_flow.ip_src)) != NULL) {
587                      if (strcmp(addrstr, "not resolved")) {
588                         if (found) {
589                            snprintf (&label[slen], MAXBUFFERLEN - slen, ":");
590                            slen++;
591                         }
592                         snprintf (&label[slen], MAXBUFFERLEN - slen, "sname=%s", addrstr);
593                         found++;
594                      }
595                   }
596                }
597                if (labeler->RaLabelBindName & ARGUS_DST_ADDR) {
598                   slen = strlen(label);
599                   if ((addrstr = ArgusGetName (parser, (unsigned char *)&flow->ip_flow.ip_dst)) != NULL) {
600                      if (strcmp(addrstr, "not resolved")) {
601                         if (found) {
602                            snprintf (&label[slen], MAXBUFFERLEN - slen, ":");
603                            slen++;
604                         }
605                         snprintf (&label[slen], MAXBUFFERLEN - slen, "dname=%s", addrstr);
606                         found++;
607                      }
608                   }
609                }
610                if (labeler->RaLabelBindName & ARGUS_INODE_ADDR) {
611                   struct ArgusIcmpStruct *icmp = (void *)argus->dsrs[ARGUS_ICMP_INDEX];
612                   slen = strlen(label);
613                   if (icmp != NULL) {
614                      if (icmp->hdr.argus_dsrvl8.qual & ARGUS_ICMP_MAPPED) {
615                         if ((addrstr = ArgusGetName (parser, (unsigned char *)&icmp->osrcaddr)) != NULL) {
616                            if (strcmp(addrstr, "not resolved")) {
617                               if (found) {
618                                  snprintf (&label[slen], MAXBUFFERLEN - slen, ":");
619                                  slen++;
620                               }
621                               snprintf (&label[slen], MAXBUFFERLEN - slen, "iname=%s", addrstr);
622                               found++;
623                            }
624                         }
625                      }
626                   }
627                }
628                break;
629             }
630             case ARGUS_TYPE_IPV6: {
631                 break;
632             }
633          }
634       }
635    }
636 
637    if (labeler->RaLabelIanaPort) {
638       char buf[MAXSTRLEN];
639       if ((rstr = RaPortLabel (parser, argus, buf, MAXSTRLEN)) != NULL) {
640          if (strlen(rstr)) {
641             slen = strlen(label);
642             if (found) {
643                snprintf (&label[slen], MAXBUFFERLEN - slen, ":");
644                slen++;
645             }
646             snprintf (&label[slen], MAXBUFFERLEN - slen, "%s", rstr);
647             found++;
648          }
649       }
650    }
651 
652    if (labeler->RaLabelArgusFlow) {
653       char buf[MAXSTRLEN];
654       if ((rstr = RaFlowLabel (parser, argus, buf, MAXSTRLEN)) != NULL) {
655          if (strlen(rstr)) {
656             slen = strlen(label);
657             if (found) {
658                snprintf (&label[slen], MAXBUFFERLEN - slen, ":");
659                slen++;
660             }
661             snprintf (&label[slen], MAXBUFFERLEN - slen, "%s", rstr);
662             found++;
663          }
664       }
665    }
666 
667 #if defined(ARGUS_GEOIP)
668    if (labeler->RaLabelGeoIPAsn) {
669       if (labeler->RaGeoIPv4AsnObject != NULL) {
670          struct ArgusAsnStruct *asn = (struct ArgusAsnStruct *) argus->dsrs[ARGUS_ASN_INDEX];
671          struct ArgusFlow *flow = (struct ArgusFlow *) argus->dsrs[ARGUS_FLOW_INDEX];
672          struct ArgusIcmpStruct *icmp = (void *)argus->dsrs[ARGUS_ICMP_INDEX];
673 
674          if (asn == NULL) {
675             if ((asn = ArgusCalloc(1, sizeof(*asn))) == NULL)
676                ArgusLog (LOG_ERR, "RaProcessRecord: ArgusCalloc error %s", strerror(errno));
677 
678             asn->hdr.type              = ARGUS_ASN_DSR;
679             asn->hdr.subtype           = ARGUS_ASN_ORIGIN;
680             asn->hdr.argus_dsrvl8.qual = 0;
681             asn->hdr.argus_dsrvl8.len  = 3;
682 
683             argus->dsrs[ARGUS_ASN_INDEX] = (struct ArgusDSRHeader*) asn;
684             argus->dsrindex |= (0x01 << ARGUS_ASN_INDEX);
685          }
686 
687          if (flow != NULL) {
688             switch (flow->hdr.subtype & 0x3F) {
689                case ARGUS_FLOW_CLASSIC5TUPLE:
690                case ARGUS_FLOW_LAYER_3_MATRIX: {
691                   switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
692                      case ARGUS_TYPE_IPV4: {
693                         if (asn->src_as == 0) {
694                            if ((rstr = GeoIP_org_by_ipnum (labeler->RaGeoIPv4AsnObject, flow->ip_flow.ip_src)) != NULL) {
695                               if (strlen(rstr)) {
696                                  int result = 0;
697                                  if (sscanf(rstr, "AS%d", &result) == 1)
698                                     asn->src_as = result;
699                               }
700                               free(rstr);
701                            }
702                         }
703 
704                         if (asn->dst_as == 0) {
705                            if ((rstr = GeoIP_org_by_ipnum (labeler->RaGeoIPv4AsnObject, flow->ip_flow.ip_dst)) != NULL) {
706                               if (strlen(rstr)) {
707                                  int result = 0;
708                                  if (sscanf(rstr, "AS%d", &result) == 1)
709                                     asn->dst_as = result;
710                               }
711                               free(rstr);
712                            }
713                         }
714 
715                         if (asn->inode_as == 0) {
716                            if (icmp != NULL) {
717                               if (icmp->hdr.argus_dsrvl8.qual & ARGUS_ICMP_MAPPED) {
718                                  if ((rstr = GeoIP_org_by_ipnum (labeler->RaGeoIPv4AsnObject, icmp->osrcaddr)) != NULL) {
719                                     if (strlen(rstr)) {
720                                        int result = 0;
721                                        if (sscanf(rstr, "AS%d", &result) == 1)
722                                           asn->inode_as = result;
723 
724                                        asn->hdr.argus_dsrvl8.len  = 4;
725                                     }
726                                     free(rstr);
727                                  }
728                               }
729                            }
730                         }
731                         break;
732                      }
733 
734                      case ARGUS_TYPE_IPV6: {
735                         if (labeler->RaGeoIPv6AsnObject) {
736                            if (asn->src_as == 0) {
737                               struct in6_addr saddr;
738 
739                               bcopy(flow->ipv6_flow.ip_src, saddr.s6_addr, sizeof(saddr));
740 
741                               if ((rstr = GeoIP_org_by_ipnum_v6 (labeler->RaGeoIPv6AsnObject, saddr)) != NULL) {
742                                  if (strlen(rstr)) {
743                                     int result = 0;
744                                     if (sscanf(rstr, "AS%d", &result) == 1)
745                                        asn->src_as = result;
746                                  }
747                                  free(rstr);
748                               }
749                            }
750 
751                            if (asn->dst_as == 0) {
752                               struct in6_addr daddr;
753 
754                               bcopy(flow->ipv6_flow.ip_dst, daddr.s6_addr, sizeof(daddr));
755 
756                               if ((rstr = GeoIP_org_by_ipnum_v6 (labeler->RaGeoIPv6AsnObject, daddr)) != NULL) {
757                                  if (strlen(rstr)) {
758                                     int result = 0;
759                                     if (sscanf(rstr, "AS%d", &result) == 1)
760                                        asn->dst_as = result;
761                                  }
762                                  free(rstr);
763                               }
764                            }
765                         }
766                         break;
767                      }
768                   }
769                   break;
770                }
771             }
772          }
773       }
774    }
775 
776    if (labeler->RaLabelGeoIPCity) {
777       if (labeler->RaGeoIPv4CityObject != NULL) {
778          struct ArgusFlow *flow = (struct ArgusFlow *) argus->dsrs[ARGUS_FLOW_INDEX];
779          GeoIPRecord *gir;
780 
781          if (flow != NULL) {
782             switch (flow->hdr.subtype & 0x3F) {
783                case ARGUS_FLOW_CLASSIC5TUPLE:
784                case ARGUS_FLOW_LAYER_3_MATRIX: {
785                   switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
786                      case ARGUS_TYPE_IPV4: {
787                         if (labeler->RaLabelGeoIPCity & ARGUS_SRC_ADDR)
788                            if ((gir = GeoIP_record_by_ipnum (labeler->RaGeoIPv4CityObject, flow->ip_flow.ip_src)) != NULL) {
789                               ArgusPrintGeoIPRecord(parser, gir, label, sizeof(label), found, "scity=");
790                               GeoIPRecord_delete(gir);
791                               found++;
792                            }
793 
794                         if (labeler->RaLabelGeoIPCity & ARGUS_DST_ADDR)
795                            if ((gir = GeoIP_record_by_ipnum (labeler->RaGeoIPv4CityObject, flow->ip_flow.ip_dst)) != NULL) {
796                               ArgusPrintGeoIPRecord(parser, gir, label, sizeof(label), found, "dcity=");
797                               GeoIPRecord_delete(gir);
798                               found++;
799                            }
800 
801                         if (labeler->RaLabelGeoIPCity & ARGUS_INODE_ADDR) {
802                            struct ArgusIcmpStruct *icmp = (void *)argus->dsrs[ARGUS_ICMP_INDEX];
803 
804                            if (icmp != NULL) {
805                               if (icmp->hdr.argus_dsrvl8.qual & ARGUS_ICMP_MAPPED) {
806                                  struct ArgusFlow *flow = (void *)argus->dsrs[ARGUS_FLOW_INDEX];
807 
808                                  if (flow != NULL) {
809                                     switch (flow->hdr.subtype & 0x3F) {
810                                        case ARGUS_FLOW_CLASSIC5TUPLE:
811                                        case ARGUS_FLOW_LAYER_3_MATRIX: {
812                                           switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
813                                              case ARGUS_TYPE_IPV4:
814                                                 if ((gir = GeoIP_record_by_ipnum (labeler->RaGeoIPv4CityObject, icmp->osrcaddr)) != NULL) {
815                                                    ArgusPrintGeoIPRecord(parser, gir, label, sizeof(label), found, "icity=");
816                                                    GeoIPRecord_delete(gir);
817                                                    found++;
818                                                 }
819                                                 break;
820 
821                                              case ARGUS_TYPE_IPV6:
822                                                 break;
823                                           }
824                                           break;
825                                        }
826 
827                                        default:
828                                           break;
829                                     }
830                                  }
831                               }
832                            }
833                         }
834                         break;
835                      }
836                      case ARGUS_TYPE_IPV6: {
837                         if (labeler->RaGeoIPv6CityObject != NULL) {
838                            if (labeler->RaLabelGeoIPCity & ARGUS_SRC_ADDR) {
839                               struct in6_addr saddr;
840                               bcopy(flow->ipv6_flow.ip_src, saddr.s6_addr, sizeof(saddr));
841 
842                               if ((gir = GeoIP_record_by_ipnum_v6 (labeler->RaGeoIPv6CityObject, saddr)) != NULL) {
843                                  ArgusPrintGeoIPRecord(parser, gir, label, sizeof(label), found, "scity=");
844                                  GeoIPRecord_delete(gir);
845                                  found++;
846                               }
847                            }
848 
849                            if (labeler->RaLabelGeoIPCity & ARGUS_DST_ADDR) {
850                               struct in6_addr daddr;
851                               bcopy(flow->ipv6_flow.ip_dst, daddr.s6_addr, sizeof(daddr));
852 
853                               if ((gir = GeoIP_record_by_ipnum_v6 (labeler->RaGeoIPv6CityObject, daddr)) != NULL) {
854                                  ArgusPrintGeoIPRecord(parser, gir, label, sizeof(label), found, "dcity=");
855                                  GeoIPRecord_delete(gir);
856                                  found++;
857                               }
858                            }
859                         }
860                         break;
861                      }
862                   }
863                }
864             }
865          }
866       }
867    }
868 #endif
869 
870    if (found)
871       ArgusAddToRecordLabel (parser, argus, label);
872 
873    return (retn);
874 }
875 
876 
877 #define ARGUS_RCITEMS    4
878 
879 #define ARGUS_RC_FILTER  0
880 #define ARGUS_RC_LABEL   1
881 #define ARGUS_RC_COLOR   2
882 #define ARGUS_RC_CONT    3
883 
884 char *ArgusFlowLabelFields[ARGUS_RCITEMS] = {
885    "filter", "label", "color", "cont",
886 };
887 
888 int
RaReadFlowLabels(struct ArgusParserStruct * parser,struct ArgusLabelerStruct * labeler,char * file)889 RaReadFlowLabels (struct ArgusParserStruct *parser, struct ArgusLabelerStruct *labeler, char *file)
890 {
891    char strbuf[MAXSTRLEN], *str = strbuf;
892    char *ptr, *end, *value, *filter;
893    char *label = NULL, *color = NULL;
894    int retn = 1, linenum = 0;
895    FILE *fd =  NULL;
896 
897    if (labeler != NULL) {
898       if (labeler->ArgusFlowQueue == NULL)
899          if ((labeler->ArgusFlowQueue = ArgusNewQueue()) == NULL)
900             ArgusLog (LOG_ERR, "RaReadAddressConfig: ArgusNewList error %s\n", strerror(errno));
901 
902       if ((fd = fopen (file, "r")) != NULL) {
903          while ((ptr = fgets (str, MAXSTRLEN, fd)) != NULL) {
904             linenum++;
905             while (isspace((int)*ptr)) ptr++;
906 
907             if (*str && (*str != '\n') && (*str != '!')) {
908                switch (*ptr) {
909                   case '#': {
910                      if (!strncmp((char *)&ptr[1], "include ", 8)) {
911                         char *sptr;
912                         if ((sptr = strtok(&ptr[9], " \t\n")) != NULL)
913                            RaReadFlowLabels (parser, labeler, sptr);
914                      }
915                      break;
916                   }
917 
918                   default: {
919                      int i, done = 0, tlines = 0, cont = 0, defined = 0;
920 
921                      while (!done) {
922                         for (i = 0; i < ARGUS_RCITEMS; i++) {
923                            if (!(strncmp(str, ArgusFlowLabelFields[i], strlen(ArgusFlowLabelFields[i])))) {
924                               ptr = str + strlen(ArgusFlowLabelFields[i]);
925                               while (*ptr && isspace((int)*ptr)) ptr++;
926 
927                               if (!(*ptr == '=') && (i != ARGUS_RC_CONT))
928                                  ArgusLog (LOG_ERR, "ArgusParseFlowLabeler: syntax error line %d %s", tlines, str);
929 
930                               ptr++;
931                               while (*ptr && isspace((int)*ptr)) ptr++;
932 
933                               switch (i) {
934                                  case ARGUS_RC_FILTER:
935                                  case ARGUS_RC_LABEL:
936                                  case ARGUS_RC_COLOR: {
937                                     if ((*ptr == '\"') || (*ptr =='\'')) {
938                                        char delim = *ptr;
939                                        ptr++;
940                                        end = ptr;
941                                        while (*end != delim) end++;
942                                        *end++ = '\0';
943                                        value = strdup(ptr);
944                                        ptr = end;
945                                     }
946                                     break;
947                                  }
948                               }
949 
950                               switch (i) {
951                                  case ARGUS_RC_FILTER: filter = value; break;
952                                  case ARGUS_RC_LABEL:  label  = value; break;
953                                  case ARGUS_RC_COLOR:  color  = value; break;
954                                  case ARGUS_RC_CONT: {
955                                    cont++;
956                                    done++;
957                                    break;
958                                  }
959                               }
960 
961                               while (*ptr && isspace((int)*ptr)) ptr++;
962                               str = ptr;
963                               defined++;
964                            }
965                         }
966 
967                         if (!(done || defined))
968                            ArgusLog (LOG_ERR, "ArgusParseAggregator: syntax error line %d: %s", tlines, str);
969 
970                         if (ptr && ((*ptr == '\n') || (*ptr == '\0')))
971                            done++;
972                      }
973 
974                      if (defined) {
975                         struct RaFlowLabelStruct *raflow = NULL;
976                         if ((raflow = (void *)ArgusCalloc(1, sizeof(*raflow))) != NULL) {
977                            if (filter != NULL) {
978                               raflow->filterstr = strdup(filter);
979                               if (ArgusFilterCompile (&raflow->filter, raflow->filterstr, ArgusParser->Oflag) < 0)
980                                  ArgusLog (LOG_ERR, "RaReadFlowLabels ArgusFilterCompile returned error");
981                            }
982 
983                            if (label != NULL)
984                               raflow->labelstr = strdup(label);
985 
986                            if (color != NULL)
987                               raflow->colorstr = strdup(color);
988 
989                            if (cont != 0)
990                               raflow->cont = 1;
991                         }
992                         ArgusAddToQueue(labeler->ArgusFlowQueue, &raflow->qhdr, ARGUS_LOCK);
993                      }
994                      retn = 0;
995                      break;
996                   }
997                }
998             }
999             str = strbuf;
1000          }
1001 
1002          fclose(fd);
1003 
1004       } else
1005          ArgusLog (LOG_ERR, "%s: %s", file, strerror(errno));
1006    }
1007 
1008 #ifdef ARGUSDEBUG
1009    ArgusDebug (1, "RaReadFlowLabels (0x%x, 0x%x, %s) returning %d\n", parser, labeler, file, retn);
1010 #endif
1011 
1012    return (retn);
1013 }
1014 
1015 
1016 struct RaAddressStruct *RaFindAddress (struct ArgusParserStruct *, struct RaAddressStruct *, struct RaAddressStruct *, int);
1017 struct RaAddressStruct *RaInsertAddress (struct ArgusParserStruct *, struct ArgusLabelerStruct *, struct RaAddressStruct *, struct RaAddressStruct *, int);
1018 
1019 void RaInsertRIRTree (struct ArgusParserStruct *, struct ArgusLabelerStruct *labeler, char *);
1020 void RaInsertAddressTree (struct ArgusParserStruct *, struct ArgusLabelerStruct *labeler, char *);
1021 
1022 struct RaAddressStruct *
RaFindAddress(struct ArgusParserStruct * parser,struct RaAddressStruct * tree,struct RaAddressStruct * node,int mode)1023 RaFindAddress (struct ArgusParserStruct *parser, struct RaAddressStruct *tree, struct RaAddressStruct *node, int mode)
1024 {
1025    struct RaAddressStruct *retn = NULL;
1026    int done = 0;
1027 
1028    while (tree && !done) {
1029      unsigned int mask, taddr, naddr;
1030 
1031       switch (tree->addr.type) {
1032          case AF_INET: {
1033             if (tree->addr.masklen > 0)
1034                mask = 0xFFFFFFFF << (32 - tree->addr.masklen);
1035             else
1036                mask = 0;
1037 
1038             taddr = tree->addr.addr[0] & mask;
1039             naddr = node->addr.addr[0] & mask;
1040 
1041             if (taddr == naddr) {
1042                switch (mode) {
1043                   case ARGUS_NODE_MATCH:
1044                      if ((tree->l == NULL) && (tree->r == NULL)) {
1045                         retn = tree;
1046                         done++;
1047                         break;
1048                      } else
1049                      if (tree->status & ARGUS_NODE) {
1050                         retn = tree;
1051                         done++;
1052                         break;
1053                      }
1054 
1055                   case ARGUS_EXACT_MATCH:
1056                      if (node->addr.masklen == tree->addr.masklen)
1057                         retn = tree;
1058                      else
1059                      if ((tree->l == NULL) && (tree->r == NULL)) {
1060                         retn = NULL;
1061 
1062                      } else {
1063                         if ((node->addr.addr[0] >> (32 - (tree->addr.masklen + 1))) & 0x01)
1064                           retn = RaFindAddress (parser, tree->l, node, mode);
1065                         else
1066                           retn = RaFindAddress (parser, tree->r, node, mode);
1067                      }
1068                      done++;
1069                      break;
1070 
1071                   case ARGUS_LONGEST_MATCH:
1072                      if ((node->addr.addr[0] >> (32 - (tree->addr.masklen + 1))) & 0x01) {
1073                         if ((retn = RaFindAddress (parser, tree->l, node, mode)) == NULL)
1074                            retn = tree;
1075                      } else {
1076                         if ((retn = RaFindAddress (parser, tree->r, node, mode)) == NULL)
1077                            retn = tree;
1078                      }
1079                      done++;
1080                      break;
1081 
1082                   case ARGUS_ANY_MATCH:
1083                      retn = tree;
1084                      done++;
1085                      break;
1086                }
1087 
1088             } else
1089                done++;
1090             break;
1091          }
1092 
1093          case AF_INET6: {
1094             done++;
1095             break;
1096          }
1097       }
1098    }
1099 
1100    return (retn);
1101 }
1102 
1103 
1104 int
ArgusNodesAreEqual(struct RaAddressStruct * tree,struct RaAddressStruct * node)1105 ArgusNodesAreEqual (struct RaAddressStruct *tree, struct RaAddressStruct *node)
1106 {
1107    int retn = 0;
1108    if (tree && node)
1109       retn = bcmp(&tree->addr, &node->addr, sizeof(tree->addr));
1110 
1111    return ((retn == 0) ? 1 : 0);
1112 }
1113 
1114 void
ArgusUpdateNode(struct RaAddressStruct * tree,struct RaAddressStruct * node)1115 ArgusUpdateNode (struct RaAddressStruct *tree, struct RaAddressStruct *node)
1116 {
1117    if (strlen(node->cco)) strncpy(tree->cco, node->cco, sizeof(tree->cco));
1118    if ((tree->label != NULL) && (node->label == NULL))
1119       node->label = strdup(tree->label);
1120 }
1121 
1122 
1123 struct RaAddressStruct *
RaInsertAddress(struct ArgusParserStruct * parser,struct ArgusLabelerStruct * labeler,struct RaAddressStruct * tree,struct RaAddressStruct * node,int status)1124 RaInsertAddress (struct ArgusParserStruct *parser, struct ArgusLabelerStruct *labeler, struct RaAddressStruct *tree, struct RaAddressStruct *node, int status)
1125 {
1126    struct RaAddressStruct **ArgusAddrTree = labeler->ArgusAddrTree;
1127    struct RaAddressStruct *retn  = NULL;
1128 
1129    if ((labeler == NULL) || (node == NULL))
1130       return (retn);
1131 
1132    if ((tree == NULL) && (ArgusAddrTree[node->addr.type] == NULL)) {
1133       ArgusAddrTree[node->addr.type] = node;
1134       node->status |= ARGUS_NODE | status;
1135       return (node);
1136    }
1137 
1138    if (tree == NULL) tree = ArgusAddrTree[node->addr.type];
1139 
1140 // OK, so we need to decend into the tree, and insert this record,
1141 // and any additional interior nodes, needed.
1142 // As long as the the new node, and the current nodes masked addrs
1143 // are equal, then we just needed to decend either left of right.
1144 
1145    if (ArgusNodesAreEqual(tree, node)) {
1146       ArgusUpdateNode(tree, node);
1147       tree->status |= status;
1148       return (NULL);
1149 
1150    } else {
1151       unsigned int taddr, naddr;
1152       unsigned int tmask, nmask;
1153 
1154       node->status |= status;
1155 
1156       switch (tree->addr.type) {
1157          case AF_INET: {
1158             tmask = tree->addr.mask[0];
1159             taddr = tree->addr.addr[0] & tmask;
1160             naddr = node->addr.addr[0] & tmask;
1161 
1162             if (naddr == taddr) {     // node and tree address are same, but may not be at right part in tree
1163                if (node->addr.masklen > tree->addr.masklen) {  // if node mask is longer, then we'll insert below, which side?
1164                   unsigned int naddr = 0;
1165                   int nmasklen = (32 - (tree->addr.masklen + 1));
1166 
1167                   if (nmasklen != 0)
1168                      naddr = node->addr.addr[0] >> nmasklen;
1169 
1170                   if (naddr & 0x01) {
1171                      if (tree->l == NULL) {
1172                         if (node->addr.masklen > 0) {
1173                            nmask = (0xFFFFFFFF << (32 - node->addr.masklen));
1174                            nmask &= (0xFFFFFFFF >> tree->addr.masklen);
1175                         } else
1176                            nmask = 0;
1177 
1178                         node->offset = tree->addr.masklen;
1179                         tree->l = node;
1180                         node->p = tree;
1181                         retn = node;
1182 
1183                      } else {
1184                         struct RaAddressStruct *lt = tree->l;
1185 
1186                         if (node->addr.masklen < lt->addr.masklen) {
1187                            int maskn = node->addr.masklen;
1188                            int i = tree->addr.masklen + 1;
1189 
1190                            for (; i < node->addr.masklen; i++) {
1191                               tmask = (0xFFFFFFFF << (32 - i));
1192                               taddr = lt->addr.addr[0] & tmask;
1193                               naddr = node->addr.addr[0] & tmask;
1194                               if (naddr != taddr)
1195                                  break;
1196                               maskn = i;
1197                            }
1198                            if (maskn == node->addr.masklen) {
1199                               tree->l = node;
1200                               node->p = tree;
1201                               return (RaInsertAddress (parser, labeler, tree->l, lt, status));
1202 
1203                            } else {
1204                               struct RaAddressStruct *addr = NULL;
1205 
1206                               if ((addr = (struct RaAddressStruct *) ArgusCalloc (1, sizeof(*addr))) == NULL)
1207                                  ArgusLog (LOG_ERR, "RaInsertAddress: ArgusCalloc error %s\n", strerror(errno));
1208 
1209                               bcopy ((char *)&node->addr, (char *)&addr->addr, sizeof(addr->addr));
1210                               addr->addr.masklen = maskn;
1211                               addr->offset = lt->offset;
1212                               addr->status = status;
1213 
1214                               if (addr->addr.masklen) {
1215                                  addr->addr.mask[0]  = (0xFFFFFFFF << (32 - addr->addr.masklen));
1216                                  addr->addr.addr[0] &= addr->addr.mask[0];
1217                               } else
1218                                  addr->addr.mask[0] = 0;
1219 
1220                               addr->addr.mask[0] &= addr->addr.mask[0] & (0xFFFFFFFF >> addr->offset);
1221                               tree->l = addr;
1222                               addr->p = tree;
1223 
1224                               RaInsertAddress (parser, labeler, tree->l, lt, status);
1225                               return (RaInsertAddress (parser, labeler, tree->l, node, status));
1226                            }
1227 
1228                         } else
1229                            return (RaInsertAddress (parser, labeler, tree->l, node, status));
1230                      }
1231 
1232                   } else {
1233                      if (tree->r == NULL) {
1234                         if (node->addr.masklen > 0) {
1235                            nmask  = (0xFFFFFFFF << (32 - node->addr.masklen));
1236                            nmask &= (0xFFFFFFFF >> tree->addr.masklen);
1237                         } else
1238                            nmask = 0;
1239 
1240                         node->offset = tree->addr.masklen;
1241 //                      node->addr.mask[0] = nmask;
1242                         tree->r = node;
1243                         node->p = tree;
1244                         retn = node;
1245 
1246                      } else {
1247                         struct RaAddressStruct *rt = tree->r;
1248 
1249                         if (node->addr.masklen < rt->addr.masklen) {
1250                            int maskn = node->addr.masklen;
1251                            int i = tree->addr.masklen + 1;
1252 
1253                            for (; i < node->addr.masklen; i++) {
1254                               tmask = (0xFFFFFFFF << (32 - i));
1255                               taddr = rt->addr.addr[0] & tmask;
1256                               naddr = node->addr.addr[0] & tmask;
1257                               if (naddr != taddr)
1258                                  break;
1259                               maskn = i;
1260                            }
1261                            if (maskn == node->addr.masklen) {
1262                               tree->r = node;
1263                               node->p = tree;
1264                               return (RaInsertAddress (parser, labeler, tree->r, rt, status));
1265 
1266                            } else {
1267                               struct RaAddressStruct *addr = NULL;
1268 
1269                               if ((addr = (struct RaAddressStruct *) ArgusCalloc (1, sizeof(*addr))) == NULL)
1270                                  ArgusLog (LOG_ERR, "RaInsertAddress: ArgusCalloc error %s\n", strerror(errno));
1271 
1272                               bcopy ((char *)&node->addr, (char *)&addr->addr, sizeof(addr->addr));
1273                               addr->addr.masklen = maskn;
1274                               addr->offset = rt->offset;
1275                               addr->status = status;
1276 
1277                               if (addr->addr.masklen) {
1278                                  addr->addr.mask[0]  = (0xFFFFFFFF << (32 - addr->addr.masklen));
1279                                  addr->addr.addr[0] &= addr->addr.mask[0];
1280                               } else
1281                                  addr->addr.mask[0] = 0;
1282 
1283                               addr->addr.mask[0] &= addr->addr.mask[0] & (0xFFFFFFFF >> addr->offset);
1284                               tree->r = addr;
1285                               addr->p = tree;
1286 
1287                               RaInsertAddress (parser, labeler, tree->r, rt, status);
1288                               return (RaInsertAddress (parser, labeler, tree->r, node, status));
1289                            }
1290 
1291                         } else
1292                            return (RaInsertAddress (parser, labeler, tree->r, node, status));
1293                      }
1294                   }
1295 
1296                } else {
1297                   struct RaAddressStruct *ptree = tree->p;
1298 
1299                   if ((32 - (node->addr.masklen + 1)) > 0)
1300                      naddr = tree->addr.addr[0] >> (32 - (node->addr.masklen + 1));
1301                   if (node->addr.masklen > 0)
1302                      nmask = (0xFFFFFFFF << (32 - node->addr.masklen));
1303                   else
1304                      nmask = 0;
1305 
1306                   if (naddr & 0x01) {
1307                      node->l = tree;
1308                      tree->p = node;
1309                   } else {
1310                      node->r = tree;
1311                      tree->p = node;
1312                   }
1313 
1314                   if (ptree != NULL) {
1315                      if (ptree->l == tree)
1316                         ptree->l = node;
1317                      else
1318                         ptree->r = node;
1319 
1320                      node->p = ptree;
1321 
1322                      if (ptree->addr.masklen < 32)
1323                         nmask &= nmask & (0xFFFFFFFF >> ptree->addr.masklen);
1324                      else
1325                         nmask = 0;
1326                      node->offset = ptree->addr.masklen;
1327 
1328                   } else {
1329                      ArgusAddrTree[node->addr.type] = node;
1330                      node->offset = 0;
1331                   }
1332 
1333                   node->addr.mask[0] = nmask;
1334                   tree->offset = node->addr.masklen;
1335 
1336                   if (32 - tree->addr.masklen)
1337                      tmask = (0xFFFFFFFF << (32 - tree->addr.masklen));
1338                   else
1339                      tmask = 0;
1340                   tmask &= tmask & (0xFFFFFFFF >> node->addr.masklen);
1341                   tree->addr.mask[0] = tmask;
1342                }
1343                retn = node;
1344 
1345             } else {
1346                struct RaAddressStruct *addr = NULL, *ptree = tree->p;
1347                unsigned int value;
1348                int i, len = (node->addr.masklen - tree->offset);
1349                int masklen = 0;
1350 
1351                if (tree->addr.masklen > 0)
1352                   tmask = (0xFFFFFFFF << (32 - tree->addr.masklen));
1353                else
1354                   tmask = 0;
1355 
1356                value = ~(taddr ^ naddr) & tmask;
1357                value = value << tree->offset;
1358 
1359                for (i = 0; i < len; i++) {
1360                   if (value & 0x80000000) {
1361                      masklen++;
1362                      value = value << 1;
1363                   } else
1364                      break;
1365                }
1366 
1367                if ((addr = (struct RaAddressStruct *) ArgusCalloc (1, sizeof(*addr))) == NULL)
1368                   ArgusLog (LOG_ERR, "RaInsertAddress: ArgusCalloc error %s\n", strerror(errno));
1369 
1370                bcopy ((char *)&node->addr, (char *)&addr->addr, sizeof(addr->addr));
1371                addr->offset = tree->offset;
1372                addr->status = status;
1373 
1374                if (ptree != NULL) {
1375                   addr->addr.masklen = ptree->addr.masklen + masklen;
1376                } else {
1377                   addr->addr.masklen = masklen;
1378                }
1379 
1380                if (addr->addr.masklen) {
1381                   addr->addr.mask[0]  = (0xFFFFFFFF << (32 - addr->addr.masklen));
1382                   addr->addr.addr[0] &= addr->addr.mask[0];
1383                } else
1384                   addr->addr.mask[0] = 0;
1385 
1386                addr->addr.mask[0] &= addr->addr.mask[0] & (0xFFFFFFFF >> addr->offset);
1387 
1388                tree->offset += masklen;
1389 
1390                if (tree->addr.masklen)
1391                   tree->addr.mask[0] = (0xFFFFFFFF << (32 - tree->addr.masklen));
1392                else
1393                   tree->addr.mask[0] = 0;
1394 
1395                tree->addr.mask[0] &= tree->addr.mask[0] & (0xFFFFFFFF >> tree->offset);
1396 
1397                node->offset  = tree->offset;
1398                value = tree->addr.addr[0] >> (32 - (tree->offset + 1));
1399 
1400                if ((node->addr.addr[0] == addr->addr.addr[0]) &&
1401                    (node->addr.masklen == addr->addr.masklen)) {
1402                   ArgusFree(addr);
1403                   if (ptree) {
1404                      if (ptree->l == tree) {
1405                         ptree->l = node;
1406                         node->p = ptree;
1407                      } else {
1408                         ptree->r = node;
1409                         node->p = ptree;
1410                      }
1411                   } else {
1412                      ArgusAddrTree[tree->addr.type] = node;
1413                      node->offset = 0;
1414                   }
1415 
1416                   if (value & 0x01) {
1417                      node->l = tree;
1418                      tree->p = node;
1419                   } else {
1420                      node->r = tree;
1421                      tree->p = node;
1422                   }
1423                } else {
1424                   if (ptree) {
1425                      if (ptree->l == tree) {
1426                         ptree->l = addr;
1427                         addr->p = ptree;
1428                      } else {
1429                         ptree->r = addr;
1430                         addr->p = ptree;
1431                      }
1432                   } else {
1433                      ArgusAddrTree[tree->addr.type] = addr;
1434                      addr->offset = 0;
1435                   }
1436 
1437                   if (value & 0x01) {
1438                      addr->p = tree->p;
1439                      addr->l = tree;
1440                      addr->r = node;
1441                      tree->p = addr;
1442                      node->p = addr;
1443                   } else {
1444                      addr->p = tree->p;
1445                      addr->l = node;
1446                      addr->r = tree;
1447                      tree->p = addr;
1448                      node->p = addr;
1449                   }
1450                   if (tree->ns)
1451                      addr->ns = ArgusCopyRecordStruct(tree->ns);
1452                }
1453 
1454                if (node->addr.masklen > 0)
1455                   node->addr.mask[0] = (0xFFFFFFFF << (32 - node->addr.masklen));
1456 
1457                node->addr.mask[0] &= node->addr.mask[0] & (0xFFFFFFFF >> node->offset);
1458                retn = node;
1459             }
1460             break;
1461          }
1462 
1463          case AF_INET6: {
1464             retn = node;
1465             break;
1466          }
1467       }
1468 
1469       if (retn != NULL)
1470          retn->status |= status;
1471    }
1472 
1473 #ifdef ARGUSDEBUG
1474    ArgusDebug (4, "RaInsertAddress (0x%x, 0x%x, 0x%x, 0x%x) returning 0x%x\n", parser, ArgusAddrTree, node, status, retn);
1475 #endif
1476 
1477    return (retn);
1478 }
1479 
1480 void RaDeleteAddressTree(struct RaAddressStruct *);
1481 char *RaPruneAddressTree (struct ArgusLabelerStruct *, struct RaAddressStruct *);
1482 
1483 void
RaDeleteAddressTree(struct RaAddressStruct * node)1484 RaDeleteAddressTree(struct RaAddressStruct *node)
1485 {
1486    if (node->l) RaDeleteAddressTree(node->l);
1487    if (node->r) RaDeleteAddressTree(node->r);
1488 
1489    if (node->addr.str) { free(node->addr.str); node->addr.str = NULL;}
1490    if (node->str)   {free(node->str); node->str = NULL;}
1491    if (node->label) {free(node->label); node->label = NULL;}
1492    if (node->dns)   {free(node->dns); node->dns = NULL;}
1493    if (node->ns) {ArgusDeleteRecordStruct(ArgusParser, node->ns); node->ns = NULL;}
1494 
1495    ArgusFree(node);
1496 }
1497 
1498 char *
RaPruneAddressTree(struct ArgusLabelerStruct * labeler,struct RaAddressStruct * node)1499 RaPruneAddressTree (struct ArgusLabelerStruct *labeler, struct RaAddressStruct *node)
1500 {
1501    char *retn = NULL, *lstr = NULL, *rstr = NULL;
1502 
1503    if (node == NULL)
1504       return(NULL);
1505 
1506    if (node->l || node->r) {   // if we have sub-trees, grab the labels below.
1507       if ((lstr = RaPruneAddressTree(labeler, node->l)) != NULL) {
1508          if (node->addr.masklen != (node->l->addr.masklen - 1))
1509             lstr = NULL;
1510       }
1511 
1512       if ((rstr = RaPruneAddressTree(labeler, node->r)) != NULL) {
1513          if (node->addr.masklen != (node->r->addr.masklen - 1))
1514             rstr = NULL;
1515       }
1516 
1517       if (node->l && node->r) {
1518          if (lstr && rstr) {    // the idea here is to propagate up the label
1519                                 // so that if they are equal, then we can trim
1520                                 // the tree, by removing everything below.
1521             if (strlen(lstr) && strlen(rstr)) {
1522                if (!(strcmp(lstr, rstr))) {
1523                   retn = lstr;  // children are equal, so propagate up for comparison
1524                }
1525             }
1526          }
1527 
1528       } else {
1529          if (node->l && lstr)
1530             retn = lstr;
1531 
1532          if (node->r && rstr)
1533             retn = rstr;
1534       }
1535 
1536       if (retn && strlen(retn)) {              // there is a child label, so compare to current
1537          if (node->label) {
1538             if ((strcmp(node->label, retn)))   // if sub-tree labels aren't equal to current
1539                                                // then nothing to propagate up .... return NULL
1540                retn = NULL;
1541          } else {
1542             node->label = strdup(retn);        // so children are equal and node is not labeled, label it
1543             retn = node->label;
1544          }
1545       }
1546 
1547    } else                                      // if there are no children, then give back current label
1548       retn = node->label;
1549 
1550    if (retn != NULL) {                         // at this point, we can prune the tree.
1551       if (node->l) {
1552          RaDeleteAddressTree(node->l);
1553          node->l = NULL;
1554       }
1555       if (node->r) {
1556          RaDeleteAddressTree(node->r);
1557          node->r = NULL;
1558       }
1559    }
1560    return (retn);
1561 }
1562 
1563 
1564 struct ArgusCIDRAddr *ArgusGetCIDRList (struct ArgusCIDRAddr *, int *, int);
1565 
1566 struct ArgusCIDRAddr *
ArgusGetCIDRList(struct ArgusCIDRAddr * addr,int * elem,int type)1567 ArgusGetCIDRList (struct ArgusCIDRAddr *addr, int *elem, int type)
1568 {
1569    struct ArgusCIDRAddr *retn = NULL;
1570 
1571    if (*elem > 0) {
1572       double bvalue, value, lbval, l2;
1573       bvalue = *elem * 1.0;
1574       lbval = log(bvalue);
1575       l2 = log(2.0);
1576       l2 = lbval/l2;
1577 
1578       if ((value = floor(l2)) > 0) {  // compare this as a mask.
1579          long long eval = pow (2.0, value);
1580          int len, i;
1581 
1582          for (i = value; i > 0; i--) {
1583             uint32_t mask = (0xFFFFFFFF << i);
1584             if ((addr->addr[0] & mask) == addr->addr[0])
1585                break;
1586          }
1587 
1588          {
1589             struct ArgusCIDRAddr *cidr = NULL;
1590 
1591             if (i == value) {
1592                if ((cidr = ArgusCalloc(1, sizeof(*cidr))) == NULL)
1593                   ArgusLog (LOG_ERR, "ArgusGetCIDRList: ArgusCalloc error %s\n", strerror(errno));
1594 
1595                bcopy(addr, cidr, sizeof(*cidr));
1596 
1597                cidr->masklen = (32 - i);
1598                cidr->mask[0] = 0xFFFFFFFF << i;
1599 
1600                addr->addr[0] += eval;
1601                *elem -= eval;
1602                retn = cidr;
1603 
1604             } else {
1605                eval = pow (2.0, i);
1606                len = eval;
1607                retn = ArgusGetCIDRList (addr, &len, type);
1608                *elem -= (eval - len);
1609             }
1610          }
1611       }
1612    }
1613 
1614    return(retn);
1615 }
1616 
1617 void
RaInsertRIRTree(struct ArgusParserStruct * parser,struct ArgusLabelerStruct * labeler,char * str)1618 RaInsertRIRTree (struct ArgusParserStruct *parser, struct ArgusLabelerStruct *labeler, char *str)
1619 {
1620    struct RaAddressStruct *saddr = NULL, *node;
1621    char tstrbuf[MAXSTRLEN], *sptr = tstrbuf, *tptr;
1622    char *co = NULL, *type = NULL;
1623 // char *rir = NULL;
1624    char *addr, *endptr = NULL;
1625    int tok = 0, elem = -1, ttype = 0;
1626 
1627    if (labeler != NULL) {
1628       struct RaAddressStruct **ArgusAddrTree = labeler->ArgusAddrTree;
1629 
1630       snprintf (tstrbuf, MAXSTRLEN, "%s", str);
1631 
1632       while ((tptr = strtok(sptr, "|\n")) != NULL) {
1633          switch (tok++) {
1634             case 0:               break;
1635 //          case 0:  rir  = tptr; break;
1636             case 1:  co   = tptr; break;
1637             case 2:  type = tptr; break;
1638             case 3:  addr = tptr; break;
1639             case 4:
1640                if (isdigit((int)*tptr)) {
1641                   if ((elem = strtol(tptr, &endptr, 10)) == 0)
1642                      if (endptr == tptr)
1643                         usage();
1644                }
1645 
1646             case 5:  break;
1647             case 6:  break;
1648          }
1649 
1650          sptr = NULL;
1651       }
1652 
1653       if (!(strcmp("ipv4", type)))
1654          ttype = ARGUS_TYPE_IPV4;
1655       if (!(strcmp("ipv6", type)))
1656          ttype = ARGUS_TYPE_IPV6;
1657 
1658       if (ttype && (strcmp ("*", co))) {
1659          if ((co != NULL) && (addr != NULL)) {
1660             struct ArgusCIDRAddr *cidr = NULL, *ncidr;
1661 
1662             switch (ttype) {
1663                case ARGUS_TYPE_IPV4:
1664                case ARGUS_TYPE_IPV6: {
1665                   if ((cidr = RaParseCIDRAddr (parser, addr)) != NULL)
1666                      while ((ncidr = ArgusGetCIDRList (cidr, &elem, ttype)) != NULL) {
1667                         if ((saddr = (struct RaAddressStruct *) ArgusCalloc (1, sizeof(*saddr))) != NULL) {
1668                            bcopy ((char *)ncidr, (char *)&saddr->addr, sizeof (*ncidr));
1669                            if ((node = RaFindAddress (parser, ArgusAddrTree[saddr->addr.type], saddr, ARGUS_EXACT_MATCH)) == NULL) {
1670                               strncpy(saddr->cco, co, 4);
1671                               RaInsertAddress (parser, labeler, NULL, saddr, ARGUS_VISITED);
1672 
1673                            } else {
1674                               ArgusFree(saddr);
1675                               saddr = NULL;
1676                               strncpy(node->cco, co, 4);
1677                            }
1678                         }
1679                         ArgusFree(ncidr);
1680                      }
1681                }
1682             }
1683          }
1684       }
1685    }
1686 }
1687 
1688 
1689 #define ARGUS_PARSING_START_ADDRESS	0
1690 #define ARGUS_PARSING_END_ADDRESS	1
1691 #define ARGUS_PARSING_LABEL		2
1692 #define ARGUS_PARSING_DONE		3
1693 
1694 void
RaInsertAddressTree(struct ArgusParserStruct * parser,struct ArgusLabelerStruct * labeler,char * str)1695 RaInsertAddressTree (struct ArgusParserStruct *parser, struct ArgusLabelerStruct *labeler, char *str)
1696 {
1697    struct RaAddressStruct *saddr = NULL, *node;
1698    struct ArgusCIDRAddr *cidr, scidr, dcidr;
1699    char *sptr = NULL, *eptr = NULL, *ptr = NULL;
1700    char tstrbuf[MAXSTRLEN], *tptr = NULL, *label = NULL;
1701    long long i, step = 0, arange;
1702    unsigned int masklen = 32;
1703    double mstep = 0;
1704 
1705    if (labeler != NULL) {
1706       struct RaAddressStruct **ArgusAddrTree = labeler->ArgusAddrTree;
1707       int state = ARGUS_PARSING_START_ADDRESS;
1708 
1709       snprintf (tstrbuf, MAXSTRLEN, "%s", str);
1710       ptr = tstrbuf;
1711 
1712       while ((sptr = strtok(ptr, " \t\n\"")) != NULL) {
1713          switch (state) {
1714             case ARGUS_PARSING_START_ADDRESS: {
1715                if ((eptr = strchr(sptr, '-')) != NULL)
1716                   *eptr++ = '\0';
1717 
1718                if (sptr && ((cidr = RaParseCIDRAddr (parser, sptr)) != NULL))
1719                   bcopy ((char *)cidr, (char *)&scidr, sizeof (*cidr));
1720 
1721                if (eptr && ((cidr = RaParseCIDRAddr (parser, eptr)) != NULL))
1722                   bcopy ((char *)cidr, (char *)&dcidr, sizeof (*cidr));
1723                else
1724                   bcopy ((char *)&scidr, (char *)&dcidr, sizeof (scidr));
1725 
1726                state = ARGUS_PARSING_LABEL;
1727                break;
1728             }
1729 
1730             case ARGUS_PARSING_END_ADDRESS: {
1731                if (sptr && ((cidr = RaParseCIDRAddr (parser, sptr)) != NULL))
1732                   bcopy ((char *)cidr, (char *)&dcidr, sizeof (*cidr));
1733                state = ARGUS_PARSING_LABEL;
1734                break;
1735             }
1736 
1737             case ARGUS_PARSING_LABEL: {
1738                if (*sptr == '-')
1739                   state = ARGUS_PARSING_END_ADDRESS;
1740                else {
1741                   label = sptr;
1742                   state = ARGUS_PARSING_DONE;
1743                }
1744                break;
1745             }
1746 
1747             case ARGUS_PARSING_DONE:
1748                break;
1749          }
1750          ptr = NULL;
1751       }
1752 
1753 //  OK, so we've got the range of addresses to load up into the tree.
1754 //  Lets figure out a good starting point for the netmask.
1755 
1756       {
1757          int slen = 0, len = dcidr.addr[0] - scidr.addr[0];
1758 
1759          if (len > 0) {
1760             while ((len / 2) >= 2) {
1761                slen++;
1762                len = len >> 1;
1763             }
1764 
1765             while (slen && ((scidr.addr[0] & (0xFFFFFFFF << slen)) != scidr.addr[0]))
1766                slen--;
1767 
1768             masklen = 32 - slen;
1769          }
1770       }
1771 
1772       if (masklen < scidr.masklen) {
1773          scidr.masklen = masklen;
1774          scidr.mask[0] = 0xFFFFFFFF << (32 - masklen);
1775 
1776       }
1777 
1778       for (i = scidr.addr[0]; i <= dcidr.addr[0]; i += step) {
1779          struct RaAddressStruct *paddr = saddr;
1780 
1781          if ((saddr = (struct RaAddressStruct *) ArgusCalloc (1, sizeof(*saddr))) != NULL) {
1782             unsigned int taddr;
1783 
1784             if (paddr != NULL) {
1785                bcopy ((char *)&paddr->addr, (char *)&saddr->addr, sizeof (*cidr));
1786                saddr->addr.addr[0] = i;
1787 
1788                do {
1789                   arange  = dcidr.addr[0] - saddr->addr.addr[0];
1790                   arange -= (0xFFFFFFFF >> saddr->addr.masklen);
1791 
1792                   if (arange < 0) {
1793                      if (saddr->addr.masklen < dcidr.masklen)
1794                         saddr->addr.masklen++;
1795                      else {
1796                         arange = (dcidr.addr[0] - saddr->addr.addr[0]);
1797                         break;
1798                      }
1799                   }
1800                } while (arange < 0);
1801 
1802                taddr = saddr->addr.addr[0] + ((0xFFFFFFFF >> saddr->addr.masklen) + 1);
1803 
1804                if (taddr != (taddr & (0xFFFFFFFF << (32 - (saddr->addr.masklen - 1))))) {
1805                   int carry = dcidr.addr[0] - (saddr->addr.addr[0] + (0xFFFFFFFF >> (saddr->addr.masklen - 1)));
1806                   if ((carry > 0) && (arange >= carry)) {
1807                      saddr->addr.masklen--;
1808                      saddr->addr.mask[0] = 0xFFFFFFFF << (32 - saddr->addr.masklen);
1809                      saddr->addr.addr[0] &= saddr->addr.mask[0];
1810                   } else {
1811                      if (arange == 1) {
1812                      }
1813                   }
1814                }
1815 
1816             } else {
1817                bcopy ((char *)&scidr, (char *)&saddr->addr, sizeof (*cidr));
1818                saddr->addr.addr[0] = i;
1819             }
1820 
1821             if ((node = RaFindAddress (parser, ArgusAddrTree[saddr->addr.type], saddr, ARGUS_EXACT_MATCH)) == NULL) {
1822                if (tptr)
1823                   saddr->addr.str = strdup(tptr);
1824 
1825                RaInsertAddress (parser, labeler, NULL, saddr, ARGUS_VISITED);
1826 
1827                if (label) {
1828                   if (saddr->label != NULL) {
1829                      char sbuf[1024];
1830                      snprintf(sbuf, 1024, "%s,", saddr->label);
1831 #if HAVE_STRLCAT
1832                      strlcat(sbuf, label, 1024 - strlen(sbuf));
1833 #else
1834                      strncat(sbuf, label, 1024 - strlen(sbuf));
1835 #endif
1836                      free(saddr->label);
1837                      saddr->label = strdup(sbuf);
1838                   } else
1839                      saddr->label = strdup (label);
1840                }
1841 
1842                if (labeler->status & ARGUS_TREE_DEBUG_NODE) {
1843                   RaPrintLabelTree (labeler, labeler->ArgusAddrTree[AF_INET], 0, 0);
1844                   printf("\n");
1845                }
1846 
1847 
1848             } else {
1849                ArgusFree(saddr);
1850                saddr = node;
1851 
1852                if (label) {
1853                   if (node->label != NULL) {
1854                      char sbuf[1024];
1855                      snprintf(sbuf, 1024, "%s,", node->label);
1856 #if HAVE_STRLCAT
1857                      strlcat(sbuf, label, 1024 - strlen(sbuf));
1858 #else
1859                      strncat(sbuf, label, 1024 - strlen(sbuf));
1860 #endif
1861                      free(node->label);
1862                      node->label = strdup(sbuf);
1863                   } else
1864                      node->label = strdup (label);
1865                }
1866             }
1867          }
1868 
1869          mstep = pow (2.0, (32 - saddr->addr.masklen));
1870          step = mstep;
1871       }
1872    }
1873 }
1874 
1875 
1876 int RaReadAddressConfig (struct ArgusParserStruct *, struct ArgusLabelerStruct *, char *);
1877 
1878 int
RaReadAddressConfig(struct ArgusParserStruct * parser,struct ArgusLabelerStruct * labeler,char * file)1879 RaReadAddressConfig (struct ArgusParserStruct *parser, struct ArgusLabelerStruct *labeler, char *file)
1880 {
1881    char strbuf[MAXSTRLEN], *str = strbuf, *ptr;
1882    int retn = 1, linenum = 0;
1883    FILE *fd =  NULL;
1884 
1885    if (labeler != NULL) {
1886       if (labeler->ArgusAddrTree == NULL)
1887          if ((labeler->ArgusAddrTree = ArgusCalloc(128, sizeof(void *))) == NULL)
1888             ArgusLog (LOG_ERR, "RaReadAddressConfig: ArgusCalloc error %s\n", strerror(errno));
1889 
1890       if ((fd = fopen (file, "r")) != NULL) {
1891          while ((ptr = fgets (str, MAXSTRLEN, fd)) != NULL) {
1892             linenum++;
1893             while (isspace((int)*ptr)) ptr++;
1894             switch (*ptr) {
1895                case '#': {
1896                   if (!strncmp((char *)&ptr[1], "include ", 8)) {
1897                      char *sptr;
1898                      if ((sptr = strtok(&ptr[9], " \t\n")) != NULL)
1899                         RaReadAddressConfig (parser, labeler, sptr);
1900                   }
1901                   break;
1902                }
1903 
1904                default:
1905                   if (isdigit((int)*ptr)) {
1906                      RaInsertAddressTree (parser, labeler, ptr);
1907                   } else {
1908                      if (strchr(ptr, '|')) {
1909                         RaInsertRIRTree (parser, labeler, ptr);
1910                      }
1911                   }
1912                   break;
1913             }
1914          }
1915 
1916          fclose(fd);
1917 
1918       } else
1919          ArgusLog (LOG_ERR, "%s: %s", file, strerror(errno));
1920 
1921       if (labeler->prune)
1922          RaPruneAddressTree(labeler, labeler->ArgusAddrTree[AF_INET]);
1923    }
1924 
1925 #ifdef ARGUSDEBUG
1926    ArgusDebug (1, "RaReadAddressConfig (0x%x, 0x%x, %s) returning %d\n", parser, labeler, file, retn);
1927 #endif
1928 
1929    return (retn);
1930 }
1931 
1932 struct enamemem elabeltable[HASHNAMESIZE];
1933 extern struct enamemem *lookup_emem(struct enamemem *, const unsigned char *);
1934 
1935 int
RaReadIeeeAddressConfig(struct ArgusParserStruct * parser,struct ArgusLabelerStruct * labeler,char * file)1936 RaReadIeeeAddressConfig (struct ArgusParserStruct *parser, struct ArgusLabelerStruct *labeler, char *file)
1937 {
1938    int retn = 1;
1939    struct enamemem *tp;
1940    struct argus_etherent *ep;
1941    FILE *fp;
1942 
1943    /* Suck in entire ethers file */
1944    fp = fopen(PCAP_ETHERS_FILE, "r");
1945    if (fp != NULL) {
1946       while ((ep = argus_next_etherent(fp)) != NULL) {
1947          tp = lookup_emem(elabeltable, ep->addr);
1948          tp->e_name = savestr(ep->name);
1949       }
1950       (void)fclose(fp);
1951    }
1952 
1953 #ifdef ARGUSDEBUG
1954    ArgusDebug (1, "RaReadIeeeAddressConfig (0x%x, 0x%x, %s) returning %d\n", parser, labeler, file, retn);
1955 #endif
1956 
1957    return (retn);
1958 }
1959 
1960 
1961 
1962 struct RaPortStruct *RaParsePortEntry (struct ArgusParserStruct *, struct ArgusLabelerStruct *, char *);
1963 int RaReadPortConfig (struct ArgusParserStruct *, struct ArgusLabelerStruct *, char *);
1964 
1965 
1966 struct RaPortStruct ArgusPortBuf;
1967 
1968 /*
1969 dbbrowse        47557/tcp  Databeam Corporation
1970 */
1971 
1972 struct RaPortStruct *
RaParsePortEntry(struct ArgusParserStruct * parser,struct ArgusLabelerStruct * labeler,char * str)1973 RaParsePortEntry (struct ArgusParserStruct *parser, struct ArgusLabelerStruct *labeler, char *str)
1974 {
1975    struct RaPortStruct *retn = NULL;
1976    char *strend, *label = NULL, *port = NULL;
1977    char *proto = NULL, *desc = NULL, *ptr, *tmp;
1978    int error = 0, len = 0;
1979 
1980    len = strlen(str);
1981    strend = str + len;
1982 
1983    ptr = str;
1984    while  (!isspace(*ptr)) ptr++;
1985    *ptr++ = '\0';
1986    label = str;
1987    while  (isspace(*ptr)) ptr++;
1988    port = ptr;
1989    if ((proto = strchr (port, '/')) != NULL) {
1990       *proto++ = '\0';
1991       ptr = proto;
1992       while  (!isspace(*ptr)) ptr++;
1993       *ptr++ = '\0';
1994    }
1995 
1996    if (ptr < strend) {
1997       while (isspace(*ptr)) ptr++;
1998       desc = ptr;
1999       tmp = NULL;
2000       while (*ptr != '\n') {
2001          if (isspace(*ptr)) {
2002             if (tmp == NULL)
2003                tmp = ptr;
2004          } else
2005             tmp = NULL;
2006          ptr++;
2007       }
2008       if (tmp != NULL)
2009          *tmp = '\0';
2010       else
2011          *ptr = '\0';
2012    }
2013 
2014    if ((port == NULL) || (proto == NULL)) {
2015    } else {
2016       char *endptr;
2017 
2018       retn = &ArgusPortBuf;
2019       retn->proto = (strcmp (proto, "tcp")) ? 17 : 6;
2020 
2021       if (label != NULL)
2022          retn->label = label;
2023       if (desc != NULL)
2024          retn->desc = desc;
2025 
2026       retn->start = strtol(port, &endptr, 10);
2027       if ((endptr != NULL) && (endptr == port)) {
2028          error++;
2029       } else {
2030          if ((ptr = strchr(port, '-')) != NULL) {
2031             retn->end   = strtol(ptr + 1, &endptr, 10);
2032             if ((endptr != NULL) && (endptr == port))
2033                error++;
2034          } else {
2035             retn->end   = retn->start;
2036          }
2037       }
2038    }
2039 
2040    return(retn);
2041 }
2042 
2043 int
RaReadPortConfig(struct ArgusParserStruct * parser,struct ArgusLabelerStruct * labeler,char * file)2044 RaReadPortConfig (struct ArgusParserStruct *parser, struct ArgusLabelerStruct *labeler, char *file)
2045 {
2046    struct RaPortStruct *tp, *port, **array;
2047    int retn = 0, lines = 0;
2048    char buf[MAXSTRLEN], *str = buf;
2049    FILE *fd;
2050 
2051    if (file) {
2052       if ((fd = fopen (file, "r")) != NULL) {
2053          while ((fgets(str, MAXSTRLEN, fd)) != NULL)  {
2054             lines++;
2055             if (*str && (*str != '#') && (*str != '\n') && (*str != '!')) {
2056                if (strstr (str, "/udp") || strstr (str, "/tcp") || strstr (str, "/ddp")) {
2057                   if ((tp = RaParsePortEntry (parser, labeler, str)) != NULL) {
2058                      if ((port = ArgusCalloc(1, sizeof(*port))) == NULL)
2059                         ArgusLog (LOG_ERR, "RaReadPortConfig: ArgusCalloc error %s", strerror(errno));
2060 
2061                      bcopy ((char *)tp, (char *)port, sizeof(*tp));
2062                      if (tp->label != NULL)
2063                         port->label = strdup(tp->label);
2064                      if (tp->desc != NULL)
2065                         port->desc = strdup(tp->desc);
2066 
2067                      switch (port->proto) {
2068                         case IPPROTO_TCP: {
2069                            if ((array = labeler->ArgusTCPPortLabels) == NULL) {
2070                               if ((array = (void *) ArgusCalloc(1, 0x10000 * sizeof(port))) == NULL)
2071                                  ArgusLog (LOG_ERR, "RaReadPortConfig: ArgusCalloc error %s", strerror(errno));
2072                               labeler->ArgusTCPPortLabels = array;
2073                            }
2074                            break;
2075                         }
2076 
2077                         case IPPROTO_UDP: {
2078                            if ((array = labeler->ArgusUDPPortLabels) == NULL) {
2079                               if ((array = (void *) ArgusCalloc(1, 0x10000 * sizeof(port))) == NULL)
2080                                  ArgusLog (LOG_ERR, "RaReadPortConfig: ArgusCalloc error %s", strerror(errno));
2081                               labeler->ArgusUDPPortLabels = array;
2082                            }
2083                            break;
2084                         }
2085                      }
2086 
2087                      if (array != NULL) {
2088                         int i;
2089                         for (i = port->start; i <= port->end; i++) {
2090 /* so if there is already a port descriptor here, we'll add this label
2091    to any existing label, but replace the existing tp with the newly
2092    allocated port */
2093                            if ((tp = array[i]) != NULL) {
2094                               int found = 0;
2095                               char *plabel = port->label;
2096 
2097                               if (plabel && strlen(plabel)) {
2098                                  char *tlabel = tp->label;
2099                                  if (strlen(tlabel)) {
2100                                     char tbuf[MAXSTRLEN], *tok, *tptr = tbuf;
2101                                     snprintf (tbuf, MAXSTRLEN, "%s", tlabel);
2102                                     while (!found && ((tok = strtok (tptr, ":")) != NULL)) {
2103                                        if (!strcmp(tok, plabel))
2104                                           found++;
2105                                        tptr = NULL;
2106                                     }
2107 
2108                                     free(port->label);
2109 
2110                                     if (!found) {
2111                                        snprintf (tbuf, MAXSTRLEN, "%s", tlabel);
2112                                        sprintf(&tbuf[strlen(tbuf)], ":%s", plabel);
2113                                        port->label = strdup(tbuf);
2114                                     } else
2115                                        port->label = strdup(tlabel);
2116                                  }
2117                               }
2118                               if (tp->label != NULL)
2119                                  free (tp->label);
2120                               if (tp->desc != NULL)
2121                                  free (tp->desc);
2122                               ArgusFree (tp);
2123                            }
2124                            array[i] = port;
2125                         }
2126                      }
2127 
2128                   } else  {
2129                      ArgusLog (LOG_ERR, "RaReadPortConfig: syntax error line %d", lines);
2130                   }
2131                }
2132             }
2133          }
2134 
2135          fclose(fd);
2136 
2137       } else
2138          ArgusLog (LOG_ERR, "RaReadPortConfig: fopen error %s", strerror(errno));
2139    }
2140    return (retn);
2141 }
2142 
2143 
2144 struct ArgusLabelerStruct *
ArgusNewLabeler(struct ArgusParserStruct * parser,int status)2145 ArgusNewLabeler (struct ArgusParserStruct *parser, int status)
2146 {
2147    struct ArgusLabelerStruct *retn = NULL;
2148 
2149    if ((retn = (struct ArgusLabelerStruct *) ArgusCalloc (1, sizeof(*retn))) == NULL)
2150       ArgusLog (LOG_ERR, "ArgusNewLabeler: ArgusCalloc error %s", strerror(errno));
2151 
2152    if ((retn->drap = (struct RaPolicyStruct *) ArgusCalloc(1, sizeof(*retn->drap))) == NULL)
2153       ArgusLog (LOG_ERR, "ArgusNewLabeler: ArgusCalloc error %s", strerror(errno));
2154 
2155    if ((retn->queue = ArgusNewQueue()) == NULL)
2156       ArgusLog (LOG_ERR, "ArgusNewLabeler: ArgusNewQueue error %s", strerror(errno));
2157 
2158    if ((retn->htable.array = (struct ArgusHashTableHdr **) ArgusCalloc (RA_HASHTABLESIZE, sizeof(void *))) == NULL)
2159       ArgusLog (LOG_ERR, "ArgusNewLabeler: ArgusCalloc error %s", strerror(errno));
2160 
2161    retn->htable.size = RA_HASHTABLESIZE;
2162 
2163    retn->status = status;
2164 
2165    retn->RaPrintLabelTreeMode = ARGUS_TREE;
2166 
2167    if (status & ARGUS_LABELER_COCODE) {
2168       if (parser->ArgusDelegatedIPFile) {
2169          if (!(RaReadAddressConfig (parser, retn, parser->ArgusDelegatedIPFile) > 0))
2170             ArgusLog (LOG_ERR, "ArgusNewLabeler: RaReadAddressConfig error");
2171       }
2172    }
2173 
2174    if (status & ARGUS_LABELER_ADDRESS) {
2175       if (parser->ArgusFlowModelFile) {
2176          if (!(RaReadAddressConfig (parser, retn, parser->ArgusFlowModelFile) > 0))
2177             ArgusLog (LOG_ERR, "ArgusNewLabeler: RaReadAddressConfig error");
2178       }
2179    }
2180 
2181    retn->prune = 1;
2182 
2183 #ifdef ARGUSDEBUG
2184    ArgusDebug (1, "ArgusNewLabeler (%p, %d) returning %p\n", parser, status, retn);
2185 #endif
2186    return (retn);
2187 }
2188 
2189 void
ArgusDeleteLabeler(struct ArgusParserStruct * parser,struct ArgusLabelerStruct * labeler)2190 ArgusDeleteLabeler (struct ArgusParserStruct *parser, struct ArgusLabelerStruct *labeler)
2191 {
2192    if (labeler != NULL) {
2193       struct RaAddressStruct **ArgusAddrTree;
2194 
2195       if (labeler->drap !=  NULL)
2196          ArgusFree (labeler->drap);
2197 
2198       if (labeler->queue !=  NULL)
2199          ArgusDeleteQueue (labeler->queue);
2200 
2201       ArgusEmptyHashTable (&labeler->htable);
2202 
2203       if (labeler->htable.array != NULL)
2204          ArgusFree(labeler->htable.array);
2205 
2206       if ((ArgusAddrTree = labeler->ArgusAddrTree) != NULL) {
2207          if (labeler->ArgusAddrTree[AF_INET] != NULL)
2208             RaDeleteAddressTree (labeler->ArgusAddrTree[AF_INET]);
2209 
2210          ArgusFree(ArgusAddrTree);
2211       }
2212 
2213       ArgusFree(labeler);
2214    }
2215 #ifdef ARGUSDEBUG
2216    ArgusDebug (1, "ArgusDeleteLabeler (%p, %p) returning\n", parser, labeler);
2217 #endif
2218 }
2219 
2220 
2221 struct RaSrvSignature *RaCreateSrvEntry(struct ArgusLabelerStruct *, int, char *);
2222 
2223 struct RaSrvSignature *
RaCreateSrvEntry(struct ArgusLabelerStruct * labeler,int linenum,char * str)2224 RaCreateSrvEntry(struct ArgusLabelerStruct *labeler, int linenum, char *str)
2225 {
2226    struct RaSrvSignature *srv = NULL;
2227    char *ptr = NULL, *tmp, *dup;
2228 
2229    dup = strdup(str);
2230 
2231    if ((ptr = strstr (dup, "Service: ")) != NULL) {
2232       if ((srv = (void *) ArgusCalloc(1, sizeof(*srv))) != NULL) {
2233          ptr += strlen("Service: ");
2234          tmp = ptr;
2235          while (!isspace((int)*ptr)) ptr++;
2236          *ptr++ = '\0';
2237          srv->name = strdup(tmp);
2238          tmp = ptr;
2239 
2240          if ((tmp = strstr(ptr, "tcp port ")) != NULL) {
2241             tmp += strlen("tcp port ");
2242             srv->proto = IPPROTO_TCP;
2243             srv->port  = atoi(tmp);
2244          } else {
2245             if ((tmp = strstr(ptr, "udp port ")) != NULL) {
2246                tmp += strlen("udp port ");
2247                srv->proto = IPPROTO_UDP;
2248                srv->port  = atoi(tmp);
2249             }
2250          }
2251 
2252          if ((tmp = strstr(ptr, "n =")) != NULL) {
2253             tmp += strlen("n =") + 1;
2254             srv->count = atoi(tmp);
2255          }
2256 
2257          if (((tmp = strstr(ptr, "src = ")) == NULL) &&
2258              ((tmp = strstr(ptr, "dst = ")) == NULL)) {
2259             if ((tmp = strchr(ptr, '\"')) != NULL) {
2260                char nbuf[4], *nptr = nbuf, *ptmp, *endptr;
2261                int value, i, length;
2262 
2263                tmp++;
2264                if ((ptmp = strchr(tmp, '\"')) == NULL)
2265                   ArgusLog (LOG_ERR, "RaCreateSrvEntry: format error %s\n", ptr);
2266 
2267                *ptmp++ = '\0';
2268 
2269                length = ((strlen(tmp) > (RASIGLENGTH * 2)) ? RASIGLENGTH : strlen(tmp))/2;
2270                for (i = 0; i < length; i++) {
2271                   endptr = NULL;
2272                   bzero (nbuf, 4);
2273                   nbuf[0] = *tmp++;
2274                   nbuf[1] = *tmp++;
2275                   if (nbuf[0] == ' ') {
2276                      ((u_char *)&srv->srcmask)[i/8] |= (0x80 >> (i % 8));
2277                      value = 0;
2278                   } else {
2279                      value = strtol(nptr, &endptr, 16);
2280                      if ((endptr != NULL) && (endptr != (nptr + 2)))
2281                         ArgusLog (LOG_ERR, "RaCreateSrvEntry: format error %s\n", ptr);
2282                   }
2283                   srv->src[i] = (u_char) value;
2284                }
2285 
2286                for ( ; i < RASIGLENGTH; i++) {
2287                   ((u_char *)&srv->srcmask)[i/8] |= (0x80 >> (i % 8));
2288                }
2289                tmp++;
2290             }
2291 
2292             if ((tmp = strchr(tmp, '\"')) != NULL) {
2293                char nbuf[4], *nptr = nbuf, *ptmp, *endptr;
2294                int value, i, length;
2295 
2296                tmp++;
2297                if ((ptmp = strchr(tmp, '\"')) == NULL)
2298                   ArgusLog (LOG_ERR, "RaCreateSrvEntry: format error %s\n", ptr);
2299                else
2300                   *ptmp = '\0';
2301 
2302                length = ((strlen(tmp) > (RASIGLENGTH * 2)) ? RASIGLENGTH : strlen(tmp))/2;
2303                for (i = 0; i < length; i++) {
2304                   endptr = NULL;
2305                   bzero (nbuf, 4);
2306                   nbuf[0] = *tmp++;
2307                   nbuf[1] = *tmp++;
2308                   if (nbuf[0] == ' ') {
2309                      ((u_char *)&srv->dstmask)[i/8] |= (0x80 >> (i % 8));
2310                      value = 0;
2311                   } else {
2312                      value = strtol(nptr, &endptr, 16);
2313                      if ((endptr != NULL) && (endptr != (nptr + 2)))
2314                         ArgusLog (LOG_ERR, "RaCreateSrvEntry: format error %s\n", ptr);
2315                   }
2316                   srv->dst[i] = (u_char) value;
2317                }
2318 
2319                for ( ; i < RASIGLENGTH; i++) {
2320                   ((u_char *)&srv->dstmask)[i/8] |= (0x80 >> (i % 8));
2321                }
2322             } else {
2323                srv->srcmask = 0xFFFFFFFF;
2324                srv->dstmask = 0xFFFFFFFF;
2325             }
2326 
2327          } else {
2328             if ((tmp = strstr(ptr, "src = ")) != NULL) {
2329                tmp += strlen("src = ");
2330 
2331                if ((tmp = strchr(tmp, '\"')) != NULL) {
2332                   char nbuf[4], *nptr = nbuf, *ptmp, *endptr;
2333                   int value, i, length;
2334 
2335                   tmp++;
2336                   if ((ptmp = strchr(tmp, '\"')) == NULL)
2337                      ArgusLog (LOG_ERR, "RaCreateSrvEntry: format error %s\n", ptr);
2338 
2339                   *ptmp++ = '\0';
2340                   ptr = ptmp;
2341 
2342                   length = ((strlen(tmp) > (RASIGLENGTH * 2)) ? RASIGLENGTH : strlen(tmp))/2;
2343                   for (i = 0; i < length; i++) {
2344                      endptr = NULL;
2345                      bzero (nbuf, 4);
2346                      nbuf[0] = *tmp++;
2347                      nbuf[1] = *tmp++;
2348                      if (nbuf[0] == ' ') {
2349                         ((u_char *)&srv->srcmask)[i/8] |= (0x80 >> (i % 8));
2350                         value = 0;
2351                      } else {
2352                         value = strtol(nptr, &endptr, 16);
2353                         if ((endptr != NULL) && (endptr != (nptr + 2)))
2354                            ArgusLog (LOG_ERR, "RaCreateSrvEntry: format error %s\n", dup);
2355                      }
2356                      srv->src[i] = (u_char) value;
2357                   }
2358 
2359                   for ( ; i < RASIGLENGTH; i++) {
2360                      ((u_char *)&srv->srcmask)[i/8] |= (0x80 >> (i % 8));
2361                   }
2362                   tmp++;
2363                }
2364             } else
2365                srv->srcmask = 0xFFFFFFFF;
2366 
2367             if ((tmp = strstr(ptr, "dst = ")) != NULL) {
2368                tmp += strlen("dst = ");
2369 
2370                if ((tmp = strchr(ptr, '\"')) != NULL) {
2371                   char nbuf[4], *nptr = nbuf, *ptmp, *endptr;
2372                   int value, i, length;
2373 
2374                   tmp++;
2375                   if ((ptmp = strchr(tmp, '\"')) == NULL)
2376                      ArgusLog (LOG_ERR, "RaCreateSrvEntry: format error %s\n", ptr);
2377 
2378                   *ptmp++ = '\0';
2379                   ptr = ptmp;
2380 
2381                   length = ((strlen(tmp) > (RASIGLENGTH * 2)) ? RASIGLENGTH : strlen(tmp))/2;
2382                   for (i = 0; i < length; i++) {
2383                      endptr = NULL;
2384                      bzero (nbuf, 4);
2385                      nbuf[0] = *tmp++;
2386                      nbuf[1] = *tmp++;
2387                      if (nbuf[0] == ' ') {
2388                         ((u_char *)&srv->dstmask)[i/8] |= (0x80 >> (i % 8));
2389                         value = 0;
2390                      } else {
2391                         value = strtol(nptr, &endptr, 16);
2392                         if ((endptr != NULL) && (endptr != (nptr + 2)))
2393                            ArgusLog (LOG_ERR, "RaCreateSrvEntry: format error %s\n", ptr);
2394                      }
2395                      srv->dst[i] = (u_char) value;
2396                   }
2397 
2398                   for ( ; i < RASIGLENGTH; i++) {
2399                      ((u_char *)&srv->dstmask)[i/8] |= (0x80 >> (i % 8));
2400                   }
2401                   tmp++;
2402                }
2403             } else
2404                srv->dstmask = 0xFFFFFFFF;
2405          }
2406 
2407          if ((tmp = strstr(ptr, "encrypted")) != NULL) {
2408             tmp += strlen("encrypted") + 1;
2409             srv->status = RA_SVC_WILDCARD;
2410          }
2411 
2412          ArgusAddToQueue (labeler->queue, &srv->qhdr, ARGUS_LOCK);
2413       }
2414    }
2415 
2416    free(dup);
2417    return(srv);
2418 }
2419 
2420 
2421 
2422 int RaTallySrvTree (struct RaSrvTreeNode *);
2423 void RaPrintSrvTree (struct ArgusLabelerStruct *, struct RaSrvTreeNode *, int, int);
2424 
2425 
2426 int
RaTallySrvTree(struct RaSrvTreeNode * node)2427 RaTallySrvTree (struct RaSrvTreeNode *node)
2428 {
2429    int retn = 0;
2430 
2431    if (node != NULL) {
2432       retn += RaTallySrvTree(node->r);
2433       retn += RaTallySrvTree(node->l);
2434       retn += node->srv->count;
2435    }
2436 
2437    return (retn);
2438 }
2439 
2440 
2441 void
RaPrintSrvTree(struct ArgusLabelerStruct * labeler,struct RaSrvTreeNode * node,int level,int dir)2442 RaPrintSrvTree (struct ArgusLabelerStruct *labeler, struct RaSrvTreeNode *node, int level, int dir)
2443 {
2444    int i = 0, length, len, olen = strlen(RaSrvTreeArray);
2445    char str[MAXSTRLEN], chr = ' ';
2446 
2447    bzero(str, MAXSTRLEN);
2448 
2449    if (node != NULL) {
2450       if (dir == RA_SRV_LEFT) {
2451          strncat (str, "   |", (MAXSTRLEN - strlen(str)));
2452          strncat (RaSrvTreeArray, str, (MAXSTRLEN - olen));
2453          printf ("%s\n", RaSrvTreeArray);
2454       }
2455 
2456       length = strlen(RaSrvTreeArray);
2457       if ((len = length) > 0) {
2458          chr = RaSrvTreeArray[len - 1];
2459          if (node->r != NULL) {
2460             if (dir == RA_SRV_RIGHT)
2461                RaSrvTreeArray[len - 1] = ' ';
2462          }
2463       }
2464 
2465       strncat (RaSrvTreeArray, "   |", (MAXSTRLEN - strlen(RaSrvTreeArray)));
2466 
2467       RaPrintSrvTree(labeler, node->r, level + 1, RA_SRV_RIGHT);
2468 
2469       for (i = length, len = strlen(RaSrvTreeArray); i < len; i++)
2470          RaSrvTreeArray[i] = '\0';
2471 
2472       if ((len = length) > 0)
2473          RaSrvTreeArray[len - 1] = chr;
2474 
2475       printf ("%s+", RaSrvTreeArray);
2476       printf ("%s %s port %d  n = %d\n", node->srv->name,
2477                        (node->srv->proto == IPPROTO_TCP) ? "tcp" : "udp",
2478                         node->srv->port, node->srv->count);
2479 
2480       len = strlen(RaSrvTreeArray);
2481       if (len > 0) {
2482          chr = RaSrvTreeArray[len - 1];
2483          if (node->l != NULL) {
2484             if (dir == RA_SRV_LEFT)
2485                RaSrvTreeArray[len - 1] = ' ';
2486          }
2487       }
2488 
2489       RaPrintSrvTree(labeler, node->l, level + 1, RA_SRV_LEFT);
2490 
2491       if (dir == RA_SRV_RIGHT) {
2492          printf ("%s", RaSrvTreeArray);
2493          putchar ('\n');
2494       }
2495 
2496       for (i = olen, len = strlen(RaSrvTreeArray); i < len; i++)
2497          RaSrvTreeArray[i] = '\0';
2498    }
2499 }
2500 
2501 
2502 int
RaGenerateBinaryTrees(struct ArgusParserStruct * parser,struct ArgusLabelerStruct * labeler)2503 RaGenerateBinaryTrees(struct ArgusParserStruct *parser, struct ArgusLabelerStruct *labeler)
2504 {
2505    struct ArgusQueueStruct *queue = labeler->queue;
2506    struct RaSrvSignature *srv;
2507    int retn = 1;
2508 
2509    if (ArgusSorter) {
2510       ArgusSorter->ArgusSortAlgorithms[0] = ArgusSortSrvSignatures;
2511       ArgusSorter->ArgusSortAlgorithms[1] = NULL;
2512       ArgusSortQueue (ArgusSorter, queue);
2513    }
2514 
2515    while ((srv = (struct RaSrvSignature *) ArgusPopQueue(queue, ARGUS_LOCK)) != NULL) {
2516       if (srv->srcmask != 0xFFFFFFFF)
2517          RaAddToSrvTree (srv, RA_SRC_SERVICES);
2518 
2519       if (srv->dstmask != 0xFFFFFFFF)
2520          RaAddToSrvTree (srv, RA_DST_SERVICES);
2521    }
2522 
2523 #ifdef ARGUSDEBUG
2524    if (ARGUS_DEBUG_SERVICES & parser->dflag) {
2525       int i;
2526 
2527       printf ("\nTCP Src Services Tree:\n");
2528       for (i = 0; i < RASIGLENGTH; i++) {
2529          if (RaSrcTCPServicesTree[i] != NULL) {
2530             printf ("  signature length %d\n", i);
2531             bzero (RaSrvTreeArray, MAXSTRLEN);
2532             RaPrintSrvTree (labeler, RaSrcTCPServicesTree[i], 0, RA_SRV_ROOT);
2533             fflush (stdout);
2534          }
2535       }
2536 
2537       printf ("\nTCP Dst Services Tree:\n");
2538       for (i = 0; i < RASIGLENGTH; i++) {
2539          if (RaDstTCPServicesTree[i] != NULL) {
2540             printf ("  signature length %d\n", i);
2541             bzero (RaSrvTreeArray, MAXSTRLEN);
2542             RaPrintSrvTree (labeler, RaDstTCPServicesTree[i], 0, RA_SRV_ROOT);
2543             fflush (stdout);
2544          }
2545       }
2546 
2547       printf ("\nUDP Src Services Tree:\n");
2548       for (i = 0; i < RASIGLENGTH; i++) {
2549          if (RaSrcUDPServicesTree[i] != NULL) {
2550             printf ("  signature length %d\n", i);
2551             bzero (RaSrvTreeArray, MAXSTRLEN);
2552             RaPrintSrvTree (labeler, RaSrcUDPServicesTree[i], 0, RA_SRV_ROOT);
2553             fflush (stdout);
2554          }
2555       }
2556 
2557       printf ("\nUDP Dst Services Tree:\n");
2558       for (i = 0; i < RASIGLENGTH; i++) {
2559          if (RaDstUDPServicesTree[i] != NULL) {
2560             printf ("  signature length %d\n", i);
2561             bzero (RaSrvTreeArray, MAXSTRLEN);
2562             RaPrintSrvTree (labeler, RaDstUDPServicesTree[i], 0, RA_SRV_ROOT);
2563             fflush (stdout);
2564          }
2565       }
2566 
2567       ArgusShutDown(0);
2568       exit(0);
2569    }
2570 #endif
2571 
2572    return (retn);
2573 }
2574 
2575 struct RaSrvTreeNode *RaTCPSrcArray[0x10000], *RaTCPDstArray[0x10000];
2576 struct RaSrvTreeNode *RaUDPSrcArray[0x10000], *RaUDPDstArray[0x10000];
2577 int RaAddToArray(struct RaSrvTreeNode **, struct RaSrvSignature *, int);
2578 
2579 int
RaAddToArray(struct RaSrvTreeNode * array[],struct RaSrvSignature * srv,int mode)2580 RaAddToArray(struct RaSrvTreeNode *array[], struct RaSrvSignature *srv, int mode)
2581 {
2582    int retn = 1;
2583    struct RaSrvTreeNode *tree;
2584 
2585    if ((tree = array[srv->port]) == NULL) {
2586       if ((tree = (struct RaSrvTreeNode *) ArgusCalloc (1, sizeof(*tree))) != NULL) {
2587          tree->srv = srv;
2588          array[srv->port] = tree;
2589       } else
2590          ArgusLog (LOG_ERR, "ArgusCalloc error %s\n", strerror(errno));
2591 
2592    } else {
2593       if ((srv->srcmask == 0xFFFFFFFF) && (srv->dstmask == 0xFFFFFFFF)) {
2594          tree->srv = srv;
2595       } else {
2596          RaAddSrvTreeNode(tree, srv, 0, mode);
2597       }
2598    }
2599 
2600    return (retn);
2601 }
2602 
2603 
2604 
2605 int
RaReadSrvSignature(struct ArgusParserStruct * parser,struct ArgusLabelerStruct * labeler,char * file)2606 RaReadSrvSignature(struct ArgusParserStruct *parser, struct ArgusLabelerStruct *labeler, char *file)
2607 {
2608    int retn = 0;
2609    struct RaSrvSignature *srv = NULL;
2610    char strbuf[MAXSTRLEN], *str = strbuf, **model = NULL;
2611    int i = 0, RaSigLineNumber = 0;
2612    FILE *fd;
2613 
2614    bzero ((char *) RaTCPSrcArray, sizeof(RaTCPSrcArray));
2615    bzero ((char *) RaTCPDstArray, sizeof(RaTCPDstArray));
2616    bzero ((char *) RaUDPSrcArray, sizeof(RaUDPSrcArray));
2617    bzero ((char *) RaUDPDstArray, sizeof(RaUDPDstArray));
2618 
2619    if (model == NULL) {
2620       bzero ((char *) sigbuf, sizeof(sigbuf));
2621       if ((fd = fopen (file, "r")) != NULL) {
2622          while ((str = fgets (str, MAXSTRLEN, fd)) != NULL)
2623             sigbuf[i++] = strdup(str);
2624 
2625          model = sigbuf;
2626          fclose(fd);
2627 
2628       } else
2629          ArgusLog (LOG_ERR, "%s: %s", file, strerror(errno));
2630    }
2631 
2632    while ((str = *model++) != NULL) {
2633       RaSigLineNumber++;
2634 
2635       while (isspace((int)*str))
2636          str++;
2637       if (strlen(str)) {
2638          switch (*str) {
2639             case '#':
2640             case '\n':
2641             case '!':
2642                break;
2643 
2644             default: {
2645                if ((srv = RaCreateSrvEntry(labeler, RaSigLineNumber, str)) != NULL) {
2646                   RaSigLineNumber++;
2647                   switch (srv->proto) {
2648                      case IPPROTO_TCP:
2649                         if (srv->srcmask != 0xFFFFFFFF)
2650                            RaAddToArray(RaTCPSrcArray, srv, RA_SRC_SERVICES);
2651                         if (srv->dstmask != 0xFFFFFFFF)
2652                            RaAddToArray(RaTCPDstArray, srv, RA_DST_SERVICES);
2653                         break;
2654 
2655                      case IPPROTO_UDP:
2656                         if (srv->srcmask != 0xFFFFFFFF)
2657                            RaAddToArray(RaUDPSrcArray, srv, RA_SRC_SERVICES);
2658                         if (srv->dstmask != 0xFFFFFFFF)
2659                            RaAddToArray(RaUDPDstArray, srv, RA_DST_SERVICES);
2660                         break;
2661                   }
2662                }
2663 
2664                break;
2665             }
2666          }
2667       }
2668    }
2669 
2670    if (RaSigLineNumber > 0)
2671       retn = RaGenerateBinaryTrees(parser, labeler);
2672 
2673    return (retn);
2674 }
2675 
2676 
2677 void
RaAddSrvTreeNode(struct RaSrvTreeNode * node,struct RaSrvSignature * srv,int ind,int mode)2678 RaAddSrvTreeNode(struct RaSrvTreeNode *node, struct RaSrvSignature *srv, int ind, int mode)
2679 {
2680    struct RaSrvTreeNode *tree = NULL;
2681    u_char *sbuf = NULL, *tbuf = NULL;
2682    unsigned int mask;
2683    int i = 0;
2684 
2685    switch (mode) {
2686       case RA_SRC_SERVICES:
2687          mask = node->srv->srcmask;
2688          sbuf  = node->srv->src;
2689          tbuf  = srv->src;
2690          break;
2691 
2692       case RA_DST_SERVICES:
2693          mask = node->srv->dstmask;
2694          sbuf  = node->srv->dst;
2695          tbuf  = srv->dst;
2696          break;
2697 
2698       default:
2699          return;
2700    }
2701 
2702    if (mask != 0xFFFFFFFF) {
2703       for (i = ind; i < RASIGLENGTH; i++)
2704          if ((!(((u_char *)&mask)[i/8] & (0x80 >> (i % 8)))) && (sbuf[i] != tbuf[i]))
2705             break;
2706 
2707       if (i != RASIGLENGTH) {
2708          if (tbuf[i] > sbuf[i]) {
2709             if (node->r != NULL) {
2710                RaAddSrvTreeNode(node->r, srv, ind, mode);
2711             } else {
2712                if ((tree = (struct RaSrvTreeNode *) ArgusCalloc (1, sizeof(*tree))) != NULL) {
2713                   tree->srv = srv;
2714                   node->r = tree;
2715                }
2716             }
2717 
2718          } else {
2719             if (node->l != NULL) {
2720                RaAddSrvTreeNode(node->l, srv, ind, mode);
2721             } else {
2722                if ((tree = (struct RaSrvTreeNode *) ArgusCalloc (1, sizeof(*tree))) != NULL) {
2723                   tree->srv = srv;
2724                   node->l = tree;
2725                }
2726             }
2727          }
2728       }
2729    }
2730 }
2731 
2732 
2733 void
RaAddToSrvTree(struct RaSrvSignature * srv,int mode)2734 RaAddToSrvTree (struct RaSrvSignature *srv, int mode)
2735 {
2736    struct RaSrvTreeNode *tree = NULL;
2737    struct RaSrvTreeNode **RaServicesTree = NULL;
2738    unsigned int mask;
2739    int i = 0;
2740 
2741    switch (mode) {
2742       case RA_SRC_SERVICES:
2743          mask = srv->srcmask;
2744          switch (srv->proto) {
2745             case IPPROTO_TCP: RaServicesTree = RaSrcTCPServicesTree; break;
2746             case IPPROTO_UDP: RaServicesTree = RaSrcUDPServicesTree; break;
2747          }
2748          break;
2749 
2750       case RA_DST_SERVICES:
2751          mask = srv->dstmask;
2752          switch (srv->proto) {
2753             case IPPROTO_TCP: RaServicesTree = RaDstTCPServicesTree; break;
2754             case IPPROTO_UDP: RaServicesTree = RaDstUDPServicesTree; break;
2755          }
2756          break;
2757    }
2758 
2759 
2760    for (i = 0; i < RASIGLENGTH; i++)
2761       if (!(((u_char *)&mask)[i/8] & (0x80 >> (i % 8))))
2762          break;
2763 
2764    if (i < RASIGLENGTH) {
2765       if (RaServicesTree[i] != NULL)
2766          RaAddSrvTreeNode(RaServicesTree[i], srv, i, mode);
2767       else {
2768          if ((tree = (struct RaSrvTreeNode *) ArgusCalloc (1, sizeof(*tree))) != NULL) {
2769             tree->srv = srv;
2770             RaServicesTree[i] = tree;
2771          }
2772       }
2773    }
2774 
2775 #ifdef ARGUSDEBUG
2776    ArgusDebug (ARGUS_DEBUG_POLICY, "RaAddToSrvTree (0x%x) returning\n", srv);
2777 #endif
2778 }
2779 
2780 
2781 struct RaSrvSignature *
RaFindSrv(struct RaSrvTreeNode * node,u_char * ptr,int len,int mode)2782 RaFindSrv (struct RaSrvTreeNode *node, u_char *ptr, int len, int mode)
2783 {
2784    int i, nomatch = 0, guess = 0, wildcard = 0;
2785    struct RaSrvSignature *retn = NULL;
2786    unsigned int mask;
2787    u_char *buf = NULL;
2788 
2789    if ((node != NULL)  && (ptr != NULL)) {
2790       if (node->srv->status & RA_SVC_WILDCARD)
2791          wildcard++;
2792 
2793       switch (mode) {
2794          case RA_SRC_SERVICES:
2795             mask = node->srv->srcmask;
2796             buf  = node->srv->src;
2797             break;
2798          case RA_DST_SERVICES:
2799             mask = node->srv->dstmask;
2800             buf  = node->srv->dst;
2801             break;
2802 
2803          default:
2804             return (retn);
2805       }
2806 
2807       if (buf && (mask != 0xFFFFFFFF)) {
2808          retn = node->srv;
2809 
2810          for (i = 0; i < RASIGLENGTH; i++) {
2811             if (!(((u_char *)&mask)[i/8] & (0x80 >> (i % 8)))) {
2812                if (buf[i] != ptr[i]) {
2813                   if (!(isalpha(buf[i]) &&
2814                       ((isupper(buf[i]) ? (tolower(buf[i]) == ptr[i]) :
2815                                           (toupper(buf[i]) == ptr[i]))))) {
2816                      nomatch++;
2817                      if (buf[i] > ptr[i])
2818                         retn = RaFindSrv (node->l, ptr, len, mode);
2819                      else
2820                         retn = RaFindSrv (node->r, ptr, len, mode);
2821                      break;
2822 
2823                   } else {
2824                      guess++;
2825                   }
2826                } else {
2827                   guess++;
2828                }
2829             } else
2830                guess++;
2831          }
2832 
2833          for (; i < RASIGLENGTH; i++) {
2834             if (!(((u_char *)&mask)[i/8] & (0x80 >> (i % 8)))) {
2835                if (buf[i] == ptr[i])
2836                   guess++;
2837             } else
2838                guess++;
2839          }
2840 
2841          if (nomatch) {
2842             if (guess > RaBestGuessScore) {
2843                RaBestGuessScore = guess;
2844                RaBestGuess = node->srv;
2845             }
2846          }
2847       }
2848 
2849       if (wildcard)
2850          retn = node->srv;
2851    }
2852 
2853    return (retn);
2854 }
2855 
2856 int
RaFindService(struct ArgusRecordStruct * argus)2857 RaFindService(struct ArgusRecordStruct *argus)
2858 {
2859    int retn = 0;
2860    struct RaSrvTreeNode **array = NULL;
2861    struct RaSrvTreeNode *tree = NULL;
2862    struct ArgusFlow *flow = (struct ArgusFlow *) argus->dsrs[ARGUS_FLOW_INDEX];
2863 
2864    if (flow) {
2865       switch (flow->ip_flow.ip_p) {
2866          case IPPROTO_TCP: array = RaTCPSrcArray; break;
2867          case IPPROTO_UDP: array = RaUDPSrcArray; break;
2868 
2869          default:
2870             return (0);
2871       }
2872 
2873       if ((tree = array[flow->ip_flow.dport]) != NULL)
2874          retn = 1;
2875       else
2876          if ((tree = array[flow->ip_flow.sport]) != NULL)
2877             retn = 1;
2878    }
2879 
2880    return(retn);
2881 }
2882 
2883 
2884 struct RaSrvSignature *
RaValidateService(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus)2885 RaValidateService(struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus)
2886 {
2887    struct RaSrvSignature *retn = NULL;
2888    struct RaSrvSignature *srvSrc = NULL, *srcGuess = NULL;
2889    struct RaSrvSignature *srvDst = NULL, *dstGuess = NULL;
2890    struct ArgusDataStruct *suser, *duser;
2891    int srcPort = 0, dstPort = 0;
2892    struct ArgusFlow *flow = NULL;
2893 #ifdef ARGUSDEBUG
2894    int srcScore = 0, dstScore = 0;
2895    char buf[MAXSTRLEN];
2896 #endif
2897    int found = 0;
2898 
2899    if ((flow = (struct ArgusFlow *)argus->dsrs[ARGUS_FLOW_INDEX]) == NULL)
2900       return(retn);
2901 
2902    suser = (void *) argus->dsrs[ARGUS_SRCUSERDATA_INDEX];
2903    duser = (void *) argus->dsrs[ARGUS_DSTUSERDATA_INDEX];
2904 
2905    if (!(suser || duser)) {
2906       struct RaSrvTreeNode **array = NULL;
2907       struct RaSrvTreeNode *node = NULL;
2908 
2909       switch (flow->hdr.subtype & 0x3F) {
2910          case ARGUS_FLOW_CLASSIC5TUPLE: {
2911             switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
2912                case ARGUS_TYPE_IPV4:
2913                   switch (flow->ip_flow.ip_p) {
2914                      case IPPROTO_TCP: array = RaTCPSrcArray; break;
2915                      case IPPROTO_UDP: array = RaUDPSrcArray; break;
2916                         break;
2917                   }
2918                   if (array != NULL)
2919                      if ((node = array[flow->ip_flow.dport]) == NULL)
2920                            node = array[flow->ip_flow.sport];
2921                   if (node != NULL)
2922                      RaBestGuess = node->srv;
2923                   break;
2924 
2925                case ARGUS_TYPE_IPV6: {
2926                   switch (flow->ipv6_flow.ip_p) {
2927                      case IPPROTO_TCP: array = RaTCPSrcArray; break;
2928                      case IPPROTO_UDP: array = RaUDPSrcArray; break;
2929                   }
2930                   if (array != NULL)
2931                      if ((node = array[flow->ipv6_flow.dport]) == NULL)
2932                         node = array[flow->ipv6_flow.sport];
2933                   if (node != NULL)
2934                      RaBestGuess = node->srv;
2935                   break;
2936                }
2937             }
2938          }
2939       }
2940       return (RaBestGuess);
2941    }
2942 
2943    if (suser != NULL) {
2944       struct RaSrvTreeNode *tree = NULL;
2945       u_char *ptr = (u_char *) &suser->array;
2946       struct RaSrvTreeNode **array = NULL;
2947       int i, len = suser->count;
2948 
2949       RaBestGuess = NULL;
2950       RaBestGuessScore = 0;
2951 
2952       switch (flow->ip_flow.ip_p) {
2953          case IPPROTO_TCP: array = RaTCPSrcArray; break;
2954          case IPPROTO_UDP: array = RaUDPSrcArray; break;
2955          default:
2956             return (retn);
2957       }
2958 
2959       if ((tree = array[flow->ip_flow.dport]) != NULL) {
2960          if ((srvSrc = RaFindSrv (tree, ptr, len, RA_SRC_SERVICES)) == NULL) {
2961             if (RaBestGuess && (RaBestGuessScore > 5)) {
2962                srvSrc = RaBestGuess;
2963                srcPort++;
2964             }
2965          }
2966       }
2967 
2968       if ((tree = array[flow->ip_flow.sport]) == NULL) {
2969          if (srvSrc == NULL)
2970             for (i = 0; i < RASIGLENGTH && !found; i++) {
2971                switch (flow->ip_flow.ip_p) {
2972                   case IPPROTO_TCP: tree = RaSrcTCPServicesTree[i]; break;
2973                   case IPPROTO_UDP: tree = RaSrcUDPServicesTree[i]; break;
2974                }
2975                if (tree != NULL)
2976                   if ((srvSrc = RaFindSrv(tree, ptr, len, RA_SRC_SERVICES)) != NULL)
2977                          break;
2978             }
2979       }
2980       srcGuess = RaBestGuess;
2981 #ifdef ARGUSDEBUG
2982       srcScore = RaBestGuessScore;
2983 #endif
2984    }
2985 
2986    if (duser != NULL) {
2987       struct RaSrvTreeNode *tree = NULL;
2988       u_char *ptr = (u_char *) &duser->array;
2989       struct RaSrvTreeNode **array = NULL;
2990       int i, len = duser->count;
2991 
2992       RaBestGuess = NULL;
2993       RaBestGuessScore = 0;
2994 
2995       switch (flow->ip_flow.ip_p) {
2996          case IPPROTO_TCP: array = RaTCPDstArray; break;
2997          case IPPROTO_UDP: array = RaUDPDstArray; break;
2998          default:
2999             return (retn);
3000       }
3001 
3002       if ((tree = array[flow->ip_flow.dport]) != NULL) {
3003          if ((srvDst = RaFindSrv (tree, ptr, len, RA_DST_SERVICES)) == NULL) {
3004             if (RaBestGuess && (RaBestGuessScore > 4)) {
3005                srvDst = RaBestGuess;
3006                dstPort++;
3007             }
3008          }
3009       }
3010 
3011       if ((srvSrc == NULL) && (srvDst == NULL)) {
3012          for (i = 0; i < RASIGLENGTH && !found; i++) {
3013             switch (flow->ip_flow.ip_p) {
3014                case IPPROTO_TCP: tree = RaDstTCPServicesTree[i]; break;
3015                case IPPROTO_UDP: tree = RaDstUDPServicesTree[i]; break;
3016             }
3017 
3018             if (tree != NULL)
3019                if ((srvDst = RaFindSrv(tree, ptr, len, RA_DST_SERVICES)) != NULL)
3020                    break;
3021          }
3022       }
3023 
3024 #ifdef ARGUSDEBUG
3025       dstGuess = RaBestGuess;
3026       dstScore = RaBestGuessScore;
3027 #endif
3028    }
3029 
3030 #ifdef ARGUSDEBUG
3031    ArgusPrintRecord(parser, buf, argus, MAXSTRLEN);
3032 #endif
3033 
3034    if (srvSrc && srvDst) {
3035       if (!(strcmp(srvSrc->name, srvDst->name))) {
3036 #ifdef ARGUSDEBUG
3037          ArgusDebug (ARGUS_DEBUG_POLICY, "%s both match %s\n", buf, srvSrc->name);
3038 #endif
3039          retn = srvSrc;
3040 
3041       } else {
3042          if (srcPort && dstPort) {
3043 #ifdef ARGUSDEBUG
3044             ArgusDebug (ARGUS_DEBUG_POLICY, "%s src %s dst %s mismatch\n", buf, srvSrc->name, srvDst->name);
3045 #endif
3046             retn = srvSrc;
3047 
3048          } else {
3049             if (srcPort && !dstPort) {
3050 #ifdef ARGUSDEBUG
3051                ArgusDebug (ARGUS_DEBUG_POLICY, "%s match %s with dst null\n", buf, srvSrc->name);
3052 #endif
3053                retn = srvSrc;
3054 
3055             } else {
3056 #ifdef ARGUSDEBUG
3057                ArgusDebug (ARGUS_DEBUG_POLICY, "%s match %s with src null\n", buf, srvDst->name);
3058 #endif
3059                retn = srvDst;
3060             }
3061          }
3062       }
3063 
3064    } else {
3065       if (srvDst && (argus->dsrs[ARGUS_SRCUSERDATA_INDEX] == NULL)) {
3066          if (srvDst && (srvDst->srcmask == 0xFFFFFFFF)) {
3067 #ifdef ARGUSDEBUG
3068             ArgusDebug (ARGUS_DEBUG_POLICY, "%s dst buffer matches %s\n", buf, srvDst->name);
3069 #endif
3070             retn = srvDst;
3071 
3072          } else {
3073 #ifdef ARGUSDEBUG
3074             ArgusDebug (ARGUS_DEBUG_POLICY, "%s dst buffer matches %s\n", buf, srvDst->name);
3075 #endif
3076             retn = srvDst;
3077          }
3078 
3079       } else
3080       if (srvSrc && (argus->dsrs[ARGUS_DSTUSERDATA_INDEX] == NULL)) {
3081          if (srvSrc && (srvSrc->dstmask == 0xFFFFFFFF)) {
3082 #ifdef ARGUSDEBUG
3083             ArgusDebug (ARGUS_DEBUG_POLICY, "%s src buffer matches %s\n", buf, srvSrc->name);
3084 #endif
3085             retn = srvSrc;
3086          } else {
3087 #ifdef ARGUSDEBUG
3088             ArgusDebug (ARGUS_DEBUG_POLICY, "%s src buffer matches %s\n", buf, srvSrc->name);
3089 #endif
3090             retn = srvSrc;
3091          }
3092 
3093       } else {
3094          if (srvSrc && (srvDst == NULL)) {
3095             if ((dstGuess) && (srvSrc == dstGuess)) {
3096 #ifdef ARGUSDEBUG
3097                ArgusDebug (ARGUS_DEBUG_POLICY, "%s match with dst search %s score %d\n", buf, srvSrc->name, dstScore);
3098 #endif
3099                retn = srvSrc;
3100 
3101             } else {
3102                if (dstPort == 0) {
3103 #ifdef ARGUSDEBUG
3104                   ArgusDebug (ARGUS_DEBUG_POLICY, "%s match with dst null\n", buf, srvSrc->name);
3105 #endif
3106                   retn = srvSrc;
3107 
3108                } else {
3109                   retn = NULL;
3110                }
3111             }
3112 
3113          } else
3114          if (srvDst && (srvSrc == NULL)) {
3115             if ((srcGuess) && (srvDst == srcGuess)) {
3116 #ifdef ARGUSDEBUG
3117                ArgusDebug (ARGUS_DEBUG_POLICY, "%s match with src search %s score %d\n", buf, srvDst->name, srcScore);
3118 #endif
3119                retn = srvDst;
3120 
3121             } else {
3122                if (srcPort == 0) {
3123 #ifdef ARGUSDEBUG
3124                   ArgusDebug (ARGUS_DEBUG_POLICY, "%s match %s with src null\n", buf, srvDst->name);
3125 #endif
3126                } else
3127                   retn = NULL;
3128             }
3129 
3130          } else {
3131             retn = NULL;
3132          }
3133       }
3134    }
3135 
3136    return (retn);
3137 }
3138 
3139 
3140 int RaMatchService(struct ArgusRecord *);
3141 
3142 int
RaMatchService(struct ArgusRecord * argus)3143 RaMatchService(struct ArgusRecord *argus)
3144 {
3145    int retn = 0;
3146    return (retn);
3147 }
3148 
3149 
3150 extern void ArgusPrintSrcCountryCode (struct ArgusParserStruct *, char *, struct ArgusRecordStruct *, int);
3151 extern void ArgusPrintDstCountryCode (struct ArgusParserStruct *, char *, struct ArgusRecordStruct *, int);
3152 
3153 
3154 int
RaCountryCodeLabel(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus)3155 RaCountryCodeLabel (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus)
3156 {
3157    int retn = 0;
3158 
3159    if (argus != NULL) {
3160       struct ArgusCountryCodeStruct *cocode = (struct ArgusCountryCodeStruct *)argus->dsrs[ARGUS_COCODE_INDEX];
3161       char sbuf[16], dbuf[16];
3162 
3163       bzero (sbuf, sizeof(sbuf));
3164       bzero (dbuf, sizeof(dbuf));
3165 
3166       if (cocode == NULL) {
3167          if ((cocode = ArgusCalloc(1, sizeof(*cocode))) == NULL)
3168             ArgusLog (LOG_ERR, "RaProcessRecord: ArgusCalloc error %s", strerror(errno));
3169 
3170          cocode->hdr.type             = ARGUS_COCODE_DSR;
3171          cocode->hdr.argus_dsrvl8.len = (sizeof(*cocode) + 3) / 4;
3172          cocode->hdr.subtype = 0;
3173 
3174          ArgusPrintSrcCountryCode (parser, sbuf, argus, 2);
3175          ArgusPrintDstCountryCode (parser, dbuf, argus, 2);
3176 
3177          bcopy(sbuf, &cocode->src[0], 2);
3178          bcopy(dbuf, &cocode->dst[0], 2);
3179 
3180          argus->dsrindex |= (0x01 << ARGUS_COCODE_INDEX);
3181          argus->dsrs[ARGUS_COCODE_INDEX] = (struct ArgusDSRHeader*) cocode;
3182       }
3183    }
3184 
3185    return (retn);
3186 }
3187 
3188 
3189 char RaAddressLabelBuffer[1024];
3190 
3191 char *
RaAddressLabel(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus)3192 RaAddressLabel (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus)
3193 {
3194    struct ArgusFlow *flow = (struct ArgusFlow *) argus->dsrs[ARGUS_FLOW_INDEX];
3195    char *retn = NULL, *saddr = NULL, *daddr = NULL;
3196    int found = 0;
3197 
3198    bzero (RaAddressLabelBuffer, sizeof(RaAddressLabelBuffer));
3199    if (flow != NULL) {
3200       switch(flow->hdr.subtype & 0x3F) {
3201          case ARGUS_FLOW_LAYER_3_MATRIX:
3202          case ARGUS_FLOW_CLASSIC5TUPLE: {
3203             switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
3204                case ARGUS_TYPE_IPV4: {
3205                   if ((saddr = RaFetchIPv4AddressLabel(parser, &flow->ip_flow.ip_src)) != NULL) {
3206                      int slen = strlen(RaAddressLabelBuffer);
3207                      snprintf (&RaAddressLabelBuffer[slen], 1024 - slen, "saddr=%s", saddr);
3208                      free(saddr);
3209                      found++;
3210                   }
3211                   if ((daddr = RaFetchIPv4AddressLabel(parser, &flow->ip_flow.ip_dst)) != NULL) {
3212                      int slen = strlen(RaAddressLabelBuffer);
3213                      if (found) {
3214                         snprintf (&RaAddressLabelBuffer[slen], 1024 - slen, ":");
3215                         slen++;
3216                      }
3217                      snprintf (&RaAddressLabelBuffer[slen], 1024 - slen, "daddr=%s", daddr);
3218                      free(daddr);
3219                      found++;
3220                   }
3221                }
3222             }
3223          }
3224       }
3225    }
3226 
3227    if (found)
3228       retn = RaAddressLabelBuffer;
3229 
3230    return(retn);
3231 }
3232 
3233 char RaIANAAddressLabel[128];
3234 
3235 char *RaLabelIPv4Address(struct ArgusParserStruct *, unsigned int *);
3236 char *RaLabelIPv6Address(struct ArgusParserStruct *, struct in6_addr *);
3237 
3238 char *
RaLabelIANAAddressType(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus)3239 RaLabelIANAAddressType (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus)
3240 {
3241    struct ArgusFlow *flow = (struct ArgusFlow *) argus->dsrs[ARGUS_FLOW_INDEX];
3242    char *retn = NULL, *saddr = NULL, *daddr = NULL;
3243 
3244    if (flow != NULL) {
3245       switch(flow->hdr.subtype & 0x3F) {
3246          case ARGUS_FLOW_LAYER_3_MATRIX:
3247          case ARGUS_FLOW_CLASSIC5TUPLE: {
3248             int found = 0;
3249 
3250             bzero (RaIANAAddressLabel, sizeof(RaIANAAddressLabel));
3251 
3252             switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
3253                case ARGUS_TYPE_IPV4: {
3254                   if ((saddr = RaLabelIPv4Address(parser, &flow->ip_flow.ip_src)) != NULL) {
3255                      int slen = strlen(RaIANAAddressLabel);
3256                      snprintf (&RaIANAAddressLabel[slen], 128 - slen, "saddr=%s", saddr);
3257                      found++;
3258                   }
3259                   if ((daddr = RaLabelIPv4Address(parser, &flow->ip_flow.ip_dst)) != NULL) {
3260                      int slen = strlen(RaIANAAddressLabel);
3261                      if (found) {
3262                         snprintf (&RaIANAAddressLabel[slen], 128 - slen, ":");
3263                         slen++;
3264                      }
3265                      snprintf (&RaIANAAddressLabel[slen], 128 - slen, "daddr=%s", daddr);
3266                      found++;
3267                   }
3268                   break;
3269                }
3270 
3271                case ARGUS_TYPE_IPV6: {
3272                   if ((saddr = RaLabelIPv6Address(parser, (struct in6_addr *)&flow->ipv6_flow.ip_src)) != NULL) {
3273                      int slen = strlen(RaIANAAddressLabel);
3274                      snprintf (&RaIANAAddressLabel[slen], 128 - slen, "saddr=%s", saddr);
3275                      found++;
3276                   }
3277                   if ((daddr = RaLabelIPv6Address(parser, (struct in6_addr *)&flow->ipv6_flow.ip_dst)) != NULL) {
3278                      int slen = strlen(RaIANAAddressLabel);
3279                      if (found) {
3280                         snprintf (&RaIANAAddressLabel[slen], 128 - slen, ":");
3281                         slen++;
3282                      }
3283                      snprintf (&RaIANAAddressLabel[slen], 128 - slen, "daddr=%s", daddr);
3284                      found++;
3285                   }
3286                   break;
3287                }
3288             }
3289 
3290             if (found)
3291                retn = RaIANAAddressLabel;
3292          }
3293       }
3294    }
3295 
3296    return (retn);
3297 }
3298 
3299 char *
RaLabelIPv4Address(struct ArgusParserStruct * parser,unsigned int * aptr)3300 RaLabelIPv4Address(struct ArgusParserStruct *parser, unsigned int *aptr)
3301 {
3302    unsigned int addr = *aptr;
3303    char *retn = NULL;
3304 
3305    if (IN_MULTICAST(addr)) {
3306       if ((addr & 0xFF000000) == 0xE0000000) {
3307          if ((addr & 0x00FFFFFF) <  0x00000100) retn="IPv4AddrMulticastLocal"; else
3308          if ((addr & 0x00FFFFFF) <  0x00000200) retn="IPv4AddrMulticastInternet"; else
3309          if ((addr & 0x00FFFFFF) <  0x0000FF00) retn="IPv4AddrMulticastAdHoc"; else
3310          if ((addr & 0x00FFFFFF) <  0x00020000) retn="IPv4AddrMulticastReserved"; else
3311          if ((addr & 0x00FFFFFF) <  0x00030000) retn="IPv4AddrMulticastSdpSap"; else
3312          if ((addr & 0x00FFFFFF) <  0x00030040) retn="IPv4AddrMulticastNasdaq"; else
3313          if ((addr & 0x00FFFFFF) <  0x00FD0000) retn="IPv4AddrMulticastReserved"; else
3314          if ((addr & 0x00FFFFFF) <= 0x00FD0000) retn="IPv4AddrMulticastDisTrans";
3315       }
3316       if (((addr & 0xFF000000) > 0xE0000000) && ((addr & 0xFF000000) < 0xE8000000)) {
3317          retn="IPv4AddrMulticastReserved";
3318       }
3319       if ((addr & 0xFF000000) == 0xE8000000) {
3320          retn="IPv4AddrMulticastSrcSpec";
3321       }
3322       if ((addr & 0xFF000000) == 0xE9000000) {
3323          retn="IPv4AddrMulticastGlop";
3324       }
3325       if (((addr & 0xFF000000) >= 0xE9000000) && ((addr & 0xFF000000) <= 0xEE000000)) {
3326          retn="IPv4AddrMulticastReserved";
3327       }
3328       if ((addr & 0xFF000000) == 0xEF000000) {
3329          retn="IPv4AddrMulticastAdmin";
3330          if (((addr & 0x00FF0000) > 0x00000000) && ((addr & 0x00FF0000) <  0x00C00000)) {
3331             retn="IPv4AddrMulticastReserved";
3332          }
3333          if (((addr & 0x00FF0000) >= 0x00C00000) && ((addr & 0x00FF0000) <  0x00FC0000)) {
3334             retn="IPv4AddrMulticastOrgLocal";
3335          }
3336          if (((addr & 0x00FF0000) >= 0x00FC0000) && ((addr & 0x00FF0000) <= 0x00FF0000)) {
3337             retn="IPv4AddrMulticastSiteLocal";
3338          }
3339       }
3340 
3341    } else {
3342       if (((addr & 0xFF000000) == 0x00000000)) {
3343          retn="IPv4AddrUnicastThisNet";
3344       } else
3345       if (((addr & 0xFF000000) > 0x00000000) && ((addr & 0xFF000000) <  0x03000000)) {
3346          retn="IPv4AddrUnicastReserved";
3347       } else
3348       if ((addr & 0xFF000000) == 0x05000000) {
3349          retn="IPv4AddrUnicastReserved";
3350       } else
3351       if ((addr & 0xFF000000) == 0x17000000) {
3352          retn="IPv4AddrUnicastReserved";
3353       } else
3354       if ((addr & 0xFF000000) == 0x1B000000) {
3355          retn="IPv4AddrUnicastReserved";
3356       } else
3357       if (((addr & 0xFF000000) == 0x24000000) || ((addr & 0xFF000000) == 0x25000000)) {
3358          retn="IPv4AddrUnicastReserved";
3359       } else
3360       if (((addr & 0xFF000000) == 0x29000000) || ((addr & 0xFF000000) == 0x30000000)) {
3361          retn="IPv4AddrUnicastReserved";
3362       } else
3363       if (((addr & 0xFF000000) >= 0x49000000) && ((addr & 0xFF000000) <  0x50000000)) {
3364          retn="IPv4AddrUnicastReserved";
3365       } else
3366       if (((addr & 0xFF000000) >= 0x59000000) && ((addr & 0xFF000000) <  0x7F000000)) {
3367          retn="IPv4AddrUnicastReserved";
3368       } else
3369       if ((addr & 0xFF000000) == 0x7F000000) {
3370          retn="IPv4AddrUnicastLoopBack";
3371       } else
3372       if ((addr & 0xFFFF0000) == 0xAC100000) {
3373          retn="IPv4AddrUnicastPrivate";
3374       } else
3375       if (((addr & 0xFF000000) >= 0xAD000000) && ((addr & 0xFF000000) <  0xBC000000)) {
3376          if ((addr & 0xFFFF0000) == 0xA9FE0000)
3377             retn="IPv4AddrUnicastLinkLocal";
3378          else
3379             retn="IPv4AddrUnicastReserved";
3380       } else
3381       if (((addr & 0xFF000000) >= 0xBE000000) && ((addr & 0xFF000000) <  0xC0000000)) {
3382          retn="IPv4AddrUnicastReserved";
3383       } else
3384       if ((addr & 0xFF000000) == 0xC0000000) {
3385          if ((addr & 0xFFFFFF00) == 0xC0000200)
3386             retn="IPv4AddrUnicastTestNet";
3387          else
3388          if ((addr & 0xFFFF0000) == 0xC0A80000)
3389             retn="IPv4AddrUnicastPrivate";
3390          else
3391             retn="IPv4AddrUnicast";
3392       } else
3393       if ((addr & 0xFF000000) == 0xC5000000) {
3394          retn="IPv4AddrUnicastReserved";
3395       } else
3396       if ((addr & 0xFF000000) == 0xDF000000) {
3397          retn="IPv4AddrUnicastReserved";
3398       } else
3399       if (((addr & 0xFF000000) >= 0xBE000000) && ((addr & 0xFF000000) <  0xC0000000)) {
3400          retn="IPv4AddrUnicastReserved";
3401       } else
3402       if (((addr & 0xFF000000) >= 0xF0000000) && ((addr & 0xFF000000) <= 0xFF000000)) {
3403          retn="IPv4AddrUnicastReserved";
3404       } else
3405       if ((addr & 0xFF000000) == 0x0A000000) {
3406          retn="IPv4AddrUnicastPrivate";
3407       } else
3408          retn="IPv4AddrUnicast";
3409    }
3410 
3411    return (retn);
3412 }
3413 
3414 char *
RaLabelIPv6Address(struct ArgusParserStruct * parser,struct in6_addr * addr)3415 RaLabelIPv6Address(struct ArgusParserStruct *parser, struct in6_addr *addr)
3416 {
3417    char *retn = NULL;
3418 
3419    if (IN6_IS_ADDR_UNSPECIFIED(addr))  retn = "IPv6AddrUnspecified"; else
3420    if (IN6_IS_ADDR_LOOPBACK(addr))     retn = "IPv6AddrLoopback"; else
3421    if (IN6_IS_ADDR_V4COMPAT(addr))     retn = "IPv6AddrV4Compat"; else
3422    if (IN6_IS_ADDR_V4MAPPED(addr))     retn = "IPv6AddrV4Mapped"; else
3423 
3424    if (IN6_IS_ADDR_LINKLOCAL(addr))    retn = "IPv6AddrLinkLocal"; else
3425    if (IN6_IS_ADDR_SITELOCAL(addr))    retn = "IPv6AddrSiteLocal"; else
3426 
3427    if (IN6_IS_ADDR_MC_NODELOCAL(addr)) retn = "IPv6AddrMulticastNodeLocal"; else
3428    if (IN6_IS_ADDR_MC_LINKLOCAL(addr)) retn = "IPv6AddrMulticastLinkLocal"; else
3429    if (IN6_IS_ADDR_MC_SITELOCAL(addr)) retn = "IPv6AddrMulticastSiteLocal"; else
3430    if (IN6_IS_ADDR_MC_ORGLOCAL(addr))  retn = "IPv6AddrMulticastOrgLocal"; else
3431    if (IN6_IS_ADDR_MC_GLOBAL(addr))    retn = "IPv6AddrMulticastGlobal";
3432 
3433    return (retn);
3434 }
3435 
3436 
3437 char ArgusIPv4AddressLabelBuffer[1024];
3438 char *ArgusReturnLabel (struct RaAddressStruct *);
3439 
3440 char *
RaFetchIPv4AddressLabel(struct ArgusParserStruct * parser,unsigned int * aptr)3441 RaFetchIPv4AddressLabel(struct ArgusParserStruct *parser, unsigned int *aptr)
3442 {
3443    struct ArgusLabelerStruct *labeler;
3444    struct RaAddressStruct *raddr;
3445    unsigned int addr = *aptr;
3446    char *retn = NULL;
3447 
3448    bzero(ArgusIPv4AddressLabelBuffer, sizeof(ArgusIPv4AddressLabelBuffer));
3449 
3450    if ((labeler = parser->ArgusLabeler) != NULL) {
3451       if (labeler->ArgusAddrTree) {
3452          struct RaAddressStruct node;
3453          bzero ((char *)&node, sizeof(node));
3454 
3455          node.addr.type = AF_INET;
3456          node.addr.len = 4;
3457          node.addr.addr[0] = addr;
3458          node.addr.masklen = 32;
3459 
3460          if ((raddr = RaFindAddress (parser, labeler->ArgusAddrTree[AF_INET], &node, ARGUS_LONGEST_MATCH)) != NULL)
3461             retn = ArgusReturnLabel(raddr);
3462       }
3463    }
3464 
3465    return(retn);
3466 }
3467 
3468 
3469 char *
RaPortLabel(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus,char * buf,int len)3470 RaPortLabel (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus, char *buf, int len)
3471 {
3472    struct ArgusFlow *flow = (struct ArgusFlow *) argus->dsrs[ARGUS_FLOW_INDEX];
3473    char *retn = NULL, *sport = NULL, *dport = NULL;
3474    int found = 0;
3475 
3476    bzero (buf, len);
3477    if (flow != NULL) {
3478       switch(flow->hdr.subtype & 0x3F) {
3479          case ARGUS_FLOW_LAYER_3_MATRIX:
3480          case ARGUS_FLOW_CLASSIC5TUPLE: {
3481             switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
3482                case ARGUS_TYPE_IPV4: {
3483                   if ((sport = RaFetchIPPortLabel(parser, flow->ip_flow.ip_p, flow->ip_flow.sport)) != NULL) {
3484                      if (strlen(sport)) {
3485                         int slen = strlen(buf);
3486                         snprintf (&buf[slen], len - slen, "sport=%s", sport);
3487                         found++;
3488                      }
3489                   }
3490                   if ((dport = RaFetchIPPortLabel(parser, flow->ip_flow.ip_p, flow->ip_flow.dport)) != NULL) {
3491                      if (strlen(dport)) {
3492                         int slen = strlen(buf);
3493                         if (found) {
3494                            snprintf (&buf[slen], len - slen, ":");
3495                            slen++;
3496                         }
3497                         snprintf (&buf[slen], len - slen, "dport=%s", dport);
3498                         found++;
3499                      }
3500                   }
3501                }
3502             }
3503          }
3504       }
3505    }
3506 
3507    if (found)
3508       retn = buf;
3509 
3510    return(retn);
3511 }
3512 
3513 
3514 char ArgusIPPortLabelBuffer[1024];
3515 
3516 char *
RaFetchIPPortLabel(struct ArgusParserStruct * parser,unsigned short proto,unsigned short port)3517 RaFetchIPPortLabel(struct ArgusParserStruct *parser, unsigned short proto, unsigned short port)
3518 {
3519    struct RaPortStruct **array = NULL, *ps = NULL;
3520    struct ArgusLabelerStruct *labeler;
3521    char *retn = NULL;
3522 
3523    bzero(ArgusIPPortLabelBuffer, sizeof(ArgusIPPortLabelBuffer));
3524 
3525    if ((labeler = parser->ArgusLabeler) != NULL) {
3526       switch (proto) {
3527          case IPPROTO_TCP:
3528             array = labeler->ArgusTCPPortLabels;
3529             break;
3530 
3531          case IPPROTO_UDP:
3532             array = labeler->ArgusUDPPortLabels;
3533             break;
3534       }
3535 
3536       if (array != NULL)
3537          if ((ps = array[port]) != NULL)
3538             retn = ps->label;
3539    }
3540 
3541    return(retn);
3542 }
3543 
3544 
3545 char *
RaFlowLabel(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus,char * buf,int len)3546 RaFlowLabel (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus, char *buf, int len)
3547 {
3548    struct ArgusLabelerStruct *labeler = NULL;
3549    struct RaFlowLabelStruct *raflow = NULL;
3550    int found = 0, count = 0, done = 0, x, z;
3551    struct ArgusQueueStruct *queue = NULL;
3552    char *retn = NULL;
3553 
3554    if ((labeler = parser->ArgusLabeler) == NULL)
3555       ArgusLog (LOG_ERR, "RaProcessAddress: No labeler\n");
3556 
3557    bzero (buf, len);
3558 
3559    if ((queue = labeler->ArgusFlowQueue) && ((count = labeler->ArgusFlowQueue->count) > 0)) {
3560       for (x = 0, z = count; x < z; x++) {
3561          if ((raflow = (void *)ArgusPopQueue(queue, ARGUS_NOLOCK)) != NULL) {
3562             if (!done) {
3563                int pass = 1;
3564                if (raflow->filterstr != NULL) {
3565                   struct nff_insn *wfcode = raflow->filter.bf_insns;
3566                   pass = ArgusFilterRecord (wfcode, argus);
3567                }
3568 
3569                if (pass != 0) {
3570                   int slen = strlen(buf);
3571                   if (found) {
3572                      snprintf (&buf[slen], MAXSTRLEN - slen, ":");
3573                      slen++;
3574                   }
3575                   snprintf (&buf[slen], MAXSTRLEN - slen, "flow=%s", raflow->labelstr);
3576                   found++;
3577                   if (raflow->cont == 0)
3578                      done = 1;
3579                }
3580             }
3581             ArgusAddToQueue (queue, &raflow->qhdr, ARGUS_NOLOCK);
3582          }
3583       }
3584    }
3585 
3586    if (found)
3587       retn = buf;
3588 
3589    return(retn);
3590 }
3591 
3592 
3593 char *
ArgusReturnLabel(struct RaAddressStruct * raddr)3594 ArgusReturnLabel (struct RaAddressStruct *raddr)
3595 {
3596    char *retn = NULL, *ptr = NULL;
3597 
3598    if (raddr->p)
3599       ptr = ArgusReturnLabel(raddr->p);
3600 
3601    if (raddr->label) {
3602       if (ptr != NULL) {
3603          int slen = strlen(ptr) + strlen(raddr->label) + 2;
3604          if ((retn = malloc(slen)) != NULL)  {
3605             snprintf(retn, slen, "%s,%s", ptr, raddr->label);
3606             free(ptr);
3607          }
3608       } else
3609          retn = strdup(raddr->label);
3610    } else
3611       retn = ptr;
3612 
3613    return (retn);
3614 }
3615 
3616 
3617 char RaFlowColorBuffer[1024];
3618 
3619 char *
RaFlowColor(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus)3620 RaFlowColor (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus)
3621 {
3622    struct ArgusLabelerStruct *labeler = NULL;
3623    struct RaFlowLabelStruct *raflow = NULL;
3624    struct ArgusQueueStruct *queue = NULL;
3625    int count = 0, done = 0, x, z;
3626    char *retn = NULL;
3627 
3628    if ((labeler = parser->ArgusColorLabeler) == NULL)
3629       return(retn);
3630 
3631    bzero (RaFlowColorBuffer, sizeof(RaFlowColorBuffer));
3632 
3633    if ((queue = labeler->ArgusFlowQueue) && ((count = labeler->ArgusFlowQueue->count) > 0)) {
3634       for (x = 0, z = count; x < z; x++) {
3635          if ((raflow = (void *)ArgusPopQueue(queue, ARGUS_NOLOCK)) != NULL) {
3636             if (!done) {
3637                int pass = 1;
3638                if (raflow->filterstr != NULL) {
3639                   struct nff_insn *wfcode = raflow->filter.bf_insns;
3640                   pass = ArgusFilterRecord (wfcode, argus);
3641                }
3642 
3643                if (pass != 0) {
3644                   int slen = strlen(RaFlowColorBuffer);
3645                   if (slen) {
3646                      snprintf (&RaFlowColorBuffer[slen], 1024 - slen, ";");
3647                      slen++;
3648                   }
3649                   snprintf (&RaFlowColorBuffer[slen], 1024 - slen, "%s", raflow->colorstr);
3650                   if (raflow->cont == 0)
3651                      done = 1;
3652                }
3653             }
3654             ArgusAddToQueue (queue, &raflow->qhdr, ARGUS_NOLOCK);
3655          }
3656       }
3657    }
3658 
3659    if (strlen(RaFlowColorBuffer))
3660       retn = RaFlowColorBuffer;
3661 
3662    return(retn);
3663 }
3664 
3665 
3666 int RaLabelItemNum = 0;
3667 
3668 float xBaseValue = 30.0;
3669 float yBaseValue = 100.0;
3670 
3671 float yDelta = -2.0;
3672 float xDelta = -12.0;
3673 
3674 void
RaMapLabelMol(struct ArgusLabelerStruct * labeler,struct RaAddressStruct * node,int level,int x,int y,int dir)3675 RaMapLabelMol (struct ArgusLabelerStruct *labeler, struct RaAddressStruct *node, int level, int x, int y, int dir)
3676 {
3677    if (node != NULL) {
3678       x += (xDelta * 16.0/node->addr.masklen);
3679       if (node->r) RaMapLabelMol(labeler, node->r, level + 1, x, y, dir);
3680       node->x = x;
3681       node->y = yBaseValue + (RaLabelItemNum++ * yDelta);
3682       if (node->l) RaMapLabelMol(labeler, node->l, level + 1, x, y, dir);
3683    }
3684 }
3685 
3686 void
RaPrintLabelMol(struct ArgusLabelerStruct * labeler,struct RaAddressStruct * node,int level,int x,int y,int dir)3687 RaPrintLabelMol (struct ArgusLabelerStruct *labeler, struct RaAddressStruct *node, int level, int x, int y, int dir)
3688 {
3689    char strbuf[256];
3690    float xl, yl, zl;
3691    int slen = 0;
3692 
3693    if (node != NULL) {
3694       float size = 0.2;
3695 
3696       if (node->addr.masklen)
3697          size = 32.0/node->addr.masklen;
3698 
3699       if (node->r) {
3700          printf ("draw arrow {%f %f %f} {%f %f %f}\n", node->x, node->y, 0.0, node->r->x, node->r->y, 0.0);
3701          RaPrintLabelMol(labeler, node->r, level + 1, x, y, RA_SRV_RIGHT);
3702       }
3703 
3704       if (!(node->r || node->l))
3705          printf ("draw color green\n");
3706 
3707       printf ("draw sphere {%f %f %f} radius %f resolution 32\n", node->x, node->y, 0.0, size);
3708 
3709       snprintf (strbuf, sizeof(strbuf), "%s/%d ", intoa(node->addr.addr[0] & (0xFFFFFFFF << (32 - node->addr.masklen))), node->addr.masklen);
3710       printf ("draw color white\n");
3711       slen = strlen(strbuf);
3712 
3713       if (node->label) {
3714          char *ptr;
3715          if ((ptr = strchr (node->label, '\n')) != NULL) *ptr = '\0';
3716          snprintf (&strbuf[slen], sizeof(strbuf) - slen,  "%s", node->label);
3717          xl = node->x; yl = node->y; zl = (size*2 + 0.25);
3718 
3719       } else {
3720          snprintf (&strbuf[slen], sizeof(strbuf) - slen,  "\"");
3721          xl = node->x; yl = node->y; zl = (size*2 + 0.25);
3722       }
3723 
3724       printf ("draw text {%f %f %f} \"%s size %f\n", xl, yl, zl, strbuf, size/4);
3725       printf ("draw color blue\n");
3726 
3727       if (node->l) {
3728          printf ("draw arrow {%f %f %f} {%f %f %f}\n", node->x, node->y, 0.0, node->l->x, node->l->y, 0.0);
3729          RaPrintLabelMol(labeler, node->l, level + 1, x, y, RA_SRV_LEFT);
3730       }
3731    }
3732 }
3733 
3734 
3735 
3736 char RaAddrTreeArray[MAXSTRLEN];
3737 
3738 void
RaPrintLabelTree(struct ArgusLabelerStruct * labeler,struct RaAddressStruct * node,int level,int dir)3739 RaPrintLabelTree (struct ArgusLabelerStruct *labeler, struct RaAddressStruct *node, int level, int dir)
3740 {
3741    int i = 0, length, len;
3742    int olen = strlen(RaAddrTreeArray);
3743    char str[MAXSTRLEN], chr = ' ';
3744 
3745    if (level > RaPrintLabelTreeLevel)
3746       return;
3747 
3748    bzero(str, MAXSTRLEN);
3749 
3750    if (node != NULL) {
3751       switch (labeler->RaPrintLabelTreeMode) {
3752 
3753          case ARGUS_TREE:
3754          case ARGUS_TREE_VISITED: {
3755             if (node->status & ARGUS_VISITED) {
3756                if (dir == RA_SRV_LEFT) {
3757                   strcat (str, "   |");
3758                   strcat (RaAddrTreeArray, str);
3759                   printf ("%s\n", RaAddrTreeArray);
3760                }
3761 
3762                length = strlen(RaAddrTreeArray);
3763                if ((len = length) > 0) {
3764                   chr = RaAddrTreeArray[len - 1];
3765                   if (node->r != NULL) {
3766                      if (dir == RA_SRV_RIGHT)
3767                         RaAddrTreeArray[len - 1] = ' ';
3768                   }
3769                }
3770 
3771                strcat (RaAddrTreeArray, "   |");
3772 
3773                RaPrintLabelTree(labeler, node->r, level + 1, RA_SRV_RIGHT);
3774 
3775                for (i = length, len = strlen(RaAddrTreeArray); i < len; i++)
3776                   RaAddrTreeArray[i] = '\0';
3777 
3778                if ((len = length) > 0)
3779                   RaAddrTreeArray[len - 1] = chr;
3780 
3781                printf ("%s+", RaAddrTreeArray);
3782 
3783                if (node->addr.str)
3784                   printf ("%s ", node->addr.str);
3785 
3786                else  {
3787                   if (node->addr.masklen > 0) {
3788                      printf ("%s/%d ", intoa(node->addr.addr[0] & (0xFFFFFFFF << (32 - node->addr.masklen))),
3789                                   node->addr.masklen);
3790 //                   printf ("%s ", intoa((0xFFFFFFFF << (32 - node->addr.masklen))));
3791                   } else
3792                      printf ("0.0.0.0/0 ");
3793                }
3794 
3795                if (strlen(node->cco))
3796                   printf ("%s ", node->cco);
3797 
3798                if (node->label)
3799                   printf ("%s ", node->label);
3800 
3801                if (node->ns) {
3802                   char buf[MAXSTRLEN];
3803                   bzero (buf, sizeof(buf));
3804                   ArgusPrintRecord(ArgusParser, buf, node->ns, MAXSTRLEN);
3805                   printf ("%s ", buf);
3806                }
3807 
3808                printf ("\n");
3809 
3810                len = strlen(RaAddrTreeArray);
3811                if (len > 0) {
3812                   chr = RaAddrTreeArray[len - 1];
3813                   if (node->l != NULL) {
3814                      if (dir == RA_SRV_LEFT)
3815                         RaAddrTreeArray[len - 1] = ' ';
3816                   }
3817                }
3818 
3819                RaPrintLabelTree(labeler, node->l, level + 1, RA_SRV_LEFT);
3820 
3821                if (dir == RA_SRV_RIGHT) {
3822                   printf ("%s", RaAddrTreeArray);
3823                   putchar ('\n');
3824                }
3825 
3826                for (i = olen, len = strlen(RaAddrTreeArray); i < len; i++)
3827                   RaAddrTreeArray[i] = '\0';
3828             }
3829             break;
3830          }
3831 
3832          case ARGUS_GRAPH: {
3833             if (node->status & ARGUS_VISITED) {
3834                if (node->r || node->l) {
3835                   if (node->r) {
3836                      if (node->addr.str)
3837                         printf ("\"%s\" ", node->addr.str);
3838                      else  {
3839                         if (node->addr.addr[0]) {
3840                            if (node->addr.masklen > 0) {
3841                               printf ("\"%s/%d\" ", intoa(node->addr.addr[0] & (0xFFFFFFFF << (32 - node->addr.masklen))),
3842                                         node->addr.masklen);
3843                            } else
3844                               printf ("\"0.0.0.0/0\" ");
3845                         }
3846                      }
3847                      printf (" -> ");
3848                      if (node->r->addr.str)
3849                         printf ("\"%s\"\n", node->r->addr.str);
3850                      else  {
3851                         if (node->r->addr.addr[0]) {
3852                            if (node->r->addr.masklen > 0) {
3853                               printf ("\"%s/%d\"\n", intoa(node->r->addr.addr[0] & (0xFFFFFFFF << (32 - node->r->addr.masklen))),
3854                                         node->r->addr.masklen);
3855                            } else
3856                               printf ("\"0.0.0.0/0\"\n");
3857                         }
3858                      }
3859                      RaPrintLabelTree(labeler, node->r, level + 1, RA_SRV_RIGHT);
3860                   }
3861 
3862                   if (node->l) {
3863                      if (node->addr.str)
3864                         printf ("\"%s\" ", node->addr.str);
3865                      else  {
3866                         if (node->addr.addr[0]) {
3867                            if (node->addr.masklen > 0) {
3868                               printf ("\"%s/%d\" ", intoa(node->addr.addr[0] & (0xFFFFFFFF << (32 - node->addr.masklen))),
3869                                         node->addr.masklen);
3870                            } else
3871                               printf ("\"0.0.0.0/0\" ");
3872                         }
3873                      }
3874                      printf (" -> ");
3875                      if (node->l->addr.str)
3876                         printf ("\"%s\"\n", node->l->addr.str);
3877                      else  {
3878                         if (node->l->addr.addr[0]) {
3879                            if (node->l->addr.masklen > 0) {
3880                               printf ("\"%s/%d\"\n", intoa(node->l->addr.addr[0] & (0xFFFFFFFF << (32 - node->l->addr.masklen))),
3881                                         node->l->addr.masklen);
3882                            } else
3883                               printf ("\"0.0.0.0/0\"\n");
3884                         }
3885                      }
3886                      RaPrintLabelTree(labeler, node->l, level + 1, RA_SRV_RIGHT);
3887                   }
3888                }
3889             }
3890             break;
3891          }
3892       }
3893    }
3894 }
3895 
3896