|
INET Framework for OMNeT++/OMNEST
|
00001 // 00002 // Copyright (C) 2007 Vojtech Janota 00003 // 00004 // This program is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU General Public License 00006 // as published by the Free Software Foundation; either version 2 00007 // of the License, or (at your option) any later version. 00008 // 00009 // This program is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with this program; if not, see <http://www.gnu.org/licenses/>. 00016 // 00017 00018 #include <fstream> 00019 #include <algorithm> 00020 00021 #include "NetworkInfo.h" 00022 #include "IRoutingTable.h" 00023 #include "IPAddressResolver.h" 00024 #include "InterfaceEntry.h" 00025 00026 00027 Define_Module(NetworkInfo); 00028 00029 void NetworkInfo::initialize() 00030 { 00031 // so far no initialization 00032 } 00033 00034 void NetworkInfo::handleMessage(cMessage *msg) 00035 { 00036 ASSERT(false); 00037 } 00038 00039 void NetworkInfo::processCommand(const cXMLElement& node) 00040 { 00041 cModule *target = simulation.getModuleByPath(node.getAttribute("target")); 00042 00043 if (!strcmp(node.getTagName(), "routing")) 00044 { 00045 const char *filename = node.getAttribute("file"); 00046 ASSERT(filename); 00047 const char *mode = node.getAttribute("mode"); 00048 const char *compat = node.getAttribute("compat"); 00049 00050 dumpRoutingInfo(target, filename, (mode && !strcmp(mode, "a")), (compat && !strcmp(compat, "linux"))); 00051 } 00052 else 00053 ASSERT(false); 00054 } 00055 00056 void NetworkInfo::dumpRoutingInfo(cModule *target, const char *filename, bool append, bool compat) 00057 { 00058 std::ofstream s; 00059 s.open(filename, append?(std::ios::app):(std::ios::out)); 00060 if (s.fail()) 00061 error("cannot open `%s' for write", filename); 00062 00063 if (compat) s << "Kernel IP routing table" << endl; 00064 s << "Destination Gateway Genmask "; 00065 if (compat) s << "Flags "; 00066 s << "Metric "; 00067 if (compat) s << "Ref Use "; 00068 s << "Iface" << endl; 00069 00070 cModule *rtmod = target->getSubmodule("routingTable"); 00071 if (rtmod) 00072 { 00073 std::vector<std::string> lines; 00074 00075 IRoutingTable *rt = check_and_cast<IRoutingTable *>(rtmod); 00076 for (int i = 0; i < rt->getNumRoutes(); i++) 00077 { 00078 IPAddress host = rt->getRoute(i)->getHost(); 00079 00080 if (host.isMulticast()) 00081 continue; 00082 00083 if (rt->getRoute(i)->getInterface()->isLoopback()) 00084 continue; 00085 00086 IPAddress netmask = rt->getRoute(i)->getNetmask(); 00087 IPAddress gateway = rt->getRoute(i)->getGateway(); 00088 int metric = rt->getRoute(i)->getMetric(); 00089 00090 std::ostringstream line; 00091 00092 line << std::left; 00093 IPAddress dest = compat ? host.doAnd(netmask) : host; 00094 line.width(16); 00095 if (dest.isUnspecified()) line << "0.0.0.0"; else line << dest; 00096 00097 line.width(16); 00098 if (gateway.isUnspecified()) line << "0.0.0.0"; else line << gateway; 00099 00100 line.width(16); 00101 if (netmask.isUnspecified()) line << "0.0.0.0"; else line << netmask; 00102 00103 if (compat) 00104 { 00105 int pad = 3; 00106 line << "U"; // routes in INET are always up 00107 if (!gateway.isUnspecified()) line << "G"; else ++pad; 00108 if (netmask.equals(IPAddress::ALLONES_ADDRESS)) line << "H"; else ++pad; 00109 line.width(pad); 00110 line << " "; 00111 } 00112 00113 line.width(7); 00114 if (compat && rt->getRoute(i)->getSource() == IPRoute::IFACENETMASK) 00115 metric = 0; 00116 line << metric; 00117 00118 if (compat) line << "0 0 "; 00119 00120 line << rt->getRoute(i)->getInterfaceName() << endl; 00121 00122 if (compat) 00123 lines.push_back(line.str()); 00124 else 00125 s << line.str(); 00126 } 00127 00128 if (compat) 00129 { 00130 // sort to avoid random order 00131 // typically routing tables are sorted by netmask prefix length (descending) 00132 // sorting by reversed natural order looks weired, but allows easy comparison 00133 // with `route -n | sort -r` output by means of `diff` command... 00134 std::sort(lines.begin(), lines.end()); 00135 for (std::vector<std::string>::reverse_iterator it = lines.rbegin(); it != lines.rend(); it++) 00136 s << *it; 00137 } 00138 } 00139 s << endl; 00140 s.close(); 00141 }