Public Member Functions | Protected Member Functions

ICMPv6 Class Reference

#include <ICMPv6.h>

List of all members.

Public Member Functions

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

Protected Member Functions

virtual void sendToIP (ICMPv6Message *msg, const IPv6Address &dest)
virtual void sendToIP (ICMPv6Message *msg)
virtual ICMPv6Message * createDestUnreachableMsg (int code)
virtual ICMPv6Message * createPacketTooBigMsg (int mtu)
virtual ICMPv6Message * createTimeExceededMsg (int code)
virtual 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 (cPacket *)
virtual bool validateDatagramPromptingError (IPv6Datagram *datagram)
virtual void errorOut (ICMPv6Message *)

Detailed Description

ICMPv6 implementation.

Definition at line 33 of file ICMPv6.h.


Member Function Documentation

ICMPv6Message * ICMPv6::createDestUnreachableMsg ( int  code  )  [protected, virtual]

Definition at line 204 of file ICMPv6.cc.

Referenced by sendErrorMessage().

{
    ICMPv6DestUnreachableMsg *errorMsg = new ICMPv6DestUnreachableMsg("Dest Unreachable");
    errorMsg->setType(ICMPv6_DESTINATION_UNREACHABLE);
    errorMsg->setCode(code);
    return errorMsg;
}

ICMPv6Message * ICMPv6::createPacketTooBigMsg ( int  mtu  )  [protected, virtual]

Definition at line 212 of file ICMPv6.cc.

Referenced by sendErrorMessage().

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

ICMPv6Message * ICMPv6::createParamProblemMsg ( int  code  )  [protected, virtual]

Definition at line 229 of file ICMPv6.cc.

Referenced by sendErrorMessage().

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

ICMPv6Message * ICMPv6::createTimeExceededMsg ( int  code  )  [protected, virtual]

Definition at line 221 of file ICMPv6.cc.

Referenced by sendErrorMessage().

{
    ICMPv6TimeExceededMsg *errorMsg = new ICMPv6TimeExceededMsg("Time Exceeded");
    errorMsg->setType(ICMPv6_TIME_EXCEEDED);
    errorMsg->setCode(code);
    return errorMsg;
}

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

Definition at line 262 of file ICMPv6.cc.

Referenced by processICMPv6Message().

{
    send(icmpv6msg, "errorOut");
}

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.

Definition at line 30 of file ICMPv6.cc.

{
    ASSERT(!msg->isSelfMessage()); // no timers in ICMPv6

    // process arriving ICMP message
    if (msg->getArrivalGate()->isName("ipv6In"))
    {
        EV << "Processing ICMPv6 message.\n";
        processICMPv6Message(check_and_cast<ICMPv6Message *>(msg));
        return;
    }

    // request from application
    if (msg->getArrivalGate()->isName("pingIn"))
    {
        sendEchoRequest(PK(msg));
        return;
    }
}

void ICMPv6::initialize (  )  [protected, virtual]

Initialization

Definition at line 26 of file ICMPv6.cc.

{
}

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

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

Definition at line 110 of file ICMPv6.cc.

Referenced by processICMPv6Message().

{
    IPv6ControlInfo *ctrl = check_and_cast<IPv6ControlInfo*>(reply->removeControlInfo());
    cPacket *payload = reply->decapsulate();
    payload->setControlInfo(ctrl);
    delete reply;
    send(payload, "pingOut");
}

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

Respond to the machine that tried to ping us.

Definition at line 87 of file ICMPv6.cc.

Referenced by processICMPv6Message().

