//=========================================================================== // @(#) $Name: cflowd-2-1-b1 $ // @(#) $Id: CflowdCisco.cc,v 1.31 2000/08/03 17:20:45 dwm Exp $ //=========================================================================== // CAIDA Copyright Notice // // By accessing this software, cflowd++, you are duly informed // of and agree to be bound by the conditions described below in this // notice: // // This software product, cflowd++, is developed by Daniel W. McRobb, and // copyrighted(C) 1998 by the University of California, San Diego // (UCSD), with all rights reserved. UCSD administers the CAIDA grant, // NCR-9711092, under which part of this code was developed. // // There is no charge for cflowd++ software. You can redistribute it // and/or modify it under the terms of the GNU General Public License, // v. 2 dated June 1991 which is incorporated by reference herein. // cflowd++ is distributed WITHOUT ANY WARRANTY, IMPLIED OR EXPRESS, OF // MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE or that the use // of it will not infringe on any third party's intellectual property // rights. // // You should have received a copy of the GNU GPL along with cflowd++. // Copies can also be obtained from: // // http://www.gnu.org/copyleft/gpl.html // // or by writing to: // // University of California, San Diego // // SDSC/CAIDA // 9500 Gilman Dr., MS-0505 // La Jolla, CA 92093 - 0505 USA // // Or contact: // // info@caida.org //=========================================================================== extern "C" { #include #include #include "caida_t.h" } #include #include #include "CflowdCisco.hh" static const string rcsid = "@(#) $Name: cflowd-2-1-b1 $ $Id: CflowdCisco.cc,v 1.31 2000/08/03 17:20:45 dwm Exp $"; static Oid g_ipAdEntIfIndexOid("1.3.6.1.2.1.4.20.1.2"); static Oid g_ifDescrOid("1.3.6.1.2.1.2.2.1.2"); //------------------------------------------------------------------------- // CflowdCisco::CflowdCisco() //......................................................................... // //------------------------------------------------------------------------- CflowdCisco::CflowdCisco() { this->_ipAddress = 0; this->_flowPort = 0; this->_localAS = 0; this->_snmpCommunity = string("public"); this->_lastCleared = time((time_t *)NULL); this->_lastUpdated = 0; this->_tableIndex = 0; this->_flowLogger = (CflowdRawFlowLogger *)NULL; this->_missedFlowsThreshold = 0; this->_haveInterfaceInfo = false; this->_lastSnmpQueryTime = 0; } //---------------------------------------------------------------------------- // CflowdCisco::CflowdCisco(const CflowdCisco & cflowdCisco) //............................................................................ // //---------------------------------------------------------------------------- CflowdCisco::CflowdCisco(const CflowdCisco & cflowdCisco) { this->_ipAddress = cflowdCisco.IpAddress(); this->_flowPort = cflowdCisco.FlowPort(); this->_localAS = cflowdCisco.LocalAS(); this->_snmpCommunity = cflowdCisco.SnmpCommunity(); this->_lastCleared = cflowdCisco.LastCleared(); this->_lastUpdated = cflowdCisco.LastUpdated(); this->_tableIndex = cflowdCisco.TableIndex(); this->CreateFlowLogger(cflowdCisco.FlowLogger()->FlowDirectory(), cflowdCisco.FlowLogger()->NumLogs(), cflowdCisco.FlowLogger()->LogSize()); this->_missedFlowsThreshold = cflowdCisco.MissedFlowsThreshold(); this->_haveInterfaceInfo = cflowdCisco._haveInterfaceInfo; this->_lastSnmpQueryTime = cflowdCisco._lastSnmpQueryTime; this->_flowEngines = cflowdCisco.FlowEngines(); this->_interfaces = cflowdCisco.Interfaces(); } //------------------------------------------------------------------------- // CflowdCisco::~CflowdCisco() //......................................................................... // //------------------------------------------------------------------------- CflowdCisco::~CflowdCisco() { if (this->_flowLogger != (CflowdRawFlowLogger *)NULL) { delete(this->_flowLogger); this->_flowLogger = (CflowdRawFlowLogger *)NULL; } if (this->FlowEngines().size() > 0) this->FlowEngines().erase(this->FlowEngines().begin(), this->FlowEngines().end()); if (this->Interfaces().size() > 0) this->Interfaces().erase(this->Interfaces().begin(), this->Interfaces().end()); } //------------------------------------------------------------------------- // ipv4addr_t CflowdCisco::IpAddress() const //......................................................................... // //------------------------------------------------------------------------- ipv4addr_t CflowdCisco::IpAddress() const { return(this->_ipAddress); } //------------------------------------------------------------------------- // ipv4addr_t CflowdCisco::IpAddress(ipv4addr_t ipAddr) //......................................................................... // //------------------------------------------------------------------------- ipv4addr_t CflowdCisco::IpAddress(ipv4addr_t ipAddr) { this->_ipAddress = ipAddr; return(this->_ipAddress); } //------------------------------------------------------------------------- // uint16_t CflowdCisco::FlowPort() const //......................................................................... // //------------------------------------------------------------------------- uint16_t CflowdCisco::FlowPort() const { return(this->_flowPort); } //------------------------------------------------------------------------- // uint16_t CflowdCisco::FlowPort(uint16_t flowPort) //......................................................................... // //------------------------------------------------------------------------- uint16_t CflowdCisco::FlowPort(uint16_t flowPort) { this->_flowPort = flowPort; return(this->_flowPort); } //---------------------------------------------------------------------------- // const string & CflowdCisco::SnmpCommunity() const //............................................................................ // //---------------------------------------------------------------------------- const string & CflowdCisco::SnmpCommunity() const { return(this->_snmpCommunity); } //---------------------------------------------------------------------------- // const string & CflowdCisco::SnmpCommunity(const string & snmpCommunity) //............................................................................ // //---------------------------------------------------------------------------- const string & CflowdCisco::SnmpCommunity(const string & snmpCommunity) { this->_snmpCommunity = snmpCommunity; return(this->_snmpCommunity); } //------------------------------------------------------------------------- // uint16_t CflowdCisco::LocalAS() const //......................................................................... // //------------------------------------------------------------------------- uint16_t CflowdCisco::LocalAS() const { return(this->_localAS); } //------------------------------------------------------------------------- // uint16_t CflowdCisco::LocalAS(uint16_t localAS) //......................................................................... // //------------------------------------------------------------------------- uint16_t CflowdCisco::LocalAS(uint16_t localAS) { this->_localAS = localAS; return(this->_localAS); } //------------------------------------------------------------------------- // uint16_t CflowdCisco::TableIndex() const //......................................................................... // //------------------------------------------------------------------------- uint16_t CflowdCisco::TableIndex() const { return(this->_tableIndex); } //------------------------------------------------------------------------- // uint16_t CflowdCisco::TableIndex(uint16_t tableIndex) //......................................................................... // //------------------------------------------------------------------------- uint16_t CflowdCisco::TableIndex(uint16_t tableIndex) { this->_tableIndex = tableIndex; return(this->_tableIndex); } //------------------------------------------------------------------------- // int CflowdCisco::AddFlow(const CflowdRawFlow & flow) //......................................................................... // //------------------------------------------------------------------------- int CflowdCisco::AddFlow(const CflowdRawFlow & flow) { uint16_t inputIfIndex; if (! (flow.Index() & CflowdRawFlow::k_inputIfIndexMask)) { inputIfIndex = 0; } else { inputIfIndex = flow.InputIfIndex(); } if (this->_tableIndex & k_cflowdProtocolTableMask) { this->Interfaces()[inputIfIndex].ProtocolTable().AddFlow(flow); } if (this->_tableIndex & k_cflowdPortTableMask) { cerr << "port table not yet implemented! {" << __FILE__ << ":" << __LINE__ << "}" << endl; } // update the net matrix if (this->_tableIndex & k_cflowdNetMatrixMask) { this->Interfaces()[inputIfIndex].NetMatrix().AddFlow(flow); } // update the AS matrix if (this->_tableIndex & k_cflowdAsMatrixMask) { this->Interfaces()[inputIfIndex].AsMatrix().AddFlow(flow); } if (this->_tableIndex & k_cflowdRawFlowMask) { this->_flowLogger->AddFlow(flow); } // update the port matrix if (this->_tableIndex & k_cflowdPortMatrixMask) { this->Interfaces()[inputIfIndex].PortMatrix().AddFlow(flow); } // update the interface matrix if (this->_tableIndex & k_cflowdInterfaceMatrixMask) { this->Interfaces()[inputIfIndex].InterfaceMatrix().AddFlow(flow); } // update the nextHop table if (this->_tableIndex & k_cflowdNextHopTableMask) { this->Interfaces()[inputIfIndex].NextHopTable().AddFlow(flow); } // update the TOS table if (this->_tableIndex & k_cflowdTosTableMask) { this->Interfaces()[inputIfIndex].TosTable().AddFlow(flow); } this->_lastUpdated = time((time_t *)NULL); return(0); } //------------------------------------------------------------------------- // istream & CflowdCisco::read(istream & is) //......................................................................... // //------------------------------------------------------------------------- istream & CflowdCisco::read(istream & is) { cerr << "CflowdCisco::read(istream & is) not implemented! {" << __FILE__ << ":" << __LINE__ << "}" << endl; return(is); } //------------------------------------------------------------------------- // int CflowdCisco::read(int fd) //......................................................................... // //------------------------------------------------------------------------- int CflowdCisco::read(int fd) { int rc; int bytesRead = 0; // read the Cisco's IP address rc = g_CfdArtsPrimitive.FdRead(fd,&this->_ipAddress, sizeof(this->_ipAddress)); if (rc < (int)sizeof(this->_ipAddress)) { syslog(LOG_ERR,"[E] FdRead(%d,%p,%d) failed: %m {%s:%d}", fd,&this->_ipAddress,sizeof(this->_ipAddress),__FILE__,__LINE__); return(-1); } bytesRead += rc; // read the start time of the data rc = g_CfdArtsPrimitive.ReadUint32(fd,this->_lastCleared, sizeof(this->_lastCleared)); if (rc < (int)sizeof(this->_lastCleared)) { syslog(LOG_ERR,"[E] ReadUint32(%d,%p,%d) failed: %m {%s:%d}", fd,&this->_lastCleared,sizeof(this->_lastCleared), __FILE__,__LINE__); return(-1); } bytesRead += rc; // read the end time of the data rc = g_CfdArtsPrimitive.ReadUint32(fd,this->_lastUpdated, sizeof(this->_lastUpdated)); if (rc < (int)sizeof(this->_lastUpdated)) { syslog(LOG_ERR,"[E] ReadUint32(%d,%p,%d) failed: %m {%s:%d}", fd,&this->_lastUpdated,sizeof(this->_lastUpdated), __FILE__,__LINE__); return(-1); } bytesRead += rc; // We need to read data for all interfaces. Currently the // table index is not interface-specific, but it's written // per-interface anyway. So we'll read the number of interfaces, // then the tabular data for each interface. uint16_t numInterfaces; rc = g_CfdArtsPrimitive.ReadUint16(fd,numInterfaces,sizeof(numInterfaces)); if (rc < (int)sizeof(numInterfaces)) { syslog(LOG_ERR,"[E] ReadUint16(%d,%p,%d) failed: %m {%s:%d}", fd,&numInterfaces,sizeof(numInterfaces),__FILE__,__LINE__); return(-1); } bytesRead += rc; uint16_t ifNum; uint16_t ifIndex; for (ifNum = 0; ifNum < numInterfaces; ifNum++) { CflowdCiscoFlowInterface ciscoInterface; // read the interface number rc = g_CfdArtsPrimitive.ReadUint16(fd,ifIndex,sizeof(ifIndex)); if (rc < (int)sizeof(ifIndex)) { syslog(LOG_ERR,"[E] ReadUint16(%d,%p,%d) failed: %m {%s:%d}", fd,&ifIndex,sizeof(ifIndex),__FILE__,__LINE__); return(-1); } bytesRead += rc; // read the ifDescr uint8_t ifDescrLength; rc = g_CfdArtsPrimitive.FdRead(fd,&ifDescrLength,1); if (rc < 1) { syslog(LOG_ERR,"[E] FdRead(%d,%p,1) failed: %m {%s:%d}", fd,&ifDescrLength,__FILE__,__LINE__); return(-1); } bytesRead += rc; if (ifDescrLength > 0) { char *buf = (char *)malloc(ifDescrLength + 1); if (! buf) { syslog(LOG_ERR,"[E] malloc(%d) failed: %m {%s:%d}", ifDescrLength + 1,__FILE__,__LINE__); return(-1); } memset(buf,0,ifDescrLength + 1); rc = g_CfdArtsPrimitive.FdRead(fd,buf,ifDescrLength); if (rc < ifDescrLength) { syslog(LOG_ERR,"[E] FdRead(%d,%p,%d) failed: %m {%s:%d}", fd,buf,ifDescrLength,__FILE__,__LINE__); free(buf); return(-1); } bytesRead += rc; ciscoInterface.IfDescr(buf); free(buf); } // read the IP address ipv4addr_t intfIpAddr; rc = g_CfdArtsPrimitive.ReadIpv4Network(fd,intfIpAddr,4); if (rc < 4) { syslog(LOG_ERR,"[E] ReadIpv4Network(%d,%p,4) failed: %m {%s:%d}", fd,&intfIpAddr,__FILE__,__LINE__); return(-1); } bytesRead += rc; ciscoInterface.IpAddr(intfIpAddr); // read the table index rc = g_CfdArtsPrimitive.ReadUint16(fd,this->_tableIndex, sizeof(this->_tableIndex)); if (rc < (int)sizeof(this->_tableIndex)) { syslog(LOG_ERR,"[E] ReadUint16(%d,%p,%d) failed: %m {%s:%d}", fd,&(this->_tableIndex),sizeof(this->_tableIndex)); return(-1); } // read the tabular data if (this->_tableIndex & k_cflowdProtocolTableMask) { if ((rc = ciscoInterface.ProtocolTable().read(fd)) < 0) { syslog(LOG_ERR,"[E] ciscoInterface.ProtocolTable().read(%d)" " failed: %m {%s:%d}",fd,__FILE__,__LINE__); return(-1); } bytesRead += rc; } if (this->_tableIndex & k_cflowdNetMatrixMask) { if ((rc = ciscoInterface.NetMatrix().read(fd)) < 0) { syslog(LOG_ERR,"[E] ciscoInterface.NetMatrix().read(%d)" " failed: %m {%s:%d}",fd,__FILE__,__LINE__); return(-1); } bytesRead += rc; } if (this->_tableIndex & k_cflowdAsMatrixMask) { if ((rc = ciscoInterface.AsMatrix().read(fd)) < 0) { syslog(LOG_ERR,"[E] ciscoInterface.AsMatrix().read(%d)" " failed: %m {%s:%d}",fd,__FILE__,__LINE__); return(-1); } bytesRead += rc; } if (this->_tableIndex & k_cflowdPortMatrixMask) { if ((rc = ciscoInterface.PortMatrix().read(fd)) < 0) { syslog(LOG_ERR,"[E] ciscoInterface.PortMatrix().read(%d)" " failed: %m {%s:%d}",fd,__FILE__,__LINE__); return(-1); } bytesRead += rc; } if (this->_tableIndex & k_cflowdInterfaceMatrixMask) { if ((rc = ciscoInterface.InterfaceMatrix().read(fd)) < 0) { syslog(LOG_ERR,"[E] ciscoInterface.InterfaceMatrix().read(%d)" " failed: %m {%s:%d}",fd,__FILE__,__LINE__); return(-1); } bytesRead += rc; } if (this->_tableIndex & k_cflowdNextHopTableMask) { if ((rc = ciscoInterface.NextHopTable().read(fd)) < 0) { syslog(LOG_ERR,"[E] ciscoInterface.NextHopTable().read(%d)" " failed: %m {%s:%d}",fd,__FILE__,__LINE__); return(-1); } bytesRead += rc; } if (this->_tableIndex & k_cflowdTosTableMask) { if ((rc = ciscoInterface.TosTable().read(fd)) < 0) { syslog(LOG_ERR,"[E] ciscoInterface.TosTable().read(%d)" " failed: %m {%s:%d}",fd,__FILE__,__LINE__); return(-1); } bytesRead += rc; } this->Interfaces()[ifIndex] = ciscoInterface; } return(bytesRead); } //------------------------------------------------------------------------- // ostream & CflowdCisco::write(ostream & os) const //......................................................................... // //------------------------------------------------------------------------- ostream & CflowdCisco::write(ostream & os) const { cerr << "CflowdCisco::write(istream & is) not implemented! {" << __FILE__ << ":" << __LINE__ << "}" << endl; return(os); } //------------------------------------------------------------------------- // int CflowdCisco::write(int fd) const //......................................................................... // //------------------------------------------------------------------------- int CflowdCisco::write(int fd) const { int rc; int bytesWritten = 0; // write the Cisco's IP address rc = g_CfdArtsPrimitive.FdWrite(fd,&this->_ipAddress, sizeof(this->_ipAddress)); if (rc < (int)sizeof(this->_ipAddress)) { syslog(LOG_ERR,"[E] FdWrite(%d,%p,%d) failed: %m {%s:%d}", fd,&this->_ipAddress,sizeof(this->_ipAddress), __FILE__,__LINE__); return(-1); } bytesWritten += rc; // write the time we last cleared (start time of the data) rc = g_CfdArtsPrimitive.WriteUint32(fd,this->_lastCleared, sizeof(this->_lastCleared)); if (rc < (int)sizeof(this->_lastCleared)) { syslog(LOG_ERR,"[E] WriteUint32(%d,%p,%d) failed: %m {%s:%d}", fd,&this->_lastCleared,sizeof(this->_lastCleared), __FILE__,__LINE__); return(-1); } bytesWritten += rc; // write the time we last updated (end time of the data) rc = g_CfdArtsPrimitive.WriteUint32(fd,this->_lastUpdated, sizeof(this->_lastUpdated)); if (rc < (int)sizeof(this->_lastUpdated)) { syslog(LOG_ERR,"[E] write(%d,%p,%d) failed: %m {%s:%d}", fd,&this->_lastUpdated,sizeof(this->_lastUpdated), __FILE__,__LINE__); return(-1); } bytesWritten += rc; // We need to write data for all interfaces. Currently our // table index is not interface-specific, but we'll write it // per-interface anyway. So we'll write the number of interfaces, // then the tabular data for each interface. uint16_t numInterfaces; numInterfaces = this->Interfaces().size(); rc = g_CfdArtsPrimitive.WriteUint16(fd,numInterfaces,sizeof(numInterfaces)); if (rc < (int)sizeof(numInterfaces)) return(-1); bytesWritten += rc; CflowdCiscoFlowInterfaceMap::iterator intfIter; uint16_t ifIndex; for (intfIter = this->Interfaces().begin(); intfIter != this->Interfaces().end(); intfIter++) { // write the interface number ifIndex = (*intfIter).first; rc = g_CfdArtsPrimitive.WriteUint16(fd,ifIndex,sizeof(ifIndex)); if (rc < (int)sizeof(ifIndex)) { syslog(LOG_ERR,"[E] WriteUint16(%d,%p,%d) failed: %m {%s:%d}", fd,&ifIndex,sizeof(ifIndex),__FILE__,__LINE__); return(-1); } bytesWritten += rc; // write the ifDescr uint8_t ifDescrLength = (*intfIter).second.IfDescr().length(); rc = g_CfdArtsPrimitive.FdWrite(fd,&ifDescrLength,1); if (rc < (int)1) { syslog(LOG_ERR,"[E] FdWrite(%d,%p,1) failed: %m {%s:%d}", fd,&ifDescrLength,__FILE__,__LINE__); return(-1); } bytesWritten += rc; if (ifDescrLength > 0) { rc = g_CfdArtsPrimitive.FdWrite(fd,(*intfIter).second.IfDescr().c_str(), ifDescrLength); if (rc < ifDescrLength) { syslog(LOG_ERR,"[E] FdWrite(%d,%p,%d) failed: %m {%s:%d}", fd,(*intfIter).second.IfDescr().c_str(),ifDescrLength, __FILE__,__LINE__); return(-1); } bytesWritten += rc; } // write the IP address rc = g_CfdArtsPrimitive.WriteIpv4Network(fd,(*intfIter).second.IpAddr(),4); if (rc < 4) { syslog(LOG_ERR,"[E] WriteIpv4Network(%d,%x,4) failed: %m {%s:%d}", fd,(*intfIter).second.IpAddr(),__FILE__,__LINE__); return(-1); } bytesWritten += rc; // write the table index rc = g_CfdArtsPrimitive.WriteUint16(fd,this->_tableIndex, sizeof(this->_tableIndex)); if (rc < (int)sizeof(this->_tableIndex)) { syslog(LOG_ERR,"[E] WriteUint16(%d,%p,%d) failed: %m {%s:%d}", fd,&this->_tableIndex,sizeof(this->_tableIndex), __FILE__,__LINE__); return(-1); } bytesWritten += rc; // write the tabular data if (this->_tableIndex & k_cflowdProtocolTableMask) { if ((rc = (*intfIter).second.ProtocolTable().write(fd)) < 0) { syslog(LOG_ERR,"[E] ProtocolTable().write(%d) failed {%s:%d}", fd,__FILE__,__LINE__); return(-1); } bytesWritten += rc; } if (this->_tableIndex & k_cflowdNetMatrixMask) { if ((rc = (*intfIter).second.NetMatrix().write(fd)) < 0) { syslog(LOG_ERR,"[E] NetMatrix().write(%d) failed {%s:%d}", fd,__FILE__,__LINE__); return(-1); } bytesWritten += rc; } if (this->_tableIndex & k_cflowdAsMatrixMask) { if ((rc = (*intfIter).second.AsMatrix().write(fd)) < 0) { syslog(LOG_ERR,"[E] AsMatrix().write(%d) failed {%s:%d}", fd,__FILE__,__LINE__); return(-1); } bytesWritten += rc; } if (this->_tableIndex & k_cflowdPortMatrixMask) { if ((rc = (*intfIter).second.PortMatrix().write(fd)) < 0) { syslog(LOG_ERR,"[E] PortMatrix().write(%d) failed {%s:%d}", fd,__FILE__,__LINE__); return(-1); } bytesWritten += rc; } if (this->_tableIndex & k_cflowdInterfaceMatrixMask) { if ((rc = (*intfIter).second.InterfaceMatrix().write(fd)) < 0) { syslog(LOG_ERR,"[E] InterfaceMatrix().write(%d) failed {%s:%d}", fd,__FILE__,__LINE__); return(-1); } bytesWritten += rc; } if (this->_tableIndex & k_cflowdNextHopTableMask) { if ((rc = (*intfIter).second.NextHopTable().write(fd)) < 0) { syslog(LOG_ERR,"[E] NextHopTable().write(%d) failed {%s:%d}", fd,__FILE__,__LINE__); return(-1); } bytesWritten += rc; } if (this->_tableIndex & k_cflowdTosTableMask) { if ((rc = (*intfIter).second.TosTable().write(fd)) < 0) { syslog(LOG_ERR,"[E] TosTable().write(%d) failed {%s:%d}", fd,__FILE__,__LINE__); return(-1); } bytesWritten += rc; } } return(bytesWritten); } //------------------------------------------------------------------------- // int CflowdCisco::ClearTableData() //......................................................................... // //------------------------------------------------------------------------- int CflowdCisco::ClearTableData() { this->Interfaces().erase(this->Interfaces().begin(), this->Interfaces().end()); this->_lastCleared = this->_lastUpdated; CflowdCiscoFlowEngineMap::iterator engineIter; for (engineIter = this->FlowEngines().begin(); engineIter != this->FlowEngines().end(); engineIter++) { for (uint8_t aggMethod = 0; aggMethod <= k_CiscoV8FlowExportMaxAggType; aggMethod++) { if ((*engineIter).second.MissedFlows((char)aggMethod) > this->_missedFlowsThreshold) { struct in_addr addrIn; addrIn.s_addr = this->IpAddress(); uint64_t totalFlows = ((*engineIter).second.MissedFlows((char)aggMethod) + (*engineIter).second.FlowsReceived((char)aggMethod)); syslog(LOG_INFO, "[I] missed %u of %u flows from %s" " engine %d agg_method %d (%g%% loss)", (*engineIter).second.MissedFlows((char)aggMethod), totalFlows, inet_ntoa(addrIn), (*engineIter).first, aggMethod, ((*engineIter).second.MissedFlows((char)(aggMethod) * 100.0) / totalFlows)); } (*engineIter).second.MissedFlows(0,aggMethod); (*engineIter).second.FlowsReceived(0,aggMethod); } } return(0); } //------------------------------------------------------------------------- // int CflowdCisco::CreateFlowLogger(const string & flowDirectory, // int numLogs, int logSize) //......................................................................... // //------------------------------------------------------------------------- int CflowdCisco::CreateFlowLogger(const string & flowDirectory, int numLogs, int logSize) { struct in_addr addrIn; ostrstream flowFilePrefix; addrIn.s_addr = this->_ipAddress; flowFilePrefix << inet_ntoa(addrIn) << ".flows" << ends; this->_flowLogger = new CflowdRawFlowLogger(flowDirectory, flowFilePrefix.str(), numLogs,logSize); flowFilePrefix.freeze(0); if (this->_flowLogger == (CflowdRawFlowLogger *)0) { syslog(LOG_ERR,"[E] unable to create raw flow logger for %s {%s:%d}", inet_ntoa(addrIn),__FILE__,__LINE__); this->_tableIndex &= (~CflowdCisco::k_cflowdRawFlowMask); return(-1); } if (this->_flowLogger->MapAddr() == (caddr_t)(-1)) { // failed to create valid flow logger. Log, delete the flow // logger, and disable raw flow logging. syslog(LOG_ERR,"[E] unable to create raw flow logger for %s {%s:%d}", inet_ntoa(addrIn),__FILE__,__LINE__); delete(this->_flowLogger); this->_tableIndex &= (~CflowdCisco::k_cflowdRawFlowMask); syslog(LOG_WARNING,"[W] disabled raw flow collection for %s {%s:%d}", inet_ntoa(addrIn),__FILE__,__LINE__); return(-1); } return(0); } //---------------------------------------------------------------------------- // void CflowdCisco::GetInterfaceDescriptions(Snmp & session, // CTarget & target) //............................................................................ // //---------------------------------------------------------------------------- void CflowdCisco::GetInterfaceDescriptions(Snmp & session, CTarget & target) { Vb varBinding; Pdu pdu; int status; uint16_t ifIndex; Oid receivedOid; CflowdCiscoFlowInterfaceMap::iterator intfMapIter; varBinding.set_oid(g_ifDescrOid); pdu += varBinding; while ((status = session.get_next(pdu,target)) == SNMP_CLASS_SUCCESS) { for (int i = 0; i < pdu.get_vb_count(); i++) { pdu.get_vb(varBinding,i); varBinding.get_oid(receivedOid); if (g_ifDescrOid.nCompare(g_ifDescrOid.len(),receivedOid) == 0) { ifIndex = receivedOid[receivedOid.len() - 1]; intfMapIter = this->_interfaces.find(ifIndex); if (intfMapIter != this->_interfaces.end()) { intfMapIter->second.IfDescr((const char *)(varBinding.get_printable_value())); } } else { pdu.delete_vb(i); } } if (pdu.get_vb_count() < 1) break; } return; } //---------------------------------------------------------------------------- // ipv4addr_t IpAdEntIfIndexOidIpAddr(Oid & oid) //............................................................................ // //---------------------------------------------------------------------------- ipv4addr_t IpAdEntIfIndexOidIpAddr(Oid & oid) { ipv4addr_t ipAddr = 0; for (int i = oid.len() - 4; i < oid.len(); i++) { ipAddr |= ((ipv4addr_t)(oid[i]) << ((oid.len() - (i + 1)) * 8)); } ipAddr = htonl(ipAddr); return(ipAddr); } //---------------------------------------------------------------------------- // void CflowdCisco::GetInterfaceAddresses(Snmp & session, // CTarget & target) //............................................................................ // //---------------------------------------------------------------------------- void CflowdCisco::GetInterfaceAddresses(Snmp & session, CTarget & target) { Vb varBinding; Pdu pdu; int status; Oid receivedOid; int interfaceIndex; CflowdCiscoFlowInterfaceMap::iterator intfMapIter; varBinding.set_oid(g_ipAdEntIfIndexOid); pdu += varBinding; while ((status = session.get_next(pdu,target)) == SNMP_CLASS_SUCCESS) { for (int i = 0; i < pdu.get_vb_count(); i++) { pdu.get_vb(varBinding,i); varBinding.get_oid(receivedOid); if (g_ipAdEntIfIndexOid.nCompare(g_ipAdEntIfIndexOid.len(), receivedOid) == 0) { int ifIndex; varBinding.get_value(interfaceIndex); ifIndex = interfaceIndex; intfMapIter = this->_interfaces.find(ifIndex); if (intfMapIter != this->_interfaces.end()) { intfMapIter->second.IpAddr(IpAdEntIfIndexOidIpAddr(receivedOid)); } } else { pdu.delete_vb(i); } } if (pdu.get_vb_count() < 1) break; } return; } //---------------------------------------------------------------------------- // int CflowdCisco::GetInterfaceInfo() //............................................................................ // //---------------------------------------------------------------------------- int CflowdCisco::GetInterfaceInfo() { struct in_addr inAddr; inAddr.s_addr = this->_ipAddress; GenAddress snmpAddress(inet_ntoa(inAddr)); CTarget snmpTarget(snmpAddress,this->_snmpCommunity.c_str(), this->_snmpCommunity.c_str()); snmpTarget.set_timeout(200); snmpTarget.set_retry(2); if (! snmpTarget.valid()) { syslog(LOG_ERR,"[E] invalid SNMP target {%s:%d}",__FILE__,__LINE__); return(-1); } int sessionStatus; Snmp snmpSession(sessionStatus); if (sessionStatus) { syslog(LOG_ERR,"[E] failed to create SNMP session {%s:%d}", __FILE__,__LINE__); return(-1); } GetInterfaceDescriptions(snmpSession,snmpTarget); GetInterfaceAddresses(snmpSession,snmpTarget); this->_haveInterfaceInfo = true; this->_lastSnmpQueryTime = time((time_t *)0); return(0); } //---------------------------------------------------------------------------- // bool CflowdCisco::HaveRecentInterfaceInfo() const //............................................................................ // //---------------------------------------------------------------------------- bool CflowdCisco::HaveRecentInterfaceInfo() const { if (this->_haveInterfaceInfo && (this->_lastSnmpQueryTime > (time((time_t *)0) - (30 * 60)))) return(true); return(false); } //---------------------------------------------------------------------------- // bool CflowdCisco::HaveRecentInterfaceInfo(bool value) //............................................................................ // //---------------------------------------------------------------------------- bool CflowdCisco::HaveRecentInterfaceInfo(bool value) { if (! value) this->_lastSnmpQueryTime = 0; this->_haveInterfaceInfo = value; return(value); } const uint16_t CflowdCisco::k_cflowdProtocolTableMask = 0x0001; const uint16_t CflowdCisco::k_cflowdPortTableMask = 0x0002; const uint16_t CflowdCisco::k_cflowdNetMatrixMask = 0x0004; const uint16_t CflowdCisco::k_cflowdAsMatrixMask = 0x0008; const uint16_t CflowdCisco::k_cflowdRawFlowMask = 0x0010; const uint16_t CflowdCisco::k_cflowdPortMatrixMask = 0x0020; const uint16_t CflowdCisco::k_cflowdInterfaceMatrixMask = 0x0040; const uint16_t CflowdCisco::k_cflowdNextHopTableMask = 0x0080; const uint16_t CflowdCisco::k_cflowdTosTableMask = 0x0100;