#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 |
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] |
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] |
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 }
RoutingTableAccess ICMP::routingTableAccess [protected] |