Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ICMPv6 Class Reference

#include <ICMPv6.h>

List of all members.


Detailed Description

ICMPv6 implementation.


Public Member Functions

void sendErrorMessage (IPv6Datagram *datagram, ICMPv6Type type, int code)
void sendErrorMessage (cMessage *transportPacket, IPv6ControlInfo *ctrl, ICMPv6Type type, int code)

Protected Member Functions

void sendToIP (ICMPv6Message *msg, const IPv6Address &dest)
void sendToIP (ICMPv6Message *msg)
ICMPv6MessagecreateDestUnreachableMsg (int code)
ICMPv6MessagecreatePacketTooBigMsg (int mtu)
ICMPv6MessagecreateTimeExceededMsg (int code)
ICMPv6MessagecreateParamProblemMsg (int code)
virtual void initialize ()
virtual void handleMessage (cMessage *msg)
virtual void processICMPv6Message (ICMPv6Message *)
virtual void processEchoRequest (ICMPv6EchoRequestMsg *)
virtual void processEchoReply (ICMPv6EchoReplyMsg *)
virtual void sendEchoRequest (cMessage *)
bool validateDatagramPromptingError (IPv6Datagram *datagram)
virtual void errorOut (ICMPv6Message *)


Member Function Documentation

ICMPv6Message * ICMPv6::createDestUnreachableMsg int  code  )  [protected]
 

00206 {
00207     ICMPv6DestUnreachableMsg *errorMsg = new ICMPv6DestUnreachableMsg("Dest Unreachable");
00208     errorMsg->setType(ICMPv6_DESTINATION_UNREACHABLE);
00209     errorMsg->setCode(code);
00210     return errorMsg;
00211 }

ICMPv6Message * ICMPv6::createPacketTooBigMsg int  mtu  )  [protected]
 

00214 {
00215     ICMPv6PacketTooBigMsg *errorMsg = new ICMPv6PacketTooBigMsg("Packet Too Big");
00216     errorMsg->setType(ICMPv6_PACKET_TOO_BIG);
00217     errorMsg->setCode(0);//Set to 0 by sender and ignored by receiver.
00218     errorMsg->setMTU(mtu);
00219     return errorMsg;
00220 }

ICMPv6Message * ICMPv6::createParamProblemMsg int  code  )  [protected]
 

00231 {
00232     ICMPv6ParamProblemMsg *errorMsg = new ICMPv6ParamProblemMsg("Parameter Problem");
00233     errorMsg->setType(ICMPv6_PARAMETER_PROBLEM);
00234     errorMsg->setCode(code);
00235     //TODO: What Pointer? section 3.4
00236     return errorMsg;
00237 }

ICMPv6Message * ICMPv6::createTimeExceededMsg int  code  )  [protected]
 

00223 {
00224     ICMPv6TimeExceededMsg *errorMsg = new ICMPv6TimeExceededMsg("Time Exceeded");
00225     errorMsg->setType(ICMPv6_TIME_EXCEEDED);
00226     errorMsg->setCode(code);
00227     return errorMsg;
00228 }

void ICMPv6::errorOut ICMPv6Message  )  [protected, virtual]
 

00264 {
00265     send(icmpv6msg, "errorOut");
00266 }

void ICMPv6::handleMessage cMessage *  msg  )  [protected, virtual]
 

Processing of messages that arrive in this module. Messages arrived here could be for ICMP ping requests or ICMPv6 messages that require processing.

00032 {
00033     ASSERT(!msg->isSelfMessage()); // no timers in ICMPv6
00034 
00035     // process arriving ICMP message
00036     if (msg->arrivalGate()->isName("fromIPv6"))
00037     {
00038         EV << "Processing ICMPv6 message.\n";
00039         processICMPv6Message(check_and_cast<ICMPv6Message *>(msg));
00040         return;
00041     }
00042 
00043     // request from application
00044     if (msg->arrivalGate()->isName("pingIn"))
00045     {
00046         sendEchoRequest(msg);
00047         return;
00048     }
00049 }

void ICMPv6::initialize  )  [protected, virtual]
 

Initialization

00028 {
00029 }

void ICMPv6::processEchoReply ICMPv6EchoReplyMsg  )  [protected, virtual]
 

Forward the ping reply to the "pingOut" of this module.

00112 {
00113     IPv6ControlInfo *ctrl = check_and_cast<IPv6ControlInfo*>(reply->removeControlInfo());
00114     cMessage *payload = reply->decapsulate();
00115     payload->setControlInfo(ctrl);
00116     delete reply;
00117     send(payload, "pingOut");
00118 }

