1 #include "icmpv4-l4-protocol.h"
2 #include "ipv4-raw-socket-factory-impl.h"
3 #include "ipv4-interface.h"
4 #include "ipv4-l3-protocol.h"
5 #include "ns3/assert.h"
8 #include "ns3/packet.h"
9 #include "ns3/boolean.h"
10 #include "ns3/ipv4-route.h"
16 NS_OBJECT_ENSURE_REGISTERED (Icmpv4L4Protocol);
19 const uint8_t Icmpv4L4Protocol::PROT_NUMBER = 1;
22 Icmpv4L4Protocol::GetTypeId (
void)
24 static TypeId tid = TypeId (
"ns3::Icmpv4L4Protocol")
25 .SetParent<IpL4Protocol> ()
26 .AddConstructor<Icmpv4L4Protocol> ()
31 Icmpv4L4Protocol::Icmpv4L4Protocol ()
36 Icmpv4L4Protocol::~Icmpv4L4Protocol ()
43 Icmpv4L4Protocol::SetNode (Ptr<Node> node)
60 Ptr<Node> node = this->GetObject<Node> ();
63 Ptr<Ipv4> ipv4 = this->GetObject<Ipv4> ();
64 if (ipv4 != 0 && m_downTarget.IsNull ())
69 ipv4->AggregateObject (rawFactory);
78 Icmpv4L4Protocol::GetStaticProtocolNumber (
void)
93 NS_LOG_FUNCTION (
this << packet << dest << static_cast<uint32_t> (type) << static_cast<uint32_t> (code));
95 NS_ASSERT (ipv4 != 0 && ipv4->GetRoutingProtocol () != 0);
98 header.SetProtocol (PROT_NUMBER);
99 Socket::SocketErrno errno_;
102 route = ipv4->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
107 SendMessage (packet, source, dest, type, code, route);
116 Icmpv4L4Protocol::SendMessage (Ptr<Packet> packet, Ipv4Address source, Ipv4Address dest, uint8_t type, uint8_t code, Ptr<Ipv4Route> route)
118 NS_LOG_FUNCTION (
this << packet << source << dest << static_cast<uint32_t> (type) << static_cast<uint32_t> (code) << route);
124 icmp.EnableChecksum ();
126 packet->AddHeader (icmp);
128 m_downTarget (packet, source, dest, PROT_NUMBER, route);
131 Icmpv4L4Protocol::SendDestUnreachFragNeeded (Ipv4Header header,
132 Ptr<const Packet> orgData,
136 SendDestUnreach (header, orgData, Icmpv4DestinationUnreachable::FRAG_NEEDED, nextHopMtu);
139 Icmpv4L4Protocol::SendDestUnreachPort (Ipv4Header header,
140 Ptr<const Packet> orgData)
143 SendDestUnreach (header, orgData, Icmpv4DestinationUnreachable::PORT_UNREACHABLE, 0);
146 Icmpv4L4Protocol::SendDestUnreach (Ipv4Header header, Ptr<const Packet> orgData,
147 uint8_t code, uint16_t nextHopMtu)
149 NS_LOG_FUNCTION (
this << header << *orgData << (uint32_t) code << nextHopMtu);
150 Ptr<Packet> p = Create<Packet> ();
151 Icmpv4DestinationUnreachable unreach;
152 unreach.SetNextHopMtu (nextHopMtu);
153 unreach.SetHeader (header);
154 unreach.SetData (orgData);
155 p->AddHeader (unreach);
156 SendMessage (p, header.GetSource (), Icmpv4Header::DEST_UNREACH, code);
160 Icmpv4L4Protocol::SendTimeExceededTtl (Ipv4Header header, Ptr<const Packet> orgData)
163 Ptr<Packet> p = Create<Packet> ();
164 Icmpv4TimeExceeded time;
165 time.SetHeader (header);
166 time.SetData (orgData);
168 SendMessage (p, header.GetSource (), Icmpv4Header::TIME_EXCEEDED, Icmpv4TimeExceeded::TIME_TO_LIVE);
172 Icmpv4L4Protocol::HandleEcho (Ptr<Packet> p,
175 Ipv4Address destination)
179 Ptr<Packet> reply = Create<Packet> ();
181 p->RemoveHeader (echo);
182 reply->AddHeader (echo);
183 SendMessage (reply, destination, source, Icmpv4Header::ECHO_REPLY, 0, 0);
186 Icmpv4L4Protocol::Forward (Ipv4Address source, Icmpv4Header icmp,
187 uint32_t info, Ipv4Header ipHeader,
188 const uint8_t payload[8])
190 NS_LOG_FUNCTION (
this << source << icmp << info << ipHeader << payload);
192 Ptr<Ipv4> ipv4 = m_node->
GetObject<Ipv4> ();
193 Ptr<IpL4Protocol> l4 = ipv4->GetProtocol (ipHeader.GetProtocol ());
196 l4->ReceiveIcmp (source, ipHeader.GetTtl (), icmp.GetType (), icmp.GetCode (),
197 info, ipHeader.GetSource (), ipHeader.GetDestination (), payload);
201 Icmpv4L4Protocol::HandleDestUnreach (Ptr<Packet> p,
204 Ipv4Address destination)
208 Icmpv4DestinationUnreachable unreach;
209 p->PeekHeader (unreach);
211 unreach.GetData (payload);
212 Ipv4Header ipHeader = unreach.GetHeader ();
213 Forward (source, icmp, unreach.GetNextHopMtu (), ipHeader, payload);
216 Icmpv4L4Protocol::HandleTimeExceeded (Ptr<Packet> p,
219 Ipv4Address destination)
223 Icmpv4TimeExceeded time;
224 p->PeekHeader (time);
226 time.GetData (payload);
227 Ipv4Header ipHeader = time.GetHeader ();
229 Forward (source, icmp, 0, ipHeader, payload);
232 enum IpL4Protocol::RxStatus
241 switch (icmp.GetType ()) {
242 case Icmpv4Header::ECHO:
245 case Icmpv4Header::DEST_UNREACH:
248 case Icmpv4Header::TIME_EXCEEDED:
255 return IpL4Protocol::RX_OK;
257 enum IpL4Protocol::RxStatus
263 return IpL4Protocol::RX_ENDPOINT_UNREACH;
270 m_downTarget.Nullify ();
278 m_downTarget = callback;
287 IpL4Protocol::DownTargetCallback
295 Icmpv4L4Protocol::GetDownTarget6 (
void)
const
uint32_t RemoveHeader(Header &header)
#define NS_LOG_FUNCTION(parameters)
static bool ChecksumEnabled(void)
#define NS_ASSERT(condition)
#define NS_LOG_COMPONENT_DEFINE(name)
virtual void DoDispose(void)
#define NS_LOG_FUNCTION_NOARGS()
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Ipv4Address GetSource(void) const
#define NS_LOG_LOGIC(msg)
virtual IpL4Protocol::DownTargetCallback GetDownTarget(void) const
virtual void NotifyNewAggregate(void)
Access to the Ipv4 forwarding table, interfaces, and configuration.
virtual int GetProtocolNumber(void) const
virtual void Send(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, uint8_t protocol, Ptr< Ipv4Route > route)=0
virtual void NotifyNewAggregate()
virtual enum IpL4Protocol::RxStatus Receive(Ptr< Packet > p, Ipv4Header const &header, Ptr< Ipv4Interface > incomingInterface)
Ipv4 addresses are stored in host order in this class.
virtual void DoDispose(void)
#define NS_LOG_DEBUG(msg)
Ptr< T > GetObject(void) const
virtual void SetDownTarget(IpL4Protocol::DownTargetCallback cb)