#include <ICMP.h>
Public Member Functions | |
void | sendErrorMessage (IPDatagram *datagram, ICMPType type, ICMPCode code) |
void | sendErrorMessage (cMessage *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 (cMessage *) |
virtual void | sendToIP (ICMPMessage *, const IPAddress &dest) |
virtual void | sendToIP (ICMPMessage *msg) |
virtual void | handleMessage (cMessage *msg) |
Protected Attributes | |
RoutingTableAccess | routingTableAccess |
void ICMP::errorOut | ( | ICMPMessage * | ) | [protected, virtual] |
void ICMP::handleMessage | ( | cMessage * | msg | ) | [protected, virtual] |
00033 { 00034 cGate *arrivalGate = msg->arrivalGate(); 00035 00036 // process arriving ICMP message 00037 if (!strcmp(arrivalGate->name(), "localIn")) 00038 { 00039 processICMPMessage(check_and_cast<ICMPMessage *>(msg)); 00040 return; 00041 } 00042 00043 // request from application 00044 if (!strcmp(arrivalGate->name(), "pingIn")) 00045 { 00046 sendEchoRequest(msg); 00047 return; 00048 } 00049 }
void ICMP::processEchoReply | ( | ICMPMessage * | ) | [protected, virtual] |
00183 { 00184 IPControlInfo *ctrl = check_and_cast<IPControlInfo*>(reply->removeControlInfo()); 00185 cMessage *payload = reply->decapsulate(); 00186 payload->setControlInfo(ctrl); 00187 delete reply; 00188 send(payload, "pingOut"); 00189 }
void ICMP::processEchoRequest | ( | ICMPMessage * | ) | [protected, virtual] |
00165 { 00166 // turn request into a reply 00167 ICMPMessage *reply = request; 00168 reply->setName((std::string(request->name())+"-reply").c_str()); 00169 reply->setType(ICMP_ECHO_REPLY); 00170 00171 // swap src and dest 00172 // TBD check what to do if dest was multicast etc? 00173 IPControlInfo *ctrl = check_and_cast<IPControlInfo *>(reply->controlInfo()); 00174 IPAddress src = ctrl->srcAddr(); 00175 IPAddress dest = ctrl->destAddr(); 00176 ctrl->setSrcAddr(dest); 00177 ctrl->setDestAddr(src); 00178 00179 sendToIP(reply); 00180 }
void ICMP::processICMPMessage | ( | ICMPMessage * | ) | [protected, virtual] |
00127 { 00128 switch (icmpmsg->getType()) 00129 { 00130 case ICMP_DESTINATION_UNREACHABLE: 00131 errorOut(icmpmsg); 00132 break; 00133 case ICMP_REDIRECT: 00134 errorOut(icmpmsg); 00135 break; 00136 case ICMP_TIME_EXCEEDED: 00137 errorOut(icmpmsg); 00138 break; 00139 case ICMP_PARAMETER_PROBLEM: 00140 errorOut(icmpmsg); 00141 break; 00142 case ICMP_ECHO_REQUEST: 00143 processEchoRequest(icmpmsg); 00144 break; 00145 case ICMP_ECHO_REPLY: 00146 processEchoReply(icmpmsg); 00147 break; 00148 case ICMP_TIMESTAMP_REQUEST: 00149 processEchoRequest(icmpmsg); 00150 break; 00151 case ICMP_TIMESTAMP_REPLY: 00152 processEchoReply(icmpmsg); 00153 break; 00154 default: 00155 opp_error("Unknown ICMP type %d", icmpmsg->getType()); 00156 } 00157 }
void ICMP::sendEchoRequest | ( | cMessage * | ) | [protected, virtual] |
00192 { 00193 IPControlInfo *ctrl = check_and_cast<IPControlInfo*>(msg->removeControlInfo()); 00194 ctrl->setProtocol(IP_PROT_ICMP); 00195 ICMPMessage *request = new ICMPMessage(msg->name()); 00196 request->setType(ICMP_ECHO_REQUEST); 00197 request->encapsulate(msg); 00198 request->setControlInfo(ctrl); 00199 sendToIP(request); 00200 }
void ICMP::sendErrorMessage | ( | cMessage * | transportPacket, | |
IPControlInfo * | ctrl, | |||
ICMPType | type, | |||
ICMPCode | code | |||
) |
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.
00116 { 00117 Enter_Method("sendErrorMessage(transportPacket, ctrl, type=%d, code=%d)", type, code); 00118 00119 IPDatagram *datagram = ctrl->removeOrigDatagram(); 00120 take(transportPacket); 00121 take(datagram); 00122 datagram->encapsulate(transportPacket); 00123 sendErrorMessage(datagram, type, code); 00124 }
void ICMP::sendErrorMessage | ( | IPDatagram * | datagram, | |
ICMPType | type, | |||
ICMPCode | code | |||
) |
This method can be called from other modules to send an ICMP error packet in response to a received bogus packet.
00053 { 00054 Enter_Method("sendErrorMessage(datagram, type=%d, code=%d)", type, code); 00055 00056 // get ownership 00057 take(origDatagram); 00058 00059 // don't send ICMP error messages for multicast messages 00060 if (origDatagram->destAddress().isMulticast()) 00061 { 00062 EV << "won't send ICMP error messages for multicast message " << origDatagram << endl; 00063 delete origDatagram; 00064 return; 00065 } 00066 00067 // do not reply with error message to error message 00068 if (origDatagram->transportProtocol() == IP_PROT_ICMP) 00069 { 00070 ICMPMessage *recICMPMsg = check_and_cast<ICMPMessage *>(origDatagram->encapsulatedMsg()); 00071 if (recICMPMsg->getType()<128) 00072 { 00073 EV << "ICMP error received -- do not reply to it" << endl; 00074 delete origDatagram; 00075 return; 00076 } 00077 } 00078 00079 // assemble a message name 00080 char msgname[32]; 00081 static long ctr; 00082 sprintf(msgname, "ICMP-error-#%ld-type%d-code%d", ++ctr, type, code); 00083 00084 // debugging information 00085 EV << "sending ICMP error " << msgname << endl; 00086 00087 // create and send ICMP packet 00088 ICMPMessage *errorMessage = new ICMPMessage(msgname); 00089 errorMessage->setType(type); 00090 errorMessage->setCode(code); 00091 errorMessage->encapsulate(origDatagram); 00092 // ICMP message length: the internet header plus the first 8 bytes of 00093 // the original datagram's data is returned to the sender 00094 errorMessage->setByteLength(8 + origDatagram->headerLength() + 8); 00095 00096 // if srcAddr is not filled in, we're still in the src node, so we just 00097 // process the ICMP message locally, right away 00098 if (origDatagram->srcAddress().isUnspecified()) 00099 { 00100 // pretend it came from the IP layer 00101 IPControlInfo *controlInfo = new IPControlInfo(); 00102 controlInfo->setSrcAddr(IPAddress::LOOPBACK_ADDRESS); // FIXME maybe use configured loopback address 00103 controlInfo->setProtocol(IP_PROT_ICMP); 00104 errorMessage->setControlInfo(controlInfo); 00105 00106 // then process it locally 00107 processICMPMessage(errorMessage); 00108 } 00109 else 00110 { 00111 sendToIP(errorMessage, origDatagram->srcAddress()); 00112 } 00113 }
void ICMP::sendToIP | ( | ICMPMessage * | msg | ) | [protected, virtual] |
void ICMP::sendToIP | ( | ICMPMessage * | , | |
const IPAddress & | dest | |||
) | [protected, virtual] |
00203 { 00204 IPControlInfo *controlInfo = new IPControlInfo(); 00205 controlInfo->setDestAddr(dest); 00206 controlInfo->setProtocol(IP_PROT_ICMP); 00207 msg->setControlInfo(controlInfo); 00208 00209 send(msg, "sendOut"); 00210 }
RoutingTableAccess ICMP::routingTableAccess [protected] |