@@ -20,8 +20,10 @@ namespace ns3
2020
2121NS_LOG_COMPONENT_DEFINE (" Address" );
2222
23+ Address::KindTypeRegistry Address::m_typeRegistry;
24+
2325Address::Address ()
24- : m_type(0 ),
26+ : m_type(UNASSIGNED_TYPE ),
2527 m_len (0 )
2628{
2729 // Buffer left uninitialized
@@ -33,7 +35,8 @@ Address::Address(uint8_t type, const uint8_t* buffer, uint8_t len)
3335 m_len(len)
3436{
3537 NS_LOG_FUNCTION (this << static_cast <uint32_t >(type) << &buffer << static_cast<uint32_t>(len));
36- NS_ASSERT (m_len <= MAX_SIZE);
38+ NS_ASSERT_MSG (m_len <= MAX_SIZE, " Address length too large" );
39+ NS_ASSERT_MSG (type != UNASSIGNED_TYPE, " Type 0 is reserved for uninitialized addresses." );
3740 std::memcpy (m_data, buffer, m_len);
3841}
3942
@@ -56,11 +59,29 @@ Address::operator=(const Address& address)
5659 return *this ;
5760}
5861
62+ void
63+ Address::SetType (const std::string& kind, uint8_t length)
64+ {
65+ NS_LOG_FUNCTION (this << kind << static_cast <uint32_t >(length));
66+ auto search = m_typeRegistry.find ({kind, length});
67+ NS_ASSERT_MSG (search != m_typeRegistry.end(),
68+ "No address with the given kind and length is registered.");
69+
70+ if (m_type != search->second )
71+ {
72+ NS_ASSERT_MSG (m_type == UNASSIGNED_TYPE,
73+ " You can only change the type of a type-0 address."
74+ << static_cast <uint32_t >(m_type));
75+
76+ m_type = search->second ;
77+ }
78+ }
79+
5980bool
6081Address::IsInvalid () const
6182{
6283 NS_LOG_FUNCTION (this );
63- return m_len == 0 && m_type == 0 ;
84+ return m_len == 0 && m_type == UNASSIGNED_TYPE ;
6485}
6586
6687uint8_t
@@ -95,7 +116,9 @@ uint32_t
95116Address::CopyFrom (const uint8_t * buffer, uint8_t len)
96117{
97118 NS_LOG_FUNCTION (this << &buffer << static_cast <uint32_t >(len));
98- NS_ASSERT (len <= MAX_SIZE);
119+ NS_ASSERT_MSG (m_len <= MAX_SIZE, " Address length too large" );
120+ NS_ASSERT_MSG (m_type != UNASSIGNED_TYPE,
121+ " Type-0 addresses are reserved. Please use SetType before using CopyFrom." );
99122 std::memcpy (m_data, buffer, len);
100123 m_len = len;
101124 return m_len;
@@ -119,9 +142,7 @@ Address::CheckCompatible(uint8_t type, uint8_t len) const
119142{
120143 NS_LOG_FUNCTION (this << static_cast <uint32_t >(type) << static_cast<uint32_t>(len));
121144 NS_ASSERT (len <= MAX_SIZE);
122- // / @internal
123- // / Mac address type/length detection is discussed in \bugid{1568}
124- return (m_len == len && m_type == type) || (m_len >= len && m_type == 0 );
145+ return (m_len == len && m_type == type);
125146}
126147
127148bool
@@ -132,12 +153,15 @@ Address::IsMatchingType(uint8_t type) const
132153}
133154
134155uint8_t
135- Address::Register ()
156+ Address::Register (const std::string& kind, uint8_t length )
136157{
137- NS_LOG_FUNCTION_NOARGS ();
138- static uint8_t type = 1 ;
139- type++;
140- return type;
158+ NS_LOG_FUNCTION (kind << length);
159+ static uint8_t lastRegisteredType = UNASSIGNED_TYPE;
160+ NS_ASSERT_MSG (m_typeRegistry.find({kind, length}) == m_typeRegistry.end(),
161+ "An address of the same kind and length is already registered.");
162+ lastRegisteredType++;
163+ m_typeRegistry[{kind, length}] = lastRegisteredType;
164+ return lastRegisteredType;
141165}
142166
143167uint32_t
@@ -171,16 +195,7 @@ ATTRIBUTE_HELPER_CPP(Address);
171195bool
172196operator ==(const Address& a, const Address& b)
173197{
174- /* Two addresses can be equal even if their types are
175- * different if one of the two types is zero. a type of
176- * zero identifies an Address which might contain meaningful
177- * payload but for which the type field could not be set because
178- * we did not know it. This can typically happen in the ARP
179- * layer where we receive an address from an ArpHeader but
180- * we do not know its type: we really want to be able to
181- * compare addresses without knowing their real type.
182- */
183- if (a.m_type != b.m_type && a.m_type != 0 && b.m_type != 0 )
198+ if (a.m_type != b.m_type )
184199 {
185200 return false ;
186201 }
@@ -238,8 +253,9 @@ operator<<(std::ostream& os, const Address& address)
238253 {
239254 return os;
240255 }
256+ std::ios_base::fmtflags ff = os.flags ();
257+ auto fill = os.fill (' 0' );
241258 os.setf (std::ios::hex, std::ios::basefield);
242- os.fill (' 0' );
243259 os << std::setw (2 ) << (uint32_t )address.m_type << " -" << std::setw (2 ) << (uint32_t )address.m_len
244260 << " -" ;
245261 for (uint8_t i = 0 ; i < (address.m_len - 1 ); ++i)
@@ -248,8 +264,8 @@ operator<<(std::ostream& os, const Address& address)
248264 }
249265 // Final byte not suffixed by ":"
250266 os << std::setw (2 ) << (uint32_t )address.m_data [address.m_len - 1 ];
251- os.setf (std::ios::dec, std::ios::basefield);
252- os.fill (' ' );
267+ os.flags (ff); // Restore stream flags
268+ os.fill (fill );
253269 return os;
254270}
255271
0 commit comments