#include <IPAddressResolver.h>
Syntax variations understood:
anonymous enum |
IPvXAddress IPAddressResolver::addressOf | ( | cModule * | host, | |
const char * | ifname, | |||
int | addrType = ADDR_PREFER_IPv6 | |||
) |
Similar to addressOf(), but only looks at the given interface
00105 { 00106 InterfaceTable *ift = interfaceTableOf(host); 00107 InterfaceEntry *ie = ift->interfaceByName(ifname); 00108 if (!ie) 00109 opp_error("IPAddressResolver: no interface called `%s' in `%s'", ifname, ift->fullPath().c_str()); 00110 return getAddressFrom(ie, addrType); 00111 }
IPvXAddress IPAddressResolver::addressOf | ( | cModule * | host, | |
int | addrType = ADDR_PREFER_IPv6 | |||
) |
Returns IPv4 or IPv6 address of the given host or router.
This function uses routingTableOf() to find the RoutingTable module, then invokes getAddressFrom() to extract the IP address.
00099 { 00100 InterfaceTable *ift = interfaceTableOf(host); 00101 return getAddressFrom(ift, addrType); 00102 }
InterfaceTable * IPAddressResolver::findInterfaceTableOf | ( | cModule * | host | ) |
Like interfaceTableOf(), but doesn't throw error if not found.
00259 { 00260 cModule *mod = host->submodule("interfaceTable"); 00261 return dynamic_cast<InterfaceTable *>(mod); 00262 }
NotificationBoard * IPAddressResolver::findNotificationBoardOf | ( | cModule * | host | ) |
Like notificationBoardOf(), but doesn't throw error if not found.
00279 { 00280 cModule *mod = host->submodule("notificationBoard"); 00281 return dynamic_cast<NotificationBoard *>(mod); 00282 }
RoutingTable * IPAddressResolver::findRoutingTableOf | ( | cModule * | host | ) |
Like routingTableOf(), but doesn't throw error if not found.
00265 { 00266 cModule *mod = host->submodule("routingTable"); 00267 return dynamic_cast<RoutingTable *>(mod); 00268 }
IPvXAddress IPAddressResolver::getAddressFrom | ( | InterfaceEntry * | ie, | |
int | addrType = ADDR_PREFER_IPv6 | |||
) |
Returns the IPv4 or IPv6 address of the given interface (of a host or router).
00136 { 00137 IPvXAddress ret; 00138 if (addrType==ADDR_IPv6 || addrType==ADDR_PREFER_IPv6) 00139 { 00140 if (ie->ipv6()) 00141 ret = getInterfaceIPv6Address(ie); 00142 if (ret.isUnspecified() && addrType==ADDR_PREFER_IPv6 && ie->ipv4()) 00143 ret = ie->ipv4()->inetAddress(); 00144 } 00145 else if (addrType==ADDR_IPv4 || addrType==ADDR_PREFER_IPv4) 00146 { 00147 if (ie->ipv4()) 00148 ret = ie->ipv4()->inetAddress(); 00149 if (ret.isUnspecified() && addrType==ADDR_PREFER_IPv4 && ie->ipv6()) 00150 ret = getInterfaceIPv6Address(ie); 00151 } 00152 else 00153 { 00154 opp_error("IPAddressResolver: unknown addrType %d", addrType); 00155 } 00156 return ret; 00157 }
IPvXAddress IPAddressResolver::getAddressFrom | ( | InterfaceTable * | ift, | |
int | addrType = ADDR_PREFER_IPv6 | |||
) |
Returns the IPv4 or IPv6 address of the given host or router, given its InterfaceTable module. For IPv4, the first usable interface address is chosen.
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 }
IPv6Address IPAddressResolver::getInterfaceIPv6Address | ( | InterfaceEntry * | ie | ) | [private] |
00206 { 00207 #ifdef WITH_IPv6 00208 if (!ie->ipv6()) 00209 return IPv6Address(); 00210 return ie->ipv6()->preferredAddress(); 00211 #else 00212 return IPv6Address(); 00213 #endif 00214 }
IPAddress IPAddressResolver::getIPv4AddressFrom | ( | InterfaceTable * | ift | ) | [private] |
00160 { 00161 IPAddress addr; 00162 if (ift->numInterfaces()==0) 00163 opp_error("IPAddressResolver: interface table `%s' has no interface registered " 00164 "(yet? try in a later init stage!)", ift->fullPath().c_str()); 00165 00166 // choose first usable interface address (configured for IPv4, non-loopback if, addr non-null) 00167 for (int i=0; i<ift->numInterfaces(); i++) 00168 { 00169 InterfaceEntry *ie = ift->interfaceAt(i); 00170 if (ie->ipv4() && !ie->ipv4()->inetAddress().isUnspecified() && !ie->isLoopback()) 00171 { 00172 addr = ie->ipv4()->inetAddress(); 00173 break; 00174 } 00175 } 00176 return addr; 00177 }
IPv6Address IPAddressResolver::getIPv6AddressFrom | ( | InterfaceTable * | ift, | |
int | scope | |||
) | [private] |
IPv6Address IPAddressResolver::getIPv6AddressFrom | ( | InterfaceTable * | ift | ) | [private] |
00180 { 00181 #ifdef WITH_IPv6 00182 // browse interfaces and pick a globally routable address 00183 if (ift->numInterfaces()==0) 00184 opp_error("IPAddressResolver: interface table `%s' has no interface registered " 00185 "(yet? try in a later init stage!)", ift->fullPath().c_str()); 00186 00187 IPv6Address addr; 00188 for (int i=0; i<ift->numInterfaces() && addr.isUnspecified(); i++) 00189 { 00190 InterfaceEntry *ie = ift->interfaceAt(i); 00191 if (!ie->ipv6() || ie->isLoopback()) 00192 continue; 00193 IPv6Address ifAddr = ie->ipv6()->preferredAddress(); 00194 if (addr.isGlobal() && ifAddr.isGlobal() && addr!=ifAddr) 00195 EV << ift->fullPath() << " 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 }
InterfaceTable * IPAddressResolver::interfaceTableOf | ( | cModule * | host | ) |
The function tries to look up the InterfaceTable module as submodule "interfaceTable"
or "networkLayer.interfaceTable"
within the host/router module. Throws an error if not found.
00217 { 00218 // find InterfaceTable 00219 cModule *mod = host->submodule("interfaceTable"); 00220 if (!mod) 00221 opp_error("IPAddressResolver: InterfaceTable not found as submodule " 00222 " `interfaceTable' in host/router `%s'", host->fullPath().c_str()); 00223 return check_and_cast<InterfaceTable *>(mod); 00224 }
NotificationBoard * IPAddressResolver::notificationBoardOf | ( | cModule * | host | ) |
The function tries to look up the NotificationBoard module as submodule "notificationBoard"
within the host/router module. Throws an error if not found.
00249 { 00250 // find NotificationBoard 00251 cModule *mod = host->submodule("notificationBoard"); 00252 if (!mod) 00253 opp_error("IPAddressResolver: NotificationBoard not found as submodule " 00254 " notificationBoard' in host/router `%s'", host->fullPath().c_str()); 00255 return check_and_cast<NotificationBoard *>(mod); 00256 }
IPvXAddress IPAddressResolver::resolve | ( | const char * | str, | |
int | addrType = ADDR_PREFER_IPv6 | |||
) |
Accepts dotted decimal notation ("127.0.0.1"), module name of the host or router ("host[2]"), and empty string (""). For the latter, it returns the null address. If module name is specified, the module will be looked up using simulation.moduleByPath()
, and then addressOf() will be called to determine its IP address.
00031 { 00032 IPvXAddress addr; 00033 if (!tryResolve(s, addr, addrType)) 00034 opp_error("IPAddressResolver: address `%s' not configured (yet?)", s); 00035 return addr; 00036 }
IPAddress IPAddressResolver::routerIdOf | ( | cModule * | host | ) |
Returns the router Id of the given router. Router Id is obtained from the routerId() method of the RoutingTable submodule.
00093 { 00094 RoutingTable *rt = routingTableOf(host); 00095 return rt->routerId(); 00096 }
RoutingTable * IPAddressResolver::routingTableOf | ( | cModule * | host | ) |
The function tries to look up the RoutingTable module as submodule "routingTable"
or "networkLayer.routingTable"
within the host/router module. Throws an error if not found.
00227 { 00228 // find RoutingTable 00229 cModule *mod = host->submodule("routingTable"); 00230 if (!mod) 00231 opp_error("IPAddressResolver: RoutingTable not found as submodule " 00232 " `routingTable' in host/router `%s'", host->fullPath().c_str()); 00233 return check_and_cast<RoutingTable *>(mod); 00234 }
bool IPAddressResolver::tryResolve | ( | const char * | str, | |
IPvXAddress & | result, | |||
int | addrType = ADDR_PREFER_IPv6 | |||
) |
Similar to resolve(), but returns false (instead of throwing an error) if the address cannot be resolved because the given host (or interface) doesn't have an address assigned yet. (It still throws an error on any other error condition).
00039 { 00040 // empty address 00041 result = IPvXAddress(); 00042 if (!s || !*s) 00043 return true; 00044 00045 // handle address literal 00046 if (result.tryParse(s)) 00047 return true; 00048 00049 // must be "modulename/interfacename(protocol)" syntax then, 00050 // "/interfacename" and "(protocol)" being optional 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 // rudimentary syntax check 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 // parse fields: modname, ifname, protocol 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 // find module and check protocol 00074 cModule *mod = simulation.moduleByPath(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 // get address from the given module/interface 00083 if (ifname.empty()) 00084 result = addressOf(mod, addrType); 00085 else if (ifname == "routerId") 00086 result = IPvXAddress(routerIdOf(mod)); // addrType is meaningless here, routerId is protocol independent 00087 else 00088 result = addressOf(mod, ifname.c_str(), addrType); 00089 return !result.isUnspecified(); 00090 }