# HG changeset patch # User Tom Henderson # Date 1227881127 28800 # Node ID 0339a8ad59837efd97f4914a707009c6554e006c # Parent 016c554c4f6d31d068b53b21c5730aec2904579f Bug 400: allow /32 addresses to be used on IPv4 interfaces diff -r 016c554c4f6d -r 0339a8ad5983 src/internet-stack/ipv4-l3-protocol.cc --- a/src/internet-stack/ipv4-l3-protocol.cc Wed Nov 26 14:00:05 2008 -0800 +++ b/src/internet-stack/ipv4-l3-protocol.cc Fri Nov 28 06:05:27 2008 -0800 @@ -852,6 +852,7 @@ Ipv4L3Protocol::DoForward (uint32_t ifIn Ptr icmp = GetIcmp (); icmp->SendTimeExceededTtl (ipHeader, packet); } + NS_LOG_WARN ("TTL exceeded. Drop."); m_dropTrace (packet); return; } diff -r 016c554c4f6d -r 0339a8ad5983 src/internet-stack/udp-socket-impl.cc --- a/src/internet-stack/udp-socket-impl.cc Wed Nov 26 14:00:05 2008 -0800 +++ b/src/internet-stack/udp-socket-impl.cc Fri Nov 28 06:05:27 2008 -0800 @@ -349,8 +349,13 @@ UdpSocketImpl::DoSendTo (Ptr p, } } // - // If dest is sent to the limited broadcast address (all ones), - // convert it to send a copy of the packet out of every interface + // If dest is set to the limited broadcast address (all ones), + // convert it to send a copy of the packet out of every + // interface as a subnet-directed broadcast. + // Exception: if the interface has a /32 address, there is no + // valid subnet-directed broadcast, so send it as limited broadcast + // Note also that some systems will only send limited broadcast packets + // out of the "default" interface; here we send it out all interfaces // if (dest.IsBroadcast ()) { @@ -359,13 +364,27 @@ UdpSocketImpl::DoSendTo (Ptr p, { Ipv4Address addri = ipv4->GetAddress (i); Ipv4Mask maski = ipv4->GetNetworkMask (i); - Ipv4Address bcast = addri.GetSubnetDirectedBroadcast (maski); - NS_LOG_LOGIC ("Sending one copy from " << addri << " to " << bcast - << " (mask is " << maski << ")"); - m_udp->Send (p->Copy (), addri, bcast, - m_endPoint->GetLocalPort (), port); - NotifyDataSent (p->GetSize ()); - NotifySend (GetTxAvailable ()); + if (maski == Ipv4Mask::GetOnes ()) + { + // if the network mask is 255.255.255.255, do not convert dest + NS_LOG_LOGIC ("Sending one copy from " << addri << " to " << dest + << " (mask is " << maski << ")"); + m_udp->Send (p->Copy (), addri, dest, + m_endPoint->GetLocalPort (), port); + NotifyDataSent (p->GetSize ()); + NotifySend (GetTxAvailable ()); + } + else + { + // Convert to subnet-directed broadcast + Ipv4Address bcast = addri.GetSubnetDirectedBroadcast (maski); + NS_LOG_LOGIC ("Sending one copy from " << addri << " to " << bcast + << " (mask is " << maski << ")"); + m_udp->Send (p->Copy (), addri, bcast, + m_endPoint->GetLocalPort (), port); + NotifyDataSent (p->GetSize ()); + NotifySend (GetTxAvailable ()); + } } NS_LOG_LOGIC ("Limited broadcast end."); return p->GetSize(); diff -r 016c554c4f6d -r 0339a8ad5983 src/node/ipv4-address.cc --- a/src/node/ipv4-address.cc Wed Nov 26 14:00:05 2008 -0800 +++ b/src/node/ipv4-address.cc Fri Nov 28 06:05:27 2008 -0800 @@ -77,7 +77,6 @@ Ipv4Mask::IsEqual (Ipv4Mask other) const } } - bool Ipv4Mask::IsMatch (Ipv4Address a, Ipv4Address b) const { @@ -125,6 +124,12 @@ Ipv4Mask::GetZero (void) { static Ipv4Mask zero = Ipv4Mask ("0.0.0.0"); return zero; +} +Ipv4Mask +Ipv4Mask::GetOnes (void) +{ + static Ipv4Mask ones = Ipv4Mask ("255.255.255.255"); + return ones; } Ipv4Address::Ipv4Address () @@ -164,12 +169,22 @@ Ipv4Address Ipv4Address Ipv4Address::GetSubnetDirectedBroadcast (Ipv4Mask const &mask) const { + if (mask == Ipv4Mask::GetOnes ()) + { + NS_ASSERT_MSG (false, "Trying to get subnet-directed broadcast address with an all-ones netmask"); + } return Ipv4Address (Get () | mask.GetInverse ()); } bool Ipv4Address::IsSubnetDirectedBroadcast (Ipv4Mask const &mask) const { + if (mask == Ipv4Mask::GetOnes ()) + { + // If the mask is 255.255.255.255, there is no subnet directed + // broadcast for this address. + return false; + } return ( (Get () | mask.GetInverse ()) == Get () ); } diff -r 016c554c4f6d -r 0339a8ad5983 src/node/ipv4-address.h --- a/src/node/ipv4-address.h Wed Nov 26 14:00:05 2008 -0800 +++ b/src/node/ipv4-address.h Fri Nov 28 06:05:27 2008 -0800 @@ -91,7 +91,7 @@ public: void Serialize (uint8_t buf[4]) const; /** * \param buf buffer to read address from - * \returns an Ipv4Address + * \return an Ipv4Address * * The input address is expected to be in network byte order format. */ @@ -103,8 +103,13 @@ public: * \param os The output stream to which this Ipv4Address is printed */ void Print (std::ostream &os) const; - + /** + * \return true if address is 255.255.255.255; false otherwise + */ bool IsBroadcast (void) const; + /** + * \return true only if address is in the range 224.0.0.0 - 239.255.255.255 + */ bool IsMulticast (void) const; /** * \brief Combine this address with a network mask @@ -120,20 +125,63 @@ public: * \brief Generate subnet-directed broadcast address corresponding to mask * * The subnet-directed broadcast address has the host bits set to all - * ones. + * ones. If this method is called with a mask of 255.255.255.255, + * (i.e., the address is a /32 address), the program will assert, since + * there is no subnet associated with a /32 address. * * \param mask a network mask */ Ipv4Address GetSubnetDirectedBroadcast (Ipv4Mask const &mask) const; + /** + * \brief Generate subnet-directed broadcast address corresponding to mask + * + * The subnet-directed broadcast address has the host bits set to all + * ones. If this method is called with a mask of 255.255.255.255, + * (i.e., the address is a /32 address), the program will assert, since + * there is no subnet associated with a /32 address. + * + * \param mask a network mask + * \return true if the address, when combined with the input mask, has all + * of its host bits set to one + */ bool IsSubnetDirectedBroadcast (Ipv4Mask const &mask) const; - + /** + * \param address an address to compare type with + * + * \return true if the type of the address stored internally + * is compatible with the type of the input address, false otherwise. + */ static bool IsMatchingType (const Address &address); + /** + * Convert an instance of this class to a polymorphic Address instance. + * + * \return a new Address instance + */ operator Address () const; + /** + * \param address a polymorphic address + * \return a new Ipv4Address from the polymorphic address + * + * This function performs a type check and asserts if the + * type of the input address is not compatible with an + * Ipv4Address. + */ static Ipv4Address ConvertFrom (const Address &address); - + /** + * \return the 0.0.0.0 address + */ static Ipv4Address GetZero (void); + /** + * \return the 0.0.0.0 address + */ static Ipv4Address GetAny (void); + /** + * \return the 255.255.255.255 address + */ static Ipv4Address GetBroadcast (void); + /** + * \return the 127.0.0.1 address + */ static Ipv4Address GetLoopback (void); private: @@ -156,9 +204,17 @@ public: Ipv4Mask (); Ipv4Mask (uint32_t mask); Ipv4Mask (char const *mask); - + /** + * \param a first address to compare + * \param b second address to compare + * \return true if both addresses are equal in their masked bits, + * corresponding to this mask + */ bool IsMatch (Ipv4Address a, Ipv4Address b) const; - + /** + * \param other a mask to compare + * \return true if the mask equals the mask passed as input parameter + */ bool IsEqual (Ipv4Mask other) const; /** * Get the host-order 32-bit IP mask @@ -174,11 +230,25 @@ public: * \brief Return the inverse mask in host order. */ uint32_t GetInverse (void) const; - + /** + * \brief Print this mask to the given output stream + * + * The print format is in the typical "255.255.255.0" + * \param os The output stream to which this Ipv4Address is printed + */ void Print (std::ostream &os) const; - + /** + * \return the 255.0.0.0 mask corresponding to a typical loopback address + */ static Ipv4Mask GetLoopback (void); + /** + * \return the 0.0.0.0 mask + */ static Ipv4Mask GetZero (void); + /** + * \return the 255.255.255.255 mask + */ + static Ipv4Mask GetOnes (void); private: uint32_t m_mask;