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 #include "OSPFRouting.h"
00019 #include "IPAddress.h"
00020 #include "IPAddressResolver.h"
00021 #include "IPControlInfo.h"
00022 #include "OSPFcommon.h"
00023 #include "OSPFArea.h"
00024 #include "OSPFInterface.h"
00025 #include "MessageHandler.h"
00026 #include "RoutingTableAccess.h"
00027 #include "InterfaceTableAccess.h"
00028 #include <string>
00029 #include <map>
00030 #include <stdlib.h>
00031 #include <memory.h>
00032
00033
00034 Define_Module(OSPFRouting);
00035
00036
00037 OSPFRouting::OSPFRouting()
00038 {
00039 ospfRouter = NULL;
00040 }
00041
00046 OSPFRouting::~OSPFRouting(void)
00047 {
00048 delete ospfRouter;
00049 }
00050
00051
00059 void OSPFRouting::initialize(int stage)
00060 {
00061
00062
00063 if (stage == 4)
00064 {
00065 rt = RoutingTableAccess().get();
00066 ift = InterfaceTableAccess().get();
00067
00068
00069 ospfRouter = new OSPF::Router(rt->getRouterId().getInt(), this);
00070
00071
00072 const char *fileName = par("ospfConfigFile");
00073 if (fileName == NULL || (!strcmp(fileName, "")) || !LoadConfigFromXML(fileName))
00074 error("Error reading AS configuration from file %s", fileName);
00075
00076 ospfRouter->AddWatches();
00077 }
00078 }
00079
00080
00085 void OSPFRouting::handleMessage(cMessage *msg)
00086 {
00087
00088
00089
00090 ospfRouter->GetMessageHandler()->MessageReceived(msg);
00091 }
00092
00096 int OSPFRouting::ResolveInterfaceName(const std::string& name) const
00097 {
00098 InterfaceEntry* ie = ift->getInterfaceByName(name.c_str());
00099 if (!ie)
00100 opp_error("error reading XML config: IInterfaceTable contains no interface named '%s'", name.c_str());
00101 return ie->getInterfaceId();
00102 }
00103
00109 void OSPFRouting::GetAreaListFromXML(const cXMLElement& routerNode, std::map<std::string, int>& areaList) const
00110 {
00111 cXMLElementList routerConfig = routerNode.getChildren();
00112 for (cXMLElementList::iterator routerConfigIt = routerConfig.begin(); routerConfigIt != routerConfig.end(); routerConfigIt++) {
00113 std::string nodeName = (*routerConfigIt)->getTagName();
00114 if ((nodeName == "PointToPointInterface") ||
00115 (nodeName == "BroadcastInterface") ||
00116 (nodeName == "NBMAInterface") ||
00117 (nodeName == "PointToMultiPointInterface"))
00118 {
00119 std::string areaId = (*routerConfigIt)->getChildrenByTagName("AreaID")[0]->getNodeValue();
00120 if (areaList.find(areaId) == areaList.end()) {
00121 areaList[areaId] = 1;
00122 }
00123 }
00124 }
00125 }
00126
00127
00134 void OSPFRouting::LoadAreaFromXML(const cXMLElement& asConfig, const std::string& areaID)
00135 {
00136 std::string areaXPath("Area[@id='");
00137 areaXPath += areaID;
00138 areaXPath += "']";
00139
00140 cXMLElement* areaConfig = asConfig.getElementByPath(areaXPath.c_str());
00141 if (areaConfig == NULL) {
00142 error("No configuration for Area ID: %s", areaID.c_str());
00143 }
00144 else {
00145 EV << " loading info for Area id = " << areaID << "\n";
00146 }
00147
00148 OSPF::Area* area = new OSPF::Area(ULongFromAddressString(areaID.c_str()));
00149 cXMLElementList areaDetails = areaConfig->getChildren();
00150 for (cXMLElementList::iterator arIt = areaDetails.begin(); arIt != areaDetails.end(); arIt++) {
00151 std::string nodeName = (*arIt)->getTagName();
00152 if (nodeName == "AddressRange") {
00153 OSPF::IPv4AddressRange addressRange;
00154 addressRange.address = IPv4AddressFromAddressString((*arIt)->getChildrenByTagName("Address")[0]->getNodeValue());
00155 addressRange.mask = IPv4AddressFromAddressString((*arIt)->getChildrenByTagName("Mask")[0]->getNodeValue());
00156 std::string status = (*arIt)->getChildrenByTagName("Status")[0]->getNodeValue();
00157 if (status == "Advertise") {
00158 area->AddAddressRange(addressRange, true);
00159 } else {
00160 area->AddAddressRange(addressRange, false);
00161 }
00162 }
00163 if ((nodeName == "Stub") && (areaID != "0.0.0.0")) {
00164 area->SetExternalRoutingCapability(false);
00165 area->SetStubDefaultCost(atoi((*arIt)->getChildrenByTagName("DefaultCost")[0]->getNodeValue()));
00166 }
00167 }
00168
00169 ospfRouter->AddArea(area);
00170 }
00171
00172
00178 void OSPFRouting::LoadInterfaceParameters(const cXMLElement& ifConfig)
00179 {
00180 OSPF::Interface* intf = new OSPF::Interface;
00181 std::string ifName = ifConfig.getAttribute("ifName");
00182 int ifIndex = ResolveInterfaceName(ifName);
00183 std::string interfaceType = ifConfig.getTagName();
00184
00185 EV << " loading " << interfaceType << " " << ifName << " ifIndex[" << ifIndex << "]\n";
00186
00187 intf->SetIfIndex(ifIndex);
00188 if (interfaceType == "PointToPointInterface") {
00189 intf->SetType(OSPF::Interface::PointToPoint);
00190 } else if (interfaceType == "BroadcastInterface") {
00191 intf->SetType(OSPF::Interface::Broadcast);
00192 } else if (interfaceType == "NBMAInterface") {
00193 intf->SetType(OSPF::Interface::NBMA);
00194 } else if (interfaceType == "PointToMultiPointInterface") {
00195 intf->SetType(OSPF::Interface::PointToMultiPoint);
00196 } else {
00197 delete intf;
00198 error("Loading %s ifIndex[%d] aborted", interfaceType.c_str(), ifIndex);
00199 }
00200
00201 OSPF::AreaID areaID = 0;
00202 cXMLElementList ifDetails = ifConfig.getChildren();
00203
00204 for (cXMLElementList::iterator ifElemIt = ifDetails.begin(); ifElemIt != ifDetails.end(); ifElemIt++) {
00205 std::string nodeName = (*ifElemIt)->getTagName();
00206 if (nodeName == "AreaID") {
00207 areaID = ULongFromAddressString((*ifElemIt)->getNodeValue());
00208 intf->SetAreaID(areaID);
00209 }
00210 if (nodeName == "InterfaceOutputCost") {
00211 intf->SetOutputCost(atoi((*ifElemIt)->getNodeValue()));
00212 }
00213 if (nodeName == "RetransmissionInterval") {
00214 intf->SetRetransmissionInterval(atoi((*ifElemIt)->getNodeValue()));
00215 }
00216 if (nodeName == "InterfaceTransmissionDelay") {
00217 intf->SetTransmissionDelay(atoi((*ifElemIt)->getNodeValue()));
00218 }
00219 if (nodeName == "RouterPriority") {
00220 intf->SetRouterPriority(atoi((*ifElemIt)->getNodeValue()));
00221 }
00222 if (nodeName == "HelloInterval") {
00223 intf->SetHelloInterval(atoi((*ifElemIt)->getNodeValue()));
00224 }
00225 if (nodeName == "RouterDeadInterval") {
00226 intf->SetRouterDeadInterval(atoi((*ifElemIt)->getNodeValue()));
00227 }
00228 if (nodeName == "AuthenticationType") {
00229 std::string authenticationType = (*ifElemIt)->getNodeValue();
00230 if (authenticationType == "SimplePasswordType") {
00231 intf->SetAuthenticationType(OSPF::SimplePasswordType);
00232 } else if (authenticationType == "CrytographicType") {
00233 intf->SetAuthenticationType(OSPF::CrytographicType);
00234 } else {
00235 intf->SetAuthenticationType(OSPF::NullType);
00236 }
00237 }
00238 if (nodeName == "AuthenticationKey") {
00239 std::string key = (*ifElemIt)->getNodeValue();
00240 OSPF::AuthenticationKeyType keyValue;
00241 memset(keyValue.bytes, 0, 8 * sizeof(char));
00242 int keyLength = key.length();
00243 if ((keyLength > 4) && (keyLength <= 18) && (keyLength % 2 == 0) && (key[0] == '0') && (key[1] == 'x')) {
00244 for (int i = keyLength; (i > 2); i -= 2) {
00245 keyValue.bytes[(i - 2) / 2] = HexPairToByte(key[i - 1], key[i]);
00246 }
00247 }
00248 intf->SetAuthenticationKey(keyValue);
00249 }
00250 if (nodeName == "PollInterval") {
00251 intf->SetPollInterval(atoi((*ifElemIt)->getNodeValue()));
00252 }
00253 if ((interfaceType == "NBMAInterface") && (nodeName == "NBMANeighborList")) {
00254 cXMLElementList neighborList = (*ifElemIt)->getChildren();
00255 for (cXMLElementList::iterator neighborIt = neighborList.begin(); neighborIt != neighborList.end(); neighborIt++) {
00256 std::string neighborNodeName = (*neighborIt)->getTagName();
00257 if (neighborNodeName == "NBMANeighbor") {
00258 OSPF::Neighbor* neighbor = new OSPF::Neighbor;
00259 neighbor->SetAddress(IPv4AddressFromAddressString((*neighborIt)->getChildrenByTagName("NetworkInterfaceAddress")[0]->getNodeValue()));
00260 neighbor->SetPriority(atoi((*neighborIt)->getChildrenByTagName("NeighborPriority")[0]->getNodeValue()));
00261 intf->AddNeighbor(neighbor);
00262 }
00263 }
00264 }
00265 if ((interfaceType == "PointToMultiPointInterface") && (nodeName == "PointToMultiPointNeighborList")) {
00266 cXMLElementList neighborList = (*ifElemIt)->getChildren();
00267 for (cXMLElementList::iterator neighborIt = neighborList.begin(); neighborIt != neighborList.end(); neighborIt++) {
00268 std::string neighborNodeName = (*neighborIt)->getTagName();
00269 if (neighborNodeName == "PointToMultiPointNeighbor") {
00270 OSPF::Neighbor* neighbor = new OSPF::Neighbor;
00271 neighbor->SetAddress(IPv4AddressFromAddressString((*neighborIt)->getNodeValue()));
00272 intf->AddNeighbor(neighbor);
00273 }
00274 }
00275 }
00276
00277 }
00278
00279 OSPF::Area* area = ospfRouter->GetArea(areaID);
00280 if (area != NULL) {
00281 area->AddInterface(intf);
00282 intf->ProcessEvent(OSPF::Interface::InterfaceUp);
00283 } else {
00284 delete intf;
00285 error("Loading %s ifIndex[%d] in Area %d aborted", interfaceType.c_str(), ifIndex, areaID);
00286 }
00287 }
00288
00289
00294 void OSPFRouting::LoadExternalRoute(const cXMLElement& externalRouteConfig)
00295 {
00296 std::string ifName = externalRouteConfig.getAttribute("ifName");
00297 int ifIndex = ResolveInterfaceName(ifName);
00298 OSPFASExternalLSAContents asExternalRoute;
00299 OSPF::RoutingTableEntry externalRoutingEntry;
00300 OSPF::IPv4AddressRange networkAddress;
00301
00302 EV << " loading ExternalInterface " << ifName << " ifIndex[" << ifIndex << "]\n";
00303
00304 cXMLElementList ifDetails = externalRouteConfig.getChildren();
00305 for (cXMLElementList::iterator exElemIt = ifDetails.begin(); exElemIt != ifDetails.end(); exElemIt++) {
00306 std::string nodeName = (*exElemIt)->getTagName();
00307 if (nodeName == "AdvertisedExternalNetwork") {
00308 networkAddress.address = IPv4AddressFromAddressString((*exElemIt)->getChildrenByTagName("Address")[0]->getNodeValue());
00309 networkAddress.mask = IPv4AddressFromAddressString((*exElemIt)->getChildrenByTagName("Mask")[0]->getNodeValue());
00310 asExternalRoute.setNetworkMask(ULongFromIPv4Address(networkAddress.mask));
00311 }
00312 if (nodeName == "ExternalInterfaceOutputParameters") {
00313 std::string metricType = (*exElemIt)->getChildrenByTagName("ExternalInterfaceOutputType")[0]->getNodeValue();
00314 int routeCost = atoi((*exElemIt)->getChildrenByTagName("ExternalInterfaceOutputCost")[0]->getNodeValue());
00315
00316 asExternalRoute.setRouteCost(routeCost);
00317 if (metricType == "Type2") {
00318 asExternalRoute.setE_ExternalMetricType(true);
00319 externalRoutingEntry.SetType2Cost(routeCost);
00320 externalRoutingEntry.SetPathType(OSPF::RoutingTableEntry::Type2External);
00321 } else {
00322 asExternalRoute.setE_ExternalMetricType(false);
00323 externalRoutingEntry.SetCost(routeCost);
00324 externalRoutingEntry.SetPathType(OSPF::RoutingTableEntry::Type1External);
00325 }
00326 }
00327 if (nodeName == "ForwardingAddress") {
00328 asExternalRoute.setForwardingAddress(ULongFromAddressString((*exElemIt)->getNodeValue()));
00329 }
00330 if (nodeName == "ExternalRouteTag") {
00331 std::string externalRouteTag = (*exElemIt)->getNodeValue();
00332 char externalRouteTagValue[4];
00333
00334 memset(externalRouteTagValue, 0, 4 * sizeof(char));
00335 int externalRouteTagLength = externalRouteTag.length();
00336 if ((externalRouteTagLength > 4) && (externalRouteTagLength <= 10) && (externalRouteTagLength % 2 == 0) && (externalRouteTag[0] == '0') && (externalRouteTag[1] == 'x')) {
00337 for (int i = externalRouteTagLength; (i > 2); i -= 2) {
00338 externalRouteTagValue[(i - 2) / 2] = HexPairToByte(externalRouteTag[i - 1], externalRouteTag[i]);
00339 }
00340 }
00341 asExternalRoute.setExternalRouteTag((externalRouteTagValue[0] << 24) + (externalRouteTagValue[1] << 16) + (externalRouteTagValue[2] << 8) + externalRouteTagValue[3]);
00342 }
00343 }
00344
00345 ospfRouter->UpdateExternalRoute(networkAddress.address, asExternalRoute, ifIndex);
00346 }
00347
00348
00353 void OSPFRouting::LoadHostRoute(const cXMLElement& hostRouteConfig)
00354 {
00355 OSPF::HostRouteParameters hostParameters;
00356 OSPF::AreaID hostArea;
00357
00358 std::string ifName = hostRouteConfig.getAttribute("ifName");
00359 hostParameters.ifIndex = ResolveInterfaceName(ifName);
00360
00361 EV << " loading HostInterface " << ifName << " ifIndex[" << static_cast<short> (hostParameters.ifIndex) << "]\n";
00362
00363 cXMLElementList ifDetails = hostRouteConfig.getChildren();
00364 for (cXMLElementList::iterator hostElemIt = ifDetails.begin(); hostElemIt != ifDetails.end(); hostElemIt++) {
00365 std::string nodeName = (*hostElemIt)->getTagName();
00366 if (nodeName == "AreaID") {
00367 hostArea = ULongFromAddressString((*hostElemIt)->getNodeValue());
00368 }
00369 if (nodeName == "AttachedHost") {
00370 hostParameters.address = IPv4AddressFromAddressString((*hostElemIt)->getNodeValue());
00371 }
00372 if (nodeName == "LinkCost") {
00373 hostParameters.linkCost = atoi((*hostElemIt)->getNodeValue());
00374 }
00375 }
00376
00377 OSPF::Area* area = ospfRouter->GetArea(hostArea);
00378 if (area != NULL) {
00379 area->AddHostRoute(hostParameters);
00380
00381 } else {
00382 error("Loading HostInterface ifIndex[%d] in Area %d aborted", hostParameters.ifIndex, hostArea);
00383 }
00384 }
00385
00386
00391 void OSPFRouting::LoadVirtualLink(const cXMLElement& virtualLinkConfig)
00392 {
00393 OSPF::Interface* intf = new OSPF::Interface;
00394 std::string endPoint = virtualLinkConfig.getAttribute("endPointRouterID");
00395 OSPF::Neighbor* neighbor = new OSPF::Neighbor;
00396
00397 EV << " loading VirtualLink to " << endPoint << "\n";
00398
00399 intf->SetType(OSPF::Interface::Virtual);
00400 neighbor->SetNeighborID(ULongFromAddressString(endPoint.c_str()));
00401 intf->AddNeighbor(neighbor);
00402
00403 cXMLElementList ifDetails = virtualLinkConfig.getChildren();
00404 for (cXMLElementList::iterator ifElemIt = ifDetails.begin(); ifElemIt != ifDetails.end(); ifElemIt++) {
00405 std::string nodeName = (*ifElemIt)->getTagName();
00406 if (nodeName == "TransitAreaID") {
00407 intf->SetTransitAreaID(ULongFromAddressString((*ifElemIt)->getNodeValue()));
00408 }
00409 if (nodeName == "RetransmissionInterval") {
00410 intf->SetRetransmissionInterval(atoi((*ifElemIt)->getNodeValue()));
00411 }
00412 if (nodeName == "InterfaceTransmissionDelay") {
00413 intf->SetTransmissionDelay(atoi((*ifElemIt)->getNodeValue()));
00414 }
00415 if (nodeName == "HelloInterval") {
00416 intf->SetHelloInterval(atoi((*ifElemIt)->getNodeValue()));
00417 }
00418 if (nodeName == "RouterDeadInterval") {
00419 intf->SetRouterDeadInterval(atoi((*ifElemIt)->getNodeValue()));
00420 }
00421 if (nodeName == "AuthenticationType") {
00422 std::string authenticationType = (*ifElemIt)->getNodeValue();
00423 if (authenticationType == "SimplePasswordType") {
00424 intf->SetAuthenticationType(OSPF::SimplePasswordType);
00425 } else if (authenticationType == "CrytographicType") {
00426 intf->SetAuthenticationType(OSPF::CrytographicType);
00427 } else {
00428 intf->SetAuthenticationType(OSPF::NullType);
00429 }
00430 }
00431 if (nodeName == "AuthenticationKey") {
00432 std::string key = (*ifElemIt)->getNodeValue();
00433 OSPF::AuthenticationKeyType keyValue;
00434 memset(keyValue.bytes, 0, 8 * sizeof(char));
00435 int keyLength = key.length();
00436 if ((keyLength > 4) && (keyLength <= 18) && (keyLength % 2 == 0) && (key[0] == '0') && (key[1] == 'x')) {
00437 for (int i = keyLength; (i > 2); i -= 2) {
00438 keyValue.bytes[(i - 2) / 2] = HexPairToByte(key[i - 1], key[i]);
00439 }
00440 }
00441 intf->SetAuthenticationKey(keyValue);
00442 }
00443 }
00444
00445
00446 OSPF::Area* transitArea = ospfRouter->GetArea(intf->GetAreaID());
00447 OSPF::Area* backbone = ospfRouter->GetArea(OSPF::BackboneAreaID);
00448
00449 if ((backbone != NULL) && (transitArea != NULL) && (transitArea->GetExternalRoutingCapability())) {
00450 backbone->AddInterface(intf);
00451 } else {
00452 delete intf;
00453 error("Loading VirtualLink to %s through Area %d aborted", endPoint.c_str(), intf->GetAreaID());
00454 }
00455 }
00456
00457
00464 bool OSPFRouting::LoadConfigFromXML(const char * filename)
00465 {
00466 cXMLElement* asConfig = ev.getXMLDocument(filename);
00467 if (asConfig == NULL) {
00468 error("Cannot read AS configuration from file: %s", filename);
00469 }
00470
00471
00472 std::string routerXPath("Router[@id='");
00473 IPAddress routerId(ospfRouter->GetRouterID());
00474 routerXPath += routerId.str();
00475 routerXPath += "']";
00476
00477 cXMLElement* routerNode = asConfig->getElementByPath(routerXPath.c_str());
00478 if (routerNode == NULL) {
00479 error("No configuration for Router ID: %s", routerId.str().c_str());
00480 }
00481 else {
00482 EV << "OSPFRouting: Loading info for Router id = " << routerId.str() << "\n";
00483 }
00484
00485 if (routerNode->getChildrenByTagName("RFC1583Compatible").size() > 0) {
00486 ospfRouter->SetRFC1583Compatibility(true);
00487 }
00488
00489 std::map<std::string, int> areaList;
00490 GetAreaListFromXML(*routerNode, areaList);
00491
00492
00493 for (std::map<std::string, int>::iterator areaIt = areaList.begin(); areaIt != areaList.end(); areaIt++) {
00494 LoadAreaFromXML(*asConfig, areaIt->first);
00495 }
00496
00497 if ((areaList.size() > 1) && (areaList.find("0.0.0.0") == areaList.end())) {
00498 LoadAreaFromXML(*asConfig, "0.0.0.0");
00499 }
00500
00501
00502 cXMLElementList routerConfig = routerNode->getChildren();
00503 for (cXMLElementList::iterator routerConfigIt = routerConfig.begin(); routerConfigIt != routerConfig.end(); routerConfigIt++) {
00504 std::string nodeName = (*routerConfigIt)->getTagName();
00505 if ((nodeName == "PointToPointInterface") ||
00506 (nodeName == "BroadcastInterface") ||
00507 (nodeName == "NBMAInterface") ||
00508 (nodeName == "PointToMultiPointInterface"))
00509 {
00510 LoadInterfaceParameters(*(*routerConfigIt));
00511 }
00512 if (nodeName == "ExternalInterface") {
00513 LoadExternalRoute(*(*routerConfigIt));
00514 }
00515 if (nodeName == "HostInterface") {
00516 LoadHostRoute(*(*routerConfigIt));
00517 }
00518 if (nodeName == "VirtualLink") {
00519 LoadVirtualLink(*(*routerConfigIt));
00520 }
00521 }
00522 return true;
00523 }