%{ extern "C" { #include #include #include } #include #include "CflowdRawFlow.hh" #include "flowfilt.tab.h" extern int flowfiltlval; extern int flowfiltparse (void); static const string rcsid = "@(#) $Name: cflowd-2-1-b1 $ $Id: flowfilt.lex,v 1.5 1999/05/26 11:01:09 dwm Exp $"; static const CflowdRawFlow *g_cflowdRawFlow; static const char *g_expression; int flowfiltparseval; static int charnum = 0; static struct tm g_Tm; void flowfilterror(const char *msg); %} %option noyywrap %x INERROR %% all {charnum += strlen(yytext); flowfiltlval = 1; return ALL; /* matches all flows */} router {charnum += strlen(yytext); flowfiltlval = (g_cflowdRawFlow->Index() & CflowdRawFlow::k_routerMask) ? g_cflowdRawFlow->Router() : 0; return FIELDNAME;} srcaddr {charnum += strlen(yytext); flowfiltlval = (g_cflowdRawFlow->Index() & CflowdRawFlow::k_srcIpAddrMask) ? g_cflowdRawFlow->SrcIpAddr() : 0; return FIELDNAME;} dstaddr {charnum += strlen(yytext); flowfiltlval = (g_cflowdRawFlow->Index() & CflowdRawFlow::k_dstIpAddrMask) ? g_cflowdRawFlow->DstIpAddr() : 0; return FIELDNAME;} nexthop {charnum += strlen(yytext); flowfiltlval = (g_cflowdRawFlow->Index() & CflowdRawFlow::k_ipNextHopMask) ? g_cflowdRawFlow->IpNextHop() : 0; return FIELDNAME;} srcport {charnum += strlen(yytext); flowfiltlval = (g_cflowdRawFlow->Index() & CflowdRawFlow::k_srcPortMask) ? g_cflowdRawFlow->SrcPort() : 0; return FIELDNAME;} dstport {charnum += strlen(yytext); flowfiltlval = (g_cflowdRawFlow->Index() & CflowdRawFlow::k_dstPortMask) ? g_cflowdRawFlow->DstPort() : 0; return FIELDNAME;} srcas {charnum += strlen(yytext); flowfiltlval = (g_cflowdRawFlow->Index() & CflowdRawFlow::k_srcAsMask) ? g_cflowdRawFlow->SrcAs() : 0; return FIELDNAME;} dstas {charnum += strlen(yytext); flowfiltlval = (g_cflowdRawFlow->Index() & CflowdRawFlow::k_dstAsMask) ? g_cflowdRawFlow->DstAs() : 0; return FIELDNAME;} srcmask {charnum += strlen(yytext); flowfiltlval = (g_cflowdRawFlow->Index() & CflowdRawFlow::k_srcMaskLenMask) ? g_cflowdRawFlow->SrcMaskLen() : 0; return FIELDNAME;} dstmask {charnum += strlen(yytext); flowfiltlval = (g_cflowdRawFlow->Index() & CflowdRawFlow::k_dstMaskLenMask) ? g_cflowdRawFlow->DstMaskLen() : 0; return FIELDNAME;} tcpflags {charnum += strlen(yytext); flowfiltlval = (g_cflowdRawFlow->Index() & CflowdRawFlow::k_dstMaskLenMask) ? g_cflowdRawFlow->DstMaskLen() : 0; return FIELDNAME;} protocol {charnum += strlen(yytext); flowfiltlval = (g_cflowdRawFlow->Index() & CflowdRawFlow::k_protocolMask) ? g_cflowdRawFlow->Protocol() : 0; return FIELDNAME;} tos {charnum += strlen(yytext); flowfiltlval = (g_cflowdRawFlow->Index() & CflowdRawFlow::k_tosMask) ? g_cflowdRawFlow->Tos() : 0; return FIELDNAME;} inputif {charnum += strlen(yytext); flowfiltlval = (g_cflowdRawFlow->Index() & CflowdRawFlow::k_inputIfIndexMask) ? g_cflowdRawFlow->InputIfIndex() : 0; return FIELDNAME;} outputif {charnum += strlen(yytext); flowfiltlval = (g_cflowdRawFlow->Index() & CflowdRawFlow::k_outputIfIndexMask) ? g_cflowdRawFlow->OutputIfIndex() : 0; return FIELDNAME;} pkts {charnum += strlen(yytext); flowfiltlval = (g_cflowdRawFlow->Index() & CflowdRawFlow::k_pktsMask) ? g_cflowdRawFlow->Pkts() : 0; return FIELDNAME;} bytes {charnum += strlen(yytext); flowfiltlval = (g_cflowdRawFlow->Index() & CflowdRawFlow::k_bytesMask) ? g_cflowdRawFlow->Bytes() : 0; return FIELDNAME;} starttime {charnum += strlen(yytext); flowfiltlval = (g_cflowdRawFlow->Index() & CflowdRawFlow::k_startTimeMask) ? g_cflowdRawFlow->StartTime() : 0; return FIELDNAME;} endtime {charnum += strlen(yytext); flowfiltlval = (g_cflowdRawFlow->Index() & CflowdRawFlow::k_endTimeMask) ? g_cflowdRawFlow->EndTime() : 0; return FIELDNAME;} enginetype {charnum += strlen(yytext); flowfiltlval = (g_cflowdRawFlow->Index() & CflowdRawFlow::k_engineTypeMask) ? g_cflowdRawFlow->EngineType() : 0; return FIELDNAME;} engineid {charnum += strlen(yytext); flowfiltlval = (g_cflowdRawFlow->Index() & CflowdRawFlow::k_engineIdMask) ? g_cflowdRawFlow->EngineId() : 0; return FIELDNAME;} now {charnum += strlen(yytext); flowfiltlval = time((time_t *)0); return INTEGER;} [0-9]+[.][0-9]+[.][0-9]+[.][0-9]+ {charnum += strlen(yytext); flowfiltlval = inet_addr(yytext); return INTEGER;} /* Match a date and time of the form 'MM/DD/YY hh:mm:ss', convert to * * an integer of seconds since UNIX epoch. */ [0-9]+[/][0-9]+[/][0-9]+[ ]+[0-9]+[\:][0-9][0-9][\:][0-9][0-9] { charnum += strlen(yytext); memset(&g_Tm,0,sizeof(g_Tm)); if (sscanf(yytext, "%d/%d/%d %d:%02d:%02d",&g_Tm.tm_mon,&g_Tm.tm_mday, &g_Tm.tm_year,&g_Tm.tm_hour,&g_Tm.tm_min,&g_Tm.tm_sec) != 6) { flowfilterror("bad date format"); exit(1); } else { g_Tm.tm_mon --; g_Tm.tm_isdst = -1; if (g_Tm.tm_year >= 1900) g_Tm.tm_year -= 1900; flowfiltlval = mktime(&g_Tm); return INTEGER; } } [0-9]+ {charnum += strlen(yytext); flowfiltlval = atoi(yytext); return INTEGER;} 0x[0-9a-fA-F]+ {charnum += strlen(yytext); flowfiltlval = strtoul(yytext,(char **)NULL,16); return INTEGER;} [ \t]+ {charnum += strlen(yytext); /* skip whitespace */ } [!][=] {charnum += 2; return(NE); /* not equal */ } [=][=] {charnum += 2; return(EQ); /* equal */ } [<] {charnum++; return(LT); /* less than */ } [>] {charnum++; return(GT); /* greater than */ } [<][=] {charnum += 2; return(LE); /* less than or equal */ } [>][=] {charnum += 2; return(GE); /* greater than or equal */ } [=] {charnum++; return(EQ); /* equal */ } [\&][\&] {charnum += 2; return(AND); /* and */ } [\&] {charnum++; return(BITAND); /* bitwise and */ } [\|][\|] {charnum += 2; return(LOGOR); /* logical or */ } [\|] {charnum++; return(BITOR); /* bitwise or */ } [\(] {charnum++; return(LPAREN); /* left paren */ } [\)] {charnum++; return(RPAREN); /* right paren */ } [/] {charnum++; return(DIV); /* divide */ } [*] {charnum++; return(MUL); /* multiply */ } [+] {charnum++; return(ADD); /* add */ } [-] {charnum++; return(SUB); /* subtract */ } [%] {charnum++; return(MOD); /* modulo */ } [~] {charnum++; return(BITNOT); /* bitwise not */ } [!] {charnum++; return(LOGNOT); /* logical not */ } \n {charnum++; return(0);} <> {return(0);} . {charnum++; BEGIN(INERROR); yyless(0);} [a-zA-Z]+ {return(1);} [^a-zA-Z]* {return(1);} %% //------------------------------------------------------------------------- // void flowfilterror(const char *msg) //......................................................................... // //------------------------------------------------------------------------- void flowfilterror(const char *msg) { char fmtString[10]; fprintf(stderr,"[E] %s at '%s':\n",msg,yytext); fprintf(stderr,"%s\n",g_expression); sprintf(fmtString,"%%%ds\n",charnum); fprintf(stderr,fmtString,"^"); exit(1); return; } //------------------------------------------------------------------------- // bool FlowMatches(const char *expression, const CflowdRawFlow *rawFlow) //......................................................................... // //------------------------------------------------------------------------- bool FlowMatches(const char *expression, const CflowdRawFlow *rawFlow) { YY_BUFFER_STATE bufferState; int rc; g_cflowdRawFlow = rawFlow; g_expression = expression; bufferState = yy_scan_string(expression); rc = flowfiltparse(); if (rc) { yy_delete_buffer(bufferState); return(false); } if (flowfiltparseval) { yy_delete_buffer(bufferState); return(true); } yy_delete_buffer(bufferState); return(false); }