You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3644 lines
116 KiB
3644 lines
116 KiB
# --- SDE-COPYRIGHT-NOTE-BEGIN --- |
|
# This copyright note is auto-generated by ./scripts/Create-CopyPatch. |
|
# |
|
# Filename: package/.../sancp/sancp-1.6.1-stable-prelude-3.diff |
|
# Copyright (C) 2007 The OpenSDE Project |
|
# |
|
# More information can be found in the files COPYING and README. |
|
# |
|
# This patch file is dual-licensed. It is available under the license the |
|
# patched project is licensed under, as long as it is an OpenSource license |
|
# as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms |
|
# of the GNU General Public License as published by the Free Software |
|
# Foundation; either version 2 of the License, or (at your option) any later |
|
# version. |
|
# --- SDE-COPYRIGHT-NOTE-END --- |
|
|
|
diff -ruN sancp-1.6.1-stable.vanilla/Makefile sancp-1.6.1-stable/Makefile |
|
--- sancp-1.6.1-stable.vanilla/Makefile 2007-07-07 00:46:11.000000000 +0200 |
|
+++ sancp-1.6.1-stable/Makefile 2007-07-24 13:44:01.000000000 +0200 |
|
@@ -9,7 +9,7 @@ |
|
|
|
|
|
# LINUX and BSD CFLAGS |
|
-CFLAGS = -O3 -I/usr/include/pcap -I/usr/local/include/pcap -I./ -L/usr/lib/libsocket.so -g -L/opt/csw/lib -ggdb |
|
+CFLAGS = -g -O3 -I/usr/include/pcap -I/usr/local/include/pcap -I./ -L/usr/lib/libsocket.so -g -L/opt/csw/lib -ggdb `libprelude-config --cflags` |
|
|
|
# LINUX LFLAGS |
|
LFLAGS = -lresolv -lnsl -lpcap -L/usr/lib/libpcap.so.0.6.2 |
|
@@ -41,10 +41,10 @@ |
|
bsd : |
|
@(echo "#define PLATFORM_BSD" > platform.h) |
|
@make final |
|
- g++ -Wall $(BFLAGS) $(CFLAGS) -o sancp sancp.o misc_functs.o check_packet.o statefull_logging.o build_acl.o apply_rule.o decode.o pcap_functions.o pcapFileHandle.o fileHandle.o MemoryPool.o permissions.o outputFileHandle.o help.o |
|
+ g++ -Wall $(BFLAGS) $(CFLAGS) -o sancp sancp.o misc_functs.o check_packet.o statefull_logging.o build_acl.o apply_rule.o decode.o pcap_functions.o pcapFileHandle.o fileHandle.o MemoryPool.o permissions.o outputFileHandle.o help.o `libprelude-config --libs` `libprelude-config --ldflags` |
|
|
|
linux : |
|
@(echo "#define PLATFORM_LINUX" > platform.h) |
|
@make final |
|
- g++ -Wall $(LFLAGS) $(CFLAGS) -o sancp sancp.o misc_functs.o check_packet.o statefull_logging.o build_acl.o apply_rule.o decode.o pcap_functions.o pcapFileHandle.o fileHandle.o MemoryPool.o permissions.o outputFileHandle.o help.o |
|
+ g++ -Wall $(LFLAGS) $(CFLAGS) -o sancp sancp.o misc_functs.o check_packet.o statefull_logging.o build_acl.o apply_rule.o decode.o pcap_functions.o pcapFileHandle.o fileHandle.o MemoryPool.o permissions.o outputFileHandle.o help.o `libprelude-config --libs` `libprelude-config --ldflags` |
|
|
|
diff -ruN sancp-1.6.1-stable.vanilla/apply_rule.cc sancp-1.6.1-stable/apply_rule.cc |
|
--- sancp-1.6.1-stable.vanilla/apply_rule.cc 2007-07-05 18:12:20.000000000 +0200 |
|
+++ sancp-1.6.1-stable/apply_rule.cc 2007-07-24 13:44:01.000000000 +0200 |
|
@@ -47,6 +47,12 @@ |
|
tc->tcplag=myacl->tcplag; |
|
tc->status=myacl->status; |
|
tc->rid=myacl->rid; |
|
+ tc->prelude_impact_severity=myacl->prelude_impact_severity; |
|
+ tc->prelude_impact_completion=myacl->prelude_impact_completion; |
|
+ tc->prelude_impact_type=myacl->prelude_impact_type; |
|
+ tc->prelude_confidence_rating=myacl->prelude_confidence_rating; |
|
+ |
|
+ |
|
|
|
if(myacl->pmode==OMODE_UNIQ) |
|
{ |
|
@@ -112,6 +118,10 @@ |
|
nc->rgid=myacl->rgid; |
|
nc->zone=myacl->zone; |
|
nc->node=myacl->node; |
|
+ nc->prelude_impact_severity=myacl->prelude_impact_severity; |
|
+ nc->prelude_impact_completion=myacl->prelude_impact_completion; |
|
+ nc->prelude_impact_type=myacl->prelude_impact_type; |
|
+ nc->prelude_confidence_rating=myacl->prelude_confidence_rating; |
|
myacl->ctr++; |
|
return; |
|
} |
|
@@ -130,6 +140,10 @@ |
|
nc->timeout=gVars.default_timeout; |
|
nc->tcplag=gVars.default_tcplag; |
|
nc->node=gVars.default_node; |
|
+ nc->prelude_impact_severity=gVars.prelude_impact_severity; |
|
+ nc->prelude_impact_completion=gVars.prelude_impact_completion; |
|
+ nc->prelude_impact_type=gVars.prelude_impact_type; |
|
+ nc->prelude_confidence_rating=gVars.prelude_confidence_rating; |
|
gVars.default_ctr++; |
|
#ifdef DEBUG |
|
printf("Setting stats: %d pcap: %d realtime: %d limit: %d timeout: %d tcplag: %d\n", nc->stats, nc->pcap, nc->realtime, nc->limit, nc->timeout, nc->tcplag); |
|
diff -ruN sancp-1.6.1-stable.vanilla/build_acl.cc sancp-1.6.1-stable/build_acl.cc |
|
--- sancp-1.6.1-stable.vanilla/build_acl.cc 2007-07-05 18:12:20.000000000 +0200 |
|
+++ sancp-1.6.1-stable/build_acl.cc 2007-07-24 13:44:01.000000000 +0200 |
|
@@ -1168,6 +1168,62 @@ |
|
fprintf(stdout,"Didn't set default for %s to %s\n",tok,tmp); |
|
#endif |
|
} |
|
+ if(strcmp(tok,"prelude_impact_severity")==0) |
|
+ { |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, prelude_impact_severity specified but none provided, using prelude_impact_severity %s\n",PRELUDE_IMPACT_SEVERITY); |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ gVars.prelude_impact_severity = strdup(tmp); |
|
+ free(rule); |
|
+ } |
|
+ if(strcmp(tok,"prelude_impact_completion")==0) |
|
+ { |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, prelude_impact_completion specified but none provided, using prelude_impact_completion %s\n",PRELUDE_IMPACT_COMPLETION); |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ gVars.prelude_impact_completion = strdup(tmp); |
|
+ free(rule); |
|
+ } |
|
+ if(strcmp(tok,"prelude_impact_type")==0) |
|
+ { |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, prelude_impact_type specified but none provided, using prelude_impact_type %s\n",PRELUDE_IMPACT_TYPE); |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ gVars.prelude_impact_type = strdup(tmp); |
|
+ free(rule); |
|
+ } |
|
+ if(strcmp(tok,"prelude_confidence_rating")==0) |
|
+ { |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, prelude_confidence_rating specified but none provided, using prelude_confidence_rating %s\n",PRELUDE_CONFIDENCE_RATING); |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ gVars.prelude_confidence_rating = strdup(tmp); |
|
+ free(rule); |
|
+ } |
|
+ if(strcmp(tok,"prelude_profile")==0) |
|
+ { |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, prelude_profile specified but none provided, using prelude_profile %s\n",PRELUDE_PROFILE); |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ gVars.prelude_profile = strdup(tmp); |
|
+ free(rule); |
|
+ } |
|
+ |
|
} |
|
|
|
void parse_var(char *c_rule, char *accept) |
|
@@ -1426,6 +1482,10 @@ |
|
}else{ |
|
n_acl->fH = 0; |
|
} |
|
+ n_acl->prelude_impact_severity = gVars.prelude_impact_severity; |
|
+ n_acl->prelude_impact_completion = gVars.prelude_impact_completion; |
|
+ n_acl->prelude_impact_type = gVars.prelude_impact_type; |
|
+ n_acl->prelude_confidence_rating = gVars.prelude_confidence_rating; |
|
|
|
// FIELD 0 - required - Get the h_proto |
|
n_acl->h_proto_h = 0xFFFF; |
|
@@ -2061,6 +2121,46 @@ |
|
n_acl->retro = true; |
|
continue; |
|
} |
|
+ if(strcmp(tok,"severity")==0) |
|
+ { |
|
+ if((tmp = get_tok(rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, severity specified but no option provided%s\n",rule); |
|
+ return; |
|
+ } |
|
+ n_acl->prelude_impact_severity = strdup(tmp); |
|
+ continue; |
|
+ } |
|
+ if(strcmp(tok,"completion")==0) |
|
+ { |
|
+ if((tmp = get_tok(rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, completion specified but no option provided%s\n",rule); |
|
+ return; |
|
+ } |
|
+ n_acl->prelude_impact_completion = strdup(tmp); |
|
+ continue; |
|
+ } |
|
+ if(strcmp(tok,"type")==0) |
|
+ { |
|
+ if((tmp = get_tok(rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, type specified but no option provided%s\n",rule); |
|
+ return; |
|
+ } |
|
+ n_acl->prelude_impact_type = strdup(tmp); |
|
+ continue; |
|
+ } |
|
+ if(strcmp(tok,"confidence")==0) |
|
+ { |
|
+ if((tmp = get_tok(rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, confidence specified but no option provided%s\n",rule); |
|
+ return; |
|
+ } |
|
+ n_acl->prelude_confidence_rating = strdup(tmp); |
|
+ continue; |
|
+ } |
|
syslog(LOG_ERR,"Skipping, invalid option in rule: %s %s\n", tok,*rules); |
|
return; |
|
} |
|
diff -ruN sancp-1.6.1-stable.vanilla/build_acl.cc~ sancp-1.6.1-stable/build_acl.cc~ |
|
--- sancp-1.6.1-stable.vanilla/build_acl.cc~ 1970-01-01 01:00:00.000000000 +0100 |
|
+++ sancp-1.6.1-stable/build_acl.cc~ 2007-07-05 18:12:20.000000000 +0200 |
|
@@ -0,0 +1,2648 @@ |
|
+#ifndef SANCP_H |
|
+#include "sancp.h" |
|
+#endif |
|
+//#define DEBUG |
|
+/************************************************************************** |
|
+ **SA Network Connection Profiler [sancp] - A TCP/IP statistical/collection tool |
|
+ * ************************************************************************ |
|
+ * * Copyright (C) 2003 John Curry <john.curry@metre.net> |
|
+ * * |
|
+ * * This program is distributed under the terms of version 1.0 of the |
|
+ * * Q Public License. See LICENSE.QPL for further details. |
|
+ * * |
|
+ * * This program is distributed in the hope that it will be useful, |
|
+ * * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
+ * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
+ * * |
|
+ * ***********************************************************************/ |
|
+ |
|
+void license(); |
|
+void version(); |
|
+struct acl *tacl_head=NULL, *tacl_tail=NULL; |
|
+struct t_ports *tports[MAX_IP_PROTO]; |
|
+void set_bpf_filter( char *); |
|
+char * get_tok(char **rule, const char * accept); |
|
+void parse_default(char *rule, char *accept); |
|
+char * get_next_tok(char **rule, const char *delimiters); |
|
+char *rev_search_vars(char *key, struct vars *var_head, int ); |
|
+ |
|
+int fgetcline (char **buf, int size, FILE *fp){ |
|
+ int len; |
|
+ int c=0; |
|
+ if( fp== NULL){ |
|
+ syslog(LOG_ERR,"Invalid FILE handle\n"); |
|
+ return -1; |
|
+ } |
|
+ if(feof(fp)){ |
|
+ syslog(LOG_ERR,"Early END OF FILE\n"); |
|
+ return -1; |
|
+ } |
|
+ if (*buf == NULL){ |
|
+ if( size == 0) |
|
+ size=BUFSIZ; |
|
+ if((*buf = (char *)calloc(1,size)) == NULL){ |
|
+ syslog(LOG_ERR,"Out of memory\n"); |
|
+ return -1; |
|
+ } |
|
+ } |
|
+ len=0; |
|
+// Get characters until EOF or ';' |
|
+ while (((c = getc(fp)) != EOF) && c!='\n' && c!='\r'){ |
|
+ if(c=='\\'){ |
|
+ if((c = getc(fp))==EOF){ |
|
+ break; |
|
+ } |
|
+ if(c=='\n'){ |
|
+ c=' '; |
|
+ }else{ |
|
+ ungetc(c,fp); |
|
+ c='\\'; |
|
+ } |
|
+ } |
|
+ if(c == '#'){ |
|
+ // if comment mark, FF to end of line |
|
+ while( (c = getc(fp))!= EOF && c !='\n'); |
|
+ //if(c=='\n'){ break;} |
|
+ //if(c==EOF){ break; } |
|
+ break; |
|
+ } |
|
+ if(len+1 >= size) { |
|
+ if(( *buf = (char *)realloc(*buf, size += BUFSIZ))==NULL){ |
|
+ syslog(LOG_ERR,"Out of memory\n"); |
|
+ free(*buf); |
|
+ return -1; |
|
+ } |
|
+ } |
|
+ if(c == ',' || c == '=' ) { |
|
+ c = ' '; |
|
+ } |
|
+ // |
|
+ // Make everything lower case for now |
|
+ // |
|
+ if(!(len==0 && (c==' ' || c=='\t'))) |
|
+ (*buf)[len++]=tolower(c); |
|
+ |
|
+ if(c == '\t' || c == ' ' ){ |
|
+ while( (c=fgetc(fp))!= EOF && c!='\n' && (c=='\t' || c==' ')); |
|
+ //while( (c=fgetc(fp))!= EOF && c!='\n' && (c=='\t' || c==' ' || c==',' || c=='=')); |
|
+ if(c=='\n'|| c==EOF){ break; } |
|
+ // Trunicate comments |
|
+ if(c=='#') (*buf)[len]='\0'; |
|
+ ungetc(c,fp); |
|
+ // If we ran into a '#' sign, then just turn the last \t or space into a null. |
|
+ } |
|
+ } |
|
+ if (len == 0 && c == EOF){ |
|
+ if(*buf!=NULL) |
|
+ free(*buf); |
|
+ return -1; |
|
+ } |
|
+ if(len>0 && ((*buf)[len-1]==' ' || (*buf)[len-1]=='\t')){ |
|
+ (*buf)[len-1]='\0'; |
|
+ return len-1; |
|
+ }else{ |
|
+ (*buf)[len++]='\0'; |
|
+ return len; |
|
+ } |
|
+} |
|
+ |
|
+void parse_args(int argc, char *argv[]) |
|
+{ |
|
+ extern struct gvars gVars; |
|
+ u_int64_t num; |
|
+ char *ftmp=0; |
|
+ //int ctr=0; |
|
+ for(int ctr=1; ctr < argc; ctr++) |
|
+ { |
|
+ if(strcmp(argv[ctr],"--schemas")==0) |
|
+ { |
|
+ // once we finished reading the config, we will print the schemas and exit |
|
+ gVars.print_schemas = 1; |
|
+ }else{ |
|
+ if(strcmp(argv[ctr],"--shift")==0) |
|
+ { |
|
+ // enable internal 2 byte shifting the packet read from file |
|
+ // 'any' interface |
|
+ gVars.shift = 1; |
|
+ }else{ |
|
+ if(strcmp(argv[ctr],"-K")==0 || strcmp(argv[ctr],"--console")==0) |
|
+ { |
|
+ // enable console mode - log realtimes to stdout |
|
+ gVars.console_mode = 1; |
|
+ |
|
+ }else{ |
|
+ if(strcmp(argv[ctr],"-D")==0 || strcmp(argv[ctr],"--daemon")==0) |
|
+ { |
|
+ // enable daemon mode |
|
+ gVars.daemon_mode = 1; |
|
+ openlog(NAME,LOG_CONS,gVars.log_facility); |
|
+ }else{ |
|
+ if(strcmp(argv[ctr],"-C")==0 || strcmp(argv[ctr],"--last_cnxid")==0) |
|
+ { |
|
+ // set last connection id to use - ~~~! Need to supply -d argument first !~~~ |
|
+ if( ctr < argc-1 ){ |
|
+ ctr++; |
|
+ ftmp=argv[ctr]; |
|
+ num = (u_int64_t) strtoll(argv[ctr],&ftmp,0); |
|
+ if(argv[ctr]==ftmp) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, invalid last_cnxid: %s, using cnxid %llu\n",argv[ctr],(long long unsigned)gVars.cnx_id); |
|
+ }else |
|
+ manage_cid(0); |
|
+ if(gVars.cnx_id>num){ |
|
+ syslog(LOG_ERR,"cnxid provided (%llu) is less than 64bit cnxid in the '.cnxid' cache file, using cnxid %llu from cache instead\n",num,(long long unsigned) gVars.cnx_id); |
|
+ }else{ |
|
+ syslog(LOG_ERR,"Using cnxid provided (%llu) rather than the last cnxid in the '.cnxid' cache file (%llu)\n",num,(long long unsigned) gVars.cnx_id); |
|
+ // Save the new cnx_id |
|
+ gVars.cnx_id=num; |
|
+ manage_cid(1); |
|
+ } |
|
+ }else{ |
|
+ syslog(LOG_ERR,"No cnxid provided with -C/--last_cnxid option\n"); |
|
+ exit(0); |
|
+ } |
|
+ }else{ |
|
+ if(strcmp(argv[ctr],"-i")==0) |
|
+ { |
|
+ // Set device name |
|
+ if( ctr < argc-1 ){ |
|
+ if(gVars.default_device){ free(gVars.default_device); } ctr++; |
|
+ if( (gVars.default_device = (char *)calloc(strlen(argv[ctr])+ 1,1) ) ==NULL){ |
|
+ syslog(LOG_ERR,"Unable to allocate memory for -i option\n"); |
|
+ exit(0); |
|
+ } |
|
+ bcopy(argv[ctr],gVars.default_device,strlen(argv[ctr])); |
|
+ gVars.shift=0; // disable shift (only needed for 'any' interface) |
|
+ if(strstr(gVars.default_device,DEFAULT_DEVICE)) |
|
+ gVars.shift=1; |
|
+ }else{ |
|
+ syslog(LOG_ERR,"No device name provided with -i option\n"); |
|
+ exit(0); |
|
+ } |
|
+ }else{ |
|
+ if(strcmp(argv[ctr],"-d")==0) |
|
+ { |
|
+ // Set log directory name |
|
+ if( ctr < argc-1 ){ |
|
+ if(gVars.log_directory){ free(gVars.log_directory); } ctr++; |
|
+ if( (gVars.log_directory = (char *)calloc(strlen(argv[ctr])+ 2,1) ) ==NULL){ |
|
+ syslog(LOG_ERR,"Unable to allocate memory for -d option\n"); |
|
+ exit(0); |
|
+ } |
|
+ bcopy(argv[ctr],gVars.log_directory,strlen(argv[ctr])); |
|
+ // We allocated an extra space for this... |
|
+ *(gVars.log_directory+strlen(argv[ctr]))='/'; |
|
+ }else{ |
|
+ syslog(LOG_ERR,"No directory provided with -d option\n"); |
|
+ exit(0); |
|
+ } |
|
+ }else{ |
|
+ if(strcmp(argv[ctr],"-r")==0) |
|
+ { |
|
+ // Set pcap input file name |
|
+ if( ctr < argc-1 ){ |
|
+ if(gVars.input_filename){ free(gVars.input_filename); } ctr++; |
|
+ if( (gVars.input_filename = (char *)calloc(strlen(argv[ctr])+1,1) ) ==NULL){ |
|
+ syslog(LOG_ERR,"Unable to allocate memory for -r option\n"); |
|
+ exit(0); |
|
+ } |
|
+ bcopy(argv[ctr],gVars.input_filename,strlen(argv[ctr])); |
|
+ gVars.shift=0; // disable shift (only needed for 'any' interface) |
|
+ }else{ |
|
+ syslog(LOG_ERR,"No pcap filename provided with -r option\n"); |
|
+ exit(0); |
|
+ } |
|
+ }else{ |
|
+ if(strcmp(argv[ctr],"-c")==0) |
|
+ { |
|
+ // Set configuration directory name |
|
+ if( ctr < argc-1 ){ |
|
+ if(gVars.config_file){ free(gVars.config_file); } ctr++; |
|
+ if( (gVars.config_file = (char *)calloc(strlen(argv[ctr])+1,1) ) ==NULL){ |
|
+ syslog(LOG_ERR,"Unable to allocate memory for -c option\n"); |
|
+ exit(0); |
|
+ } |
|
+ bcopy(argv[ctr],gVars.config_file,strlen(argv[ctr])); |
|
+ }else{ |
|
+ syslog(LOG_ERR,"No configuration filename provided with -c option\n"); |
|
+ exit(0); |
|
+ } |
|
+ }else{ |
|
+ if(strcmp(argv[ctr],"--log-facility")==0) |
|
+ { |
|
+ // Set log facility |
|
+ if( ctr < argc-1 ){ |
|
+ ctr++; |
|
+ if(strcmp(argv[ctr],"LOCAL1")==0) |
|
+ gVars.log_facility = LOG_LOCAL1; |
|
+ if(strcmp(argv[ctr],"LOCAL2")==0) |
|
+ gVars.log_facility = LOG_LOCAL2; |
|
+ if(strcmp(argv[ctr],"LOCAL3")==0) |
|
+ gVars.log_facility = LOG_LOCAL3; |
|
+ if(strcmp(argv[ctr],"LOCAL4")==0) |
|
+ gVars.log_facility = LOG_LOCAL4; |
|
+ if(strcmp(argv[ctr],"LOCAL5")==0) |
|
+ gVars.log_facility = LOG_LOCAL5; |
|
+ if(strcmp(argv[ctr],"LOCAL6")==0) |
|
+ gVars.log_facility = LOG_LOCAL6; |
|
+ if(strcmp(argv[ctr],"LOCAL7")==0) |
|
+ gVars.log_facility = LOG_LOCAL7; |
|
+ }else{ |
|
+ syslog(LOG_ERR,"No value provided with --log-facility option\n"); |
|
+ exit(0); |
|
+ } |
|
+ }else{ |
|
+ if(strcmp(argv[ctr],"-u")==0) |
|
+ { |
|
+ // Set username name |
|
+ if( ctr < argc-1 ){ |
|
+ if(gVars.username){ free(gVars.username); gVars.username=0; } ctr++; |
|
+ if( (gVars.username = (char *)calloc(strlen(argv[ctr])+ 1,1) ) ==NULL){ |
|
+ syslog(LOG_ERR,"Unable to allocate memory for -u option\n"); |
|
+ exit(0); |
|
+ } |
|
+ bcopy(argv[ctr],gVars.username,strlen(argv[ctr])); |
|
+ }else{ |
|
+ syslog(LOG_ERR,"No user provided with -u option\n"); |
|
+ exit(0); |
|
+ } |
|
+ }else{ |
|
+ if(strcmp(argv[ctr],"-g")==0) |
|
+ { |
|
+ // Set group name |
|
+ if( ctr < argc-1 ){ |
|
+ if(gVars.groupname){ free(gVars.groupname); gVars.groupname=0; } ctr++; |
|
+ if( (gVars.groupname = (char *)calloc(strlen(argv[ctr])+ 1,1) ) ==NULL){ |
|
+ syslog(LOG_ERR,"Unable to allocate memory for -g option\n"); |
|
+ exit(0); |
|
+ } |
|
+ bcopy(argv[ctr],gVars.groupname,strlen(argv[ctr])); |
|
+ }else{ |
|
+ syslog(LOG_ERR,"No group provided with -g option\n"); |
|
+ exit(0); |
|
+ } |
|
+ }else{ |
|
+ if(strcmp(argv[ctr],"-F")==0) |
|
+ { |
|
+ // Set bp filter file name |
|
+ if( ctr < argc-1 ){ |
|
+ ctr++; |
|
+ // We alloc mem here, but fileHandle will free it |
|
+ // This should be changed, but it works for now |
|
+ set_bpf_filter(argv[ctr]); |
|
+ syslog(LOG_INFO,"using file %s: %s\n",gVars.bpf_fname,argv[ctr]); |
|
+ //if(!gVars.daemon_mode) |
|
+ syslog(LOG_INFO,"enabling bpf filter from file %s: %s\n",gVars.bpf_fname,argv[ctr]); |
|
+ |
|
+ }else{ |
|
+ syslog(LOG_ERR,"No filename provided with -F option\n"); |
|
+ exit(0); |
|
+ } |
|
+ }else{ |
|
+ if(strcmp(argv[ctr],"--strip-80211")==0) |
|
+ { |
|
+ // enable removal of 80211 header |
|
+ gVars.strip_80211 = ENABLED; |
|
+ if(!gVars.daemon_mode) |
|
+ syslog(LOG_INFO,"enabling stripping of 80211 headers\n"); |
|
+ }else{ |
|
+ if(strcmp(argv[ctr],"--local-time")==0) |
|
+ { |
|
+ // disable GMT, enable localtime |
|
+ gVars.uselocaltime = 1; |
|
+ if(!gVars.daemon_mode) |
|
+ syslog(LOG_INFO,"enabling local timestamps instead of GMT\n"); |
|
+ }else{ |
|
+ if(strcmp(argv[ctr],"-A")==0) |
|
+ { |
|
+ // enable recording all data to tcpdump file before |
|
+ // processing, any strip-80211 option applies, however |
|
+ if(gVars.rpfH){ gVars.rpfH->destroy(); gVars.rpfH=0; } |
|
+ ftmp=createFileName(PCAP_RAW_FNAME); |
|
+ gVars.rpfH = new pcapFileHandle(ftmp); |
|
+ free(ftmp); |
|
+ gVars.pcap_raw = ENABLED; |
|
+ syslog(LOG_INFO,"enabling debug recording of all pcap data to a tcpdump file\n"); |
|
+ }else{ |
|
+ if(strcmp(argv[ctr],"-R")==0) |
|
+ { |
|
+ // disable realtime |
|
+ gVars.cmdl_realtimes_action = ACTION_PASS; |
|
+ gVars.rmode = OMODE_PASS; |
|
+ syslog(LOG_INFO,"disabling default 'realtimes' logging mode\n"); |
|
+ }else{ |
|
+ if(strcmp(argv[ctr],"-P")==0) |
|
+ { |
|
+ // disable default collect action |
|
+ gVars.cmdl_pcap_action = ACTION_PASS; |
|
+ gVars.pmode = OMODE_PASS; |
|
+ syslog(LOG_INFO,"disabling default 'pcap' logging mode\n"); |
|
+ |
|
+ }else{ |
|
+ if(strcmp(argv[ctr],"-S")==0) |
|
+ { |
|
+ // disable default log action |
|
+ gVars.cmdl_stats_action = ACTION_PASS; |
|
+ gVars.smode = OMODE_PASS; |
|
+ syslog(LOG_INFO,"disabling default 'stats' logging mode\n"); |
|
+ }else{ |
|
+ if(strcmp(argv[ctr],"-I")==0 || strcmp(argv[ctr],"--enable-icmp-mixed")==0) |
|
+ { |
|
+ // enable recording and tracking ICMP type/code in src and dst port fields |
|
+ gVars.log_icmp_type_code = 1; |
|
+ syslog(LOG_INFO,"enabling logging icmp type/code for s_port and d_port fields\n"); |
|
+ }else{ |
|
+ if(strcmp(argv[ctr],"-B")==0) |
|
+ { |
|
+ // The rest of this line should be the bpf expression |
|
+ if(gVars.bpf_filter){ free(gVars.bpf_filter); } ctr++; |
|
+ if(argc>ctr){ |
|
+ gVars.bpf_filter=(char *) calloc(1,strlen(argv[ctr])+1); |
|
+ strncpy(gVars.bpf_filter,argv[ctr],strlen(argv[ctr])); |
|
+ syslog(LOG_INFO,"enabling bpf expression %s\n",gVars.bpf_filter); |
|
+ } |
|
+ |
|
+ }else{ |
|
+ if(strcmp(argv[ctr],"-H")==0 || strcmp(argv[ctr],"--human-readable")==0) |
|
+ { |
|
+ // enable human readable mode - affects IP addressess and tcp flag fields |
|
+ gVars.human_readable = 1; |
|
+ syslog(LOG_INFO,"enabling human readable connection logging\n"); |
|
+ |
|
+ }else{ |
|
+ if(strcmp(argv[ctr],"-V")==0||strcmp(argv[ctr],"-v")==0) |
|
+ { |
|
+ version(); |
|
+ license(); |
|
+ exit_all(0); |
|
+ }else{ |
|
+ if(strcmp(argv[ctr],"-?")==0 || strcmp(argv[ctr],"-h")==0){ |
|
+ version(); |
|
+ usage(); |
|
+ exit_all(0); |
|
+ }else{ |
|
+ // See if this was a -option |
|
+ if(strstr(argv[ctr],"-")){ |
|
+ syslog(LOG_ERR,"skipping unrecognized option: %s\n",argv[ctr]); |
|
+ |
|
+ }else{ |
|
+ // The rest of this line should be the bpf expression |
|
+ //if((argc-1)>(ctr++)){ |
|
+ if(gVars.bpf_filter){ free(gVars.bpf_filter); gVars.bpf_filter=0; } |
|
+ gVars.bpf_filter=(char *) calloc(1,strlen(argv[ctr])+1); |
|
+ strncpy(gVars.bpf_filter,argv[ctr],strlen(argv[ctr])); |
|
+ syslog(LOG_INFO,"enabling bpf expression %s\n",gVars.bpf_filter); |
|
+ //syslog(LOG_ERR,"Unknown option: %s\n",argv[ctr]); |
|
+ } |
|
+ //} |
|
+ |
|
+ }}}}}}}}}}}}}}}}}}}}}}}} |
|
+ } |
|
+ |
|
+ |
|
+} |
|
+void build_config(int a){ |
|
+ extern struct gvars gVars; |
|
+ int lc=0; |
|
+ FILE *config_file; |
|
+ int size=0; |
|
+ int mylen=0; |
|
+ char *rule=NULL; |
|
+ char *accept="\t ,="; |
|
+ struct vars *tmp_var=NULL; |
|
+ struct acl *tmp_acl=0; |
|
+ struct t_ports *ports_head; |
|
+ struct t_ports *tmp_port; |
|
+ int p=0; |
|
+ if(!gVars.config_file){ return; } |
|
+ if((config_file=fopen(gVars.config_file,"r")) == NULL ) { |
|
+ return; |
|
+ } |
|
+ // Drop the vars now |
|
+ while(gVars.var_head!=NULL){ tmp_var=gVars.var_head; gVars.var_head=gVars.var_head->next; if(tmp_var->key)free(tmp_var->key); if(tmp_var->value)free(tmp_var->value); free(tmp_var); } gVars.var_head=NULL; |
|
+ /* the first field should tell us everything we need to know about |
|
+ * what to expect in the rule |
|
+ */ |
|
+#ifdef DEBUG |
|
+ fprintf(stdout,"Reading config\n"); |
|
+#endif |
|
+ while((mylen=fgetcline(&rule, size, config_file)) >= 0){ |
|
+ lc++; |
|
+ if(mylen<2){ |
|
+#ifdef DEBUG |
|
+ fprintf(stdout,"Line: %d rule too small, skipping %s\n",lc, rule); |
|
+#endif |
|
+ continue; } |
|
+#ifdef DEBUG |
|
+ fprintf(stdout,"Processing %s\n",rule); |
|
+#endif |
|
+ if(strncmp(rule,"format",6)==0) |
|
+ { |
|
+ parse_format(rule,accept); |
|
+ } |
|
+ else if(strncmp(rule,"known_ports",11)==0) |
|
+ { |
|
+ parse_known_ports(rule,gVars.var_head,accept); |
|
+ } |
|
+ else if(strncmp(rule,"default",7)==0) |
|
+ { |
|
+ parse_default(rule,accept); |
|
+ }else if(strncmp(rule,"var",3)==0) |
|
+ { |
|
+ parse_var(rule,accept); |
|
+#ifdef DEBUG |
|
+ if(gVars.var_head!=NULL) |
|
+ fprintf(stdout,"Have var, %s/%s\n",gVars.var_head->key,gVars.var_head->value); |
|
+#endif |
|
+ }else{ |
|
+ parse_connection_rule(rule,gVars.var_head,accept); |
|
+ } |
|
+ if(rule){ |
|
+#ifdef DEBUG |
|
+ printf("freeing %X\n",(u_int32_t) &rule); |
|
+#endif |
|
+ free(rule); |
|
+ rule=NULL; |
|
+ } |
|
+ |
|
+ } |
|
+ fclose(config_file); |
|
+#ifdef DEBUG |
|
+ printf("Done reading rules\n"); |
|
+#endif |
|
+ // swap out old rules with new rules |
|
+ tmp_acl=gVars.acl_head; |
|
+ gVars.acl_head=tacl_head; |
|
+ tacl_head=tmp_acl; |
|
+#ifdef DEBUG |
|
+ printf("Disposing old rules\n"); |
|
+#endif |
|
+ // dispose of previous rules |
|
+ while(tacl_head!=NULL){ tmp_acl=tacl_head; tacl_head=tacl_head->next; free(tmp_acl);} |
|
+ tacl_head=NULL; tacl_tail=NULL; |
|
+ |
|
+#ifdef DEBUG |
|
+ printf("Disposing old ports\n"); |
|
+#endif |
|
+ //while(acl_head!=NULL){ tmpptr=acl_head; acl_head=acl_head->next; free(tmpptr); } |
|
+ // dispose of previous ports |
|
+ for(p=0; p<MAX_IP_PROTO; p++) |
|
+ { |
|
+ ports_head=gVars.ports[p]; |
|
+ |
|
+ while(ports_head!=NULL){ |
|
+ tmp_port=ports_head; |
|
+ ports_head=tmp_port->next; |
|
+ free(tmp_port); |
|
+ } |
|
+ gVars.ports[p]=tports[p]; |
|
+ tports[p]=NULL; |
|
+ } |
|
+ // Dispose of temporary rule variables |
|
+ // |
|
+} |
|
+ |
|
+void parse_format(const char *c_rule,const char *accept) |
|
+{ |
|
+ extern struct gvars gVars; |
|
+ extern char fmtnames[MAXFLDS][MAXFLDSIZE]; |
|
+ char *rule=(char *)calloc(1,strlen(c_rule)+1); |
|
+ memcpy(rule,c_rule,strlen(c_rule)); |
|
+ char *rules=rule; |
|
+ char *tok=0; |
|
+ if((tok = get_tok(&rules,accept))==NULL){ |
|
+ syslog(LOG_ERR,"Skipping, Invalid default, rule trunicated %s\n",rule); |
|
+ return; |
|
+ }else if((tok = get_tok(&rules,accept))==NULL){ |
|
+ syslog(LOG_ERR,"Skipping, Invalid default, rule trunicated %s\n",rule); |
|
+ return; |
|
+ } |
|
+ |
|
+ int type=0; |
|
+ if(strcmp(tok,"realtime")==0) |
|
+ type=1; |
|
+ if(strcmp(tok,"stats")==0) |
|
+ type=2; |
|
+ if(strcmp(tok,"stdout")==0) |
|
+ type=4; |
|
+ char delimiter=0; |
|
+ if(strncmp(rules,"delimiter",9)==0){ |
|
+ if((tok = get_tok(&rules,accept))==NULL){ |
|
+ syslog(LOG_ERR,"Skipping, Invalid delimiter, rule trunicated %s\n",rule); |
|
+ return; |
|
+ }else if((tok = get_tok(&rules,accept))==NULL){ |
|
+ syslog(LOG_ERR,"Skipping, Invalid delimiter, rule trunicated %s\n",rule); |
|
+ return; |
|
+ } |
|
+ delimiter=tok[0]; |
|
+ if(delimiter=='\\'){ |
|
+ if(tok[1]=='s') |
|
+ delimiter=' '; |
|
+ if(tok[1]=='t') |
|
+ delimiter='\t'; |
|
+ if(tok[1]=='n') |
|
+ delimiter='\n'; |
|
+ } |
|
+ } |
|
+ |
|
+ char eor=0; |
|
+ if(strncmp(rules,"eor",3)==0){ |
|
+ if((tok = get_tok(&rules,accept))==NULL){ |
|
+ syslog(LOG_ERR,"Skipping, Invalid eor, rule trunicated %s\n",rule); |
|
+ return; |
|
+ }else if((tok = get_tok(&rules,accept))==NULL){ |
|
+ syslog(LOG_ERR,"Skipping, Invalid eor, rule trunicated %s\n",rule); |
|
+ return; |
|
+ } |
|
+ eor=tok[0]; |
|
+ if(eor=='\\'){ |
|
+ if(tok[1]=='s') |
|
+ eor=' '; |
|
+ if(tok[1]=='t') |
|
+ eor='\t'; |
|
+ if(tok[1]=='n') |
|
+ eor='\n'; |
|
+ } |
|
+ } |
|
+ |
|
+ char *tmpfldnames; |
|
+ int col=0; |
|
+ int icol=0; |
|
+ int fmtval=0; |
|
+ char fmt[MAXFLDS]; |
|
+ while(rules && (tok = get_tok(&rules,accept))!=NULL && *tok != 0) |
|
+ { |
|
+ tmpfldnames=(char *)fmtnames; |
|
+ while((fmtval<MAXFLDS) && strncmp(tmpfldnames,tok,MAXFLDSIZE)){ |
|
+ /* keep track of the current index of fmtnames in fmtval */ |
|
+ tmpfldnames+=MAXFLDSIZE; fmtval++; |
|
+ } |
|
+ /* if our index (fmtval) exceeds MAXFLDS then we have no more room in our fmt array */ |
|
+ if(fmtval<MAXFLDS){ |
|
+ fmt[col]=fmtval; |
|
+ col++; |
|
+ }else{ |
|
+ syslog(LOG_ERR,"Skipping, invalid format field name %s for column %d",tok,icol); |
|
+ } |
|
+ if(col>MAXFLDS-1){ |
|
+ syslog(LOG_ERR,"Exceeded maximum columns allowed (%d) , skipping remaining format fields at column %d: %s",MAXFLDS,icol,rules); |
|
+ break; |
|
+ } |
|
+ icol++; |
|
+ fmtval=0; |
|
+ } |
|
+ if(type==1){ |
|
+ if(gVars.realtime_fmt_len){ |
|
+ free(gVars.realtime_fmt); |
|
+ gVars.realtime_fmt_len=0; |
|
+ } |
|
+ gVars.realtime_fmt=(char *) calloc(col,1); |
|
+ memcpy(gVars.realtime_fmt,fmt,col); |
|
+ gVars.realtime_fmt_len=col; |
|
+ if(eor) |
|
+ gVars.realtime_eor=eor; |
|
+ if(delimiter) |
|
+ gVars.realtime_delimiter=delimiter; |
|
+ if(gVars.rfH){ |
|
+ gVars.rfH->setFormat(gVars.realtime_fmt,gVars.realtime_fmt_len); |
|
+ gVars.rfH->setEor(gVars.realtime_eor); |
|
+ gVars.rfH->setDelimiter(gVars.realtime_delimiter); |
|
+ |
|
+ } |
|
+ } |
|
+ if(type==2){ |
|
+ if(gVars.stats_fmt_len){ |
|
+ free(gVars.stats_fmt); |
|
+ gVars.stats_fmt_len=0; |
|
+ } |
|
+ gVars.stats_fmt=(char *) calloc(col,1); |
|
+ memcpy(gVars.stats_fmt,fmt,col); |
|
+ gVars.stats_fmt_len=col; |
|
+ if(eor) |
|
+ gVars.stats_eor=eor; |
|
+ if(delimiter) |
|
+ gVars.stats_delimiter=delimiter; |
|
+ if(gVars.sfH){ |
|
+ gVars.sfH->setFormat(gVars.stats_fmt,gVars.stats_fmt_len); |
|
+ gVars.sfH->setEor(gVars.stats_eor); |
|
+ gVars.sfH->setDelimiter(gVars.stats_delimiter); |
|
+ } |
|
+ } |
|
+ if(type==4){ |
|
+ if(gVars.stdout_fmt_len){ |
|
+ free(gVars.stdout_fmt); |
|
+ gVars.stdout_fmt_len=0; |
|
+ } |
|
+ gVars.stdout_fmt=(char *) calloc(col,1); |
|
+ memcpy(gVars.stdout_fmt,fmt,col); |
|
+ gVars.stdout_fmt_len=col; |
|
+ if(eor) |
|
+ gVars.stdout_eor=eor; |
|
+ if(delimiter) |
|
+ gVars.stdout_delimiter=delimiter; |
|
+ if(gVars.sdF){ |
|
+ gVars.sdF->setFormat(gVars.stdout_fmt,gVars.stdout_fmt_len); |
|
+ gVars.sdF->setEor(gVars.stdout_eor); |
|
+ gVars.sdF->setDelimiter(gVars.stdout_delimiter); |
|
+ } |
|
+ } |
|
+ if(rule) free(rule); |
|
+ |
|
+} |
|
+ |
|
+void parse_default(char *c_rule,char *accept) |
|
+{ |
|
+ extern struct gvars gVars; |
|
+ char *rule=(char *)calloc(1,strlen(c_rule)+1); |
|
+ memcpy(rule,c_rule,strlen(c_rule)); |
|
+ char *rules=rule; |
|
+ char *tok=0; |
|
+ char *tmp=0; |
|
+ char *ftmp=0; |
|
+ char *pptr=0; |
|
+ |
|
+ if((tok = get_tok(&rules,accept))==NULL){ |
|
+ syslog(LOG_ERR,"Skipping, Invalid default, rule trunicated %s\n",rule); |
|
+ free(rule); |
|
+ return; |
|
+ }else if((tok = get_tok(&rules,accept))==NULL){ |
|
+ syslog(LOG_ERR,"Skipping, Invalid default, rule trunicated %s\n",rule); |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tok,"expire_interval")==0) |
|
+ { |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, default expire_interval specified but none provided, using default expire_interval %d\n",DEFAULT_EXPIRE_INTERVAL); |
|
+ gVars.default_expire_interval = DEFAULT_EXPIRE_INTERVAL; |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ pptr=tmp; |
|
+ gVars.default_expire_interval = (u_int16_t) strtol(tmp,&pptr,0); |
|
+ if(tmp==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, invalid expire_interval %s, using default expire_interval %d\n",tmp,DEFAULT_EXPIRE_INTERVAL); |
|
+ } |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tok,"flush_interval")==0) |
|
+ { |
|
+ int reset_alarm=gVars.default_flush_interval; |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, default flush_interval specified but none provided, using default flush_interval %d\n",DEFAULT_FLUSH_INTERVAL); |
|
+ gVars.default_flush_interval = DEFAULT_FLUSH_INTERVAL; |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ pptr=tmp; |
|
+ gVars.default_flush_interval = (u_int16_t) strtol(tmp,&pptr,0); |
|
+ if(tmp==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, invalid flush_interval %s, using default flush_interval %d\n",tmp,DEFAULT_FLUSH_INTERVAL); |
|
+ } |
|
+ // If the default flush_interval in the config file changed, we |
|
+ // need to reset the alarm to the new interval |
|
+ if(reset_alarm){ |
|
+ alarm(gVars.default_flush_interval); |
|
+ } |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tok,"zone")==0) |
|
+ { |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, default zone specified but none provided, using default zone %d\n",DEFAULT_ZONE); |
|
+ gVars.default_zone = DEFAULT_ZONE; |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ pptr=tmp; |
|
+ gVars.default_zone = (u_int16_t) strtol(tmp,&pptr,0); |
|
+ if(tmp==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, invalid zone %s, using default zone %d\n",tmp,DEFAULT_ZONE); |
|
+ } |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tok,"node")==0) |
|
+ { |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, default node specified but none provided, using default node %d\n",DEFAULT_NODE); |
|
+ gVars.default_node = DEFAULT_NODE; |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ pptr=tmp; |
|
+ gVars.default_node = (u_int16_t) strtol(tmp,&pptr,0); |
|
+ if(tmp==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, invalid node %s, using default node %d\n",tmp,DEFAULT_NODE); |
|
+ } |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tok,"rid")==0) |
|
+ { |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, default rid specified but none provided, using default rid %d\n",DEFAULT_RID); |
|
+ gVars.default_rid = DEFAULT_RID; |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ pptr=tmp; |
|
+ gVars.default_rid = (u_int32_t) strtol(tmp,&pptr,0); |
|
+ if(tmp==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, invalid rid %s, using default rid %d\n",tmp,DEFAULT_RID); |
|
+ } |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tok,"rgid")==0) |
|
+ { |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, default rgid specified but none provided, using default rgid %d\n",DEFAULT_RGID); |
|
+ gVars.default_rgid = DEFAULT_RGID; |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ pptr=tmp; |
|
+ gVars.default_rgid = (u_int32_t) strtol(tmp,&pptr,0); |
|
+ if(tmp==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, invalid rid %s, using default rid %d\n",tmp,DEFAULT_RID); |
|
+ } |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tok,"status")==0) |
|
+ { |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, default status specified but none provided, using default status %d\n",DEFAULT_STATUS); |
|
+ gVars.default_status = DEFAULT_STATUS; |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ pptr=tmp; |
|
+ gVars.default_status = (u_int8_t) strtol(tmp,&pptr,0); |
|
+ if(tmp==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, invalid status %s, using default status %d\n",tmp,DEFAULT_STATUS); |
|
+ } |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tok,"use_pcap_time")==0) |
|
+ { |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, default for use_pcap_time specified but no value provided%s\n",rule); |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tmp,"enable")==0) |
|
+ { |
|
+ gVars.use_pcap_time = ENABLED; |
|
+ } |
|
+ if(strcmp(tmp,"disable")==0) |
|
+ { |
|
+ gVars.use_pcap_time = DISABLED; |
|
+ } |
|
+#ifdef DEBUG |
|
+ fprintf(stdout,"Setting default for %s to %s\n",tok,tmp); |
|
+#endif |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tok,"burst_mode")==0) |
|
+ { |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, default for burst_mode specified but no value provided%s\n",rule); |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tmp,"enable")==0) |
|
+ { |
|
+ gVars.burst_mode = ENABLED; |
|
+ } |
|
+ if(strcmp(tmp,"disable")==0) |
|
+ { |
|
+ gVars.burst_mode = DISABLED; |
|
+ } |
|
+#ifdef DEBUG |
|
+ fprintf(stdout,"Setting default for %s to %s\n",tok,tmp); |
|
+#endif |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tok,"debug_pcap_raw")==0) |
|
+ { |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, default for debug_pcap_raw specified but no value provided%s\n",rule); |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tmp,"enable")==0) |
|
+ { |
|
+ if(gVars.rpfH){ gVars.rpfH->destroy(); gVars.rpfH=0; } |
|
+ ftmp=createFileName("tcpdump"); |
|
+ gVars.rpfH = new pcapFileHandle(ftmp); |
|
+ free(ftmp); |
|
+ gVars.pcap_raw = ENABLED; |
|
+ } |
|
+ if(strcmp(tmp,"disable")==0) |
|
+ { |
|
+ if(gVars.rpfH){ gVars.rpfH->destroy(); gVars.rpfH=0; } |
|
+ gVars.pcap_raw = DISABLED; |
|
+ } |
|
+#ifdef DEBUG |
|
+ fprintf(stdout,"Setting default for %s to %s\n",tok,tmp); |
|
+#endif |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tok,"strip-80211")==0) |
|
+ { |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, default for strip_80211 specified but no value provided%s\n",rule); |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tmp,"enable")==0) |
|
+ { |
|
+ gVars.strip_80211 = ENABLED; |
|
+ } |
|
+ if(strcmp(tmp,"disable")==0) |
|
+ { |
|
+ gVars.strip_80211 = DISABLED; |
|
+ } |
|
+#ifdef DEBUG |
|
+ fprintf(stdout,"Setting default for %s to %s\n",tok,tmp); |
|
+#endif |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tok,"pcapfilter")==0) |
|
+ { |
|
+ // We don't parse pcapfilter after initial startup, so see if we have an open pcap handle |
|
+ if( gVars.ph!=0 ){ free(rule); return; } |
|
+ gVars.bpf_filter=(char *) calloc(1,strlen(rules)+1); |
|
+ strncpy(gVars.bpf_filter,rules,strlen(rules)); |
|
+ syslog(LOG_INFO,"setting pcap filter expression %s\n",gVars.bpf_filter); |
|
+ |
|
+#ifdef DEBUG |
|
+ fprintf(stdout,"Setting default for %s to %s\n",tok,tmp); |
|
+#endif |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tok,"stats")==0) |
|
+ { |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, default for stats specified but no value provided%s\n",rule); |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tmp,"log")==0) // log all matching traffic |
|
+ { |
|
+ if(gVars.stats_fname){ free(gVars.stats_fname); } |
|
+ gVars.stats_fname=(char *) calloc(1,strlen(STATS_FNAME)+1); |
|
+ strncpy(gVars.stats_fname,STATS_FNAME,strlen(STATS_FNAME)); |
|
+ if(gVars.sfH){ gVars.sfH->destroy(); gVars.sfH=0; } |
|
+ ftmp=createFileName(gVars.stats_fname); |
|
+ gVars.sfH = new outputFileHandle((const char*)ftmp,gVars.stats_fmt,gVars.stats_fmt_len,APPEND_MODE); |
|
+ free(ftmp); |
|
+ gVars.smode=OMODE_LOG; |
|
+ } |
|
+ if(strcmp(tmp,"pass")==0) |
|
+ { |
|
+ if(gVars.sfH){ gVars.sfH->destroy(); gVars.sfH=0; } |
|
+ gVars.smode=OMODE_PASS; |
|
+ } |
|
+ if(strcmp(tmp,"filename")==0) |
|
+ { |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, default filename for stats specified but no value provided%s\n",rule); |
|
+ return; |
|
+ } |
|
+ if(gVars.stats_fname){ free(gVars.stats_fname); } |
|
+ gVars.stats_fname=(char *) calloc(1,strlen(tmp)+1); |
|
+ strncpy(gVars.stats_fname,tmp,strlen(tmp)); |
|
+ gVars.smode=OMODE_FILENAME; |
|
+ if(gVars.sfH){ gVars.sfH->destroy(); gVars.sfH=0; } |
|
+ ftmp=createFileName(gVars.stats_fname,gVars.smode == OMODE_TSFILENAME); |
|
+ gVars.sfH = new outputFileHandle((const char*)ftmp,gVars.stats_fmt,gVars.stats_fmt_len,APPEND_MODE); |
|
+ gVars.sfH->setEor(gVars.stats_eor); |
|
+ gVars.sfH->setDelimiter(gVars.stats_delimiter); |
|
+ free(ftmp); |
|
+ } |
|
+ if(strcmp(tmp,"tsfilename")==0) |
|
+ { |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, default tsfilename for stats specified but no value provided%s\n",rule); |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(gVars.stats_fname){ free(gVars.stats_fname); } |
|
+ gVars.stats_fname=(char *) calloc(1,strlen(tmp)+1); |
|
+ strncpy(gVars.stats_fname,tmp,strlen(tmp)); |
|
+ gVars.smode=OMODE_TSFILENAME; |
|
+ if(gVars.sfH){ gVars.sfH->destroy(); gVars.sfH=0; } |
|
+ ftmp=createFileName(gVars.stats_fname,gVars.smode == OMODE_TSFILENAME); |
|
+ gVars.sfH = new outputFileHandle((const char*)ftmp,gVars.stats_fmt,gVars.stats_fmt_len,APPEND_MODE); |
|
+ gVars.sfH->setEor(gVars.stats_eor); |
|
+ gVars.sfH->setDelimiter(gVars.stats_delimiter); |
|
+ free(ftmp); |
|
+ } |
|
+ |
|
+#ifdef DEBUG |
|
+ fprintf(stdout,"Setting default for %s to %s\n",tok,tmp); |
|
+#endif |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tok,"pcap")==0) |
|
+ { |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, default for pcap specified but no value provided%s\n",rule); |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tmp,"log")==0) // log all matching traffic |
|
+ { |
|
+ gVars.pmode = OMODE_LOG; |
|
+ if(gVars.pcap_fname){ free(gVars.pcap_fname); } |
|
+ gVars.pcap_fname=(char *) calloc(1,strlen(PCAP_FNAME)+1); |
|
+ strncpy(gVars.pcap_fname,PCAP_FNAME,strlen(PCAP_FNAME)); |
|
+ if(gVars.pfH){ gVars.pfH->destroy(); gVars.pfH=0; } |
|
+ ftmp=createFileName(gVars.pcap_fname); |
|
+ gVars.pfH = new pcapFileHandle(ftmp); |
|
+ free(ftmp); |
|
+ } |
|
+ if(strcmp(tmp,"pass")==0) |
|
+ { |
|
+ gVars.pmode=OMODE_PASS; |
|
+ if(gVars.pfH){ gVars.pfH->destroy(); gVars.pfH=0; } |
|
+ } |
|
+ if(strcmp(tmp,"filename")==0) |
|
+ { |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, default filename for pcap specified but no value provided%s\n",rule); |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(gVars.pcap_fname){ free(gVars.pcap_fname); } |
|
+ gVars.pcap_fname=(char *) calloc(1,strlen(tmp)+1); |
|
+ strncpy(gVars.pcap_fname,tmp,strlen(tmp)); |
|
+ gVars.pmode=OMODE_FILENAME; |
|
+ if(gVars.pfH){ gVars.pfH->destroy(); gVars.pfH=0; } |
|
+ ftmp=createFileName(gVars.pcap_fname,gVars.pmode == OMODE_TSFILENAME ); |
|
+ gVars.pfH = new pcapFileHandle(ftmp); |
|
+ free(ftmp); |
|
+ } |
|
+ if(strcmp(tmp,"tsfilename")==0) |
|
+ { |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, default tsfilename for pcap specified but no value provided%s\n",rule); |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(gVars.pcap_fname){ free(gVars.pcap_fname); } |
|
+ gVars.pcap_fname=(char *) calloc(1,strlen(tmp)+1); |
|
+ strncpy(gVars.pcap_fname,tmp,strlen(tmp)); |
|
+ gVars.pmode=OMODE_TSFILENAME; |
|
+ if(gVars.pfH){ gVars.pfH->destroy(); gVars.pfH=0; } |
|
+ ftmp=createFileName(gVars.pcap_fname,gVars.pmode == OMODE_TSFILENAME); |
|
+ gVars.pfH = new pcapFileHandle(ftmp); |
|
+ free(ftmp); |
|
+ } |
|
+ |
|
+#ifdef DEBUG |
|
+ fprintf(stdout,"Setting default for %s to %s\n",tok,tmp); |
|
+#endif |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tok,"realtime")==0) |
|
+ { |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, default for realtime specified but no value provided%s\n",rule); |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tmp,"log")==0) // log all matching traffic |
|
+ { |
|
+ if(gVars.realtime_fname){ free(gVars.realtime_fname); } |
|
+ gVars.realtime_fname=(char *) calloc(1,strlen(REALTIME_FNAME)+1); |
|
+ strncpy(gVars.realtime_fname,REALTIME_FNAME,strlen(REALTIME_FNAME)); |
|
+ if(gVars.rfH){ gVars.rfH->destroy(); gVars.rfH=0; } |
|
+ ftmp=createFileName(gVars.realtime_fname); |
|
+ gVars.rfH = new outputFileHandle((const char*)ftmp,gVars.realtime_fmt,gVars.realtime_fmt_len,APPEND_MODE); |
|
+ free(ftmp); |
|
+ gVars.rmode=OMODE_LOG; |
|
+ } |
|
+ if(strcmp(tmp,"pass")==0) |
|
+ { |
|
+ if(gVars.rfH){ gVars.rfH->destroy(); gVars.rfH=0; } |
|
+ gVars.rmode=OMODE_PASS; |
|
+ } |
|
+ if(strcmp(tmp,"filename")==0) |
|
+ { |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, default filename for realtime specified but no value provided%s\n",rule); |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(gVars.realtime_fname){ free(gVars.realtime_fname); } |
|
+ gVars.realtime_fname=(char *) calloc(1,strlen(tmp)+1); |
|
+ strncpy(gVars.realtime_fname,tmp,strlen(tmp)); |
|
+ gVars.rmode=OMODE_FILENAME; |
|
+ if(gVars.rfH){ gVars.rfH->destroy(); gVars.rfH=0; } |
|
+ ftmp=createFileName(gVars.realtime_fname,gVars.rmode == OMODE_TSFILENAME); |
|
+ gVars.rfH = new outputFileHandle((const char*)ftmp,gVars.realtime_fmt,gVars.realtime_fmt_len,APPEND_MODE); |
|
+ gVars.rfH->setEor(gVars.realtime_eor); |
|
+ gVars.rfH->setDelimiter(gVars.realtime_delimiter); |
|
+ free(ftmp); |
|
+ } |
|
+ if(strcmp(tmp,"tsfilename")==0) |
|
+ { |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, default tsfilename for realtime specified but no value provided%s\n",rule); |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(gVars.realtime_fname){ free(gVars.realtime_fname); } |
|
+ gVars.realtime_fname=(char *) calloc(1,strlen(tmp)+1); |
|
+ strncpy(gVars.realtime_fname,tmp,strlen(tmp)); |
|
+ gVars.rmode=OMODE_TSFILENAME; |
|
+ if(gVars.rfH){ gVars.rfH->destroy(); gVars.rfH=0; } |
|
+ ftmp=createFileName(gVars.realtime_fname,gVars.rmode == OMODE_TSFILENAME); |
|
+ gVars.rfH = new outputFileHandle((const char*)ftmp,gVars.realtime_fmt,gVars.realtime_fmt_len,APPEND_MODE); |
|
+ gVars.rfH->setEor(gVars.realtime_eor); |
|
+ gVars.rfH->setDelimiter(gVars.realtime_delimiter); |
|
+ free(ftmp); |
|
+ } |
|
+ |
|
+#ifdef DEBUG |
|
+ fprintf(stdout,"Setting default for %s to '%s'\n",tok,tmp); |
|
+#endif |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tok,"limit")==0) |
|
+ { |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, limit specified but none provided, using default limit %d\n",DEFAULT_LIMIT); |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ pptr=tmp; |
|
+ gVars.default_limit = (u_int64_t) strtoll(tmp,&pptr,0); |
|
+ if(tmp==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, invalid limit %s, using default limit %d\n",tmp,DEFAULT_LIMIT); |
|
+ gVars.default_limit = DEFAULT_LIMIT; |
|
+ } |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tok,"timeout")==0) |
|
+ { |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, default timeout specified but none provided, using timeout value %d\n",DEFAULT_TIMEOUT); |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ pptr=tmp; |
|
+ gVars.default_timeout = (u_int16_t) strtol(tmp,&pptr,0); |
|
+ if(tmp==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, invalid timeout %s, using default timeout %d\n",tmp,DEFAULT_TIMEOUT); |
|
+ gVars.default_timeout = DEFAULT_TIMEOUT; |
|
+ } |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tok,"tcplag")==0) |
|
+ { |
|
+ if((tmp = get_tok(&rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, tcplag specified but none provided, using tcplag value %d\n",DEFAULT_LAG); |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ pptr=tmp; |
|
+ gVars.default_tcplag = (u_int16_t) strtol(tmp,&pptr,0); |
|
+ if(tmp==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, invalid tcplag %s, using default tcplag %d\n",tmp,DEFAULT_LAG); |
|
+ gVars.default_tcplag = DEFAULT_LAG; |
|
+ } |
|
+ free(rule); |
|
+ return; |
|
+#ifdef DEBUG |
|
+ fprintf(stdout,"Didn't set default for %s to %s\n",tok,tmp); |
|
+#endif |
|
+ } |
|
+} |
|
+ |
|
+void parse_var(char *c_rule, char *accept) |
|
+{ |
|
+ extern struct gvars gVars; |
|
+ char *rule=(char *)calloc(1,strlen(c_rule)+1); |
|
+ memcpy(rule,c_rule,strlen(c_rule)); |
|
+ char **rules=&rule; |
|
+ char *tok=NULL; |
|
+ struct vars *n_var; |
|
+ rules=&rule; |
|
+ |
|
+ if((n_var=(struct vars *)calloc(1,sizeof(struct vars)))==NULL){ printf ("Out of Memory?\n"); return;} |
|
+ |
|
+ n_var->key=NULL; |
|
+ n_var->value=NULL; |
|
+ n_var->next=NULL; |
|
+ if((tok = get_tok(rules,accept))==NULL || strcmp(tok,"var")!=0) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid rule trunicated when expecting var type %s\n",rule); |
|
+ free(n_var); |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ else |
|
+ { |
|
+ if((tok = get_tok(rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid rule trunicated when expecting var key %s\n",rule); |
|
+ free(n_var); |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ else |
|
+ { |
|
+ if((n_var->key=(char *)calloc(1,sizeof(char)*strlen(tok)+1))==NULL){ printf ("Out of Memory?\n"); free(n_var); free(rule); return;} |
|
+ strncpy(n_var->key,tok,sizeof(char)*strlen(tok)); |
|
+ |
|
+ if((tok = get_tok(rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid rule trunicated when expecting var value %s\n",rule); |
|
+ free(n_var->key); |
|
+ n_var->key=NULL; free(n_var); |
|
+ free(rule); |
|
+ return; |
|
+ } |
|
+ else |
|
+ { |
|
+ if((n_var->value=(char *)calloc(1,sizeof(char)*strlen(tok)+1))==NULL){ printf ("Out of Memory?\n"); free(n_var->key); free(n_var); free(rule); return;} |
|
+ strncpy(n_var->value,tok,sizeof(char)*strlen(tok)); |
|
+ } |
|
+ } |
|
+ } |
|
+ |
|
+ // If we made it this var, then we have a valid var |
|
+ if(!gVars.var_head){ |
|
+ gVars.var_head=n_var; |
|
+ } |
|
+ else |
|
+ { |
|
+ n_var->next = gVars.var_head; |
|
+ gVars.var_head=n_var; |
|
+ } |
|
+ free(rule); |
|
+} |
|
+ |
|
+ |
|
+ |
|
+char *search_vars(char *key, struct vars *var_head, int vclass) |
|
+{ |
|
+ struct vars *tmp; |
|
+ tmp = var_head; |
|
+#ifdef DEBUG |
|
+ syslog(LOG_ERR,"Searching for key '%s'\n",key); |
|
+#endif |
|
+ while(tmp!=NULL) |
|
+ { |
|
+#ifdef DEBUG |
|
+ fprintf(stdout,"Checking key/value (%d) '%s'/'%s' for (%d) '%s'\n",strlen(tmp->key),tmp->key,tmp->value,strlen(key),key); |
|
+#endif |
|
+ if(strcmp(tmp->key,key)==0) |
|
+ { |
|
+#ifdef DEBUG |
|
+ syslog(LOG_ERR,"Found key/value %s/%s\n",key,tmp->value); |
|
+#endif |
|
+ // Mark the variable class that we were looking in |
|
+ // so we will 'remember' which values pertained to which |
|
+ // class of keys when we do a reverse lookup later. |
|
+ // i.e. The value of 8 may exist in two or more classes |
|
+ // Different class variables, having the same name, may |
|
+ // cause undefined results. |
|
+ tmp->vclass=vclass; |
|
+ return tmp->value; |
|
+ } |
|
+ tmp=tmp->next; |
|
+ } |
|
+#ifdef DEBUG |
|
+ fprintf(stdout,"Key not found '%s'\n",key); |
|
+#endif |
|
+ return NULL; |
|
+} |
|
+ |
|
+char *rev_search_vars(char *value, struct vars *var_head, int vclass) |
|
+{ |
|
+ struct vars *tmp; |
|
+ tmp = var_head; |
|
+#ifdef DEBUG |
|
+ syslog(LOG_INFO,"REV Search %d:'%s' for %d:'%s'\n",tmp->vclass,tmp->value,vclass,value); |
|
+#endif |
|
+ while(tmp!=NULL) |
|
+ { |
|
+ if( tmp->vclass==vclass && strcmp(tmp->value,value)==0) |
|
+ { |
|
+#ifdef DEBUG |
|
+ syslog(LOG_ERR,"Found key/value %s/'%s'\n",tmp->key,tmp->value); |
|
+#endif |
|
+ return tmp->key; |
|
+ } |
|
+ tmp=tmp->next; |
|
+ } |
|
+#ifdef DEBUG |
|
+ fprintf(stdout,"Value not found '%s'\n",value); |
|
+#endif |
|
+ return NULL; |
|
+} |
|
+ |
|
+void parse_known_ports(char *rule, struct vars *var_head, char *accept) |
|
+{ |
|
+ extern struct t_ports *tports[MAX_IP_PROTO]; |
|
+ char *tmp=NULL, *pptr=NULL,*tok=NULL; |
|
+ char **rules=NULL; |
|
+ struct t_ports *n_ports=NULL; |
|
+ int proto = 0; |
|
+ char ptok[256]; |
|
+ u_int16_t port_h=0; |
|
+ u_int16_t port_l=0; |
|
+ rules=&rule; |
|
+ |
|
+ if((tok = get_tok(rules,accept))!=NULL) |
|
+ { |
|
+ if((tok = get_tok(rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid rule trunicated when expecting ports protocol %s\n",rule); |
|
+ return; |
|
+ } |
|
+ if((tmp=search_vars(tok,var_head,VCLASS_2))!=NULL) |
|
+ { |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,tmp,sizeof(char)*strlen(tmp)); |
|
+ tok=ptok; |
|
+ } |
|
+ |
|
+ pptr=tok; |
|
+ |
|
+ proto = (u_int8_t) strtol(tok,&pptr,0); |
|
+ |
|
+ if(tok==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid protocol value found: %s\n",tok); |
|
+ return; |
|
+ } |
|
+ |
|
+ while((tok = get_tok(rules,accept))!=NULL && *tok != 0) |
|
+ { |
|
+ if((tmp=search_vars(tok,var_head,VCLASS_3))!=NULL) |
|
+ { |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,tmp,sizeof(char)*strlen(tmp)); |
|
+ tok=ptok; |
|
+ } |
|
+ if((tmp = get_next_tok(&tok,"-"))!=NULL) |
|
+ { |
|
+ pptr=tmp; |
|
+ port_l = (u_int16_t) strtol(tmp,&pptr,0); |
|
+ if(tmp==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid port start of range found: %s\n",tmp); |
|
+ return; |
|
+ } |
|
+ pptr=tok; |
|
+ port_h = (u_int16_t) strtol(tok,&pptr,0); |
|
+ if(tok==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid port end of range found: %s\n",tok); |
|
+ return; |
|
+ } |
|
+ }else{ |
|
+ pptr=tok; |
|
+ port_l = (u_int16_t) strtol(tok,&pptr,0); |
|
+ if(tok==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid port found: %X.\n",*tok); |
|
+ return; |
|
+ } |
|
+#ifdef DEBUG |
|
+ syslog(LOG_ERR,"Port found: %s\n",tok); |
|
+#endif |
|
+ port_h=port_l; |
|
+ } |
|
+ // if we made it this far we have a valid oort |
|
+ if((n_ports=(struct t_ports *)calloc(1,sizeof(struct t_ports)))==NULL){ printf ("Out of Memory?\n"); return;} |
|
+ |
|
+ n_ports->h_port=port_h; |
|
+ n_ports->l_port=port_l; |
|
+ n_ports->next=NULL; |
|
+ if(!tports[proto]){ |
|
+ tports[proto]=n_ports; |
|
+ } |
|
+ else |
|
+ { |
|
+ n_ports->next = tports[proto]; |
|
+ tports[proto]=n_ports; |
|
+ } |
|
+ } |
|
+ }else{ |
|
+ syslog(LOG_ERR,"Skipping, Invalid rule trunicated when expecting ports protocol %s\n",rule); |
|
+ } |
|
+} |
|
+ |
|
+void parse_connection_rule(char *rule, struct vars *var_head, char *accept) |
|
+{ |
|
+ // THIS FUNCTION DOES NOT EXIT THE PROGRAM WHEN IT RECEIVES A |
|
+ // BAD RULE!!! THIS IS DONE TO ENSURE THIS TOOL CONTINUES COLLECTION |
|
+ // SPECIFICALLY IN CASE IT READS A BAD CONFIGURATION FILE AFTER RECEIVING |
|
+ // A KILL -HUP SIGNAL - SO ALWAYS CHECK THE SYSLOG FOR ERRORS |
|
+ // IF THE DEFAULT PCAP MODE IS TO RECORD EVERYTHING THEN BAD RULES WILL |
|
+ // NOT MEAN LOST DATA. YOU CAN ALWAYS RE-PROCESS PCAP DATA BUT CAN'T |
|
+ // RECOVER FROM DATA YOU DIDN'T RECORD |
|
+ char *tmp, *tok=NULL; |
|
+ char **rules=NULL; |
|
+ char *pptr=NULL; |
|
+ char *ftmp=0; |
|
+ char ptok[256]; |
|
+ struct acl *n_acl; |
|
+ extern struct gvars gVars; |
|
+ extern struct acl *tacl_head, *tacl_tail; |
|
+ bzero(ptok,256); |
|
+ rules=&rule; |
|
+ if((n_acl=(struct acl *)calloc(1,sizeof(struct acl)))==NULL){ syslog (LOG_CRIT,"Unable to allocate ACL - Out of Memory!\n"); return;} |
|
+ bzero(n_acl,sizeof(struct acl)); |
|
+ n_acl->next=NULL; |
|
+ n_acl->cmode = CMODE_BOTH; |
|
+ n_acl->pcap = gVars.pmode?1:0; |
|
+ n_acl->pmode = gVars.pmode; |
|
+ n_acl->stats = gVars.smode?1:0; |
|
+ n_acl->smode = gVars.smode; |
|
+ n_acl->realtime = gVars.rmode?1:0; |
|
+ n_acl->rmode = gVars.rmode; |
|
+ n_acl->timeout = gVars.default_timeout; |
|
+ n_acl->limit = gVars.default_limit; |
|
+ n_acl->status = gVars.default_status; |
|
+ n_acl->rid = gVars.default_rid; |
|
+ n_acl->tcplag = gVars.default_tcplag; |
|
+ if(gVars.pfH && gVars.pmode){ |
|
+ n_acl->fH = gVars.pfH->attach(); |
|
+ }else{ |
|
+ n_acl->fH = 0; |
|
+ } |
|
+ |
|
+ // FIELD 0 - required - Get the h_proto |
|
+ n_acl->h_proto_h = 0xFFFF; |
|
+ n_acl->h_proto_l = 0x0000; |
|
+ if((tok = get_tok(rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid rule trunicated when expecting hw protocol %s\n",rule); |
|
+ free(n_acl); |
|
+ return; |
|
+ } |
|
+ else if(strcmp(tok,"any")){ |
|
+ if((tmp=search_vars(tok,gVars.var_head,VCLASS_0))!=NULL) |
|
+ { |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,tmp,sizeof(char)*strlen(tmp)); |
|
+ tok=ptok; |
|
+ } |
|
+ |
|
+ if((tmp = get_next_tok(&tok,"-"))!=NULL) |
|
+ { |
|
+ pptr=tmp; |
|
+ n_acl->h_proto_l = (u_int16_t) strtol(tmp,&pptr,0); |
|
+ if(tmp==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid start of h_proto range found: %s\n",tmp); |
|
+ free(n_acl); return; |
|
+ } |
|
+ pptr=tok; |
|
+ n_acl->h_proto_h = (u_int16_t) strtol(tok,&pptr,0); |
|
+ if(tok==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid end of h_proto range found: %s\n",tok); |
|
+ free(n_acl); return; |
|
+ } |
|
+ }else{ |
|
+ pptr=tok; |
|
+ n_acl->h_proto_l = (u_int16_t) strtol(tok,&pptr,0); |
|
+ if(tok==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid h_protocol value found: %s\n",tok); |
|
+ free(n_acl); |
|
+ return; |
|
+ } |
|
+ n_acl->h_proto_h = n_acl->h_proto_l; |
|
+ } |
|
+ } |
|
+ |
|
+ // FIELD 1 - required - Get the source address and mask fields |
|
+ n_acl->s_mask=0xFFFFFFFF; |
|
+ n_acl->s_ip=0x00000000; |
|
+ |
|
+ if((tok = get_tok(rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid rule trunicated when expecting source address and mask %s\n",rule); |
|
+ free(n_acl); |
|
+ return; |
|
+ } |
|
+ else if(strcmp(tok,"any")){ |
|
+ if((tmp=search_vars(tok,gVars.var_head,VCLASS_1))!=NULL) |
|
+ { |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,tmp,sizeof(char)*strlen(tmp)); |
|
+ tok=ptok; |
|
+ } |
|
+ |
|
+ if((tmp = get_next_tok(&tok,"/"))!=NULL) |
|
+ { |
|
+ if(inet_aton(tmp,(struct in_addr *)&n_acl->s_ip)==0) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid source address found: %s/%s %s\n",tmp,tok,rule); |
|
+ free(n_acl); |
|
+ return; |
|
+ } |
|
+ if(strstr(tok,".")) |
|
+ { |
|
+ if(inet_aton(tok,(struct in_addr *)&n_acl->s_mask)==0) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid source mask found: %s/%s %s\n",tmp,tok,rule); |
|
+ free(n_acl); |
|
+ return; |
|
+ } |
|
+ } |
|
+ else |
|
+ { |
|
+ pptr=tok; |
|
+ n_acl->s_mask=htonl(0xFFFFFFF<<(32-(u_int8_t)(strtol(tok,&pptr,0)))); |
|
+ if(tok==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid source mask found: %s/%s %s\n",tmp,tok,rule); |
|
+ free(n_acl); |
|
+ return; |
|
+ } |
|
+ } |
|
+ }else{ |
|
+ if(inet_aton(tok,(struct in_addr *)&n_acl->s_ip)==0) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid source address found: %s %s\n",tok,rule); |
|
+ free(n_acl); |
|
+ return; |
|
+ } |
|
+ } |
|
+ } |
|
+ // FIELD 3 - required - Get the destination address and mask fields |
|
+ |
|
+ n_acl->d_mask=0xFFFFFFFF; |
|
+ n_acl->d_ip=0x00000000; |
|
+ |
|
+ if((tok = get_tok(rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid rule trunicated when expecting destination address and mask %s\n",rule); |
|
+ free(n_acl); |
|
+ return; |
|
+ } |
|
+ else if(strcmp(tok,"any")){ |
|
+ if((tmp=search_vars(tok,gVars.var_head,VCLASS_1))!=NULL) |
|
+ { |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,tmp,sizeof(char)*strlen(tmp)); |
|
+ tok=ptok; |
|
+ } |
|
+ if((tmp = get_next_tok(&tok,"/"))!=NULL) |
|
+ { |
|
+ if(inet_aton(tmp,(struct in_addr *)&n_acl->d_ip)==0) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid destination address found: %s/%s %s\n",tmp,tok,rule); |
|
+ free(n_acl); |
|
+ return; |
|
+ } |
|
+ if(strstr(tok,".")) |
|
+ { |
|
+ if(inet_aton(tok,(struct in_addr *)&n_acl->d_mask)==0) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid destination mask found: %s/%s %s\n",tmp,tok,rule); |
|
+ free(n_acl); |
|
+ return; |
|
+ } |
|
+ } |
|
+ else |
|
+ { |
|
+ pptr=tok; |
|
+ n_acl->d_mask=htonl(0xFFFFFFFF<<(32-(u_int8_t)(strtol(tok,&pptr,0)))); |
|
+ if(tok==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid destination mask found: %s/%s %s\n",tmp,tok,rule); |
|
+ free(n_acl); |
|
+ return; |
|
+ } |
|
+ } |
|
+ }else{ |
|
+ if(inet_aton(tok,(struct in_addr *)&n_acl->d_ip)==0) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid destination address found: %s %s\n",tok,rule); |
|
+ free(n_acl); |
|
+ return; |
|
+ } |
|
+ } |
|
+ } |
|
+ |
|
+ // FIELD 4 - required - Get the protocol field |
|
+ n_acl->proto_l = 0x00; |
|
+ n_acl->proto_h = 0xFF; |
|
+ if((tok = get_tok(rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid rule trunicated when expecting protocol %s\n",rule); |
|
+ free(n_acl); |
|
+ return; |
|
+ } |
|
+ else if(strcmp(tok,"any")){ |
|
+ if((tmp=search_vars(tok,gVars.var_head,VCLASS_2))!=NULL) |
|
+ { |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,tmp,sizeof(char)*strlen(tmp)); |
|
+ tok=ptok; |
|
+ } |
|
+ |
|
+ // Use the defaults for ANY |
|
+ if((tmp = get_next_tok(&tok,"-"))!=NULL) |
|
+ { |
|
+ pptr=tmp; |
|
+ n_acl->proto_l = (u_int8_t) strtol(tmp,&pptr,0); |
|
+ if(tmp==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid start of proto range found: %s\n",tmp); |
|
+ free(n_acl); return; |
|
+ } |
|
+ pptr=tok; |
|
+ n_acl->proto_h = (u_int8_t) strtol(tok,&pptr,0); |
|
+ if(tok==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid end of proto range found: %s\n",tok); |
|
+ free(n_acl); return; |
|
+ } |
|
+ }else{ |
|
+ pptr=tok; |
|
+ n_acl->proto_l = (u_int8_t) strtol(tok,&pptr,0); |
|
+ if(tok==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid protocol value found: %s\n",tok); |
|
+ free(n_acl); |
|
+ return; |
|
+ } |
|
+ n_acl->proto_h = n_acl->proto_l; |
|
+ } |
|
+ } |
|
+ |
|
+ // FIELD 5 - required - Get the source ports field |
|
+ |
|
+ n_acl->s_port_l=0x0000; |
|
+ n_acl->s_port_h=0xFFFF; |
|
+ |
|
+ if((tok = get_tok(rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid rule trunicated when expecting source ports %s\n",rule); |
|
+ free(n_acl); |
|
+ return; |
|
+ } |
|
+ else if(strcmp(tok,"any")){ |
|
+ if((tmp=search_vars(tok,gVars.var_head,VCLASS_3))!=NULL) |
|
+ { |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,tmp,sizeof(char)*strlen(tmp)); |
|
+ tok=ptok; |
|
+ } |
|
+ |
|
+ // Use the defaults for ANY |
|
+ if((tmp = get_next_tok(&tok,"-"))!=NULL) |
|
+ { |
|
+ pptr=tmp; |
|
+ n_acl->s_port_l = (u_int16_t) strtol(tmp,&pptr,0); |
|
+ if(tmp==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid source port start of range found: %s\n",tmp); |
|
+ free(n_acl); |
|
+ return; |
|
+ } |
|
+ pptr=tok; |
|
+ n_acl->s_port_h = (u_int16_t) strtol(tok,&pptr,0); |
|
+ if(tok==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid source port end of range found: %s\n",tok); |
|
+ free(n_acl); |
|
+ return; |
|
+ } |
|
+ }else{ |
|
+ pptr=tok; |
|
+ n_acl->s_port_l = (u_int16_t) strtol(tok,&pptr,0); |
|
+ if(tok==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid source port found: %s\n",tok); |
|
+ free(n_acl); |
|
+ return; |
|
+ } |
|
+ n_acl->s_port_h=n_acl->s_port_l; |
|
+ } |
|
+ } |
|
+ // FIELD 6 - required - Get the destination ports field |
|
+ |
|
+ n_acl->d_port_l=0x0000; |
|
+ n_acl->d_port_h=0xFFFF; |
|
+ |
|
+ if((tok = get_tok(rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid rule trunicated when expecting destination ports %s\n",rule); |
|
+ free(n_acl); |
|
+ return; |
|
+ } |
|
+ else if(strcmp(tok,"any")){ |
|
+ |
|
+ |
|
+ if((tmp=search_vars(tok,gVars.var_head,VCLASS_3))!=NULL) |
|
+ { |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,tmp,sizeof(char)*strlen(tmp)); |
|
+ tok=ptok; |
|
+ } |
|
+ |
|
+ if((tmp = get_next_tok(&tok,"-"))!=NULL ) |
|
+ { |
|
+ pptr=tmp; |
|
+ n_acl->d_port_l = (u_int16_t) strtol(tmp,&pptr,0); |
|
+ if(tmp==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid destination port start of range found: %s\n",tmp); |
|
+ free(n_acl); |
|
+ return; |
|
+ } |
|
+ pptr=tok; |
|
+ n_acl->d_port_h = (u_int16_t) strtol(tok,&pptr,0); |
|
+ if(tok==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid destination port end of range found: %s\n",tok); |
|
+ free(n_acl); |
|
+ return; |
|
+ } |
|
+ }else{ |
|
+ pptr=tok; |
|
+ n_acl->d_port_l = (u_int16_t) strtol(tok,&pptr,0); |
|
+ if(tok==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Skipping, Invalid destination port found: %s\n",tok); |
|
+ free(n_acl); |
|
+ return; |
|
+ } |
|
+ n_acl->d_port_h=n_acl->d_port_l; |
|
+ } |
|
+ } |
|
+ |
|
+ // REMAINING FIELDs - not required - limit and timeout |
|
+ |
|
+ while((tok = get_tok(rules,accept))!=NULL && *tok!=0 ) |
|
+ { |
|
+ if(strcmp(tok,"rid")==0) |
|
+ { |
|
+ if((tmp = get_tok(rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, rid specified but none provided, using default rid %u\n",gVars.default_rid); |
|
+ return; |
|
+ } |
|
+ if((tok=search_vars(tmp,gVars.var_head,VCLASS_4))!=NULL) |
|
+ { |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,tok,sizeof(char)*strlen(tok)); |
|
+ tmp=ptok; |
|
+ } |
|
+ pptr=tmp; |
|
+ n_acl->rid = (u_int32_t) strtol(tmp,&pptr,0); |
|
+ if(tmp==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, invalid rid %s, using default rid %u\n",tmp,gVars.default_rid); |
|
+ // Let's restore the delimiter and put back our token |
|
+ // this might be the next option |
|
+ tmp[sizeof(tmp)-1]=' '; |
|
+ *rules=tmp; |
|
+ } |
|
+ continue; |
|
+ } |
|
+ if(strcmp(tok,"rgid")==0) |
|
+ { |
|
+ if((tmp = get_tok(rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, rgid specified but none provided, using default rgid %u\n",gVars.default_rgid); |
|
+ return; |
|
+ } |
|
+ if((tok=search_vars(tmp,gVars.var_head,VCLASS_5))!=NULL) |
|
+ { |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,tok,sizeof(char)*strlen(tok)); |
|
+ tmp=ptok; |
|
+ } |
|
+ pptr=tmp; |
|
+ n_acl->rgid = (u_int32_t) strtol(tmp,&pptr,0); |
|
+ if(tmp==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, invalid rgid %s, using default rgid %u\n",tmp,gVars.default_rgid); |
|
+ // Let's restore the delimiter and put back our token |
|
+ // this might be the next option |
|
+ tmp[sizeof(tmp)-1]=' '; |
|
+ *rules=tmp; |
|
+ } |
|
+ continue; |
|
+ } |
|
+ if(strcmp(tok,"zone")==0) |
|
+ { |
|
+ if((tmp = get_tok(rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, zone specified but none provided, using default zone %d\n",gVars.default_zone); |
|
+ return; |
|
+ } |
|
+ if((tok=search_vars(tmp,gVars.var_head,VCLASS_6))!=NULL) |
|
+ { |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,tok,sizeof(char)*strlen(tok)); |
|
+ tmp=ptok; |
|
+ } |
|
+ pptr=tmp; |
|
+ n_acl->zone = (u_int16_t) strtol(tmp,&pptr,0); |
|
+ if(tmp==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, invalid zone %s, using default zone %d\n",tmp,gVars.default_zone); |
|
+ // Let's restore the delimiter and put back our token |
|
+ // this might be the next option |
|
+ tmp[sizeof(tmp)-1]=' '; |
|
+ *rules=tmp; |
|
+ } |
|
+ continue; |
|
+ } |
|
+ if(strcmp(tok,"node")==0) |
|
+ { |
|
+ if((tmp = get_tok(rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, node specified but none provided, using default node %d\n",gVars.default_node); |
|
+ return; |
|
+ } |
|
+ if((tok=search_vars(tmp,gVars.var_head,VCLASS_7))!=NULL) |
|
+ { |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,tok,sizeof(char)*strlen(tok)); |
|
+ tmp=ptok; |
|
+ } |
|
+ pptr=tmp; |
|
+ n_acl->node = (u_int16_t) strtol(tmp,&pptr,0); |
|
+ if(tmp==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, invalid node %s, using default node %d\n",tmp,gVars.default_node); |
|
+ // Let's restore the delimiter and put back our token |
|
+ // this might be the next option |
|
+ tmp[sizeof(tmp)-1]=' '; |
|
+ *rules=tmp; |
|
+ } |
|
+ continue; |
|
+ } |
|
+ if(strcmp(tok,"status")==0) |
|
+ { |
|
+ if((tmp = get_tok(rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, status specified but none provided, using default status %d\n",gVars.default_status); |
|
+ return; |
|
+ } |
|
+ if((tok=search_vars(tmp,gVars.var_head,VCLASS_8))!=NULL) |
|
+ { |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,tok,sizeof(char)*strlen(tok)); |
|
+ tmp=ptok; |
|
+ } |
|
+ pptr=tmp; |
|
+ n_acl->status = (u_int8_t) strtol(tmp,&pptr,0); |
|
+ if(tmp==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, invalid status %s, using default status %d\n",tmp,gVars.default_status); |
|
+ // Let's restore the delimiter and put back our token |
|
+ // this might be the next option |
|
+ tmp[sizeof(tmp)-1]=' '; |
|
+ *rules=tmp; |
|
+ } |
|
+ continue; |
|
+ } |
|
+ if(strcmp(tok,"timeout")==0) |
|
+ { |
|
+ if((tmp = get_tok(rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, timeout specified but none provided, using default timeout %d\n",gVars.default_timeout); |
|
+ return; |
|
+ } |
|
+ pptr=tmp; |
|
+ n_acl->timeout = (u_int16_t) strtol(tmp,&pptr,0); |
|
+ if(tmp==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, invalid timeout %s, using default timeout\n",tmp); |
|
+ // Let's restore the delimiter and put back our token |
|
+ // this might be the next option |
|
+ tmp[sizeof(tmp)-1]=' '; |
|
+ *rules=tmp; |
|
+ } |
|
+ continue; |
|
+ } |
|
+ if(strcmp(tok,"tcplag")==0) |
|
+ { |
|
+ if((tmp = get_tok(rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, tcplag specified but none provided, using default tcplag %d\n",gVars.default_tcplag); |
|
+ return; |
|
+ } |
|
+ pptr=tmp; |
|
+ n_acl->tcplag = (u_int16_t) strtol(tmp,&pptr,0); |
|
+ if(tmp==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, invalid tcplag %s, using default tcplag \n",tmp); |
|
+ |
|
+ tmp[sizeof(tmp)-1]=' '; |
|
+ *rules=tmp; |
|
+ } |
|
+ continue; |
|
+ } |
|
+ if(strcmp(tok,"limit")==0) |
|
+ { |
|
+ if((tmp = get_tok(rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, limit specified but none provided, using default limit %llu\n",(long long unsigned)gVars.default_limit); |
|
+ return; |
|
+ } |
|
+ pptr=tmp; |
|
+ n_acl->limit = (u_int64_t) strtol(tmp,&pptr,0); |
|
+ if(tmp==pptr) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, invalid limit %s, using default limit %llu\n",tmp,(long long unsigned)gVars.default_limit); |
|
+ // Let's restore the delimiter and put back our token |
|
+ // this might be the next option |
|
+ tmp[sizeof(tmp)-1]=' '; |
|
+ *rules=tmp; |
|
+ } |
|
+ continue; |
|
+ } |
|
+ if(strcmp(tok,"realtime")==0) |
|
+ { |
|
+ if((tmp = get_tok(rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, realtime specified but no option provided%s\n",rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tmp,"log")==0) // log all matching traffic |
|
+ { |
|
+ n_acl->realtime = ACTION_LOG; |
|
+ n_acl->rmode = OMODE_LOG; |
|
+ continue; |
|
+ } |
|
+ if(strcmp(tmp,"pass")==0) |
|
+ { |
|
+ n_acl->realtime = ACTION_PASS; |
|
+ n_acl->rmode = OMODE_PASS; |
|
+ continue; |
|
+ } |
|
+ syslog(LOG_ERR,"Skipping, invalid realtime option in rule: %s %s\n",tok,tmp); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tok,"stats")==0) |
|
+ { |
|
+ if((tmp = get_tok(rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, stats specified but no option provided%s\n",rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tmp,"log")==0) // log all matching traffic |
|
+ { |
|
+ n_acl->stats=ACTION_LOG; |
|
+ n_acl->smode=OMODE_LOG; |
|
+ continue; |
|
+ } |
|
+ if(strcmp(tmp,"pass")==0) |
|
+ { |
|
+ n_acl->stats = ACTION_PASS; |
|
+ n_acl->smode = OMODE_PASS; |
|
+ continue; |
|
+ } |
|
+ syslog(LOG_ERR,"Skipping, invalid stats option in rule: %s %s\n",tok,tmp); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tok,"pcap")==0) |
|
+ { |
|
+ if((tmp = get_tok(rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, output specified but none provided, using default output%s\n",rule); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tmp,"log")==0) // log all matching traffic |
|
+ { |
|
+ if(n_acl->fH){ n_acl->fH->destroy(); n_acl->fH=0; } |
|
+ n_acl->fH = gVars.pfH->attach(); |
|
+ n_acl->pcap = ACTION_LOG; |
|
+ n_acl->pmode = OMODE_LOG; |
|
+ continue; |
|
+ } |
|
+ if(strcmp(tmp,"pass")==0) |
|
+ { |
|
+ if(n_acl->fH){ n_acl->fH->destroy(); n_acl->fH=0; } |
|
+ n_acl->fH = 0; |
|
+ n_acl->pcap = ACTION_PASS; |
|
+ n_acl->pmode = OMODE_PASS; |
|
+ n_acl->cmode = CMODE_NONE; |
|
+ continue; |
|
+ } |
|
+ if(strcmp(tmp,"rule")==0) |
|
+ { |
|
+ if(n_acl->fH){ n_acl->fH->destroy(); n_acl->fH=0; } |
|
+ n_acl->fH = new pcapFileHandle(createPcapFileName(n_acl)); |
|
+ n_acl->pcap = ACTION_LOG; |
|
+ n_acl->pmode=OMODE_RULE; |
|
+ continue; |
|
+ } |
|
+ if(strcmp(tmp,"connection")==0) |
|
+ { |
|
+ n_acl->fH=0; |
|
+ n_acl->pcap = ACTION_LOG; |
|
+ n_acl->pmode=OMODE_UNIQ; |
|
+ continue; |
|
+ } |
|
+ if(strcmp(tmp,"filename")==0) |
|
+ { |
|
+ if((tmp = get_tok(rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, filename specified but none provided, using default filename %s\n",rule); |
|
+ return; |
|
+ }else{ |
|
+ if(n_acl->fH){ n_acl->fH->destroy(); n_acl->fH=0; } |
|
+ // Create this filename without a timestamp |
|
+ ftmp=createFileName(tmp,false); |
|
+ n_acl->fH = new pcapFileHandle(ftmp); |
|
+ free(ftmp); |
|
+ n_acl->pcap = ACTION_LOG; |
|
+ n_acl->pmode=OMODE_FILENAME; |
|
+ } |
|
+ continue; |
|
+ } |
|
+ if(strcmp(tmp,"tsfilename")==0) |
|
+ { |
|
+ if((tmp = get_tok(rules,accept))==NULL) |
|
+ { |
|
+ syslog(LOG_ERR,"Format error, tsfilename specified but none provided, using default pcap output file%s\n",rule); |
|
+ return; |
|
+ }else{ |
|
+ if(n_acl->fH){ n_acl->fH->destroy(); n_acl->fH=0; } |
|
+ // Create this filename with a timestamp |
|
+ ftmp=createFileName(tmp,true); |
|
+ n_acl->fH = new pcapFileHandle(ftmp); |
|
+ free(ftmp); |
|
+ n_acl->pcap = ACTION_LOG; |
|
+ n_acl->pmode=OMODE_TSFILENAME; |
|
+ } |
|
+ continue; |
|
+ } |
|
+ syslog(LOG_ERR,"Skipping, invalid pcap option in rule: %s %s\n",tok,tmp); |
|
+ return; |
|
+ } |
|
+ if(strcmp(tok,"logdst")==0) |
|
+ { |
|
+ n_acl->cmode = CMODE_DST; |
|
+ continue; |
|
+ } |
|
+ if(strcmp(tok,"logsrc")==0) |
|
+ { |
|
+ n_acl->cmode = CMODE_SRC; |
|
+ continue; |
|
+ } |
|
+ if(strcmp(tok,"ignore")==0) |
|
+ { |
|
+ // We should ignore everything for this rule |
|
+ n_acl->stats=n_acl->realtime=n_acl->pcap=ACTION_PASS; |
|
+ n_acl->cmode = CMODE_NONE; |
|
+ n_acl->pmode = OMODE_PASS; |
|
+ continue; |
|
+ } |
|
+ if(strcmp(tok,"retro")==0) // Apply rule to pre-existing connections in memory |
|
+ { |
|
+ n_acl->retro = true; |
|
+ continue; |
|
+ } |
|
+ syslog(LOG_ERR,"Skipping, invalid option in rule: %s %s\n", tok,*rules); |
|
+ return; |
|
+ } |
|
+ // If we made it this far, the rule is good |
|
+ // So we will add it to our list |
|
+ if(tacl_head){ |
|
+ tacl_tail->next=n_acl; |
|
+ }else{ |
|
+ tacl_head=n_acl; |
|
+ } |
|
+ tacl_tail=n_acl; |
|
+ if(n_acl->retro){ |
|
+ #ifdef DEBUG |
|
+ printf("Applying rule retro-actively!\n"); |
|
+ #endif |
|
+ retroactive(n_acl); |
|
+ } |
|
+ |
|
+} |
|
+/* |
|
+ * char * get_tok (char **rule, const char *delimiters ) |
|
+ * Uses strpbrk to locate the first occurrance of a character in *delimiters, |
|
+ * replaces this character with a null '\0', modifying **rule to point |
|
+ * one byte past the delimiter character. |
|
+ * |
|
+ * Returns pointer to beginning of token, or NULL if no delimiter is found. |
|
+ * |
|
+ */ |
|
+ |
|
+// Returns the rule you were pointing to and modifies rule |
|
+char * get_tok(char **rule, const char *delimiters) |
|
+{ |
|
+ char *tok=*rule; |
|
+ char *tmp=0; |
|
+ int len=0; |
|
+ if(*rule==NULL) |
|
+ return NULL; |
|
+ len=strlen(tok); |
|
+ |
|
+ if((tmp = strpbrk(*rule,delimiters))!=NULL){ |
|
+ *tmp=0; |
|
+ if(tmp>*rule) |
|
+ *rule=++tmp; |
|
+ } else { |
|
+ *rule=NULL; |
|
+ } |
|
+ return tok; |
|
+} |
|
+ |
|
+// Returns next tok or NULL |
|
+char * get_next_tok(char **rule, const char *delimiters) |
|
+{ |
|
+ char *tok=*rule; |
|
+ char *tmp; |
|
+ int len=0; |
|
+ if(*rule==NULL) |
|
+ return NULL; |
|
+ len=strlen(tok); |
|
+ |
|
+ if((tmp = strpbrk(*rule,delimiters))!=NULL){ |
|
+ *tmp='\0'; |
|
+ if(tmp>*rule) |
|
+ *rule=++tmp; |
|
+ return tok; |
|
+ } else { |
|
+ return NULL; |
|
+ } |
|
+} |
|
+ |
|
+void print_acl(int a){ |
|
+ extern struct gvars gVars; |
|
+ struct t_ports *tmp_port; |
|
+ struct t_ports *ports_head; |
|
+ char currenttime[80]; |
|
+ time_t timestr=gVars.timeptr.tv_sec; |
|
+ struct acl* tmpptr; |
|
+ int p, cidr,bits; |
|
+ char ptok[256]; |
|
+ char *tmp; |
|
+ u_int32_t tmpint; |
|
+ char LOG[1024]; |
|
+ tmpptr=gVars.acl_head; |
|
+ if(gVars.uselocaltime){ |
|
+ strftime(currenttime,80,"%Y-%m-%d %T",(struct tm *)localtime(×tr)); |
|
+ }else{ |
|
+ strftime(currenttime,80,"%Y-%m-%d %T GMT",(struct tm *)gmtime(×tr)); |
|
+ } |
|
+ bzero(LOG,1024); |
|
+ sprintf(LOG,"#\n# Running configuration as of %s\n#\n",currenttime); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ char type[10][36]={ {"unused or unassociated vars"},{"ethernet protocols"},{"networks and hosts"},{"ip protocols"},{"udp/tcp ports"},{ "rule ids"},{"rule groups (kinds of traffic)"},{"zones"},{"nodes"},{"status"}}; |
|
+ int unused=0; |
|
+ struct vars *tvars=gVars.var_head; |
|
+ for(int x=1; x<10; x++){ |
|
+ sprintf(LOG,"\n#\n# defined %s\n#\n",type[x]); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ while(tvars!=NULL){ |
|
+ if(tvars->vclass==x){ |
|
+ sprintf(LOG,"var %s %s\n",tvars->key,tvars->value); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ } |
|
+ if(tvars->vclass==0){ unused=1; } |
|
+ tvars=tvars->next; |
|
+ } |
|
+ tvars=gVars.var_head; |
|
+ } |
|
+ if(unused){ |
|
+ sprintf(LOG,"\n#\n# %s\n#\n",type[0]); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ while(tvars!=NULL){ |
|
+ if(tvars->vclass==0){ |
|
+ sprintf(LOG,"var %s %s\n",tvars->key,tvars->value); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ } |
|
+ tvars=tvars->next; |
|
+ } |
|
+ } |
|
+ sprintf(LOG,"\n#\n# define defaults\n#\n"); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ if(gVars.rmode==OMODE_FILENAME){ |
|
+ sprintf(LOG,"default realtime filename %s\n",gVars.realtime_fname); |
|
+ }else if(gVars.rmode==OMODE_TSFILENAME){ |
|
+ sprintf(LOG,"default realtime tsfilename %s\n",gVars.realtime_fname); |
|
+ }else{ |
|
+ sprintf(LOG,"default realtime=%s\n",gVars.pmode?"log":"pass"); |
|
+ } |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ if(gVars.smode==OMODE_FILENAME){ |
|
+ sprintf(LOG,"default stats filename %s\n",gVars.stats_fname); |
|
+ }else if(gVars.smode==OMODE_TSFILENAME){ |
|
+ sprintf(LOG,"default stats tsfilename %s\n",gVars.stats_fname); |
|
+ }else{ |
|
+ sprintf(LOG,"default stats=%s\n",gVars.smode?"log":"pass"); |
|
+ } |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ if(gVars.pmode==OMODE_FILENAME){ |
|
+ sprintf(LOG,"default pcap filename %s\n",gVars.pcap_fname); |
|
+ }else if(gVars.pmode==OMODE_TSFILENAME){ |
|
+ sprintf(LOG,"default pcap tsfilename %s\n",gVars.pcap_fname); |
|
+ }else{ |
|
+ sprintf(LOG,"default pcap=%s\n",gVars.pmode?"log":"pass"); |
|
+ } |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ if(gVars.pcap_raw){ |
|
+ sprintf(LOG,"default debug_pcap_raw=%s\n",gVars.pcap_raw?"enable":"disable"); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ } |
|
+ if(gVars.strip_80211){ |
|
+ sprintf(LOG,"default strip-80211=%s\n",gVars.strip_80211?"enable":"disable"); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ } |
|
+ sprintf(LOG,"default flush_interval=%u\n",gVars.default_flush_interval); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ sprintf(LOG,"default expire_interval=%u\n",gVars.default_expire_interval); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ sprintf(LOG,"default burst_mode=%s\n",gVars.burst_mode?"enable":"disable"); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ sprintf(LOG,"default status=%u\n",gVars.default_status); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ sprintf(LOG,"default node=%u\n",gVars.default_node); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ sprintf(LOG,"default zone=%u\n",gVars.default_zone); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ sprintf(LOG,"default rid=%u\n",gVars.default_rid); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ sprintf(LOG,"default rgid=%u\n",gVars.default_rgid); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ sprintf(LOG,"default timeout=%d\n",gVars.default_timeout); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ sprintf(LOG,"default limit=%llu\n",(long long unsigned)gVars.default_limit); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ sprintf(LOG,"default tcplag=%d\n",gVars.default_tcplag); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ if(gVars.bpf_filter){ |
|
+ sprintf(LOG,"default pcapfilter \"%s\"\n",gVars.bpf_filter); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ } |
|
+ sprintf(LOG,"\n#\n# define known_ports\n#\n"); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ for(p=0; p<MAX_IP_PROTO; p++) |
|
+ { |
|
+ ports_head=gVars.ports[p]; |
|
+ if(ports_head!=NULL) |
|
+ { |
|
+ strcat(LOG,"known_ports"); |
|
+ |
|
+ bzero(ptok,256); |
|
+ sprintf(ptok,"%d",p); |
|
+ if((tmp=rev_search_vars(ptok,gVars.var_head,VCLASS_2))!=NULL) |
|
+ { |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,tmp,sizeof(char)*strlen(tmp)); |
|
+ } |
|
+ sprintf(LOG,"%s %s ",LOG,ptok); |
|
+ |
|
+ while(ports_head!=NULL){ |
|
+ tmp_port=ports_head; |
|
+ ports_head=tmp_port->next; |
|
+ bzero(ptok,256); |
|
+ sprintf(ptok,"%d",tmp_port->l_port); |
|
+ if(tmp_port->l_port!=tmp_port->h_port) |
|
+ sprintf(ptok,"%s-%d",ptok,tmp_port->h_port); |
|
+ if((tmp=rev_search_vars(ptok,gVars.var_head,VCLASS_3))!=NULL) |
|
+ { |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,tmp,sizeof(char)*strlen(tmp)); |
|
+ } |
|
+ sprintf(LOG,"%s%s",LOG,ptok); |
|
+ if(tmp_port->next) |
|
+ strcat(LOG,","); |
|
+ } |
|
+ strcat(LOG,"\n"); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ } |
|
+ } |
|
+ sprintf(LOG,"\n#\n# Running rules as of %s\n#\n",currenttime); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ while(tmpptr!=NULL){ |
|
+ // |
|
+ // ETHPROTO (VCLASS_0) |
|
+ // |
|
+ |
|
+ bzero(ptok,256); |
|
+ if(tmpptr->h_proto_l==tmpptr->h_proto_h){ |
|
+ sprintf(ptok,"%d",tmpptr->h_proto_l); |
|
+ }else{ |
|
+ sprintf(ptok,"%d-%d",tmpptr->h_proto_l,tmpptr->h_proto_h); |
|
+ } |
|
+ if((tmp=rev_search_vars(ptok,gVars.var_head,VCLASS_0))!=NULL){ |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,tmp,sizeof(char)*strlen(tmp)); |
|
+ }else if(tmpptr->h_proto_l==0 && tmpptr->h_proto_h==0xFFFF ){ |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,"any",sizeof(char)*strlen("any")); |
|
+ } |
|
+ sprintf(LOG,"%s ",ptok); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ |
|
+ // |
|
+ // SOURCE IP (VCLASS_1) |
|
+ // |
|
+ |
|
+ bzero(ptok,256); |
|
+ sprintf(ptok,"%s",inet_ntoa(*(struct in_addr*) &tmpptr->s_ip)); |
|
+ if(tmpptr->s_mask!=0xFFFFFFFF){ |
|
+ tmpint = htonl(tmpptr->s_mask); |
|
+ cidr=bits=0; |
|
+ while((tmpint&0xC0000000)!=0x40000000){ |
|
+ bits++; |
|
+ if((tmpint&0xC0000000)!=0xC0000000){ cidr=bits; break; } |
|
+ tmpint<<=1; |
|
+ } |
|
+ if(htonl(tmpptr->s_mask)==(u_int32_t)(0xFFFFFFFF<<(32-cidr))){ |
|
+ sprintf(ptok,"%s/%d",ptok,cidr); |
|
+ }else{ |
|
+ sprintf(ptok,"%s/%s",ptok,inet_ntoa(*(struct in_addr*) &tmpptr->s_mask)); |
|
+ } |
|
+ } |
|
+ if((tmp=rev_search_vars(ptok,gVars.var_head,VCLASS_1))!=NULL) { |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,tmp,sizeof(char)*strlen(tmp)); |
|
+ }else if(tmpptr->s_ip==0){ |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,"any",sizeof(char)*strlen("any")); |
|
+ } |
|
+ sprintf(LOG,"%s ",ptok); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ |
|
+ // |
|
+ // DESTINATION IP (VCLASS_1) |
|
+ // |
|
+ |
|
+ bzero(ptok,256); |
|
+ sprintf(ptok,"%s",inet_ntoa(*(struct in_addr*) &tmpptr->d_ip)); |
|
+ if(tmpptr->d_mask!=0xFFFFFFFF){ |
|
+ tmpint = htonl(tmpptr->d_mask); |
|
+ cidr=bits=0; |
|
+ while((tmpint&0xC0000000)!=0x40000000){ |
|
+ bits++; |
|
+ if((tmpint&0xC0000000)!=0xC0000000){ cidr=bits; break; } |
|
+ tmpint<<=1; |
|
+ } |
|
+ if(htonl(tmpptr->d_mask)==(u_int32_t)(0xFFFFFFFF<<(32-cidr))){ |
|
+ sprintf(ptok,"%s/%d",ptok,cidr); |
|
+ }else{ |
|
+ sprintf(ptok,"%s/%s",ptok,inet_ntoa(*(struct in_addr*) &tmpptr->d_mask)); |
|
+ } |
|
+ } |
|
+ if((tmp=rev_search_vars(ptok,gVars.var_head,VCLASS_1))!=NULL) { |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,tmp,sizeof(char)*strlen(tmp)); |
|
+ }else if(tmpptr->d_ip==0){ |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,"any",sizeof(char)*strlen("any")); |
|
+ } |
|
+ sprintf(LOG,"%s ",ptok); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ |
|
+ // |
|
+ // IPPROTO (VCLASS_2) |
|
+ // |
|
+ |
|
+ bzero(ptok,256); |
|
+ sprintf(ptok,"%d",tmpptr->proto_l); |
|
+ if(tmpptr->proto_l!=tmpptr->proto_h){ |
|
+ sprintf(ptok,"%s-%d",ptok,tmpptr->proto_h); |
|
+ } |
|
+ if((tmp=rev_search_vars(ptok,gVars.var_head,VCLASS_2))!=NULL) { |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,tmp,sizeof(char)*strlen(tmp)); |
|
+ }else if(tmpptr->proto_l==0x00 && tmpptr->proto_h==0xFF){ |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,"any",sizeof(char)*strlen("any")); |
|
+ } |
|
+ sprintf(LOG,"%s ",ptok); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ |
|
+ // |
|
+ // Source TCP_UDP_PORT (VCLASS_3) |
|
+ // |
|
+ |
|
+ bzero(ptok,256); |
|
+ sprintf(ptok,"%d",tmpptr->s_port_l); |
|
+ if(tmpptr->s_port_l!=tmpptr->s_port_h){ |
|
+ sprintf(ptok,"%s-%d",ptok,tmpptr->s_port_h); |
|
+ } |
|
+ if((tmp=rev_search_vars(ptok,gVars.var_head,VCLASS_2))!=NULL) { |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,tmp,sizeof(char)*strlen(tmp)); |
|
+ }else if(tmpptr->s_port_l==0 && tmpptr->s_port_h==0xFFFF){ |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,"any",sizeof(char)*strlen("any")); |
|
+ } |
|
+ sprintf(LOG,"%s ",ptok); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ |
|
+ // |
|
+ // Destination TCP_UDP_PORT (VCLASS_3) |
|
+ // |
|
+ |
|
+ bzero(ptok,256); |
|
+ sprintf(ptok,"%d",tmpptr->d_port_l); |
|
+ if(tmpptr->d_port_l!=tmpptr->d_port_h){ |
|
+ sprintf(ptok,"%s-%d",ptok,tmpptr->d_port_h); |
|
+ } |
|
+ if((tmp=rev_search_vars(ptok,gVars.var_head,VCLASS_2))!=NULL) { |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,tmp,sizeof(char)*strlen(tmp)); |
|
+ }else if(tmpptr->d_port_l==0 && tmpptr->d_port_h==0xFFFF){ |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,"any",sizeof(char)*strlen("any")); |
|
+ } |
|
+ sprintf(LOG,"%s",ptok); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ |
|
+ // |
|
+ // Logging options |
|
+ // |
|
+ |
|
+ if(!tmpptr->stats && !tmpptr->realtime && !tmpptr->pcap){ |
|
+ // no logging options are enabled |
|
+ strcat(LOG,", ignore"); |
|
+ }else{ |
|
+ // |
|
+ // Only display logging actions that differ from the default logging actions |
|
+ // |
|
+ // |
|
+ // STATS |
|
+ // |
|
+ if(tmpptr->stats!=gVars.smode){ |
|
+ strcat(LOG,", stats"); |
|
+ if(tmpptr->smode==OMODE_PASS) |
|
+ strcat(LOG,"=pass"); |
|
+ else if(tmpptr->smode==OMODE_LOG) |
|
+ strcat(LOG,"=log"); |
|
+ } |
|
+ // |
|
+ // REALTIME |
|
+ // |
|
+ if(tmpptr->realtime!=gVars.rmode){ |
|
+ strcat(LOG,", realtime"); |
|
+ if(tmpptr->rmode==OMODE_PASS) |
|
+ strcat(LOG,"=pass"); |
|
+ else if(tmpptr->rmode==OMODE_LOG) |
|
+ strcat(LOG,"=log"); |
|
+ } |
|
+ // |
|
+ // PCAP |
|
+ // |
|
+ if(tmpptr->pmode!=gVars.pmode){ |
|
+ strcat(LOG,", pcap"); |
|
+ if(tmpptr->pmode==OMODE_PASS) |
|
+ strcat(LOG,"=pass"); |
|
+ else if(tmpptr->pmode==OMODE_LOG) |
|
+ strcat(LOG,"=log"); |
|
+ else if(tmpptr->pmode==OMODE_RULE) |
|
+ strcat(LOG,"=rule"); |
|
+ else if(tmpptr->pmode==OMODE_UNIQ) |
|
+ strcat(LOG,"=connection"); |
|
+ else if(tmpptr->pmode==OMODE_FILENAME && gVars.pfH->getFileHandle()!=tmpptr->fH->getFileHandle()) |
|
+ sprintf(LOG,"%s filename=%s",LOG,tmpptr->fH->getFileName()); |
|
+ else if(tmpptr->pmode==OMODE_TSFILENAME) |
|
+ sprintf(LOG,"%s tsfilename=%s",LOG,tmpptr->fH->getFileName()); |
|
+ } |
|
+ // |
|
+ // Half-stream direction collection flag |
|
+ // |
|
+ if(tmpptr->cmode==CMODE_SRC) |
|
+ strcat(LOG,", logsrc"); |
|
+ if(tmpptr->cmode==CMODE_DST) |
|
+ strcat(LOG,", logdst"); |
|
+ } |
|
+ |
|
+ // |
|
+ // REMAINING OPTIONS |
|
+ // |
|
+ |
|
+ // LIMIT |
|
+ if(tmpptr->limit!=gVars.default_limit) |
|
+ sprintf(LOG,"%s, limit=%llu",LOG,(long long unsigned)tmpptr->limit); |
|
+ // TIMEOUT |
|
+ if(tmpptr->timeout!=gVars.default_timeout) |
|
+ sprintf(LOG,"%s, timeout=%d",LOG,tmpptr->timeout); |
|
+ // TCPLAG |
|
+ if(tmpptr->tcplag!=gVars.default_tcplag) |
|
+ sprintf(LOG,"%s, tcplag=%d",LOG,tmpptr->tcplag); |
|
+ // RID VCLASS_4 |
|
+ if(tmpptr->rid) |
|
+ { |
|
+ bzero(ptok,256); |
|
+ sprintf(ptok,"%u",tmpptr->rid); |
|
+ if((tmp=rev_search_vars(ptok,gVars.var_head,VCLASS_4))!=NULL) { |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,tmp,sizeof(char)*strlen(tmp)); |
|
+ } |
|
+ sprintf(LOG,"%s, rid=%s",LOG,ptok); |
|
+ } |
|
+ // RGID VCLASS_5 |
|
+ if(tmpptr->rgid) |
|
+ { |
|
+ bzero(ptok,256); |
|
+ sprintf(ptok,"%u",tmpptr->rgid); |
|
+ if((tmp=rev_search_vars(ptok,gVars.var_head,VCLASS_5))!=NULL) { |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,tmp,sizeof(char)*strlen(tmp)); |
|
+ } |
|
+ sprintf(LOG,"%s, rgid=%s",LOG,ptok); |
|
+ } |
|
+ // ZONE VCLASS_6 |
|
+ if(tmpptr->zone) |
|
+ { |
|
+ bzero(ptok,256); |
|
+ sprintf(ptok,"%u",tmpptr->zone); |
|
+ if((tmp=rev_search_vars(ptok,gVars.var_head,VCLASS_6))!=NULL) { |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,tmp,sizeof(char)*strlen(tmp)); |
|
+ } |
|
+ sprintf(LOG,"%s, zone=%s",LOG,ptok); |
|
+ } |
|
+ // NODE VCLASS_7 |
|
+ if(tmpptr->node) |
|
+ { |
|
+ bzero(ptok,256); |
|
+ sprintf(ptok,"%u",tmpptr->node); |
|
+ if((tmp=rev_search_vars(ptok,gVars.var_head,VCLASS_7))!=NULL) { |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,tmp,sizeof(char)*strlen(tmp)); |
|
+ } |
|
+ sprintf(LOG,"%s, node=%s",LOG,ptok); |
|
+ } |
|
+ // STATUS VCLASS_8 |
|
+ if(tmpptr->status!=gVars.default_status) |
|
+ { |
|
+ bzero(ptok,256); |
|
+ sprintf(ptok,"%u",tmpptr->status); |
|
+ if((tmp=rev_search_vars(ptok,gVars.var_head,VCLASS_8))!=NULL) { |
|
+ bzero(ptok,256); |
|
+ strncpy(ptok,tmp,sizeof(char)*strlen(tmp)); |
|
+ } |
|
+ sprintf(LOG,"%s, status=%s",LOG,ptok); |
|
+ } |
|
+ // RETRO |
|
+ if(tmpptr->retro) |
|
+ strcat(LOG,", retro"); |
|
+ |
|
+ // DEFAULT RULE MATCHES |
|
+ sprintf(LOG,"%s # Matches: %d\n",LOG,tmpptr->ctr); |
|
+ |
|
+ tmpptr=tmpptr->next; |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ } |
|
+ sprintf(LOG,"# Implicit rule matches: %d\n",gVars.default_ctr); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ if(gVars.username || gVars.groupname){ |
|
+ sprintf(LOG,"# Running as: %s:%s\n",gVars.username,gVars.groupname); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ } |
|
+ if(gVars.config_file){ |
|
+ sprintf(LOG,"# Configuration file: %s \n",gVars.config_file?gVars.config_file:"CWD"); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ } |
|
+ if(gVars.log_directory){ |
|
+ sprintf(LOG,"# Output directory: %s \n",gVars.log_directory); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ } |
|
+ if(gVars.input_filename){ |
|
+ sprintf(LOG,"# Reading from file: %s \n",gVars.input_filename); |
|
+ LOG[1023]='\0'; gVars.sdF->write(LOG,strlen(LOG)); bzero(LOG,1024); |
|
+ } |
|
+ |
|
+} |
|
+ |
|
+void license() |
|
+{ |
|
+ fprintf(stdout,"\n -- Released under the QPL LICENSE --\n \n Copyright (C) 2003 John Curry <john.curry@metre.net>\n \n No Warranty Expressed or Implied\n "); |
|
+} |
|
+ |
|
+void version() |
|
+{ |
|
+ fprintf(stdout,"SA Network Connection Profiler v %s\n",VERSION); |
|
+} |
|
+ |
|
+void set_bpf_filter(char *argv) |
|
+{ |
|
+ extern struct gvars gVars; |
|
+ long len; |
|
+ |
|
+ if(gVars.bpf_fname){ free(gVars.bpf_fname); } |
|
+ gVars.bpf_fname=(char *) calloc(1,strlen(argv)+1); |
|
+ strncpy(gVars.bpf_fname,argv,strlen(argv)); |
|
+ if(gVars.bfH){ gVars.bfH->destroy(); gVars.bfH=0; } |
|
+ gVars.bfH = new fileHandle(gVars.bpf_fname); |
|
+ gVars.bfH->setMode(READ_MODE); |
|
+ gVars.bfH->seek(0,SEEK_END); |
|
+ len=gVars.bfH->tell(); |
|
+ if(gVars.bpf_filter){ free(gVars.bpf_filter); } |
|
+ if((gVars.bpf_filter = (char *) calloc(1,len+1))==NULL) |
|
+ { |
|
+#ifdef DEBUG |
|
+ syslog(LOG_CRIT,"Out of memory - bpf filter too big?\n"); |
|
+ return; |
|
+#endif |
|
+ } |
|
+ gVars.bfH->seek(0,0); |
|
+ gVars.bfH->close(); |
|
+ gVars.bfH->setMode(READ_MODE); |
|
+ if(gVars.bfH->read(gVars.bpf_filter,len)==-1) |
|
+ { |
|
+ switch (errno){ |
|
+ case EINTR: |
|
+ syslog(LOG_ERR,"Error reading bpf filter: EINTR\n"); |
|
+ break; |
|
+ case EAGAIN: |
|
+ syslog(LOG_ERR,"Error reading bpf filter: EAGAIN\n"); |
|
+ break; |
|
+ case EIO: |
|
+ syslog(LOG_ERR,"Error reading bpf filter: EIO\n"); |
|
+ break; |
|
+ case EISDIR: |
|
+ syslog(LOG_ERR,"Error reading bpf filter: EISDIR\n"); |
|
+ break; |
|
+ case EBADF: |
|
+ syslog(LOG_ERR,"Error reading bpf filter: EBADF\n"); |
|
+ break; |
|
+ case EINVAL: |
|
+ syslog(LOG_ERR,"Error reading bpf filter: EINVAL\n"); |
|
+ break; |
|
+ case EFAULT: |
|
+ syslog(LOG_ERR,"Error reading bpf filter: EFAULT\n"); |
|
+ break; |
|
+ } |
|
+ } |
|
+ if(gVars.bpf_filter[len-1]=='\n') |
|
+ gVars.bpf_filter[len-1]=0; |
|
+ /* We'll get rid of bpF here - close_files() |
|
+ * is not a good place for this right now |
|
+ * cause it gets called by reload_config() |
|
+ * and that may be confusing, until we can apply |
|
+ * new bpf filters -after- start-up |
|
+ */ |
|
+ if(gVars.bfH){ |
|
+ gVars.bfH->destroy(); gVars.bfH=NULL; |
|
+ } |
|
+ |
|
+} |
|
diff -ruN sancp-1.6.1-stable.vanilla/docs/README sancp-1.6.1-stable/docs/README |
|
--- sancp-1.6.1-stable.vanilla/docs/README 2007-07-06 03:33:14.000000000 +0200 |
|
+++ sancp-1.6.1-stable/docs/README 2007-07-24 13:44:01.000000000 +0200 |
|
@@ -277,6 +277,10 @@ |
|
strip-80211 { disable|enable } |
|
node <number> |
|
debug_pcap_raw { disable|enable } |
|
+ prelude_impact_severity [string] |
|
+ prelude_impact_completion [string] |
|
+ prelude_impact_type [string] |
|
+ prelude_confidence_rating [string] |
|
|
|
known_port syntax: |
|
-----------------------: |
|
@@ -310,6 +314,9 @@ |
|
b) tagging options |
|
i.e. status=16 rid=1112 node=2 |
|
|
|
+ c) prelude options |
|
+ i.e. severity=severe, completion=succeeded, type=other, confidence=high |
|
+ |
|
[<ether protocol>[-<end_range>] [<src_ip{/<CIDR>|<dotted>}>] [<dst_ip{/<CIDR>|<dotted>}>] [{tcp|udp|icmp|<proto number>[-<end_range>] }] |
|
[<src_port>{-[<end_port_range>]}] [<dst_port>{-[<end_port_range>]}] |
|
{ ignore | stats [{log|pass}] | realtime [{log|pass}] | |
|
diff -ruN sancp-1.6.1-stable.vanilla/gvars.h sancp-1.6.1-stable/gvars.h |
|
--- sancp-1.6.1-stable.vanilla/gvars.h 2007-07-05 18:12:20.000000000 +0200 |
|
+++ sancp-1.6.1-stable/gvars.h 2007-07-24 13:44:01.000000000 +0200 |
|
@@ -17,7 +17,8 @@ |
|
/* Make certain all id's are represented in the same order (as strings) in fmtnames[] */ |
|
/* 'null' is a place holder - in the list for field 0 */ |
|
|
|
-enum id {null,sancp_id,start_time_gmt,start_time_local,stop_time_gmt,stop_time_local,erased_time_gmt,erased_time_local,eth_proto_hex,eth_proto,ip_proto,src_ip_decimal,src_ip_dotted,src_port,dst_ip_decimal,dst_ip_dotted,dst_port,duration,timeout,src_pkts,dst_pkts,src_bytes,dst_bytes,sflags_hex,sflags,sflags_1,sflags_2,sflags_U,sflags_A,sflags_P,sflags_R,sflags_S,sflags_F,dflags_hex,dflags,dflags_1,dflags_2,dflags_U,dflags_A,dflags_P,dflags_R,dflags_S,dflags_F,cflags_hex,cflags,cflags_DA,cflags_SA,cflags_DR,cflags_SR,cflags_DF,cflags_SF,ip_len_s,ip_ttl_s,ip_df_s,tcp_wss_s,tcp_mss_s,tcp_wscale_s,tcp_sack_ok_s,tcp_nop_s,ip_len_d,ip_ttl_d,ip_df_d,tcp_wss_d,tcp_mss_d,tcp_wscale_d,tcp_sack_ok_d,tcp_nop_d,total_bytes,collect,collected,climit,tcplag,pcap,realtime,stats,reversed,hash,rid,rgid,node,zone,status,retro,src_mac,dst_mac }; |
|
+enum id |
|
+{null,sancp_id,start_time_gmt,start_time_local,stop_time_gmt,stop_time_local,erased_time_gmt,erased_time_local,eth_proto_hex,eth_proto,ip_proto,src_ip_decimal,src_ip_dotted,src_port,dst_ip_decimal,dst_ip_dotted,dst_port,duration,timeout,src_pkts,dst_pkts,src_bytes,dst_bytes,sflags_hex,sflags,sflags_1,sflags_2,sflags_U,sflags_A,sflags_P,sflags_R,sflags_S,sflags_F,dflags_hex,dflags,dflags_1,dflags_2,dflags_U,dflags_A,dflags_P,dflags_R,dflags_S,dflags_F,cflags_hex,cflags,cflags_DA,cflags_SA,cflags_DR,cflags_SR,cflags_DF,cflags_SF,ip_len_s,ip_ttl_s,ip_df_s,tcp_wss_s,tcp_mss_s,tcp_wscale_s,tcp_sack_ok_s,tcp_nop_s,ip_len_d,ip_ttl_d,ip_df_d,tcp_wss_d,tcp_mss_d,tcp_wscale_d,tcp_sack_ok_d,tcp_nop_d,total_bytes,collect,collected,climit,tcplag,pcap,realtime,stats,reversed,hash,rid,rgid,node,zone,status,retro,src_mac,dst_mac,prelude_impact_sevirty,prelude_impact_completion,prelude_impact_type,prelude_confidence_rating,prelude_profile }; |
|
|
|
struct cnx_queue { |
|
struct cnx *head; |
|
@@ -102,5 +103,10 @@ |
|
int stdout_fmt_len; |
|
pcap_t *ph; // pcap handle |
|
struct pcap_pkthdr *g_pkthdr;// |
|
+ char *prelude_impact_severity; |
|
+ char *prelude_impact_completion; |
|
+ char *prelude_impact_type; |
|
+ char *prelude_confidence_rating; |
|
+ char *prelude_profile; |
|
}; |
|
|
|
diff -ruN sancp-1.6.1-stable.vanilla/sancp.cc sancp-1.6.1-stable/sancp.cc |
|
--- sancp-1.6.1-stable.vanilla/sancp.cc 2007-07-05 18:12:20.000000000 +0200 |
|
+++ sancp-1.6.1-stable/sancp.cc 2007-07-24 13:44:01.000000000 +0200 |
|
@@ -48,7 +48,40 @@ |
|
//char dfltfmt[]= { sancp_id,start_time_gmt,src_mac,dst_mac,eth_proto,src_ip_dotted,dst_ip_dotted,ip_proto,src_port,dst_port }; |
|
char dfltfmt_human_readable[]= { sancp_id,start_time_gmt,stop_time_gmt,erased_time_gmt,eth_proto,ip_proto,src_ip_dotted,src_port,dst_ip_dotted,dst_port,duration,timeout,src_pkts,dst_pkts,src_bytes,dst_bytes,sflags_hex,dflags_hex,cflags_hex,ip_len_s,ip_ttl_s,ip_df_s,tcp_wss_s,tcp_mss_s,tcp_wscale_s,tcp_sack_ok_s,tcp_nop_s,ip_len_d,ip_ttl_d,ip_df_d,tcp_wss_d,tcp_mss_d,tcp_wscale_d,tcp_sack_ok_d,tcp_nop_d,total_bytes,collect,collected,climit,tcplag,pcap,realtime,stats,reversed,hash,rid,rgid,node,zone,status,retro,src_mac,dst_mac }; |
|
|
|
+prelude_client_t *client; |
|
+static idmef_analyzer_t *idmef_analyzer; |
|
|
|
+int sancp_alert_init(prelude_client_t *client) |
|
+{ |
|
+ int ret; |
|
+ prelude_string_t *string; |
|
+ |
|
+ idmef_analyzer = prelude_client_get_analyzer(client); |
|
+ if ( ! idmef_analyzer ) |
|
+ return -1; |
|
+ |
|
+ ret = idmef_analyzer_new_model(idmef_analyzer, &string); |
|
+ if ( ret < 0 ) |
|
+ return -1; |
|
+ prelude_string_set_constant(string, PRELUDE_ANALYZER_MODEL); |
|
+ |
|
+ ret = idmef_analyzer_new_class(idmef_analyzer, &string); |
|
+ if ( ret < 0 ) |
|
+ return -1; |
|
+ prelude_string_set_constant(string, PRELUDE_ANALYZER_CLASS); |
|
+ |
|
+ ret = idmef_analyzer_new_manufacturer(idmef_analyzer, &string); |
|
+ if ( ret < 0 ) |
|
+ return -1; |
|
+ prelude_string_set_constant(string, PRELUDE_ANALYZER_MANUFACTURER); |
|
+ |
|
+ ret = idmef_analyzer_new_version(idmef_analyzer, &string); |
|
+ if ( ret < 0 ) |
|
+ return -1; |
|
+ prelude_string_set_constant(string, VERSION); |
|
+ |
|
+ return 0; |
|
+} |
|
/************* |
|
* Main * |
|
*************/ |
|
@@ -56,6 +89,7 @@ |
|
int main(int argc, char *argv[]) { |
|
extern struct gvars gVars; |
|
int cKey; |
|
+ int ret; |
|
pid_t pid=0; |
|
|
|
/* |
|
@@ -102,6 +136,14 @@ |
|
gVars.stdout_delimiter=DEFAULT_DELIMITER; |
|
gVars.stdout_eor=DEFAULT_EOR; |
|
|
|
+ gVars.prelude_impact_severity=PRELUDE_IMPACT_SEVERITY; |
|
+ gVars.prelude_impact_completion=PRELUDE_IMPACT_COMPLETION; |
|
+ gVars.prelude_impact_type=PRELUDE_IMPACT_TYPE; |
|
+ gVars.prelude_confidence_rating=PRELUDE_CONFIDENCE_RATING; |
|
+ gVars.prelude_profile=PRELUDE_PROFILE; |
|
+ |
|
+ |
|
+ |
|
for(cKey=0; cKey<HASH_KEYS; cKey++) |
|
{ |
|
gVars.cnx_head[cKey]=NULL; |
|
@@ -116,6 +158,8 @@ |
|
|
|
parse_args(argc, argv); |
|
|
|
+ |
|
+ |
|
if(gVars.human_readable){ |
|
if(gVars.realtime_fmt_len!=sizeof(dfltfmt_human_readable)){ |
|
free(gVars.realtime_fmt); |
|
@@ -143,7 +187,15 @@ |
|
|
|
setsid(); |
|
} |
|
+ prelude_log_set_flags((prelude_log_flags_t)PRELUDE_LOG_FLAGS_SYSLOG); |
|
} |
|
+ |
|
+ /* Initialize prelude */ |
|
+ ret = prelude_init(&argc, argv); |
|
+ if (ret < 0) { |
|
+ prelude_perror(ret, "unable to initialize the prelude library"); |
|
+ exit_all(0); |
|
+ } |
|
/* Retrieve the last cnxid from cache file if we haven't already in parse_args() */ |
|
|
|
if(!gVars.cnx_id) |
|
@@ -197,6 +249,29 @@ |
|
|
|
build_config(1); |
|
|
|
+ /* Create prelude sensor */ |
|
+ |
|
+ ret = prelude_client_new(&client, gVars.prelude_profile); |
|
+ if ( ! client ) { |
|
+ prelude_perror(ret, "Unable to create a prelude client object"); |
|
+ exit_all(0); |
|
+ } |
|
+ |
|
+ /* Start prelude sensor */ |
|
+ sancp_alert_init(client); |
|
+ ret = prelude_client_start(client); |
|
+ if ( ret < 0 ) { |
|
+ prelude_perror(ret, "Unable to start prelude client"); |
|
+ exit_all(0); |
|
+ } |
|
+ |
|
+ ret = prelude_client_set_flags(client, (prelude_client_flags_t) |
|
+ (PRELUDE_CLIENT_FLAGS_ASYNC_SEND|PRELUDE_CLIENT_FLAGS_ASYNC_TIMER)); |
|
+ if ( ret < 0 ) { |
|
+ fprintf(stderr, "Unable to set asynchronous send and timer.\n"); |
|
+ exit_all(0); |
|
+ } |
|
+ |
|
/* Open files for output */ |
|
/* Be r3al l33t h3r3 */ |
|
|
|
diff -ruN sancp-1.6.1-stable.vanilla/sancp.h sancp-1.6.1-stable/sancp.h |
|
--- sancp-1.6.1-stable.vanilla/sancp.h 2007-07-06 06:18:04.000000000 +0200 |
|
+++ sancp-1.6.1-stable/sancp.h 2007-07-24 13:44:01.000000000 +0200 |
|
@@ -47,6 +47,10 @@ |
|
#include "gvars.h" |
|
#endif |
|
|
|
+#include <libprelude/prelude.h> |
|
+#include <libprelude/prelude-log.h> |
|
+#include <netdb.h> |
|
+ |
|
#define NCP_H |
|
#define Y 'Y' |
|
#define N 'N' |
|
@@ -79,6 +83,7 @@ |
|
struct vars *next; |
|
}; |
|
|
|
+extern prelude_client_t *client; |
|
int main(int argc, char *argv[]); |
|
struct cnx *process(struct cnx*, int len, u_char * pkt); |
|
char * createPcapFileName(); |
|
@@ -185,6 +190,15 @@ |
|
#define OMODE_RULE 5 |
|
#define OMODE_UNIQ 6 |
|
|
|
+#define PRELUDE_IMPACT_SEVERITY "medium" |
|
+#define PRELUDE_IMPACT_COMPLETION "succeeded" |
|
+#define PRELUDE_IMPACT_TYPE "other" |
|
+#define PRELUDE_CONFIDENCE_RATING "high" |
|
+#define PRELUDE_ANALYZER_MODEL "Sancp" |
|
+#define PRELUDE_ANALYZER_CLASS "NIDS" |
|
+#define PRELUDE_ANALYZER_MANUFACTURER "http://www.metre.net/sancp.html" |
|
+#define PRELUDE_PROFILE "sancp" |
|
+ |
|
// Need to distinguish between classes of variables |
|
#define VCLASS_0 1 // eth_proto class vars |
|
#define VCLASS_1 2 // ip_addr class vars |
|
@@ -276,6 +290,10 @@ |
|
u_int16_t rgid; |
|
u_int16_t node; |
|
u_int16_t zone; |
|
+ char *prelude_impact_severity; |
|
+ char *prelude_impact_completion; |
|
+ char *prelude_impact_type; |
|
+ char *prelude_confidence_rating; |
|
CBuffer *CBufferPtr; |
|
struct acl *next; |
|
}; |
|
@@ -314,6 +332,10 @@ |
|
u_int16_t rgid; |
|
u_int16_t node; |
|
u_int16_t zone; |
|
+ char *prelude_impact_severity; |
|
+ char *prelude_impact_completion; |
|
+ char *prelude_impact_type; |
|
+ char *prelude_confidence_rating; |
|
CBuffer *CBufferPtr; |
|
struct os_info os_info; |
|
struct os_info os_info2; |
|
diff -ruN sancp-1.6.1-stable.vanilla/sancp.h~ sancp-1.6.1-stable/sancp.h~ |
|
--- sancp-1.6.1-stable.vanilla/sancp.h~ 1970-01-01 01:00:00.000000000 +0100 |
|
+++ sancp-1.6.1-stable/sancp.h~ 2007-07-06 06:18:04.000000000 +0200 |
|
@@ -0,0 +1,327 @@ |
|
+/************************************************************************** |
|
+ **SA Network Connection Profiler [sancp] - A TCP/IP statistical/collection tool |
|
+ * ************************************************************************ |
|
+ * * Copyright (C) 2003 John Curry <john.curry@metre.net> |
|
+ * * |
|
+ * * This program is distributed under the terms of version 1.0 of the |
|
+ * * Q Public License. See LICENSE.QPL for further details. |
|
+ * * |
|
+ * * This program is distributed in the hope that it will be useful, |
|
+ * * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
+ * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
+ * * |
|
+ * ***********************************************************************/ |
|
+ |
|
+#define SANCP_H |
|
+ |
|
+ |
|
+//#define DEBUG 1 |
|
+ |
|
+#include <signal.h> // set_signals(), SIGHUP, signal, SIGUSR1, SIGUSR2, SIGTERM, SIGINT, SIGKILL, SIGQUIT |
|
+#include <arpa/inet.h> // inet_aton(), inet_ntoa() |
|
+#include <errno.h> // errno, EINTR, EAGAIN, EIO, EISDIR, EBADF, EINVAL, EFAULT |
|
+#include <syslog.h> // LOG_ERR, LOG_CONS, LOG_INFO, LOG_CRIT |
|
+ // LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4, LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7 |
|
+ |
|
+#include <ctype.h> |
|
+#include <time.h> |
|
+//#include <net/ethernet.h> |
|
+ |
|
+//#include <stdio.h> |
|
+//#include <unistd.h> |
|
+//#include <sys/socket.h> |
|
+ |
|
+// Required for BSD |
|
+#include <netinet/in.h> |
|
+ |
|
+//#include <net/if.h> |
|
+//#include <fcntl.h> |
|
+//#include <stdlib.h> |
|
+//#include <sys/ioctl.h> |
|
+//#include <time.h> |
|
+//#include <sys/time.h> |
|
+//#include <ctype.h> |
|
+//#include <string.h> |
|
+ |
|
+#ifndef GVARS_H |
|
+#include "gvars.h" |
|
+#endif |
|
+ |
|
+#define NCP_H |
|
+#define Y 'Y' |
|
+#define N 'N' |
|
+#define MIN_WAIT_TIME 4 // We will wait at least this many seconds before expiring a closed connection |
|
+ |
|
+// Include our own version of ether_addr since linux/solaris |
|
+// differ from bsd systems on definition of struct ether_addr |
|
+ |
|
+#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */ |
|
+ |
|
+struct myether_addr { |
|
+ u_char octet[ETHER_ADDR_LEN]; |
|
+}; |
|
+ |
|
+/* |
|
+ * Structure of a 10Mb/s Ethernet header. |
|
+ */ |
|
+struct ether_header { // we pulled this from net/ethernet.h |
|
+ u_char ether_dhost[ETHER_ADDR_LEN]; |
|
+ u_char ether_shost[ETHER_ADDR_LEN]; |
|
+ u_short ether_type; |
|
+}; |
|
+ |
|
+ |
|
+ |
|
+struct vars { |
|
+ char *key; |
|
+ char *value; |
|
+ int vclass; // variable class |
|
+ struct vars *next; |
|
+}; |
|
+ |
|
+int main(int argc, char *argv[]); |
|
+struct cnx *process(struct cnx*, int len, u_char * pkt); |
|
+char * createPcapFileName(); |
|
+char * createFileName(const char* filename); |
|
+char * createFileName(const char* filename, bool); |
|
+char * createPcapFileName(const struct acl* tacl); |
|
+char * createPcapFileName(const struct cnx* tcnx); |
|
+extern "C" pcap_t * open_pcap_live(char *,char *); |
|
+extern "C" pcap_t * open_pcap_file(char *,char *); |
|
+extern "C" void close_pcap_file(pcap_t *); |
|
+extern "C" void start_pcap_loop(pcap_t *); |
|
+extern "C" void print_linktype(pcap_t *); |
|
+void erase_idle(int a); |
|
+void reopen_files(int a); |
|
+void expire_connections(); |
|
+struct cnx *update_state_node(struct cnx *); |
|
+void build_config(int a); |
|
+void parse_args(int arg, char* argv[]); |
|
+void parse_format(const char *,const char *); |
|
+void print_acl(int a); |
|
+void print_stats(int a); |
|
+void print_output_schema(outputFileHandle *fH, char *fmtcols, int fmtlen); |
|
+void write_schema(char *name, char *fmt, int fmtlen); |
|
+void print_schemas(); |
|
+int fgetcline(char **buf, int size, FILE *fp); |
|
+int promisc_mode(char *, int); |
|
+void close_files(int a); |
|
+void open_files(); |
|
+void reload_config(int a); |
|
+void record_all(int a); |
|
+void free_all(int a); |
|
+void exit_all(int a); |
|
+void manage_cid(int a); |
|
+ |
|
+void record(struct cnx *, outputFileHandle *fH); |
|
+void set_signals(); |
|
+void decode(struct cnx*, int len, const u_char * pkt); |
|
+void decode_pcap(struct cnx*,struct pcap_pkthdr * pkthdr, u_char * pkt); |
|
+int CheckPort(u_int8_t proto,u_int16_t port); |
|
+void SChangeUserGroup(); |
|
+void apply_rule(struct cnx*); |
|
+void parse_var(char *,char *); |
|
+void parse_known_ports(char *, struct vars*, char *); |
|
+void parse_connection_rule(char *, struct vars*, char *); |
|
+void open_pcap_output(); |
|
+ |
|
+/* Hash Table Protos */ |
|
+#define DEFAULT_FLUSH_INTERVAL 1800 |
|
+#define DEFAULT_EXPIRE_INTERVAL 10 |
|
+#define VERSION "1.6.1-stable" |
|
+#define NAME "sancp" |
|
+#define LOG_DIR "./" /* default relative to current working directory */ |
|
+#define CONFIG_DIR "/etc/sancp/" |
|
+#define CONFIG_FILE "sancp.conf" |
|
+#define PCAP_RAW_FNAME "debug_pcap_raw" |
|
+#define PCAP_FNAME "pcap" |
|
+#define STATS_FNAME "stats" |
|
+#define REALTIME_FNAME "realtime" |
|
+#define true 1 |
|
+#define false 0 |
|
+#define PROMISC 1 |
|
+#define MAX_VAR 256 |
|
+#define MAXFLDS 85 // define number of elements in fmtnames[] |
|
+#define MAXFLDSIZE 19 // define largest element in fmtnames[MAXFLDS][MAXFLDLEN] |
|
+#define MAXENTRYLEN 256 |
|
+#define DELIMITER '|' |
|
+#define READ_TIMEOUT 500 |
|
+#define ETHPROTO_IP 0x0008 |
|
+// network order bytes 0x0806 |
|
+#define ETHPROTO_ARP 0x0608 |
|
+// network order bytes 0x8035 |
|
+#define ETHPROTO_RARP 0x3580 |
|
+// network order bytes 0x8100 |
|
+#define ETHPROTO_8021Q 0x0081 |
|
+#define DEFAULT_DEVICE "any" |
|
+#define DEFAULT_NODE 0 |
|
+#define DEFAULT_LIMIT 0 |
|
+#define DEFAULT_RID 0 |
|
+#define DEFAULT_RGID 0 |
|
+#define DEFAULT_ZONE 0 |
|
+//#define TCP_TIMEOUT 120 |
|
+//#define UDP_TIMEOUT 300 |
|
+//#define ICMP_TIMEOUT 120 |
|
+#define DEFAULT_TIMEOUT 300 |
|
+#define DEFAULT_STATUS 0 |
|
+#define DEFAULT_LAG 0 |
|
+#define DEFAULT_DELIMITER '|' |
|
+#define DEFAULT_EOR '\n' |
|
+#define MAX_PORTS 65536 |
|
+#define FROM_INITIATOR 0 |
|
+#define FROM_TARGET 1 |
|
+#define ACTION_PASS 0 |
|
+#define ACTION_LOG 1 |
|
+#define ACTION_DEFAULT 2 |
|
+#define CMODE_NONE 0 |
|
+#define CMODE_BOTH 1 |
|
+#define CMODE_SRC 2 |
|
+#define CMODE_DST 3 |
|
+#define OMODE_PASS 0 |
|
+#define OMODE_LOG 1 |
|
+#define OMODE_DEFAULT 2 |
|
+#define OMODE_FILENAME 3 |
|
+#define OMODE_TSFILENAME 4 |
|
+#define OMODE_RULE 5 |
|
+#define OMODE_UNIQ 6 |
|
+ |
|
+// Need to distinguish between classes of variables |
|
+#define VCLASS_0 1 // eth_proto class vars |
|
+#define VCLASS_1 2 // ip_addr class vars |
|
+#define VCLASS_2 3 // ip_proto class vars |
|
+#define VCLASS_3 4 // port class vars |
|
+#define VCLASS_4 5 // rid class vars |
|
+#define VCLASS_5 6 // rgid class vars |
|
+#define VCLASS_6 7 // zone class vars |
|
+#define VCLASS_7 8 // node class vars |
|
+#define VCLASS_8 9 // status class vars |
|
+ |
|
+#define DISABLED 0 |
|
+#define ENABLED 1 |
|
+#define CNX_REVERSED 1 |
|
+#define CNX_BOTH_PORTS_KNOWN 2 |
|
+#define CNX_BOTH_PORTS_UNKNOWN 3 |
|
+#define CNX_REREVERSED 4 |
|
+#define MAX_PACK_LEN 20000 /* Sufficient for ethernet packets. */ |
|
+#define ETHER_SIZE 14 |
|
+#ifdef EXPERIMENTAL_TCPOPTIONS |
|
+#define TCPOPT_EOL 0 |
|
+#define TCPOPT_NOP 1 |
|
+#define TCPOPT_MAXSEG 2 |
|
+#define TCPOPT_SACKOK 4 /* Experimental */ |
|
+#define TCPOPT_WSCALE 3 |
|
+#define TCPOPTIONS_MAX 8 /* Maximum number of tcpoptions to parse */ |
|
+#endif |
|
+ |
|
+ |
|
+#define R_FIN 0x01 |
|
+#define R_SYN 0x02 |
|
+#define R_RST 0x04 |
|
+#define R_PSH 0x08 |
|
+#define R_ACK 0x10 |
|
+#define R_URG 0x20 |
|
+#define R_RES2 0x40 |
|
+#define R_RES1 0x80 |
|
+#define max(i,j) (((i)>(j)) ? (i) : (j)) |
|
+#define SIZE_OF_CLASS_C 11 |
|
+ |
|
+struct t_ports { |
|
+ u_int16_t l_port; |
|
+ u_int16_t h_port; |
|
+ struct t_ports *next; |
|
+}; |
|
+ |
|
+ |
|
+struct os_info { |
|
+ u_int8_t ttl; |
|
+ u_int16_t len; |
|
+ u_int16_t wss; |
|
+#ifdef EXPERIMENTAL_TCPOPTIONS |
|
+ u_int8_t df:1, nop:1, sack_ok:1; |
|
+ u_int16_t mss; |
|
+ short wscale; |
|
+#else |
|
+ u_int8_t df:1; |
|
+#endif |
|
+ |
|
+}; |
|
+ |
|
+ |
|
+struct acl { |
|
+ struct ether_header eth_hdr; |
|
+ u_int16_t h_proto_h; |
|
+ u_int16_t h_proto_l; |
|
+ u_int32_t s_ip; |
|
+ u_int32_t s_mask; |
|
+ u_int16_t s_port_l; |
|
+ u_int16_t s_port_h; |
|
+ u_int32_t d_ip; |
|
+ u_int32_t d_mask; |
|
+ u_int16_t d_port_l; |
|
+ u_int16_t d_port_h; |
|
+ u_int8_t proto_l; |
|
+ u_int8_t proto_h; |
|
+ u_int32_t offset; |
|
+ u_int32_t mask; |
|
+ u_int32_t value; |
|
+ pcapFileHandle * fH; |
|
+ u_int8_t stats:1, realtime:1, pcap:1, retro:1, smode:2, rmode:2; |
|
+ u_int8_t cmode:2, pmode:4; |
|
+ u_int16_t tcplag; |
|
+ u_int16_t timeout; |
|
+ u_int64_t limit; |
|
+ u_int16_t status; |
|
+ u_int32_t ctr; |
|
+ u_int32_t rid; |
|
+ u_int16_t rgid; |
|
+ u_int16_t node; |
|
+ u_int16_t zone; |
|
+ CBuffer *CBufferPtr; |
|
+ struct acl *next; |
|
+}; |
|
+ |
|
+void retroactive(struct acl*); |
|
+ |
|
+struct cnx { |
|
+ struct ether_header eth_hdr; |
|
+ u_int16_t h_proto; |
|
+ u_int8_t proto; |
|
+ u_int32_t s_ip; |
|
+ u_int32_t d_ip; |
|
+ u_int16_t s_port; |
|
+ u_int16_t d_port; |
|
+ u_int64_t s_total_pkts; |
|
+ u_int64_t s_total_bytes; |
|
+ u_int64_t d_total_pkts; |
|
+ u_int64_t d_total_bytes; |
|
+ u_int64_t total_bytes; |
|
+ time_t start_time; |
|
+ time_t last_pkt; |
|
+ u_int8_t free:1,direction:1; |
|
+ pcapFileHandle *fH; |
|
+ u_int8_t cmode:4, pcap:1, realtime:1, stats:1, retro:1; |
|
+ u_int8_t tcpFlags[2]; |
|
+ u_int8_t tcpCFlags; |
|
+ u_int8_t reversed; |
|
+ u_int16_t tcplag; |
|
+ u_int64_t limit; |
|
+ u_int16_t status; |
|
+ u_int64_t collected; |
|
+ u_int64_t cid; |
|
+ u_int16_t timeout; |
|
+ u_int16_t hash; |
|
+ u_int32_t rid; |
|
+ u_int16_t rgid; |
|
+ u_int16_t node; |
|
+ u_int16_t zone; |
|
+ CBuffer *CBufferPtr; |
|
+ struct os_info os_info; |
|
+ struct os_info os_info2; |
|
+ struct cnx *next; |
|
+ struct cnx *prev; |
|
+}; |
|
+ |
|
+ |
|
+void usage(); |
|
+void outputfields(); |
|
+void rule_syntax(); |
|
diff -ruN sancp-1.6.1-stable.vanilla/statefull_logging.cc sancp-1.6.1-stable/statefull_logging.cc |
|
--- sancp-1.6.1-stable.vanilla/statefull_logging.cc 2007-07-05 18:12:20.000000000 +0200 |
|
+++ sancp-1.6.1-stable/statefull_logging.cc 2007-07-24 13:44:01.000000000 +0200 |
|
@@ -183,6 +183,208 @@ |
|
snprintf(buf,len,"%s",currenttime); |
|
} |
|
|
|
+static int add_idmef_object(idmef_message_t *message, const char *object, const char *value) |
|
+{ |
|
+ int ret; |
|
+ idmef_value_t *val; |
|
+ idmef_path_t *path; |
|
+ |
|
+ ret = idmef_path_new(&path, object); |
|
+ if ( ret < 0 ) |
|
+ return -1; |
|
+ |
|
+ ret = idmef_value_new_from_path(&val, path, value); |
|
+ if ( ret < 0 ) { |
|
+ idmef_path_destroy(path); |
|
+ return -1; |
|
+ } |
|
+ |
|
+ ret = idmef_path_set(path, message, val); |
|
+ |
|
+ idmef_value_destroy(val); |
|
+ idmef_path_destroy(path); |
|
+ |
|
+ return ret; |
|
+} |
|
+ |
|
+#define IDMEF(x) { \ |
|
+ int ret = (x); \ |
|
+ if (ret < 0) { idmef_message_destroy(idmef); printf("error\n"); return; } \ |
|
+ } |
|
+ |
|
+void record_prelude(struct cnx *cn) { |
|
+ char LOG[MAXENTRYLEN]; |
|
+ |
|
+ idmef_message_t *idmef; |
|
+ idmef_alert_t *alert; |
|
+ idmef_time_t *time; |
|
+ |
|
+ struct servent *sourceservent; |
|
+ struct protoent *protoent; |
|
+ |
|
+ IDMEF(idmef_message_new(&idmef)); |
|
+ IDMEF(idmef_message_new_alert(idmef, &alert)); |
|
+ |
|
+ /* alert.detecttime */ |
|
+ if (cn->start_time) { |
|
+ IDMEF(idmef_time_new_from_time(&time, &cn->start_time)); |
|
+ } else { |
|
+ /* using the curen time */ |
|
+ IDMEF(idmef_time_new_from_gettimeofday(&time)); |
|
+ } |
|
+ idmef_alert_set_detect_time(alert, time); |
|
+ |
|
+ /* alert.createtime */ |
|
+ time = NULL; |
|
+ IDMEF(idmef_time_new_from_gettimeofday(&time)); |
|
+ idmef_alert_set_create_time(alert, time); |
|
+ |
|
+ /* alert.analyzer */ |
|
+ idmef_alert_set_analyzer(alert,idmef_analyzer_ref(prelude_client_get_analyzer(client)),0); |
|
+ |
|
+ /* alert.classification.text */ |
|
+ add_idmef_object(idmef, "alert.classification.text", |
|
+ "Unauthorized network connectivity"); |
|
+ |
|
+ /* alert.messageid */ |
|
+ snprintf(LOG,MAXENTRYLEN,"%lld",cn->cid); |
|
+ add_idmef_object(idmef, "alert.messageid", LOG); |
|
+ |
|
+ /* alert.impact.severity */ |
|
+ add_idmef_object(idmef, "alert.assessment.impact.severity", |
|
+ cn->prelude_impact_severity); |
|
+ |
|
+ /* alert.impact.completion */ |
|
+ add_idmef_object(idmef, "alert.assessment.impact.completion", |
|
+ cn->prelude_impact_completion); |
|
+ |
|
+ /* alert.impact.type */ |
|
+ add_idmef_object(idmef, "alert.assessment.impact.type", |
|
+ cn->prelude_impact_type); |
|
+ |
|
+ /* alert.confidence.rating */ |
|
+ add_idmef_object(idmef, "alert.assessment.confidence.rating", |
|
+ cn->prelude_confidence_rating); |
|
+ |
|
+ /* alert.additionaldata(0) */ |
|
+ add_idmef_object(idmef, "alert.additionaldata(0).type", "integer"); |
|
+ add_idmef_object(idmef, "alert.additionaldata(0).meaning", "status"); |
|
+ snprintf(LOG,MAXENTRYLEN,"%u",cn->status); |
|
+ add_idmef_object(idmef, "alert.additionaldata(0).integer", LOG); |
|
+ |
|
+ /* alert.additionaldata(1) */ |
|
+ add_idmef_object(idmef, "alert.additionaldata(1).type", "integer"); |
|
+ add_idmef_object(idmef, "alert.additionaldata(1).meaning", "Network node"); |
|
+ snprintf(LOG,MAXENTRYLEN,"%u",cn->node); |
|
+ add_idmef_object(idmef, "alert.additionaldata(1).integer", LOG); |
|
+ |
|
+ /* IP versios */ |
|
+ if (cn->h_proto == 8) { |
|
+ add_idmef_object(idmef, "alert.source(0).service.ip_version", "4"); |
|
+ add_idmef_object(idmef, "alert.target(0).service.ip_version", "4"); |
|
+ } else { |
|
+ /* bail out */ |
|
+ idmef_message_destroy(idmef); |
|
+ return; |
|
+ } |
|
+ |
|
+ /* alert.source(0).node.address(0) (ip address) */ |
|
+ if(cn->reversed==CNX_REVERSED){ |
|
+ snprintf_inaddr_toa(LOG,MAXENTRYLEN,(struct in_addr*) &cn->d_ip,'\0'); |
|
+ }else{ |
|
+ snprintf_inaddr_toa(LOG,MAXENTRYLEN,(struct in_addr*) &cn->s_ip,'\0'); |
|
+ } |
|
+ add_idmef_object(idmef, "alert.source(0).node.address(0).category", |
|
+ "ipv4-addr"); |
|
+ add_idmef_object(idmef, "alert.source(0).node.address(0).address", LOG); |
|
+ |
|
+ /* alert.source(0).node.address(1) (mac address) */ |
|
+ add_idmef_object(idmef, "alert.source(0).node.address(1).category", "mac"); |
|
+ { |
|
+ struct myether_addr *es=(struct myether_addr *)&cn->eth_hdr.ether_shost; |
|
+ snprintf(LOG,MAXENTRYLEN,"%0x:%0x:%0x:%0x:%0x:%0x",es->octet[0],es->octet[1],es->octet[2],es->octet[3],es->octet[4],es->octet[5]); |
|
+ } |
|
+ add_idmef_object(idmef, "alert.source(0).node.address(1).address", LOG); |
|
+ |
|
+ protoent = getprotobynumber(cn->proto); |
|
+ |
|
+ /* alert.source(0).iana_protocol_number */ |
|
+ snprintf(LOG,MAXENTRYLEN,"%u",(cn->proto)); |
|
+ add_idmef_object(idmef, "alert.source(0).service.iana_protocol_number", LOG); |
|
+ |
|
+ /* alert.target(0).iana_protocol_number */ |
|
+ add_idmef_object(idmef, "alert.target(0).service.iana_protocol_number", LOG); |
|
+ |
|
+ |
|
+ if (protoent) { |
|
+ /* alert.source(0).iana_protocol_name */ |
|
+ add_idmef_object(idmef, "alert.source(0).service.iana_protocol_name", |
|
+ protoent->p_name); |
|
+ |
|
+ /* alert.target(0).iana_protocol_name */ |
|
+ add_idmef_object(idmef, "alert.target(0).service.iana_protocol_name", |
|
+ protoent->p_name); |
|
+ |
|
+ /* alert.source(0).service */ |
|
+ setservent(1); |
|
+ if(cn->reversed==CNX_REVERSED){ |
|
+ snprintf(LOG,MAXENTRYLEN,"%u",ntohs(cn->d_port)); |
|
+ sourceservent = getservbyport(ntohs(cn->d_port), protoent->p_name); |
|
+ }else{ |
|
+ snprintf(LOG,MAXENTRYLEN,"%u",ntohs(cn->s_port)); |
|
+ sourceservent = getservbyport(ntohs(cn->s_port), protoent->p_name); |
|
+ } |
|
+ |
|
+ if (sourceservent && sourceservent->s_name) |
|
+ add_idmef_object(idmef, "alert.source(0).service.name", |
|
+ sourceservent->s_name ); |
|
+ add_idmef_object(idmef, "alert.source(0).service.port", |
|
+ LOG); |
|
+ add_idmef_object(idmef, "alert.source(0).service.protocol", |
|
+ protoent->p_name); |
|
+ |
|
+ /* alert.target(0).service */ |
|
+ if(cn->reversed==CNX_REVERSED){ |
|
+ snprintf(LOG,MAXENTRYLEN,"%u",ntohs(cn->s_port)); |
|
+ sourceservent = getservbyport(ntohs(cn->s_port), protoent->p_name); |
|
+ }else{ |
|
+ snprintf(LOG,MAXENTRYLEN,"%u",ntohs(cn->d_port)); |
|
+ sourceservent = getservbyport(ntohs(cn->d_port), protoent->p_name); |
|
+ } |
|
+ |
|
+ if (sourceservent && sourceservent->s_name) |
|
+ add_idmef_object(idmef, "alert.target(0).service.name", |
|
+ sourceservent->s_name ); |
|
+ add_idmef_object(idmef, "alert.target(0).service.port", |
|
+ LOG); |
|
+ add_idmef_object(idmef, "alert.target(0).service.protocol", |
|
+ protoent->p_name); |
|
+ } |
|
+/* |
|
+*/ |
|
+ |
|
+ /* alert.target(0).node.address(0) (ip address) */ |
|
+ if(cn->reversed==CNX_REVERSED){ |
|
+ snprintf_inaddr_toa(LOG,MAXENTRYLEN,(struct in_addr*) &cn->s_ip,'\0'); |
|
+ }else{ |
|
+ snprintf_inaddr_toa(LOG,MAXENTRYLEN,(struct in_addr*) &cn->d_ip,'\0'); |
|
+ } |
|
+ add_idmef_object(idmef, "alert.target(0).node.address(0).category", |
|
+ "ipv4-addr"); |
|
+ add_idmef_object(idmef, "alert.target(0).node.address(0).address", LOG); |
|
+ |
|
+ /* alert.target(0).node_address(1) (mac address) */ |
|
+ add_idmef_object(idmef, "alert.target(0).node.address(1).category", "mac"); |
|
+ { |
|
+ struct myether_addr *es=(struct myether_addr *)&cn->eth_hdr.ether_dhost; |
|
+ snprintf(LOG,MAXENTRYLEN,"%0x:%0x:%0x:%0x:%0x:%0x",es->octet[0],es->octet[1],es->octet[2],es->octet[3],es->octet[4],es->octet[5]); |
|
+ } |
|
+ add_idmef_object(idmef, "alert.target(0).node.address(1).address", LOG); |
|
+ |
|
+ prelude_client_send_idmef(client, idmef); |
|
+ idmef_message_destroy(idmef); |
|
+} |
|
+ |
|
|
|
void record(struct cnx *cn, outputFileHandle *fH) |
|
{ |
|
@@ -199,8 +401,15 @@ |
|
|
|
char eor=fH->getEor(); |
|
|
|
+ /* do we want prelude alert generation for this record? */ |
|
+ |
|
bzero(LOG,MAXENTRYLEN); |
|
|
|
+ if (fH == gVars.sfH) { |
|
+ record_prelude(cn); |
|
+ } |
|
+ |
|
+ |
|
|
|
/* |
|
* Structure of a 48-bit Ethernet address.
|
|
|