From 073e685b0d8518336ca29d23d3d8e3e054f6672b Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 26 Jul 2007 14:03:41 +0200 Subject: [PATCH] new address types --- src/node/address.cc | 113 +++++++++++++++++++++++++++++ src/node/address.h | 43 +++++++++++ src/node/eui48-address.cc | 83 +++++++++++++++++++++ src/node/eui48-address.h | 25 +++++++ src/node/ipv4-address.cc | 41 ++++++++++- src/node/ipv4-address.h | 13 ++++ src/node/ipv4-transport-address.cc | 67 +++++++++++++++++ src/node/ipv4-transport-address.h | 33 +++++++++ src/node/wscript | 6 ++ 9 files changed, 422 insertions(+), 2 deletions(-) create mode 100644 src/node/address.cc create mode 100644 src/node/address.h create mode 100644 src/node/eui48-address.cc create mode 100644 src/node/eui48-address.h create mode 100644 src/node/ipv4-transport-address.cc create mode 100644 src/node/ipv4-transport-address.h diff --git a/src/node/address.cc b/src/node/address.cc new file mode 100644 index 000000000..a09129019 --- /dev/null +++ b/src/node/address.cc @@ -0,0 +1,113 @@ +#include "ns3/assert.h" +#include "address.h" +#include +#include + +namespace ns3 { + +Address::Address (uint8_t type, const uint8_t *buffer, uint8_t len) + : m_type (type), + m_len (len) +{ + NS_ASSERT (m_len <= MAX_SIZE); + memset (m_data, 0, m_len); + memcpy (m_data, buffer, m_len); +} +Address::Address (const Address & address) + : m_type (address.m_type), + m_len (address.m_len) +{ + NS_ASSERT (m_len <= MAX_SIZE); + memset (m_data, 0, m_len); + memcpy (m_data, address.m_data, m_len); +} +Address & +Address::operator = (const Address &address) +{ + NS_ASSERT (m_len <= MAX_SIZE); + m_type = address.m_type; + m_len = address.m_len; + NS_ASSERT (m_len <= MAX_SIZE); + memset (m_data, 0, m_len); + memcpy (m_data, address.m_data, m_len); + return *this; +} + +uint8_t +Address::GetLength (void) const +{ + NS_ASSERT (m_len <= MAX_SIZE); + return m_len; +} +void +Address::CopyTo (uint8_t *buffer) const +{ + NS_ASSERT (m_len <= MAX_SIZE); + memcpy (buffer, m_data, m_len); +} +uint8_t +Address::GetType (void) const +{ + NS_ASSERT (m_len <= MAX_SIZE); + return m_type; +} + +uint8_t +Address::Register (void) +{ + static uint8_t type = 1; + type++; + return type; +} + +bool operator == (const Address &a, const Address &b) +{ + NS_ASSERT (a.GetType () == b.GetType ()); + NS_ASSERT (a.GetLength() == b.GetLength()); + return memcmp (a.m_data, b.m_data, a.m_len) == 0; +} +bool operator != (const Address &a, const Address &b) +{ + return !(a == b); +} +bool operator < (const Address &a, const Address &b) +{ + NS_ASSERT (a.GetType () == b.GetType ()); + NS_ASSERT (a.GetLength() == b.GetLength()); + for (uint8_t i = 0; i < a.GetLength(); i++) + { + if (a.m_data[i] < b.m_data[i]) + { + return true; + } + else if (a.m_data[i] > b.m_data[i]) + { + return false; + } + } + return false; +} + +std::ostream& operator<< (std::ostream& os, const Address & address) +{ + if (address.m_len == 0) + { + os << "NULL-ADDRESS"; + return os; + } + os.setf (std::ios::hex, std::ios::basefield); + std::cout.fill('0'); + for (uint8_t i=0; i < (address.m_len-1); i++) + { + os << std::setw(2) << (uint32_t)address.m_data[i] << ":"; + } + // Final byte not suffixed by ":" + os << std::setw(2) << (uint32_t)address.m_data[address.m_len-1]; + os.setf (std::ios::dec, std::ios::basefield); + std::cout.fill(' '); + return os; +} + + + +} // namespace ns3 diff --git a/src/node/address.h b/src/node/address.h new file mode 100644 index 000000000..39551550d --- /dev/null +++ b/src/node/address.h @@ -0,0 +1,43 @@ +#ifndef ADDRESS_H +#define ADDRESS_H + +#include +#include + +namespace ns3 { + +class Address +{ +public: + Address (uint8_t type, const uint8_t *buffer, uint8_t len); + Address (const Address & address); + Address &operator = (const Address &address); + + uint8_t GetLength (void) const; + void CopyTo (uint8_t *buffer) const; + uint8_t GetType (void) const; + + static uint8_t Register (void); +private: + friend bool operator == (const Address &a, const Address &b); + friend bool operator < (const Address &a, const Address &b); + friend std::ostream& operator<< (std::ostream& os, const Address & address); + + Address (); + enum { + MAX_SIZE = 14 + }; + uint8_t m_type; + uint8_t m_len; + uint8_t m_data[MAX_SIZE]; +}; + +bool operator == (const Address &a, const Address &b); +bool operator != (const Address &a, const Address &b); +bool operator < (const Address &a, const Address &b); +std::ostream& operator<< (std::ostream& os, const Address & address); + +} // namespace ns3 + + +#endif /* ADDRESS_H */ diff --git a/src/node/eui48-address.cc b/src/node/eui48-address.cc new file mode 100644 index 000000000..6f9e86879 --- /dev/null +++ b/src/node/eui48-address.cc @@ -0,0 +1,83 @@ +#include "eui48-address.h" +#include "address.h" +#include "ns3/assert.h" + +namespace ns3 { + +#define ASCII_a (0x41) +#define ASCII_z (0x5a) +#define ASCII_A (0x61) +#define ASCII_Z (0x7a) +#define ASCII_COLON (0x3a) +#define ASCII_ZERO (0x30) + +static char +AsciiToLowCase (char c) +{ + if (c >= ASCII_a && c <= ASCII_z) { + return c; + } else if (c >= ASCII_A && c <= ASCII_Z) { + return c + (ASCII_a - ASCII_A); + } else { + return c; + } +} + + +Eui48Address::Eui48Address () +{ + memset (m_address, 0, 6); +} +Eui48Address::Eui48Address (const char *str) +{ + int i = 0; + while (*str != 0 && i < 6) + { + uint8_t byte = 0; + while (*str != ASCII_COLON && *str != 0) + { + byte <<= 4; + char low = AsciiToLowCase (*str); + if (low >= ASCII_a) + { + byte |= low - ASCII_a + 10; + } + else + { + byte |= low - ASCII_ZERO; + } + str++; + } + m_address[i] = byte; + i++; + if (*str == 0) + { + break; + } + str++; + } + NS_ASSERT (i == 6); +} +Address +Eui48Address::ConvertTo (void) const +{ + return Address (GetType (), m_address, 6); +} +Eui48Address +Eui48Address::ConvertFrom (const Address &address) +{ + NS_ASSERT (address.GetType () == GetType ()); + NS_ASSERT (address.GetLength () == 6); + Eui48Address retval; + address.CopyTo (retval.m_address); + return retval; +} +uint8_t +Eui48Address::GetType (void) +{ + static uint8_t type = Address::Register (); + return type; +} + + +} // namespace ns3 diff --git a/src/node/eui48-address.h b/src/node/eui48-address.h new file mode 100644 index 000000000..5f57971de --- /dev/null +++ b/src/node/eui48-address.h @@ -0,0 +1,25 @@ +#ifndef EUI48_ADDRESS_H +#define EUI48_ADDRESS_H + +#include + +namespace ns3 { + +class Address; + +class Eui48Address +{ +public: + Eui48Address (); + Eui48Address (const char *str); + Address ConvertTo (void) const; + static Eui48Address ConvertFrom (const Address &address); +private: + static uint8_t GetType (void); + uint8_t m_address[6]; + +}; + +} // namespace ns3 + +#endif /* EUI48_ADDRESS_H */ diff --git a/src/node/ipv4-address.cc b/src/node/ipv4-address.cc index f8ff9f7a6..70b0ff486 100644 --- a/src/node/ipv4-address.cc +++ b/src/node/ipv4-address.cc @@ -19,11 +19,11 @@ * Author: Mathieu Lacage */ #include "ns3/debug.h" +#include "ipv4-address.h" +#include "ns3/assert.h" NS_DEBUG_COMPONENT_DEFINE("Ipv4Address"); -#include "ipv4-address.h" - namespace ns3 { @@ -170,6 +170,20 @@ Ipv4Address::Serialize (uint8_t buf[4]) const buf[2] = (m_address >> 8) & 0xff; buf[3] = (m_address >> 0) & 0xff; } +Ipv4Address +Ipv4Address::Deserialize (const uint8_t buf[4]) +{ + Ipv4Address ipv4; + ipv4.m_address = 0; + ipv4.m_address |= buf[0]; + ipv4.m_address <<= 8; + ipv4.m_address |= buf[1]; + ipv4.m_address <<= 8; + ipv4.m_address |= buf[2]; + ipv4.m_address <<= 8; + ipv4.m_address |= buf[3]; + return ipv4; +} void Ipv4Address::Print (std::ostream &os) const @@ -180,7 +194,30 @@ Ipv4Address::Print (std::ostream &os) const << ((m_address >> 0) & 0xff); } +Address +Ipv4Address::ConvertTo (void) const +{ + uint8_t buf[4]; + Serialize (buf); + return Address (GetType (), buf, 4); +} +Ipv4Address +Ipv4Address::ConvertFrom (const Address &address) +{ + NS_ASSERT (address.GetType () == GetType ()); + NS_ASSERT (address.GetLength () == 4); + uint8_t buf[4]; + address.CopyTo (buf); + return Deserialize (buf); +} + +uint8_t +Ipv4Address::GetType (void) +{ + static uint8_t type = Address::Register (); + return type; +} Ipv4Address Ipv4Address::GetZero (void) diff --git a/src/node/ipv4-address.h b/src/node/ipv4-address.h index dc834052a..2012d2f78 100644 --- a/src/node/ipv4-address.h +++ b/src/node/ipv4-address.h @@ -24,6 +24,7 @@ #include #include +#include "address.h" namespace ns3 { @@ -68,10 +69,18 @@ public: void SetHostOrder (uint32_t ip); /** * Serialize this address to a 4-byte buffer + * * \param buf output buffer to which this address gets overwritten with this * Ipv4Address */ void Serialize (uint8_t buf[4]) const; + /** + * \param buf buffer to read address from + * \returns an Ipv4Address + * + * The input address is expected to be in network byte order format. + */ + static Ipv4Address Deserialize (const uint8_t buf[4]); /** * \brief Print this address to the given output stream * @@ -83,11 +92,15 @@ public: bool IsBroadcast (void); bool IsMulticast (void); + Address ConvertTo (void) const; + static Ipv4Address ConvertFrom (const Address &address); + static Ipv4Address GetZero (void); static Ipv4Address GetAny (void); static Ipv4Address GetBroadcast (void); static Ipv4Address GetLoopback (void); private: + static uint8_t GetType (void); uint32_t m_address; }; diff --git a/src/node/ipv4-transport-address.cc b/src/node/ipv4-transport-address.cc new file mode 100644 index 000000000..b088a1017 --- /dev/null +++ b/src/node/ipv4-transport-address.cc @@ -0,0 +1,67 @@ +#include "ipv4-transport-address.h" +#include "ns3/assert.h" + +namespace ns3 { + +Ipv4TransportAddress::Ipv4TransportAddress (Ipv4Address ipv4, uint16_t port) + : m_ipv4 (ipv4), + m_port (port) +{} +Ipv4TransportAddress::Ipv4TransportAddress (Ipv4Address ipv4) + : m_ipv4 (ipv4), + m_port (0) +{} +Ipv4TransportAddress::Ipv4TransportAddress (uint16_t port) + : m_ipv4 (Ipv4Address::GetAny ()), + m_port (port) +{} +uint16_t +Ipv4TransportAddress::GetPort (void) const +{ + return m_port; +} +Ipv4Address +Ipv4TransportAddress::GetIpv4 (void) const +{ + return m_ipv4; +} + +void +Ipv4TransportAddress::SetPort (uint16_t port) +{ + m_port = port; +} +void +Ipv4TransportAddress::SetIpv4 (Ipv4Address address) +{ + m_ipv4 = address; +} + +Address +Ipv4TransportAddress::ConvertTo (void) const +{ + uint8_t buf[6]; + m_ipv4.Serialize (buf); + buf[4] = m_port & 0xff; + buf[5] = (m_port >> 8) & 0xff; + return Address (GetType (), buf, 6); +} +Ipv4TransportAddress +Ipv4TransportAddress::ConvertFrom (const Address &address) +{ + NS_ASSERT (address.GetType () == GetType ()); + NS_ASSERT (address.GetLength () == 6); + uint8_t buf[6]; + address.CopyTo (buf); + Ipv4Address ipv4 = Ipv4Address::Deserialize (buf); + uint16_t port = buf[0] | (buf[1] << 8); + return Ipv4TransportAddress (ipv4, port); +} +uint8_t +Ipv4TransportAddress::GetType (void) +{ + static uint8_t type = Address::Register (); + return type; +} + +} // namespace ns3 diff --git a/src/node/ipv4-transport-address.h b/src/node/ipv4-transport-address.h new file mode 100644 index 000000000..e73ca8d3d --- /dev/null +++ b/src/node/ipv4-transport-address.h @@ -0,0 +1,33 @@ +#ifndef IPV4_TRANSPORT_ADDRESS_H +#define IPV4_TRANSPORT_ADDRESS_H + +#include "address.h" +#include "ipv4-address.h" +#include + +namespace ns3 { + +class Ipv4TransportAddress +{ +public: + Ipv4TransportAddress (Ipv4Address ipv4, uint16_t port); + Ipv4TransportAddress (Ipv4Address ipv4); + Ipv4TransportAddress (uint16_t post); + uint16_t GetPort (void) const; + Ipv4Address GetIpv4 (void) const; + + void SetPort (uint16_t post); + void SetIpv4 (Ipv4Address address); + + Address ConvertTo (void) const; + static Ipv4TransportAddress ConvertFrom (const Address &address); +private: + static uint8_t GetType (void); + Ipv4Address m_ipv4; + uint16_t m_port; +}; + +} // namespace ns3 + + +#endif /* IPV4_TRANSPORT_ADDRESS_H */ diff --git a/src/node/wscript b/src/node/wscript index 0a5c64aa9..e11cd8eac 100644 --- a/src/node/wscript +++ b/src/node/wscript @@ -6,6 +6,9 @@ def build(bld): node.target = node.name node.uselib_local = ['ns3-core', 'ns3-common', 'ns3-simulator'] node.source = [ + 'address.cc', + 'eui48-address.cc', + 'ipv4-transport-address.cc', 'node.cc', 'ipv4-address.cc', 'net-device.cc', @@ -26,6 +29,9 @@ def build(bld): headers = bld.create_obj('ns3header') headers.source = [ + 'address.h', + 'eui48-address.h', + 'ipv4-transport-address.h', 'node.h', 'ipv4-address.h', 'net-device.h',