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)
ICMPv6Message * createDestUnreachableMsg (int code)
ICMPv6Message * createPacketTooBigMsg (int mtu)
ICMPv6Message * createTimeExceededMsg (int code)
ICMPv6Message * createParamProblemMsg (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]
 

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

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

00213 {
00214     ICMPv6PacketTooBigMsg *errorMsg
00215         = 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]
 

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

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

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

00266 {
00267     send(icmpv6msg, "errorOut");
00268 }

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.

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

void ICMPv6::initialize  )  [protected, virtual]
 

Initialization

00028 {
00029     //...
00030 }

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

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

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

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

Respond to the machine that tried to ping us.

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

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

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

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!!!

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

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.

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

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

void ICMPv6::sendToIP ICMPv6Message *  msg  )  [protected]
 

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

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

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

bool ICMPv6::validateDatagramPromptingError IPv6Datagram datagram  )  [protected]
 

Validate the received IPv6 datagram before responding with error message.

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


The documentation for this class was generated from the following files:
Generated on Sat Apr 1 20:52:22 2006 for INET Framework for OMNeT++/OMNEST by  doxygen 1.4.1