void ICMPv6::processEchoRequest ICMPv6EchoRequestMsg  )  [protected, virtual]
 

Respond to the machine that tried to ping us.

00089 {
00090     //Create an ICMPv6 Reply Message
00091     ICMPv6EchoReplyMsg *reply = new ICMPv6EchoReplyMsg("Echo Reply");
00092     reply->setName((std::string(request->name())+"-reply").c_str());
00093     reply->setType(ICMPv6_ECHO_REPLY);
00094     reply->encapsulate(request->decapsulate());
00095 
00096     // TBD check what to do if dest was multicast etc?
00097     IPv6ControlInfo *ctrl
00098         = check_and_cast<IPv6ControlInfo *>(request->controlInfo());
00099     IPv6ControlInfo *replyCtrl = new IPv6ControlInfo();
00100     replyCtrl->setProtocol(IP_PROT_IPv6_ICMP);
00101     //set Msg's source addr as the dest addr of request msg.
00102     replyCtrl->setSrcAddr(ctrl->destAddr());
00103     //set Msg's dest addr as the source addr of request msg.
00104     replyCtrl->setDestAddr(ctrl->srcAddr());
00105     reply->setControlInfo(replyCtrl);
00106 
00107     delete request;
00108     sendToIP(reply);
00109 }

void ICMPv6::processICMPv6Message ICMPv6Message  )  [protected, virtual]
 

00052 {
00053     ASSERT(dynamic_cast<ICMPv6Message *>(icmpv6msg));
00054     if (dynamic_cast<ICMPv6DestUnreachableMsg *>(icmpv6msg))
00055     {
00056         EV << "ICMPv6 Destination Unreachable Message Received." << endl;
00057         errorOut(icmpv6msg);
00058     }
00059     else if (dynamic_cast<ICMPv6PacketTooBigMsg *>(icmpv6msg))
00060     {
00061         EV << "ICMPv6 Packet Too Big Message Received." << endl;
00062         errorOut(icmpv6msg);
00063     }
00064     else if (dynamic_cast<ICMPv6TimeExceededMsg *>(icmpv6msg))
00065     {
00066         EV << "ICMPv6 Time Exceeded Message Received." << endl;
00067         errorOut(icmpv6msg);
00068     }
00069     else if (dynamic_cast<ICMPv6ParamProblemMsg *>(icmpv6msg))
00070     {
00071         EV << "ICMPv6 Parameter Problem Message Received." << endl;
00072         errorOut(icmpv6msg);
00073     }
00074     else if (dynamic_cast<ICMPv6EchoRequestMsg *>(icmpv6msg))
00075     {
00076         EV << "ICMPv6 Echo Request Message Received." << endl;
00077         processEchoRequest((ICMPv6EchoRequestMsg *)icmpv6msg);
00078     }
00079     else if (dynamic_cast<ICMPv6EchoReplyMsg *>(icmpv6msg))
00080     {
00081         EV << "ICMPv6 Echo Reply Message Received." << endl;
00082         processEchoReply((ICMPv6EchoReplyMsg *)icmpv6msg);
00083     }
00084     else
00085         error("Unknown message type received.\n");
00086 }

void ICMPv6::sendEchoRequest cMessage *   )  [protected, virtual]
 

Ping a machine. The information needed to do this is in the cMessage parameter. TODO where in cMessage? document!!!

00121 {
00122     IPv6ControlInfo *ctrl = check_and_cast<IPv6ControlInfo*>(msg->removeControlInfo());
00123     ctrl->setProtocol(IP_PROT_IPv6_ICMP);
00124     ICMPv6EchoRequestMsg *request = new ICMPv6EchoRequestMsg(msg->name());
00125     request->setType(ICMPv6_ECHO_REQUEST);
00126     request->encapsulate(msg);
00127     request->setControlInfo(ctrl);
00128     sendToIP(request);
00129 }

void ICMPv6::sendErrorMessage cMessage *  transportPacket,
IPv6ControlInfo ctrl,
ICMPv6Type  type,
int  code
 

This method can be called from other modules to send an ICMP error packet in response to a received bogus packet from the transport layer (like UDP). The ICMP error packet needs to include (part of) the original IP datagram, so this function will wrap back the transport packet into the IP datagram based on its IPControlInfo.

00180 {
00181     Enter_Method("sendErrorMessage(transportPacket, ctrl, type=%d, code=%d)", type, code);
00182 
00183     IPv6Datagram *datagram = ctrl->removeOrigDatagram();
00184     datagram->encapsulate(transportPacket);
00185     sendErrorMessage(datagram, type, code);
00186 }

