Bug 400: allow /32 addresses to be used on IPv4 interfaces
authorTom Henderson <tomh@tomh.org>
Fri Nov 28 06:05:27 2008 -0800 (14 months ago)
changeset 3926c791fdb74629
parent 3925 9af06b55e945
child 3927 dce929afa491
Bug 400: allow /32 addresses to be used on IPv4 interfaces
src/internet-stack/udp-socket-impl.cc
src/node/ipv4-address.cc
src/node/ipv4-address.h
     1.1 --- a/src/internet-stack/udp-socket-impl.cc	Fri Nov 07 07:35:35 2008 -0800
     1.2 +++ b/src/internet-stack/udp-socket-impl.cc	Fri Nov 28 06:05:27 2008 -0800
     1.3 @@ -329,8 +329,13 @@
     1.4        p->AddTag (tag);
     1.5      }
     1.6    //
     1.7 -  // If dest is sent to the limited broadcast address (all ones),
     1.8 -  // convert it to send a copy of the packet out of every interface
     1.9 +  // If dest is set to the limited broadcast address (all ones),
    1.10 +  // convert it to send a copy of the packet out of every 
    1.11 +  // interface as a subnet-directed broadcast.
    1.12 +  // Exception:  if the interface has a /32 address, there is no
    1.13 +  // valid subnet-directed broadcast, so send it as limited broadcast
    1.14 +  // Note also that some systems will only send limited broadcast packets
    1.15 +  // out of the "default" interface; here we send it out all interfaces
    1.16    //
    1.17    if (dest.IsBroadcast ())
    1.18      {
    1.19 @@ -339,12 +344,27 @@
    1.20          {
    1.21            Ipv4Address addri = ipv4->GetAddress (i);
    1.22            Ipv4Mask maski = ipv4->GetNetworkMask (i);
    1.23 -          Ipv4Address bcast = addri.GetSubnetDirectedBroadcast (maski);
    1.24 -          NS_LOG_LOGIC ("Sending one copy from " << addri << " to " << bcast
    1.25 -                        << " (mask is " << maski << ")");
    1.26 -          m_udp->Send (p->Copy (), addri, bcast,
    1.27 -                       m_endPoint->GetLocalPort (), port);
    1.28 -          NotifyDataSent (p->GetSize ());
    1.29 +          if (maski == Ipv4Mask::GetOnes ())
    1.30 +            {
    1.31 +              // if the network mask is 255.255.255.255, do not convert dest
    1.32 +              NS_LOG_LOGIC ("Sending one copy from " << addri << " to " << dest
    1.33 +                            << " (mask is " << maski << ")");
    1.34 +              m_udp->Send (p->Copy (), addri, dest,
    1.35 +                           m_endPoint->GetLocalPort (), port);
    1.36 +              NotifyDataSent (p->GetSize ());
    1.37 +              NotifySend (GetTxAvailable ());
    1.38 +            }
    1.39 +          else
    1.40 +            {
    1.41 +              // Convert to subnet-directed broadcast
    1.42 +              Ipv4Address bcast = addri.GetSubnetDirectedBroadcast (maski);
    1.43 +              NS_LOG_LOGIC ("Sending one copy from " << addri << " to " << bcast
    1.44 +                            << " (mask is " << maski << ")");
    1.45 +              m_udp->Send (p->Copy (), addri, bcast,
    1.46 +                           m_endPoint->GetLocalPort (), port);
    1.47 +              NotifyDataSent (p->GetSize ());
    1.48 +              NotifySend (GetTxAvailable ());
    1.49 +            }
    1.50          }
    1.51        NS_LOG_LOGIC ("Limited broadcast end.");
    1.52        return p->GetSize();
     2.1 --- a/src/node/ipv4-address.cc	Fri Nov 07 07:35:35 2008 -0800
     2.2 +++ b/src/node/ipv4-address.cc	Fri Nov 28 06:05:27 2008 -0800
     2.3 @@ -77,7 +77,6 @@
     2.4    }
     2.5  }
     2.6  
     2.7 -
     2.8  bool 
     2.9  Ipv4Mask::IsMatch (Ipv4Address a, Ipv4Address b) const
    2.10  {
    2.11 @@ -126,6 +125,12 @@
    2.12    static Ipv4Mask zero = Ipv4Mask ("0.0.0.0");
    2.13    return zero;
    2.14  }
    2.15 +Ipv4Mask
    2.16 +Ipv4Mask::GetOnes (void)
    2.17 +{
    2.18 +  static Ipv4Mask ones = Ipv4Mask ("255.255.255.255");
    2.19 +  return ones;
    2.20 +}
    2.21  
    2.22  Ipv4Address::Ipv4Address ()
    2.23    : m_address (0x66666666)
    2.24 @@ -164,12 +169,22 @@
    2.25  Ipv4Address 
    2.26  Ipv4Address::GetSubnetDirectedBroadcast (Ipv4Mask const &mask) const
    2.27  {
    2.28 +  if (mask == Ipv4Mask::GetOnes ())
    2.29 +    {
    2.30 +      NS_ASSERT_MSG (false, "Trying to get subnet-directed broadcast address with an all-ones netmask");
    2.31 +    }
    2.32    return Ipv4Address (Get () | mask.GetInverse ());
    2.33  }
    2.34  
    2.35  bool
    2.36  Ipv4Address::IsSubnetDirectedBroadcast (Ipv4Mask const &mask) const
    2.37  {
    2.38 +  if (mask == Ipv4Mask::GetOnes ())
    2.39 +    {
    2.40 +      // If the mask is 255.255.255.255, there is no subnet directed
    2.41 +      // broadcast for this address.
    2.42 +      return false;
    2.43 +    }
    2.44    return ( (Get () | mask.GetInverse ()) == Get () );
    2.45  }
    2.46  
     3.1 --- a/src/node/ipv4-address.h	Fri Nov 07 07:35:35 2008 -0800
     3.2 +++ b/src/node/ipv4-address.h	Fri Nov 28 06:05:27 2008 -0800
     3.3 @@ -91,7 +91,7 @@
     3.4    void Serialize (uint8_t buf[4]) const;
     3.5    /**
     3.6     * \param buf buffer to read address from
     3.7 -   * \returns an Ipv4Address
     3.8 +   * \return an Ipv4Address
     3.9     * 
    3.10     * The input address is expected to be in network byte order format.
    3.11     */
    3.12 @@ -103,8 +103,13 @@
    3.13     * \param os The output stream to which this Ipv4Address is printed
    3.14     */
    3.15    void Print (std::ostream &os) const;
    3.16 -
    3.17 +  /**
    3.18 +    * \return true if address is 255.255.255.255; false otherwise
    3.19 +    */
    3.20    bool IsBroadcast (void) const;
    3.21 +  /**
    3.22 +    * \return true only if address is in the range 224.0.0.0 - 239.255.255.255
    3.23 +    */
    3.24    bool IsMulticast (void) const;
    3.25    /**
    3.26     * \brief Combine this address with a network mask
    3.27 @@ -120,20 +125,63 @@
    3.28     * \brief Generate subnet-directed broadcast address corresponding to mask
    3.29     *
    3.30     * The subnet-directed broadcast address has the host bits set to all
    3.31 -   * ones.
    3.32 +   * ones.  If this method is called with a mask of 255.255.255.255,
    3.33 +   * (i.e., the address is a /32 address), the program will assert, since
    3.34 +   * there is no subnet associated with a /32 address.
    3.35     *
    3.36     * \param mask a network mask 
    3.37     */
    3.38    Ipv4Address GetSubnetDirectedBroadcast (Ipv4Mask const &mask) const;
    3.39 +  /**
    3.40 +   * \brief Generate subnet-directed broadcast address corresponding to mask
    3.41 +   * 
    3.42 +   * The subnet-directed broadcast address has the host bits set to all
    3.43 +   * ones.  If this method is called with a mask of 255.255.255.255,
    3.44 +   * (i.e., the address is a /32 address), the program will assert, since
    3.45 +   * there is no subnet associated with a /32 address.
    3.46 +   *
    3.47 +   * \param mask a network mask 
    3.48 +   * \return true if the address, when combined with the input mask, has all
    3.49 +   * of its host bits set to one
    3.50 +   */
    3.51    bool IsSubnetDirectedBroadcast (Ipv4Mask const &mask) const;
    3.52 -
    3.53 +  /**
    3.54 +   * \param address an address to compare type with
    3.55 +   *
    3.56 +   * \return true if the type of the address stored internally
    3.57 +   * is compatible with the type of the input address, false otherwise.
    3.58 +   */
    3.59    static bool IsMatchingType (const Address &address);
    3.60 +  /**
    3.61 +   * Convert an instance of this class to a polymorphic Address instance.
    3.62 +   *
    3.63 +   * \return a new Address instance
    3.64 +   */
    3.65    operator Address () const;
    3.66 +  /**
    3.67 +   * \param address a polymorphic address
    3.68 +   * \return a new Ipv4Address from the polymorphic address
    3.69 +   *
    3.70 +   * This function performs a type check and asserts if the
    3.71 +   * type of the input address is not compatible with an
    3.72 +   * Ipv4Address.
    3.73 +   */
    3.74    static Ipv4Address ConvertFrom (const Address &address);
    3.75 -
    3.76 +  /**
    3.77 +   * \return the 0.0.0.0 address
    3.78 +   */
    3.79    static Ipv4Address GetZero (void);
    3.80 +  /**
    3.81 +   * \return the 0.0.0.0 address
    3.82 +   */
    3.83    static Ipv4Address GetAny (void);
    3.84 +  /**
    3.85 +   * \return the 255.255.255.255 address
    3.86 +   */
    3.87    static Ipv4Address GetBroadcast (void);
    3.88 +  /**
    3.89 +   * \return the 127.0.0.1 address
    3.90 +   */
    3.91    static Ipv4Address GetLoopback (void);
    3.92  
    3.93  private:
    3.94 @@ -156,9 +204,17 @@
    3.95    Ipv4Mask ();
    3.96    Ipv4Mask (uint32_t mask);
    3.97    Ipv4Mask (char const *mask);
    3.98 -
    3.99 +  /**
   3.100 +   * \param a first address to compare
   3.101 +   * \param b second address to compare
   3.102 +   * \return true if both addresses are equal in their masked bits, 
   3.103 +   * corresponding to this mask
   3.104 +   */
   3.105    bool IsMatch (Ipv4Address a, Ipv4Address b) const;
   3.106 -
   3.107 +  /**
   3.108 +   * \param other a mask to compare 
   3.109 +   * \return true if the mask equals the mask passed as input parameter
   3.110 +   */
   3.111    bool IsEqual (Ipv4Mask other) const;
   3.112    /** 
   3.113     * Get the host-order 32-bit IP mask
   3.114 @@ -174,11 +230,25 @@
   3.115     * \brief Return the inverse mask in host order. 
   3.116     */
   3.117    uint32_t GetInverse (void) const;
   3.118 -
   3.119 +  /**
   3.120 +   * \brief Print this mask to the given output stream
   3.121 +   *
   3.122 +   * The print format is in the typical "255.255.255.0"
   3.123 +   * \param os The output stream to which this Ipv4Address is printed
   3.124 +   */
   3.125    void Print (std::ostream &os) const;
   3.126 -
   3.127 +  /**
   3.128 +   * \return the 255.0.0.0 mask corresponding to a typical loopback address
   3.129 +   */
   3.130    static Ipv4Mask GetLoopback (void);
   3.131 +  /**
   3.132 +   * \return the 0.0.0.0 mask
   3.133 +   */
   3.134    static Ipv4Mask GetZero (void);
   3.135 +  /**
   3.136 +   * \return the 255.255.255.255 mask
   3.137 +   */
   3.138 +  static Ipv4Mask GetOnes (void);
   3.139  
   3.140  private:
   3.141    uint32_t m_mask;