MessageHandler.cc

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2006 Andras Babos and Andras Varga
00003 //
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU Lesser General Public License
00015 // along with this program; if not, see <http://www.gnu.org/licenses/>.
00016 //
00017 
00018 #include "MessageHandler.h"
00019 #include "OSPFRouter.h"
00020 
00021 OSPF::MessageHandler::MessageHandler(OSPF::Router* containingRouter, cSimpleModule* containingModule) :
00022     OSPF::IMessageHandler(containingRouter),
00023     ospfModule(containingModule),
00024     helloHandler(containingRouter),
00025     ddHandler(containingRouter),
00026     lsRequestHandler(containingRouter),
00027     lsUpdateHandler(containingRouter),
00028     lsAckHandler(containingRouter)
00029 {
00030 }
00031 
00032 void OSPF::MessageHandler::MessageReceived(cMessage* message)
00033 {
00034     if (message->isSelfMessage()) {
00035         HandleTimer(check_and_cast<OSPFTimer*> (message));
00036     } else {
00037         OSPFPacket* packet = check_and_cast<OSPFPacket*> (message);
00038         EV << "Received packet: (" << packet->getClassName() << ")" << packet->getName() << "\n";
00039         if (packet->getRouterID() == router->GetRouterID()) {
00040             EV << "This packet is from ourselves, discarding.\n";
00041             delete message;
00042         } else {
00043             ProcessPacket(packet);
00044         }
00045     }
00046 }
00047 
00048 void OSPF::MessageHandler::HandleTimer(OSPFTimer* timer)
00049 {
00050     switch (timer->getTimerKind()) {
00051         case InterfaceHelloTimer:
00052             {
00053                 OSPF::Interface* intf;
00054                 if (! (intf = reinterpret_cast <OSPF::Interface*> (timer->getContextPointer()))) {
00055                     // should not reach this point
00056                     EV << "Discarding invalid InterfaceHelloTimer.\n";
00057                     delete timer;
00058                 } else {
00059                     PrintEvent("Hello Timer expired", intf);
00060                     intf->ProcessEvent(OSPF::Interface::HelloTimer);
00061                 }
00062             }
00063             break;
00064         case InterfaceWaitTimer:
00065             {
00066                 OSPF::Interface* intf;
00067                 if (! (intf = reinterpret_cast <OSPF::Interface*> (timer->getContextPointer()))) {
00068                     // should not reach this point
00069                     EV << "Discarding invalid InterfaceWaitTimer.\n";
00070                     delete timer;
00071                 } else {
00072                     PrintEvent("Wait Timer expired", intf);
00073                     intf->ProcessEvent(OSPF::Interface::WaitTimer);
00074                 }
00075             }
00076             break;
00077         case InterfaceAcknowledgementTimer:
00078             {
00079                 OSPF::Interface* intf;
00080                 if (! (intf = reinterpret_cast <OSPF::Interface*> (timer->getContextPointer()))) {
00081                     // should not reach this point
00082                     EV << "Discarding invalid InterfaceAcknowledgementTimer.\n";
00083                     delete timer;
00084                 } else {
00085                     PrintEvent("Acknowledgement Timer expired", intf);
00086                     intf->ProcessEvent(OSPF::Interface::AcknowledgementTimer);
00087                 }
00088             }
00089             break;
00090         case NeighborInactivityTimer:
00091             {
00092                 OSPF::Neighbor* neighbor;
00093                 if (! (neighbor = reinterpret_cast <OSPF::Neighbor*> (timer->getContextPointer()))) {
00094                     // should not reach this point
00095                     EV << "Discarding invalid NeighborInactivityTimer.\n";
00096                     delete timer;
00097                 } else {
00098                     PrintEvent("Inactivity Timer expired", neighbor->GetInterface(), neighbor);
00099                     neighbor->ProcessEvent(OSPF::Neighbor::InactivityTimer);
00100                 }
00101             }
00102             break;
00103         case NeighborPollTimer:
00104             {
00105                 OSPF::Neighbor* neighbor;
00106                 if (! (neighbor = reinterpret_cast <OSPF::Neighbor*> (timer->getContextPointer()))) {
00107                     // should not reach this point
00108                     EV << "Discarding invalid NeighborInactivityTimer.\n";
00109                     delete timer;
00110                 } else {
00111                     PrintEvent("Poll Timer expired", neighbor->GetInterface(), neighbor);
00112                     neighbor->ProcessEvent(OSPF::Neighbor::PollTimer);
00113                 }
00114             }
00115             break;
00116         case NeighborDDRetransmissionTimer:
00117             {
00118                 OSPF::Neighbor* neighbor;
00119                 if (! (neighbor = reinterpret_cast <OSPF::Neighbor*> (timer->getContextPointer()))) {
00120                     // should not reach this point
00121                     EV << "Discarding invalid NeighborDDRetransmissionTimer.\n";
00122                     delete timer;
00123                 } else {
00124                     PrintEvent("Database Description Retransmission Timer expired", neighbor->GetInterface(), neighbor);
00125                     neighbor->ProcessEvent(OSPF::Neighbor::DDRetransmissionTimer);
00126                 }
00127             }
00128             break;
00129         case NeighborUpdateRetransmissionTimer:
00130             {
00131                 OSPF::Neighbor* neighbor;
00132                 if (! (neighbor = reinterpret_cast <OSPF::Neighbor*> (timer->getContextPointer()))) {
00133                     // should not reach this point
00134                     EV << "Discarding invalid NeighborUpdateRetransmissionTimer.\n";
00135                     delete timer;
00136                 } else {
00137                     PrintEvent("Update Retransmission Timer expired", neighbor->GetInterface(), neighbor);
00138                     neighbor->ProcessEvent(OSPF::Neighbor::UpdateRetransmissionTimer);
00139                 }
00140             }
00141             break;
00142         case NeighborRequestRetransmissionTimer:
00143             {
00144                 OSPF::Neighbor* neighbor;
00145                 if (! (neighbor = reinterpret_cast <OSPF::Neighbor*> (timer->getContextPointer()))) {
00146                     // should not reach this point
00147                     EV << "Discarding invalid NeighborRequestRetransmissionTimer.\n";
00148                     delete timer;
00149                 } else {
00150                     PrintEvent("Request Retransmission Timer expired", neighbor->GetInterface(), neighbor);
00151                     neighbor->ProcessEvent(OSPF::Neighbor::RequestRetransmissionTimer);
00152                 }
00153             }
00154             break;
00155         case DatabaseAgeTimer:
00156             {
00157                 PrintEvent("Ageing the database");
00158                 router->AgeDatabase();
00159             }
00160             break;
00161         default: break;
00162     }
00163 }
00164 
00165 void OSPF::MessageHandler::ProcessPacket(OSPFPacket* packet, OSPF::Interface* unused1, OSPF::Neighbor* unused2)
00166 {
00167     // packet version must be OSPF version 2
00168     if (packet->getVersion() == 2) {
00169         IPControlInfo*  controlInfo = check_and_cast<IPControlInfo *> (packet->getControlInfo());
00170         int             interfaceId = controlInfo->getInterfaceId();
00171         OSPF::AreaID    areaID      = packet->getAreaID().getInt();
00172         OSPF::Area*     area        = router->GetArea(areaID);
00173 
00174         if (area != NULL) {
00175             // packet Area ID must either match the Area ID of the receiving interface or...
00176             OSPF::Interface* intf = area->GetInterface(interfaceId);
00177 
00178             if (intf == NULL) {
00179                 // it must be the backbone area and...
00180                 if (areaID == BackboneAreaID) {
00181                     if (router->GetAreaCount() > 1) {
00182                         // it must be a virtual link and the source router's router ID must be the endpoint of this virtual link and...
00183                         intf = area->FindVirtualLink(packet->getRouterID().getInt());
00184 
00185                         if (intf != NULL) {
00186                             OSPF::Area* virtualLinkTransitArea = router->GetArea(intf->GetTransitAreaID());
00187 
00188                             if (virtualLinkTransitArea != NULL) {
00189                                 // the receiving interface must attach to the virtual link's configured transit area
00190                                 OSPF::Interface* virtualLinkInterface = virtualLinkTransitArea->GetInterface(interfaceId);
00191 
00192                                 if (virtualLinkInterface == NULL) {
00193                                     intf = NULL;
00194                                 }
00195                             } else {
00196                                 intf = NULL;
00197                             }
00198                         }
00199                     }
00200                 }
00201             }
00202             if (intf != NULL) {
00203                 unsigned long                       destinationAddress = controlInfo->getDestAddr().getInt();
00204                 unsigned long                       allDRouters        = ULongFromIPv4Address(OSPF::AllDRouters);
00205                 OSPF::Interface::InterfaceStateType interfaceState     = intf->GetState();
00206 
00207                 // if destination address is AllDRouters the receiving interface must be in DesignatedRouter or Backup state
00208                 if (
00209                     ((destinationAddress == allDRouters) &&
00210                      (
00211                       (interfaceState == OSPF::Interface::DesignatedRouterState) ||
00212                       (interfaceState == OSPF::Interface::BackupState)
00213                      )
00214                     ) ||
00215                     (destinationAddress != allDRouters)
00216                    )
00217                 {
00218                     // packet authentication
00219                     if (AuthenticatePacket(packet)) {
00220                         OSPFPacketType  packetType = static_cast<OSPFPacketType> (packet->getType());
00221                         OSPF::Neighbor* neighbor   = NULL;
00222 
00223                         // all packets except HelloPackets are sent only along adjacencies, so a Neighbor must exist
00224                         if (packetType != HelloPacket) {
00225                             switch (intf->GetType()) {
00226                                 case OSPF::Interface::Broadcast:
00227                                 case OSPF::Interface::NBMA:
00228                                 case OSPF::Interface::PointToMultiPoint:
00229                                     neighbor = intf->GetNeighborByAddress(IPv4AddressFromULong(controlInfo->getSrcAddr().getInt()));
00230                                     break;
00231                                 case OSPF::Interface::PointToPoint:
00232                                 case OSPF::Interface::Virtual:
00233                                     neighbor = intf->GetNeighborByID(packet->getRouterID().getInt());
00234                                     break;
00235                                 default: break;
00236                             }
00237                         }
00238                         switch (packetType) {
00239                             case HelloPacket:
00240                                 helloHandler.ProcessPacket(packet, intf);
00241                                 break;
00242                             case DatabaseDescriptionPacket:
00243                                 if (neighbor != NULL) {
00244                                     ddHandler.ProcessPacket(packet, intf, neighbor);
00245                                 }
00246                                 break;
00247                             case LinkStateRequestPacket:
00248                                 if (neighbor != NULL) {
00249                                     lsRequestHandler.ProcessPacket(packet, intf, neighbor);
00250                                 }
00251                                 break;
00252                             case LinkStateUpdatePacket:
00253                                 if (neighbor != NULL) {
00254                                     lsUpdateHandler.ProcessPacket(packet, intf, neighbor);
00255                                 }
00256                                 break;
00257                             case LinkStateAcknowledgementPacket:
00258                                 if (neighbor != NULL) {
00259                                     lsAckHandler.ProcessPacket(packet, intf, neighbor);
00260                                 }
00261                                 break;
00262                             default: break;
00263                         }
00264                     }
00265                 }
00266             }
00267         }
00268     }
00269     delete packet;
00270 }
00271 
00272 void OSPF::MessageHandler::SendPacket(OSPFPacket* packet, IPv4Address destination, int outputIfIndex, short ttl)
00273 {
00274     IPControlInfo *ipControlInfo = new IPControlInfo();
00275     ipControlInfo->setProtocol(IP_PROT_OSPF);
00276     ipControlInfo->setDestAddr(ULongFromIPv4Address(destination));
00277     ipControlInfo->setTimeToLive(ttl);
00278     ipControlInfo->setInterfaceId(outputIfIndex);
00279 
00280     packet->setControlInfo(ipControlInfo);
00281     switch (packet->getType()) {
00282         case HelloPacket:
00283             {
00284                 packet->setKind(HelloPacket);
00285                 packet->setName("OSPF_HelloPacket");
00286 
00287                 OSPFHelloPacket* helloPacket = check_and_cast<OSPFHelloPacket*> (packet);
00288                 PrintHelloPacket(helloPacket, destination, outputIfIndex);
00289             }
00290             break;
00291         case DatabaseDescriptionPacket:
00292             {
00293                 packet->setKind(DatabaseDescriptionPacket);
00294                 packet->setName("OSPF_DDPacket");
00295 
00296                 OSPFDatabaseDescriptionPacket* ddPacket = check_and_cast<OSPFDatabaseDescriptionPacket*> (packet);
00297                 PrintDatabaseDescriptionPacket(ddPacket, destination, outputIfIndex);
00298             }
00299             break;
00300         case LinkStateRequestPacket:
00301             {
00302                 packet->setKind(LinkStateRequestPacket);
00303                 packet->setName("OSPF_LSReqPacket");
00304 
00305                 OSPFLinkStateRequestPacket* requestPacket = check_and_cast<OSPFLinkStateRequestPacket*> (packet);
00306                 PrintLinkStateRequestPacket(requestPacket, destination, outputIfIndex);
00307             }
00308             break;
00309         case LinkStateUpdatePacket:
00310             {
00311                 packet->setKind(LinkStateUpdatePacket);
00312                 packet->setName("OSPF_LSUpdPacket");
00313 
00314                 OSPFLinkStateUpdatePacket* updatePacket = check_and_cast<OSPFLinkStateUpdatePacket*> (packet);
00315                 PrintLinkStateUpdatePacket(updatePacket, destination, outputIfIndex);
00316             }
00317             break;
00318         case LinkStateAcknowledgementPacket:
00319             {
00320                 packet->setKind(LinkStateAcknowledgementPacket);
00321                 packet->setName("OSPF_LSAckPacket");
00322 
00323                 OSPFLinkStateAcknowledgementPacket* ackPacket = check_and_cast<OSPFLinkStateAcknowledgementPacket*> (packet);
00324                 PrintLinkStateAcknowledgementPacket(ackPacket, destination, outputIfIndex);
00325             }
00326             break;
00327         default: break;
00328     }
00329 
00330     ospfModule->send(packet,"ipOut");
00331 }
00332 
00333 void OSPF::MessageHandler::ClearTimer(OSPFTimer* timer)
00334 {
00335     ospfModule->cancelEvent(timer);
00336 }
00337 
00338 void OSPF::MessageHandler::StartTimer(OSPFTimer* timer, simtime_t delay)
00339 {
00340     ospfModule->scheduleAt(simTime() + delay, timer);
00341 }
00342 
00343 void OSPF::MessageHandler::PrintEvent(const char* eventString, const OSPF::Interface* onInterface, const OSPF::Neighbor* forNeighbor /*= NULL*/) const
00344 {
00345     EV << eventString;
00346     if ((onInterface != NULL) || (forNeighbor != NULL)) {
00347         EV << ": ";
00348     }
00349     if (forNeighbor != NULL) {
00350         char addressString[16];
00351         EV << "neighbor["
00352            << AddressStringFromULong(addressString, sizeof(addressString), forNeighbor->GetNeighborID())
00353            << "] (state: "
00354            << forNeighbor->GetStateString(forNeighbor->GetState())
00355            << "); ";
00356     }
00357     if (onInterface != NULL) {
00358         EV << "interface["
00359            << static_cast <short> (onInterface->GetIfIndex())
00360            << "] ";
00361         switch (onInterface->GetType()) {
00362             case OSPF::Interface::PointToPoint:      EV << "(PointToPoint)";
00363                                                      break;
00364             case OSPF::Interface::Broadcast:         EV << "(Broadcast)";
00365                                                      break;
00366             case OSPF::Interface::NBMA:              EV << "(NBMA).\n";
00367                                                      break;
00368             case OSPF::Interface::PointToMultiPoint: EV << "(PointToMultiPoint)";
00369                                                      break;
00370             case OSPF::Interface::Virtual:           EV << "(Virtual)";
00371                                                      break;
00372             default:                                 EV << "(Unknown)";
00373         }
00374         EV << " (state: "
00375            << onInterface->GetStateString(onInterface->GetState())
00376            << ")";
00377     }
00378     EV << ".\n";
00379 }
00380 
00381 void OSPF::MessageHandler::PrintHelloPacket(const OSPFHelloPacket* helloPacket, IPv4Address destination, int outputIfIndex) const
00382 {
00383     char addressString[16];
00384     EV << "Sending Hello packet to "
00385        << AddressStringFromIPv4Address(addressString, sizeof(addressString), destination)
00386        << " on interface["
00387        << outputIfIndex
00388        << "] with contents:\n";
00389     EV << "  netMask="
00390        << AddressStringFromULong(addressString, sizeof(addressString), helloPacket->getNetworkMask().getInt())
00391        << "\n";
00392     EV << "  DR="
00393        << AddressStringFromULong(addressString, sizeof(addressString), helloPacket->getDesignatedRouter().getInt())
00394        << "\n";
00395     EV << "  BDR="
00396        << AddressStringFromULong(addressString, sizeof(addressString), helloPacket->getBackupDesignatedRouter().getInt())
00397        << "\n";
00398     EV << "  neighbors:\n";
00399 
00400     unsigned int neighborCount = helloPacket->getNeighborArraySize();
00401     for (unsigned int i = 0; i < neighborCount; i++) {
00402         EV << "    "
00403            << AddressStringFromULong(addressString, sizeof(addressString), helloPacket->getNeighbor(i).getInt())
00404            << "\n";
00405     }
00406 }
00407 
00408 void OSPF::MessageHandler::PrintDatabaseDescriptionPacket(const OSPFDatabaseDescriptionPacket* ddPacket, IPv4Address destination, int outputIfIndex) const
00409 {
00410     char addressString[16];
00411     EV << "Sending Database Description packet to "
00412        << AddressStringFromIPv4Address(addressString, sizeof(addressString), destination)
00413        << " on interface["
00414        << outputIfIndex
00415        << "] with contents:\n";
00416 
00417     const OSPFDDOptions& ddOptions = ddPacket->getDdOptions();
00418     EV << "  ddOptions="
00419        << ((ddOptions.I_Init) ? "I " : "_ ")
00420        << ((ddOptions.M_More) ? "M " : "_ ")
00421        << ((ddOptions.MS_MasterSlave) ? "MS" : "__")
00422        << "\n";
00423     EV << "  seqNumber="
00424        << ddPacket->getDdSequenceNumber()
00425        << "\n";
00426     EV << "  LSA headers:\n";
00427 
00428     unsigned int lsaCount = ddPacket->getLsaHeadersArraySize();
00429     for (unsigned int i = 0; i < lsaCount; i++) {
00430         EV << "    ";
00431         PrintLSAHeader(ddPacket->getLsaHeaders(i), ev.getOStream());
00432         EV << "\n";
00433     }
00434 }
00435 
00436 void OSPF::MessageHandler::PrintLinkStateRequestPacket(const OSPFLinkStateRequestPacket* requestPacket, IPv4Address destination, int outputIfIndex) const
00437 {
00438     char addressString[16];
00439     EV << "Sending Link State Request packet to "
00440        << AddressStringFromIPv4Address(addressString, sizeof(addressString), destination)
00441        << " on interface["
00442        << outputIfIndex
00443        << "] with requests:\n";
00444 
00445     unsigned int requestCount = requestPacket->getRequestsArraySize();
00446     for (unsigned int i = 0; i < requestCount; i++) {
00447         const LSARequest& request = requestPacket->getRequests(i);
00448         EV << "  type="
00449            << request.lsType
00450            << ", LSID="
00451            << AddressStringFromULong(addressString, sizeof(addressString), request.linkStateID);
00452         EV << ", advertisingRouter="
00453            << AddressStringFromULong(addressString, sizeof(addressString), request.advertisingRouter.getInt())
00454            << "\n";
00455     }
00456 }
00457 
00458 void OSPF::MessageHandler::PrintLinkStateUpdatePacket(const OSPFLinkStateUpdatePacket* updatePacket, IPv4Address destination, int outputIfIndex) const
00459 {
00460     char addressString[16];
00461     EV << "Sending Link State Update packet to "
00462        << AddressStringFromIPv4Address(addressString, sizeof(addressString), destination)
00463        << " on interface["
00464        << outputIfIndex
00465        << "] with updates:\n";
00466 
00467     unsigned int i           = 0;
00468     unsigned int updateCount = updatePacket->getRouterLSAsArraySize();
00469 
00470     for (i = 0; i < updateCount; i++) {
00471         const OSPFRouterLSA& lsa = updatePacket->getRouterLSAs(i);
00472         EV << "  ";
00473         PrintLSAHeader(lsa.getHeader(), ev.getOStream());
00474         EV << "\n";
00475 
00476         EV << "  bits="
00477            << ((lsa.getV_VirtualLinkEndpoint()) ? "V " : "_ ")
00478            << ((lsa.getE_ASBoundaryRouter()) ? "E " : "_ ")
00479            << ((lsa.getB_AreaBorderRouter()) ? "B" : "_")
00480            << "\n";
00481         EV << "  links:\n";
00482 
00483         unsigned int linkCount = lsa.getLinksArraySize();
00484         for (unsigned int j = 0; j < linkCount; j++) {
00485             const Link& link = lsa.getLinks(j);
00486             EV << "    ID="
00487                << AddressStringFromULong(addressString, sizeof(addressString), link.getLinkID().getInt())
00488                << ",";
00489             EV << " data="
00490                << AddressStringFromULong(addressString, sizeof(addressString), link.getLinkData())
00491                << ", type=";
00492             switch (link.getType()) {
00493                 case PointToPointLink:  EV << "PointToPoint";   break;
00494                 case TransitLink:       EV << "Transit";        break;
00495                 case StubLink:          EV << "Stub";           break;
00496                 case VirtualLink:       EV << "Virtual";        break;
00497                 default:                EV << "Unknown";        break;
00498             }
00499             EV << ", cost="
00500                << link.getLinkCost()
00501                << "\n";
00502         }
00503     }
00504 
00505     updateCount = updatePacket->getNetworkLSAsArraySize();
00506     for (i = 0; i < updateCount; i++) {
00507         const OSPFNetworkLSA& lsa = updatePacket->getNetworkLSAs(i);
00508         EV << "  ";
00509         PrintLSAHeader(lsa.getHeader(), ev.getOStream());
00510         EV << "\n";
00511 
00512         EV << "  netMask="
00513            << AddressStringFromULong(addressString, sizeof(addressString), lsa.getNetworkMask().getInt())
00514            << "\n";
00515         EV << "  attachedRouters:\n";
00516 
00517         unsigned int routerCount = lsa.getAttachedRoutersArraySize();
00518         for (unsigned int j = 0; j < routerCount; j++) {
00519             EV << "    "
00520                << AddressStringFromULong(addressString, sizeof(addressString), lsa.getAttachedRouters(j).getInt())
00521                << "\n";
00522         }
00523     }
00524 
00525     updateCount = updatePacket->getSummaryLSAsArraySize();
00526     for (i = 0; i < updateCount; i++) {
00527         const OSPFSummaryLSA& lsa = updatePacket->getSummaryLSAs(i);
00528         EV << "  ";
00529         PrintLSAHeader(lsa.getHeader(), ev.getOStream());
00530         EV << "\n";
00531 
00532         EV << "  netMask="
00533            << AddressStringFromULong(addressString, sizeof(addressString), lsa.getNetworkMask().getInt())
00534            << "\n";
00535         EV << "  cost="
00536            << lsa.getRouteCost()
00537            << "\n";
00538     }
00539 
00540     updateCount = updatePacket->getAsExternalLSAsArraySize();
00541     for (i = 0; i < updateCount; i++) {
00542         const OSPFASExternalLSA& lsa = updatePacket->getAsExternalLSAs(i);
00543         EV << "  ";
00544         PrintLSAHeader(lsa.getHeader(), ev.getOStream());
00545         EV << "\n";
00546 
00547         const OSPFASExternalLSAContents& contents = lsa.getContents();
00548         EV << "  netMask="
00549            << AddressStringFromULong(addressString, sizeof(addressString), contents.getNetworkMask().getInt())
00550            << "\n";
00551         EV << "  bits="
00552            << ((contents.getE_ExternalMetricType()) ? "E\n" : "_\n");
00553         EV << "  cost="
00554            << contents.getRouteCost()
00555            << "\n";
00556         EV << "  forward="
00557            << AddressStringFromULong(addressString, sizeof(addressString), contents.getForwardingAddress().getInt())
00558            << "\n";
00559     }
00560 }
00561 
00562 void OSPF::MessageHandler::PrintLinkStateAcknowledgementPacket(const OSPFLinkStateAcknowledgementPacket* ackPacket, IPv4Address destination, int outputIfIndex) const
00563 {
00564     char addressString[16];
00565     EV << "Sending Link State Acknowledgement packet to "
00566        << AddressStringFromIPv4Address(addressString, sizeof(addressString), destination)
00567        << " on interface["
00568        << outputIfIndex
00569        << "] with acknowledgements:\n";
00570 
00571     unsigned int lsaCount = ackPacket->getLsaHeadersArraySize();
00572     for (unsigned int i = 0; i < lsaCount; i++) {
00573         EV << "    ";
00574         PrintLSAHeader(ackPacket->getLsaHeaders(i), ev.getOStream());
00575         EV << "\n";
00576     }
00577 }
00578