diff --git a/examples/csma-cd-one-subnet.cc b/examples/csma-cd-one-subnet.cc index caff83dcf..db0731a23 100644 --- a/examples/csma-cd-one-subnet.cc +++ b/examples/csma-cd-one-subnet.cc @@ -50,18 +50,14 @@ #include "ns3/csma-cd-net-device.h" #include "ns3/csma-cd-topology.h" #include "ns3/csma-cd-ipv4-topology.h" -#include "ns3/mac-address.h" +#include "ns3/eui48-address.h" #include "ns3/ipv4-address.h" +#include "ns3/inet-socket-address.h" #include "ns3/ipv4.h" #include "ns3/socket.h" #include "ns3/ipv4-route.h" #include "ns3/onoff-application.h" -#include "ns3/ascii-trace.h" - -#include "ns3/trace-context.h" -#include "ns3/trace-root.h" - using namespace ns3; @@ -105,13 +101,13 @@ int main (int argc, char *argv[]) DataRate(5000000), MilliSeconds(2)); uint32_t n0ifIndex = CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n0, channel0, - MacAddress("10:54:23:54:23:50")); + Eui48Address("10:54:23:54:23:50")); uint32_t n1ifIndex = CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n1, channel0, - MacAddress("10:54:23:54:23:51")); + Eui48Address("10:54:23:54:23:51")); uint32_t n2ifIndex = CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n2, channel0, - MacAddress("10:54:23:54:23:52")); + Eui48Address("10:54:23:54:23:52")); uint32_t n3ifIndex = CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n3, channel0, - MacAddress("10:54:23:54:23:53")); + Eui48Address("10:54:23:54:23:53")); // Later, we add IP addresses. CsmaCdIpv4Topology::AddIpv4Address ( @@ -131,8 +127,7 @@ int main (int argc, char *argv[]) // from n0 to n1 Ptr ooff = Create ( n0, - Ipv4Address("10.1.1.2"), - 80, + InetSocketAddress ("10.1.1.2", 80), "Udp", ConstantVariable(1), ConstantVariable(0)); @@ -143,8 +138,7 @@ int main (int argc, char *argv[]) // Create a similar flow from n3 to n0, starting at time 1.1 seconds ooff = Create ( n3, - Ipv4Address("10.1.1.1"), - 80, + InetSocketAddress ("10.1.1.1", 80), "Udp", ConstantVariable(1), ConstantVariable(0)); diff --git a/examples/csma-cd-packet-socket.cc b/examples/csma-cd-packet-socket.cc new file mode 100644 index 000000000..ed1976645 --- /dev/null +++ b/examples/csma-cd-packet-socket.cc @@ -0,0 +1,136 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * 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 + */ + +// Port of ns-2/tcl/ex/simple.tcl to ns-3 +// +// Network topology +// +// n0 n1 n2 n3 +// | | | | +// ===================== +// +// - CBR/UDP flows from n0 to n1, and from n3 to n0 +// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec. +// (i.e., DataRate of 448,000 bps) +// - DropTail queues +// - Tracing of queues and packet receptions to file "csma-cd-one-subnet.tr" + +#include +#include +#include +#include + +#include "ns3/command-line.h" +#include "ns3/default-value.h" +#include "ns3/ptr.h" +#include "ns3/random-variable.h" +#include "ns3/debug.h" + +#include "ns3/simulator.h" +#include "ns3/nstime.h" +#include "ns3/data-rate.h" + +#include "ns3/ascii-trace.h" +#include "ns3/pcap-trace.h" +#include "ns3/internet-node.h" +#include "ns3/csma-cd-channel.h" +#include "ns3/csma-cd-net-device.h" +#include "ns3/eui48-address.h" +#include "ns3/packet-socket-address.h" +#include "ns3/socket.h" +#include "ns3/onoff-application.h" +#include "ns3/queue.h" + +using namespace ns3; + +static Ptr +CreateCsmaCdDevice (Ptr node, Ptr channel) +{ + Ptr device = Create (node); + device->Attach (channel); + Ptr queue = Queue::CreateDefault (); + device->AddQueue (queue); + return device; +} + + +int main (int argc, char *argv[]) +{ + CommandLine::Parse (argc, argv); + + // Here, we will explicitly create four nodes. In more sophisticated + // topologies, we could configure a node factory. + Ptr n0 = Create (); + Ptr n1 = Create (); + Ptr n2 = Create (); + Ptr n3 = Create (); + + // create the shared medium used by all csma/cd devices. + Ptr channel = Create (DataRate(5000000), MilliSeconds(2)); + + // use a helper function to connect our nodes to the shared channel. + Ptr n0If = CreateCsmaCdDevice (n0, channel); + Ptr n1If = CreateCsmaCdDevice (n1, channel); + Ptr n2If = CreateCsmaCdDevice (n2, channel); + Ptr n3If = CreateCsmaCdDevice (n3, channel); + + + // create the address which identifies n1 from n0 + PacketSocketAddress n0ToN1; + n0ToN1.SetSingleDevice (n0If->GetIfIndex ()); // set outgoing interface for outgoing packets + n0ToN1.SetPhysicalAddress (n1If->GetAddress ()); // set destination address for outgoing packets + n0ToN1.SetProtocol (2); // set arbitrary protocol for outgoing packets + + // create the address which identifies n0 from n3 + PacketSocketAddress n3ToN0; + n3ToN0.SetSingleDevice (n3If->GetIfIndex ()); + n3ToN0.SetPhysicalAddress (n0If->GetAddress ()); + n3ToN0.SetProtocol (3); + + // Create the OnOff application to send raw datagrams of size + // 210 bytes at a rate of 448 Kb/s + // from n0 to n1 + Ptr ooff = Create ( + n0, + n0ToN1, + "Packet", + ConstantVariable(1), + ConstantVariable(0)); + // Start the application + ooff->Start(Seconds(1.0)); + ooff->Stop (Seconds(10.0)); + + // Create a similar flow from n3 to n0, starting at time 1.1 seconds + ooff = Create ( + n3, + n3ToN0, + "Packet", + ConstantVariable(1), + ConstantVariable(0)); + // Start the application + ooff->Start(Seconds(1.1)); + ooff->Stop (Seconds(10.0)); + + // Configure tracing of all enqueue, dequeue, and NetDevice receive events + // Trace output will be sent to the csma-cd-packet-socket.tr file + AsciiTrace asciitrace ("csma-cd-packet-socket.tr"); + asciitrace.TraceAllNetDeviceRx (); + asciitrace.TraceAllQueues (); + + Simulator::Run (); + + Simulator::Destroy (); +} diff --git a/examples/simple-global-routing.cc b/examples/simple-global-routing.cc index 2a005589a..3458bb84f 100644 --- a/examples/simple-global-routing.cc +++ b/examples/simple-global-routing.cc @@ -58,10 +58,10 @@ #include "ns3/internet-node.h" #include "ns3/point-to-point-channel.h" #include "ns3/point-to-point-net-device.h" -#include "ns3/mac-address.h" #include "ns3/ipv4-address.h" #include "ns3/ipv4.h" #include "ns3/socket.h" +#include "ns3/inet-socket-address.h" #include "ns3/ipv4-route.h" #include "ns3/point-to-point-topology.h" #include "ns3/onoff-application.h" @@ -82,7 +82,7 @@ int main (int argc, char *argv[]) DebugComponentEnable ("PointToPointChannel"); DebugComponentEnable ("PointToPointNetDevice"); DebugComponentEnable ("GlobalRouter"); - DebugComponentEnable ("GlobalRouteManager"); + DebugComponentEnable ("GlobalRouteMaager"); #endif // Set up some default values for the simulation. Use the Bind () @@ -143,8 +143,7 @@ int main (int argc, char *argv[]) // 210 bytes at a rate of 448 Kb/s Ptr ooff = Create ( n0, - Ipv4Address ("10.1.3.2"), - 80, + InetSocketAddress ("10.1.3.2", 80), "Udp", ConstantVariable (1), ConstantVariable (0)); @@ -155,8 +154,7 @@ int main (int argc, char *argv[]) // Create a similar flow from n3 to n1, starting at time 1.1 seconds ooff = Create ( n3, - Ipv4Address ("10.1.2.1"), - 80, + InetSocketAddress ("10.1.2.1", 80), "Udp", ConstantVariable (1), ConstantVariable (0)); @@ -180,4 +178,6 @@ int main (int argc, char *argv[]) Simulator::Run (); Simulator::Destroy (); + + return 0; } diff --git a/examples/simple-p2p.cc b/examples/simple-p2p.cc index 9ad235b5e..d06ef329f 100644 --- a/examples/simple-p2p.cc +++ b/examples/simple-p2p.cc @@ -56,8 +56,8 @@ #include "ns3/internet-node.h" #include "ns3/p2p-channel.h" #include "ns3/p2p-net-device.h" -#include "ns3/mac-address.h" #include "ns3/ipv4-address.h" +#include "ns3/inet-socket-address.h" #include "ns3/ipv4.h" #include "ns3/socket.h" #include "ns3/ipv4-route.h" @@ -143,8 +143,7 @@ int main (int argc, char *argv[]) // 210 bytes at a rate of 448 Kb/s Ptr ooff = Create ( n0, - Ipv4Address("10.1.3.2"), - 80, + InetSocketAddress("10.1.3.2", 80).ConvertTo (), "Udp", ConstantVariable(1), ConstantVariable(0)); @@ -155,8 +154,7 @@ int main (int argc, char *argv[]) // Create a similar flow from n3 to n1, starting at time 1.1 seconds ooff = Create ( n3, - Ipv4Address("10.1.2.1"), - 80, + InetSocketAddress("10.1.2.1", 80).ConvertTo (), "Udp", ConstantVariable(1), ConstantVariable(0)); diff --git a/examples/simple-point-to-point.cc b/examples/simple-point-to-point.cc index cf3091a7b..fa826ab5c 100644 --- a/examples/simple-point-to-point.cc +++ b/examples/simple-point-to-point.cc @@ -57,8 +57,8 @@ #include "ns3/internet-node.h" #include "ns3/point-to-point-channel.h" #include "ns3/point-to-point-net-device.h" -#include "ns3/mac-address.h" #include "ns3/ipv4-address.h" +#include "ns3/inet-socket-address.h" #include "ns3/ipv4.h" #include "ns3/socket.h" #include "ns3/ipv4-route.h" @@ -144,8 +144,7 @@ int main (int argc, char *argv[]) // 210 bytes at a rate of 448 Kb/s Ptr ooff = Create ( n0, - Ipv4Address("10.1.3.2"), - 80, + InetSocketAddress ("10.1.3.2", 80), "Udp", ConstantVariable(1), ConstantVariable(0)); @@ -156,8 +155,7 @@ int main (int argc, char *argv[]) // Create a similar flow from n3 to n1, starting at time 1.1 seconds ooff = Create ( n3, - Ipv4Address("10.1.2.1"), - 80, + InetSocketAddress ("10.1.2.1", 80), "Udp", ConstantVariable(1), ConstantVariable(0)); diff --git a/examples/wscript b/examples/wscript index 0f15f23df..71efc3a9e 100644 --- a/examples/wscript +++ b/examples/wscript @@ -15,4 +15,5 @@ def build(bld): deps=['point-to-point', 'internet-node']) obj = create_ns_prog('csma-cd-one-subnet', 'csma-cd-one-subnet.cc', deps=['csma-cd', 'internet-node']) + obj = create_ns_prog('csma-cd-packet-socket', 'csma-cd-packet-socket.cc', deps=['csma-cd', 'internet-node']) diff --git a/samples/main-simple.cc b/samples/main-simple.cc index f0f4ce4dc..3be286c46 100644 --- a/samples/main-simple.cc +++ b/samples/main-simple.cc @@ -4,6 +4,7 @@ #include "ns3/simulator.h" #include "ns3/socket-factory.h" #include "ns3/socket.h" +#include "ns3/inet-socket-address.h" #include "ns3/nstime.h" using namespace ns3; @@ -24,7 +25,7 @@ GenerateTraffic (Ptr socket, uint32_t size) } static void -SocketPrinter (Ptr socket, uint32_t size, const Ipv4Address &from, uint16_t fromPort) +SocketPrinter (Ptr socket, uint32_t size, const Address &from) { std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, rx bytes=" << size << std::endl; } @@ -44,10 +45,12 @@ RunSimulation (void) Ptr socketFactory = a->QueryInterface (iid); Ptr sink = socketFactory->CreateSocket (); - sink->Bind (80); + InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), 80); + sink->Bind (local); Ptr source = socketFactory->CreateSocket (); - source->Connect (Ipv4Address::GetLoopback (), 80); + InetSocketAddress remote = InetSocketAddress (Ipv4Address::GetLoopback (), 80); + source->Connect (remote); GenerateTraffic (source, 500); PrintTraffic (sink); diff --git a/src/applications/onoff-application.cc b/src/applications/onoff-application.cc index f9c4146c8..5fa2c8266 100644 --- a/src/applications/onoff-application.cc +++ b/src/applications/onoff-application.cc @@ -22,7 +22,7 @@ // George F. Riley, Georgia Tech, Spring 2007 // Adapted from ApplicationOnOff in GTNetS. -#include "ns3/ipv4-address.h" +#include "ns3/address.h" #include "ns3/node.h" #include "ns3/nstime.h" #include "ns3/data-rate.h" @@ -47,22 +47,20 @@ static NumericDefaultValue g_defaultSize ("OnOffApplicationPacketSize" // Constructors OnOffApplication::OnOffApplication(Ptr n, - const Ipv4Address rip, - uint16_t rport, + const Address &remote, std::string iid, const RandomVariable& ontime, const RandomVariable& offtime) : Application(n), m_cbrRate (g_defaultRate.GetValue ()) { - Construct (n, rip, rport, iid, + Construct (n, remote, iid, ontime, offtime, g_defaultSize.GetValue ()); } OnOffApplication::OnOffApplication(Ptr n, - const Ipv4Address rip, - uint16_t rport, + const Address &remote, std::string iid, const RandomVariable& ontime, const RandomVariable& offtime, @@ -71,22 +69,20 @@ OnOffApplication::OnOffApplication(Ptr n, : Application(n), m_cbrRate (rate) { - Construct (n, rip, rport, iid, + Construct (n, remote, iid, ontime, offtime, size); } void OnOffApplication::Construct (Ptr n, - const Ipv4Address rip, - uint16_t rport, + const Address &remote, std::string iid, const RandomVariable& onTime, const RandomVariable& offTime, uint32_t size) { m_socket = 0; - m_peerIp = rip; - m_peerPort = rport; + m_peer = remote; m_connected = false; m_onTime = onTime.Copy (); m_offTime = offTime.Copy (); @@ -144,7 +140,7 @@ void OnOffApplication::StartApplication() // Called at time specified by Star Ptr socketFactory = GetNode ()->QueryInterface (iid); m_socket = socketFactory->CreateSocket (); m_socket->Bind (); - m_socket->Connect (m_peerIp, m_peerPort); + m_socket->Connect (m_peer); } // Insure no pending event StopApplication(); diff --git a/src/applications/onoff-application.h b/src/applications/onoff-application.h index e3aafcb11..c42d9d14f 100644 --- a/src/applications/onoff-application.h +++ b/src/applications/onoff-application.h @@ -31,7 +31,7 @@ namespace ns3 { -class Ipv4Address; +class Address; class RandomVariable; class Socket; class DataRate; @@ -52,23 +52,20 @@ class OnOffApplication : public Application public: /** * \param n node associated to this application - * \param rip remote ip address - * \param rport remove port number + * \param remote remote ip address * \param iid * \param ontime on time random variable * \param offtime off time random variable */ OnOffApplication(Ptr n, - const Ipv4Address rip, - uint16_t rport, + const Address &remote, std::string iid, const RandomVariable& ontime, const RandomVariable& offtime); /** * \param n node associated to this application - * \param rip remote ip address - * \param rport remove port number + * \param remote remote ip address * \param iid * \param ontime on time random variable * \param offtime off time random variable @@ -76,8 +73,7 @@ public: * \param size size of packets when sending data. */ OnOffApplication(Ptr n, - const Ipv4Address rip, - uint16_t rport, + const Address &remote, std::string iid, const RandomVariable& ontime, const RandomVariable& offtime, @@ -112,8 +108,7 @@ private: virtual void StopApplication (void); // Called at time specified by Stop void Construct (Ptr n, - const Ipv4Address rip, - uint16_t rport, + const Address &remote, std::string iid, const RandomVariable& ontime, const RandomVariable& offtime, @@ -126,8 +121,7 @@ private: void SendPacket(); Ptr m_socket; // Associated socket - Ipv4Address m_peerIp; // Peer IP address - uint16_t m_peerPort; // Peer port + Address m_peer; // Peer address bool m_connected; // True if connected RandomVariable* m_onTime; // rng for On Time RandomVariable* m_offTime; // rng for Off Time diff --git a/src/common/array-trace-resolver.h b/src/common/array-trace-resolver.h index 740616b42..e4507d4af 100644 --- a/src/common/array-trace-resolver.h +++ b/src/common/array-trace-resolver.h @@ -53,11 +53,11 @@ public: */ ArrayTraceResolver (TraceContext const &context, Callback getSize, - Callback get); + Callback get); private: virtual TraceResolverList DoLookup (std::string id) const; Callback m_getSize; - Callback m_get; + Callback m_get; }; }//namespace ns3 @@ -66,7 +66,7 @@ namespace ns3 { template ArrayTraceResolver::ArrayTraceResolver (TraceContext const &context, Callback getSize, - Callback get) + Callback get) : TraceResolver (context), m_getSize (getSize), m_get (get) diff --git a/src/core/breakpoint.cc b/src/core/breakpoint.cc index c748792bc..41efcbb13 100644 --- a/src/core/breakpoint.cc +++ b/src/core/breakpoint.cc @@ -31,7 +31,7 @@ namespace ns3 { #ifdef HAVE_SIGNAL_H void -Breakpoint (void) +BreakpointFallback (void) { raise (SIGTRAP); } @@ -39,7 +39,7 @@ Breakpoint (void) #else void -Breakpoint (void) +BreakpointFallback (void) { int *a = 0; /** diff --git a/src/devices/csma-cd/csma-cd-ipv4-topology.cc b/src/devices/csma-cd/csma-cd-ipv4-topology.cc index be04cc8d4..923f89dc4 100644 --- a/src/devices/csma-cd/csma-cd-ipv4-topology.cc +++ b/src/devices/csma-cd/csma-cd-ipv4-topology.cc @@ -38,7 +38,7 @@ namespace ns3 { uint32_t CsmaCdIpv4Topology::AddIpv4CsmaCdNode(Ptr n1, Ptr ch, - MacAddress addr) + Eui48Address addr) { Ptr q = Queue::CreateDefault (); @@ -55,7 +55,7 @@ CsmaCdIpv4Topology::AddIpv4CsmaCdNode(Ptr n1, void CsmaCdIpv4Topology::AddIpv4LlcCsmaCdNode(Ptr n1, Ptr ch, - MacAddress addr) + Eui48Address addr) { Ptr q = Queue::CreateDefault (); @@ -75,7 +75,7 @@ CsmaCdIpv4Topology::AddIpv4LlcCsmaCdNode(Ptr n1, void CsmaCdIpv4Topology::AddIpv4RawCsmaCdNode(Ptr n1, Ptr ch, - MacAddress addr) + Eui48Address addr) { Ptr q = Queue::CreateDefault (); diff --git a/src/devices/csma-cd/csma-cd-ipv4-topology.h b/src/devices/csma-cd/csma-cd-ipv4-topology.h index d31ee4184..84a769880 100644 --- a/src/devices/csma-cd/csma-cd-ipv4-topology.h +++ b/src/devices/csma-cd/csma-cd-ipv4-topology.h @@ -62,8 +62,8 @@ public: * \return ifIndex of the device */ static uint32_t AddIpv4CsmaCdNode( Ptr n1, - Ptr ch, - MacAddress addr); + Ptr ch, + Eui48Address addr); /** * \param n1 Node to be attached to the Csma/Cd channel @@ -76,7 +76,7 @@ public: */ static void AddIpv4RawCsmaCdNode( Ptr n1, Ptr ch, - MacAddress addr); + Eui48Address addr); /** * \param n1 Node to be attached to the Csma/Cd channel @@ -89,7 +89,7 @@ public: */ static void AddIpv4LlcCsmaCdNode( Ptr n1, Ptr ch, - MacAddress addr); + Eui48Address addr); diff --git a/src/devices/csma-cd/csma-cd-net-device.cc b/src/devices/csma-cd/csma-cd-net-device.cc index b3527d354..141daf68c 100644 --- a/src/devices/csma-cd/csma-cd-net-device.cc +++ b/src/devices/csma-cd/csma-cd-net-device.cc @@ -35,9 +35,19 @@ NS_DEBUG_COMPONENT_DEFINE ("CsmaCdNetDevice"); namespace ns3 { -CsmaCdNetDevice::CsmaCdNetDevice (Ptr node, MacAddress addr, +CsmaCdNetDevice::CsmaCdNetDevice (Ptr node) + : NetDevice (node, Eui48Address::Allocate ()), + m_bps (DataRate (0xffffffff)) +{ + NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << node << ")"); + m_encapMode = IP_ARP; + Init(true, true); +} + +CsmaCdNetDevice::CsmaCdNetDevice (Ptr node, Eui48Address addr, CsmaCdEncapsulationMode encapMode) - : NetDevice(node, addr), m_bps (DataRate (0xffffffff)) + : NetDevice(node, addr), + m_bps (DataRate (0xffffffff)) { NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << node << ")"); m_encapMode = encapMode; @@ -45,10 +55,11 @@ CsmaCdNetDevice::CsmaCdNetDevice (Ptr node, MacAddress addr, Init(true, true); } -CsmaCdNetDevice::CsmaCdNetDevice (Ptr node, MacAddress addr, +CsmaCdNetDevice::CsmaCdNetDevice (Ptr node, Eui48Address addr, CsmaCdEncapsulationMode encapMode, bool sendEnable, bool receiveEnable) - : NetDevice(node, addr), m_bps (DataRate (0xffffffff)) + : NetDevice(node, addr), + m_bps (DataRate (0xffffffff)) { NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << node << ")"); m_encapMode = encapMode; @@ -94,7 +105,7 @@ CsmaCdNetDevice::Init(bool sendEnable, bool receiveEnable) m_channel = 0; m_queue = 0; - EnableBroadcast (MacAddress ("ff:ff:ff:ff:ff:ff")); + EnableBroadcast (Eui48Address ("ff:ff:ff:ff:ff:ff")); EnableMulticast(); EnablePointToPoint(); @@ -149,7 +160,7 @@ CsmaCdNetDevice::SetBackoffParams (Time slotTime, uint32_t minSlots, m_backoff.m_maxRetries = maxRetries; } void -CsmaCdNetDevice::AddHeader (Packet& p, const MacAddress& dest, +CsmaCdNetDevice::AddHeader (Packet& p, Eui48Address dest, uint16_t protocolNumber) { if (m_encapMode == RAW) @@ -158,7 +169,8 @@ CsmaCdNetDevice::AddHeader (Packet& p, const MacAddress& dest, } EthernetHeader header (false); EthernetTrailer trailer; - header.SetSource(this->GetAddress()); + Eui48Address source = Eui48Address::ConvertFrom (GetAddress ()); + header.SetSource(source); header.SetDestination(dest); uint16_t lengthType = 0; @@ -198,8 +210,8 @@ CsmaCdNetDevice::ProcessHeader (Packet& p, uint16_t & param) trailer.CheckFcs(p); p.RemoveHeader(header); - if ((header.GetDestination() != this->GetBroadcast()) && - (header.GetDestination() != this->GetAddress())) + if ((header.GetDestination() != GetBroadcast ()) && + (header.GetDestination() != GetAddress ())) { return false; } @@ -236,7 +248,7 @@ CsmaCdNetDevice::DoNeedsArp (void) const } bool -CsmaCdNetDevice::SendTo (Packet& p, const MacAddress& dest, uint16_t protocolNumber) +CsmaCdNetDevice::SendTo (Packet& p, const Address& dest, uint16_t protocolNumber) { NS_DEBUG ("CsmaCdNetDevice::SendTo (" << &p << ")"); NS_DEBUG ("CsmaCdNetDevice::SendTo (): UID is " << p.GetUid () << ")"); @@ -247,7 +259,8 @@ CsmaCdNetDevice::SendTo (Packet& p, const MacAddress& dest, uint16_t protocolNum if (!IsSendEnabled()) return false; - AddHeader(p, dest, protocolNumber); + Eui48Address destination = Eui48Address::ConvertFrom (dest); + AddHeader(p, destination, protocolNumber); // Place the packet to be sent on the send queue if (m_queue->Enqueue(p) == false ) @@ -451,26 +464,62 @@ CsmaCdNetDevice::AddQueue (Ptr q) } void -CsmaCdNetDevice::Receive (Packet& p) +CsmaCdNetDevice::Receive (const Packet& packet) { + EthernetHeader header (false); + EthernetTrailer trailer; + Eui48Address broadcast; + Eui48Address destination; + Packet p = packet; + NS_DEBUG ("CsmaCdNetDevice::Receive UID is (" << p.GetUid() << ")"); // Only receive if send side of net device is enabled if (!IsReceiveEnabled()) - return; - - uint16_t param = 0; - Packet packet = p; - - if (ProcessHeader(packet, param)) { - m_rxTrace (packet); - ForwardUp (packet, param); - } - else - { - m_dropTrace (packet); + goto drop; } + + if (m_encapMode == RAW) + { + ForwardUp (packet, 0, GetBroadcast ()); + goto drop; + } + p.RemoveTrailer(trailer); + trailer.CheckFcs(p); + p.RemoveHeader(header); + + broadcast = Eui48Address::ConvertFrom (GetBroadcast ()); + destination = Eui48Address::ConvertFrom (GetAddress ()); + if ((header.GetDestination() != broadcast) && + (header.GetDestination() != destination)) + { + // not for us. + goto drop; + } + + uint16_t protocol; + switch (m_encapMode) + { + case ETHERNET_V1: + case IP_ARP: + protocol = header.GetLengthType(); + break; + case LLC: { + LlcSnapHeader llc; + p.RemoveHeader (llc); + protocol = llc.GetType (); + } break; + case RAW: + NS_ASSERT (false); + break; + } + + m_rxTrace (p); + ForwardUp (p, protocol, header.GetSource ()); + return; + drop: + m_dropTrace (p); } Ptr diff --git a/src/devices/csma-cd/csma-cd-net-device.h b/src/devices/csma-cd/csma-cd-net-device.h index c3ef7586e..05a327127 100644 --- a/src/devices/csma-cd/csma-cd-net-device.h +++ b/src/devices/csma-cd/csma-cd-net-device.h @@ -25,7 +25,7 @@ #include #include "ns3/node.h" #include "ns3/backoff.h" -#include "ns3/mac-address.h" +#include "ns3/address.h" #include "ns3/net-device.h" #include "ns3/callback.h" #include "ns3/packet.h" @@ -34,6 +34,7 @@ #include "ns3/data-rate.h" #include "ns3/ptr.h" #include "ns3/random-variable.h" +#include "ns3/eui48-address.h" namespace ns3 { @@ -82,6 +83,7 @@ enum CsmaCdEncapsulationMode { LLC, /**< LLC packet encapsulation */ }; + CsmaCdNetDevice (Ptr node); /** * Construct a CsmaCdNetDevice * @@ -92,8 +94,8 @@ enum CsmaCdEncapsulationMode { * \param node the Node to which this device is connected. * \param addr The source MAC address of the net device. */ - CsmaCdNetDevice (Ptr node, MacAddress addr, CsmaCdEncapsulationMode pktType); - CsmaCdNetDevice (Ptr node, MacAddress addr, + CsmaCdNetDevice (Ptr node, Eui48Address addr, CsmaCdEncapsulationMode pktType); + CsmaCdNetDevice (Ptr node, Eui48Address addr, CsmaCdEncapsulationMode pktType, bool sendEnable, bool receiveEnable); /** @@ -172,7 +174,7 @@ enum CsmaCdEncapsulationMode { * @see CsmaCdChannel * \param p a reference to the received packet */ - void Receive (Packet& p); + void Receive (const Packet& p); bool IsSendEnabled (void); bool IsReceiveEnabled (void); @@ -210,7 +212,7 @@ protected: * \param protocolNumber In some protocols, identifies the type of * payload contained in this packet. */ - void AddHeader (Packet& p, const MacAddress& dest, + void AddHeader (Packet& p, Eui48Address dest, uint16_t protocolNumber); /** * Removes, from a packet of data, all headers and trailers that @@ -247,7 +249,7 @@ private: * \param protocolNumber -- this parameter is not used here * \return true if success, false on failure */ - virtual bool SendTo (Packet& p, const MacAddress& dest, uint16_t protocolNumber); + virtual bool SendTo (Packet& p, const Address& dest, uint16_t protocolNumber); /** * Start Sending a Packet Down the Wire. diff --git a/src/devices/csma-cd/csma-cd-topology.h b/src/devices/csma-cd/csma-cd-topology.h index b89e0b522..46c54a022 100644 --- a/src/devices/csma-cd/csma-cd-topology.h +++ b/src/devices/csma-cd/csma-cd-topology.h @@ -24,12 +24,7 @@ #include "ns3/ptr.h" #include "ns3/csma-cd-net-device.h" -#if 0 -#include "ns3/packet-socket.h" -#include "ns3/packet-socket-app.h" -#endif #include "ns3/node.h" -#include "ns3/mac-address.h" // The topology class consists of only static methods thar are used to // create the topology and data flows for an ns3 simulation diff --git a/src/devices/point-to-point/point-to-point-net-device.cc b/src/devices/point-to-point/point-to-point-net-device.cc index fff158521..7e9d5c601 100644 --- a/src/devices/point-to-point/point-to-point-net-device.cc +++ b/src/devices/point-to-point/point-to-point-net-device.cc @@ -26,9 +26,10 @@ #include "ns3/queue.h" #include "ns3/simulator.h" #include "ns3/composite-trace-resolver.h" +#include "ns3/eui48-address.h" +#include "ns3/llc-snap-header.h" #include "point-to-point-net-device.h" #include "point-to-point-channel.h" -#include "ns3/llc-snap-header.h" NS_DEBUG_COMPONENT_DEFINE ("PointToPointNetDevice"); @@ -39,10 +40,10 @@ DataRateDefaultValue PointToPointNetDevice::g_defaultRate( "The default data rate for point to point links", DataRate ("10Mb/s")); - PointToPointNetDevice::PointToPointNetDevice (Ptr node, - const DataRate& rate) +PointToPointNetDevice::PointToPointNetDevice (Ptr node, + const DataRate& rate) : - NetDevice(node, MacAddress (6)), + NetDevice(node, Eui48Address::Allocate ()), m_txMachineState (READY), m_bps (rate), m_tInterframeGap (Seconds(0)), @@ -55,7 +56,7 @@ DataRateDefaultValue PointToPointNetDevice::g_defaultRate( // BUGBUG FIXME // // You _must_ support broadcast to get any sort of packet from the ARP layer. - EnableBroadcast (MacAddress ("ff:ff:ff:ff:ff:ff")); + EnableBroadcast (Eui48Address ("ff:ff:ff:ff:ff:ff")); EnableMulticast(); EnablePointToPoint(); } @@ -66,15 +67,16 @@ PointToPointNetDevice::~PointToPointNetDevice() m_queue = 0; } -void PointToPointNetDevice::AddHeader(Packet& p, const MacAddress& dest, - uint16_t protocolNumber) +void +PointToPointNetDevice::AddHeader(Packet& p, uint16_t protocolNumber) { LlcSnapHeader llc; llc.SetType (protocolNumber); p.AddHeader (llc); } -bool PointToPointNetDevice::ProcessHeader(Packet& p, uint16_t& param) +bool +PointToPointNetDevice::ProcessHeader(Packet& p, uint16_t& param) { LlcSnapHeader llc; p.RemoveHeader (llc); @@ -100,7 +102,7 @@ void PointToPointNetDevice::SetInterframeGap(const Time& t) m_tInterframeGap = t; } -bool PointToPointNetDevice::SendTo (Packet& p, const MacAddress& dest, +bool PointToPointNetDevice::SendTo (Packet& p, const Address& dest, uint16_t protocolNumber) { NS_DEBUG ("PointToPointNetDevice::SendTo (" << &p << ", " << &dest << ")"); @@ -110,7 +112,7 @@ bool PointToPointNetDevice::SendTo (Packet& p, const MacAddress& dest, // "go down" during the simulation? Shouldn't we just wait for it // to come back up? NS_ASSERT (IsLinkUp ()); - AddHeader(p, dest, protocolNumber); + AddHeader(p, protocolNumber); // // This class simulates a point to point device. In the case of a serial @@ -119,14 +121,14 @@ bool PointToPointNetDevice::SendTo (Packet& p, const MacAddress& dest, // // If there's a transmission in progress, we enque the packet for later // trnsmission; otherwise we send it now. - if (m_txMachineState == READY) - { - return TransmitStart (p); - } - else - { - return m_queue->Enqueue(p); - } + if (m_txMachineState == READY) + { + return TransmitStart (p); + } + else + { + return m_queue->Enqueue(p); + } } bool @@ -218,12 +220,12 @@ void PointToPointNetDevice::AddQueue (Ptr q) void PointToPointNetDevice::Receive (Packet& p) { NS_DEBUG ("PointToPointNetDevice::Receive (" << &p << ")"); - uint16_t param = 0; + uint16_t protocol = 0; Packet packet = p; - ProcessHeader(packet, param); + ProcessHeader(packet, protocol); m_rxTrace (packet); - ForwardUp (packet, param); + ForwardUp (packet, protocol, GetBroadcast ()); } Ptr PointToPointNetDevice::GetQueue(void) const diff --git a/src/devices/point-to-point/point-to-point-net-device.h b/src/devices/point-to-point/point-to-point-net-device.h index 2cdafab28..77a55a8dc 100644 --- a/src/devices/point-to-point/point-to-point-net-device.h +++ b/src/devices/point-to-point/point-to-point-net-device.h @@ -22,7 +22,7 @@ #define POINT_TO_POINT_NET_DEVICE_H #include -#include "ns3/mac-address.h" +#include "ns3/address.h" #include "ns3/node.h" #include "ns3/net-device.h" #include "ns3/callback.h" @@ -191,7 +191,7 @@ private: * Adds the necessary headers and trailers to a packet of data in order to * respect the protocol implemented by the agent. */ - void AddHeader(Packet& p, const MacAddress& dest, uint16_t protocolNumber); + void AddHeader(Packet& p, uint16_t protocolNumber); /** * Removes, from a packet of data, all headers and trailers that * relate to the protocol implemented by the agent @@ -208,11 +208,11 @@ private: * * @see NetDevice * @param p a reference to the packet to send - * @param dest a reference to the MacAddress of the destination device + * @param dest a reference to the Address of the destination device * @param protocolNumber Protocol Number used to find protocol touse * @returns true if success, false on failure */ - virtual bool SendTo (Packet& p, const MacAddress& dest, + virtual bool SendTo (Packet& p, const Address& dest, uint16_t protocolNumber); /** * Start Sending a Packet Down the Wire. diff --git a/src/internet-node/arp-cache.cc b/src/internet-node/arp-cache.cc index 92cb13af4..b4987daef 100644 --- a/src/internet-node/arp-cache.cc +++ b/src/internet-node/arp-cache.cc @@ -148,7 +148,7 @@ ArpCache::Entry::MarkDead (void) UpdateSeen (); } Packet -ArpCache::Entry::MarkAlive (MacAddress macAddress) +ArpCache::Entry::MarkAlive (Address macAddress) { NS_ASSERT (m_state == WAIT_REPLY); //NS_ASSERT (m_waiting != 0); @@ -182,7 +182,7 @@ ArpCache::Entry::MarkWaitReply (Packet waiting) UpdateSeen (); } -MacAddress +Address ArpCache::Entry::GetMacAddress (void) { NS_ASSERT (m_state == ALIVE); diff --git a/src/internet-node/arp-cache.h b/src/internet-node/arp-cache.h index 436d44eba..2cd88c85f 100644 --- a/src/internet-node/arp-cache.h +++ b/src/internet-node/arp-cache.h @@ -26,7 +26,7 @@ #include "ns3/nstime.h" #include "ns3/net-device.h" #include "ns3/ipv4-address.h" -#include "ns3/mac-address.h" +#include "ns3/address.h" #include "ns3/ptr.h" #include "sgi-hashmap.h" @@ -101,7 +101,7 @@ public: * \param macAddress * \return */ - Packet MarkAlive (MacAddress macAddress); + Packet MarkAlive (Address macAddress); /** * \param waiting */ @@ -127,7 +127,7 @@ public: /** * \return The MacAddress of this entry */ - MacAddress GetMacAddress (void); + Address GetMacAddress (void); /** * \return True if this entry has timedout; false otherwise. */ @@ -143,7 +143,7 @@ public: ArpCache *m_arp; ArpCacheEntryState_e m_state; Time m_lastSeen; - MacAddress m_macAddress; + Address m_macAddress; Packet m_waiting; }; diff --git a/src/internet-node/arp-header.cc b/src/internet-node/arp-header.cc index 261385fd2..dccf80f58 100644 --- a/src/internet-node/arp-header.cc +++ b/src/internet-node/arp-header.cc @@ -38,9 +38,9 @@ ArpHeader::~ArpHeader () {} void -ArpHeader::SetRequest (MacAddress sourceHardwareAddress, +ArpHeader::SetRequest (Address sourceHardwareAddress, Ipv4Address sourceProtocolAddress, - MacAddress destinationHardwareAddress, + Address destinationHardwareAddress, Ipv4Address destinationProtocolAddress) { m_type = ARP_TYPE_REQUEST; @@ -50,9 +50,9 @@ ArpHeader::SetRequest (MacAddress sourceHardwareAddress, m_ipv4Dest = destinationProtocolAddress; } void -ArpHeader::SetReply (MacAddress sourceHardwareAddress, +ArpHeader::SetReply (Address sourceHardwareAddress, Ipv4Address sourceProtocolAddress, - MacAddress destinationHardwareAddress, + Address destinationHardwareAddress, Ipv4Address destinationProtocolAddress) { m_type = ARP_TYPE_REPLY; @@ -71,12 +71,12 @@ ArpHeader::IsReply (void) const { return (m_type == ARP_TYPE_REPLY)?true:false; } -MacAddress +Address ArpHeader::GetSourceHardwareAddress (void) { return m_macSource; } -MacAddress +Address ArpHeader::GetDestinationHardwareAddress (void) { return m_macDest; diff --git a/src/internet-node/arp-header.h b/src/internet-node/arp-header.h index a4e61f49d..79695a329 100644 --- a/src/internet-node/arp-header.h +++ b/src/internet-node/arp-header.h @@ -23,7 +23,7 @@ #define ARP_HEADER_H #include "ns3/header.h" -#include "ns3/mac-address.h" +#include "ns3/address.h" #include "ns3/ipv4-address.h" #include @@ -38,18 +38,18 @@ public: virtual ~ArpHeader (); - void SetRequest (MacAddress sourceHardwareAddress, + void SetRequest (Address sourceHardwareAddress, Ipv4Address sourceProtocolAddress, - MacAddress destinationHardwareAddress, + Address destinationHardwareAddress, Ipv4Address destinationProtocolAddress); - void SetReply (MacAddress sourceHardwareAddress, + void SetReply (Address sourceHardwareAddress, Ipv4Address sourceProtocolAddress, - MacAddress destinationHardwareAddress, + Address destinationHardwareAddress, Ipv4Address destinationProtocolAddress); bool IsRequest (void) const; bool IsReply (void) const; - MacAddress GetSourceHardwareAddress (void); - MacAddress GetDestinationHardwareAddress (void); + Address GetSourceHardwareAddress (void); + Address GetDestinationHardwareAddress (void); Ipv4Address GetSourceIpv4Address (void); Ipv4Address GetDestinationIpv4Address (void); @@ -78,8 +78,8 @@ private: ARP_TYPE_REPLY = 2 }; uint16_t m_type; - MacAddress m_macSource; - MacAddress m_macDest; + Address m_macSource; + Address m_macDest; Ipv4Address m_ipv4Source; Ipv4Address m_ipv4Dest; }; diff --git a/src/internet-node/arp-ipv4-interface.cc b/src/internet-node/arp-ipv4-interface.cc index 4ca7ebbb3..313bb5851 100644 --- a/src/internet-node/arp-ipv4-interface.cc +++ b/src/internet-node/arp-ipv4-interface.cc @@ -25,10 +25,11 @@ #include "ns3/composite-trace-resolver.h" #include "ns3/node.h" #include "ns3/net-device.h" +#include "ns3/address.h" #include "arp-ipv4-interface.h" -#include "arp-private.h" #include "ipv4-l3-protocol.h" +#include "arp-l3-protocol.h" namespace ns3 { @@ -59,18 +60,17 @@ ArpIpv4Interface::SendTo (Packet p, Ipv4Address dest) NS_ASSERT (GetDevice () != 0); if (GetDevice ()->NeedsArp ()) { - Ptr arp = m_node->QueryInterface (ArpPrivate::iid); - MacAddress hardwareDestination; + Ptr arp = m_node->QueryInterface (ArpL3Protocol::iid); + Address hardwareDestination; bool found; if (dest.IsBroadcast ()) { - hardwareDestination = GetDevice ()->GetBroadcast (); - found = true; + hardwareDestination = GetDevice ()->GetBroadcast (); + found = true; } else { - Ptr arp = m_node->QueryInterface (ArpPrivate::iid); found = arp->Lookup (p, dest, GetDevice (), &hardwareDestination); } diff --git a/src/internet-node/arp-l3-protocol.cc b/src/internet-node/arp-l3-protocol.cc index b68995be3..100f1df88 100644 --- a/src/internet-node/arp-l3-protocol.cc +++ b/src/internet-node/arp-l3-protocol.cc @@ -24,22 +24,24 @@ #include "ns3/node.h" #include "ns3/net-device.h" +#include "ipv4-l3-protocol.h" #include "arp-l3-protocol.h" #include "arp-header.h" #include "arp-cache.h" #include "ipv4-interface.h" -#include "ipv4-private.h" NS_DEBUG_COMPONENT_DEFINE ("ArpL3Protocol"); namespace ns3 { +const InterfaceId ArpL3Protocol::iid = MakeInterfaceId ("ArpL3Protocol", Object::iid); const uint16_t ArpL3Protocol::PROT_NUMBER = 0x0806; ArpL3Protocol::ArpL3Protocol (Ptr node) - : L3Protocol (PROT_NUMBER, 0/* XXX: correct version number ? */ ), - m_node (node) -{} + : m_node (node) +{ + SetInterfaceId (ArpL3Protocol::iid); +} ArpL3Protocol::~ArpL3Protocol () {} @@ -53,7 +55,7 @@ ArpL3Protocol::DoDispose (void) } m_cacheList.clear (); m_node = 0; - L3Protocol::DoDispose (); + Object::DoDispose (); } TraceResolver * @@ -72,7 +74,7 @@ ArpL3Protocol::FindCache (Ptr device) return *i; } } - Ptr ipv4 = m_node->QueryInterface (Ipv4Private::iid); + Ptr ipv4 = m_node->QueryInterface (Ipv4L3Protocol::iid); Ipv4Interface *interface = ipv4->FindInterfaceForDevice (device); ArpCache * cache = new ArpCache (device, interface); NS_ASSERT (device->IsBroadcast ()); @@ -82,10 +84,11 @@ ArpL3Protocol::FindCache (Ptr device) } void -ArpL3Protocol::Receive(Packet& packet, Ptr device) +ArpL3Protocol::Receive(Ptr device, const Packet& p, uint16_t protocol, const Address &from) { ArpCache *cache = FindCache (device); ArpHeader arp; + Packet packet = p; packet.RemoveHeader (arp); NS_DEBUG ("ARP: received "<< (arp.IsRequest ()? "request" : "reply") << @@ -104,7 +107,7 @@ ArpL3Protocol::Receive(Packet& packet, Ptr device) } else if (arp.IsReply () && arp.GetDestinationIpv4Address ().IsEqual (cache->GetInterface ()->GetAddress ()) && - arp.GetDestinationHardwareAddress ().IsEqual (device->GetAddress ())) + arp.GetDestinationHardwareAddress () == device->GetAddress ()) { Ipv4Address from = arp.GetSourceIpv4Address (); ArpCache::Entry *entry = cache->Lookup (from); @@ -115,7 +118,7 @@ ArpL3Protocol::Receive(Packet& packet, Ptr device) NS_DEBUG ("node="<GetId ()<<", got reply from " << arp.GetSourceIpv4Address () << " for waiting entry -- flush"); - MacAddress from_mac = arp.GetSourceHardwareAddress (); + Address from_mac = arp.GetSourceHardwareAddress (); Packet waiting = entry->MarkAlive (from_mac); cache->GetInterface ()->Send (waiting, arp.GetSourceIpv4Address ()); } @@ -144,8 +147,8 @@ ArpL3Protocol::Receive(Packet& packet, Ptr device) } bool ArpL3Protocol::Lookup (Packet &packet, Ipv4Address destination, - Ptr device, - MacAddress *hardwareDestination) + Ptr device, + Address *hardwareDestination) { ArpCache *cache = FindCache (device); ArpCache::Entry *entry = cache->Lookup (destination); @@ -231,7 +234,7 @@ ArpL3Protocol::SendArpRequest (ArpCache const *cache, Ipv4Address to) } void -ArpL3Protocol::SendArpReply (ArpCache const *cache, Ipv4Address toIp, MacAddress toMac) +ArpL3Protocol::SendArpReply (ArpCache const *cache, Ipv4Address toIp, Address toMac) { ArpHeader arp; NS_DEBUG ("ARP: sending reply from node "<GetId ()<< diff --git a/src/internet-node/arp-l3-protocol.h b/src/internet-node/arp-l3-protocol.h index d27d2dba2..a2ea8227e 100644 --- a/src/internet-node/arp-l3-protocol.h +++ b/src/internet-node/arp-l3-protocol.h @@ -23,9 +23,8 @@ #include #include "ns3/ipv4-address.h" -#include "ns3/mac-address.h" +#include "ns3/address.h" #include "ns3/ptr.h" -#include "l3-protocol.h" namespace ns3 { @@ -38,22 +37,23 @@ class TraceContext; /** * \brief An implementation of the ARP protocol */ -class ArpL3Protocol : public L3Protocol +class ArpL3Protocol : public Object { public: + static const InterfaceId iid; static const uint16_t PROT_NUMBER; /** * \brief Constructor * \param node The node which this ARP object is associated with */ ArpL3Protocol (Ptr node); - ~ArpL3Protocol (); + virtual ~ArpL3Protocol (); virtual TraceResolver *CreateTraceResolver (TraceContext const &context); /** * \brief Recieve a packet */ - virtual void Receive(Packet& p, Ptr device); + void Receive(Ptr device, const Packet& p, uint16_t protocol, const Address &from); /** * \brief Perform an ARP lookup * \param p @@ -64,14 +64,14 @@ public: */ bool Lookup (Packet &p, Ipv4Address destination, Ptr device, - MacAddress *hardwareDestination); + Address *hardwareDestination); protected: virtual void DoDispose (void); private: typedef std::list CacheList; ArpCache *FindCache (Ptr device); void SendArpRequest (ArpCache const *cache, Ipv4Address to); - void SendArpReply (ArpCache const *cache, Ipv4Address toIp, MacAddress toMac); + void SendArpReply (ArpCache const *cache, Ipv4Address toIp, Address toMac); CacheList m_cacheList; Ptr m_node; }; diff --git a/src/internet-node/ascii-trace.cc b/src/internet-node/ascii-trace.cc index 1314f2150..b4e1430cb 100644 --- a/src/internet-node/ascii-trace.cc +++ b/src/internet-node/ascii-trace.cc @@ -26,12 +26,6 @@ #include "ns3/node.h" #include "ns3/queue.h" #include "ns3/node-list.h" -#include "ns3/llc-snap-header.h" - -#include "ipv4-l3-protocol.h" -#include "arp-header.h" -#include "udp-header.h" -#include "ipv4-header.h" namespace ns3 { @@ -47,51 +41,17 @@ void AsciiTrace::TraceAllQueues (void) { Packet::EnableMetadata (); - TraceRoot::Connect ("/nodes/*/ipv4/interfaces/*/netdevice/queue/*", + TraceRoot::Connect ("/nodes/*/devices/*/queue/*", MakeCallback (&AsciiTrace::LogDevQueue, this)); } void AsciiTrace::TraceAllNetDeviceRx (void) { Packet::EnableMetadata (); - TraceRoot::Connect ("/nodes/*/ipv4/interfaces/*/netdevice/rx", + TraceRoot::Connect ("/nodes/*/devices/*/rx", MakeCallback (&AsciiTrace::LogDevRx, this)); } -void -AsciiTrace::PrintType (Packet const &packet) -{ - Packet p = packet; - LlcSnapHeader llc; - p.RemoveHeader (llc); - switch (llc.GetType ()) - { - case 0x0800: { - Ipv4Header ipv4; - p.RemoveHeader (ipv4); - if (ipv4.GetProtocol () == 17) - { - UdpHeader udp; - p.RemoveHeader (udp); - m_os << "udp size=" << p.GetSize (); - } - } break; - case 0x0806: { - ArpHeader arp; - p.RemoveHeader (arp); - m_os << "arp "; - if (arp.IsRequest ()) - { - m_os << "request"; - } - else - { - m_os << "reply "; - } - } break; - } -} - void AsciiTrace::LogDevQueue (TraceContext const &context, Packet const &packet) { @@ -113,9 +73,9 @@ AsciiTrace::LogDevQueue (TraceContext const &context, Packet const &packet) NodeList::NodeIndex nodeIndex; context.Get (nodeIndex); m_os << "node=" << NodeList::GetNode (nodeIndex)->GetId () << " "; - Ipv4L3Protocol::InterfaceIndex interfaceIndex; - context.Get (interfaceIndex); - m_os << "interface=" << interfaceIndex << " "; + Node::NetDeviceIndex deviceIndex; + context.Get (deviceIndex); + m_os << "device=" << deviceIndex << " "; m_os << "pkt-uid=" << packet.GetUid () << " "; packet.Print (m_os); m_os << std::endl; @@ -127,9 +87,9 @@ AsciiTrace::LogDevRx (TraceContext const &context, Packet &p) NodeList::NodeIndex nodeIndex; context.Get (nodeIndex); m_os << "node=" << NodeList::GetNode (nodeIndex)->GetId () << " "; - Ipv4L3Protocol::InterfaceIndex interfaceIndex; - context.Get (interfaceIndex); - m_os << "interface=" << interfaceIndex << " "; + Node::NetDeviceIndex deviceIndex; + context.Get (deviceIndex); + m_os << "device=" << deviceIndex << " "; m_os << "pkt-uid=" << p.GetUid () << " "; p.Print (m_os); m_os << std::endl; diff --git a/src/internet-node/ascii-trace.h b/src/internet-node/ascii-trace.h index 5d7554665..56b4195cb 100644 --- a/src/internet-node/ascii-trace.h +++ b/src/internet-node/ascii-trace.h @@ -37,7 +37,6 @@ public: void TraceAllQueues (void); void TraceAllNetDeviceRx (void); private: - void PrintType (Packet const &p); void LogDevQueue (TraceContext const &context, const Packet &p); void LogDevRx (TraceContext const &context, Packet &p); std::ofstream m_os; diff --git a/src/internet-node/internet-node.cc b/src/internet-node/internet-node.cc index 26acb8ce2..580baec0f 100644 --- a/src/internet-node/internet-node.cc +++ b/src/internet-node/internet-node.cc @@ -23,17 +23,15 @@ #include "ns3/composite-trace-resolver.h" #include "ns3/net-device.h" +#include "ns3/callback.h" -#include "l3-demux.h" #include "ipv4-l4-demux.h" #include "internet-node.h" #include "udp-l4-protocol.h" #include "ipv4-l3-protocol.h" #include "arp-l3-protocol.h" #include "udp-impl.h" -#include "arp-private.h" #include "ipv4-impl.h" -#include "ipv4-private.h" namespace ns3 { @@ -55,38 +53,35 @@ InternetNode::Construct (void) { Ptr ipv4 = Create (this); Ptr arp = Create (this); - Ptr udp = Create (this); + // XXX remove the PeekPointer below. + RegisterProtocolHandler (MakeCallback (&Ipv4L3Protocol::Receive, PeekPointer (ipv4)), + Ipv4L3Protocol::PROT_NUMBER, 0); + RegisterProtocolHandler (MakeCallback (&ArpL3Protocol::Receive, PeekPointer (arp)), + ArpL3Protocol::PROT_NUMBER, 0); + - Ptr l3Demux = Create (this); Ptr ipv4L4Demux = Create (this); - - l3Demux->Insert (ipv4); - l3Demux->Insert (arp); + Ptr udp = Create (this); ipv4L4Demux->Insert (udp); Ptr udpImpl = Create (udp); - Ptr arpPrivate = Create (arp); Ptr ipv4Impl = Create (ipv4); - Ptr ipv4Private = Create (ipv4); - Object::AddInterface (ipv4Private); + Object::AddInterface (ipv4); + Object::AddInterface (arp); Object::AddInterface (ipv4Impl); - Object::AddInterface (arpPrivate); Object::AddInterface (udpImpl); - Object::AddInterface (l3Demux); Object::AddInterface (ipv4L4Demux); } -TraceResolver * -InternetNode::DoCreateTraceResolver (TraceContext const &context) +void +InternetNode::DoFillTraceResolver (CompositeTraceResolver &resolver) { - CompositeTraceResolver *resolver = new CompositeTraceResolver (context); - Ptr ipv4 = QueryInterface (Ipv4Private::iid); - resolver->Add ("ipv4", - MakeCallback (&Ipv4Private::CreateTraceResolver, PeekPointer (ipv4)), - InternetNode::IPV4); - - return resolver; + Node::DoFillTraceResolver (resolver); + Ptr ipv4 = QueryInterface (Ipv4L3Protocol::iid); + resolver.Add ("ipv4", + MakeCallback (&Ipv4L3Protocol::CreateTraceResolver, PeekPointer (ipv4)), + InternetNode::IPV4); } void @@ -95,25 +90,4 @@ InternetNode::DoDispose() Node::DoDispose (); } -void -InternetNode::DoAddDevice (Ptr device) -{ - device->SetReceiveCallback (MakeCallback (&InternetNode::ReceiveFromDevice, this)); -} - -bool -InternetNode::ReceiveFromDevice (Ptr device, const Packet &p, uint16_t protocolNumber) const -{ - Ptr demux = QueryInterface (L3Demux::iid); - Ptr target = demux->GetProtocol (protocolNumber); - if (target != 0) - { - Packet packet = p; - target->Receive(packet, device); - return true; - } - return false; -} - - }//namespace ns3 diff --git a/src/internet-node/internet-node.h b/src/internet-node/internet-node.h index b577f6b6b..6047a1717 100644 --- a/src/internet-node/internet-node.h +++ b/src/internet-node/internet-node.h @@ -46,8 +46,7 @@ public: protected: virtual void DoDispose(void); private: - virtual void DoAddDevice (Ptr device); - virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context); + virtual void DoFillTraceResolver (CompositeTraceResolver &resolver); bool ReceiveFromDevice (Ptr device, const Packet &p, uint16_t protocolNumber) const; void Construct (void); }; diff --git a/src/internet-node/ipv4-l3-protocol.cc b/src/internet-node/ipv4-l3-protocol.cc index 077acb3f7..a012d814c 100644 --- a/src/internet-node/ipv4-l3-protocol.cc +++ b/src/internet-node/ipv4-l3-protocol.cc @@ -41,15 +41,16 @@ NS_DEBUG_COMPONENT_DEFINE ("Ipv4L3Protocol"); namespace ns3 { +const InterfaceId Ipv4L3Protocol::iid = MakeInterfaceId ("Ipv4L3Protocol", Object::iid); const uint16_t Ipv4L3Protocol::PROT_NUMBER = 0x0800; Ipv4L3Protocol::Ipv4L3Protocol(Ptr node) - : L3Protocol (PROT_NUMBER, 4), - m_nInterfaces (0), + : m_nInterfaces (0), m_defaultTtl (64), m_identification (0), m_node (node) { + SetInterfaceId (Ipv4L3Protocol::iid); m_staticRouting = Create (); AddRoutingProtocol (m_staticRouting, 0); SetupLoopback (); @@ -66,9 +67,9 @@ Ipv4L3Protocol::DoDispose (void) } m_interfaces.clear (); m_node = 0; - L3Protocol::DoDispose (); m_staticRouting->Dispose (); m_staticRouting = 0; + Object::DoDispose (); } void @@ -98,8 +99,8 @@ Ipv4L3Protocol::CreateTraceResolver (TraceContext const &context) TraceResolver * Ipv4L3Protocol::InterfacesCreateTraceResolver (TraceContext const &context) const { - ArrayTraceResolver *resolver = - new ArrayTraceResolver + ArrayTraceResolver *resolver = + new ArrayTraceResolver (context, MakeCallback (&Ipv4L3Protocol::GetNInterfaces, this), MakeCallback (&Ipv4L3Protocol::GetInterface, this)); @@ -240,18 +241,19 @@ Ipv4L3Protocol::FindInterfaceForDevice (Ptr device) } void -Ipv4L3Protocol::Receive(Packet& packet, Ptr device) +Ipv4L3Protocol::Receive( Ptr device, const Packet& p, uint16_t protocol, const Address &from) { uint32_t index = 0; for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++) { if ((*i)->GetDevice () == device) { - m_rxTrace (packet, index); + m_rxTrace (p, index); break; } index++; } + Packet packet = p; Ipv4Header ipHeader; packet.RemoveHeader (ipHeader); diff --git a/src/internet-node/ipv4-l3-protocol.h b/src/internet-node/ipv4-l3-protocol.h index b41b6aefa..6130872cd 100644 --- a/src/internet-node/ipv4-l3-protocol.h +++ b/src/internet-node/ipv4-l3-protocol.h @@ -30,7 +30,6 @@ #include "ipv4-header.h" #include "ns3/ptr.h" #include "ns3/ipv4.h" -#include "l3-protocol.h" #include "ipv4-static-routing.h" namespace ns3 { @@ -46,9 +45,10 @@ class TraceResolver; class TraceContext; -class Ipv4L3Protocol : public L3Protocol +class Ipv4L3Protocol : public Object { public: + static const InterfaceId iid; static const uint16_t PROT_NUMBER; enum TraceType { @@ -57,7 +57,7 @@ public: DROP, INTERFACES, }; - typedef ArrayTraceResolver::Index InterfaceIndex; + typedef ArrayTraceResolver::Index InterfaceIndex; Ipv4L3Protocol(Ptr node); virtual ~Ipv4L3Protocol (); @@ -95,7 +95,7 @@ public: * - implement a per-NetDevice ARP cache * - send back arp replies on the right device */ - virtual void Receive(Packet& p, Ptr device); + void Receive( Ptr device, const Packet& p, uint16_t protocol, const Address &from); /** * \param packet packet to send diff --git a/src/internet-node/ipv4-loopback-interface.cc b/src/internet-node/ipv4-loopback-interface.cc index 906c0a001..47ddc9ee2 100644 --- a/src/internet-node/ipv4-loopback-interface.cc +++ b/src/internet-node/ipv4-loopback-interface.cc @@ -23,7 +23,7 @@ #include "ns3/net-device.h" #include "ns3/node.h" #include "ipv4-loopback-interface.h" -#include "ipv4-private.h" +#include "ipv4-l3-protocol.h" namespace ns3 { @@ -43,8 +43,8 @@ Ipv4LoopbackInterface::DoCreateTraceResolver (TraceContext const &context) void Ipv4LoopbackInterface::SendTo (Packet packet, Ipv4Address dest) { - Ptr ipv4 = m_node->QueryInterface (Ipv4Private::iid); - ipv4->Receive (packet, GetDevice ()); + Ptr ipv4 = m_node->QueryInterface (Ipv4L3Protocol::iid); + ipv4->Receive (GetDevice (), packet, Ipv4L3Protocol::PROT_NUMBER, GetDevice ()->GetAddress ()); } }//namespace ns3 diff --git a/src/internet-node/ipv4-private.cc b/src/internet-node/ipv4-private.cc deleted file mode 100644 index 1b9314152..000000000 --- a/src/internet-node/ipv4-private.cc +++ /dev/null @@ -1,67 +0,0 @@ -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2007 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 - */ -#include "ipv4-private.h" -#include "ipv4-l3-protocol.h" -#include "ns3/assert.h" -#include "ns3/net-device.h" - -namespace ns3 { - -const InterfaceId Ipv4Private::iid = MakeInterfaceId ("Ipv4Private", Object::iid); - -Ipv4Private::Ipv4Private (Ptr ipv4) - : m_ipv4 (ipv4) -{ - SetInterfaceId (Ipv4Private::iid); -} -Ipv4Private::~Ipv4Private () -{ - NS_ASSERT (m_ipv4 == 0); -} -TraceResolver * -Ipv4Private::CreateTraceResolver (TraceContext const &context) -{ - return m_ipv4->CreateTraceResolver (context); -} -void -Ipv4Private::Send (Packet const &packet, Ipv4Address source, - Ipv4Address destination, uint8_t protocol) -{ - m_ipv4->Send (packet, source, destination, protocol); -} -Ipv4Interface * -Ipv4Private::FindInterfaceForDevice (Ptrdevice) -{ - return m_ipv4->FindInterfaceForDevice (device); -} -void -Ipv4Private::Receive(Packet& p, Ptr device) -{ - m_ipv4->Receive (p, device); -} -void -Ipv4Private::DoDispose (void) -{ - m_ipv4 = 0; - Object::DoDispose (); -} - -} // namespace ns3 diff --git a/src/internet-node/ipv4-private.h b/src/internet-node/ipv4-private.h deleted file mode 100644 index 3208d0f1a..000000000 --- a/src/internet-node/ipv4-private.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2007 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 - */ -#ifndef IPV4_PRIVATE_H -#define IPV4_PRIVATE_H - -#include "ns3/object.h" -#include "ns3/ipv4-address.h" -#include "ns3/ptr.h" -#include - -namespace ns3 { - -class Packet; -class Ipv4L3Protocol; -class TraceContext; -class TraceResolver; -class Ipv4Interface; -class NetDevice; - -class Ipv4Private : public Object -{ -public: - static const InterfaceId iid; - Ipv4Private (Ptr ipv4); - virtual ~Ipv4Private (); - - TraceResolver *CreateTraceResolver (TraceContext const &context); - void Send (Packet const &packet, Ipv4Address source, - Ipv4Address destination, uint8_t protocol); - Ipv4Interface *FindInterfaceForDevice (Ptrdevice); - void Receive(Packet& p, Ptr device); -protected: - virtual void DoDispose (void); -private: - Ptr m_ipv4; -}; - -} // namespace ns3 - -#endif /* IPV4_PRIVATE_H */ diff --git a/src/internet-node/ipv4-static-routing.h b/src/internet-node/ipv4-static-routing.h index f7e6d52ab..8462f55a7 100644 --- a/src/internet-node/ipv4-static-routing.h +++ b/src/internet-node/ipv4-static-routing.h @@ -31,7 +31,6 @@ #include "ipv4-header.h" #include "ns3/ptr.h" #include "ns3/ipv4.h" -#include "l3-protocol.h" namespace ns3 { diff --git a/src/internet-node/l3-demux.cc b/src/internet-node/l3-demux.cc deleted file mode 100644 index 6e8416a50..000000000 --- a/src/internet-node/l3-demux.cc +++ /dev/null @@ -1,90 +0,0 @@ -// -*- 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 -// -// Implement the L3Protocols capability for ns3. -// George F. Riley, Georgia Tech, Fall 2006 -#include -#include -#include "ns3/composite-trace-resolver.h" -#include "ns3/node.h" -#include "l3-demux.h" -#include "l3-protocol.h" - -namespace ns3 { - -const InterfaceId L3Demux::iid = MakeInterfaceId ("L3Demux", Object::iid); - -L3Demux::L3Demux (Ptr node) - : m_node (node) -{ - SetInterfaceId (L3Demux::iid); -} - -L3Demux::~L3Demux() -{} - -void -L3Demux::DoDispose (void) -{ - for (L3Map_t::iterator i = m_protocols.begin(); i != m_protocols.end(); ++i) - { - i->second->Dispose (); - i->second = 0; - } - m_protocols.clear (); - m_node = 0; - Object::DoDispose (); -} - -TraceResolver * -L3Demux::CreateTraceResolver (TraceContext const &context) const -{ - CompositeTraceResolver *resolver = new CompositeTraceResolver (context); - for (L3Map_t::const_iterator i = m_protocols.begin(); i != m_protocols.end(); ++i) - { - std::string protValue; - std::ostringstream oss (protValue); - oss << i->second->GetProtocolNumber (); - ProtocolTraceType context = i->second->GetProtocolNumber (); - resolver->Add (protValue, - MakeCallback (&L3Protocol::CreateTraceResolver, PeekPointer (i->second)), - context); - } - return resolver; -} - -void L3Demux::Insert(Ptr p) -{ - m_protocols.insert(L3Map_t::value_type(p->GetProtocolNumber (), p)); -} - -Ptr -L3Demux::GetProtocol (int p) -{ // Look up a protocol by protocol number - L3Map_t::iterator i = m_protocols.find(p); - if (i == m_protocols.end()) - { - return 0; - } - return i->second; // Return the protocol -} - -} //namespace ns3 - diff --git a/src/internet-node/l3-demux.h b/src/internet-node/l3-demux.h deleted file mode 100644 index 43a3e1b7d..000000000 --- a/src/internet-node/l3-demux.h +++ /dev/null @@ -1,93 +0,0 @@ -// -*- 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 -// -// Define the L3Protocols capability for ns3. -// George F. Riley, Georgia Tech, Fall 2006 - -// This object manages the different layer 3 protocols for any ns3 -// node that has this capability. - -#ifndef L3_DEMUX_H -#define L3_DEMUX_H - -#include -#include "ns3/object.h" -#include "ns3/ptr.h" - -namespace ns3 { - -class L3Protocol; -class Node; -class TraceResolver; -class TraceContext; - -/** - * \brief L3 Demux - */ -class L3Demux : public Object -{ -public: - static const InterfaceId iid; - typedef int ProtocolTraceType; - L3Demux(Ptr node); - virtual ~L3Demux(); - - /** - * \param context the trace context to use to construct the - * TraceResolver to return - * \returns a TraceResolver which can resolve all traces - * performed in this object. The caller must - * delete the returned object. - */ - TraceResolver *CreateTraceResolver (TraceContext const &context) const; - - - /** - * \param protocol a template for the protocol to add to this L3 Demux. - * - * Invoke Copy on the input template to get a copy of the input - * protocol which can be used on the Node on which this L3 Demux - * is running. The new L3Protocol is registered internally as - * a working L3 Protocol and returned from this method. - * The caller does not get ownership of the returned pointer. - */ - void Insert(Ptr protocol); - /** - * \param protocolNumber number of protocol to lookup - * in this L4 Demux - * \returns a matching L3 Protocol - * - * This method is typically called by lower layers - * to forward packets up the stack to the right protocol. - * It is also called from NodeImpl::GetIpv4 for example. - */ - Ptr GetProtocol (int protocolNumber); -protected: - virtual void DoDispose (void); -private: - typedef std::map > L3Map_t; - - Ptr m_node; - L3Map_t m_protocols; -}; - -} //namespace ns3 -#endif - diff --git a/src/internet-node/l3-protocol.cc b/src/internet-node/l3-protocol.cc deleted file mode 100644 index 71dbc2d46..000000000 --- a/src/internet-node/l3-protocol.cc +++ /dev/null @@ -1,54 +0,0 @@ -// -*- 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 -// - -// NS3 - Layer 3 Protocol base class -// George F. Riley, Georgia Tech, Spring 2007 - -#include "l3-protocol.h" - - -namespace ns3 { - -L3Protocol::L3Protocol(int protocolNumber, int version) - : m_protocolNumber (protocolNumber), - m_version (version) -{} -L3Protocol::~L3Protocol () -{} - -int -L3Protocol::GetProtocolNumber (void) const -{ - return m_protocolNumber; -} -int -L3Protocol::GetVersion() const -{ - return m_version; -} - -void -L3Protocol::DoDispose (void) -{ - Object::DoDispose (); -} - -}//namespace ns3 diff --git a/src/internet-node/l3-protocol.h b/src/internet-node/l3-protocol.h deleted file mode 100644 index e0c2a469a..000000000 --- a/src/internet-node/l3-protocol.h +++ /dev/null @@ -1,73 +0,0 @@ -// -*- 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 -// - -// NS3 - Layer 3 Protocol base class -// George F. Riley, Georgia Tech, Spring 2007 - -#ifndef L3_PROTOCOL_H -#define L3_PROTOCOL_H - -#include "ns3/object.h" -#include "ns3/ptr.h" - -namespace ns3 { - -class Packet; -class NetDevice; -class TraceResolver; -class TraceContext; - -/** - * ::Send is always defined in subclasses. - */ -class L3Protocol : public Object { -public: - L3Protocol(int protocolNumber, int version); - virtual ~L3Protocol (); - /** - * \return The protocol number of this Layer 3 protocol - */ - int GetProtocolNumber (void) const; - /** - * \return The version number of this protocol - */ - int GetVersion() const; - - virtual TraceResolver *CreateTraceResolver (TraceContext const &context) = 0; - /** - * Lower layer calls this method after calling L3Demux::Lookup - * The ARP subclass needs to know from which NetDevice this - * packet is coming to: - * - implement a per-NetDevice ARP cache - * - send back arp replies on the right device - */ - virtual void Receive(Packet& p, Ptr device) = 0; - -protected: - virtual void DoDispose (void); -private: - int m_protocolNumber; - int m_version; -}; - -} // Namespace ns3 - -#endif diff --git a/src/internet-node/udp-l4-protocol.cc b/src/internet-node/udp-l4-protocol.cc index 90fb782b9..f0ef8569b 100644 --- a/src/internet-node/udp-l4-protocol.cc +++ b/src/internet-node/udp-l4-protocol.cc @@ -29,8 +29,6 @@ #include "ipv4-end-point-demux.h" #include "ipv4-end-point.h" #include "ipv4-l3-protocol.h" -#include "ipv4-private.h" -#include "l3-demux.h" #include "udp-socket.h" namespace ns3 { @@ -138,7 +136,7 @@ UdpL4Protocol::Send (Packet packet, packet.AddHeader (udpHeader); - Ptr ipv4 = m_node->QueryInterface (Ipv4Private::iid); + Ptr ipv4 = m_node->QueryInterface (Ipv4L3Protocol::iid); if (ipv4 != 0) { ipv4->Send (packet, saddr, daddr, PROT_NUMBER); diff --git a/src/internet-node/udp-socket.cc b/src/internet-node/udp-socket.cc index 0ab911c9e..0817ae937 100644 --- a/src/internet-node/udp-socket.cc +++ b/src/internet-node/udp-socket.cc @@ -19,6 +19,7 @@ * Author: Mathieu Lacage */ #include "ns3/node.h" +#include "ns3/inet-socket-address.h" #include "udp-socket.h" #include "udp-l4-protocol.h" #include "ipv4-end-point.h" @@ -72,12 +73,12 @@ UdpSocket::Destroy (void) int UdpSocket::FinishBind (void) { - m_endPoint->SetRxCallback (MakeCallback (&UdpSocket::ForwardUp, this)); - m_endPoint->SetDestroyCallback (MakeCallback (&UdpSocket::Destroy, this)); if (m_endPoint == 0) { return -1; } + m_endPoint->SetRxCallback (MakeCallback (&UdpSocket::ForwardUp, this)); + m_endPoint->SetDestroyCallback (MakeCallback (&UdpSocket::Destroy, this)); return 0; } @@ -88,21 +89,32 @@ UdpSocket::Bind (void) return FinishBind (); } int -UdpSocket::Bind (Ipv4Address address) +UdpSocket::Bind (const Address &address) { - m_endPoint = m_udp->Allocate (address); - return FinishBind (); -} -int -UdpSocket::Bind (uint16_t port) -{ - m_endPoint = m_udp->Allocate (port); - return FinishBind (); -} -int -UdpSocket::Bind (Ipv4Address address, uint16_t port) -{ - m_endPoint = m_udp->Allocate (address, port); + if (!InetSocketAddress::IsMatchingType (address)) + { + return ERROR_INVAL; + } + InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); + Ipv4Address ipv4 = transport.GetIpv4 (); + uint16_t port = transport.GetPort (); + if (ipv4 == Ipv4Address::GetAny () && port == 0) + { + m_endPoint = m_udp->Allocate (); + } + else if (ipv4 == Ipv4Address::GetAny () && port != 0) + { + m_endPoint = m_udp->Allocate (port); + } + else if (ipv4 != Ipv4Address::GetAny () && port == 0) + { + m_endPoint = m_udp->Allocate (ipv4); + } + else if (ipv4 != Ipv4Address::GetAny () && port != 0) + { + m_endPoint = m_udp->Allocate (ipv4, port); + } + return FinishBind (); } @@ -124,34 +136,36 @@ UdpSocket::ShutdownRecv (void) return 0; } -void -UdpSocket::DoClose(ns3::Callback > closeCompleted) +int +UdpSocket::DoClose(Callback > closeCompleted) { // XXX: we should set the close state and check it in all API methods. if (!closeCompleted.IsNull ()) { closeCompleted (this); } + return 0; } -void -UdpSocket::DoConnect(const Ipv4Address & address, - uint16_t portNumber, - ns3::Callback > connectionSucceeded, - ns3::Callback > connectionFailed, - ns3::Callback > halfClose) +int +UdpSocket::DoConnect(const Address & address, + Callback > connectionSucceeded, + Callback > connectionFailed, + Callback > halfClose) { - m_defaultAddress = address; - m_defaultPort = portNumber; + InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); + m_defaultAddress = transport.GetIpv4 (); + m_defaultPort = transport.GetPort (); if (!connectionSucceeded.IsNull ()) { connectionSucceeded (this); } m_connected = true; + return 0; } int -UdpSocket::DoAccept(ns3::Callback, const Ipv4Address&, uint16_t> connectionRequest, - ns3::Callback, const Ipv4Address&, uint16_t> newConnectionCreated, - ns3::Callback > closeRequested) +UdpSocket::DoAccept(Callback, const Address&> connectionRequest, + Callback, const Address&> newConnectionCreated, + Callback > closeRequested) { // calling accept on a udp socket is a programming error. m_errno = ERROR_OPNOTSUPP; @@ -160,7 +174,7 @@ UdpSocket::DoAccept(ns3::Callback, const Ipv4Address&, uint16_ int UdpSocket::DoSend (const uint8_t* buffer, uint32_t size, - ns3::Callback, uint32_t> dataSent) + Callback, uint32_t> dataSent) { if (!m_connected) { @@ -179,8 +193,17 @@ UdpSocket::DoSend (const uint8_t* buffer, return DoSendPacketTo (p, m_defaultAddress, m_defaultPort, dataSent); } int -UdpSocket::DoSendPacketTo (const Packet &p, Ipv4Address daddr, uint16_t dport, - ns3::Callback, uint32_t> dataSent) +UdpSocket::DoSendPacketTo (const Packet &p, const Address &address, + Callback, uint32_t> dataSent) +{ + InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); + Ipv4Address ipv4 = transport.GetIpv4 (); + uint16_t port = transport.GetPort (); + return DoSendPacketTo (p, ipv4, port, dataSent); +} +int +UdpSocket::DoSendPacketTo (const Packet &p, Ipv4Address ipv4, uint16_t port, + Callback, uint32_t> dataSent) { if (m_endPoint == 0) { @@ -196,8 +219,8 @@ UdpSocket::DoSendPacketTo (const Packet &p, Ipv4Address daddr, uint16_t dport, m_errno = ERROR_SHUTDOWN; return -1; } - m_udp->Send (p, m_endPoint->GetLocalAddress (), daddr, - m_endPoint->GetLocalPort (), dport); + m_udp->Send (p, m_endPoint->GetLocalAddress (), ipv4, + m_endPoint->GetLocalPort (), port); if (!dataSent.IsNull ()) { dataSent (this, p.GetSize ()); @@ -205,11 +228,10 @@ UdpSocket::DoSendPacketTo (const Packet &p, Ipv4Address daddr, uint16_t dport, return 0; } int -UdpSocket::DoSendTo(const Ipv4Address &address, - uint16_t port, +UdpSocket::DoSendTo(const Address &address, const uint8_t *buffer, uint32_t size, - ns3::Callback, uint32_t> dataSent) + Callback, uint32_t> dataSent) { if (m_connected) { @@ -225,34 +247,39 @@ UdpSocket::DoSendTo(const Ipv4Address &address, { p = Packet (buffer, size); } - return DoSendPacketTo (p, address, port, dataSent); + InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); + Ipv4Address ipv4 = transport.GetIpv4 (); + uint16_t port = transport.GetPort (); + return DoSendPacketTo (p, ipv4, port, dataSent); } void -UdpSocket::DoRecv(ns3::Callback, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> callback) +UdpSocket::DoRecv(Callback, const uint8_t*, uint32_t,const Address&> callback) { m_rxCallback = callback; } void -UdpSocket::DoRecvDummy(ns3::Callback, uint32_t,const Ipv4Address&, uint16_t> callback) +UdpSocket::DoRecvDummy(Callback, uint32_t,const Address&> callback) { m_dummyRxCallback = callback; } void -UdpSocket::ForwardUp (const Packet &packet, Ipv4Address saddr, uint16_t sport) +UdpSocket::ForwardUp (const Packet &packet, Ipv4Address ipv4, uint16_t port) { if (m_shutdownRecv) { return; } + + Address address = InetSocketAddress (ipv4, port); Packet p = packet; if (!m_dummyRxCallback.IsNull ()) { - m_dummyRxCallback (this, p.GetSize (), saddr, sport); + m_dummyRxCallback (this, p.GetSize (), address); } if (!m_rxCallback.IsNull ()) { - m_rxCallback (this, p.PeekData (), p.GetSize (), saddr, sport); + m_rxCallback (this, p.PeekData (), p.GetSize (), address); } } diff --git a/src/internet-node/udp-socket.h b/src/internet-node/udp-socket.h index c2923c80f..8778aff84 100644 --- a/src/internet-node/udp-socket.h +++ b/src/internet-node/udp-socket.h @@ -25,6 +25,7 @@ #include "ns3/callback.h" #include "ns3/socket.h" #include "ns3/ptr.h" +#include "ns3/ipv4-address.h" namespace ns3 { @@ -45,49 +46,47 @@ public: virtual enum SocketErrno GetErrno (void) const; virtual Ptr GetNode (void) const; virtual int Bind (void); - virtual int Bind (Ipv4Address address); - virtual int Bind (uint16_t port); - virtual int Bind (Ipv4Address address, uint16_t port); + virtual int Bind (const Address &address); virtual int ShutdownSend (void); virtual int ShutdownRecv (void); private: - virtual void DoClose(ns3::Callback > closeCompleted); - virtual void DoConnect(const Ipv4Address & address, - uint16_t portNumber, - ns3::Callback > connectionSucceeded, - ns3::Callback > connectionFailed, - ns3::Callback > halfClose); - virtual int DoAccept(ns3::Callback, const Ipv4Address&, uint16_t> connectionRequest, - ns3::Callback, const Ipv4Address&, uint16_t> newConnectionCreated, - ns3::Callback > closeRequested); + virtual int DoClose(Callback > closeCompleted); + virtual int DoConnect(const Address & address, + Callback > connectionSucceeded, + Callback > connectionFailed, + Callback > halfClose); + virtual int DoAccept(Callback, const Address&> connectionRequest, + Callback, const Address&> newConnectionCreated, + Callback > closeRequested); virtual int DoSend (const uint8_t* buffer, uint32_t size, - ns3::Callback, uint32_t> dataSent); - virtual int DoSendTo(const Ipv4Address &address, - uint16_t port, + Callback, uint32_t> dataSent); + virtual int DoSendTo(const Address &address, const uint8_t *buffer, uint32_t size, - ns3::Callback, uint32_t> dataSent); - virtual void DoRecv(ns3::Callback, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t>); - virtual void DoRecvDummy(ns3::Callback, uint32_t,const Ipv4Address&, uint16_t>); + Callback, uint32_t> dataSent); + virtual void DoRecv(Callback, const uint8_t*, uint32_t,const Address&>); + virtual void DoRecvDummy(Callback, uint32_t,const Address&>); private: friend class Udp; // invoked by Udp class int FinishBind (void); - void ForwardUp (const Packet &p, Ipv4Address saddr, uint16_t sport); + void ForwardUp (const Packet &p, Ipv4Address ipv4, uint16_t port); void Destroy (void); + int DoSendPacketTo (const Packet &p, const Address &daddr, + Callback, uint32_t> dataSent); int DoSendPacketTo (const Packet &p, Ipv4Address daddr, uint16_t dport, - ns3::Callback, uint32_t> dataSent); + Callback, uint32_t> dataSent); Ipv4EndPoint *m_endPoint; Ptr m_node; Ptr m_udp; Ipv4Address m_defaultAddress; uint16_t m_defaultPort; - Callback,uint32_t,const Ipv4Address &,uint16_t> m_dummyRxCallback; - Callback,uint8_t const*,uint32_t,const Ipv4Address &,uint16_t> m_rxCallback; + Callback,uint32_t,const Address &> m_dummyRxCallback; + Callback,uint8_t const*,uint32_t,const Address &> m_rxCallback; enum SocketErrno m_errno; bool m_shutdownSend; bool m_shutdownRecv; diff --git a/src/internet-node/wscript b/src/internet-node/wscript index 7a1b1c10e..e0af13434 100644 --- a/src/internet-node/wscript +++ b/src/internet-node/wscript @@ -8,8 +8,6 @@ def build(bld): obj.uselib_local = ['ns3-node', 'ns3-applications'] obj.source = [ 'internet-node.cc', - 'l3-demux.cc', - 'l3-protocol.cc', 'ipv4-l4-demux.cc', 'ipv4-l4-protocol.cc', 'ipv4-header.cc', @@ -27,9 +25,7 @@ def build(bld): 'ipv4-loopback-interface.cc', 'udp-socket.cc', 'ipv4-end-point-demux.cc', - 'arp-private.cc', 'ipv4-impl.cc', - 'ipv4-private.cc', 'ascii-trace.cc', 'pcap-trace.cc', 'udp-impl.cc', diff --git a/src/node/address-utils.cc b/src/node/address-utils.cc index 702db4dd5..08c5b1736 100644 --- a/src/node/address-utils.cc +++ b/src/node/address-utils.cc @@ -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 diff --git a/src/node/address-utils.h b/src/node/address-utils.h index 9dbe8fc55..1403c544a 100644 --- a/src/node/address-utils.h +++ b/src/node/address-utils.h @@ -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); }; diff --git a/src/node/address.cc b/src/node/address.cc new file mode 100644 index 000000000..33104083d --- /dev/null +++ b/src/node/address.cc @@ -0,0 +1,164 @@ +#include "ns3/assert.h" +#include "address.h" +#include +#include + +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 diff --git a/src/node/address.h b/src/node/address.h new file mode 100644 index 000000000..aedc940d4 --- /dev/null +++ b/src/node/address.h @@ -0,0 +1,172 @@ +#ifndef ADDRESS_H +#define ADDRESS_H + +#include +#include + +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 */ diff --git a/src/node/ethernet-header.cc b/src/node/ethernet-header.cc index 781c5723a..458696a9d 100644 --- a/src/node/ethernet-header.cc +++ b/src/node/ethernet-header.cc @@ -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 diff --git a/src/node/ethernet-header.h b/src/node/ethernet-header.h index cea37705c..a755bae79 100644 --- a/src/node/ethernet-header.h +++ b/src/node/ethernet-header.h @@ -23,8 +23,8 @@ #define ETHERNET_HEADER_H #include "ns3/header.h" -#include "ns3/mac-address.h" #include +#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 diff --git a/src/node/eui48-address.cc b/src/node/eui48-address.cc new file mode 100644 index 000000000..d8b62257b --- /dev/null +++ b/src/node/eui48-address.cc @@ -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 + */ +#include "eui48-address.h" +#include "address.h" +#include "ns3/assert.h" +#include +#include + +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 diff --git a/src/node/eui48-address.h b/src/node/eui48-address.h new file mode 100644 index 000000000..bd778a444 --- /dev/null +++ b/src/node/eui48-address.h @@ -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 + */ +#ifndef EUI48_ADDRESS_H +#define EUI48_ADDRESS_H + +#include +#include + +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 */ diff --git a/src/node/eui64-address.cc b/src/node/eui64-address.cc new file mode 100644 index 000000000..3b91353fe --- /dev/null +++ b/src/node/eui64-address.cc @@ -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 + */ +#include "eui64-address.h" +#include "address.h" +#include "ns3/assert.h" +#include +#include + +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 diff --git a/src/node/eui64-address.h b/src/node/eui64-address.h new file mode 100644 index 000000000..98b930057 --- /dev/null +++ b/src/node/eui64-address.h @@ -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 + */ +#ifndef EUI64_ADDRESS_H +#define EUI64_ADDRESS_H + +#include +#include + +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 */ diff --git a/src/node/inet-socket-address.cc b/src/node/inet-socket-address.cc new file mode 100644 index 000000000..3b2ad5ba8 --- /dev/null +++ b/src/node/inet-socket-address.cc @@ -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 diff --git a/src/node/inet-socket-address.h b/src/node/inet-socket-address.h new file mode 100644 index 000000000..0a00172ba --- /dev/null +++ b/src/node/inet-socket-address.h @@ -0,0 +1,96 @@ +#ifndef IPV4_TRANSPORT_ADDRESS_H +#define IPV4_TRANSPORT_ADDRESS_H + +#include "address.h" +#include "ipv4-address.h" +#include + +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 */ diff --git a/src/node/ipv4-address.cc b/src/node/ipv4-address.cc index 374a124ee..34b15372d 100644 --- a/src/node/ipv4-address.cc +++ b/src/node/ipv4-address.cc @@ -19,11 +19,11 @@ * Author: Mathieu Lacage */ #include "ns3/debug.h" +#include "ipv4-address.h" +#include "ns3/assert.h" NS_DEBUG_COMPONENT_DEFINE("Ipv4Address"); -#include "ipv4-address.h" - namespace ns3 { @@ -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) diff --git a/src/node/ipv4-address.h b/src/node/ipv4-address.h index e33025fac..8bf91f5c9 100644 --- a/src/node/ipv4-address.h +++ b/src/node/ipv4-address.h @@ -24,6 +24,7 @@ #include #include +#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; }; diff --git a/src/node/mac-address.cc b/src/node/mac-address.cc deleted file mode 100644 index 9dcf9bdd6..000000000 --- a/src/node/mac-address.cc +++ /dev/null @@ -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 - */ - -#include -#include -#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 diff --git a/src/node/mac-address.h b/src/node/mac-address.h deleted file mode 100644 index 76c5a6ae0..000000000 --- a/src/node/mac-address.h +++ /dev/null @@ -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 - */ - -#ifndef MAC_ADDRESS_H -#define MAC_ADDRESS_H - -#include -#include - -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 */ diff --git a/src/node/net-device.cc b/src/node/net-device.cc index 7bc61dc9b..4fa2e8d51 100644 --- a/src/node/net-device.cc +++ b/src/node/net-device.cc @@ -35,7 +35,7 @@ namespace ns3 { const InterfaceId NetDevice::iid = MakeInterfaceId ("NetDevice", Object::iid); -NetDevice::NetDevice(Ptr node, const MacAddress& addr) : +NetDevice::NetDevice(Ptr node, const Address& addr) : m_node (node), m_name(""), m_ifIndex (0), @@ -53,7 +53,7 @@ NetDevice::NetDevice(Ptr 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,const Packet &,uint16_t> cb) +NetDevice::SetReceiveCallback (ReceiveCallback cb) { m_receiveCallback = cb; } diff --git a/src/node/net-device.h b/src/node/net-device.h index b5de34fc8..dd590f39c 100644 --- a/src/node/net-device.h +++ b/src/node/net-device.h @@ -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 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,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,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, const MacAddress& addr); + NetDevice(Ptr 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,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 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 m_linkChangeCallback; + ReceiveCallback m_receiveCallback; }; }; // namespace ns3 diff --git a/src/node/node-list.cc b/src/node/node-list.cc index be5ff7122..db8882abd 100644 --- a/src/node/node-list.cc +++ b/src/node/node-list.cc @@ -77,7 +77,6 @@ public: NodeList::Iterator Begin (void); NodeList::Iterator End (void); TraceResolver *CreateTraceResolver (TraceContext const &context); - Node *PeekNode (uint32_t n); Ptr 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 NodeListPriv::GetNode (uint32_t n) @@ -139,11 +133,11 @@ NodeListPriv::GetNode (uint32_t n) TraceResolver * NodeListPriv::CreateTraceResolver (TraceContext const &context) { - ArrayTraceResolver *resolver = - new ArrayTraceResolver + ArrayTraceResolver, NodeListIndex> *resolver = + new ArrayTraceResolver, NodeListIndex> (context, MakeCallback (&NodeListPriv::GetNNodes, this), - MakeCallback (&NodeListPriv::PeekNode, this)); + MakeCallback (&NodeListPriv::GetNode, this)); return resolver; } diff --git a/src/node/node.cc b/src/node/node.cc index fa33ff7df..05b61c096 100644 --- a/src/node/node.cc +++ b/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 -// - -// 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 + * Mathieu Lacage + */ #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 socketFactory = Create (); + 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 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 @@ -107,8 +115,27 @@ Node::GetNApplications (void) const return m_applications.size (); } +TraceResolver * +Node::CreateDevicesTraceResolver (const TraceContext &context) +{ + ArrayTraceResolver > *resolver = + new ArrayTraceResolver > (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 >::iterator i = m_devices.begin (); i != m_devices.end (); i++) @@ -129,4 +156,56 @@ void Node::DoDispose() Object::DoDispose (); } +void +Node::NotifyDeviceAdded (Ptr device) +{} + +void +Node::RegisterProtocolHandler (ProtocolHandler handler, + uint16_t protocolType, + Ptr 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 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 diff --git a/src/node/node.h b/src/node/node.h index 4e4e7b8c7..e2e99dee3 100644 --- a/src/node/node.h +++ b/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 -// - -// 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 + * Mathieu Lacage + */ +#ifndef NODE_H +#define NODE_H #include #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 >::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 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 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, 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 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 device) = 0; + virtual void NotifyDeviceAdded (Ptr device); + bool ReceiveFromDevice (Ptr 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 device; + }; + typedef std::vector ProtocolHandlerList; uint32_t m_id; // Node id for this node uint32_t m_sid; // System id for this node std::vector > m_devices; std::vector > m_applications; + ProtocolHandlerList m_handlers; }; } //namespace ns3 -#endif /* I_NODE_H */ +#endif /* NODE_H */ diff --git a/src/node/packet-socket-address.cc b/src/node/packet-socket-address.cc new file mode 100644 index 000000000..1b16b9cb5 --- /dev/null +++ b/src/node/packet-socket-address.cc @@ -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 + */ +#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 diff --git a/src/node/packet-socket-address.h b/src/node/packet-socket-address.h new file mode 100644 index 000000000..e280db8df --- /dev/null +++ b/src/node/packet-socket-address.h @@ -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 + */ +#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 */ diff --git a/src/internet-node/arp-private.h b/src/node/packet-socket-factory.cc similarity index 55% rename from src/internet-node/arp-private.h rename to src/node/packet-socket-factory.cc index 6e238ade0..3cd403a1a 100644 --- a/src/internet-node/arp-private.h +++ b/src/node/packet-socket-factory.cc @@ -1,6 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2007 INRIA + * Copyright (c) 2007 Emmanuelle Laprise * All rights reserved. * * This program is free software; you can redistribute it and/or modify @@ -16,36 +16,25 @@ * 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 + * Author: Emmanuelle Laprise */ -#ifndef ARP_PRIVATE_H -#define ARP_PRIVATE_H - -#include "ns3/object.h" -#include "ns3/ipv4-address.h" +#include "packet-socket-factory.h" +#include "node.h" namespace ns3 { -class NetDevice; -class MacAddress; -class Packet; -class ArpL3Protocol; +const InterfaceId PacketSocketFactory::iid = MakeInterfaceId ("Packet", + SocketFactory::iid); -class ArpPrivate : public Object +PacketSocketFactory::PacketSocketFactory () { -public: - static const InterfaceId iid; - ArpPrivate (Ptr arp); - virtual ~ArpPrivate (); - bool Lookup (Packet &p, Ipv4Address destination, - Ptr device, - MacAddress *hardwareDestination); -protected: - virtual void DoDispose (void); -private: - Ptr m_arp; -}; + SetInterfaceId (PacketSocketFactory::iid); +} +Ptr PacketSocketFactory::CreateSocket (void) +{ + Ptr node = QueryInterface (Node::iid); + Ptr socket = Create (node); + return socket; +} } // namespace ns3 - -#endif /* ARP_PRIVATE_H */ diff --git a/src/internet-node/arp-private.cc b/src/node/packet-socket-factory.h similarity index 52% rename from src/internet-node/arp-private.cc rename to src/node/packet-socket-factory.h index 10a86b3e3..0f052ce6e 100644 --- a/src/internet-node/arp-private.cc +++ b/src/node/packet-socket-factory.h @@ -1,6 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2007 INRIA + * Copyright (c) 2007 Emmanuelle Laprise * All rights reserved. * * This program is free software; you can redistribute it and/or modify @@ -16,41 +16,37 @@ * 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 + * Author: Emmanuelle Laprise */ -#include "arp-private.h" -#include "arp-l3-protocol.h" -#include "ns3/assert.h" -#include "ns3/net-device.h" +#ifndef PACKET_SOCKET_FACTORY_H +#define PACKET_SOCKET_FACTORY_H + +#include "socket-factory.h" +#include "packet-socket.h" namespace ns3 { -const InterfaceId ArpPrivate::iid = MakeInterfaceId ("ArpPrivate", Object::iid); +class Socket; -ArpPrivate::ArpPrivate (Ptr arp) - : m_arp (arp) +/** + * 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 { - SetInterfaceId (ArpPrivate::iid); -} -ArpPrivate::~ArpPrivate () -{ - NS_ASSERT (m_arp == 0); -} +public: + static const InterfaceId iid; /// Interface identifier -bool -ArpPrivate::Lookup (Packet &p, Ipv4Address destination, - Ptr device, - MacAddress *hardwareDestination) -{ - return m_arp->Lookup (p, destination, device, hardwareDestination); -} - -void -ArpPrivate::DoDispose (void) -{ - m_arp = 0; - Object::DoDispose (); -} + PacketSocketFactory (); + /** + * Creates a PacketSocket and returns a pointer to it. + * + * \return a pointer to the created socket + */ + virtual Ptr CreateSocket (void); +}; } // namespace ns3 + +#endif /* PACKET_SOCKET_FACTORY_H */ diff --git a/src/node/packet-socket.cc b/src/node/packet-socket.cc new file mode 100644 index 000000000..700f5f8b5 --- /dev/null +++ b/src/node/packet-socket.cc @@ -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 + * Mathieu Lacage + */ + +#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) + : 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 +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 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 > 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 > connectionSucceeded, + ns3::Callback > connectionFailed, + ns3::Callback > 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, const Address &> connectionRequest, + ns3::Callback, const Address &> newConnectionCreated, + ns3::Callback > 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, 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, 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 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 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, const uint8_t*, uint32_t,const Address &> callback) +{ + m_rxCallback = callback; +} + +void +PacketSocket::DoRecvDummy(ns3::Callback, uint32_t, const Address &> callback) +{ + m_dummyRxCallback = callback; +} + +void +PacketSocket::ForwardUp (Ptr 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 diff --git a/src/node/packet-socket.h b/src/node/packet-socket.h new file mode 100644 index 000000000..f18279949 --- /dev/null +++ b/src/node/packet-socket.h @@ -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 , + * Mathieu Lacage + */ +#ifndef PACKET_SOCKET_H +#define PACKET_SOCKET_H + +#include +#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); + virtual ~PacketSocket (); + + virtual enum SocketErrno GetErrno (void) const; + virtual Ptr 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 > closeCompleted); + virtual int DoConnect(const Address & address, + Callback > connectionSucceeded, + Callback > connectionFailed, + Callback > halfClose); + virtual int DoAccept(Callback, const Address&> connectionRequest, + Callback, const Address&> newConnectionCreated, + Callback > closeRequested); + virtual int DoSend (const uint8_t* buffer, + uint32_t size, + Callback, uint32_t> dataSent); + virtual int DoSendTo(const Address &address, + const uint8_t *buffer, + uint32_t size, + Callback, uint32_t> dataSent); + virtual void DoRecv(Callback, const uint8_t*, uint32_t,const Address&> receive); + virtual void DoRecvDummy(Callback, uint32_t,const Address&>); + +private: + void Init (void); + void ForwardUp (Ptr 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 m_node; + Callback,uint32_t,const Address &> m_dummyRxCallback; + Callback,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 */ + + diff --git a/src/node/socket.cc b/src/node/socket.cc index 75cd3a023..e3e573ab6 100644 --- a/src/node/socket.cc +++ b/src/node/socket.cc @@ -5,24 +5,23 @@ namespace ns3 { Socket::~Socket () {} -void +int Socket::Close(Callback > closeCompleted) { - DoClose (closeCompleted); + return DoClose (closeCompleted); } -void -Socket::Connect(const Ipv4Address & address, - uint16_t portNumber, +int +Socket::Connect(const Address & address, Callback > connectionSucceeded, Callback > connectionFailed, Callback > halfClose) { - DoConnect (address, portNumber, connectionSucceeded, connectionFailed, halfClose); + return DoConnect (address, connectionSucceeded, connectionFailed, halfClose); } int -Socket::Accept(Callback, const Ipv4Address&, uint16_t> connectionRequest, - Callback, const Ipv4Address&, uint16_t> newConnectionCreated, +Socket::Accept(Callback, const Address&> connectionRequest, + Callback, const Address&> newConnectionCreated, Callback > 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, uint32_t> dataSent) { - return DoSendTo (address, port, buffer, size, dataSent); + return DoSendTo (address, buffer, size, dataSent); } void -Socket::Recv(Callback, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> callback) +Socket::Recv(Callback, const uint8_t*, uint32_t,const Address&> callback) { DoRecv (callback); } void -Socket::RecvDummy(Callback, uint32_t,const Ipv4Address&, uint16_t> callback) +Socket::RecvDummy(Callback, uint32_t,const Address&> callback) { DoRecvDummy (callback); } bool -Socket::RefuseAllConnections (Ptr socket, const Ipv4Address& address, uint16_t port) +Socket::RefuseAllConnections (Ptr socket, const Address& address) { return false; } @@ -67,14 +65,14 @@ void Socket::DummyCallbackVoidSocketUi32 (Ptr socket, uint32_t) {} void -Socket::DummyCallbackVoidSocketUi32Ipv4AddressUi16 (Ptr socket, uint32_t, const Ipv4Address &, uint16_t) +Socket::DummyCallbackVoidSocketUi32Address (Ptr socket, uint32_t, const Address &) {} void -Socket::DummyCallbackVoidSocketBufferUi32Ipv4AddressUi16 (Ptr socket, const uint8_t *, uint32_t, - const Ipv4Address &, uint16_t) +Socket::DummyCallbackVoidSocketBufferUi32Address (Ptr socket, const uint8_t *, uint32_t, + const Address &) {} void -Socket::DummyCallbackVoidSocketIpv4AddressUi16 (Ptr socket, const Ipv4Address &, uint16_t) +Socket::DummyCallbackVoidSocketAddress (Ptr socket, const Address &) {} diff --git a/src/node/socket.h b/src/node/socket.h index b0ec81b05..991fb01b1 100644 --- a/src/node/socket.h +++ b/src/node/socket.h @@ -23,8 +23,8 @@ #include "ns3/callback.h" #include "ns3/ptr.h" -#include "ipv4-address.h" #include "ns3/object.h" +#include "address.h" #include 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 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 > closeCompleted = MakeCallback (&Socket::DummyCallbackVoidSocket)); + int Close(Callback > 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 > connectionSucceeded = MakeCallback(&Socket::DummyCallbackVoidSocket), - Callback > connectionFailed = MakeCallback(&Socket::DummyCallbackVoidSocket), - Callback > halfClose = MakeCallback(&Socket::DummyCallbackVoidSocket)); + int Connect(const Address &address, + Callback > connectionSucceeded = MakeCallback(&Socket::DummyCallbackVoidSocket), + Callback > connectionFailed = MakeCallback(&Socket::DummyCallbackVoidSocket), + Callback > 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, const Ipv4Address&, uint16_t> connectionRequest = + int Accept(Callback, const Address &> connectionRequest = MakeCallback(&Socket::RefuseAllConnections), - Callback, const Ipv4Address&, uint16_t> newConnectionCreated = - MakeCallback (&Socket::DummyCallbackVoidSocketIpv4AddressUi16), + Callback, const Address&> newConnectionCreated = + MakeCallback (&Socket::DummyCallbackVoidSocketAddress), Callback > 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, 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, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> receivedData = - MakeCallback (&Socket::DummyCallbackVoidSocketBufferUi32Ipv4AddressUi16)); + void Recv(Callback, 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, uint32_t,const Ipv4Address&, uint16_t> receivedData = - MakeCallback (&Socket::DummyCallbackVoidSocketUi32Ipv4AddressUi16)); + void RecvDummy(Callback, uint32_t,const Address&> receivedData = + MakeCallback (&Socket::DummyCallbackVoidSocketUi32Address)); private: - virtual void DoClose(Callback > closeCompleted) = 0; - virtual void DoConnect(const Ipv4Address & address, - uint16_t portNumber, - Callback > connectionSucceeded, - Callback > connectionFailed, - Callback > halfClose) = 0; - virtual int DoAccept(Callback, const Ipv4Address&, uint16_t> connectionRequest, - Callback, const Ipv4Address&, uint16_t> newConnectionCreated, + virtual int DoClose(Callback > closeCompleted) = 0; + virtual int DoConnect(const Address & address, + Callback > connectionSucceeded, + Callback > connectionFailed, + Callback > halfClose) = 0; + virtual int DoAccept(Callback, const Address&> connectionRequest, + Callback, const Address&> newConnectionCreated, Callback > closeRequested) = 0; virtual int DoSend (const uint8_t* buffer, - uint32_t size, - Callback, uint32_t> dataSent) = 0; - virtual int DoSendTo(const Ipv4Address &address, - uint16_t port, + uint32_t size, + Callback, uint32_t> dataSent) = 0; + virtual int DoSendTo(const Address &address, const uint8_t *buffer, uint32_t size, Callback, uint32_t> dataSent) = 0; - virtual void DoRecv(Callback, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> receive) = 0; - virtual void DoRecvDummy(Callback, uint32_t,const Ipv4Address&, uint16_t>) = 0; + virtual void DoRecv(Callback, const uint8_t*, uint32_t,const Address&> receive) = 0; + virtual void DoRecvDummy(Callback, uint32_t,const Address&>) = 0; - static bool RefuseAllConnections (Ptr socket, const Ipv4Address& address, uint16_t port); + static bool RefuseAllConnections (Ptr socket, const Address& address); static void DummyCallbackVoidSocket (Ptr socket); static void DummyCallbackVoidSocketUi32 (Ptr socket, uint32_t); - static void DummyCallbackVoidSocketUi32Ipv4AddressUi16 (Ptr socket, uint32_t, const Ipv4Address &, uint16_t); - static void DummyCallbackVoidSocketBufferUi32Ipv4AddressUi16 (Ptr socket, const uint8_t *, uint32_t, - const Ipv4Address &, uint16_t); - static void DummyCallbackVoidSocketIpv4AddressUi16 (Ptr socket, const Ipv4Address &, uint16_t); + static void DummyCallbackVoidSocketUi32Address (Ptr socket, uint32_t, const Address &); + static void DummyCallbackVoidSocketBufferUi32Address (Ptr socket, const uint8_t *, uint32_t, + const Address &); + static void DummyCallbackVoidSocketAddress (Ptr socket, const Address &); }; } //namespace ns3 diff --git a/src/node/wscript b/src/node/wscript index 4b1ea1f01..17714f897 100644 --- a/src/node/wscript +++ b/src/node/wscript @@ -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', diff --git a/src/routing/global-routing/global-route-manager-impl.cc b/src/routing/global-routing/global-route-manager-impl.cc index 03578cb96..142f613be 100644 --- a/src/routing/global-routing/global-route-manager-impl.cc +++ b/src/routing/global-routing/global-route-manager-impl.cc @@ -1191,6 +1191,7 @@ GlobalRouteManagerImpl::SPFVertexAddParent (SPFVertex* v) // --------------------------------------------------------------------------- #include "ns3/test.h" +#include "ns3/simulator.h" namespace ns3 { @@ -1392,6 +1393,9 @@ GlobalRouteManagerImplTest::RunTests (void) // because the NodeList is empty srm->DebugSPFCalculate (lsa0->GetLinkStateId ()); // node n0 + Simulator::Run (); + Simulator::Destroy (); + // This delete clears the srm, which deletes the LSDB, which clears // all of the LSAs, which each destroys the attached LinkRecords. delete srm; diff --git a/src/routing/global-routing/global-router-interface.cc b/src/routing/global-routing/global-router-interface.cc index 24a84be06..778d91bcc 100644 --- a/src/routing/global-routing/global-router-interface.cc +++ b/src/routing/global-routing/global-router-interface.cc @@ -332,6 +332,13 @@ GlobalRouter::~GlobalRouter () ClearLSAs(); } +void +GlobalRouter::DoDispose () +{ + m_node = 0; + Object::DoDispose (); +} + void GlobalRouter::ClearLSAs () { @@ -535,8 +542,7 @@ GlobalRouter::GetLSA (uint32_t n, GlobalRouterLSA &lsa) const GlobalRouter::GetAdjacent(Ptr nd, Ptr ch) const { - uint32_t nDevices = ch->GetNDevices(); - NS_ASSERT_MSG(nDevices == 2, + NS_ASSERT_MSG(ch->GetNDevices() == 2, "GlobalRouter::GetAdjacent (): Channel with other than two devices"); // // This is a point to point channel with two endpoints. Get both of them. diff --git a/src/routing/global-routing/global-router-interface.h b/src/routing/global-routing/global-router-interface.h index b2927d631..737643d9e 100644 --- a/src/routing/global-routing/global-router-interface.h +++ b/src/routing/global-routing/global-router-interface.h @@ -565,6 +565,8 @@ protected: Ipv4Address m_routerId; private: + // inherited from Object + virtual void DoDispose (void); /** * @brief Global Router copy construction is disallowed. */