INET Framework for OMNeT++/OMNEST
AnsaOSPFRouting.cc
Go to the documentation of this file.
00001 /*******************************************************************
00002 *
00003 *    This library is free software, you can redistribute it
00004 *    and/or modify
00005 *    it under  the terms of the GNU Lesser General Public License
00006 *    as published by the Free Software Foundation;
00007 *    either version 2 of the License, or any later version.
00008 *    The library is distributed in the hope that it will be useful,
00009 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00011 *    See the GNU Lesser General Public License for more details.
00012 *
00013 *
00014 *********************************************************************/
00015 
00016 #include "AnsaOSPFRouting.h"
00017 #include "IPAddress.h"
00018 #include "IPAddressResolver.h"
00019 #include "IPControlInfo.h"
00020 #include "AnsaOSPFcommon.h"
00021 #include "AnsaOSPFArea.h"
00022 #include "AnsaMessageHandler.h"
00023 #include "RoutingTableAccess.h"
00024 #include "InterfaceTableAccess.h"
00025 #include "IPv4InterfaceData.h"
00026 #include <string>
00027 #include <stdlib.h>
00028 #include <memory.h>
00029 //#include <iostream>
00030 
00031 
00032 Define_Module(AnsaOSPFRouting);
00033 
00034 
00035 AnsaOSPFRouting::AnsaOSPFRouting()
00036 {
00037     ospfRouter = NULL;
00038     ospfEnabled = false;
00039 }
00040 
00045 AnsaOSPFRouting::~AnsaOSPFRouting(void)
00046 {
00047     if(ospfEnabled)
00048       delete ospfRouter;
00049 }
00050 
00051 
00059 void AnsaOSPFRouting::initialize(int stage)
00060 {    if (stage==0)
00061     {
00062         // get a pointer to the NotificationBoard module
00063         nb = NotificationBoardAccess().get();
00064 
00065         // subscribe interface change notifications
00066         nb->subscribe(this, NF_INTERFACE_STATE_CHANGED);
00067 
00068     }
00069     else 
00070       // we have to wait for stage 2 until interfaces get registered(stage 0)
00071       // and routerId gets assigned(stage 3)
00072       if (stage == 4)
00073       {
00074           rt = RoutingTableAccess().get();
00075           ift = InterfaceTableAccess().get();
00076   
00077           // Get routerId
00078           ospfRouter = new AnsaOSPF::Router(rt->getRouterId().getInt(), this);
00079   
00080           // read the OSPF AS configuration
00081           const char *fileName = par("configFile");
00082           
00083           if(par("AnsaLoadingStyle"))
00084           {
00085             if (fileName == NULL || (!strcmp(fileName, "")) || !AnsaLoadConfigFromXML(fileName))
00086               error("Error reading AS configuration from file %s", fileName);
00087           }
00088           else
00089           {
00090             if (fileName == NULL || (!strcmp(fileName, "")) || !LoadConfigFromXML(fileName))
00091               error("Error reading AS configuration from file %s", fileName);
00092           }
00093           if(ospfEnabled)
00094             ospfRouter->AddWatches();
00095       }
00096 }
00097 
00098 
00103 void AnsaOSPFRouting::handleMessage(cMessage *msg)
00104 {
00105 //    if (simulation.getEventNumber() == 90591) {
00106 //        __asm int 3;
00107 //    }
00108 
00109     if(ospfEnabled)
00110       ospfRouter->GetMessageHandler()->MessageReceived(msg);
00111     else
00112       delete msg;
00113 }
00114 
00115 
00116 void AnsaOSPFRouting::receiveChangeNotification(int category, const cPolymorphic *details)
00117 {
00118     if (simulation.getContextType()==CTX_INITIALIZE)
00119         return;  // ignore notifications during initialize
00120     
00121     Enter_Method_Silent();
00122     printNotificationBanner(category, details);
00123     
00124     if (category==NF_INTERFACE_STATE_CHANGED) // change state of notified interface
00125     {        
00126         InterfaceEntry *entry = check_and_cast<InterfaceEntry*>(details);
00127         
00128         AnsaOSPF::Interface* intf = ospfRouter->GetNonVirtualInterface(entry->getInterfaceId());
00129         
00130         if(intf != NULL)
00131         {
00132           EV << "Changing state of interface in OSPF\n";
00133           if (entry->isDown())
00134           { 
00135             intf->ProcessEvent(AnsaOSPF::Interface::InterfaceDown);
00136           }
00137           else
00138           {
00139             intf->ProcessEvent(AnsaOSPF::Interface::InterfaceUp);
00140           }
00141         }
00142     }
00143 
00144 }
00145 
00146 void AnsaOSPFRouting::finish()
00147 {
00148     recordScalar("helloPacketSend", ospfRouter->stat.GetHelloPacketSend());
00149     recordScalar("ospfPacketSend", ospfRouter->stat.GetOspfPacketSend());
00150     recordScalar("helloPacketReceived", ospfRouter->stat.GetHelloPacketReceived());
00151     recordScalar("ospfPacketReceived", ospfRouter->stat.GetOspfPacketReceived());
00152 }
00153 
00157 int AnsaOSPFRouting::ResolveInterfaceName(const std::string& name) const
00158 {
00159     InterfaceEntry* ie = ift->getInterfaceByName(name.c_str());
00160     if (!ie)
00161         opp_error("error reading XML config: IInterfaceTable contains no interface named '%s'", name.c_str());
00162     return ie->getInterfaceId();
00163 }
00164 
00170 void AnsaOSPFRouting::GetAreaListFromXML(const cXMLElement& routerNode, std::map<std::string, int>& areaList) const
00171 {
00172     cXMLElementList routerConfig = routerNode.getChildren();
00173     for (cXMLElementList::iterator routerConfigIt = routerConfig.begin(); routerConfigIt != routerConfig.end(); routerConfigIt++) {
00174         std::string nodeName = (*routerConfigIt)->getTagName();
00175         if ((nodeName == "PointToPointInterface") ||
00176             (nodeName == "BroadcastInterface") ||
00177             (nodeName == "NBMAInterface") ||
00178             (nodeName == "PointToMultiPointInterface"))
00179         {
00180             std::string areaId = (*routerConfigIt)->getChildrenByTagName("AreaID")[0]->getNodeValue();
00181             if (areaList.find(areaId) == areaList.end()) {
00182                 areaList[areaId] = 1;
00183             }
00184         }
00185     }
00186 }
00187 
00188 
00195 void AnsaOSPFRouting::LoadAreaFromXML(const cXMLElement& asConfig, const std::string& areaID)
00196 {
00197     std::string areaXPath("Area[@id='");
00198     areaXPath += areaID;
00199     areaXPath += "']";
00200 
00201     cXMLElement* areaConfig = asConfig.getElementByPath(areaXPath.c_str());
00202     if (areaConfig == NULL) {
00203         error("No configuration for Area ID: %s", areaID.c_str());
00204     }
00205     else {
00206         EV << "    loading info for Area id = " << areaID << "\n";
00207     }
00208 
00209     AnsaOSPF::Area* area = new AnsaOSPF::Area(ULongFromAddressString(areaID.c_str()));
00210 
00211     cXMLElementList areaDetails = areaConfig->getChildren();
00212     for (cXMLElementList::iterator arIt = areaDetails.begin(); arIt != areaDetails.end(); arIt++) {
00213         std::string nodeName = (*arIt)->getTagName();
00214         if (nodeName == "AddressRange") {
00215             AnsaOSPF::IPv4AddressRange addressRange;
00216             addressRange.address = IPv4AddressFromAddressString((*arIt)->getChildrenByTagName("Address")[0]->getNodeValue());
00217             addressRange.mask = IPv4AddressFromAddressString((*arIt)->getChildrenByTagName("Mask")[0]->getNodeValue());
00218             std::string status = (*arIt)->getChildrenByTagName("Status")[0]->getNodeValue();
00219             if (status == "Advertise") {
00220                 area->AddAddressRange(addressRange, true);
00221             } else {
00222                 area->AddAddressRange(addressRange, false);
00223             }
00224         }
00225         if ((nodeName == "Stub") && (areaID != "0.0.0.0")) {    // the backbone cannot be configured as a stub
00226             area->SetExternalRoutingCapability(false);
00227             area->SetStubDefaultCost(atoi((*arIt)->getChildrenByTagName("DefaultCost")[0]->getNodeValue()));
00228         }
00229     }
00230     // Add the Area to the router
00231     ospfRouter->AddArea(area);
00232 }
00233 
00234 
00240 void AnsaOSPFRouting::LoadInterfaceParameters(const cXMLElement& ifConfig)
00241 {
00242     AnsaOSPF::Interface* intf          = new AnsaOSPF::Interface;
00243     std::string      ifName        = ifConfig.getAttribute("ifName");
00244     int              ifIndex       = ResolveInterfaceName(ifName);
00245     std::string      interfaceType = ifConfig.getTagName();
00246 
00247     EV << "        loading " << interfaceType << " " << ifName << " ifIndex[" << ifIndex << "]\n";
00248 
00249     intf->SetIfIndex(ifIndex);
00250     if (interfaceType == "PointToPointInterface") {
00251         intf->SetType(AnsaOSPF::Interface::PointToPoint);
00252     } else if (interfaceType == "BroadcastInterface") {
00253         intf->SetType(AnsaOSPF::Interface::Broadcast);
00254     } else if (interfaceType == "NBMAInterface") {
00255         intf->SetType(AnsaOSPF::Interface::NBMA);
00256     } else if (interfaceType == "PointToMultiPointInterface") {
00257         intf->SetType(AnsaOSPF::Interface::PointToMultiPoint);
00258     } else {
00259         delete intf;
00260         error("Loading %s ifIndex[%d] aborted", interfaceType.c_str(), ifIndex);
00261     }
00262 
00263     AnsaOSPF::AreaID    areaID    = 0;
00264     cXMLElementList ifDetails = ifConfig.getChildren();
00265 
00266     for (cXMLElementList::iterator ifElemIt = ifDetails.begin(); ifElemIt != ifDetails.end(); ifElemIt++) {
00267         std::string nodeName = (*ifElemIt)->getTagName();
00268         if (nodeName == "AreaID") {
00269             areaID = ULongFromAddressString((*ifElemIt)->getNodeValue());
00270             intf->SetAreaID(areaID);
00271         }
00272         if (nodeName == "InterfaceOutputCost") {
00273             intf->SetOutputCost(atoi((*ifElemIt)->getNodeValue()));
00274         }
00275         if (nodeName == "RetransmissionInterval") {
00276             intf->SetRetransmissionInterval(atoi((*ifElemIt)->getNodeValue()));
00277         }
00278         if (nodeName == "InterfaceTransmissionDelay") {
00279             intf->SetTransmissionDelay(atoi((*ifElemIt)->getNodeValue()));
00280         }
00281         if (nodeName == "RouterPriority") {
00282             intf->SetRouterPriority(atoi((*ifElemIt)->getNodeValue()));
00283         }
00284         if (nodeName == "HelloInterval") {
00285             intf->SetHelloInterval(atoi((*ifElemIt)->getNodeValue()));
00286         }
00287         if (nodeName == "RouterDeadInterval") {
00288             intf->SetRouterDeadInterval(atoi((*ifElemIt)->getNodeValue()));
00289         }
00290         if (nodeName == "AuthenticationType") {
00291             std::string authenticationType = (*ifElemIt)->getNodeValue();
00292             if (authenticationType == "SimplePasswordType") {
00293                 intf->SetAuthenticationType(AnsaOSPF::SimplePasswordType);
00294             } else if (authenticationType == "CrytographicType") {
00295                 intf->SetAuthenticationType(AnsaOSPF::CrytographicType);
00296             } else {
00297                 intf->SetAuthenticationType(AnsaOSPF::NullType);
00298             }
00299         }
00300         if (nodeName == "AuthenticationKey") {
00301             std::string key = (*ifElemIt)->getNodeValue();
00302             AnsaOSPF::AuthenticationKeyType keyValue;
00303             memset(keyValue.bytes, 0, 8 * sizeof(char));
00304             int keyLength = key.length();
00305             if ((keyLength > 4) && (keyLength <= 18) && (keyLength % 2 == 0) && (key[0] == '0') && (key[1] == 'x')) {
00306                 for (int i = keyLength; (i > 2); i -= 2) {
00307                     keyValue.bytes[(i - 2) / 2] = HexPairToByte(key[i - 1], key[i]);
00308                 }
00309             }
00310             intf->SetAuthenticationKey(keyValue);
00311         }
00312         if (nodeName == "PollInterval") {
00313             intf->SetPollInterval(atoi((*ifElemIt)->getNodeValue()));
00314         }
00315         if ((interfaceType == "NBMAInterface") && (nodeName == "NBMANeighborList")) {
00316             cXMLElementList neighborList = (*ifElemIt)->getChildren();
00317             for (cXMLElementList::iterator neighborIt = neighborList.begin(); neighborIt != neighborList.end(); neighborIt++) {
00318                 std::string neighborNodeName = (*neighborIt)->getTagName();
00319                 if (neighborNodeName == "NBMANeighbor") {
00320                     AnsaOSPF::Neighbor* neighbor = new AnsaOSPF::Neighbor;
00321                     neighbor->SetAddress(IPv4AddressFromAddressString((*neighborIt)->getChildrenByTagName("NetworkInterfaceAddress")[0]->getNodeValue()));
00322                     neighbor->SetPriority(atoi((*neighborIt)->getChildrenByTagName("NeighborPriority")[0]->getNodeValue()));
00323                     intf->AddNeighbor(neighbor);
00324                 }
00325             }
00326         }
00327         if ((interfaceType == "PointToMultiPointInterface") && (nodeName == "PointToMultiPointNeighborList")) {
00328             cXMLElementList neighborList = (*ifElemIt)->getChildren();
00329             for (cXMLElementList::iterator neighborIt = neighborList.begin(); neighborIt != neighborList.end(); neighborIt++) {
00330                 std::string neighborNodeName = (*neighborIt)->getTagName();
00331                 if (neighborNodeName == "PointToMultiPointNeighbor") {
00332                     AnsaOSPF::Neighbor* neighbor = new AnsaOSPF::Neighbor;
00333                     neighbor->SetAddress(IPv4AddressFromAddressString((*neighborIt)->getNodeValue()));
00334                     intf->AddNeighbor(neighbor);
00335                 }
00336             }
00337         }
00338 
00339     }
00340     // add the interface to it's Area
00341     AnsaOSPF::Area* area = ospfRouter->GetArea(areaID);
00342     if (area != NULL) {
00343         area->AddInterface(intf);
00344         intf->ProcessEvent(AnsaOSPF::Interface::InterfaceUp); // notification should come from the blackboard...
00345     } else {
00346         delete intf;
00347         error("Loading %s ifIndex[%d] in Area %d aborted", interfaceType.c_str(), ifIndex, areaID);
00348     }
00349 }
00350 
00351 
00356 void AnsaOSPFRouting::LoadExternalRoute(const cXMLElement& externalRouteConfig)
00357 {
00358     std::string               ifName  = externalRouteConfig.getAttribute("ifName");
00359     int                       ifIndex = ResolveInterfaceName(ifName);
00360     OSPFASExternalLSAContents asExternalRoute;
00361     AnsaOSPF::RoutingTableEntry   externalRoutingEntry; // only used here to keep the path cost calculation in one place
00362     AnsaOSPF::IPv4AddressRange    networkAddress;
00363 
00364     EV << "        loading ExternalInterface " << ifName << " ifIndex[" << ifIndex << "]\n";
00365 
00366     cXMLElementList ifDetails = externalRouteConfig.getChildren();
00367     for (cXMLElementList::iterator exElemIt = ifDetails.begin(); exElemIt != ifDetails.end(); exElemIt++) {
00368         std::string nodeName = (*exElemIt)->getTagName();
00369         if (nodeName == "AdvertisedExternalNetwork") {
00370             networkAddress.address = IPv4AddressFromAddressString((*exElemIt)->getChildrenByTagName("Address")[0]->getNodeValue());
00371             networkAddress.mask    = IPv4AddressFromAddressString((*exElemIt)->getChildrenByTagName("Mask")[0]->getNodeValue());
00372             asExternalRoute.setNetworkMask(ULongFromIPv4Address(networkAddress.mask));
00373         }
00374         if (nodeName == "ExternalInterfaceOutputParameters") {
00375             std::string metricType = (*exElemIt)->getChildrenByTagName("ExternalInterfaceOutputType")[0]->getNodeValue();
00376             int         routeCost  = atoi((*exElemIt)->getChildrenByTagName("ExternalInterfaceOutputCost")[0]->getNodeValue());
00377 
00378             asExternalRoute.setRouteCost(routeCost);
00379             if (metricType == "Type2") {
00380                 asExternalRoute.setE_ExternalMetricType(true);
00381                 externalRoutingEntry.SetType2Cost(routeCost);
00382                 externalRoutingEntry.SetPathType(AnsaOSPF::RoutingTableEntry::Type2External);
00383             } else {
00384                 asExternalRoute.setE_ExternalMetricType(false);
00385                 externalRoutingEntry.SetCost(routeCost);
00386                 externalRoutingEntry.SetPathType(AnsaOSPF::RoutingTableEntry::Type1External);
00387             }
00388         }
00389         if (nodeName == "ForwardingAddress") {
00390             asExternalRoute.setForwardingAddress(ULongFromAddressString((*exElemIt)->getNodeValue()));
00391         }
00392         if (nodeName == "ExternalRouteTag") {
00393             std::string externalRouteTag = (*exElemIt)->getNodeValue();
00394             char        externalRouteTagValue[4];
00395 
00396             memset(externalRouteTagValue, 0, 4 * sizeof(char));
00397             int externalRouteTagLength = externalRouteTag.length();
00398             if ((externalRouteTagLength > 4) && (externalRouteTagLength <= 10) && (externalRouteTagLength % 2 == 0) && (externalRouteTag[0] == '0') && (externalRouteTag[1] == 'x')) {
00399                 for (int i = externalRouteTagLength; (i > 2); i -= 2) {
00400                     externalRouteTagValue[(i - 2) / 2] = HexPairToByte(externalRouteTag[i - 1], externalRouteTag[i]);
00401                 }
00402             }
00403             asExternalRoute.setExternalRouteTag((externalRouteTagValue[0] << 24) + (externalRouteTagValue[1] << 16) + (externalRouteTagValue[2] << 8) + externalRouteTagValue[3]);
00404         }
00405     }
00406     // add the external route to the OSPF datastructure
00407     ospfRouter->UpdateExternalRoute(networkAddress.address, asExternalRoute, ifIndex);
00408 }
00409 
00410 
00415 void AnsaOSPFRouting::LoadHostRoute(const cXMLElement& hostRouteConfig)
00416 {
00417     AnsaOSPF::HostRouteParameters hostParameters;
00418     AnsaOSPF::AreaID              hostArea;
00419 
00420     std::string ifName = hostRouteConfig.getAttribute("ifName");
00421     hostParameters.ifIndex = ResolveInterfaceName(ifName);
00422 
00423     EV << "        loading HostInterface " << ifName << " ifIndex[" << static_cast<short> (hostParameters.ifIndex) << "]\n";
00424 
00425     cXMLElementList ifDetails = hostRouteConfig.getChildren();
00426     for (cXMLElementList::iterator hostElemIt = ifDetails.begin(); hostElemIt != ifDetails.end(); hostElemIt++) {
00427         std::string nodeName = (*hostElemIt)->getTagName();
00428         if (nodeName == "AreaID") {
00429             hostArea = ULongFromAddressString((*hostElemIt)->getNodeValue());
00430         }
00431         if (nodeName == "AttachedHost") {
00432             hostParameters.address = IPv4AddressFromAddressString((*hostElemIt)->getNodeValue());
00433         }
00434         if (nodeName == "LinkCost") {
00435             hostParameters.linkCost = atoi((*hostElemIt)->getNodeValue());
00436         }
00437     }
00438     // add the host route to the OSPF datastructure.
00439     AnsaOSPF::Area* area = ospfRouter->GetArea(hostArea);
00440     if (area != NULL) {
00441         area->AddHostRoute(hostParameters);
00442 
00443     } else {
00444         error("Loading HostInterface ifIndex[%d] in Area %d aborted", hostParameters.ifIndex, hostArea);
00445     }
00446 }
00447 
00448 
00453 void AnsaOSPFRouting::LoadVirtualLink(const cXMLElement& virtualLinkConfig)
00454 {
00455     AnsaOSPF::Interface* intf     = new AnsaOSPF::Interface;
00456     std::string      endPoint = virtualLinkConfig.getAttribute("endPointRouterID");
00457     AnsaOSPF::Neighbor*  neighbor = new AnsaOSPF::Neighbor;
00458 
00459     EV << "        loading VirtualLink to " << endPoint << "\n";
00460 
00461     intf->SetType(AnsaOSPF::Interface::Virtual);
00462     neighbor->SetNeighborID(ULongFromAddressString(endPoint.c_str()));
00463     intf->AddNeighbor(neighbor);
00464 
00465     cXMLElementList ifDetails = virtualLinkConfig.getChildren();
00466     for (cXMLElementList::iterator ifElemIt = ifDetails.begin(); ifElemIt != ifDetails.end(); ifElemIt++) {
00467         std::string nodeName = (*ifElemIt)->getTagName();
00468         if (nodeName == "TransitAreaID") {
00469             intf->SetTransitAreaID(ULongFromAddressString((*ifElemIt)->getNodeValue()));
00470         }
00471         if (nodeName == "RetransmissionInterval") {
00472             intf->SetRetransmissionInterval(atoi((*ifElemIt)->getNodeValue()));
00473         }
00474         if (nodeName == "InterfaceTransmissionDelay") {
00475             intf->SetTransmissionDelay(atoi((*ifElemIt)->getNodeValue()));
00476         }
00477         if (nodeName == "HelloInterval") {
00478             intf->SetHelloInterval(atoi((*ifElemIt)->getNodeValue()));
00479         }
00480         if (nodeName == "RouterDeadInterval") {
00481             intf->SetRouterDeadInterval(atoi((*ifElemIt)->getNodeValue()));
00482         }
00483         if (nodeName == "AuthenticationType") {
00484             std::string authenticationType = (*ifElemIt)->getNodeValue();
00485             if (authenticationType == "SimplePasswordType") {
00486                 intf->SetAuthenticationType(AnsaOSPF::SimplePasswordType);
00487             } else if (authenticationType == "CrytographicType") {
00488                 intf->SetAuthenticationType(AnsaOSPF::CrytographicType);
00489             } else {
00490                 intf->SetAuthenticationType(AnsaOSPF::NullType);
00491             }
00492         }
00493         if (nodeName == "AuthenticationKey") {
00494             std::string key = (*ifElemIt)->getNodeValue();
00495             AnsaOSPF::AuthenticationKeyType keyValue;
00496             memset(keyValue.bytes, 0, 8 * sizeof(char));
00497             int keyLength = key.length();
00498             if ((keyLength > 4) && (keyLength <= 18) && (keyLength % 2 == 0) && (key[0] == '0') && (key[1] == 'x')) {
00499                 for (int i = keyLength; (i > 2); i -= 2) {
00500                     keyValue.bytes[(i - 2) / 2] = HexPairToByte(key[i - 1], key[i]);
00501                 }
00502             }
00503             intf->SetAuthenticationKey(keyValue);
00504         }
00505     }
00506 
00507     // add the virtual link to the OSPF datastructure.
00508     AnsaOSPF::Area* transitArea = ospfRouter->GetArea(intf->GetAreaID());
00509     AnsaOSPF::Area* backbone    = ospfRouter->GetArea(AnsaOSPF::BackboneAreaID);
00510 
00511     if ((backbone != NULL) && (transitArea != NULL) && (transitArea->GetExternalRoutingCapability())) {
00512         backbone->AddInterface(intf);
00513     } else {
00514         delete intf;
00515         error("Loading VirtualLink to %s through Area %d aborted", endPoint.c_str(), intf->GetAreaID());
00516     }
00517 }
00518 
00519 
00526 bool AnsaOSPFRouting::LoadConfigFromXML(const char * filename)
00527 {
00528     cXMLElement* asConfig = ev.getXMLDocument(filename);
00529     if (asConfig == NULL) {
00530         error("Cannot read AS configuration from file: %s", filename);
00531     }
00532 
00533     // load information on this router
00534     std::string routerXPath("Router[@id='");
00535     IPAddress routerId(ospfRouter->GetRouterID());
00536     routerXPath += routerId.str();
00537     routerXPath += "']";
00538 
00539     cXMLElement* routerNode = asConfig->getElementByPath(routerXPath.c_str());
00540     if (routerNode == NULL) {
00541         error("No configuration for Router ID: %s", routerId.str().c_str());
00542     }
00543     else {
00544         EV << "OSPFRouting: Loading info for Router id = " << routerId.str() << "\n";
00545     }
00546 
00547     if (routerNode->getChildrenByTagName("RFC1583Compatible").size() > 0) {
00548         ospfRouter->SetRFC1583Compatibility(true);
00549     }
00550 
00551     std::map<std::string, int> areaList;
00552     GetAreaListFromXML(*routerNode, areaList);
00553 
00554     // load area information
00555     for (std::map<std::string, int>::iterator areaIt = areaList.begin(); areaIt != areaList.end(); areaIt++) {
00556         LoadAreaFromXML(*asConfig, areaIt->first);
00557     }
00558     // if the router is an area border router then it MUST be part of the backbone(area 0)
00559     if ((areaList.size() > 1) && (areaList.find("0.0.0.0") == areaList.end())) {
00560         LoadAreaFromXML(*asConfig, "0.0.0.0");
00561     }
00562 
00563     // load interface information
00564     cXMLElementList routerConfig = routerNode->getChildren();
00565     for (cXMLElementList::iterator routerConfigIt = routerConfig.begin(); routerConfigIt != routerConfig.end(); routerConfigIt++) {
00566         std::string nodeName = (*routerConfigIt)->getTagName();
00567         if ((nodeName == "PointToPointInterface") ||
00568             (nodeName == "BroadcastInterface") ||
00569             (nodeName == "NBMAInterface") ||
00570             (nodeName == "PointToMultiPointInterface"))
00571         {
00572             LoadInterfaceParameters(*(*routerConfigIt));
00573         }
00574         if (nodeName == "ExternalInterface") {
00575             LoadExternalRoute(*(*routerConfigIt));
00576         }
00577         if (nodeName == "HostInterface") {
00578             LoadHostRoute(*(*routerConfigIt));
00579         }
00580         if (nodeName == "VirtualLink") {
00581             LoadVirtualLink(*(*routerConfigIt));
00582         }
00583     }
00584     return true;
00585 }
00586 
00592 void AnsaOSPFRouting::AnsaLoadInterface(AnsaOSPF::Area &area, AnsaOSPF::IPv4AddressRange &addressRange)
00593 {
00594         
00595   cXMLElementList intConfig = IntNode->getChildren();
00596   for (cXMLElementList::iterator intConfigIt = intConfig.begin(); intConfigIt != intConfig.end(); intConfigIt++)
00597   {
00598     std::string nodeName = (*intConfigIt)->getTagName();
00599     if (nodeName == "Interface" && (*intConfigIt)->getAttribute("name"))
00600     {
00601       AnsaOSPF::IPv4Address ifAddress = IPv4AddressFromAddressString((*intConfigIt)->getFirstChildWithTag("IPAddress")->getNodeValue());
00602       if((ifAddress != AnsaOSPF::NullIPv4Address) && ((ifAddress & addressRange.mask) == (addressRange.address & addressRange.mask)))
00603       {
00604         AnsaOSPF::IPv4AddressRange  ifAddressRange;
00605         std::string                 ifName        = (*intConfigIt)->getAttribute("name");
00606         int                         ifIndex       = ResolveInterfaceName(ifName);
00607         
00608         std::map<int, AnsaOSPF::AreaID>::iterator ifIt = ifToAreaList.find(ifIndex);
00609         if (ifIt != ifToAreaList.end())
00610         {
00611           if(ifIt->second == area.GetAreaID())
00612             return;
00613           else
00614             error("OSPFRouting: Loading interface %s ifIndex[%d] aborted - Can not be in multiple areas!!!", ifName.c_str(), ifIndex);
00615         }
00616         
00617         InterfaceEntry* ie = ift->getInterfaceById(ifIndex);
00618         
00619         AnsaOSPF::Interface*  intf = new AnsaOSPF::Interface;
00620         intf->SetIfIndex(ifIndex);
00621         intf->SetAreaID(area.GetAreaID());
00622         
00623         if(ie->isPointToPoint())
00624         {
00625           intf->SetType(AnsaOSPF::Interface::PointToPoint);
00626           intf->SetRouterPriority(0);
00627         } else if(ie->isBroadcast())
00628             {
00629               intf->SetType(AnsaOSPF::Interface::Broadcast);
00630             }
00631 
00632         double datarate = ie->getDatarate();
00633         if (datarate > 0.0)
00634             intf->SetOutputCost((int)(100000000.0/datarate));
00635 
00636         EV << "        loading " << ifName << " ifIndex[" << ifIndex << "]\n";
00637         
00638         cXMLElementList ifDetails = (*intConfigIt)->getChildren();
00639         for (cXMLElementList::iterator ifElemIt = ifDetails.begin(); ifElemIt != ifDetails.end(); ifElemIt++) 
00640         {
00641             std::string nodeName = (*ifElemIt)->getTagName();
00642             if (nodeName == "Mask") {
00643                 ifAddressRange.mask = IPv4AddressFromAddressString((*ifElemIt)->getNodeValue());
00644                 ifAddressRange.address = ifAddress & ifAddressRange.mask;
00645             }
00646             if (nodeName == "OspfNetworkType") {
00647                 std::string interfaceType = (*ifElemIt)->getNodeValue();
00648                 if (interfaceType == "point-to-point") {
00649                     intf->SetType(AnsaOSPF::Interface::PointToPoint);
00650                     intf->SetRouterPriority(0);
00651                 } else if (interfaceType == "broadcast") {
00652                     intf->SetType(AnsaOSPF::Interface::Broadcast);
00653                 } else if (interfaceType == "non-broadcast") {
00654                     intf->SetType(AnsaOSPF::Interface::NBMA);
00655                 } else if (interfaceType == "point-to-multipoint") {
00656                     intf->SetType(AnsaOSPF::Interface::PointToMultiPoint);
00657                 } else {
00658                     delete intf;
00659                     error("Loading %s ifIndex[%d] aborted", interfaceType.c_str(), ifIndex);
00660                 }
00661             }
00662             if (nodeName == "OspfCost") {
00663                 intf->SetOutputCost(atoi((*ifElemIt)->getNodeValue()));
00664             }
00665             if (nodeName == "OspfRetransmissionInterval") {
00666                 intf->SetRetransmissionInterval(atoi((*ifElemIt)->getNodeValue()));
00667             }
00668             if (nodeName == "OspfInterfaceTransmissionDelay") {
00669                 intf->SetTransmissionDelay(atoi((*ifElemIt)->getNodeValue()));
00670             }
00671             if (nodeName == "OspfPriority") {
00672                 intf->SetRouterPriority(atoi((*ifElemIt)->getNodeValue()));
00673             }
00674             if (nodeName == "OspfHelloInterval") {
00675                 intf->SetHelloInterval(atoi((*ifElemIt)->getNodeValue()));
00676             }
00677             if (nodeName == "OspfDeadInterval") {
00678                 intf->SetRouterDeadInterval(atoi((*ifElemIt)->getNodeValue()));
00679             }
00680             if (nodeName == "OspfAuthenticationType") {
00681                 std::string authenticationType = (*ifElemIt)->getNodeValue();
00682                 if (authenticationType == "ClearText") {
00683                     intf->SetAuthenticationType(AnsaOSPF::SimplePasswordType);
00684                 } else if (authenticationType == "MessageDigest") {
00685                     intf->SetAuthenticationType(AnsaOSPF::CrytographicType);
00686                 } else {
00687                     intf->SetAuthenticationType(AnsaOSPF::NullType);
00688                 }
00689             }
00690             if (nodeName == "OspfAuthenticationKey") {
00691                 std::string key = (*ifElemIt)->getNodeValue();
00692                 AnsaOSPF::AuthenticationKeyType keyValue;
00693                 memset(keyValue.bytes, 0, 8 * sizeof(char));
00694                 int keyLength = key.length();
00695                 if ((keyLength > 4) && (keyLength <= 18) && (keyLength % 2 == 0) && (key[0] == '0') && (key[1] == 'x')) {
00696                     for (int i = keyLength; (i > 2); i -= 2) {
00697                         keyValue.bytes[(i - 2) / 2] = HexPairToByte(key[i - 1], key[i]);
00698                     }
00699                 }
00700                 intf->SetAuthenticationKey(keyValue);
00701             }
00702             if (nodeName == "OspfPollInterval") {
00703                 intf->SetPollInterval(atoi((*ifElemIt)->getNodeValue()));
00704             }
00705         }
00706         
00707         area.AddAddressRange(ifAddressRange, true);
00708         area.AddInterface(intf);
00709         ifToAreaList[ifIndex] = area.GetAreaID();
00710         
00711         IPv4InterfaceData::IPAddressVector mcg = ie->ipv4Data()->getMulticastGroups();
00712 
00713         mcg.push_back(IPAddress("224.0.0.5"));
00714         if(intf->GetType() == AnsaOSPF::Interface::Broadcast)
00715             mcg.push_back(IPAddress("224.0.0.6"));
00716         ie->ipv4Data()->setMulticastGroups(mcg);
00717       }
00718     }     
00719   }
00720 }
00721 
00727 void AnsaOSPFRouting::AnsaLoadArea(const cXMLElement& areaConfig)
00728 {
00729     std::string idString = areaConfig.getAttribute("id");
00730     AnsaOSPF::AreaID    areaID = ULongFromAddressString(idString.c_str());
00731     
00732     if (areaID == AnsaOSPF::BackboneAreaID && idString != "0.0.0.0")
00733       error("Wrong format of  area ID: %s", idString.c_str());
00734     else
00735       EV << "    loading info for Area id = " << idString << "\n";
00736 
00737     AnsaOSPF::Area* area = new AnsaOSPF::Area(areaID);
00738     
00739     
00740     // load interfaces into area
00741     cXMLElementList networkConfig = areaConfig.getFirstChildWithTag("Networks")->getChildren();
00742     for (cXMLElementList::iterator networkConfigIt = networkConfig.begin(); networkConfigIt != networkConfig.end(); networkConfigIt++)
00743     {
00744       std::string nodeName = (*networkConfigIt)->getTagName();
00745       if (nodeName == "Network")
00746       {
00747         AnsaOSPF::IPv4AddressRange addressRange;
00748         addressRange.address = IPv4AddressFromAddressString((*networkConfigIt)->getFirstChildWithTag("IPAddress")->getNodeValue());
00749         addressRange.mask = ~IPv4AddressFromAddressString((*networkConfigIt)->getFirstChildWithTag("Wildcard")->getNodeValue());
00750         
00751         AnsaLoadInterface(*area, addressRange);
00752       }
00753     }
00754     
00755     if (areaConfig.getChildrenByTagName("Stub").size() > 0 && (areaID != AnsaOSPF::BackboneAreaID)) {    // the backbone cannot be configured as a stub
00756       area->SetExternalRoutingCapability(false);
00757       cXMLElement* defaultCost = areaConfig.getFirstChildWithTag("DefaultCost");
00758       if(defaultCost != NULL)
00759         area->SetStubDefaultCost(atoi(defaultCost->getNodeValue()));
00760       else
00761         area->SetStubDefaultCost(1);
00762     }
00763     
00764     ospfRouter->AddArea(area);
00765 
00766 /*
00767     cXMLElementList areaNetworks = areaConfig->getChildren();
00768     for (cXMLElementList::iterator arIt = areaDetails.begin(); arIt != areaDetails.end(); arIt++) {
00769         std::string nodeName = (*arIt)->getTagName();
00770         if (nodeName == "AddressRange") {
00771             AnsaOSPF::IPv4AddressRange addressRange;
00772             addressRange.address = IPv4AddressFromAddressString((*arIt)->getChildrenByTagName("Address")[0]->getNodeValue());
00773             addressRange.mask = IPv4AddressFromAddressString((*arIt)->getChildrenByTagName("Mask")[0]->getNodeValue());
00774             std::string status = (*arIt)->getChildrenByTagName("Status")[0]->getNodeValue();
00775             if (status == "Advertise") {
00776                 area->AddAddressRange(addressRange, true);
00777             } else {
00778                 area->AddAddressRange(addressRange, false);
00779             }
00780         }
00781         if ((nodeName == "Stub") && (areaID != "0.0.0.0")) {    // the backbone cannot be configured as a stub
00782             area->SetExternalRoutingCapability(false);
00783             area->SetStubDefaultCost(atoi((*arIt)->getChildrenByTagName("DefaultCost")[0]->getNodeValue()));
00784         }
00785     }
00786     // Add the Area to the router
00787     ospfRouter->AddArea(area);
00788 */
00789 }
00790 
00791 
00798 bool AnsaOSPFRouting::AnsaLoadConfigFromXML(const char * filename)
00799 {
00800     cXMLElement* asConfig = ev.getXMLDocument(filename);
00801     if (asConfig == NULL) {
00802         error("Cannot read OSPF configuration from file: %s", filename);
00803     }
00804 
00805     // load information on this router
00806     std::string routerXPath("Router[@id='");
00807     IPAddress routerId(ospfRouter->GetRouterID());
00808     routerXPath += routerId.str();
00809     routerXPath += "']";
00810 
00811     cXMLElement* routerNode = asConfig->getElementByPath(routerXPath.c_str());
00812     if (routerNode == NULL)
00813         error("No configuration for Router ID: %s", routerId.str().c_str());
00814 
00815     cXMLElement* routingNode = routerNode->getFirstChildWithTag("Routing");
00816 
00817     if (routingNode != NULL){
00818         IntNode = routerNode->getFirstChildWithTag("Interfaces");
00819         OspfNode = routingNode->getFirstChildWithTag("Ospf");
00820     }
00821     
00822     if (routingNode == NULL || OspfNode == NULL || IntNode == NULL) {
00823         EV << "OSPFRouting: OSPF is not enabled on Router id = " << routerId.str() << "\n";
00824         return true;
00825     }
00826     else {
00827         ospfEnabled = true;
00828         EV << "OSPFRouting: Loading info for Router id = " << routerId.str() << "\n";
00829     }
00830     
00831     if (OspfNode->getChildrenByTagName("RFC1583Compatible").size() > 0) {
00832         ospfRouter->SetRFC1583Compatibility(true);
00833     }
00834     
00835     // load areas information
00836     cXMLElementList areasConfig = OspfNode->getFirstChildWithTag("Areas")->getChildren();
00837     for (cXMLElementList::iterator areaConfigIt = areasConfig.begin(); areaConfigIt != areasConfig.end(); areaConfigIt++)
00838     {
00839       std::string nodeName = (*areaConfigIt)->getTagName();
00840       if (nodeName == "Area" && (*areaConfigIt)->getAttribute("id"))
00841         AnsaLoadArea(*(*areaConfigIt));
00842     }
00843     
00844     // starts OSPF on interfaces
00845     for (std::map<int, AnsaOSPF::AreaID>::iterator ifMapIt = ifToAreaList.begin(); ifMapIt != ifToAreaList.end(); ifMapIt++) {
00846         ospfRouter->GetArea(ifMapIt->second)->GetInterface(ifMapIt->first)->ProcessEvent(AnsaOSPF::Interface::InterfaceUp);;
00847     }
00848 
00849 
00850 /*
00851 
00852     std::map<std::string, int> areaList;
00853     GetAreaListFromXML(*routerNode, areaList);
00854 
00855     // load area information
00856     for (std::map<std::string, int>::iterator areaIt = areaList.begin(); areaIt != areaList.end(); areaIt++) {
00857         LoadAreaFromXML(*asConfig, areaIt->first);
00858     }
00859     // if the router is an area border router then it MUST be part of the backbone(area 0)
00860     if ((areaList.size() > 1) && (areaList.find("0.0.0.0") == areaList.end())) {
00861         LoadAreaFromXML(*asConfig, "0.0.0.0");
00862     }
00863 
00864     // load interface information
00865     cXMLElementList routerConfig = routerNode->getChildren();
00866     for (cXMLElementList::iterator routerConfigIt = routerConfig.begin(); routerConfigIt != routerConfig.end(); routerConfigIt++) {
00867         std::string nodeName = (*routerConfigIt)->getTagName();
00868         if ((nodeName == "PointToPointInterface") ||
00869             (nodeName == "BroadcastInterface") ||
00870             (nodeName == "NBMAInterface") ||
00871             (nodeName == "PointToMultiPointInterface"))
00872         {
00873             LoadInterfaceParameters(*(*routerConfigIt));
00874         }
00875         if (nodeName == "ExternalInterface") {
00876             LoadExternalRoute(*(*routerConfigIt));
00877         }
00878         if (nodeName == "HostInterface") {
00879             LoadHostRoute(*(*routerConfigIt));
00880         }
00881         if (nodeName == "VirtualLink") {
00882             LoadVirtualLink(*(*routerConfigIt));
00883         }
00884     }
00885     */
00886     return true;
00887 }