#include <ICMP.h>
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 |
ICMP module.
Definition at line 35 of file ICMP.h.
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] |
RoutingTableAccess ICMP::routingTableAccess [protected] |