ICMP Class Reference

#include <ICMP.h>

List of all members.


Detailed Description

ICMP module.

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

Member Function Documentation

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

Referenced by handleMessage(), and sendErrorMessage().

00126 {
00127     switch (icmpmsg->getType())
00128     {
00129         case ICMP_DESTINATION_UNREACHABLE:
00130             errorOut(icmpmsg);
00131             break;
00132         case ICMP_REDIRECT:
00133             errorOut(icmpmsg);
00134             break;
00135         case ICMP_TIME_EXCEEDED:
00136             errorOut(icmpmsg);
00137             break;
00138         case ICMP_PARAMETER_PROBLEM:
00139             errorOut(icmpmsg);
00140             break;
00141         case ICMP_ECHO_REQUEST:
00142             processEchoRequest(icmpmsg);
00143             break;
00144         case ICMP_ECHO_REPLY:
00145             processEchoReply(icmpmsg);
00146             break;
00147         case ICMP_TIMESTAMP_REQUEST:
00148             processEchoRequest(icmpmsg);
00149             break;
00150         case ICMP_TIMESTAMP_REPLY:
00151             processEchoReply(icmpmsg);
00152             break;
00153         default:
00154             opp_error("Unknown ICMP type %d", icmpmsg->getType());
00155     }
00156 }

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

Referenced by processICMPMessage().

00159 {
00160     send(icmpmsg, "errorOut");
00161 }

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

Referenced by processICMPMessage().

00164 {
00165     // turn request into a reply
00166     ICMPMessage *reply = request;
00167     reply->setName((std::string(request->getName())+"-reply").c_str());
00168     reply->setType(ICMP_ECHO_REPLY);
00169 
00170     // swap src and dest
00171     // TBD check what to do if dest was multicast etc?
00172     IPControlInfo *ctrl = check_and_cast<IPControlInfo *>(reply->getControlInfo());
00173     IPAddress src = ctrl->getSrcAddr();
00174     IPAddress dest = ctrl->getDestAddr();
00175     ctrl->setSrcAddr(dest);
00176     ctrl->setDestAddr(src);
00177 
00178     sendToIP(reply);
00179 }

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

Referenced by processICMPMessage().

00182 {
00183     IPControlInfo *ctrl = check_and_cast<IPControlInfo*>(reply->removeControlInfo());
00184     cPacket *payload = reply->decapsulate();
00185     payload->setControlInfo(ctrl);
00186     delete reply;
00187     send(payload, "pingOut");
00188 }

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

Referenced by handleMessage().

00191 {
00192     IPControlInfo *ctrl = check_and_cast<IPControlInfo*>(msg->removeControlInfo());
00193     ctrl->setProtocol(IP_PROT_ICMP);
00194     ICMPMessage *request = new ICMPMessage(msg->getName());
00195     request->setType(ICMP_ECHO_REQUEST);
00196     request->encapsulate(msg);
00197     request->setControlInfo(ctrl);
00198     sendToIP(request);
00199 }

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

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

00202 {
00203     IPControlInfo *controlInfo = new IPControlInfo();
00204     controlInfo->setDestAddr(dest);
00205     controlInfo->setProtocol(IP_PROT_ICMP);
00206     msg->setControlInfo(controlInfo);
00207 
00208     send(msg, "sendOut");
00209 }

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

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

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.

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

00052 {
00053     Enter_Method("sendErrorMessage(datagram, type=%d, code=%d)", type, code);
00054 
00055     // get ownership
00056     take(origDatagram);
00057 
00058     // don't send ICMP error messages for multicast messages
00059     if (origDatagram->getDestAddress().isMulticast())
00060     {
00061         EV << "won't send ICMP error messages for multicast message " << origDatagram << endl;
00062         delete origDatagram;
00063         return;
00064     }
00065 
00066     // do not reply with error message to error message
00067     if (origDatagram->getTransportProtocol() == IP_PROT_ICMP)
00068     {
00069         ICMPMessage *recICMPMsg = check_and_cast<ICMPMessage *>(origDatagram->getEncapsulatedMsg());
00070         if (recICMPMsg->getType()<128)
00071         {
00072             EV << "ICMP error received -- do not reply to it" << endl;
00073             delete origDatagram;
00074             return;
00075         }
00076     }
00077 
00078     // assemble a message name
00079     char msgname[32];
00080     static long ctr;
00081     sprintf(msgname, "ICMP-error-#%ld-type%d-code%d", ++ctr, type, code);
00082 
00083     // debugging information
00084     EV << "sending ICMP error " << msgname << endl;
00085 
00086     // create and send ICMP packet
00087     ICMPMessage *errorMessage = new ICMPMessage(msgname);
00088     errorMessage->setType(type);
00089     errorMessage->setCode(code);
00090     errorMessage->encapsulate(origDatagram);
00091     // ICMP message length: the internet header plus the first 8 bytes of
00092     // the original datagram's data is returned to the sender
00093     errorMessage->setByteLength(8 + origDatagram->getHeaderLength() + 8);
00094 
00095     // if srcAddr is not filled in, we're still in the src node, so we just
00096     // process the ICMP message locally, right away
00097     if (origDatagram->getSrcAddress().isUnspecified())
00098     {
00099         // pretend it came from the IP layer
00100         IPControlInfo *controlInfo = new IPControlInfo();
00101         controlInfo->setSrcAddr(IPAddress::LOOPBACK_ADDRESS); // FIXME maybe use configured loopback address
00102         controlInfo->setProtocol(IP_PROT_ICMP);
00103         errorMessage->setControlInfo(controlInfo);
00104 
00105         // then process it locally
00106         processICMPMessage(errorMessage);
00107     }
00108     else
00109     {
00110         sendToIP(errorMessage, origDatagram->getSrcAddress());
00111     }
00112 }

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.

00115 {
00116     Enter_Method("sendErrorMessage(transportPacket, ctrl, type=%d, code=%d)", type, code);
00117 
00118     IPDatagram *datagram = ctrl->removeOrigDatagram();
00119     take(transportPacket);
00120     take(datagram);
00121     datagram->encapsulate(transportPacket);
00122     sendErrorMessage(datagram, type, code);
00123 }

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

00032 {
00033     cGate *arrivalGate = msg->getArrivalGate();
00034 
00035     // process arriving ICMP message
00036     if (!strcmp(arrivalGate->getName(), "localIn"))
00037     {
00038         processICMPMessage(check_and_cast<ICMPMessage *>(msg));
00039         return;
00040     }
00041 
00042     // request from application
00043     if (!strcmp(arrivalGate->getName(), "pingIn"))
00044     {
00045         sendEchoRequest(PK(msg));
00046         return;
00047     }
00048 }


Member Data Documentation


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

Generated on Fri Mar 20 18:51:19 2009 for INET Framework for OMNeT++/OMNEST by  doxygen 1.5.5