//=========================================================================== // @(#) $Name: cflowd-2-1-b1 $ // @(#) $Id: cfdnets.cc,v 1.12 1999/05/25 10:26:59 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 #include #include #include #include #include #include } #include #include #include #include "CflowdConfig.hh" #include "CflowdConfigLex.hh" #include "CflowdTableRequest.hh" #include "CflowdVersion.hh" #ifndef INADDR_NONE #define INADDR_NONE 0xffffffff #endif extern char *tzname[2]; static const string rcsid = "@(#) $Name: cflowd-2-1-b1 $ $Id: cfdnets.cc,v 1.12 1999/05/25 10:26:59 dwm Exp $"; static CflowdVersion g_cflowdVersion = CflowdVersion(rcsid); CflowdConfig g_cflowdConfig; static bool g_srcNetSpecified = false; static bool g_dstNetSpecified = false; static ipv4addr_t g_srcNet = 0; static uint8_t g_srcMaskLen = 0; static ipv4addr_t g_dstNet = 0; static uint8_t g_dstMaskLen = 0; //---------------------------------------------------------------------------- // static bool // NetEntryMatches(const CflowdNetMatrixKey & netmKey) //............................................................................ // //---------------------------------------------------------------------------- static bool NetEntryMatches(const CflowdNetMatrixKey & netmKey) { ipv4addr_t netmask, netaddr; struct in_addr addrIn; netmask = htonl((0xffffffff) << (32 - g_srcMaskLen)); if (g_srcNetSpecified) { if ((netmKey.Src() & netmask) != g_srcNet) { return(false); } if (g_srcMaskLen > netmKey.SrcMaskLen()) { return(false); } } netmask = htonl((0xffffffff) << (32 - g_dstMaskLen)); if (g_dstNetSpecified) { if ((netmKey.Dst() & netmask) != g_dstNet) { return(false); } if (g_dstMaskLen > netmKey.DstMaskLen()) { return(false); } } return(true); } //------------------------------------------------------------------------- // void Usage(const char *argv0) //......................................................................... // //------------------------------------------------------------------------- void Usage(const char *argv0) { cerr << "usage: " << argv0 << " [-v] [-s srcNet/masklen] [-d dstNet/masklen]" << " [-t] [-c configfile] routerIpAddr [ifIndex]" << endl; return; } //------------------------------------------------------------------------- // int main(int argc, char *argv[]) //......................................................................... // //------------------------------------------------------------------------- int main(int argc, char *argv[]) { struct sockaddr_un servSockAddr; int servSockAddrLen; int sockFd; extern int optind; extern char *optarg; int optChar; bool printRates = true; char *configFile = NULL; ipv4addr_t routerIpAddr; CflowdTableRequest tableRequest; CflowdCisco cflowdCisco; struct in_addr srcNetAddr, dstNetAddr; uint16_t ifIndexMatch = (uint16_t)(-1); CflowdCiscoFlowInterfaceMap::const_iterator intfIter; char *ipAddrString; char *maskLenString; if (argc < 2) { Usage(argv[0]); exit(1); } while ((optChar = getopt(argc,argv,"c:d:s:tv")) != EOF) { switch (optChar) { case 'c': configFile = (char *)strdup(optarg); break; case 'd': g_dstNetSpecified = true; ipAddrString = strtok(optarg,"/"); if (! ipAddrString) { Usage(argv[0]); exit(1); } g_dstNet = inet_addr(ipAddrString); if (g_dstNet == INADDR_NONE) { cerr << "'" << ipAddrString << "'" << " is an illegal destination network address." << endl; Usage(argv[0]); exit(1); } maskLenString = strtok(NULL," "); if (! maskLenString) { Usage(argv[0]); exit(1); } g_dstMaskLen = (uint8_t)atoi(maskLenString); if (g_dstMaskLen > 32 || g_dstMaskLen == 0) { cerr << maskLenString << " is an illegal destination network mask length." << endl; Usage(argv[0]); exit(1); } break; case 's': g_srcNetSpecified = true; ipAddrString = strtok(optarg,"/"); if (! ipAddrString) { Usage(argv[0]); exit(1); } g_srcNet = inet_addr(ipAddrString); if (g_srcNet == INADDR_NONE) { cerr << "'" << ipAddrString << "'" << " is an illegal source network address." << endl; Usage(argv[0]); exit(1); } maskLenString = strtok(NULL," "); if (! maskLenString) { Usage(argv[0]); exit(1); } g_srcMaskLen = (uint8_t)atoi(maskLenString); if (g_srcMaskLen > 32 || g_srcMaskLen == 0) { cerr << maskLenString << " is an illegal source network mask length." << endl; Usage(argv[0]); exit(1); } break; case 't': printRates = false; break; case 'v': cerr << g_cflowdVersion.Name() << " " << g_cflowdVersion.Id() << endl; exit(0); break; case '?': default: Usage(argv[0]); exit(1); break; } } if (optind > (argc - 1)) { Usage(argv[0]); exit(1); } tableRequest.RouterIpAddr(inet_addr(argv[optind])); tableRequest.TableIndex(CflowdCisco::k_cflowdNetMatrixMask); if ((argc - 1) > optind) { optind++; ifIndexMatch = atoi(argv[optind]); } if (!configFile) { configFile = (char *)strdup(CflowdConfig::k_defaultCflowdConfigFile.c_str()); } if (LoadConfigFile(configFile,g_cflowdConfig) < 0) { cerr << "failed to load config file '" << configFile << "': " << strerror(errno) << " {" << __FILE__ << ":" << __LINE__ << "}" << endl; Usage(argv[0]); exit(1); } openlog("cfdnets",LOG_PID,g_cflowdConfig.LogFacility()); sockFd = socket(AF_UNIX,SOCK_STREAM,0); if (sockFd < 0) { cerr << "socket(AF_UNIX,SOCK_STREAM,0) failed: " << strerror(errno) << " {" << __FILE__ << ":" << __LINE__ << "}" << endl; exit(1); } memset(&servSockAddr,0,sizeof(servSockAddr)); servSockAddr.sun_family = AF_UNIX; strcpy(servSockAddr.sun_path,g_cflowdConfig.TableSockFile().c_str()); servSockAddrLen = strlen(servSockAddr.sun_path) + 1 + sizeof(servSockAddr.sun_family); if (connect(sockFd,(struct sockaddr *)&servSockAddr,servSockAddrLen) < 0) { cerr << "connect(" << sockFd << "," << (void *)&servSockAddr << "(\"" << servSockAddr.sun_path << "\",AF_UNIX)" << "," << servSockAddrLen << ") failed: " << strerror(errno) << " {" << __FILE__ << ":" << __LINE__ << "}" << endl; exit(1); } if (tableRequest.Write(sockFd) < 0) { cerr << "tableRequest.Write(" << sockFd << ") failed! {" << __FILE__ << ":" << __LINE__ << "}" << endl; exit(1); } if (cflowdCisco.read(sockFd) < 0) { cerr << "cflowdCisco.read(" << sockFd << ") failed! {" << __FILE__ << ":" << __LINE__ << "}" << endl; // exit(1); } time_t startTime, endTime, timeDelta; startTime = cflowdCisco.LastCleared(); endTime = cflowdCisco.LastUpdated(); timeDelta = endTime - startTime; struct tm *localTm; localTm = localtime(&startTime); cout << "period: " << setfill('0') << setw(2) << (int)localTm->tm_mon+1 << "/" << setw(2) << localTm->tm_mday << "/" << setw(4) << localTm->tm_year + 1900 << " " << setw(2) << localTm->tm_hour << ":" << setw(2) << localTm->tm_min << ":" << setw(2) << localTm->tm_sec << " - "; localTm = localtime(&endTime); cout << setw(2) << (int)localTm->tm_mon+1 << "/" << setw(2) << localTm->tm_mday << "/" << setw(4) << localTm->tm_year + 1900 << " " << setw(2) << localTm->tm_hour << ":" << setw(2) << localTm->tm_min << ":" << setw(2) << localTm->tm_sec << " " << tzname[localTm->tm_isdst] << " (" << timeDelta/60 << " min, " << timeDelta%60 << " sec)" << endl << endl << setfill(' '); for (intfIter = cflowdCisco.Interfaces().begin(); intfIter != cflowdCisco.Interfaces().end(); intfIter++) { CflowdNetMatrix::const_iterator netIter; if (ifIndexMatch != (uint16_t)(-1)) { if ((*intfIter).first != ifIndexMatch) { continue; } } cout << "ifIndex: " << (*intfIter).first; if ((*intfIter).second.IpAddr() != INADDR_NONE) { cout << " (" << (*intfIter).second.IfDescr(); struct in_addr inAddr; inAddr.s_addr = (*intfIter).second.IpAddr(); cout << " " << inet_ntoa(inAddr) << ")"; } cout << endl; cout << " " << setw(18) << "source network" << " " << setw(18) << "dest network"; if (printRates) { cout << " " << setw(15) << "pkts/sec" << " " << setw(15) << "bits/sec" << endl; } else { cout << " " << setw(15) << "packets" << " " << setw(15) << "bytes" << endl; } cout << " " << "---------------" << "-" << "--" << " " << "---------------" << "-" << "--" << " " << "---------------" << " " << "---------------" << endl; for (netIter = (*intfIter).second.NetMatrix().begin(); netIter != (*intfIter).second.NetMatrix().end(); netIter++) { if (NetEntryMatches((*netIter).first)) { srcNetAddr.s_addr = (*netIter).first.Src(); cout << resetiosflags(ios::left) << " " << setw(15) << inet_ntoa(srcNetAddr) << "/" << setiosflags(ios::left) << setw(2) << (uint16_t)(*netIter).first.SrcMaskLen() << setiosflags(ios::right) << " "; dstNetAddr.s_addr = (*netIter).first.Dst(); cout << resetiosflags(ios::left) << setw(15) << inet_ntoa(dstNetAddr) << "/" << setiosflags(ios::left) << setw(2) << (uint16_t)(*netIter).first.DstMaskLen() << resetiosflags(ios::left) << " "; if (printRates) { cout << setw(15) << (uint64_t)((double)(*netIter).second.Pkts()/timeDelta) << " " << setw(15) << (uint64_t)(((double)(*netIter).second.Bytes()*8.0)/timeDelta) << endl; } else { cout << setw(15) << (*netIter).second.Pkts() << " " << setw(15) << (*netIter).second.Bytes() << endl; } } // if (NetEntryMatches((*netIter).first)) ... } // for (netIter = (*intfIter).second.NetMatrix().begin(); ... cout << endl; } }