{
    //Create an ICMPv6 Reply Message
    ICMPv6EchoReplyMsg *reply = new ICMPv6EchoReplyMsg("Echo Reply");
    reply->setName((std::string(request->getName())+"-reply").c_str());
    reply->setType(ICMPv6_ECHO_REPLY);
    reply->encapsulate(request->decapsulate());

    // TBD check what to do if dest was multicast etc?
    IPv6ControlInfo *ctrl
        = check_and_cast<IPv6ControlInfo *>(request->getControlInfo());
    IPv6ControlInfo *replyCtrl = new IPv6ControlInfo();
    replyCtrl->setProtocol(IP_PROT_IPv6_ICMP);
    //set Msg's source addr as the dest addr of request msg.
    replyCtrl->setSrcAddr(ctrl->getDestAddr());
    //set Msg's dest addr as the source addr of request msg.
    replyCtrl->setDestAddr(ctrl->getSrcAddr());
    reply->setControlInfo(replyCtrl);

    delete request;
    sendToIP(reply);
}

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

Definition at line 50 of file ICMPv6.cc.

Referenced by handleMessage(), and sendErrorMessage().

{
    ASSERT(dynamic_cast<ICMPv6Message *>(icmpv6msg));
    if (dynamic_cast<ICMPv6DestUnreachableMsg *>(icmpv6msg))
    {
        EV << "ICMPv6 Destination Unreachable Message Received." << endl;
        errorOut(icmpv6msg);
    }
    else if (dynamic_cast<ICMPv6PacketTooBigMsg *>(icmpv6msg))
    {
        EV << "ICMPv6 Packet Too Big Message Received." << endl;
        errorOut(icmpv6msg);
    }
    else if (dynamic_cast<ICMPv6TimeExceededMsg *>(icmpv6msg))
    {
        EV << "ICMPv6 Time Exceeded Message Received." << endl;
        errorOut(icmpv6msg);
    }
    else if (dynamic_cast<ICMPv6ParamProblemMsg *>(icmpv6msg))
    {
        EV << "ICMPv6 Parameter Problem Message Received." << endl;
        errorOut(icmpv6msg);
    }
    else if (dynamic_cast<ICMPv6EchoRequestMsg *>(icmpv6msg))
    {
        EV << "ICMPv6 Echo Request Message Received." << endl;
        processEchoRequest((ICMPv6EchoRequestMsg *)icmpv6msg);
    }
    else if (dynamic_cast<ICMPv6EchoReplyMsg *>(icmpv6msg))
    {
        EV << "ICMPv6 Echo Reply Message Received." << endl;
        processEchoReply((ICMPv6EchoReplyMsg *)icmpv6msg);
    }
    else
        error("Unknown message type received.\n");
}

void ICMPv6::sendEchoRequest ( cPacket *  msg  )  [protected, virtual]

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

Definition at line 119 of file ICMPv6.cc.

Referenced by handleMessage().

{
    IPv6ControlInfo *ctrl = check_and_cast<IPv6ControlInfo*>(msg->removeControlInfo());
    ctrl->setProtocol(IP_PROT_IPv6_ICMP);
    ICMPv6EchoRequestMsg *request = new ICMPv6EchoRequestMsg(msg->getName());
    request->setType(ICMPv6_ECHO_REQUEST);
    request->encapsulate(msg);
    request->setControlInfo(ctrl);
    sendToIP(request);
}

void ICMPv6::sendErrorMessage ( IPv6Datagram datagram,
ICMPv6Type  type,
int  code 
) [virtual]

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.

Definition at line 130 of file ICMPv6.cc.

Referenced by IPv6NeighbourDiscovery::dropQueuedPacketsAwaitingAR(), IPv6NeighbourDiscovery::processIPv6Datagram(), UDP::processUndeliverablePacket(), IPv6FragBuf::purgeStaleFragments(), and sendErrorMessage().

