bug 1359 TCP cannot receive ICMP

This commit is contained in:
Tommaso Pecorella
2012-09-27 13:29:03 -04:00
parent bb73887e20
commit b95fa01125
4 changed files with 114 additions and 0 deletions

View File

@@ -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="<<payloadDestination<<
", src=" << src << ", dst=" << dst);
}
}
void
TcpL4Protocol::ReceiveIcmp (Ipv6Address icmpSource, uint8_t icmpTtl,
uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
Ipv6Address payloadSource,Ipv6Address 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];
Ipv6EndPoint *endPoint = m_endPoints6->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="<<payloadDestination<<
", src=" << src << ", dst=" << dst);
}
}
enum IpL4Protocol::RxStatus
TcpL4Protocol::Receive (Ptr<Packet> packet,
Ipv4Header const &ipHeader,

View File

@@ -119,6 +119,26 @@ public:
Ipv6Address &dst,
Ptr<Ipv6Interface> interface);
/**
* \brief Receive an ICMP packet
* \param icmpSource The IP address of the source of the packet.
* \param icmpTtl The time to live from the IP header
* \param icmpType The type of the message from the ICMP header
* \param icmpCode The message code from the ICMP header
* \param icmpInfo 32-bit integer carrying informational value of varying semantics.
* \param payloadSource The IP source address from the IP header of the packet
* \param payloadDestination The IP destination address from the IP header of the packet
* \param payload Payload of the ICMP packet
*/
virtual void ReceiveIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
Ipv4Address payloadSource,Ipv4Address payloadDestination,
const uint8_t payload[8]);
virtual void ReceiveIcmp (Ipv6Address icmpSource, uint8_t icmpTtl,
uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
Ipv6Address payloadSource,Ipv6Address payloadDestination,
const uint8_t payload[8]);
// From IpL4Protocol
virtual void SetDownTarget (IpL4Protocol::DownTargetCallback cb);
virtual void SetDownTarget6 (IpL4Protocol::DownTargetCallback6 cb);

View File

@@ -75,6 +75,14 @@ TcpSocketBase::GetTypeId (void)
UintegerValue (65535),
MakeUintegerAccessor (&TcpSocketBase::m_maxWinSize),
MakeUintegerChecker<uint16_t> ())
.AddAttribute ("IcmpCallback", "Callback invoked whenever an icmp error is received on this socket.",
CallbackValue (),
MakeCallbackAccessor (&TcpSocketBase::m_icmpCallback),
MakeCallbackChecker ())
.AddAttribute ("IcmpCallback6", "Callback invoked whenever an icmpv6 error is received on this socket.",
CallbackValue (),
MakeCallbackAccessor (&TcpSocketBase::m_icmpCallback6),
MakeCallbackChecker ())
.AddTraceSource ("RTO",
"Retransmission timeout",
MakeTraceSourceAccessor (&TcpSocketBase::m_rto))
@@ -640,11 +648,13 @@ TcpSocketBase::SetupCallback (void)
if (m_endPoint != 0)
{
m_endPoint->SetRxCallback (MakeCallback (&TcpSocketBase::ForwardUp, Ptr<TcpSocketBase> (this)));
m_endPoint->SetIcmpCallback (MakeCallback (&TcpSocketBase::ForwardIcmp, Ptr<TcpSocketBase> (this)));
m_endPoint->SetDestroyCallback (MakeCallback (&TcpSocketBase::Destroy, Ptr<TcpSocketBase> (this)));
}
if (m_endPoint6 != 0)
{
m_endPoint6->SetRxCallback (MakeCallback (&TcpSocketBase::ForwardUp6, Ptr<TcpSocketBase> (this)));
m_endPoint6->SetIcmpCallback (MakeCallback (&TcpSocketBase::ForwardIcmp6, Ptr<TcpSocketBase> (this)));
m_endPoint6->SetDestroyCallback (MakeCallback (&TcpSocketBase::Destroy6, Ptr<TcpSocketBase> (this)));
}
@@ -772,6 +782,32 @@ TcpSocketBase::ForwardUp6 (Ptr<Packet> 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. */

View File

@@ -138,6 +138,8 @@ protected:
void ForwardUp6 (Ptr<Packet> packet, Ipv6Address saddr, Ipv6Address daddr, uint16_t port);
virtual void DoForwardUp (Ptr<Packet> packet, Ipv4Header header, uint16_t port, Ptr<Ipv4Interface> incomingInterface); //Get a pkt from L3
virtual void DoForwardUp (Ptr<Packet> 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<Node> m_node;
Ptr<TcpL4Protocol> m_tcp;
Callback<void, Ipv4Address,uint8_t,uint8_t,uint8_t,uint32_t> m_icmpCallback;
Callback<void, Ipv6Address,uint8_t,uint8_t,uint8_t,uint32_t> m_icmpCallback6;
// Round trip time estimation
Ptr<RttEstimator> m_rtt;