merge with trunk
This commit is contained in:
@@ -26,24 +26,34 @@ void WriteTo (Buffer::Iterator &i, Ipv4Address ad)
|
||||
{
|
||||
i.WriteHtonU32 (ad.GetHostOrder ());
|
||||
}
|
||||
void WriteTo (Buffer::Iterator &i, MacAddress ad)
|
||||
void WriteTo (Buffer::Iterator &i, const Address &ad)
|
||||
{
|
||||
uint8_t mac[MacAddress::MAX_LEN];
|
||||
ad.Peek (mac);
|
||||
uint8_t mac[Address::MAX_SIZE];
|
||||
ad.CopyTo (mac);
|
||||
i.Write (mac, ad.GetLength ());
|
||||
}
|
||||
void WriteTo (Buffer::Iterator &i, Eui48Address ad)
|
||||
{
|
||||
uint8_t mac[6];
|
||||
ad.CopyTo (mac);
|
||||
i.Write (mac, 6);
|
||||
}
|
||||
|
||||
void ReadFrom (Buffer::Iterator &i, Ipv4Address &ad)
|
||||
{
|
||||
ad.SetHostOrder (i.ReadNtohU32 ());
|
||||
}
|
||||
void ReadFrom (Buffer::Iterator &i, MacAddress &ad, uint32_t len)
|
||||
void ReadFrom (Buffer::Iterator &i, Address &ad, uint32_t len)
|
||||
{
|
||||
uint8_t mac[MacAddress::MAX_LEN];
|
||||
uint8_t mac[Address::MAX_SIZE];
|
||||
i.Read (mac, len);
|
||||
ad.Set (mac, len);
|
||||
ad.CopyFrom (mac, len);
|
||||
}
|
||||
void ReadFrom (Buffer::Iterator &i, Eui48Address &ad)
|
||||
{
|
||||
uint8_t mac[6];
|
||||
i.Read (mac, 6);
|
||||
ad.CopyFrom (mac);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}; // namespace ns3
|
||||
} // namespace ns3
|
||||
|
||||
@@ -22,16 +22,19 @@
|
||||
#define ADDRESS_UTILS_H
|
||||
|
||||
#include "ns3/buffer.h"
|
||||
#include "ns3/ipv4-address.h"
|
||||
#include "ns3/mac-address.h"
|
||||
#include "ipv4-address.h"
|
||||
#include "address.h"
|
||||
#include "eui48-address.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
void WriteTo (Buffer::Iterator &i, Ipv4Address ad);
|
||||
void WriteTo (Buffer::Iterator &i, MacAddress ad);
|
||||
void WriteTo (Buffer::Iterator &i, const Address &ad);
|
||||
void WriteTo (Buffer::Iterator &i, Eui48Address ad);
|
||||
|
||||
void ReadFrom (Buffer::Iterator &i, Ipv4Address &ad);
|
||||
void ReadFrom (Buffer::Iterator &i, MacAddress &ad, uint32_t len);
|
||||
void ReadFrom (Buffer::Iterator &i, Address &ad, uint32_t len);
|
||||
void ReadFrom (Buffer::Iterator &i, Eui48Address &ad);
|
||||
|
||||
};
|
||||
|
||||
|
||||
164
src/node/address.cc
Normal file
164
src/node/address.cc
Normal file
@@ -0,0 +1,164 @@
|
||||
#include "ns3/assert.h"
|
||||
#include "address.h"
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
Address::Address ()
|
||||
: m_type (0),
|
||||
m_len (0)
|
||||
{
|
||||
memset (m_data, 0, m_len);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool
|
||||
Address::IsInvalid (void) const
|
||||
{
|
||||
return m_len == 0 && m_type == 0;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
Address::GetLength (void) const
|
||||
{
|
||||
NS_ASSERT (m_len <= MAX_SIZE);
|
||||
return m_len;
|
||||
}
|
||||
uint32_t
|
||||
Address::CopyTo (uint8_t buffer[MAX_SIZE]) const
|
||||
{
|
||||
NS_ASSERT (m_len <= MAX_SIZE);
|
||||
memcpy (buffer, m_data, m_len);
|
||||
return m_len;
|
||||
}
|
||||
uint32_t
|
||||
Address::CopyAllTo (uint8_t *buffer, uint8_t len) const
|
||||
{
|
||||
NS_ASSERT (len >= m_len + 2);
|
||||
buffer[0] = m_type;
|
||||
buffer[1] = m_len;
|
||||
memcpy (buffer + 2, m_data, m_len);
|
||||
return m_len + 2;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Address::CopyFrom (const uint8_t *buffer, uint8_t len)
|
||||
{
|
||||
NS_ASSERT (len <= MAX_SIZE);
|
||||
memcpy (m_data, buffer, len);
|
||||
m_len = len;
|
||||
return m_len;
|
||||
}
|
||||
uint32_t
|
||||
Address::CopyAllFrom (const uint8_t *buffer, uint8_t len)
|
||||
{
|
||||
NS_ASSERT (len >= 2);
|
||||
m_type = buffer[0];
|
||||
m_len = buffer[1];
|
||||
NS_ASSERT (len >= m_len + 2);
|
||||
memcpy (m_data, buffer + 2, m_len);
|
||||
return m_len + 2;
|
||||
}
|
||||
bool
|
||||
Address::CheckCompatible (uint8_t type, uint8_t len) const
|
||||
{
|
||||
NS_ASSERT (len <= MAX_SIZE);
|
||||
return m_len == len && (m_type == type || m_type == 0);
|
||||
}
|
||||
bool
|
||||
Address::IsMatchingType (uint8_t type) const
|
||||
{
|
||||
return m_type == 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.m_type == b.m_type ||
|
||||
a.m_type == 0 ||
|
||||
b.m_type == 0);
|
||||
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.m_type == b.m_type ||
|
||||
a.m_type == 0 ||
|
||||
b.m_type == 0);
|
||||
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
|
||||
172
src/node/address.h
Normal file
172
src/node/address.h
Normal file
@@ -0,0 +1,172 @@
|
||||
#ifndef ADDRESS_H
|
||||
#define ADDRESS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <ostream>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* \brief a polymophic address class
|
||||
*
|
||||
* This class is very similar in design and spirit to the BSD sockaddr
|
||||
* structure: they are both used to hold multiple types of addresses
|
||||
* together with the type of the address.
|
||||
*
|
||||
* A new address class defined by a user needs to:
|
||||
* - allocate a type id with Address::Register
|
||||
* - provide a method to convert his new address to an Address
|
||||
* instance. This method is typically a member method named ConvertTo:
|
||||
* Address MyAddress::ConvertTo (void) const;
|
||||
* - provide a method to convert an Address instance back to
|
||||
* an instance of his new address type. This method is typically
|
||||
* a static member method of his address class named ConvertFrom:
|
||||
* static MyAddress MyAddress::ConvertFrom (const Address &address);
|
||||
* - the ConvertFrom method is expected to check that the type of the
|
||||
* input Address instance is compatible with its own type.
|
||||
*
|
||||
* Typical code to create a new class type looks like:
|
||||
* \code
|
||||
* // this class represents addresses which are 2 bytes long.
|
||||
* class MyAddress
|
||||
* {
|
||||
* public:
|
||||
* Address ConvertTo (void) const;
|
||||
* static MyAddress ConvertFrom (void);
|
||||
* private:
|
||||
* static uint8_t GetType (void);
|
||||
* };
|
||||
*
|
||||
* Address MyAddress::ConvertTo (void) const
|
||||
* {
|
||||
* return Address (GetType (), m_buffer, 2);
|
||||
* }
|
||||
* MyAddress MyAddress::ConvertFrom (const Address &address)
|
||||
* {
|
||||
* MyAddress ad;
|
||||
* NS_ASSERT (address.CheckCompatible (GetType (), 2));
|
||||
* address.CopyTo (ad.m_buffer, 2);
|
||||
* return ad;
|
||||
* }
|
||||
* uint8_t MyAddress::GetType (void)
|
||||
* {
|
||||
* static uint8_t type = Address::Register ();
|
||||
* return type;
|
||||
* }
|
||||
* \endcode
|
||||
*/
|
||||
class Address
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
/**
|
||||
* The maximum size of a byte buffer which
|
||||
* can be stored in an Address instance.
|
||||
*/
|
||||
MAX_SIZE = 30
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an invalid address
|
||||
*/
|
||||
Address ();
|
||||
/**
|
||||
* \param type the type of the Address to create
|
||||
* \param buffer a pointer to a buffer of bytes which hold
|
||||
* a serialized representation of the address in network
|
||||
* byte order.
|
||||
* \param len the length of the buffer.
|
||||
*
|
||||
* Create an address from a type and a buffer. This constructor
|
||||
* is typically invoked from the conversion functions of various
|
||||
* address types when they have to convert themselves to an
|
||||
* Address instance.
|
||||
*/
|
||||
Address (uint8_t type, const uint8_t *buffer, uint8_t len);
|
||||
Address (const Address & address);
|
||||
Address &operator = (const Address &address);
|
||||
|
||||
/**
|
||||
* \returns true if this address is invalid, false otherwise.
|
||||
*
|
||||
* An address is invalid if and only if it was created
|
||||
* through the default constructor and it was never
|
||||
* re-initialized.
|
||||
*/
|
||||
bool IsInvalid (void) const;
|
||||
/**
|
||||
* \returns the length of the underlying address.
|
||||
*/
|
||||
uint8_t GetLength (void) const;
|
||||
/**
|
||||
* \param buffer buffer to copy the address bytes to.
|
||||
* \returns the number of bytes copied.
|
||||
*/
|
||||
uint32_t CopyTo (uint8_t buffer[MAX_SIZE]) const;
|
||||
/**
|
||||
* \param buffer buffer to copy the whole address data structure to
|
||||
* \param len the size of the buffer
|
||||
* \returns the number of bytes copied.
|
||||
*/
|
||||
uint32_t CopyAllTo (uint8_t *buffer, uint8_t len) const;
|
||||
/**
|
||||
* \param buffer pointer to a buffer of bytes which contain
|
||||
* a serialized representation of the address in network
|
||||
* byte order.
|
||||
* \param len length of buffer
|
||||
* \returns the number of bytes copied.
|
||||
*
|
||||
* Copy the input buffer to the internal buffer of this address
|
||||
* instance.
|
||||
*/
|
||||
uint32_t CopyFrom (const uint8_t *buffer, uint8_t len);
|
||||
/**
|
||||
* \param buffer pointer to a buffer of bytes which contain
|
||||
* a copy of all the members of this Address class.
|
||||
* \param len the length of the buffer
|
||||
* \returns the number of bytes copied.
|
||||
*/
|
||||
uint32_t CopyAllFrom (const uint8_t *buffer, uint8_t len);
|
||||
/**
|
||||
* \param type a type id as returned by Address::Register
|
||||
* \param len the length associated to this type id.
|
||||
*
|
||||
* \returns true if the type of the address stored internally
|
||||
* is compatible with the requested type, false otherwise.
|
||||
*/
|
||||
bool CheckCompatible (uint8_t type, uint8_t len) const;
|
||||
/**
|
||||
* \param type a type id as returned by Address::Register
|
||||
* \returns true if the type of the address stored internally
|
||||
* is compatible with the requested type, false otherwise.
|
||||
*
|
||||
* This method checks that the types are _exactly_ equal.
|
||||
* This method is really used only by the PacketSocketAddress
|
||||
* and there is little point in using it otherwise so,
|
||||
* you have been warned: DO NOT USE THIS METHOD.
|
||||
*/
|
||||
bool IsMatchingType (uint8_t type) const;
|
||||
/**
|
||||
* Allocate a new type id for a new type of address.
|
||||
* \returns a new type id.
|
||||
*/
|
||||
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);
|
||||
|
||||
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 */
|
||||
@@ -74,22 +74,22 @@ EthernetHeader::GetPreambleSfd (void) const
|
||||
}
|
||||
|
||||
void
|
||||
EthernetHeader::SetSource (MacAddress source)
|
||||
EthernetHeader::SetSource (Eui48Address source)
|
||||
{
|
||||
m_source = source;
|
||||
}
|
||||
MacAddress
|
||||
Eui48Address
|
||||
EthernetHeader::GetSource (void) const
|
||||
{
|
||||
return m_source;
|
||||
}
|
||||
|
||||
void
|
||||
EthernetHeader::SetDestination (MacAddress dst)
|
||||
EthernetHeader::SetDestination (Eui48Address dst)
|
||||
{
|
||||
m_destination = dst;
|
||||
}
|
||||
MacAddress
|
||||
Eui48Address
|
||||
EthernetHeader::GetDestination (void) const
|
||||
{
|
||||
return m_destination;
|
||||
@@ -147,8 +147,6 @@ EthernetHeader::SerializeTo (Buffer::Iterator start) const
|
||||
{
|
||||
i.WriteU64(m_preambleSfd);
|
||||
}
|
||||
NS_ASSERT (m_destination.GetLength () == MAC_ADDR_SIZE);
|
||||
NS_ASSERT (m_source.GetLength () == MAC_ADDR_SIZE);
|
||||
WriteTo (i, m_destination);
|
||||
WriteTo (i, m_source);
|
||||
i.WriteU16 (m_lengthType);
|
||||
@@ -163,11 +161,11 @@ EthernetHeader::DeserializeFrom (Buffer::Iterator start)
|
||||
m_enPreambleSfd = i.ReadU64 ();
|
||||
}
|
||||
|
||||
ReadFrom (i, m_destination, MAC_ADDR_SIZE);
|
||||
ReadFrom (i, m_source, MAC_ADDR_SIZE);
|
||||
ReadFrom (i, m_destination);
|
||||
ReadFrom (i, m_source);
|
||||
m_lengthType = i.ReadU16 ();
|
||||
|
||||
return GetSerializedSize ();
|
||||
}
|
||||
|
||||
}; // namespace ns3
|
||||
} // namespace ns3
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
#define ETHERNET_HEADER_H
|
||||
|
||||
#include "ns3/header.h"
|
||||
#include "ns3/mac-address.h"
|
||||
#include <string>
|
||||
#include "ns3/eui48-address.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -70,11 +70,11 @@ public:
|
||||
/**
|
||||
* \param source The source address of this packet
|
||||
*/
|
||||
void SetSource (MacAddress source);
|
||||
void SetSource (Eui48Address source);
|
||||
/**
|
||||
* \param destination The destination address of this packet.
|
||||
*/
|
||||
void SetDestination (MacAddress destination);
|
||||
void SetDestination (Eui48Address destination);
|
||||
/**
|
||||
* \param preambleSfd The value that the preambleSfd field should take
|
||||
*/
|
||||
@@ -90,11 +90,11 @@ public:
|
||||
/**
|
||||
* \return The source address of this packet
|
||||
*/
|
||||
MacAddress GetSource (void) const;
|
||||
Eui48Address GetSource (void) const;
|
||||
/**
|
||||
* \return The destination address of this packet
|
||||
*/
|
||||
MacAddress GetDestination (void) const;
|
||||
Eui48Address GetDestination (void) const;
|
||||
/**
|
||||
* \return The value of the PreambleSfd field
|
||||
*/
|
||||
@@ -121,8 +121,8 @@ private:
|
||||
bool m_enPreambleSfd;
|
||||
uint64_t m_preambleSfd; /// Value of the Preamble/SFD fields
|
||||
uint16_t m_lengthType; /// Length or type of the packet
|
||||
MacAddress m_source; /// Source address
|
||||
MacAddress m_destination; /// Destination address
|
||||
Eui48Address m_source; /// Source address
|
||||
Eui48Address m_destination; /// Destination address
|
||||
};
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
168
src/node/eui48-address.cc
Normal file
168
src/node/eui48-address.cc
Normal file
@@ -0,0 +1,168 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 INRIA
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#include "eui48-address.h"
|
||||
#include "address.h"
|
||||
#include "ns3/assert.h"
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
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);
|
||||
}
|
||||
void
|
||||
Eui48Address::CopyFrom (const uint8_t buffer[6])
|
||||
{
|
||||
memcpy (m_address, buffer, 6);
|
||||
}
|
||||
void
|
||||
Eui48Address::CopyTo (uint8_t buffer[6]) const
|
||||
{
|
||||
memcpy (buffer, m_address, 6);
|
||||
}
|
||||
|
||||
bool
|
||||
Eui48Address::IsMatchingType (const Address &address)
|
||||
{
|
||||
return address.CheckCompatible (GetType (), 6);
|
||||
}
|
||||
Eui48Address::operator Address ()
|
||||
{
|
||||
return ConvertTo ();
|
||||
}
|
||||
Address
|
||||
Eui48Address::ConvertTo (void) const
|
||||
{
|
||||
return Address (GetType (), m_address, 6);
|
||||
}
|
||||
Eui48Address
|
||||
Eui48Address::ConvertFrom (const Address &address)
|
||||
{
|
||||
NS_ASSERT (address.CheckCompatible (GetType (), 6));
|
||||
Eui48Address retval;
|
||||
address.CopyTo (retval.m_address);
|
||||
return retval;
|
||||
}
|
||||
Eui48Address
|
||||
Eui48Address::Allocate (void)
|
||||
{
|
||||
static uint64_t id = 0;
|
||||
id++;
|
||||
Eui48Address address;
|
||||
address.m_address[0] = (id >> 40) & 0xff;
|
||||
address.m_address[1] = (id >> 32) & 0xff;
|
||||
address.m_address[2] = (id >> 24) & 0xff;
|
||||
address.m_address[3] = (id >> 16) & 0xff;
|
||||
address.m_address[4] = (id >> 8) & 0xff;
|
||||
address.m_address[5] = (id >> 0) & 0xff;
|
||||
return address;
|
||||
}
|
||||
uint8_t
|
||||
Eui48Address::GetType (void)
|
||||
{
|
||||
static uint8_t type = Address::Register ();
|
||||
return type;
|
||||
}
|
||||
|
||||
bool operator == (const Eui48Address &a, const Eui48Address &b)
|
||||
{
|
||||
uint8_t ada[6];
|
||||
uint8_t adb[6];
|
||||
a.CopyTo (ada);
|
||||
b.CopyTo (adb);
|
||||
return memcmp (ada, adb, 6) == 0;
|
||||
}
|
||||
bool operator != (const Eui48Address &a, const Eui48Address &b)
|
||||
{
|
||||
return ! (a == b);
|
||||
}
|
||||
|
||||
std::ostream& operator<< (std::ostream& os, const Eui48Address & address)
|
||||
{
|
||||
uint8_t ad[6];
|
||||
address.CopyTo (ad);
|
||||
|
||||
os.setf (std::ios::hex, std::ios::basefield);
|
||||
std::cout.fill('0');
|
||||
for (uint8_t i=0; i < 5; i++)
|
||||
{
|
||||
os << std::setw(2) << (uint32_t)ad[i] << ":";
|
||||
}
|
||||
// Final byte not suffixed by ":"
|
||||
os << std::setw(2) << (uint32_t)ad[5];
|
||||
os.setf (std::ios::dec, std::ios::basefield);
|
||||
std::cout.fill(' ');
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
99
src/node/eui48-address.h
Normal file
99
src/node/eui48-address.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 INRIA
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#ifndef EUI48_ADDRESS_H
|
||||
#define EUI48_ADDRESS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <ostream>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class Address;
|
||||
|
||||
/**
|
||||
* \brief an EUI-48 address
|
||||
*
|
||||
* This class can contain 48 bit IEEE addresses.
|
||||
*/
|
||||
class Eui48Address
|
||||
{
|
||||
public:
|
||||
Eui48Address ();
|
||||
/**
|
||||
* \param str a string representing the new Eui48Address
|
||||
*
|
||||
* The format of the string is "xx:xx:xx:xx:xx:xx"
|
||||
*/
|
||||
Eui48Address (const char *str);
|
||||
|
||||
/**
|
||||
* \param buffer address in network order
|
||||
*
|
||||
* Copy the input address to our internal buffer.
|
||||
*/
|
||||
void CopyFrom (const uint8_t buffer[6]);
|
||||
/**
|
||||
* \param buffer address in network order
|
||||
*
|
||||
* Copy the internal address to the input buffer.
|
||||
*/
|
||||
void CopyTo (uint8_t buffer[6]) const;
|
||||
|
||||
/**
|
||||
* \returns a new Address instance
|
||||
*
|
||||
* Convert an instance of this class to a polymorphic Address instance.
|
||||
*/
|
||||
operator Address ();
|
||||
/**
|
||||
* \param address a polymorphic address
|
||||
* \returns a new Eui48Address from the polymorphic address
|
||||
*
|
||||
* This function performs a type check and asserts if the
|
||||
* type of the input address is not compatible with an
|
||||
* Eui48Address.
|
||||
*/
|
||||
static Eui48Address ConvertFrom (const Address &address);
|
||||
/**
|
||||
* \returns true if the address matches, false otherwise.
|
||||
*/
|
||||
static bool IsMatchingType (const Address &address);
|
||||
/**
|
||||
* Allocate a new Eui48Address.
|
||||
*/
|
||||
static Eui48Address Allocate (void);
|
||||
private:
|
||||
/**
|
||||
* \returns a new Address instance
|
||||
*
|
||||
* Convert an instance of this class to a polymorphic Address instance.
|
||||
*/
|
||||
Address ConvertTo (void) const;
|
||||
static uint8_t GetType (void);
|
||||
uint8_t m_address[6];
|
||||
};
|
||||
|
||||
bool operator == (const Eui48Address &a, const Eui48Address &b);
|
||||
bool operator != (const Eui48Address &a, const Eui48Address &b);
|
||||
std::ostream& operator<< (std::ostream& os, const Eui48Address & address);
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* EUI48_ADDRESS_H */
|
||||
171
src/node/eui64-address.cc
Normal file
171
src/node/eui64-address.cc
Normal file
@@ -0,0 +1,171 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 INRIA
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#include "eui64-address.h"
|
||||
#include "address.h"
|
||||
#include "ns3/assert.h"
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Eui64Address::Eui64Address ()
|
||||
{
|
||||
memset (m_address, 0, 8);
|
||||
}
|
||||
Eui64Address::Eui64Address (const char *str)
|
||||
{
|
||||
int i = 0;
|
||||
while (*str != 0 && i < 8)
|
||||
{
|
||||
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);
|
||||
}
|
||||
void
|
||||
Eui64Address::CopyFrom (const uint8_t buffer[8])
|
||||
{
|
||||
memcpy (m_address, buffer, 8);
|
||||
}
|
||||
void
|
||||
Eui64Address::CopyTo (uint8_t buffer[8]) const
|
||||
{
|
||||
memcpy (buffer, m_address, 8);
|
||||
}
|
||||
|
||||
bool
|
||||
Eui64Address::IsMatchingType (const Address &address)
|
||||
{
|
||||
return address.CheckCompatible (GetType (), 8);
|
||||
}
|
||||
Eui64Address::operator Address ()
|
||||
{
|
||||
return ConvertTo ();
|
||||
}
|
||||
Eui64Address
|
||||
Eui64Address::ConvertFrom (const Address &address)
|
||||
{
|
||||
NS_ASSERT (address.CheckCompatible (GetType (), 8));
|
||||
Eui64Address retval;
|
||||
address.CopyTo (retval.m_address);
|
||||
return retval;
|
||||
}
|
||||
Address
|
||||
Eui64Address::ConvertTo (void) const
|
||||
{
|
||||
return Address (GetType (), m_address, 8);
|
||||
}
|
||||
|
||||
Eui64Address
|
||||
Eui64Address::Allocate (void)
|
||||
{
|
||||
static uint64_t id = 0;
|
||||
id++;
|
||||
Eui64Address address;
|
||||
address.m_address[0] = (id >> 56) & 0xff;
|
||||
address.m_address[1] = (id >> 48) & 0xff;
|
||||
address.m_address[2] = (id >> 40) & 0xff;
|
||||
address.m_address[3] = (id >> 32) & 0xff;
|
||||
address.m_address[4] = (id >> 24) & 0xff;
|
||||
address.m_address[5] = (id >> 16) & 0xff;
|
||||
address.m_address[6] = (id >> 8) & 0xff;
|
||||
address.m_address[7] = (id >> 0) & 0xff;
|
||||
return address;
|
||||
}
|
||||
uint8_t
|
||||
Eui64Address::GetType (void)
|
||||
{
|
||||
static uint8_t type = Address::Register ();
|
||||
return type;
|
||||
}
|
||||
|
||||
bool operator == (const Eui64Address &a, const Eui64Address &b)
|
||||
{
|
||||
uint8_t ada[8];
|
||||
uint8_t adb[8];
|
||||
a.CopyTo (ada);
|
||||
b.CopyTo (adb);
|
||||
return memcmp (ada, adb, 8) == 0;
|
||||
}
|
||||
bool operator != (const Eui64Address &a, const Eui64Address &b)
|
||||
{
|
||||
return ! (a == b);
|
||||
}
|
||||
|
||||
std::ostream& operator<< (std::ostream& os, const Eui64Address & address)
|
||||
{
|
||||
uint8_t ad[8];
|
||||
address.CopyTo (ad);
|
||||
|
||||
os.setf (std::ios::hex, std::ios::basefield);
|
||||
std::cout.fill('0');
|
||||
for (uint8_t i=0; i < 7; i++)
|
||||
{
|
||||
os << std::setw(2) << (uint32_t)ad[i] << ":";
|
||||
}
|
||||
// Final byte not suffixed by ":"
|
||||
os << std::setw(2) << (uint32_t)ad[7];
|
||||
os.setf (std::ios::dec, std::ios::basefield);
|
||||
std::cout.fill(' ');
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
98
src/node/eui64-address.h
Normal file
98
src/node/eui64-address.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 INRIA
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#ifndef EUI64_ADDRESS_H
|
||||
#define EUI64_ADDRESS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <ostream>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class Address;
|
||||
|
||||
/**
|
||||
* \brief an EUI-64 address
|
||||
*
|
||||
* This class can contain 64 bit IEEE addresses.
|
||||
*/
|
||||
class Eui64Address
|
||||
{
|
||||
public:
|
||||
Eui64Address ();
|
||||
/**
|
||||
* \param str a string representing the new Eui64Address
|
||||
*
|
||||
* The format of the string is "xx:xx:xx:xx:xx:xx"
|
||||
*/
|
||||
Eui64Address (const char *str);
|
||||
|
||||
/**
|
||||
* \param buffer address in network order
|
||||
*
|
||||
* Copy the input address to our internal buffer.
|
||||
*/
|
||||
void CopyFrom (const uint8_t buffer[8]);
|
||||
/**
|
||||
* \param buffer address in network order
|
||||
*
|
||||
* Copy the internal address to the input buffer.
|
||||
*/
|
||||
void CopyTo (uint8_t buffer[8]) const;
|
||||
/**
|
||||
* \returns a new Address instance
|
||||
*
|
||||
* Convert an instance of this class to a polymorphic Address instance.
|
||||
*/
|
||||
operator Address ();
|
||||
/**
|
||||
* \param address a polymorphic address
|
||||
* \returns a new Eui64Address from the polymorphic address
|
||||
*
|
||||
* This function performs a type check and asserts if the
|
||||
* type of the input address is not compatible with an
|
||||
* Eui64Address.
|
||||
*/
|
||||
static Eui64Address ConvertFrom (const Address &address);
|
||||
/**
|
||||
* \returns true if the address matches, false otherwise.
|
||||
*/
|
||||
static bool IsMatchingType (const Address &address);
|
||||
/**
|
||||
* Allocate a new Eui64Address.
|
||||
*/
|
||||
static Eui64Address Allocate (void);
|
||||
private:
|
||||
/**
|
||||
* \returns a new Address instance
|
||||
*
|
||||
* Convert an instance of this class to a polymorphic Address instance.
|
||||
*/
|
||||
Address ConvertTo (void) const;
|
||||
static uint8_t GetType (void);
|
||||
uint8_t m_address[8];
|
||||
};
|
||||
|
||||
bool operator == (const Eui64Address &a, const Eui64Address &b);
|
||||
bool operator != (const Eui64Address &a, const Eui64Address &b);
|
||||
std::ostream& operator<< (std::ostream& os, const Eui64Address & address);
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* EUI64_ADDRESS_H */
|
||||
85
src/node/inet-socket-address.cc
Normal file
85
src/node/inet-socket-address.cc
Normal file
@@ -0,0 +1,85 @@
|
||||
#include "inet-socket-address.h"
|
||||
#include "ns3/assert.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
InetSocketAddress::InetSocketAddress (Ipv4Address ipv4, uint16_t port)
|
||||
: m_ipv4 (ipv4),
|
||||
m_port (port)
|
||||
{}
|
||||
InetSocketAddress::InetSocketAddress (Ipv4Address ipv4)
|
||||
: m_ipv4 (ipv4),
|
||||
m_port (0)
|
||||
{}
|
||||
InetSocketAddress::InetSocketAddress (const char *ipv4, uint16_t port)
|
||||
: m_ipv4 (Ipv4Address (ipv4)),
|
||||
m_port (port)
|
||||
{}
|
||||
InetSocketAddress::InetSocketAddress (const char * ipv4)
|
||||
: m_ipv4 (Ipv4Address (ipv4)),
|
||||
m_port (0)
|
||||
{}
|
||||
InetSocketAddress::InetSocketAddress (uint16_t port)
|
||||
: m_ipv4 (Ipv4Address::GetAny ()),
|
||||
m_port (port)
|
||||
{}
|
||||
uint16_t
|
||||
InetSocketAddress::GetPort (void) const
|
||||
{
|
||||
return m_port;
|
||||
}
|
||||
Ipv4Address
|
||||
InetSocketAddress::GetIpv4 (void) const
|
||||
{
|
||||
return m_ipv4;
|
||||
}
|
||||
|
||||
void
|
||||
InetSocketAddress::SetPort (uint16_t port)
|
||||
{
|
||||
m_port = port;
|
||||
}
|
||||
void
|
||||
InetSocketAddress::SetIpv4 (Ipv4Address address)
|
||||
{
|
||||
m_ipv4 = address;
|
||||
}
|
||||
|
||||
bool
|
||||
InetSocketAddress::IsMatchingType (const Address &address)
|
||||
{
|
||||
return address.CheckCompatible (GetType (), 6);
|
||||
}
|
||||
|
||||
InetSocketAddress::operator Address () const
|
||||
{
|
||||
return ConvertTo ();
|
||||
}
|
||||
|
||||
Address
|
||||
InetSocketAddress::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);
|
||||
}
|
||||
InetSocketAddress
|
||||
InetSocketAddress::ConvertFrom (const Address &address)
|
||||
{
|
||||
NS_ASSERT (address.CheckCompatible (GetType (), 6));
|
||||
uint8_t buf[6];
|
||||
address.CopyTo (buf);
|
||||
Ipv4Address ipv4 = Ipv4Address::Deserialize (buf);
|
||||
uint16_t port = buf[0] | (buf[1] << 8);
|
||||
return InetSocketAddress (ipv4, port);
|
||||
}
|
||||
uint8_t
|
||||
InetSocketAddress::GetType (void)
|
||||
{
|
||||
static uint8_t type = Address::Register ();
|
||||
return type;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
96
src/node/inet-socket-address.h
Normal file
96
src/node/inet-socket-address.h
Normal file
@@ -0,0 +1,96 @@
|
||||
#ifndef IPV4_TRANSPORT_ADDRESS_H
|
||||
#define IPV4_TRANSPORT_ADDRESS_H
|
||||
|
||||
#include "address.h"
|
||||
#include "ipv4-address.h"
|
||||
#include <stdint.h>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
/**
|
||||
* \brief an Inet address class
|
||||
*
|
||||
* This class is similar to inet_sockaddr in the BSD socket
|
||||
* API. i.e., this class holds an Ipv4Address and a port number
|
||||
* to form an ipv4 transport endpoint.
|
||||
*/
|
||||
class InetSocketAddress
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \param ipv4 the ipv4 address
|
||||
* \param port the port number
|
||||
*/
|
||||
InetSocketAddress (Ipv4Address ipv4, uint16_t port);
|
||||
/**
|
||||
* \param ipv4 the ipv4 address
|
||||
*
|
||||
* The port number is set to zero by default.
|
||||
*/
|
||||
InetSocketAddress (Ipv4Address ipv4);
|
||||
/**
|
||||
* \param port the port number
|
||||
*
|
||||
* The ipv4 address is set to the "Any" address by default.
|
||||
*/
|
||||
InetSocketAddress (uint16_t port);
|
||||
/**
|
||||
* \param ipv4 string which represents an ipv4 address
|
||||
* \param port the port number
|
||||
*/
|
||||
InetSocketAddress (const char *ipv4, uint16_t port);
|
||||
/**
|
||||
* \param ipv4 string which represents an ipv4 address
|
||||
*
|
||||
* The port number is set to zero.
|
||||
*/
|
||||
InetSocketAddress (const char *ipv4);
|
||||
/**
|
||||
* \returns the port number
|
||||
*/
|
||||
uint16_t GetPort (void) const;
|
||||
/**
|
||||
* \returns the ipv4 address
|
||||
*/
|
||||
Ipv4Address GetIpv4 (void) const;
|
||||
|
||||
/**
|
||||
* \param port the new port number.
|
||||
*/
|
||||
void SetPort (uint16_t port);
|
||||
/**
|
||||
* \param address the new ipv4 address
|
||||
*/
|
||||
void SetIpv4 (Ipv4Address address);
|
||||
|
||||
/**
|
||||
* \returns true if the address matches, false otherwise.
|
||||
*/
|
||||
static bool IsMatchingType (const Address &address);
|
||||
|
||||
/**
|
||||
* \returns an Address instance which represents this
|
||||
* InetSocketAddress instance.
|
||||
*/
|
||||
operator Address () const;
|
||||
|
||||
/**
|
||||
* \param address the Address instance to convert from.
|
||||
*
|
||||
* Returns an InetSocketAddress which corresponds to the input
|
||||
* Address
|
||||
*/
|
||||
static InetSocketAddress ConvertFrom (const Address &address);
|
||||
private:
|
||||
Address ConvertTo (void) const;
|
||||
|
||||
static uint8_t GetType (void);
|
||||
Ipv4Address m_ipv4;
|
||||
uint16_t m_port;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
#endif /* IPV4_TRANSPORT_ADDRESS_H */
|
||||
@@ -19,11 +19,11 @@
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#include "ns3/debug.h"
|
||||
#include "ipv4-address.h"
|
||||
#include "ns3/assert.h"
|
||||
|
||||
NS_DEBUG_COMPONENT_DEFINE("Ipv4Address");
|
||||
|
||||
#include "ipv4-address.h"
|
||||
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -193,6 +193,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
|
||||
@@ -203,7 +217,39 @@ Ipv4Address::Print (std::ostream &os) const
|
||||
<< ((m_address >> 0) & 0xff);
|
||||
}
|
||||
|
||||
bool
|
||||
Ipv4Address::IsMatchingType (const Address &address)
|
||||
{
|
||||
return address.CheckCompatible (GetType (), 4);
|
||||
}
|
||||
Ipv4Address::operator Address ()
|
||||
{
|
||||
return ConvertTo ();
|
||||
}
|
||||
|
||||
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.CheckCompatible (GetType (), 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)
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <ostream>
|
||||
#include "address.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -86,10 +87,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
|
||||
*
|
||||
@@ -111,11 +120,17 @@ public:
|
||||
*/
|
||||
Ipv4Address CombineMask (Ipv4Mask const &mask) const;
|
||||
|
||||
static bool IsMatchingType (const Address &address);
|
||||
operator Address ();
|
||||
static Ipv4Address ConvertFrom (const Address &address);
|
||||
|
||||
static Ipv4Address GetZero (void);
|
||||
static Ipv4Address GetAny (void);
|
||||
static Ipv4Address GetBroadcast (void);
|
||||
static Ipv4Address GetLoopback (void);
|
||||
private:
|
||||
Address ConvertTo (void) const;
|
||||
static uint8_t GetType (void);
|
||||
uint32_t m_address;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,210 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2005 INRIA
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include "ns3/assert.h"
|
||||
#include "mac-address.h"
|
||||
|
||||
#define ASCII_a (0x41)
|
||||
#define ASCII_z (0x5a)
|
||||
#define ASCII_A (0x61)
|
||||
#define ASCII_Z (0x7a)
|
||||
#define ASCII_COLON (0x3a)
|
||||
#define ASCII_ZERO (0x30)
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
// Static variables
|
||||
uint8_t MacAddress::g_nextAddress[MacAddress::MAX_LEN];
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MacAddress::MacAddress () : m_len(0)
|
||||
{
|
||||
for (int i=0; i < MacAddress::MAX_LEN; i++)
|
||||
{
|
||||
m_address[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
MacAddress::MacAddress(uint8_t len) : m_len(len)
|
||||
{
|
||||
NS_ASSERT (len <= MacAddress::MAX_LEN);
|
||||
AdvanceAddress();
|
||||
memcpy(m_address, g_nextAddress, len);
|
||||
}
|
||||
|
||||
MacAddress::MacAddress (uint8_t const *address, uint8_t len)
|
||||
{
|
||||
NS_ASSERT (len <= MacAddress::MAX_LEN);
|
||||
for (int i=0; i < len; i++)
|
||||
{
|
||||
m_address[i] = address[i];
|
||||
}
|
||||
for (int i=len; i < MacAddress::MAX_LEN; i++)
|
||||
{
|
||||
m_address[i] = 0;
|
||||
}
|
||||
m_len = len;
|
||||
}
|
||||
|
||||
MacAddress::MacAddress (char const *str)
|
||||
{
|
||||
int i = 0;
|
||||
while (*str != 0 && i < MacAddress::MAX_LEN) {
|
||||
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++;
|
||||
}
|
||||
m_len = i;
|
||||
}
|
||||
|
||||
MacAddress::~MacAddress ()
|
||||
{}
|
||||
|
||||
bool
|
||||
MacAddress::IsEqual (MacAddress other) const
|
||||
{
|
||||
if (memcmp(other.m_address, m_address, m_len))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MacAddress::Print (std::ostream &os) const
|
||||
{
|
||||
int i;
|
||||
if (m_len == 0)
|
||||
{
|
||||
os << "NULL-ADDRESS";
|
||||
return;
|
||||
}
|
||||
os.setf (std::ios::hex, std::ios::basefield);
|
||||
std::cout.fill('0');
|
||||
for (i=0; i< (m_len-1); i++)
|
||||
{
|
||||
os << std::setw(2) << (uint32_t)m_address[i] << ":";
|
||||
}
|
||||
// Final byte not suffixed by ":"
|
||||
os << std::setw(2) << (uint32_t)m_address[i];
|
||||
os.setf (std::ios::dec, std::ios::basefield);
|
||||
std::cout.fill(' ');
|
||||
}
|
||||
|
||||
uint8_t
|
||||
MacAddress::GetLength () const
|
||||
{
|
||||
return m_len;
|
||||
}
|
||||
|
||||
void
|
||||
MacAddress::Peek (uint8_t ad[MacAddress::MAX_LEN]) const
|
||||
{
|
||||
memcpy (ad, m_address, MacAddress::MAX_LEN);
|
||||
}
|
||||
void
|
||||
MacAddress::Set (uint8_t const ad[MacAddress::MAX_LEN], uint8_t len)
|
||||
{
|
||||
memcpy (m_address, ad, MacAddress::MAX_LEN);
|
||||
m_len = len;
|
||||
}
|
||||
|
||||
// Static methods
|
||||
void MacAddress::AdvanceAddress()
|
||||
{
|
||||
// Advance to next address, little end first
|
||||
for(size_t i = 0; i < MAX_LEN; ++i)
|
||||
{
|
||||
if (++g_nextAddress[i] != 0) break;
|
||||
}
|
||||
}
|
||||
|
||||
// Non-member operators
|
||||
bool operator == (MacAddress const&a, MacAddress const&b)
|
||||
{
|
||||
return a.IsEqual (b);
|
||||
}
|
||||
|
||||
bool operator != (MacAddress const&a, MacAddress const&b)
|
||||
{
|
||||
return !a.IsEqual (b);
|
||||
}
|
||||
|
||||
bool operator < (MacAddress const&a, MacAddress const&b)
|
||||
{
|
||||
uint8_t a_p[MacAddress::MAX_LEN];
|
||||
uint8_t b_p[MacAddress::MAX_LEN];
|
||||
a.Peek (a_p);
|
||||
b.Peek (b_p);
|
||||
NS_ASSERT (a.GetLength() == b.GetLength());
|
||||
for (uint8_t i = 0; i < a.GetLength(); i++)
|
||||
{
|
||||
if (a_p[i] < b_p[i])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (a_p[i] > b_p[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::ostream& operator<< (std::ostream& os, MacAddress const& address)
|
||||
{
|
||||
address.Print (os);
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
}; // namespace ns3
|
||||
@@ -1,128 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2005 INRIA
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
|
||||
#ifndef MAC_ADDRESS_H
|
||||
#define MAC_ADDRESS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <ostream>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* \brief base class for Network Device addresses
|
||||
*
|
||||
* This class is a base class for different types of Network
|
||||
* Device addresses. It generically stores an address of
|
||||
* MAX_ADDR_LEN bytes, and provides methods to compare, print, and set
|
||||
* the address.
|
||||
*/
|
||||
class MacAddress {
|
||||
public:
|
||||
enum {
|
||||
MAX_LEN = 32
|
||||
};
|
||||
/**
|
||||
* \brief Construct a null MacAddress
|
||||
*
|
||||
* This MacAddress has length of zero, and is internally all zeros
|
||||
*/
|
||||
MacAddress (void);
|
||||
/**
|
||||
* \brief Construct a MacAddress using the next available
|
||||
* address.
|
||||
* \see MacAddres::Next
|
||||
* \param len length, in bytes, of the desired address
|
||||
*/
|
||||
MacAddress(uint8_t len);
|
||||
/**
|
||||
* \brief Construct a MacAddress from a byte-array
|
||||
*
|
||||
* low byte should be first.
|
||||
* \param address a byte array indicating the address
|
||||
* \param len length, in bytes, of the address points to
|
||||
*/
|
||||
MacAddress (uint8_t const *address, uint8_t len);
|
||||
/**
|
||||
* \brief Construct a MacAddress from a C-string
|
||||
*
|
||||
* The string should look like this:
|
||||
* hh:xx:xx:xx:xx:ll
|
||||
* where hh is the high byte and ll is
|
||||
* the low byte.
|
||||
* \param address the C-string representation of the address
|
||||
*/
|
||||
MacAddress (char const *address);
|
||||
~MacAddress ();
|
||||
|
||||
/**
|
||||
* \brief Comparison operation between MacAddresses
|
||||
* \param other The address against which to compare this one
|
||||
* \return True if they are equal, false otherwise.
|
||||
*/
|
||||
bool IsEqual (MacAddress other) const;
|
||||
/**
|
||||
* \brief Print this MacAddress to a stream
|
||||
*
|
||||
* The format is colon seperated groups of two hexadecimal digits
|
||||
* \param os The output stream desired
|
||||
*/
|
||||
void Print (std::ostream &os) const;
|
||||
|
||||
/**
|
||||
* \return The length in bytes of this MacAddress
|
||||
*/
|
||||
uint8_t GetLength() const;
|
||||
/**
|
||||
* \brief Copy routine to peek the contents of the MacAddress
|
||||
*
|
||||
* \param ad Output parameter which holds a copy of this MacAddress
|
||||
*/
|
||||
void Peek (uint8_t ad[MAX_LEN]) const;
|
||||
/**
|
||||
* \brief Sets this MacAddress to a specific value
|
||||
* \param ad byte buffer to set the MacAddress to
|
||||
* \param len the length of the buffer
|
||||
*/
|
||||
void Set (uint8_t const ad[MAX_LEN], uint8_t len);
|
||||
|
||||
// Static methods/members
|
||||
/**
|
||||
*
|
||||
* Advance the global to the next available mac address.
|
||||
*/
|
||||
static void AdvanceAddress();
|
||||
static uint8_t g_nextAddress[MAX_LEN];
|
||||
|
||||
private:
|
||||
uint8_t m_address[MAX_LEN];
|
||||
uint8_t m_len;
|
||||
};
|
||||
|
||||
bool operator == (MacAddress const&a, MacAddress const&b);
|
||||
bool operator != (MacAddress const&a, MacAddress const&b);
|
||||
bool operator < (MacAddress const&a, MacAddress const&b);
|
||||
|
||||
std::ostream& operator<< (std::ostream& os, MacAddress const& address);
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
#endif /* MAC_ADDRESS_H */
|
||||
@@ -35,7 +35,7 @@ namespace ns3 {
|
||||
|
||||
const InterfaceId NetDevice::iid = MakeInterfaceId ("NetDevice", Object::iid);
|
||||
|
||||
NetDevice::NetDevice(Ptr<Node> node, const MacAddress& addr) :
|
||||
NetDevice::NetDevice(Ptr<Node> node, const Address& addr) :
|
||||
m_node (node),
|
||||
m_name(""),
|
||||
m_ifIndex (0),
|
||||
@@ -53,7 +53,7 @@ NetDevice::NetDevice(Ptr<Node> node, const MacAddress& addr) :
|
||||
NetDevice::~NetDevice ()
|
||||
{}
|
||||
|
||||
MacAddress
|
||||
Address
|
||||
NetDevice::GetAddress (void) const
|
||||
{
|
||||
return m_address;
|
||||
@@ -113,7 +113,7 @@ NetDevice::IsBroadcast (void) const
|
||||
{
|
||||
return m_isBroadcast;
|
||||
}
|
||||
MacAddress const &
|
||||
Address const &
|
||||
NetDevice::GetBroadcast (void) const
|
||||
{
|
||||
NS_ASSERT (m_isBroadcast);
|
||||
@@ -121,7 +121,7 @@ NetDevice::GetBroadcast (void) const
|
||||
}
|
||||
|
||||
void
|
||||
NetDevice::EnableBroadcast (MacAddress broadcast)
|
||||
NetDevice::EnableBroadcast (Address broadcast)
|
||||
{
|
||||
m_isBroadcast = true;
|
||||
m_broadcast = broadcast;
|
||||
@@ -171,7 +171,7 @@ NetDevice::DisablePointToPoint (void)
|
||||
|
||||
// Receive packet from above
|
||||
bool
|
||||
NetDevice::Send(Packet& p, const MacAddress& dest, uint16_t protocolNumber)
|
||||
NetDevice::Send(Packet& p, const Address& dest, uint16_t protocolNumber)
|
||||
{
|
||||
if (m_isUp)
|
||||
{
|
||||
@@ -197,18 +197,19 @@ NetDevice::GetChannel (void) const
|
||||
|
||||
// Receive packets from below
|
||||
bool
|
||||
NetDevice::ForwardUp(Packet& p, uint32_t param)
|
||||
NetDevice::ForwardUp(const Packet& p, uint32_t param, const Address &from)
|
||||
{
|
||||
bool retval = false;
|
||||
Packet packet = p;
|
||||
|
||||
NS_DEBUG ("NetDevice::ForwardUp: UID is " << packet.GetUid()
|
||||
NS_DEBUG ("NetDevice::ForwardUp: UID is " << p.GetUid()
|
||||
<< " device is: " << GetName());
|
||||
|
||||
if (!m_receiveCallback.IsNull ())
|
||||
{
|
||||
retval = m_receiveCallback (this, packet, param);
|
||||
} else {
|
||||
retval = m_receiveCallback (this, p, param, from);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_DEBUG ("NetDevice::Receive call back is NULL");
|
||||
}
|
||||
|
||||
@@ -248,7 +249,7 @@ NetDevice::NeedsArp (void) const
|
||||
}
|
||||
|
||||
void
|
||||
NetDevice::SetReceiveCallback (Callback<bool,Ptr<NetDevice>,const Packet &,uint16_t> cb)
|
||||
NetDevice::SetReceiveCallback (ReceiveCallback cb)
|
||||
{
|
||||
m_receiveCallback = cb;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/object.h"
|
||||
#include "ns3/ptr.h"
|
||||
#include "mac-address.h"
|
||||
#include "address.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -79,9 +79,9 @@ public:
|
||||
Ptr<Channel> GetChannel (void) const;
|
||||
|
||||
/**
|
||||
* \return the current MacAddress of this interface.
|
||||
* \return the current Address of this interface.
|
||||
*/
|
||||
MacAddress GetAddress (void) const;
|
||||
Address GetAddress (void) const;
|
||||
/**
|
||||
* \param mtu MTU value, in bytes, to set for the device
|
||||
* \return whether the MTU value was within legal bounds
|
||||
@@ -137,7 +137,7 @@ public:
|
||||
* Calling this method is invalid if IsBroadcast returns
|
||||
* not true.
|
||||
*/
|
||||
MacAddress const &GetBroadcast (void) const;
|
||||
Address const &GetBroadcast (void) const;
|
||||
/**
|
||||
* \return value of m_isMulticast flag
|
||||
*/
|
||||
@@ -154,11 +154,11 @@ public:
|
||||
* is received.
|
||||
*
|
||||
* Called from higher layer to send packet into Network Device
|
||||
* to the specified destination MacAddress
|
||||
* to the specified destination Address
|
||||
*
|
||||
* \return whether the Send operation succeeded
|
||||
*/
|
||||
bool Send(Packet& p, const MacAddress& dest, uint16_t protocolNumber);
|
||||
bool Send(Packet& p, const Address& dest, uint16_t protocolNumber);
|
||||
/**
|
||||
* \returns the node base class which contains this network
|
||||
* interface.
|
||||
@@ -177,23 +177,36 @@ public:
|
||||
*/
|
||||
bool NeedsArp (void) const;
|
||||
|
||||
/**
|
||||
* \param device a pointer to the net device which is calling this callback
|
||||
* \param packet the packet received
|
||||
* \param protocol the 16 bit protocol number associated with this packet.
|
||||
* This protocol number is expected to be the same protocol number
|
||||
* given to the Send method by the user on the sender side.
|
||||
* \param address the address of the sender
|
||||
* \returns true if the callback could handle the packet successfully, false
|
||||
* otherwise.
|
||||
*/
|
||||
typedef Callback<bool,Ptr<NetDevice>,const Packet &,uint16_t,const Address &> ReceiveCallback;
|
||||
|
||||
/**
|
||||
* \param cb callback to invoke whenever a packet has been received and must
|
||||
* be forwarded to the higher layers.
|
||||
*
|
||||
*/
|
||||
void SetReceiveCallback (Callback<bool,Ptr<NetDevice>,const Packet &,uint16_t> cb);
|
||||
void SetReceiveCallback (ReceiveCallback cb);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* \param node base class node pointer of device's node
|
||||
* \param addr MAC address of this device.
|
||||
*/
|
||||
NetDevice(Ptr<Node> node, const MacAddress& addr);
|
||||
NetDevice(Ptr<Node> node, const Address& addr);
|
||||
/**
|
||||
* Enable broadcast support. This method should be
|
||||
* called by subclasses from their constructor
|
||||
*/
|
||||
void EnableBroadcast (MacAddress broadcast);
|
||||
void EnableBroadcast (Address broadcast);
|
||||
/**
|
||||
* Set m_isBroadcast flag to false
|
||||
*/
|
||||
@@ -230,6 +243,7 @@ public:
|
||||
* \param p packet sent from below up to Network Device
|
||||
* \param param Extra parameter extracted from header and needed by
|
||||
* some protocols
|
||||
* \param address the address of the sender of this packet.
|
||||
* \returns true if the packet was forwarded successfully,
|
||||
* false otherwise.
|
||||
*
|
||||
@@ -237,7 +251,7 @@ public:
|
||||
* forwards it to the higher layers by calling this method
|
||||
* which is responsible for passing it up to the Rx callback.
|
||||
*/
|
||||
bool ForwardUp (Packet& p, uint32_t param);
|
||||
bool ForwardUp (const Packet& p, uint32_t param, const Address &address);
|
||||
|
||||
|
||||
/**
|
||||
@@ -248,8 +262,6 @@ public:
|
||||
*/
|
||||
virtual void DoDispose (void);
|
||||
|
||||
Callback<bool,Ptr<NetDevice>,const Packet &,uint16_t> m_receiveCallback;
|
||||
|
||||
private:
|
||||
/**
|
||||
* \param p packet to send
|
||||
@@ -262,7 +274,7 @@ public:
|
||||
* method. When the link is Up, this method is invoked to ask
|
||||
* subclasses to forward packets. Subclasses MUST override this method.
|
||||
*/
|
||||
virtual bool SendTo (Packet& p, const MacAddress &dest, uint16_t protocolNumber) = 0;
|
||||
virtual bool SendTo (Packet& p, const Address &dest, uint16_t protocolNumber) = 0;
|
||||
/**
|
||||
* \returns true if this NetDevice needs the higher-layers
|
||||
* to perform ARP over it, false otherwise.
|
||||
@@ -289,14 +301,15 @@ public:
|
||||
Ptr<Node> m_node;
|
||||
std::string m_name;
|
||||
uint16_t m_ifIndex;
|
||||
MacAddress m_address;
|
||||
MacAddress m_broadcast;
|
||||
Address m_address;
|
||||
Address m_broadcast;
|
||||
uint16_t m_mtu;
|
||||
bool m_isUp;
|
||||
bool m_isBroadcast;
|
||||
bool m_isMulticast;
|
||||
bool m_isPointToPoint;
|
||||
Callback<void> m_linkChangeCallback;
|
||||
ReceiveCallback m_receiveCallback;
|
||||
};
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
@@ -77,7 +77,6 @@ public:
|
||||
NodeList::Iterator Begin (void);
|
||||
NodeList::Iterator End (void);
|
||||
TraceResolver *CreateTraceResolver (TraceContext const &context);
|
||||
Node *PeekNode (uint32_t n);
|
||||
Ptr<Node> GetNode (uint32_t n);
|
||||
uint32_t GetNNodes (void);
|
||||
|
||||
@@ -123,11 +122,6 @@ NodeListPriv::GetNNodes (void)
|
||||
{
|
||||
return m_nodes.size ();
|
||||
}
|
||||
Node *
|
||||
NodeListPriv::PeekNode (uint32_t n)
|
||||
{
|
||||
return PeekPointer (m_nodes[n]);
|
||||
}
|
||||
|
||||
Ptr<Node>
|
||||
NodeListPriv::GetNode (uint32_t n)
|
||||
@@ -139,11 +133,11 @@ NodeListPriv::GetNode (uint32_t n)
|
||||
TraceResolver *
|
||||
NodeListPriv::CreateTraceResolver (TraceContext const &context)
|
||||
{
|
||||
ArrayTraceResolver<Node, NodeListIndex> *resolver =
|
||||
new ArrayTraceResolver<Node, NodeListIndex>
|
||||
ArrayTraceResolver<Ptr<Node>, NodeListIndex> *resolver =
|
||||
new ArrayTraceResolver<Ptr<Node>, NodeListIndex>
|
||||
(context,
|
||||
MakeCallback (&NodeListPriv::GetNNodes, this),
|
||||
MakeCallback (&NodeListPriv::PeekNode, this));
|
||||
MakeCallback (&NodeListPriv::GetNode, this));
|
||||
return resolver;
|
||||
}
|
||||
|
||||
|
||||
137
src/node/node.cc
137
src/node/node.cc
@@ -1,32 +1,30 @@
|
||||
// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
|
||||
//
|
||||
// Copyright (c) 2006 Georgia Tech Research Corporation
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation;
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// Author: George F. Riley<riley@ece.gatech.edu>
|
||||
//
|
||||
|
||||
// Implement the basic Node object for ns3.
|
||||
// George F. Riley, Georgia Tech, Fall 2006
|
||||
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2006 Georgia Tech Research Corporation, INRIA
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: George F. Riley<riley@ece.gatech.edu>
|
||||
* Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#include "node.h"
|
||||
#include "node-list.h"
|
||||
#include "net-device.h"
|
||||
#include "application.h"
|
||||
#include "packet-socket-factory.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/composite-trace-resolver.h"
|
||||
|
||||
namespace ns3{
|
||||
|
||||
@@ -36,16 +34,23 @@ Node::Node()
|
||||
: m_id(0),
|
||||
m_sid(0)
|
||||
{
|
||||
SetInterfaceId (Node::iid);
|
||||
m_id = NodeList::Add (this);
|
||||
Construct ();
|
||||
}
|
||||
|
||||
Node::Node(uint32_t sid)
|
||||
: m_id(0),
|
||||
m_sid(sid)
|
||||
{
|
||||
Construct ();
|
||||
}
|
||||
|
||||
void
|
||||
Node::Construct (void)
|
||||
{
|
||||
SetInterfaceId (Node::iid);
|
||||
m_id = NodeList::Add (this);
|
||||
Ptr<PacketSocketFactory> socketFactory = Create<PacketSocketFactory> ();
|
||||
AddInterface (socketFactory);
|
||||
}
|
||||
|
||||
Node::~Node ()
|
||||
@@ -54,7 +59,9 @@ Node::~Node ()
|
||||
TraceResolver *
|
||||
Node::CreateTraceResolver (TraceContext const &context)
|
||||
{
|
||||
return DoCreateTraceResolver (context);
|
||||
CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
|
||||
DoFillTraceResolver (*resolver);
|
||||
return resolver;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@@ -74,8 +81,9 @@ Node::AddDevice (Ptr<NetDevice> device)
|
||||
{
|
||||
uint32_t index = m_devices.size ();
|
||||
m_devices.push_back (device);
|
||||
DoAddDevice (device);
|
||||
device->SetIfIndex(index);
|
||||
device->SetReceiveCallback (MakeCallback (&Node::ReceiveFromDevice, this));
|
||||
NotifyDeviceAdded (device);
|
||||
return index;
|
||||
}
|
||||
Ptr<NetDevice>
|
||||
@@ -107,8 +115,27 @@ Node::GetNApplications (void) const
|
||||
return m_applications.size ();
|
||||
}
|
||||
|
||||
TraceResolver *
|
||||
Node::CreateDevicesTraceResolver (const TraceContext &context)
|
||||
{
|
||||
ArrayTraceResolver<Ptr<NetDevice> > *resolver =
|
||||
new ArrayTraceResolver<Ptr<NetDevice> > (context,
|
||||
MakeCallback (&Node::GetNDevices, this),
|
||||
MakeCallback (&Node::GetDevice, this));
|
||||
|
||||
return resolver;
|
||||
}
|
||||
|
||||
void Node::DoDispose()
|
||||
void
|
||||
Node::DoFillTraceResolver (CompositeTraceResolver &resolver)
|
||||
{
|
||||
resolver.Add ("devices",
|
||||
MakeCallback (&Node::CreateDevicesTraceResolver, this),
|
||||
Node::DEVICES);
|
||||
}
|
||||
|
||||
void
|
||||
Node::DoDispose()
|
||||
{
|
||||
for (std::vector<Ptr<NetDevice> >::iterator i = m_devices.begin ();
|
||||
i != m_devices.end (); i++)
|
||||
@@ -129,4 +156,56 @@ void Node::DoDispose()
|
||||
Object::DoDispose ();
|
||||
}
|
||||
|
||||
void
|
||||
Node::NotifyDeviceAdded (Ptr<NetDevice> device)
|
||||
{}
|
||||
|
||||
void
|
||||
Node::RegisterProtocolHandler (ProtocolHandler handler,
|
||||
uint16_t protocolType,
|
||||
Ptr<NetDevice> device)
|
||||
{
|
||||
struct Node::ProtocolHandlerEntry entry;
|
||||
entry.handler = handler;
|
||||
entry.protocol = protocolType;
|
||||
entry.device = device;
|
||||
m_handlers.push_back (entry);
|
||||
}
|
||||
|
||||
void
|
||||
Node::UnregisterProtocolHandler (ProtocolHandler handler)
|
||||
{
|
||||
for (ProtocolHandlerList::iterator i = m_handlers.begin ();
|
||||
i != m_handlers.end (); i++)
|
||||
{
|
||||
if (i->handler.IsEqual (handler))
|
||||
{
|
||||
m_handlers.erase (i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Node::ReceiveFromDevice (Ptr<NetDevice> device, const Packet &packet,
|
||||
uint16_t protocol, const Address &from)
|
||||
{
|
||||
bool found = false;
|
||||
for (ProtocolHandlerList::iterator i = m_handlers.begin ();
|
||||
i != m_handlers.end (); i++)
|
||||
{
|
||||
if (i->device == 0 ||
|
||||
(i->device != 0 && i->device == device))
|
||||
{
|
||||
if (i->protocol == 0 ||
|
||||
i->protocol == protocol)
|
||||
{
|
||||
i->handler (device, packet, protocol, from);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
}//namespace ns3
|
||||
|
||||
130
src/node/node.h
130
src/node/node.h
@@ -1,33 +1,31 @@
|
||||
// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
|
||||
//
|
||||
// Copyright (c) 2006 Georgia Tech Research Corporation
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation;
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// Author: George F. Riley<riley@ece.gatech.edu>
|
||||
//
|
||||
|
||||
// Define the basic Node object for ns3.
|
||||
// George F. Riley, Georgia Tech, Fall 2006
|
||||
|
||||
#ifndef I_NODE_H
|
||||
#define I_NODE_H
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2006 Georgia Tech Research Corporation, INRIA
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: George F. Riley<riley@ece.gatech.edu>
|
||||
* Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#ifndef NODE_H
|
||||
#define NODE_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "ns3/object.h"
|
||||
#include "ns3/callback.h"
|
||||
#include "ns3/array-trace-resolver.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -35,6 +33,9 @@ class TraceContext;
|
||||
class TraceResolver;
|
||||
class NetDevice;
|
||||
class Application;
|
||||
class Packet;
|
||||
class Address;
|
||||
class CompositeTraceResolver;
|
||||
|
||||
/**
|
||||
* \brief A network Node.
|
||||
@@ -57,6 +58,18 @@ class Node : public Object
|
||||
{
|
||||
public:
|
||||
static const InterfaceId iid;
|
||||
typedef ArrayTraceResolver<Ptr<NetDevice> >::Index NetDeviceIndex;
|
||||
|
||||
/**
|
||||
* Must be invoked by subclasses only.
|
||||
*/
|
||||
Node();
|
||||
/**
|
||||
* \param systemId a unique integer used for parallel simulations.
|
||||
*
|
||||
* Must be invoked by subclasses only.
|
||||
*/
|
||||
Node(uint32_t systemId);
|
||||
|
||||
virtual ~Node();
|
||||
|
||||
@@ -93,11 +106,15 @@ public:
|
||||
* Associate this device to this node.
|
||||
* This method is called automatically from NetDevice::NetDevice
|
||||
* so the user has little reason to call this method himself.
|
||||
* The index returned is always non-zero.
|
||||
*/
|
||||
uint32_t AddDevice (Ptr<NetDevice> device);
|
||||
/**
|
||||
* \param index the index of the requested NetDevice
|
||||
* \returns the requested NetDevice associated to this Node.
|
||||
*
|
||||
* The indexes used by the GetDevice method start at one and
|
||||
* end at GetNDevices ()
|
||||
*/
|
||||
Ptr<NetDevice> GetDevice (uint32_t index) const;
|
||||
/**
|
||||
@@ -127,31 +144,51 @@ public:
|
||||
*/
|
||||
uint32_t GetNApplications (void) const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Must be invoked by subclasses only.
|
||||
* A protocol handler
|
||||
*/
|
||||
Node();
|
||||
typedef Callback<void,Ptr<NetDevice>, const Packet &,uint16_t,const Address &> ProtocolHandler;
|
||||
/**
|
||||
* \param systemId a unique integer used for parallel simulations.
|
||||
* \param handler the handler to register
|
||||
* \param protocolType the type of protocol this handler is
|
||||
* interested in. This protocol type is a so-called
|
||||
* EtherType, as registered here:
|
||||
* http://standards.ieee.org/regauth/ethertype/eth.txt
|
||||
* the value zero is interpreted as matching all
|
||||
* protocols.
|
||||
* \param device the device attached to this handler. If the
|
||||
* value is zero, the handler is attached to all
|
||||
* devices on this node.
|
||||
*/
|
||||
void RegisterProtocolHandler (ProtocolHandler handler,
|
||||
uint16_t protocolType,
|
||||
Ptr<NetDevice> device);
|
||||
/**
|
||||
* \param handler the handler to unregister
|
||||
*
|
||||
* Must be invoked by subclasses only.
|
||||
* After this call returns, the input handler will never
|
||||
* be invoked anymore.
|
||||
*/
|
||||
Node(uint32_t systemId);
|
||||
void UnregisterProtocolHandler (ProtocolHandler handler);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* The dispose method. Subclasses must override this method
|
||||
* and must chain up to it by calling Node::DoDispose at the
|
||||
* end of their own DoDispose method.
|
||||
*/
|
||||
virtual void DoDispose (void);
|
||||
private:
|
||||
/**
|
||||
* \param context the trace context
|
||||
* \returns a trace resolver to the user. The user must delete it.
|
||||
* \param resolver the resolver to store trace sources in.
|
||||
*
|
||||
* Subclasses must implement this method.
|
||||
* If a subclass wants to add new traces to a Node, it needs
|
||||
* to override this method and record the new trace sources
|
||||
* in the input resolver. Subclasses also _must_ chain up to
|
||||
* their parent's DoFillTraceResolver method prior
|
||||
* to recording they own trace sources.
|
||||
*/
|
||||
virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context) = 0;
|
||||
virtual void DoFillTraceResolver (CompositeTraceResolver &resolver);
|
||||
private:
|
||||
/**
|
||||
* \param device the device added to this Node.
|
||||
*
|
||||
@@ -160,14 +197,29 @@ private:
|
||||
* at this point to setup the node's receive function for
|
||||
* the NetDevice packets.
|
||||
*/
|
||||
virtual void DoAddDevice (Ptr<NetDevice> device) = 0;
|
||||
virtual void NotifyDeviceAdded (Ptr<NetDevice> device);
|
||||
|
||||
bool ReceiveFromDevice (Ptr<NetDevice> device, const Packet &packet,
|
||||
uint16_t protocol, const Address &from);
|
||||
void Construct (void);
|
||||
TraceResolver *CreateDevicesTraceResolver (const TraceContext &context);
|
||||
|
||||
enum TraceSource {
|
||||
DEVICES
|
||||
};
|
||||
struct ProtocolHandlerEntry {
|
||||
ProtocolHandler handler;
|
||||
uint16_t protocol;
|
||||
Ptr<NetDevice> device;
|
||||
};
|
||||
typedef std::vector<struct Node::ProtocolHandlerEntry> ProtocolHandlerList;
|
||||
uint32_t m_id; // Node id for this node
|
||||
uint32_t m_sid; // System id for this node
|
||||
std::vector<Ptr<NetDevice> > m_devices;
|
||||
std::vector<Ptr<Application> > m_applications;
|
||||
ProtocolHandlerList m_handlers;
|
||||
};
|
||||
|
||||
} //namespace ns3
|
||||
|
||||
#endif /* I_NODE_H */
|
||||
#endif /* NODE_H */
|
||||
|
||||
134
src/node/packet-socket-address.cc
Normal file
134
src/node/packet-socket-address.cc
Normal file
@@ -0,0 +1,134 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 INRIA
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#include "packet-socket-address.h"
|
||||
#include "net-device.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
PacketSocketAddress::PacketSocketAddress ()
|
||||
{}
|
||||
void
|
||||
PacketSocketAddress::SetProtocol (uint16_t protocol)
|
||||
{
|
||||
m_protocol = protocol;
|
||||
}
|
||||
void
|
||||
PacketSocketAddress::SetAllDevices (void)
|
||||
{
|
||||
m_isSingleDevice = false;
|
||||
m_device = 0;
|
||||
}
|
||||
void
|
||||
PacketSocketAddress::SetSingleDevice (uint32_t index)
|
||||
{
|
||||
m_isSingleDevice = true;
|
||||
m_device = index;
|
||||
}
|
||||
void
|
||||
PacketSocketAddress::SetPhysicalAddress (const Address address)
|
||||
{
|
||||
m_address = address;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
PacketSocketAddress::GetProtocol (void) const
|
||||
{
|
||||
return m_protocol;
|
||||
}
|
||||
bool
|
||||
PacketSocketAddress::IsSingleDevice (void) const
|
||||
{
|
||||
return m_isSingleDevice;
|
||||
}
|
||||
uint32_t
|
||||
PacketSocketAddress::GetSingleDevice (void) const
|
||||
{
|
||||
return m_device;
|
||||
}
|
||||
Address
|
||||
PacketSocketAddress::GetPhysicalAddress (void) const
|
||||
{
|
||||
return m_address;
|
||||
}
|
||||
|
||||
PacketSocketAddress::operator Address () const
|
||||
{
|
||||
return ConvertTo ();
|
||||
}
|
||||
|
||||
Address
|
||||
PacketSocketAddress::ConvertTo (void) const
|
||||
{
|
||||
Address address;
|
||||
uint8_t buffer[Address::MAX_SIZE];
|
||||
buffer[0] = m_protocol & 0xff;
|
||||
buffer[1] = (m_protocol >> 8) & 0xff;
|
||||
buffer[2] = (m_device >> 24) & 0xff;
|
||||
buffer[3] = (m_device >> 16) & 0xff;
|
||||
buffer[4] = (m_device >> 8) & 0xff;
|
||||
buffer[5] = (m_device >> 0) & 0xff;
|
||||
buffer[6] = m_isSingleDevice?1:0;
|
||||
uint32_t copied = m_address.CopyAllTo (buffer + 7, Address::MAX_SIZE - 7);
|
||||
return Address (GetType (), buffer, 7 + copied);
|
||||
}
|
||||
PacketSocketAddress
|
||||
PacketSocketAddress::ConvertFrom (const Address &address)
|
||||
{
|
||||
NS_ASSERT (IsMatchingType (address));
|
||||
uint8_t buffer[Address::MAX_SIZE];
|
||||
address.CopyTo (buffer);
|
||||
uint16_t protocol = buffer[0] | (buffer[1] << 8);
|
||||
uint32_t device = 0;
|
||||
device |= buffer[2];
|
||||
device <<= 8;
|
||||
device |= buffer[3];
|
||||
device <<= 8;
|
||||
device |= buffer[4];
|
||||
device <<= 8;
|
||||
device |= buffer[5];
|
||||
bool isSingleDevice = (buffer[6] == 1)?true:false;
|
||||
Address physical;
|
||||
physical.CopyAllFrom (buffer + 7, Address::MAX_SIZE - 7);
|
||||
PacketSocketAddress ad;
|
||||
ad.SetProtocol (protocol);
|
||||
if (isSingleDevice)
|
||||
{
|
||||
ad.SetSingleDevice (device);
|
||||
}
|
||||
else
|
||||
{
|
||||
ad.SetAllDevices ();
|
||||
}
|
||||
ad.SetPhysicalAddress (physical);
|
||||
return ad;
|
||||
}
|
||||
bool
|
||||
PacketSocketAddress::IsMatchingType (const Address &address)
|
||||
{
|
||||
return address.IsMatchingType (GetType ());
|
||||
}
|
||||
uint8_t
|
||||
PacketSocketAddress::GetType (void)
|
||||
{
|
||||
static uint8_t type = Address::Register ();
|
||||
return type;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
77
src/node/packet-socket-address.h
Normal file
77
src/node/packet-socket-address.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 INRIA
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#ifndef PACKET_SOCKET_ADDRESS_H
|
||||
#define PACKET_SOCKET_ADDRESS_H
|
||||
|
||||
#include "ns3/ptr.h"
|
||||
#include "address.h"
|
||||
#include "eui48-address.h"
|
||||
#include "eui64-address.h"
|
||||
#include "net-device.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class NetDevice;
|
||||
|
||||
class PacketSocketAddress
|
||||
{
|
||||
public:
|
||||
PacketSocketAddress ();
|
||||
void SetProtocol (uint16_t protocol);
|
||||
|
||||
void SetAllDevices (void);
|
||||
void SetSingleDevice (uint32_t device);
|
||||
void SetPhysicalAddress (const Address address);
|
||||
|
||||
uint16_t GetProtocol (void) const;
|
||||
uint32_t GetSingleDevice (void) const;
|
||||
bool IsSingleDevice (void) const;
|
||||
Address GetPhysicalAddress (void) const;
|
||||
|
||||
/**
|
||||
* \returns a new Address instance
|
||||
*
|
||||
* Convert an instance of this class to a polymorphic Address instance.
|
||||
*/
|
||||
operator Address () const;
|
||||
/**
|
||||
* \param address a polymorphic address
|
||||
*
|
||||
* Convert a polymorphic address to an Eui48Address instance.
|
||||
* The conversion performs a type check.
|
||||
*/
|
||||
static PacketSocketAddress ConvertFrom (const Address &address);
|
||||
/**
|
||||
* \returns true if the address matches, false otherwise.
|
||||
*/
|
||||
static bool IsMatchingType (const Address &address);
|
||||
private:
|
||||
static uint8_t GetType (void);
|
||||
Address ConvertTo (void) const;
|
||||
uint16_t m_protocol;
|
||||
bool m_isSingleDevice;
|
||||
uint32_t m_device;
|
||||
Address m_address;
|
||||
};
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* PACKET_SOCKET_ADDRESS_H */
|
||||
40
src/node/packet-socket-factory.cc
Normal file
40
src/node/packet-socket-factory.cc
Normal file
@@ -0,0 +1,40 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 Emmanuelle Laprise
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
|
||||
*/
|
||||
#include "packet-socket-factory.h"
|
||||
#include "node.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
const InterfaceId PacketSocketFactory::iid = MakeInterfaceId ("Packet",
|
||||
SocketFactory::iid);
|
||||
|
||||
PacketSocketFactory::PacketSocketFactory ()
|
||||
{
|
||||
SetInterfaceId (PacketSocketFactory::iid);
|
||||
}
|
||||
|
||||
Ptr<Socket> PacketSocketFactory::CreateSocket (void)
|
||||
{
|
||||
Ptr<Node> node = QueryInterface<Node> (Node::iid);
|
||||
Ptr<PacketSocket> socket = Create<PacketSocket> (node);
|
||||
return socket;
|
||||
}
|
||||
} // namespace ns3
|
||||
52
src/node/packet-socket-factory.h
Normal file
52
src/node/packet-socket-factory.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 Emmanuelle Laprise
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
|
||||
*/
|
||||
#ifndef PACKET_SOCKET_FACTORY_H
|
||||
#define PACKET_SOCKET_FACTORY_H
|
||||
|
||||
#include "socket-factory.h"
|
||||
#include "packet-socket.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class Socket;
|
||||
|
||||
/**
|
||||
* This can be used as an interface in a node in order for the node to
|
||||
* generate PacketSockets that can connect to net devices.
|
||||
*/
|
||||
class PacketSocketFactory : public SocketFactory
|
||||
{
|
||||
public:
|
||||
static const InterfaceId iid; /// Interface identifier
|
||||
|
||||
PacketSocketFactory ();
|
||||
|
||||
/**
|
||||
* Creates a PacketSocket and returns a pointer to it.
|
||||
*
|
||||
* \return a pointer to the created socket
|
||||
*/
|
||||
virtual Ptr<Socket> CreateSocket (void);
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* PACKET_SOCKET_FACTORY_H */
|
||||
341
src/node/packet-socket.cc
Normal file
341
src/node/packet-socket.cc
Normal file
@@ -0,0 +1,341 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 Emmanuelle Laprise, INRIA
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
|
||||
* Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
|
||||
#include "packet-socket.h"
|
||||
#include "packet-socket-address.h"
|
||||
#include "ns3/debug.h"
|
||||
#include "ns3/node.h"
|
||||
|
||||
NS_DEBUG_COMPONENT_DEFINE ("PacketSocket");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
PacketSocket::PacketSocket (Ptr<Node> node)
|
||||
: m_node (node)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
void
|
||||
PacketSocket::Init()
|
||||
{
|
||||
m_state = STATE_OPEN;
|
||||
m_shutdownSend = false;
|
||||
m_shutdownRecv = false;
|
||||
m_errno = ERROR_NOTERROR;
|
||||
}
|
||||
|
||||
PacketSocket::~PacketSocket ()
|
||||
{}
|
||||
|
||||
void
|
||||
PacketSocket::DoDispose (void)
|
||||
{
|
||||
m_device = 0;
|
||||
}
|
||||
|
||||
Ptr<Node>
|
||||
PacketSocket::GetNode (void) const
|
||||
{
|
||||
return m_node;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
PacketSocket::Bind (void)
|
||||
{
|
||||
PacketSocketAddress address;
|
||||
address.SetProtocol (0);
|
||||
address.SetAllDevices ();
|
||||
return DoBind (address);
|
||||
}
|
||||
int
|
||||
PacketSocket::Bind (const Address &address)
|
||||
{
|
||||
if (!PacketSocketAddress::IsMatchingType (address))
|
||||
{
|
||||
m_errno = ERROR_INVAL;
|
||||
return -1;
|
||||
}
|
||||
PacketSocketAddress ad = PacketSocketAddress::ConvertFrom (address);
|
||||
return DoBind (ad);
|
||||
}
|
||||
|
||||
int
|
||||
PacketSocket::DoBind (const PacketSocketAddress &address)
|
||||
{
|
||||
if (m_state == STATE_BOUND ||
|
||||
m_state == STATE_CONNECTED)
|
||||
{
|
||||
m_errno = ERROR_INVAL;
|
||||
return -1;
|
||||
}
|
||||
if (m_state == STATE_CLOSED)
|
||||
{
|
||||
m_errno = ERROR_BADF;
|
||||
return -1;
|
||||
}
|
||||
Ptr<NetDevice> dev ;
|
||||
if (address.IsSingleDevice ())
|
||||
{
|
||||
dev = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_node->GetDevice (address.GetSingleDevice ());
|
||||
}
|
||||
m_node->RegisterProtocolHandler (MakeCallback (&PacketSocket::ForwardUp, this),
|
||||
address.GetProtocol (), dev);
|
||||
m_state = STATE_BOUND;
|
||||
m_protocol = address.GetProtocol ();
|
||||
m_isSingleDevice = address.IsSingleDevice ();
|
||||
m_device = address.GetSingleDevice ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum Socket::SocketErrno
|
||||
PacketSocket::GetErrno (void) const
|
||||
{
|
||||
return m_errno;
|
||||
}
|
||||
int
|
||||
PacketSocket::ShutdownSend (void)
|
||||
{
|
||||
if (m_state == STATE_CLOSED)
|
||||
{
|
||||
m_errno = ERROR_BADF;
|
||||
return -1;
|
||||
}
|
||||
m_shutdownSend = true;
|
||||
return 0;
|
||||
}
|
||||
int
|
||||
PacketSocket::ShutdownRecv (void)
|
||||
{
|
||||
if (m_state == STATE_CLOSED)
|
||||
{
|
||||
m_errno = ERROR_BADF;
|
||||
return -1;
|
||||
}
|
||||
m_shutdownRecv = false;
|
||||
return 0;
|
||||
}
|
||||
int
|
||||
PacketSocket::DoClose(ns3::Callback<void, Ptr<Socket> > closeCompleted)
|
||||
{
|
||||
if (m_state == STATE_CLOSED)
|
||||
{
|
||||
m_errno = ERROR_BADF;
|
||||
return -1;
|
||||
}
|
||||
if (!closeCompleted.IsNull ())
|
||||
{
|
||||
closeCompleted (this);
|
||||
}
|
||||
m_state = STATE_CLOSED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
PacketSocket::DoConnect(const Address &ad,
|
||||
ns3::Callback<void, Ptr<Socket> > connectionSucceeded,
|
||||
ns3::Callback<void, Ptr<Socket> > connectionFailed,
|
||||
ns3::Callback<void, Ptr<Socket> > halfClose)
|
||||
{
|
||||
PacketSocketAddress address;
|
||||
if (m_state == STATE_CLOSED)
|
||||
{
|
||||
m_errno = ERROR_BADF;
|
||||
goto error;
|
||||
}
|
||||
if (m_state == STATE_OPEN)
|
||||
{
|
||||
// connect should happen _after_ bind.
|
||||
m_errno = ERROR_INVAL; // generic error condition.
|
||||
goto error;
|
||||
}
|
||||
if (m_state == STATE_CONNECTED)
|
||||
{
|
||||
m_errno = ERROR_ISCONN;
|
||||
goto error;
|
||||
}
|
||||
if (!PacketSocketAddress::IsMatchingType (ad))
|
||||
{
|
||||
m_errno = ERROR_AFNOSUPPORT;
|
||||
goto error;
|
||||
}
|
||||
m_destAddr = ad;
|
||||
m_state = STATE_CONNECTED;
|
||||
if (!connectionSucceeded.IsNull ())
|
||||
{
|
||||
connectionSucceeded (this);
|
||||
}
|
||||
return 0;
|
||||
error:
|
||||
if (!connectionFailed.IsNull ())
|
||||
{
|
||||
connectionFailed (this);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
PacketSocket::DoAccept(ns3::Callback<bool, Ptr<Socket>, const Address &> connectionRequest,
|
||||
ns3::Callback<void, Ptr<Socket>, const Address &> newConnectionCreated,
|
||||
ns3::Callback<void, Ptr<Socket> > closeRequested)
|
||||
{
|
||||
// calling accept on a packet socket is a programming error.
|
||||
m_errno = ERROR_OPNOTSUPP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
PacketSocket::DoSend (const uint8_t* buffer,
|
||||
uint32_t size,
|
||||
ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent)
|
||||
{
|
||||
if (m_state == STATE_OPEN ||
|
||||
m_state == STATE_BOUND)
|
||||
{
|
||||
m_errno = ERROR_NOTCONN;
|
||||
return -1;
|
||||
}
|
||||
return DoSendTo (m_destAddr, buffer, size, dataSent);
|
||||
}
|
||||
|
||||
int
|
||||
PacketSocket::DoSendTo(const Address &address,
|
||||
const uint8_t *buffer,
|
||||
uint32_t size,
|
||||
Callback<void, Ptr<Socket>, uint32_t> dataSent)
|
||||
{
|
||||
PacketSocketAddress ad;
|
||||
if (m_state == STATE_CLOSED)
|
||||
{
|
||||
m_errno = ERROR_BADF;
|
||||
return -1;
|
||||
}
|
||||
if (m_state == STATE_OPEN)
|
||||
{
|
||||
// XXX should return another error here.
|
||||
m_errno = ERROR_INVAL;
|
||||
return -1;
|
||||
}
|
||||
if (m_shutdownSend)
|
||||
{
|
||||
m_errno = ERROR_SHUTDOWN;
|
||||
return -1;
|
||||
}
|
||||
if (!PacketSocketAddress::IsMatchingType (address))
|
||||
{
|
||||
m_errno = ERROR_AFNOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
ad = PacketSocketAddress::ConvertFrom (address);
|
||||
|
||||
Packet p;
|
||||
if (buffer == 0)
|
||||
{
|
||||
p = Packet (size);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = Packet (buffer, size);
|
||||
}
|
||||
|
||||
bool error = false;
|
||||
Address dest = ad.GetPhysicalAddress ();
|
||||
if (ad.IsSingleDevice ())
|
||||
{
|
||||
Ptr<NetDevice> device = m_node->GetDevice (ad.GetSingleDevice ());
|
||||
if (!device->Send (p, dest, ad.GetProtocol ()))
|
||||
{
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint32_t i = 0; i < m_node->GetNDevices (); i++)
|
||||
{
|
||||
Ptr<NetDevice> device = m_node->GetDevice (i);
|
||||
if (!device->Send (p, dest, ad.GetProtocol ()))
|
||||
{
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!error && !dataSent.IsNull ())
|
||||
{
|
||||
dataSent (this, p.GetSize ());
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
m_errno = ERROR_INVAL;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PacketSocket::DoRecv(ns3::Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address &> callback)
|
||||
{
|
||||
m_rxCallback = callback;
|
||||
}
|
||||
|
||||
void
|
||||
PacketSocket::DoRecvDummy(ns3::Callback<void, Ptr<Socket>, uint32_t, const Address &> callback)
|
||||
{
|
||||
m_dummyRxCallback = callback;
|
||||
}
|
||||
|
||||
void
|
||||
PacketSocket::ForwardUp (Ptr<NetDevice> device, const Packet &packet,
|
||||
uint16_t protocol, const Address &from)
|
||||
{
|
||||
if (m_shutdownRecv)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Packet p = packet;
|
||||
|
||||
PacketSocketAddress address;
|
||||
address.SetPhysicalAddress (from);
|
||||
address.SetSingleDevice (device->GetIfIndex ());
|
||||
address.SetProtocol (protocol);
|
||||
|
||||
NS_DEBUG ("PacketSocket::ForwardUp: UID is " << packet.GetUid()
|
||||
<< " PacketSocket " << this);
|
||||
if (!m_dummyRxCallback.IsNull ())
|
||||
{
|
||||
m_dummyRxCallback (this, p.GetSize (), address);
|
||||
}
|
||||
if (!m_rxCallback.IsNull ())
|
||||
{
|
||||
m_rxCallback (this, p.PeekData (), p.GetSize (), address);
|
||||
}
|
||||
}
|
||||
|
||||
}//namespace ns3
|
||||
133
src/node/packet-socket.h
Normal file
133
src/node/packet-socket.h
Normal file
@@ -0,0 +1,133 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 Emmanuelle Laprise, INRIA
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>,
|
||||
* Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#ifndef PACKET_SOCKET_H
|
||||
#define PACKET_SOCKET_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "ns3/callback.h"
|
||||
#include "ns3/ptr.h"
|
||||
#include "ns3/socket.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class Node;
|
||||
class Packet;
|
||||
class NetDevice;
|
||||
class PacketSocketAddress;
|
||||
|
||||
/**
|
||||
* \brief A PacketSocket is a link between an application and a net device.
|
||||
*
|
||||
* A PacketSocket can be used to connect an application to a net
|
||||
* device. The application provides the buffers of data, the socket
|
||||
* conserts them to a raw packet and the net device then adds the
|
||||
* protocol specific headers and trailers. This socket type
|
||||
* is very similar to the linux and BSD "packet" sockets.
|
||||
*
|
||||
* Here is a summary of the semantics of this class:
|
||||
* - Bind: Bind uses only the protocol and device fields of the
|
||||
* PacketSocketAddress. If none are provided, Bind uses
|
||||
* zero for both, which means that the socket is bound
|
||||
* to all protocols on all devices on the node.
|
||||
*
|
||||
* - Connect: uses only the protocol, device and "physical address"
|
||||
* field of the PacketSocketAddress. It is used to set the default
|
||||
* destination address for outgoing packets.
|
||||
*
|
||||
* - Send: send the input packet to the underlying NetDevices
|
||||
* with the default destination address. The socket must
|
||||
* be bound and connected.
|
||||
*
|
||||
* - SendTo: uses the protocol, device, and "physical address"
|
||||
* fields of the PacketSocketAddress. The device value is
|
||||
* used to specialize the packet transmission to a single
|
||||
* device, the protocol value specifies the protocol of this
|
||||
* packet only and the "physical address" field is used to override the
|
||||
* default destination address. The socket must be bound.
|
||||
*
|
||||
* - Recv: The address represents the address of the packer originator.
|
||||
* The fields "physical address", device, and protocol are filled.
|
||||
*
|
||||
* - Accept: not allowed
|
||||
*/
|
||||
class PacketSocket : public Socket
|
||||
{
|
||||
public:
|
||||
PacketSocket (Ptr<Node> node);
|
||||
virtual ~PacketSocket ();
|
||||
|
||||
virtual enum SocketErrno GetErrno (void) const;
|
||||
virtual Ptr<Node> GetNode (void) const;
|
||||
virtual int Bind (void);
|
||||
virtual int Bind (const Address & address);
|
||||
virtual int ShutdownSend (void);
|
||||
virtual int ShutdownRecv (void);
|
||||
|
||||
private:
|
||||
virtual int DoClose(Callback<void, Ptr<Socket> > closeCompleted);
|
||||
virtual int DoConnect(const Address & address,
|
||||
Callback<void, Ptr<Socket> > connectionSucceeded,
|
||||
Callback<void, Ptr<Socket> > connectionFailed,
|
||||
Callback<void, Ptr<Socket> > halfClose);
|
||||
virtual int DoAccept(Callback<bool, Ptr<Socket>, const Address&> connectionRequest,
|
||||
Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
|
||||
Callback<void, Ptr<Socket> > closeRequested);
|
||||
virtual int DoSend (const uint8_t* buffer,
|
||||
uint32_t size,
|
||||
Callback<void, Ptr<Socket>, uint32_t> dataSent);
|
||||
virtual int DoSendTo(const Address &address,
|
||||
const uint8_t *buffer,
|
||||
uint32_t size,
|
||||
Callback<void, Ptr<Socket>, uint32_t> dataSent);
|
||||
virtual void DoRecv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address&> receive);
|
||||
virtual void DoRecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Address&>);
|
||||
|
||||
private:
|
||||
void Init (void);
|
||||
void ForwardUp (Ptr<NetDevice> device, const Packet &packet,
|
||||
uint16_t protocol, const Address &from);
|
||||
int DoBind (const PacketSocketAddress &address);
|
||||
virtual void DoDispose (void);
|
||||
|
||||
enum State {
|
||||
STATE_OPEN,
|
||||
STATE_BOUND, // open and bound
|
||||
STATE_CONNECTED, // open, bound and connected
|
||||
STATE_CLOSED
|
||||
};
|
||||
Ptr<Node> m_node;
|
||||
Callback<void,Ptr<Socket>,uint32_t,const Address &> m_dummyRxCallback;
|
||||
Callback<void,Ptr<Socket>,uint8_t const*,uint32_t, const Address &> m_rxCallback;
|
||||
enum SocketErrno m_errno;
|
||||
bool m_shutdownSend;
|
||||
bool m_shutdownRecv;
|
||||
enum State m_state;
|
||||
uint16_t m_protocol;
|
||||
bool m_isSingleDevice;
|
||||
uint32_t m_device;
|
||||
Address m_destAddr; /// Default destination address
|
||||
};
|
||||
|
||||
}//namespace ns3
|
||||
|
||||
#endif /* PACKET_SOCKET_H */
|
||||
|
||||
|
||||
@@ -5,24 +5,23 @@ namespace ns3 {
|
||||
Socket::~Socket ()
|
||||
{}
|
||||
|
||||
void
|
||||
int
|
||||
Socket::Close(Callback<void, Ptr<Socket> > closeCompleted)
|
||||
{
|
||||
DoClose (closeCompleted);
|
||||
return DoClose (closeCompleted);
|
||||
}
|
||||
|
||||
void
|
||||
Socket::Connect(const Ipv4Address & address,
|
||||
uint16_t portNumber,
|
||||
int
|
||||
Socket::Connect(const Address & address,
|
||||
Callback<void, Ptr<Socket> > connectionSucceeded,
|
||||
Callback<void, Ptr<Socket> > connectionFailed,
|
||||
Callback<void, Ptr<Socket> > halfClose)
|
||||
{
|
||||
DoConnect (address, portNumber, connectionSucceeded, connectionFailed, halfClose);
|
||||
return DoConnect (address, connectionSucceeded, connectionFailed, halfClose);
|
||||
}
|
||||
int
|
||||
Socket::Accept(Callback<bool, Ptr<Socket>, const Ipv4Address&, uint16_t> connectionRequest,
|
||||
Callback<void, Ptr<Socket>, const Ipv4Address&, uint16_t> newConnectionCreated,
|
||||
Socket::Accept(Callback<bool, Ptr<Socket>, const Address&> connectionRequest,
|
||||
Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
|
||||
Callback<void, Ptr<Socket> > closeRequested)
|
||||
{
|
||||
return DoAccept (connectionRequest, newConnectionCreated, closeRequested);
|
||||
@@ -35,28 +34,27 @@ Socket::Send (const uint8_t* buffer,
|
||||
return DoSend (buffer, size, dataSent);
|
||||
}
|
||||
int
|
||||
Socket::SendTo(const Ipv4Address &address,
|
||||
uint16_t port,
|
||||
Socket::SendTo(const Address &address,
|
||||
const uint8_t *buffer,
|
||||
uint32_t size,
|
||||
Callback<void, Ptr<Socket>, uint32_t> dataSent)
|
||||
{
|
||||
return DoSendTo (address, port, buffer, size, dataSent);
|
||||
return DoSendTo (address, buffer, size, dataSent);
|
||||
}
|
||||
void
|
||||
Socket::Recv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> callback)
|
||||
Socket::Recv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address&> callback)
|
||||
{
|
||||
DoRecv (callback);
|
||||
}
|
||||
void
|
||||
Socket::RecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Ipv4Address&, uint16_t> callback)
|
||||
Socket::RecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Address&> callback)
|
||||
{
|
||||
DoRecvDummy (callback);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Socket::RefuseAllConnections (Ptr<Socket> socket, const Ipv4Address& address, uint16_t port)
|
||||
Socket::RefuseAllConnections (Ptr<Socket> socket, const Address& address)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -67,14 +65,14 @@ void
|
||||
Socket::DummyCallbackVoidSocketUi32 (Ptr<Socket> socket, uint32_t)
|
||||
{}
|
||||
void
|
||||
Socket::DummyCallbackVoidSocketUi32Ipv4AddressUi16 (Ptr<Socket> socket, uint32_t, const Ipv4Address &, uint16_t)
|
||||
Socket::DummyCallbackVoidSocketUi32Address (Ptr<Socket> socket, uint32_t, const Address &)
|
||||
{}
|
||||
void
|
||||
Socket::DummyCallbackVoidSocketBufferUi32Ipv4AddressUi16 (Ptr<Socket> socket, const uint8_t *, uint32_t,
|
||||
const Ipv4Address &, uint16_t)
|
||||
Socket::DummyCallbackVoidSocketBufferUi32Address (Ptr<Socket> socket, const uint8_t *, uint32_t,
|
||||
const Address &)
|
||||
{}
|
||||
void
|
||||
Socket::DummyCallbackVoidSocketIpv4AddressUi16 (Ptr<Socket> socket, const Ipv4Address &, uint16_t)
|
||||
Socket::DummyCallbackVoidSocketAddress (Ptr<Socket> socket, const Address &)
|
||||
{}
|
||||
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
|
||||
#include "ns3/callback.h"
|
||||
#include "ns3/ptr.h"
|
||||
#include "ipv4-address.h"
|
||||
#include "ns3/object.h"
|
||||
#include "address.h"
|
||||
#include <stdint.h>
|
||||
|
||||
namespace ns3 {
|
||||
@@ -35,8 +35,7 @@ class Node;
|
||||
* \brief Define a Socket API based on the BSD Socket API.
|
||||
*
|
||||
* Contrary to the original BSD socket API, this API is asynchronous:
|
||||
* it does not contain blocking calls. This API also does not use
|
||||
* the dreaded BSD sockaddr_t type. Other than that, it tries to stick
|
||||
* it does not contain blocking calls. Other than that, it tries to stick
|
||||
* to the BSD API to make it easier those who know the BSD API to use
|
||||
* this API.
|
||||
*/
|
||||
@@ -53,6 +52,9 @@ public:
|
||||
ERROR_AGAIN,
|
||||
ERROR_SHUTDOWN,
|
||||
ERROR_OPNOTSUPP,
|
||||
ERROR_AFNOSUPPORT,
|
||||
ERROR_INVAL,
|
||||
ERROR_BADF,
|
||||
SOCKET_ERRNO_LAST
|
||||
};
|
||||
|
||||
@@ -69,42 +71,20 @@ public:
|
||||
virtual Ptr<Node> GetNode (void) const = 0;
|
||||
|
||||
/**
|
||||
* Allocate a free port number and
|
||||
* bind this socket to this port number on all
|
||||
* interfaces of this system.
|
||||
*
|
||||
* \param address the address to try to allocate
|
||||
* \returns 0 on success, -1 on failure.
|
||||
*
|
||||
* Allocate a local endpoint for this socket.
|
||||
*/
|
||||
virtual int Bind (void) = 0;
|
||||
virtual int Bind (const Address &address) = 0;
|
||||
|
||||
/**
|
||||
* Allocate a free port number and
|
||||
* bind this socket to this port number on the
|
||||
* specified interface.
|
||||
* Allocate a local endpoint for this socket.
|
||||
*
|
||||
* \param address address of interface to bind to.
|
||||
* \returns 0 on success, -1 on failure.
|
||||
*/
|
||||
virtual int Bind (Ipv4Address address) = 0;
|
||||
virtual int Bind () = 0;
|
||||
|
||||
/**
|
||||
* Bind this socket to this port number
|
||||
* on all interfaces of this system.
|
||||
*
|
||||
* \param port port to bind to on all interfaces
|
||||
* \returns 0 on success, -1 on failure.
|
||||
*/
|
||||
virtual int Bind (uint16_t port) = 0;
|
||||
|
||||
/**
|
||||
* Bind this socket to this port number
|
||||
* on the interface specified by address.
|
||||
*
|
||||
* \param address address of interface to bind to.
|
||||
* \param port port to bind to on specified interface
|
||||
* \returns 0 on success, -1 on failure.
|
||||
*/
|
||||
virtual int Bind (Ipv4Address address, uint16_t port) = 0;
|
||||
|
||||
/**
|
||||
* \brief Close a socket.
|
||||
@@ -114,7 +94,7 @@ public:
|
||||
* After the Close call, the socket is no longer valid, and cannot
|
||||
* safely be used for subsequent operations.
|
||||
*/
|
||||
void Close(Callback<void, Ptr<Socket> > closeCompleted = MakeCallback (&Socket::DummyCallbackVoidSocket));
|
||||
int Close(Callback<void, Ptr<Socket> > closeCompleted = MakeCallback (&Socket::DummyCallbackVoidSocket));
|
||||
|
||||
/**
|
||||
* \returns zero on success, -1 on failure.
|
||||
@@ -134,8 +114,7 @@ public:
|
||||
|
||||
/**
|
||||
* \brief Initiate a connection to a remote host
|
||||
* \param address IP Address of remote.
|
||||
* \param portNumber Port number of remote
|
||||
* \param address Address of remote.
|
||||
* \param connectionSucceeded this callback is invoked when the connection request
|
||||
* initiated by the user is successfully completed. The callback is passed
|
||||
* back a pointer to the same socket object.
|
||||
@@ -145,11 +124,10 @@ public:
|
||||
* \param halfClose XXX When exactly is this callback invoked ? If it invoked when the
|
||||
* other side closes the connection ? Or when I call Close ?
|
||||
*/
|
||||
void Connect(const Ipv4Address & address,
|
||||
uint16_t portNumber,
|
||||
Callback<void, Ptr<Socket> > connectionSucceeded = MakeCallback(&Socket::DummyCallbackVoidSocket),
|
||||
Callback<void, Ptr<Socket> > connectionFailed = MakeCallback(&Socket::DummyCallbackVoidSocket),
|
||||
Callback<void, Ptr<Socket> > halfClose = MakeCallback(&Socket::DummyCallbackVoidSocket));
|
||||
int Connect(const Address &address,
|
||||
Callback<void, Ptr<Socket> > connectionSucceeded = MakeCallback(&Socket::DummyCallbackVoidSocket),
|
||||
Callback<void, Ptr<Socket> > connectionFailed = MakeCallback(&Socket::DummyCallbackVoidSocket),
|
||||
Callback<void, Ptr<Socket> > halfClose = MakeCallback(&Socket::DummyCallbackVoidSocket));
|
||||
|
||||
/**
|
||||
* \brief Accept connection requests from remote hosts
|
||||
@@ -170,10 +148,10 @@ public:
|
||||
* \param closeRequested Callback for connection close request from peer.
|
||||
* XXX: when is this callback invoked ?
|
||||
*/
|
||||
int Accept(Callback<bool, Ptr<Socket>, const Ipv4Address&, uint16_t> connectionRequest =
|
||||
int Accept(Callback<bool, Ptr<Socket>, const Address &> connectionRequest =
|
||||
MakeCallback(&Socket::RefuseAllConnections),
|
||||
Callback<void, Ptr<Socket>, const Ipv4Address&, uint16_t> newConnectionCreated =
|
||||
MakeCallback (&Socket::DummyCallbackVoidSocketIpv4AddressUi16),
|
||||
Callback<void, Ptr<Socket>, const Address&> newConnectionCreated =
|
||||
MakeCallback (&Socket::DummyCallbackVoidSocketAddress),
|
||||
Callback<void, Ptr<Socket> > closeRequested = MakeCallback (&Socket::DummyCallbackVoidSocket));
|
||||
|
||||
/**
|
||||
@@ -191,15 +169,13 @@ public:
|
||||
/**
|
||||
* \brief Send data to a specified peer.
|
||||
* \param address IP Address of remote host
|
||||
* \param port port number
|
||||
* \param buffer Data to send (nil if dummy data).
|
||||
* \param size Number of bytes to send.
|
||||
* \param dataSent Data sent callback.
|
||||
* \returns -1 in case of error or the number of bytes copied in the
|
||||
* internal buffer and accepted for transmission.
|
||||
*/
|
||||
int SendTo(const Ipv4Address &address,
|
||||
uint16_t port,
|
||||
int SendTo(const Address &address,
|
||||
const uint8_t *buffer,
|
||||
uint32_t size,
|
||||
Callback<void, Ptr<Socket>, uint32_t> dataSent = MakeCallback (&Socket::DummyCallbackVoidSocketUi32));
|
||||
@@ -213,8 +189,8 @@ public:
|
||||
* allocation to hold the dummy memory into a buffer which can be passed
|
||||
* to the user. Instead, consider using the RecvDummy method.
|
||||
*/
|
||||
void Recv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> receivedData =
|
||||
MakeCallback (&Socket::DummyCallbackVoidSocketBufferUi32Ipv4AddressUi16));
|
||||
void Recv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address&> receivedData =
|
||||
MakeCallback (&Socket::DummyCallbackVoidSocketBufferUi32Address));
|
||||
|
||||
/**
|
||||
* \brief Receive data
|
||||
@@ -223,38 +199,36 @@ public:
|
||||
* This method is included because it is vastly more efficient than the
|
||||
* Recv method when you use dummy payload.
|
||||
*/
|
||||
void RecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Ipv4Address&, uint16_t> receivedData =
|
||||
MakeCallback (&Socket::DummyCallbackVoidSocketUi32Ipv4AddressUi16));
|
||||
void RecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Address&> receivedData =
|
||||
MakeCallback (&Socket::DummyCallbackVoidSocketUi32Address));
|
||||
|
||||
private:
|
||||
virtual void DoClose(Callback<void, Ptr<Socket> > closeCompleted) = 0;
|
||||
virtual void DoConnect(const Ipv4Address & address,
|
||||
uint16_t portNumber,
|
||||
Callback<void, Ptr<Socket> > connectionSucceeded,
|
||||
Callback<void, Ptr<Socket> > connectionFailed,
|
||||
Callback<void, Ptr<Socket> > halfClose) = 0;
|
||||
virtual int DoAccept(Callback<bool, Ptr<Socket>, const Ipv4Address&, uint16_t> connectionRequest,
|
||||
Callback<void, Ptr<Socket>, const Ipv4Address&, uint16_t> newConnectionCreated,
|
||||
virtual int DoClose(Callback<void, Ptr<Socket> > closeCompleted) = 0;
|
||||
virtual int DoConnect(const Address & address,
|
||||
Callback<void, Ptr<Socket> > connectionSucceeded,
|
||||
Callback<void, Ptr<Socket> > connectionFailed,
|
||||
Callback<void, Ptr<Socket> > halfClose) = 0;
|
||||
virtual int DoAccept(Callback<bool, Ptr<Socket>, const Address&> connectionRequest,
|
||||
Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
|
||||
Callback<void, Ptr<Socket> > closeRequested) = 0;
|
||||
virtual int DoSend (const uint8_t* buffer,
|
||||
uint32_t size,
|
||||
Callback<void, Ptr<Socket>, uint32_t> dataSent) = 0;
|
||||
virtual int DoSendTo(const Ipv4Address &address,
|
||||
uint16_t port,
|
||||
uint32_t size,
|
||||
Callback<void, Ptr<Socket>, uint32_t> dataSent) = 0;
|
||||
virtual int DoSendTo(const Address &address,
|
||||
const uint8_t *buffer,
|
||||
uint32_t size,
|
||||
Callback<void, Ptr<Socket>, uint32_t> dataSent) = 0;
|
||||
virtual void DoRecv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> receive) = 0;
|
||||
virtual void DoRecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Ipv4Address&, uint16_t>) = 0;
|
||||
virtual void DoRecv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address&> receive) = 0;
|
||||
virtual void DoRecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Address&>) = 0;
|
||||
|
||||
|
||||
static bool RefuseAllConnections (Ptr<Socket> socket, const Ipv4Address& address, uint16_t port);
|
||||
static bool RefuseAllConnections (Ptr<Socket> socket, const Address& address);
|
||||
static void DummyCallbackVoidSocket (Ptr<Socket> socket);
|
||||
static void DummyCallbackVoidSocketUi32 (Ptr<Socket> socket, uint32_t);
|
||||
static void DummyCallbackVoidSocketUi32Ipv4AddressUi16 (Ptr<Socket> socket, uint32_t, const Ipv4Address &, uint16_t);
|
||||
static void DummyCallbackVoidSocketBufferUi32Ipv4AddressUi16 (Ptr<Socket> socket, const uint8_t *, uint32_t,
|
||||
const Ipv4Address &, uint16_t);
|
||||
static void DummyCallbackVoidSocketIpv4AddressUi16 (Ptr<Socket> socket, const Ipv4Address &, uint16_t);
|
||||
static void DummyCallbackVoidSocketUi32Address (Ptr<Socket> socket, uint32_t, const Address &);
|
||||
static void DummyCallbackVoidSocketBufferUi32Address (Ptr<Socket> socket, const uint8_t *, uint32_t,
|
||||
const Address &);
|
||||
static void DummyCallbackVoidSocketAddress (Ptr<Socket> socket, const Address &);
|
||||
};
|
||||
|
||||
} //namespace ns3
|
||||
|
||||
@@ -6,11 +6,15 @@ def build(bld):
|
||||
node.target = node.name
|
||||
node.uselib_local = ['ns3-core', 'ns3-common', 'ns3-simulator']
|
||||
node.source = [
|
||||
'address.cc',
|
||||
'eui48-address.cc',
|
||||
'eui64-address.cc',
|
||||
'inet-socket-address.cc',
|
||||
'packet-socket-address.cc',
|
||||
'node.cc',
|
||||
'ipv4-address.cc',
|
||||
'net-device.cc',
|
||||
'mac-address.cc',
|
||||
'address-utils.cc',
|
||||
'address-utils.cc',
|
||||
'llc-snap-header.cc',
|
||||
'ethernet-header.cc',
|
||||
'ethernet-trailer.cc',
|
||||
@@ -21,6 +25,8 @@ def build(bld):
|
||||
'node-list.cc',
|
||||
'socket.cc',
|
||||
'socket-factory.cc',
|
||||
'packet-socket-factory.cc',
|
||||
'packet-socket.cc',
|
||||
'udp.cc',
|
||||
'ipv4.cc',
|
||||
'application.cc',
|
||||
@@ -28,11 +34,15 @@ def build(bld):
|
||||
|
||||
headers = bld.create_obj('ns3header')
|
||||
headers.source = [
|
||||
'address.h',
|
||||
'eui48-address.h',
|
||||
'eui64-address.h',
|
||||
'inet-socket-address.h',
|
||||
'packet-socket-address.h',
|
||||
'node.h',
|
||||
'ipv4-address.h',
|
||||
'net-device.h',
|
||||
'mac-address.h',
|
||||
'address-utils.h',
|
||||
'address-utils.h',
|
||||
'ipv4-route.h',
|
||||
'queue.h',
|
||||
'drop-tail-queue.h',
|
||||
@@ -43,6 +53,7 @@ def build(bld):
|
||||
'node-list.h',
|
||||
'socket.h',
|
||||
'socket-factory.h',
|
||||
'packet-socket-factory.h',
|
||||
'udp.h',
|
||||
'ipv4.h',
|
||||
'application.h',
|
||||
|
||||
Reference in New Issue
Block a user