%{ extern "C" { #include #include #include #include #include #include #include #include #include #include #include #include } #include "aclocal.h" #include "caida_t.h" #include #include "CflowdConfig.hh" #include "CflowdRawFlow.hh" #include "CflowdConfigLex.hh" #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif extern int errno; const char *g_configFileName = (const char *)0; yyFlexLexer *lexer = (yyFlexLexer *)0; static long lineNum = 1; int parenstack = 0; int i; void yyerror(const char *msg); static char rcsid[] = "@(#) $Name: cflowd-2-1-b1 $ $Id: config.lex,v 1.17 1999/05/25 10:27:08 dwm Exp $"; void yyperror(char *msg) { fprintf(stderr,"parse error in %s line %ld: %s\n",g_configFileName,lineNum, msg); return; } %} matched_OPTIONS ^[ \t]*OPTIONS[\t ]*[{][\t ]* matched_LOGFACILITY ^[ \t]*LOGFACILITY[:][\t ]* matched_TCPCOLLECTPORT ^[ \t]*TCPCOLLECTPORT[:][\t ]* matched_PKTBUFSIZE ^[ \t]*PKTBUFSIZE[:][\t ]* matched_RAWFLOWSOCKFILE ^[ \t]*RAWFLOWSOCKFILE[:][ \t]* matched_TABLESOCKFILE ^[ \t]*TABLESOCKFILE[:][ \t]* matched_MAPDIR ^[ \t]*MAPDIR[:][\t ]* matched_FLOWDIR ^[ \t]*FLOWDIR[:][\t ]* matched_FLOWFILELEN ^[ \t]*FLOWFILELEN[:][\t ]* matched_NUMFLOWFILES ^[ \t]*NUMFLOWFILES[:][\t ]* matched_MINLOGMISSED ^[ \t]*MINLOGMISSED[:][\t ]* matched_CISCOEXPORTER ^[ \t]*CISCOEXPORTER[\t ]*[{][\t ]* matched_HOST ^[ \t]*HOST[:][\t ]* matched_number [0-9]+ matched_hex 0x[0-9A-Fa-f]+ matched_ip_address [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} matched_directory \/[^#\*\&\^\$ \t\n\!\~\`\'\"\;]* matched_ADDRESSES ^[ \t]*ADDRESSES[:][\t ]*[{][\t ]* matched_CFDATAPORT ^[ \t]*CFDATAPORT[:][\t ]* matched_SNMPCOMM ^[ \t]*SNMPCOMM[:][\t ]*[\'] matched_LOCALAS ^[ \t]*LOCALAS[:][\t ]* matched_COLLECT ^[ \t]*COLLECT[:][\t ]*[{][\t ]* matched_COLLECTOR ^[ \t]*COLLECTOR[\t ]*[{][\t ]* matched_AUTH ^[ \t]*AUTH[:][\t ]* matched_flowword srcaddr|dstaddr|input_if|output_if|srcport|dstport|pkts|bytes|nexthop|starttime|endtime|protocol|tos|src_as|dst_as|src_mask|dst_mask|tcp_flags %x OPTIONS %x LOGFACILITY %x TCPCOLLECTPORT %x PKTBUFSIZE %x RAWFLOWSOCKFILE %x TABLESOCKFILE %x MAPDIR %x FLOWDIR %x FLOWFILELEN %x NUMFLOWFILES %x MINLOGMISSED %x CISCOEXPORTER %x HOST %x IPADDRESS %x IFADDRESSES %x CFDATAPORT %x SNMPCOMM %x LOCALAS %x COLLECT %x COLLECTOR %x COLLECTORHOST %x COLLECTORADDR %x COLLECTORAUTH %x CONFIG_LEX_ERROR %% [ \t,]+ [ \t,]+ [ \t,]+ [ \t,]+ [ \t,]+ [ \t,]+ [ \t,]+ [ \t,]+ [ \t,]+ [ \t,]+ [ \t,]+ [ \t,]+ [ \t,]+ [ \t,]+ [ \t,]+ [ \t,]+ [ \t,]+ [ \t,]+ [ \t,]+ [ \t,]+ [ \t,]+ [ \t,]+ [\n] {lineNum++;} [\n] {lineNum++;} [\n] {lineNum++;} [\n] {lineNum++;} [\n] {lineNum++;} [\n] {lineNum++;} [\n] {lineNum++;} [\n] {lineNum++;} [\n] {lineNum++;} [\n] {lineNum++;} [\n] {lineNum++;} [\n] {lineNum++;} [\n] {lineNum++;} [\n] {lineNum++;} [\n] {lineNum++;} [\n] {lineNum++;} [\n] {lineNum++;} [\n] {lineNum++;} [\n] {lineNum++;} [\n] {lineNum++;} [\n] {lineNum++;} [\n] {lineNum++;} #.*\n {lineNum++;} #.*\n {lineNum++;} #.*\n {lineNum++;} #.*\n {lineNum++;} #.*\n {lineNum++;} #.*\n {lineNum++;} #.*\n {lineNum++;} #.*\n {lineNum++;} #.*\n {lineNum++;} #.*\n {lineNum++;} #.*\n {lineNum++;} #.*\n {lineNum++;} #.*\n {lineNum++;} #.*\n {lineNum++;} #.*\n {lineNum++;} #.*\n {lineNum++;} #.*\n {lineNum++;} #.*\n {lineNum++;} #.*\n {lineNum++;} #.*\n {lineNum++;} #.*\n {lineNum++;} #.*\n {lineNum++;} #.*\n {lineNum++;} #.*\n {lineNum++;} {matched_CISCOEXPORTER} {parenstack++;BEGIN(CISCOEXPORTER); return(CISCOEXPORTER);} {matched_OPTIONS} {parenstack++;BEGIN(OPTIONS); return(OPTIONS);} {matched_LOGFACILITY} {BEGIN(LOGFACILITY);} [a-zA-Z0-9]+ {BEGIN(OPTIONS);return(LOGFACILITY);} {matched_TCPCOLLECTPORT} {BEGIN(TCPCOLLECTPORT);} {matched_number} {BEGIN(OPTIONS);return(TCPCOLLECTPORT);} {matched_PKTBUFSIZE} {BEGIN(PKTBUFSIZE);} {matched_number} {BEGIN(OPTIONS);return(PKTBUFSIZE);} {matched_RAWFLOWSOCKFILE} {BEGIN(RAWFLOWSOCKFILE);} {matched_directory} {BEGIN(OPTIONS);return(RAWFLOWSOCKFILE);} {matched_TABLESOCKFILE} {BEGIN(TABLESOCKFILE);} {matched_directory} {BEGIN(OPTIONS);return(TABLESOCKFILE);} {matched_MAPDIR} {BEGIN(MAPDIR);} {matched_directory} {BEGIN(OPTIONS);return(MAPDIR);} {matched_FLOWDIR} {BEGIN(FLOWDIR);} {matched_directory} {BEGIN(OPTIONS);return(FLOWDIR);} {matched_FLOWFILELEN} {BEGIN(FLOWFILELEN);} {matched_number} {BEGIN(OPTIONS);return(FLOWFILELEN);} {matched_NUMFLOWFILES} {BEGIN(NUMFLOWFILES);} {matched_number} {BEGIN(OPTIONS);return(NUMFLOWFILES);} {matched_MINLOGMISSED} {BEGIN(MINLOGMISSED);} {matched_number} {BEGIN(OPTIONS);return(MINLOGMISSED);} [}] {parenstack--;BEGIN(INITIAL);} {matched_COLLECTOR} {parenstack++;BEGIN(COLLECTOR);} {matched_HOST} {BEGIN(COLLECTORHOST);} {matched_ip_address} {BEGIN(COLLECTOR);return(COLLECTORHOST);} {matched_ADDRESSES} {parenstack++;BEGIN(COLLECTORADDR);} {matched_ip_address} {return(COLLECTORADDR);} [}] {parenstack--;BEGIN(COLLECTOR);} {matched_AUTH} {BEGIN(COLLECTORAUTH);} [a-zA-Z]+ {BEGIN(COLLECTOR);return(COLLECTORAUTH);} [}] {parenstack--;BEGIN(INITIAL);} {matched_HOST} {BEGIN(IPADDRESS);} {matched_ip_address} {BEGIN(CISCOEXPORTER);return(IPADDRESS);} {matched_ADDRESSES} {parenstack++;BEGIN(IFADDRESSES);} {matched_ip_address} {return(IFADDRESSES);} [}] {parenstack--;BEGIN(CISCOEXPORTER);} {matched_CFDATAPORT} {BEGIN(CFDATAPORT);} {matched_number} {BEGIN(CISCOEXPORTER);return(CFDATAPORT);} {matched_SNMPCOMM} {BEGIN(SNMPCOMM);} [^\']+ {return(SNMPCOMM);} [\'] {BEGIN(CISCOEXPORTER);} {matched_LOCALAS} {BEGIN(LOCALAS);} {matched_number} {BEGIN(CISCOEXPORTER);return(LOCALAS);} {matched_COLLECT} {parenstack++;BEGIN(COLLECT);} port {return(COLLECT);} portmatrix {return(COLLECT);} protocol {return(COLLECT);} netmatrix {return(COLLECT);} asmatrix {return(COLLECT);} ifmatrix {return(COLLECT);} nexthop {return(COLLECT);} tos {return(COLLECT);} flows {return(COLLECT);} [}] {parenstack--;BEGIN(CISCOEXPORTER);} [}] {parenstack--;BEGIN(INITIAL);} {matched_CISCOEXPORTER} {yyperror("found CISCOEXPORTER while " "in CISCOEXPORTER stanza. " "Missing right paren?"); return(CONFIG_LEX_ERROR);} {matched_CISCOEXPORTER} {yyperror("found CISCOEXPORTER keyword " "in COLLECT stanza. " "missing right paren?"); return(CONFIG_LEX_ERROR);} {matched_OPTIONS} {yyperror("found OPTIONS keyword while " "in CISCOEXPORTER stanza."); return(CONFIG_LEX_ERROR);} {matched_COLLECTOR} {yyperror("found COLLECTOR while in " "CISCOEXPORTER stanza."); return(CONFIG_LEX_ERROR);} {matched_CISCOEXPORTER} {yyperror("found CISCOEXPORTER while " "in OPTIONS stanza."); return(CONFIG_LEX_ERROR);} {matched_COLLECTOR} {yyperror("found COLLECTOR while in " "OPTIONS stanza."); return(CONFIG_LEX_ERROR);} {matched_OPTIONS} {yyperror("found OPTIONS keyword while " "in OPTIONS stanza."); return(CONFIG_LEX_ERROR);} {matched_CISCOEXPORTER} {yyperror("found CISCOEXPORTER while in " "COLLECTOR stanza."); return(CONFIG_LEX_ERROR);} {matched_OPTIONS} {yyperror("found OPTIONS keyword while " "in COLLECTOR stanza."); return(CONFIG_LEX_ERROR);} {matched_COLLECTOR} {yyperror("found COLLECTOR while in " "COLLECTOR stanza."); return(CONFIG_LEX_ERROR);} [ \t,]* [{] {parenstack++;} [}] {parenstack--;} [\n] {lineNum++;} %% void yyerror(const char *msg) { syslog(LOG_ERR,"[E] syntax error in %s at line %d: %s %s", g_configFileName,lineNum,msg,lexer->YYText()); } #ifndef HAVE_STRCASECMP #define HAVE_STRCASECMP static char charmap[] = { '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177', '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207', '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217', '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227', '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237', '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247', '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257', '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267', '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277', '\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347', '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', '\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337', '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347', '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377', }; int strcasecmp(register char *s1, register char *s2) { register char *cm = charmap; while (cm[*s1] == cm[*s2++]) if (*s1++ == '\0') return(0); return(cm[*s1] - cm[*--s2]); } int strncasecmp(register char *s1, register char *s2, size_t n) { register char *cm = charmap; while (--n >= 0 && cm[*s1] == cm[*s2++]) if (*s1++ == '\0') return(0); return(n < 0 ? 0 : cm[*s1] - cm[*--s2]); } #endif /*---------------------------------------------------------------------------* * int SyslogFacility(const char *facilityname) * *...........................................................................* * * * * * * * * *---------------------------------------------------------------------------*/ int SyslogFacility(const char *facilityname) { if (!strcasecmp(facilityname,"daemon")) return(LOG_DAEMON); if (!strcasecmp(facilityname,"local0")) return(LOG_LOCAL0); if (!strcasecmp(facilityname,"local1")) return(LOG_LOCAL1); if (!strcasecmp(facilityname,"local2")) return(LOG_LOCAL2); if (!strcasecmp(facilityname,"local3")) return(LOG_LOCAL3); if (!strcasecmp(facilityname,"local4")) return(LOG_LOCAL4); if (!strcasecmp(facilityname,"local5")) return(LOG_LOCAL5); if (!strcasecmp(facilityname,"local6")) return(LOG_LOCAL6); if (!strcasecmp(facilityname,"local7")) return(LOG_LOCAL7); return(LOG_LOCAL6); } /*---------------------------------------------------------------------------* * uint16_t CollectionType(const char *colltype) * *...........................................................................* * * * * * * * * *---------------------------------------------------------------------------*/ uint16_t CollectionType(const char *colltype) { if (!strcasecmp(colltype,"protocol")) return(CflowdCisco::k_cflowdProtocolTableMask); if (!strcasecmp(colltype,"port")) return(CflowdCisco::k_cflowdPortTableMask); if (!strcasecmp(colltype,"netmatrix")) return(CflowdCisco::k_cflowdNetMatrixMask); if (!strcasecmp(colltype,"asmatrix")) return(CflowdCisco::k_cflowdAsMatrixMask); if (!strncasecmp(colltype,"flows",5)) return(CflowdCisco::k_cflowdRawFlowMask); if (!strcasecmp(colltype,"portmatrix")) return(CflowdCisco::k_cflowdPortMatrixMask); if (!strcasecmp(colltype,"ifmatrix")) return(CflowdCisco::k_cflowdInterfaceMatrixMask); if (!strcasecmp(colltype,"nexthop")) return(CflowdCisco::k_cflowdNextHopTableMask); if (!strcasecmp(colltype,"tos")) return(CflowdCisco::k_cflowdTosTableMask); return(0); } /*---------------------------------------------------------------------------* * int CollectorAuthType(const char *authtypestr) * *...........................................................................* * * * * * * * * *---------------------------------------------------------------------------*/ int CollectorAuthType(const char *authtypestr) { if (strcasecmp(authtypestr,"krb4") == 0) return(1); if (strcasecmp(authtypestr,"krb5") == 0) return(2); if (strcasecmp(authtypestr,"passwd") == 0) return(3); return(0); } /*-------------------------------------------------------------------------* * int LoadConfigFile(const char *configFileName, * * CflowdConfig & cflowdConfig) * *.........................................................................* * * *-------------------------------------------------------------------------*/ int LoadConfigFile(const char *configFileName, CflowdConfig & cflowdConfig) { int rc; uint16_t indexmask = 0; CflowdCisco *newCisco = (CflowdCisco *)NULL; CflowdCollector *newCollector = (CflowdCollector *)NULL; int foundport; uint32_t IPaddr; ifstream *configStream; CflowdFlowPortList::iterator flowPortIter; CflowdFlowPort newFlowPort; assert(configFileName != NULL); g_configFileName = configFileName; configStream = new ifstream(configFileName); if (! configStream || ! *configStream) { return(-1); } lexer = new yyFlexLexer(configStream,0); assert(lexer != (yyFlexLexer *)0); while ((rc = lexer->yylex()) != 0) { switch (rc) { case OPTIONS: break; case LOGFACILITY: cflowdConfig.LogFacility(SyslogFacility(lexer->YYText())); break; case TCPCOLLECTPORT: cflowdConfig.TcpCollectPort(atoi(lexer->YYText())); break; case PKTBUFSIZE: cflowdConfig.PacketBufSize(atoi(lexer->YYText())); break; case RAWFLOWSOCKFILE: cflowdConfig.RawFlowSockFile(lexer->YYText()); break; case TABLESOCKFILE: cflowdConfig.TableSockFile(lexer->YYText()); break; case MAPDIR: cflowdConfig.MapDirectory(lexer->YYText()); break; case FLOWDIR: cflowdConfig.FlowDirectory(lexer->YYText()); break; case FLOWFILELEN: cflowdConfig.FlowFileLength(atol(lexer->YYText())); break; case NUMFLOWFILES: cflowdConfig.NumFlowFiles(atoi(lexer->YYText())); break; case MINLOGMISSED: cflowdConfig.MinLogMissed(atoi(lexer->YYText())); break; case COLLECTORHOST: IPaddr = inet_addr(lexer->YYText()); if (IPaddr == 0xffffffff) { yyperror("bad IP address"); exit(CONFIG_LEX_ERROR); } else { newCollector = new CflowdCollector(); assert(newCollector != (CflowdCollector *)0); newCollector->IpAddress(IPaddr); cflowdConfig.CollectorMap()[IPaddr] = newCollector; } break; case COLLECTORADDR: IPaddr = inet_addr(lexer->YYText()); if (IPaddr == 0xffffffff) { yyperror("bad IP address"); exit(CONFIG_LEX_ERROR); } else { cflowdConfig.CollectorMap()[IPaddr] = newCollector; } break; case COLLECTORAUTH: newCollector->AuthType(CollectorAuthType(lexer->YYText())); break; case CISCOEXPORTER: newCisco = new CflowdCisco(); assert(newCisco != (CflowdCisco *)0); newCisco->MissedFlowsThreshold(cflowdConfig.MinLogMissed()); break; case IPADDRESS: IPaddr = inet_addr(lexer->YYText()); if (IPaddr == 0xffffffff) { yyperror("bad IP address"); exit(CONFIG_LEX_ERROR); } else { newCisco->IpAddress(IPaddr); cflowdConfig.CiscoMap()[IPaddr] = newCisco; } break; case IFADDRESSES: IPaddr = inet_addr(lexer->YYText()); if (IPaddr == 0xffffffff) { yyperror("bad IP address"); exit(CONFIG_LEX_ERROR); } else { cflowdConfig.CiscoMap()[IPaddr] = newCisco; } break; case CFDATAPORT: newCisco->FlowPort(atoi(lexer->YYText())); foundport = FALSE; for (flowPortIter = cflowdConfig.FlowPortList().begin(); flowPortIter != cflowdConfig.FlowPortList().end(); flowPortIter++) { if ((*flowPortIter).portnum == newCisco->FlowPort()) foundport = TRUE; } if (!foundport) { newFlowPort.portnum = newCisco->FlowPort(); cflowdConfig.FlowPortList().push_back(newFlowPort); } break; case SNMPCOMM: newCisco->SnmpCommunity(lexer->YYText()); break; case LOCALAS: newCisco->LocalAS((uint16_t)(atoi(lexer->YYText()))); break; case COLLECT: indexmask = CollectionType(lexer->YYText()); newCisco->TableIndex(newCisco->TableIndex() | indexmask); break; case CONFIG_LEX_ERROR: exit(CONFIG_LEX_ERROR); break; default: break; } } delete(lexer); delete(configStream); if (parenstack != 0) { if (parenstack > 0) yyperror("missing right paren?"); else yyperror("missing left paren?"); fprintf(stderr,"parenstack: %d\n",parenstack); } return(0); }