void ICMPv6::sendErrorMessage IPv6Datagram datagram,
ICMPv6Type  type,
int  code
 

This method can be called from other modules to send an ICMPv6 error packet. RFC 2463, Section 3: ICMPv6 Error Messages There are a total of 4 ICMPv6 error messages as described in the RFC. This method will construct and send error messages corresponding to the given type. Error Types:

  • Destination Unreachable Message - 1
  • Packet Too Big Message - 2
  • Time Exceeded Message - 3
  • Parameter Problem Message - 4 Code Types have different semantics for each error type. See RFC 2463.
00132 {
00133     Enter_Method("sendErrorMessage(datagram, type=%d, code=%d)", type, code);
00134 
00135     // get ownership
00136     take(origDatagram);
00137 
00138     if (!validateDatagramPromptingError(origDatagram))
00139         return;
00140 
00141     ICMPv6Message *errorMsg;
00142 
00143     if (type == ICMPv6_DESTINATION_UNREACHABLE) errorMsg = createDestUnreachableMsg(code);
00144     //TODO: implement MTU support.
00145     else if (type == ICMPv6_PACKET_TOO_BIG) errorMsg = createPacketTooBigMsg(0);
00146     else if (type == ICMPv6_TIME_EXCEEDED) errorMsg = createTimeExceededMsg(code);
00147     else if (type == ICMPv6_PARAMETER_PROBLEM) errorMsg = createParamProblemMsg(code);
00148     else error("Unknown ICMPv6 error type\n");
00149 
00150     errorMsg->encapsulate(origDatagram);
00151 
00152     // debugging information
00153     EV << "sending ICMP error: (" << errorMsg->className() << ")" << errorMsg->name()
00154        << " type=" << type << " code=" << code << endl;
00155 
00156     // ICMP message length: the internet header plus the first 8 bytes of
00157     // the original datagram's data is returned to the sender
00158     //errorMessage->setByteLength(4 + origDatagram->headerLength() + 8); FIXME What is this for?
00159 
00160     // if srcAddr is not filled in, we're still in the src node, so we just
00161     // process the ICMP message locally, right away
00162     if (origDatagram->srcAddress().isUnspecified())
00163     {
00164         // pretend it came from the IP layer
00165         IPv6ControlInfo *ctrlInfo = new IPv6ControlInfo();
00166         ctrlInfo->setSrcAddr(IPv6Address::LOOPBACK_ADDRESS); // FIXME maybe use configured loopback address
00167         ctrlInfo->setProtocol(IP_PROT_ICMP);
00168         errorMsg->setControlInfo(ctrlInfo);
00169 
00170         // then process it locally
00171         processICMPv6Message(errorMsg);
00172     }
00173     else
00174     {
00175         sendToIP(errorMsg, origDatagram->srcAddress());
00176     }
00177 }

void ICMPv6::sendToIP ICMPv6Message msg  )  [protected]
 

00200 {
00201     // assumes IPControlInfo is already attached
00202     send(msg,"toIPv6");
00203 }

void ICMPv6::sendToIP ICMPv6Message msg,
const IPv6Address dest
[protected]
 

00189 {
00190 
00191     IPv6ControlInfo *ctrlInfo = new IPv6ControlInfo();
00192     ctrlInfo->setDestAddr(dest);
00193     ctrlInfo->setProtocol(IP_PROT_IPv6_ICMP);
00194     msg->setControlInfo(ctrlInfo);
00195 
00196     send(msg,"toIPv6");
00197 }

bool ICMPv6::validateDatagramPromptingError IPv6Datagram datagram  )  [protected]
 

Validate the received IPv6 datagram before responding with error message.

00240 {
00241     // don't send ICMP error messages for multicast messages
00242     if (origDatagram->destAddress().isMulticast())
00243     {
00244         EV << "won't send ICMP error messages for multicast message " << origDatagram << endl;
00245         delete origDatagram;
00246         return false;
00247     }
00248 
00249     // do not reply with error message to error message
00250     if (origDatagram->transportProtocol() == IP_PROT_IPv6_ICMP)
00251     {
00252         ICMPv6Message *recICMPMsg = check_and_cast<ICMPv6Message *>(origDatagram->encapsulatedMsg());
00253         if (recICMPMsg->type()<128)
00254         {
00255             EV << "ICMP error received -- do not reply to it" << endl;
00256             delete origDatagram;
00257             return false;
00258         }
00259     }
00260     return true;
00261 }


The documentation for this class was generated from the following files:
Generated on Thu Oct 19 18:22:22 2006 for INET Framework for OMNeT++/OMNEST by  doxygen 1.4.0