diff --git a/network/sancp/sancp-1.6.1-stable-prelude-3.diff b/network/sancp/sancp-1.6.1-stable-prelude-3.diff index 2eeb5744c..1b5671773 100644 --- a/network/sancp/sancp-1.6.1-stable-prelude-3.diff +++ b/network/sancp/sancp-1.6.1-stable-prelude-3.diff @@ -201,2658 +201,6 @@ diff -ruN sancp-1.6.1-stable.vanilla/build_acl.cc sancp-1.6.1-stable/build_acl.c 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 -+ * * -+ * * 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; pnext; -+ 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((fmtvalMAXFLDS-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; pnext; -+ 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 \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 @@ -3083,337 +431,6 @@ diff -ruN sancp-1.6.1-stable.vanilla/sancp.h sancp-1.6.1-stable/sancp.h 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 -+ * * -+ * * 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 // set_signals(), SIGHUP, signal, SIGUSR1, SIGUSR2, SIGTERM, SIGINT, SIGKILL, SIGQUIT -+#include // inet_aton(), inet_ntoa() -+#include // errno, EINTR, EAGAIN, EIO, EISDIR, EBADF, EINVAL, EFAULT -+#include // LOG_ERR, LOG_CONS, LOG_INFO, LOG_CRIT -+ // LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4, LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7 -+ -+#include -+#include -+//#include -+ -+//#include -+//#include -+//#include -+ -+// Required for BSD -+#include -+ -+//#include -+//#include -+//#include -+//#include -+//#include -+//#include -+//#include -+//#include -+ -+#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