{
    Enter_Method("sendErrorMessage(datagram, type=%d, code=%d)", type, code);

    // get ownership
    take(origDatagram);

    if (!validateDatagramPromptingError(origDatagram))
        return;

    ICMPv6Message *errorMsg;

    if (type == ICMPv6_DESTINATION_UNREACHABLE) errorMsg = createDestUnreachableMsg(code);
    //TODO: implement MTU support.
    else if (type == ICMPv6_PACKET_TOO_BIG) errorMsg = createPacketTooBigMsg(0);
    else if (type == ICMPv6_TIME_EXCEEDED) errorMsg = createTimeExceededMsg(code);
    else if (type == ICMPv6_PARAMETER_PROBLEM) errorMsg = createParamProblemMsg(code);
    else error("Unknown ICMPv6 error type\n");

    errorMsg->encapsulate(origDatagram);

    // debugging information
    EV << "sending ICMP error: (" << errorMsg->getClassName() << ")" << errorMsg->getName()
       << " type=" << type << " code=" << code << endl;

    // ICMP message length: the internet header plus the first 8 bytes of
    // the original datagram's data is returned to the sender
    //errorMessage->setByteLength(4 + origDatagram->getHeaderLength() + 8); FIXME What is this for?

    // if srcAddr is not filled in, we're still in the src node, so we just
    // process the ICMP message locally, right away
    if (origDatagram->getSrcAddress().isUnspecified())
    {
        // pretend it came from the IP layer
        IPv6ControlInfo *ctrlInfo = new IPv6ControlInfo();
        ctrlInfo->setSrcAddr(IPv6Address::LOOPBACK_ADDRESS); // FIXME maybe use configured loopback address
        ctrlInfo->setProtocol(IP_PROT_ICMP);
        errorMsg->setControlInfo(ctrlInfo);

        // then process it locally
        processICMPv6Message(errorMsg);
    }
    else
    {
        sendToIP(errorMsg, origDatagram->getSrcAddress());
    }
}

void ICMPv6::sendErrorMessage ( cPacket *  transportPacket,
IPv6ControlInfo ctrl,
ICMPv6Type  type,
int  code 
) [virtual]

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.

Definition at line 178 of file ICMPv6.cc.

{
    Enter_Method("sendErrorMessage(transportPacket, ctrl, type=%d, code=%d)", type, code);

    IPv6Datagram *datagram = ctrl->removeOrigDatagram();
    datagram->encapsulate(transportPacket);
    sendErrorMessage(datagram, type, code);
}

void ICMPv6::sendToIP ( ICMPv6Message *  msg  )  [protected, virtual]

Definition at line 198 of file ICMPv6.cc.

{
    // assumes IPControlInfo is already attached
    send(msg,"ipv6Out");
}

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

Definition at line 187 of file ICMPv6.cc.

Referenced by processEchoRequest(), sendEchoRequest(), and sendErrorMessage().

{

    IPv6ControlInfo *ctrlInfo = new IPv6ControlInfo();
    ctrlInfo->setDestAddr(dest);
    ctrlInfo->setProtocol(IP_PROT_IPv6_ICMP);
    msg->setControlInfo(ctrlInfo);

    send(msg,"ipv6Out");
}

bool ICMPv6::validateDatagramPromptingError ( IPv6Datagram datagram  )  [protected, virtual]

Validate the received IPv6 datagram before responding with error message.

Definition at line 238 of file ICMPv6.cc.

Referenced by sendErrorMessage().

{
    // don't send ICMP error messages for multicast messages
    if (origDatagram->getDestAddress().isMulticast())
    {
        EV << "won't send ICMP error messages for multicast message " << origDatagram << endl;
        delete origDatagram;
        return false;
    }

    // do not reply with error message to error message
    if (origDatagram->getTransportProtocol() == IP_PROT_IPv6_ICMP)
    {
        ICMPv6Message *recICMPMsg = check_and_cast<ICMPv6Message *>(origDatagram->getEncapsulatedMsg());
        if (recICMPMsg->getType()<128)
        {
            EV << "ICMP error received -- do not reply to it" << endl;
            delete origDatagram;
            return false;
        }
    }
    return true;
}


The documentation for this class was generated from the following files: