Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "IPAddressResolver.h"
00020 #include "IInterfaceTable.h"
00021 #include "IPv4InterfaceData.h"
00022 #include "IRoutingTable.h"
00023 #include "NotificationBoard.h"
00024 #ifndef WITHOUT_IPv6
00025 #include "IPv6InterfaceData.h"
00026 #include "RoutingTable6.h"
00027 #endif
00028
00029
00030 IPvXAddress IPAddressResolver::resolve(const char *s, int addrType)
00031 {
00032 IPvXAddress addr;
00033 if (!tryResolve(s, addr, addrType))
00034 opp_error("IPAddressResolver: address `%s' not configured (yet?)", s);
00035 return addr;
00036 }
00037
00038 bool IPAddressResolver::tryResolve(const char *s, IPvXAddress& result, int addrType)
00039 {
00040
00041 result = IPvXAddress();
00042 if (!s || !*s)
00043 return true;
00044
00045
00046 if (result.tryParse(s))
00047 return true;
00048
00049
00050
00051 const char *slashp = strchr(s,'/');
00052 const char *leftparenp = strchr(s,'(');
00053 const char *rightparenp = strchr(s,')');
00054 const char *endp = s+strlen(s);
00055
00056
00057 if ((slashp && leftparenp && slashp>leftparenp) ||
00058 (leftparenp && !rightparenp) ||
00059 (!leftparenp && rightparenp) ||
00060 (rightparenp && rightparenp!=endp-1))
00061 {
00062 opp_error("IPAddressResolver: syntax error parsing address spec `%s'", s);
00063 }
00064
00065
00066 std::string modname, ifname, protocol;
00067 modname.assign(s, (slashp?slashp:leftparenp?leftparenp:endp)-s);
00068 if (slashp)
00069 ifname.assign(slashp+1, (leftparenp?leftparenp:endp)-slashp-1);
00070 if (leftparenp)
00071 protocol.assign(leftparenp+1, rightparenp-leftparenp-1);
00072
00073
00074 cModule *mod = simulation.getModuleByPath(modname.c_str());
00075 if (!mod)
00076 opp_error("IPAddressResolver: module `%s' not found", modname.c_str());
00077 if (!protocol.empty() && protocol!="ipv4" && protocol!="ipv6")
00078 opp_error("IPAddressResolver: error parsing address spec `%s': address type must be `(ipv4)' or `(ipv6)'", s);
00079 if (!protocol.empty())
00080 addrType = protocol=="ipv4" ? ADDR_IPv4 : ADDR_IPv6;
00081
00082
00083 if (ifname.empty())
00084 result = addressOf(mod, addrType);
00085 else if (ifname == "routerId")
00086 result = IPvXAddress(routerIdOf(mod));
00087 else
00088 result = addressOf(mod, ifname.c_str(), addrType);
00089 return !result.isUnspecified();
00090 }
00091
00092 IPAddress IPAddressResolver::routerIdOf(cModule *host)
00093 {
00094 IRoutingTable *rt = routingTableOf(host);
00095 return rt->getRouterId();
00096 }
00097
00098 IPvXAddress IPAddressResolver::addressOf(cModule *host, int addrType)
00099 {
00100 IInterfaceTable *ift = interfaceTableOf(host);
00101 return getAddressFrom(ift, addrType);
00102 }
00103
00104 IPvXAddress IPAddressResolver::addressOf(cModule *host, const char *ifname, int addrType)
00105 {
00106 IInterfaceTable *ift = interfaceTableOf(host);
00107 InterfaceEntry *ie = ift->getInterfaceByName(ifname);
00108 if (!ie)
00109 opp_error("IPAddressResolver: no interface called `%s' in interface table", ifname, ift->getFullPath().c_str());
00110 return getAddressFrom(ie, addrType);
00111 }
00112
00113 IPvXAddress IPAddressResolver::getAddressFrom(IInterfaceTable *ift, int addrType)
00114 {
00115 IPvXAddress ret;
00116 if (addrType==ADDR_IPv6 || addrType==ADDR_PREFER_IPv6)
00117 {
00118 ret = getIPv6AddressFrom(ift);
00119 if (ret.isUnspecified() && addrType==ADDR_PREFER_IPv6)
00120 ret = getIPv4AddressFrom(ift);
00121 }
00122 else if (addrType==ADDR_IPv4 || addrType==ADDR_PREFER_IPv4)
00123 {
00124 ret = getIPv4AddressFrom(ift);
00125 if (ret.isUnspecified() && addrType==ADDR_PREFER_IPv4)
00126 ret = getIPv6AddressFrom(ift);
00127 }
00128 else
00129 {
00130 opp_error("IPAddressResolver: unknown addrType %d", addrType);
00131 }
00132 return ret;
00133 }
00134
00135 IPvXAddress IPAddressResolver::getAddressFrom(InterfaceEntry *ie, int addrType)
00136 {
00137 IPvXAddress ret;
00138 if (addrType==ADDR_IPv6 || addrType==ADDR_PREFER_IPv6)
00139 {
00140 if (ie->ipv6Data())
00141 ret = getInterfaceIPv6Address(ie);
00142 if (ret.isUnspecified() && addrType==ADDR_PREFER_IPv6 && ie->ipv4Data())
00143 ret = ie->ipv4Data()->getIPAddress();
00144 }
00145 else if (addrType==ADDR_IPv4 || addrType==ADDR_PREFER_IPv4)
00146 {
00147 if (ie->ipv4Data())
00148 ret = ie->ipv4Data()->getIPAddress();
00149 if (ret.isUnspecified() && addrType==ADDR_PREFER_IPv4 && ie->ipv6Data())
00150 ret = getInterfaceIPv6Address(ie);
00151 }
00152 else
00153 {
00154 opp_error("IPAddressResolver: unknown addrType %d", addrType);
00155 }
00156 return ret;
00157 }
00158
00159 IPAddress IPAddressResolver::getIPv4AddressFrom(IInterfaceTable *ift)
00160 {
00161 IPAddress addr;
00162 if (ift->getNumInterfaces()==0)
00163 opp_error("IPAddressResolver: interface table `%s' has no interface registered "
00164 "(yet? try in a later init stage!)", ift->getFullPath().c_str());
00165
00166
00167 for (int i=0; i<ift->getNumInterfaces(); i++)
00168 {
00169 InterfaceEntry *ie = ift->getInterface(i);
00170 if (ie->ipv4Data() && !ie->ipv4Data()->getIPAddress().isUnspecified() && !ie->isLoopback())
00171 {
00172 addr = ie->ipv4Data()->getIPAddress();
00173 break;
00174 }
00175 }
00176 return addr;
00177 }
00178
00179 IPv6Address IPAddressResolver::getIPv6AddressFrom(IInterfaceTable *ift)
00180 {
00181 #ifndef WITHOUT_IPv6
00182
00183 if (ift->getNumInterfaces()==0)
00184 opp_error("IPAddressResolver: interface table `%s' has no interface registered "
00185 "(yet? try in a later init stage!)", ift->getFullPath().c_str());
00186
00187 IPv6Address addr;
00188 for (int i=0; i<ift->getNumInterfaces() && addr.isUnspecified(); i++)
00189 {
00190 InterfaceEntry *ie = ift->getInterface(i);
00191 if (!ie->ipv6Data() || ie->isLoopback())
00192 continue;
00193 IPv6Address ifAddr = ie->ipv6Data()->getPreferredAddress();
00194 if (addr.isGlobal() && ifAddr.isGlobal() && addr!=ifAddr)
00195 EV << ift->getFullPath() << " has at least two globally routable addresses on different interfaces\n";
00196 if (ifAddr.isGlobal())
00197 addr = ifAddr;
00198 }
00199 return addr;
00200 #else
00201 return IPv6Address();
00202 #endif
00203 }
00204
00205 IPv6Address IPAddressResolver::getInterfaceIPv6Address(InterfaceEntry *ie)
00206 {
00207 #ifndef WITHOUT_IPv6
00208 if (!ie->ipv6Data())
00209 return IPv6Address();
00210 return ie->ipv6Data()->getPreferredAddress();
00211 #else
00212 return IPv6Address();
00213 #endif
00214 }
00215
00216 IInterfaceTable *IPAddressResolver::interfaceTableOf(cModule *host)
00217 {
00218
00219 cModule *mod = host->getSubmodule("interfaceTable");
00220 if (!mod)
00221 opp_error("IPAddressResolver: IInterfaceTable not found as submodule "
00222 " `interfaceTable' in host/router `%s'", host->getFullPath().c_str());
00223 return check_and_cast<IInterfaceTable *>(mod);
00224 }
00225
00226 IRoutingTable *IPAddressResolver::routingTableOf(cModule *host)
00227 {
00228
00229 cModule *mod = host->getSubmodule("routingTable");
00230 if (!mod)
00231 opp_error("IPAddressResolver: IRoutingTable not found as submodule "
00232 " `routingTable' in host/router `%s'", host->getFullPath().c_str());
00233 return check_and_cast<IRoutingTable *>(mod);
00234 }
00235
00236 #ifndef WITHOUT_IPv6
00237 RoutingTable6 *IPAddressResolver::routingTable6Of(cModule *host)
00238 {
00239
00240 cModule *mod = host->getSubmodule("routingTable6");
00241 if (!mod)
00242 opp_error("IPAddressResolver: RoutingTable6 not found as submodule "
00243 " `routingTable6' in host/router `%s'", host->getFullPath().c_str());
00244 return check_and_cast<RoutingTable6 *>(mod);
00245 }
00246 #endif
00247
00248 NotificationBoard *IPAddressResolver::notificationBoardOf(cModule *host)
00249 {
00250
00251 cModule *mod = host->getSubmodule("notificationBoard");
00252 if (!mod)
00253 opp_error("IPAddressResolver: NotificationBoard not found as submodule "
00254 " notificationBoard' in host/router `%s'", host->getFullPath().c_str());
00255 return check_and_cast<NotificationBoard *>(mod);
00256 }
00257
00258 IInterfaceTable *IPAddressResolver::findInterfaceTableOf(cModule *host)
00259 {
00260 cModule *mod = host->getSubmodule("interfaceTable");
00261 return dynamic_cast<IInterfaceTable *>(mod);
00262 }
00263
00264 IRoutingTable *IPAddressResolver::findRoutingTableOf(cModule *host)
00265 {
00266 cModule *mod = host->getSubmodule("routingTable");
00267 return dynamic_cast<IRoutingTable *>(mod);
00268 }
00269
00270 #ifndef WITHOUT_IPv6
00271 RoutingTable6 *IPAddressResolver::findRoutingTable6Of(cModule *host)
00272 {
00273 cModule *mod = host->getSubmodule("routingTable6");
00274 return dynamic_cast<RoutingTable6 *>(mod);
00275 }
00276 #endif
00277
00278 NotificationBoard *IPAddressResolver::findNotificationBoardOf(cModule *host)
00279 {
00280 cModule *mod = host->getSubmodule("notificationBoard");
00281 return dynamic_cast<NotificationBoard *>(mod);
00282 }
00283
00284
00285
00286