From 520865a919cc1ffa97bc449c62a45a84b20274f7 Mon Sep 17 00:00:00 2001 From: Tommaso Pecorella Date: Fri, 25 Nov 2022 19:23:37 +0100 Subject: [PATCH] internet: fixes to IPv4 subnet-directed broadcast --- RELEASE_NOTES.md | 7 +++-- src/internet/model/icmpv4-l4-protocol.cc | 30 ++++++++++++++++++++-- src/internet/model/ipv4-raw-socket-impl.cc | 18 ++++++++++--- src/network/utils/ipv4-address.cc | 2 +- 4 files changed, 48 insertions(+), 9 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index ef9ea0735..b76fb58b0 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -19,13 +19,16 @@ Release 3-dev ### New user-visible features - (network) !938 - Add class `TimestampTag` for associating a timestamp with a packet. -- (network) !1163 Initializing an Ipv[4,6]Address from an invalid string do not raise an exception anymore. Instead the address is marked as not initialized. -- (internet) !1186 `TcpWestwood` model has been removed, and the class has been renamed `TcpWestwoodPlus`. +- (network) !1163 - Initializing an Ipv[4,6]Address from an invalid string do not raise an exception anymore. Instead the address is marked as not initialized. +- (internet) !1186 - `TcpWestwood` model has been removed, and the class has been renamed `TcpWestwoodPlus`. +- (internet) !1229 - You can now ping broadcast addresses. ### Bugs fixed - (build) #808 - Handle profile setting changes in the first ns3 run - (build) #815 - Configure find_program to search for programs in PATH first, then AppBundles in MacOS +- (network) !1229 - Fixed a bug in `Ipv4Address::IsSubnetDirectedBroadcast` +- (internet) !1229 - Fixed a bug in `Icmpv4Header::HandleEcho` when replying to broadcast-type Echo requests, and two bugs in `Ipv4RawSocketImpl::SendTo` in handling sockets bound to a specific address and directed to a broadcast-type address. Release 3.37 ------------ diff --git a/src/internet/model/icmpv4-l4-protocol.cc b/src/internet/model/icmpv4-l4-protocol.cc index a6526bc90..a93fe75c9 100644 --- a/src/internet/model/icmpv4-l4-protocol.cc +++ b/src/internet/model/icmpv4-l4-protocol.cc @@ -300,9 +300,35 @@ Icmpv4L4Protocol::Receive(Ptr p, p->RemoveHeader(icmp); switch (icmp.GetType()) { - case Icmpv4Header::ICMPV4_ECHO: - HandleEcho(p, icmp, header.GetSource(), header.GetDestination()); + case Icmpv4Header::ICMPV4_ECHO: { + Ipv4Address dst = header.GetDestination(); + // We could have received an Echo request to a broadcast-type address. + if (dst.IsBroadcast()) + { + Ipv4Address src = header.GetSource(); + for (uint32_t index = 0; index < incomingInterface->GetNAddresses(); index++) + { + Ipv4InterfaceAddress addr = incomingInterface->GetAddress(index); + if (addr.IsInSameSubnet(src)) + { + dst = addr.GetAddress(); + } + } + } + else + { + for (uint32_t index = 0; index < incomingInterface->GetNAddresses(); index++) + { + Ipv4InterfaceAddress addr = incomingInterface->GetAddress(index); + if (dst == addr.GetBroadcast()) + { + dst = addr.GetAddress(); + } + } + } + HandleEcho(p, icmp, header.GetSource(), dst); break; + } case Icmpv4Header::ICMPV4_DEST_UNREACH: HandleDestUnreach(p, icmp, header.GetSource(), header.GetDestination()); break; diff --git a/src/internet/model/ipv4-raw-socket-impl.cc b/src/internet/model/ipv4-raw-socket-impl.cc index 94c68d99b..c490f2177 100644 --- a/src/internet/model/ipv4-raw-socket-impl.cc +++ b/src/internet/model/ipv4-raw-socket-impl.cc @@ -275,10 +275,19 @@ Ipv4RawSocketImpl::SendTo(Ptr p, uint32_t flags, const Address& toAddres p->AddPacketTag(tag); } - bool subnetDirectedBroadcast = false; - if (m_boundnetdevice) + Ptr boundNetDevice = m_boundnetdevice; + + if (!m_src.IsAny()) { - uint32_t iif = ipv4->GetInterfaceForDevice(m_boundnetdevice); + int32_t index = ipv4->GetInterfaceForAddress(m_src); + NS_ASSERT(index >= 0); + boundNetDevice = ipv4->GetNetDevice(index); + } + + bool subnetDirectedBroadcast = false; + if (boundNetDevice) + { + uint32_t iif = ipv4->GetInterfaceForDevice(boundNetDevice); for (uint32_t j = 0; j < ipv4->GetNAddresses(iif); j++) { Ipv4InterfaceAddress ifAddr = ipv4->GetAddress(iif, j); @@ -291,7 +300,6 @@ Ipv4RawSocketImpl::SendTo(Ptr p, uint32_t flags, const Address& toAddres if (dst.IsBroadcast() || subnetDirectedBroadcast) { - Ptr boundNetDevice = m_boundnetdevice; if (ipv4->GetNInterfaces() == 1) { boundNetDevice = ipv4->GetNetDevice(0); @@ -312,6 +320,7 @@ Ipv4RawSocketImpl::SendTo(Ptr p, uint32_t flags, const Address& toAddres route->SetSource(src); route->SetDestination(dst); route->SetOutputDevice(boundNetDevice); + route->SetGateway("0.0.0.0"); ipv4->Send(p, route->GetSource(), dst, m_protocol, route); } else @@ -324,6 +333,7 @@ Ipv4RawSocketImpl::SendTo(Ptr p, uint32_t flags, const Address& toAddres route->SetSource(src); route->SetDestination(dst); route->SetOutputDevice(boundNetDevice); + route->SetGateway("0.0.0.0"); ipv4->SendWithHeader(p, header, route); } NotifyDataSent(pktSize); diff --git a/src/network/utils/ipv4-address.cc b/src/network/utils/ipv4-address.cc index 5c48d8a12..9a84b6d14 100644 --- a/src/network/utils/ipv4-address.cc +++ b/src/network/utils/ipv4-address.cc @@ -248,7 +248,7 @@ Ipv4Address::IsSubnetDirectedBroadcast(const Ipv4Mask& mask) const // broadcast for this address. return false; } - return ((Get() | mask.GetInverse()) == Get()); + return ((Get() | mask.Get()) == Ipv4Address::GetBroadcast().Get()); } bool