diff --git a/src/internet/model/tcp-l4-protocol.cc b/src/internet/model/tcp-l4-protocol.cc index ba861e55f..d2dca532a 100644 --- a/src/internet/model/tcp-l4-protocol.cc +++ b/src/internet/model/tcp-l4-protocol.cc @@ -285,6 +285,60 @@ TcpL4Protocol::DeAllocate (Ipv6EndPoint *endPoint) m_endPoints6->DeAllocate (endPoint); } +void +TcpL4Protocol::ReceiveIcmp (Ipv4Address icmpSource, uint8_t icmpTtl, + uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo, + Ipv4Address payloadSource,Ipv4Address payloadDestination, + const uint8_t payload[8]) +{ + NS_LOG_FUNCTION (this << icmpSource << icmpTtl << icmpType << icmpCode << icmpInfo + << payloadSource << payloadDestination); + uint16_t src, dst; + src = payload[0] << 8; + src |= payload[1]; + dst = payload[2] << 8; + dst |= payload[3]; + + Ipv4EndPoint *endPoint = m_endPoints->SimpleLookup (payloadSource, src, payloadDestination, dst); + if (endPoint != 0) + { + endPoint->ForwardIcmp (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo); + } + else + { + NS_LOG_DEBUG ("no endpoint found source=" << payloadSource << + ", destination="<SetRxCallback (MakeCallback (&TcpSocketBase::ForwardUp, Ptr (this))); + m_endPoint->SetIcmpCallback (MakeCallback (&TcpSocketBase::ForwardIcmp, Ptr (this))); m_endPoint->SetDestroyCallback (MakeCallback (&TcpSocketBase::Destroy, Ptr (this))); } if (m_endPoint6 != 0) { m_endPoint6->SetRxCallback (MakeCallback (&TcpSocketBase::ForwardUp6, Ptr (this))); + m_endPoint6->SetIcmpCallback (MakeCallback (&TcpSocketBase::ForwardIcmp6, Ptr (this))); m_endPoint6->SetDestroyCallback (MakeCallback (&TcpSocketBase::Destroy6, Ptr (this))); } @@ -772,6 +782,32 @@ TcpSocketBase::ForwardUp6 (Ptr packet, Ipv6Address saddr, Ipv6Address da DoForwardUp (packet, saddr, daddr, port); } +void +TcpSocketBase::ForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl, + uint8_t icmpType, uint8_t icmpCode, + uint32_t icmpInfo) +{ + NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType << + (uint32_t)icmpCode << icmpInfo); + if (!m_icmpCallback.IsNull ()) + { + m_icmpCallback (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo); + } +} + +void +TcpSocketBase::ForwardIcmp6 (Ipv6Address icmpSource, uint8_t icmpTtl, + uint8_t icmpType, uint8_t icmpCode, + uint32_t icmpInfo) +{ + NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType << + (uint32_t)icmpCode << icmpInfo); + if (!m_icmpCallback6.IsNull ()) + { + m_icmpCallback6 (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo); + } +} + /** The real function to handle the incoming packet from lower layers. This is wrapped by ForwardUp() so that this function can be overloaded by daughter classes. */ diff --git a/src/internet/model/tcp-socket-base.h b/src/internet/model/tcp-socket-base.h index ce6d4f25d..a77ab4646 100644 --- a/src/internet/model/tcp-socket-base.h +++ b/src/internet/model/tcp-socket-base.h @@ -138,6 +138,8 @@ protected: void ForwardUp6 (Ptr packet, Ipv6Address saddr, Ipv6Address daddr, uint16_t port); virtual void DoForwardUp (Ptr packet, Ipv4Header header, uint16_t port, Ptr incomingInterface); //Get a pkt from L3 virtual void DoForwardUp (Ptr packet, Ipv6Address saddr, Ipv6Address daddr, uint16_t port); // Ipv6 version + void ForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl, uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo); + void ForwardIcmp6 (Ipv6Address icmpSource, uint8_t icmpTtl, uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo); bool SendPendingData (bool withAck = false); // Send as much as the window allows uint32_t SendDataPacket (SequenceNumber32 seq, uint32_t maxSize, bool withAck); // Send a data packet void SendEmptyPacket (uint8_t flags); // Send a empty packet that carries a flag, e.g. ACK @@ -211,6 +213,8 @@ protected: Ipv6EndPoint* m_endPoint6; Ptr m_node; Ptr m_tcp; + Callback m_icmpCallback; + Callback m_icmpCallback6; // Round trip time estimation Ptr m_rtt;