#include <ICMPv6.h>
Public Member Functions | |
virtual void | sendErrorMessage (IPv6Datagram *datagram, ICMPv6Type type, int code) |
virtual void | sendErrorMessage (cPacket *transportPacket, IPv6ControlInfo *ctrl, ICMPv6Type type, int code) |
Protected Member Functions | |
virtual void | sendToIP (ICMPv6Message *msg, const IPv6Address &dest) |
virtual void | sendToIP (ICMPv6Message *msg) |
virtual ICMPv6Message * | createDestUnreachableMsg (int code) |
virtual ICMPv6Message * | createPacketTooBigMsg (int mtu) |
virtual ICMPv6Message * | createTimeExceededMsg (int code) |
virtual ICMPv6Message * | createParamProblemMsg (int code) |
virtual void | initialize () |
virtual void | handleMessage (cMessage *msg) |
virtual void | processICMPv6Message (ICMPv6Message *) |
virtual void | processEchoRequest (ICMPv6EchoRequestMsg *) |
virtual void | processEchoReply (ICMPv6EchoReplyMsg *) |
virtual void | sendEchoRequest (cPacket *) |
virtual bool | validateDatagramPromptingError (IPv6Datagram *datagram) |
virtual void | errorOut (ICMPv6Message *) |
ICMPv6 implementation.
Definition at line 33 of file ICMPv6.h.
ICMPv6Message * ICMPv6::createDestUnreachableMsg | ( | int | code | ) | [protected, virtual] |
Definition at line 204 of file ICMPv6.cc.
Referenced by sendErrorMessage().
{ ICMPv6DestUnreachableMsg *errorMsg = new ICMPv6DestUnreachableMsg("Dest Unreachable"); errorMsg->setType(ICMPv6_DESTINATION_UNREACHABLE); errorMsg->setCode(code); return errorMsg; }
ICMPv6Message * ICMPv6::createPacketTooBigMsg | ( | int | mtu | ) | [protected, virtual] |
Definition at line 212 of file ICMPv6.cc.
Referenced by sendErrorMessage().
{ ICMPv6PacketTooBigMsg *errorMsg = new ICMPv6PacketTooBigMsg("Packet Too Big"); errorMsg->setType(ICMPv6_PACKET_TOO_BIG); errorMsg->setCode(0);//Set to 0 by sender and ignored by receiver. errorMsg->setMTU(mtu); return errorMsg; }
ICMPv6Message * ICMPv6::createParamProblemMsg | ( | int | code | ) | [protected, virtual] |
Definition at line 229 of file ICMPv6.cc.
Referenced by sendErrorMessage().
{ ICMPv6ParamProblemMsg *errorMsg = new ICMPv6ParamProblemMsg("Parameter Problem"); errorMsg->setType(ICMPv6_PARAMETER_PROBLEM); errorMsg->setCode(code); //TODO: What Pointer? section 3.4 return errorMsg; }
ICMPv6Message * ICMPv6::createTimeExceededMsg | ( | int | code | ) | [protected, virtual] |
Definition at line 221 of file ICMPv6.cc.
Referenced by sendErrorMessage().
{ ICMPv6TimeExceededMsg *errorMsg = new ICMPv6TimeExceededMsg("Time Exceeded"); errorMsg->setType(ICMPv6_TIME_EXCEEDED); errorMsg->setCode(code); return errorMsg; }
void ICMPv6::errorOut | ( | ICMPv6Message * | icmpv6msg | ) | [protected, virtual] |
Definition at line 262 of file ICMPv6.cc.
Referenced by processICMPv6Message().
{
send(icmpv6msg, "errorOut");
}
void ICMPv6::handleMessage | ( | cMessage * | msg | ) | [protected, virtual] |
Processing of messages that arrive in this module. Messages arrived here could be for ICMP ping requests or ICMPv6 messages that require processing.
Definition at line 30 of file ICMPv6.cc.
{ ASSERT(!msg->isSelfMessage()); // no timers in ICMPv6 // process arriving ICMP message if (msg->getArrivalGate()->isName("ipv6In")) { EV << "Processing ICMPv6 message.\n"; processICMPv6Message(check_and_cast<ICMPv6Message *>(msg)); return; } // request from application if (msg->getArrivalGate()->isName("pingIn")) { sendEchoRequest(PK(msg)); return; } }
void ICMPv6::initialize | ( | ) | [protected, virtual] |
void ICMPv6::processEchoReply | ( | ICMPv6EchoReplyMsg * | reply | ) | [protected, virtual] |
Forward the ping reply to the "pingOut" of this module.
Definition at line 110 of file ICMPv6.cc.
Referenced by processICMPv6Message().
{ IPv6ControlInfo *ctrl = check_and_cast<IPv6ControlInfo*>(reply->removeControlInfo()); cPacket *payload = reply->decapsulate(); payload->setControlInfo(ctrl); delete reply; send(payload, "pingOut"); }
void ICMPv6::processEchoRequest | ( | ICMPv6EchoRequestMsg * | request | ) | [protected, virtual] |
Respond to the machine that tried to ping us.
Definition at line 87 of file ICMPv6.cc.
Referenced by processICMPv6Message().
{ //Create an ICMPv6 Reply Message ICMPv6EchoReplyMsg *reply = new ICMPv6EchoReplyMsg("Echo Reply"); reply->setName((std::string(request->getName())+"-reply").c_str()); reply->setType(ICMPv6_ECHO_REPLY); reply->encapsulate(request->decapsulate()); // TBD check what to do if dest was multicast etc? IPv6ControlInfo *ctrl = check_and_cast<IPv6ControlInfo *>(request->getControlInfo()); IPv6ControlInfo *replyCtrl = new IPv6ControlInfo(); replyCtrl->setProtocol(IP_PROT_IPv6_ICMP); //set Msg's source addr as the dest addr of request msg. replyCtrl->setSrcAddr(ctrl->getDestAddr()); //set Msg's dest addr as the source addr of request msg. replyCtrl->setDestAddr(ctrl->getSrcAddr()); reply->setControlInfo(replyCtrl); delete request; sendToIP(reply); }
void ICMPv6::processICMPv6Message | ( | ICMPv6Message * | icmpv6msg | ) | [protected, virtual] |
Definition at line 50 of file ICMPv6.cc.
Referenced by handleMessage(), and sendErrorMessage().
{ ASSERT(dynamic_cast<ICMPv6Message *>(icmpv6msg)); if (dynamic_cast<ICMPv6DestUnreachableMsg *>(icmpv6msg)) { EV << "ICMPv6 Destination Unreachable Message Received." << endl; errorOut(icmpv6msg); } else if (dynamic_cast<ICMPv6PacketTooBigMsg *>(icmpv6msg)) { EV << "ICMPv6 Packet Too Big Message Received." << endl; errorOut(icmpv6msg); } else if (dynamic_cast<ICMPv6TimeExceededMsg *>(icmpv6msg)) { EV << "ICMPv6 Time Exceeded Message Received." << endl; errorOut(icmpv6msg); } else if (dynamic_cast<ICMPv6ParamProblemMsg *>(icmpv6msg)) { EV << "ICMPv6 Parameter Problem Message Received." << endl; errorOut(icmpv6msg); } else if (dynamic_cast<ICMPv6EchoRequestMsg *>(icmpv6msg)) { EV << "ICMPv6 Echo Request Message Received." << endl; processEchoRequest((ICMPv6EchoRequestMsg *)icmpv6msg); } else if (dynamic_cast<ICMPv6EchoReplyMsg *>(icmpv6msg)) { EV << "ICMPv6 Echo Reply Message Received." << endl; processEchoReply((ICMPv6EchoReplyMsg *)icmpv6msg); } else error("Unknown message type received.\n"); }
void ICMPv6::sendEchoRequest | ( | cPacket * | msg | ) | [protected, virtual] |
Ping a machine. The information needed to do this is in the cMessage parameter. TODO where in cMessage? document!!!
Definition at line 119 of file ICMPv6.cc.
Referenced by handleMessage().
{ IPv6ControlInfo *ctrl = check_and_cast<IPv6ControlInfo*>(msg->removeControlInfo()); ctrl->setProtocol(IP_PROT_IPv6_ICMP); ICMPv6EchoRequestMsg *request = new ICMPv6EchoRequestMsg(msg->getName()); request->setType(ICMPv6_ECHO_REQUEST); request->encapsulate(msg); request->setControlInfo(ctrl); sendToIP(request); }
void ICMPv6::sendErrorMessage | ( | IPv6Datagram * | datagram, | |
ICMPv6Type | type, | |||
int | code | |||
) | [virtual] |
This method can be called from other modules to send an ICMPv6 error packet. RFC 2463, Section 3: ICMPv6 Error Messages There are a total of 4 ICMPv6 error messages as described in the RFC. This method will construct and send error messages corresponding to the given type. Error Types:
Definition at line 130 of file ICMPv6.cc.
Referenced by IPv6NeighbourDiscovery::dropQueuedPacketsAwaitingAR(), IPv6NeighbourDiscovery::processIPv6Datagram(), UDP::processUndeliverablePacket(), IPv6FragBuf::purgeStaleFragments(), and sendErrorMessage().
{ Enter_Method("sendErrorMessage(datagram, type=%d, code=%d)", type, code); // get ownership take(origDatagram); if (!validateDatagramPromptingError(origDatagram)) return; ICMPv6Message *errorMsg; if (type == ICMPv6_DESTINATION_UNREACHABLE) errorMsg = createDestUnreachableMsg(code); //TODO: implement MTU support. else if (type == ICMPv6_PACKET_TOO_BIG) errorMsg = createPacketTooBigMsg(0); else if (type == ICMPv6_TIME_EXCEEDED) errorMsg = createTimeExceededMsg(code); else if (type == ICMPv6_PARAMETER_PROBLEM) errorMsg = createParamProblemMsg(code); else error("Unknown ICMPv6 error type\n"); errorMsg->encapsulate(origDatagram); // debugging information EV << "sending ICMP error: (" << errorMsg->getClassName() << ")" << errorMsg->getName() << " type=" << type << " code=" << code << endl; // ICMP message length: the internet header plus the first 8 bytes of // the original datagram's data is returned to the sender //errorMessage->setByteLength(4 + origDatagram->getHeaderLength() + 8); FIXME What is this for? // 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 IPv6ControlInfo *ctrlInfo = new IPv6ControlInfo(); ctrlInfo->setSrcAddr(IPv6Address::LOOPBACK_ADDRESS); // FIXME maybe use configured loopback address ctrlInfo->setProtocol(IP_PROT_ICMP); errorMsg->setControlInfo(ctrlInfo); // then process it locally processICMPv6Message(errorMsg); } else { sendToIP(errorMsg, origDatagram->getSrcAddress()); } }
void ICMPv6::sendErrorMessage | ( | cPacket * | transportPacket, | |
IPv6ControlInfo * | ctrl, | |||
ICMPv6Type | type, | |||
int | 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 178 of file ICMPv6.cc.
{ Enter_Method("sendErrorMessage(transportPacket, ctrl, type=%d, code=%d)", type, code); IPv6Datagram *datagram = ctrl->removeOrigDatagram(); datagram->encapsulate(transportPacket); sendErrorMessage(datagram, type, code); }
void ICMPv6::sendToIP | ( | ICMPv6Message * | msg | ) | [protected, virtual] |
void ICMPv6::sendToIP | ( | ICMPv6Message * | msg, | |
const IPv6Address & | dest | |||
) | [protected, virtual] |
Definition at line 187 of file ICMPv6.cc.
Referenced by processEchoRequest(), sendEchoRequest(), and sendErrorMessage().
{ IPv6ControlInfo *ctrlInfo = new IPv6ControlInfo(); ctrlInfo->setDestAddr(dest); ctrlInfo->setProtocol(IP_PROT_IPv6_ICMP); msg->setControlInfo(ctrlInfo); send(msg,"ipv6Out"); }
bool ICMPv6::validateDatagramPromptingError | ( | IPv6Datagram * | datagram | ) | [protected, virtual] |
Validate the received IPv6 datagram before responding with error message.
Definition at line 238 of file ICMPv6.cc.
Referenced by sendErrorMessage().
{ // 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 false; } // do not reply with error message to error message if (origDatagram->getTransportProtocol() == IP_PROT_IPv6_ICMP) { ICMPv6Message *recICMPMsg = check_and_cast<ICMPv6Message *>(origDatagram->getEncapsulatedMsg()); if (recICMPMsg->getType()<128) { EV << "ICMP error received -- do not reply to it" << endl; delete origDatagram; return false; } } return true; }