Public Member Functions | Protected Member Functions | Protected Attributes

ICMP Class Reference

#include <ICMP.h>

List of all members.

Public Member Functions

virtual void sendErrorMessage (IPDatagram *datagram, ICMPType type, ICMPCode code)
virtual void sendErrorMessage (cPacket *transportPacket, IPControlInfo *ctrl, ICMPType type, ICMPCode code)

Protected Member Functions

virtual void processICMPMessage (ICMPMessage *)
virtual void errorOut (ICMPMessage *)
virtual void processEchoRequest (ICMPMessage *)
virtual void processEchoReply (ICMPMessage *)
virtual void sendEchoRequest (cPacket *)
virtual void sendToIP (ICMPMessage *, const IPAddress &dest)
virtual void sendToIP (ICMPMessage *msg)
virtual void handleMessage (cMessage *msg)

Protected Attributes

RoutingTableAccess routingTableAccess

Detailed Description

ICMP module.

Definition at line 35 of file ICMP.h.


Member Function Documentation

void ICMP::errorOut ( ICMPMessage *  icmpmsg  )  [protected, virtual]

Definition at line 167 of file ICMP.cc.

Referenced by processICMPMessage().

{
    send(icmpmsg, "errorOut");
}

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

Definition at line 31 of file ICMP.cc.

{
    cGate *arrivalGate = msg->getArrivalGate();

    // process arriving ICMP message
    if (!strcmp(arrivalGate->getName(), "localIn"))
    {
        processICMPMessage(check_and_cast<ICMPMessage *>(msg));
        return;
    }

    // request from application
    if (!strcmp(arrivalGate->getName(), "pingIn"))
    {
        sendEchoRequest(PK(msg));
        return;
    }
}

void ICMP::processEchoReply ( ICMPMessage *  reply  )  [protected, virtual]

Definition at line 190 of file ICMP.cc.

Referenced by processICMPMessage().

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

void ICMP::processEchoRequest ( ICMPMessage *  request  )  [protected, virtual]

Definition at line 172 of file ICMP.cc.

Referenced by processICMPMessage().

{
    // turn request into a reply
    ICMPMessage *reply = request;
    reply->setName((std::string(request->getName())+"-reply").c_str());
    reply->setType(ICMP_ECHO_REPLY);

    // swap src and dest
    // TBD check what to do if dest was multicast etc?
    IPControlInfo *ctrl = check_and_cast<IPControlInfo *>(reply->getControlInfo());
    IPAddress src = ctrl->getSrcAddr();
    IPAddress dest = ctrl->getDestAddr();
    ctrl->setSrcAddr(dest);
    ctrl->setDestAddr(src);

    sendToIP(reply);
}

void ICMP::processICMPMessage ( ICMPMessage *  icmpmsg  )  [protected, virtual]

Definition at line 134 of file ICMP.cc.

Referenced by handleMessage(), and sendErrorMessage().

{
    switch (icmpmsg->getType())
    {
        case ICMP_DESTINATION_UNREACHABLE:
            errorOut(icmpmsg);
            break;
        case ICMP_REDIRECT:
            errorOut(icmpmsg);
            break;
        case ICMP_TIME_EXCEEDED:
            errorOut(icmpmsg);
            break;
        case ICMP_PARAMETER_PROBLEM:
            errorOut(icmpmsg);
            break;
        case ICMP_ECHO_REQUEST:
            processEchoRequest(icmpmsg);
            break;
        case ICMP_ECHO_REPLY:
            processEchoReply(icmpmsg);
            break;
        case ICMP_TIMESTAMP_REQUEST:
            processEchoRequest(icmpmsg);
            break;
        case ICMP_TIMESTAMP_REPLY:
            processEchoReply(icmpmsg);
            break;
        default:
            opp_error("Unknown ICMP type %d", icmpmsg->getType());
    }
}

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

Definition at line 199 of file ICMP.cc.

Referenced by handleMessage().

{
    IPControlInfo *ctrl = check_and_cast<IPControlInfo*>(msg->removeControlInfo());
    ctrl->setProtocol(IP_PROT_ICMP);
    ICMPMessage *request = new ICMPMessage(msg->getName());
    request->setType(ICMP_ECHO_REQUEST);
    request->encapsulate(msg);
    request->setControlInfo(ctrl);
    sendToIP(request);
}

void ICMP::sendErrorMessage ( cPacket *  transportPacket,
IPControlInfo ctrl,
ICMPType  type,
ICMPCode  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 123 of file ICMP.cc.

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

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

void ICMP::sendErrorMessage ( IPDatagram *  datagram,
ICMPType  type,
ICMPCode  code 
) [virtual]

This method can be called from other modules to send an ICMP error packet in response to a received bogus packet.

Definition at line 51 of file ICMP.cc.

Referenced by IP::fragmentAndSend(), IP::handlePacketFromNetwork(), IPFragBuf::purgeStaleFragments(), IP::routePacket(), IP::sendDatagramToOutput(), and sendErrorMessage().

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

    // get ownership
    take(origDatagram);

    // 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;
    }

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

    // assemble a message name
    char msgname[32];
    static long ctr;
    sprintf(msgname, "ICMP-error-#%ld-type%d-code%d", ++ctr, type, code);

    // debugging information
    EV << "sending ICMP error " << msgname << endl;

    // create and send ICMP packet
    ICMPMessage *errorMessage = new ICMPMessage(msgname);
    errorMessage->setType(type);
    errorMessage->setCode(code);
    errorMessage->encapsulate(origDatagram);

    // ICMP message length: the internet header plus the first 8 bytes of
    // the original datagram's data is returned to the sender.
    //
    // NOTE: since we just overwrite the errorMessage length without actually
    // truncating origDatagram, one can get "packet length became negative"
    // error when decapsulating the origDatagram on the receiver side.
    // A workaround is to avoid decapsulation, or to manually set the
    // errorMessage length to be larger than the encapsulated message.
    int dataLength = origDatagram->getByteLength() - origDatagram->getHeaderLength();
    int truncatedDataLength = dataLength <= 8 ? dataLength : 8;
    errorMessage->setByteLength(8 + origDatagram->getHeaderLength() + truncatedDataLength);

    // 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
        IPControlInfo *controlInfo = new IPControlInfo();
        controlInfo->setSrcAddr(IPAddress::LOOPBACK_ADDRESS); // FIXME maybe use configured loopback address
        controlInfo->setProtocol(IP_PROT_ICMP);
        errorMessage->setControlInfo(controlInfo);

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

void ICMP::sendToIP ( ICMPMessage *  msg,
const IPAddress dest 
) [protected, virtual]

Definition at line 210 of file ICMP.cc.

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

{
    IPControlInfo *controlInfo = new IPControlInfo();
    controlInfo->setDestAddr(dest);
    controlInfo->setProtocol(IP_PROT_ICMP);
    msg->setControlInfo(controlInfo);

    send(msg, "sendOut");
}

void ICMP::sendToIP ( ICMPMessage *  msg  )  [protected, virtual]

Definition at line 220 of file ICMP.cc.

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


Member Data Documentation

Definition at line 38 of file ICMP.h.


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