diff --git a/SConstruct b/SConstruct index e90c6f51f..445b04251 100644 --- a/SConstruct +++ b/SConstruct @@ -147,6 +147,7 @@ node.add_sources ([ 'capability.cc', 'l3-demux.cc', 'ipv4-l4-demux.cc', + 'ipv4-l4-protocol.cc', 'ipv4-address.cc', 'internet-node.cc', 'net-device.cc', @@ -156,16 +157,19 @@ node.add_sources ([ 'ipv4-checksum.cc', 'ipv4-route.cc', 'ipv4-interface.cc', - 'ipv4-l3-protocol.cc', + 'ipv4.cc', 'ipv4-end-point.cc', 'udp-end-point.cc', + 'udp-socket.cc', + 'udp.cc', ]) node.add_headers ([ 'ipv4-address.h', 'ipv4-header.h', 'udp-header.h', 'ipv4-checksum.h', - 'ipv4-l3-protocol.h', + 'ipv4.h', + 'udp.h', ]) node.add_inst_headers ([ 'node.h', @@ -180,6 +184,7 @@ node.add_inst_headers ([ 'mac-address.h', 'ipv4-route.h', 'ipv4-interface.h', + 'udp-socket.h', ]) diff --git a/src/node/internet-node.cc b/src/node/internet-node.cc index 282fd628a..bcfdd682f 100644 --- a/src/node/internet-node.cc +++ b/src/node/internet-node.cc @@ -25,6 +25,8 @@ #include "l3-demux.h" #include "ipv4-l4-demux.h" #include "internet-node.h" +#include "udp.h" +#include "ipv4.h" namespace ns3 { @@ -34,12 +36,12 @@ InternetNode::InternetNode() m_netDevices = new NetDeviceList(); m_l3Demux = new L3Demux(); m_ipv4L4Demux = new Ipv4L4Demux(); - // Configure the capabilities - // Insert an IPv4 protocol at layer 3 - //m_l3Protocols->Insert(ns3::IPV4()); - // L4 protocols (instances of TCP or UDP layer 4 objects) - // are inserted as created by process socket creations - // or bind calls. + // add an ipv4 protocol handler. + Ipv4 ipv4; + m_l3Demux->Insert (ipv4); + // add a udp protocol handler. + Udp udp = Udp (this); + m_ipv4L4Demux->Insert (udp); } InternetNode::InternetNode(const InternetNode& rhs) diff --git a/src/node/ipv4-end-point-demux.h b/src/node/ipv4-end-point-demux.h index 6974a4ef7..7b81823e0 100644 --- a/src/node/ipv4-end-point-demux.h +++ b/src/node/ipv4-end-point-demux.h @@ -24,7 +24,7 @@ #include #include -#include "ns3/ipv4-address.h" +#include "ipv4-address.h" namespace ns3 { @@ -45,6 +45,7 @@ public: T *Allocate (void); T *Allocate (Ipv4Address address); + T *Allocate (uint16_t port); T *Allocate (Ipv4Address address, uint16_t port); T *Allocate (Ipv4Address localAddress, uint16_t localPort, @@ -54,7 +55,7 @@ public: private: uint16_t AllocateEphemeralPort (void); typedef std::list EndPoints; - typedef std::list::iterator EndPointsI; + typedef typename std::list::iterator EndPointsI; uint16_t m_ephemeral; EndPoints m_endPoints; @@ -125,12 +126,17 @@ Ipv4EndPointDemux::Allocate (Ipv4Address address) return 0; } T *endPoint = new T (address, port); - endPoint->SetDestroyCallback (MakeCallback (&Ipv4EndPointDemux::DestroyEndPoint, this)); m_endPoints.push_back (endPoint); return endPoint; } template T * +Ipv4EndPointDemux::Allocate (uint16_t port) +{ + return Allocate (Ipv4Address::GetAny (), port); +} +template +T * Ipv4EndPointDemux::Allocate (Ipv4Address address, uint16_t port) { if (LookupLocal (address, port)) @@ -138,7 +144,6 @@ Ipv4EndPointDemux::Allocate (Ipv4Address address, uint16_t port) return 0; } T *endPoint = new T (address, port); - endPoint->SetDestroyCallback (MakeCallback (&Ipv4EndPointDemux::DestroyEndPoint, this)); m_endPoints.push_back (endPoint); return endPoint; } @@ -161,7 +166,6 @@ Ipv4EndPointDemux::Allocate (Ipv4Address localAddress, uint16_t localPort, } T *endPoint = new T (localAddress, localPort); endPoint->SetPeer (peerAddress, peerPort); - endPoint->SetDestroyCallback (MakeCallback (&Ipv4EndPointDemux::DestroyEndPoint, this)); m_endPoints.push_back (endPoint); return endPoint; } diff --git a/src/node/ipv4-l4-protocol.cc b/src/node/ipv4-l4-protocol.cc new file mode 100644 index 000000000..58a225f1b --- /dev/null +++ b/src/node/ipv4-l4-protocol.cc @@ -0,0 +1,48 @@ +// -*- 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 4 Protocol base class +// George F. Riley, Georgia Tech, Spring 2007 + +#include "ipv4-l4-protocol.h" + +namespace ns3 { + + +Ipv4L4Protocol::Ipv4L4Protocol(int protocolNumber, int version) + : m_protocolNumber (protocolNumber), + m_version (version) +{} +Ipv4L4Protocol::~Ipv4L4Protocol () +{} + +int +Ipv4L4Protocol::GetProtocolNumber (void) const +{ + return m_protocolNumber; +} +int +Ipv4L4Protocol::GetVersion() const +{ + return m_version; +} + +}//namespace ns3 diff --git a/src/node/ipv4-l4-protocol.h b/src/node/ipv4-l4-protocol.h index 3a3699dcd..3751b3632 100644 --- a/src/node/ipv4-l4-protocol.h +++ b/src/node/ipv4-l4-protocol.h @@ -34,7 +34,7 @@ class Ipv4Address; class Ipv4L4Protocol { public: - Ipv4L4Protocol(int protocolNumber, int version, int layer); + Ipv4L4Protocol(int protocolNumber, int version); virtual ~Ipv4L4Protocol (); int GetProtocolNumber (void) const; diff --git a/src/node/ipv4-l3-protocol.cc b/src/node/ipv4.cc similarity index 87% rename from src/node/ipv4-l3-protocol.cc rename to src/node/ipv4.cc index 407bff183..fdee45d72 100644 --- a/src/node/ipv4-l3-protocol.cc +++ b/src/node/ipv4.cc @@ -21,13 +21,13 @@ #include "ns3/packet.h" -#include "ipv4-l3-protocol.h" +#include "ipv4.h" #include "ipv4-l4-protocol.h" #include "ipv4-address.h" #include "ipv4-header.h" #include "ipv4-interface.h" #include "ipv4-route.h" -// the two following headers are needed for Ipv4L3Protocol::ForwardUp +// the two following headers are needed for Ipv4::ForwardUp #include "node.h" #include "ipv4-l4-demux.h" @@ -35,14 +35,14 @@ namespace ns3 { -Ipv4L3Protocol::Ipv4L3Protocol() +Ipv4::Ipv4() : L3Protocol (0x0800, 4), m_nInterfaces (0), m_defaultTtl (64), m_identification (0), m_defaultRoute (0) {} -Ipv4L3Protocol::Ipv4L3Protocol(Ipv4L3Protocol const &o) +Ipv4::Ipv4(Ipv4 const &o) : L3Protocol (o), m_nInterfaces (0), m_defaultTtl (o.m_defaultTtl), @@ -52,7 +52,7 @@ Ipv4L3Protocol::Ipv4L3Protocol(Ipv4L3Protocol const &o) // We do not copy the list of interfaces or the routes // purposedly. } -Ipv4L3Protocol::~Ipv4L3Protocol () +Ipv4::~Ipv4 () { // XXX I am not sure we are really allowed to do this here. for (Ipv4InterfaceList::iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++) @@ -75,14 +75,14 @@ Ipv4L3Protocol::~Ipv4L3Protocol () } void -Ipv4L3Protocol::SetDefaultTtl (uint8_t ttl) +Ipv4::SetDefaultTtl (uint8_t ttl) { m_defaultTtl = ttl; } void -Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest, +Ipv4::AddHostRouteTo (Ipv4Address dest, Ipv4Address nextHop, uint32_t interface) { @@ -91,7 +91,7 @@ Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest, m_hostRoutes.push_back (route); } void -Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest, +Ipv4::AddHostRouteTo (Ipv4Address dest, uint32_t interface) { Ipv4Route *route = new Ipv4Route (); @@ -99,7 +99,7 @@ Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest, m_hostRoutes.push_back (route); } void -Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network, +Ipv4::AddNetworkRouteTo (Ipv4Address network, Ipv4Mask networkMask, Ipv4Address nextHop, uint32_t interface) @@ -112,7 +112,7 @@ Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network, m_networkRoutes.push_back (route); } void -Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network, +Ipv4::AddNetworkRouteTo (Ipv4Address network, Ipv4Mask networkMask, uint32_t interface) { @@ -123,7 +123,7 @@ Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network, m_networkRoutes.push_back (route); } void -Ipv4L3Protocol::SetDefaultRoute (Ipv4Address nextHop, +Ipv4::SetDefaultRoute (Ipv4Address nextHop, uint32_t interface) { Ipv4Route *route = new Ipv4Route (); @@ -133,7 +133,7 @@ Ipv4L3Protocol::SetDefaultRoute (Ipv4Address nextHop, } Ipv4Route * -Ipv4L3Protocol::Lookup (Ipv4Address dest) +Ipv4::Lookup (Ipv4Address dest) { for (HostRoutesCI i = m_hostRoutes.begin (); i != m_hostRoutes.end (); @@ -166,7 +166,7 @@ Ipv4L3Protocol::Lookup (Ipv4Address dest) } uint32_t -Ipv4L3Protocol::GetNRoutes (void) +Ipv4::GetNRoutes (void) { uint32_t n = 0; if (m_defaultRoute != 0) @@ -178,7 +178,7 @@ Ipv4L3Protocol::GetNRoutes (void) return n; } Ipv4Route * -Ipv4L3Protocol::GetRoute (uint32_t index) +Ipv4::GetRoute (uint32_t index) { if (index == 0 && m_defaultRoute != 0) { @@ -216,7 +216,7 @@ Ipv4L3Protocol::GetRoute (uint32_t index) return 0; } void -Ipv4L3Protocol::RemoveRoute (uint32_t index) +Ipv4::RemoveRoute (uint32_t index) { if (index == 0 && m_defaultRoute != 0) { @@ -259,7 +259,7 @@ Ipv4L3Protocol::RemoveRoute (uint32_t index) uint32_t -Ipv4L3Protocol::AddInterface (Ipv4Interface *interface) +Ipv4::AddInterface (Ipv4Interface *interface) { uint32_t index = m_nInterfaces; m_interfaces.push_back (interface); @@ -267,7 +267,7 @@ Ipv4L3Protocol::AddInterface (Ipv4Interface *interface) return index; } Ipv4Interface * -Ipv4L3Protocol::GetInterface (uint32_t index) +Ipv4::GetInterface (uint32_t index) { uint32_t tmp = 0; for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++) @@ -281,20 +281,20 @@ Ipv4L3Protocol::GetInterface (uint32_t index) return 0; } uint32_t -Ipv4L3Protocol::GetNInterfaces (void) const +Ipv4::GetNInterfaces (void) const { return m_nInterfaces; } -Ipv4L3Protocol* -Ipv4L3Protocol::Copy() const +Ipv4* +Ipv4::Copy() const { - return new Ipv4L3Protocol (*this); + return new Ipv4 (*this); } void -Ipv4L3Protocol::Receive(Packet& packet, NetDevice &device) +Ipv4::Receive(Packet& packet, NetDevice &device) { // XXX trace here. Ipv4Header ipHeader; @@ -315,7 +315,7 @@ Ipv4L3Protocol::Receive(Packet& packet, NetDevice &device) } void -Ipv4L3Protocol::Send (Packet const &packet, +Ipv4::Send (Packet const &packet, Ipv4Address source, Ipv4Address destination, uint8_t protocol) @@ -351,7 +351,7 @@ Ipv4L3Protocol::Send (Packet const &packet, } void -Ipv4L3Protocol::SendRealOut (Packet const &p, Ipv4Header const &ip, Ipv4Route const &route) +Ipv4::SendRealOut (Packet const &p, Ipv4Header const &ip, Ipv4Route const &route) { Packet packet = p; packet.Add (ip); @@ -370,7 +370,7 @@ Ipv4L3Protocol::SendRealOut (Packet const &p, Ipv4Header const &ip, Ipv4Route co bool -Ipv4L3Protocol::Forwarding (Packet const &packet, Ipv4Header &ipHeader, NetDevice &device) +Ipv4::Forwarding (Packet const &packet, Ipv4Header &ipHeader, NetDevice &device) { for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++) @@ -428,7 +428,7 @@ Ipv4L3Protocol::Forwarding (Packet const &packet, Ipv4Header &ipHeader, NetDevic void -Ipv4L3Protocol::ForwardUp (Packet p, Ipv4Header const&ip) +Ipv4::ForwardUp (Packet p, Ipv4Header const&ip) { Ipv4L4Protocol *protocol = m_node->GetIpv4L4Demux ()->Lookup (ip.GetProtocol ()); protocol->Receive (p, ip.GetSource (), ip.GetDestination ()); diff --git a/src/node/ipv4-l3-protocol.h b/src/node/ipv4.h similarity index 94% rename from src/node/ipv4-l3-protocol.h rename to src/node/ipv4.h index 5be7381fb..935e0da04 100644 --- a/src/node/ipv4-l3-protocol.h +++ b/src/node/ipv4.h @@ -19,8 +19,8 @@ // Author: George F. Riley // -#ifndef IPV4_L3_PROTOCOL_H -#define IPV4_L3_PROTOCOL_H +#ifndef IPV4_H +#define IPV4_H #include #include @@ -41,11 +41,11 @@ class Node; /** * ::Send is always defined in subclasses. */ -class Ipv4L3Protocol : public L3Protocol { +class Ipv4 : public L3Protocol { public: - Ipv4L3Protocol(); - Ipv4L3Protocol(Ipv4L3Protocol const &o); - virtual ~Ipv4L3Protocol (); + Ipv4(); + Ipv4(Ipv4 const &o); + virtual ~Ipv4 (); void SetDefaultTtl (uint8_t ttl); @@ -89,7 +89,7 @@ public: uint32_t GetNInterfaces (void) const; - virtual Ipv4L3Protocol* Copy() const; + virtual Ipv4* Copy() const; /** * Lower layer calls this method after calling L3Demux::Lookup * The ARP subclass needs to know from which NetDevice this diff --git a/src/node/udp-socket.cc b/src/node/udp-socket.cc new file mode 100644 index 000000000..e8950a2b4 --- /dev/null +++ b/src/node/udp-socket.cc @@ -0,0 +1,172 @@ +/* -*- 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 "udp-socket.h" +#include "udp.h" +#include "udp-end-point.h" +#include "node.h" +#include "ipv4-l4-demux.h" + +namespace ns3 { + +UdpSocket::UdpSocket (Node *node) + : m_endPoint (0), + m_node (node) +{ + assert (GetUdp () != 0); +} +UdpSocket::~UdpSocket () +{ + delete m_endPoint; +} + +int +UdpSocket::Bind (void) +{ + m_endPoint = GetUdp ()->Allocate (); + if (m_endPoint == 0) + { + return -1; + } + m_endPoint->SetSocket (this); + return 0; +} +int +UdpSocket::Bind (Ipv4Address address) +{ + m_endPoint = GetUdp ()->Allocate (address); + if (m_endPoint == 0) + { + return -1; + } + m_endPoint->SetSocket (this); + return 0; +} +int +UdpSocket::Bind (uint16_t port) +{ + m_endPoint = GetUdp ()->Allocate (port); + if (m_endPoint == 0) + { + return -1; + } + m_endPoint->SetSocket (this); + return 0; +} +int +UdpSocket::Bind (Ipv4Address address, uint16_t port) +{ + m_endPoint = GetUdp ()->Allocate (address, port); + if (m_endPoint == 0) + { + return -1; + } + m_endPoint->SetSocket (this); + return 0; +} + +void +UdpSocket::SetDefaultDestination (Ipv4Address daddr, uint16_t dport) +{ + m_defaultAddress = daddr; + m_defaultPort = dport; +} +void +UdpSocket::SendDummy (uint32_t size) +{ + SendDummyTo (size, m_defaultAddress, m_defaultPort); +} +void +UdpSocket::SendDummyTo (uint32_t size, Ipv4Address daddr, uint16_t dport) +{ + if (m_endPoint == 0) + { + Bind (); + if (m_endPoint == 0) + { + return; + } + } + Packet p = Packet (size); + GetUdp ()->Send (p, m_endPoint->GetLocalAddress (), daddr, + m_endPoint->GetLocalPort (), dport); +} + +void +UdpSocket::Send (uint8_t const*buffer, uint32_t size) +{ + SendTo (buffer, size, m_defaultAddress, m_defaultPort); +} +void +UdpSocket::SendTo (uint8_t const*buffer, uint32_t size, + Ipv4Address daddr, uint16_t dport) +{ + if (m_endPoint == 0) + { + Bind (); + if (m_endPoint == 0) + { + return; + } + } + Packet p = Packet (buffer, size); + GetUdp ()->Send (p, m_endPoint->GetLocalAddress (), daddr, + m_endPoint->GetLocalPort (), dport); +} +void +UdpSocket::SetDummyRxCallback (Callback cb) +{ + m_dummyRxCallback = cb; +} +void +UdpSocket::SetRxCallback (Callback cb) +{ + m_rxCallback = cb; +} + +void +UdpSocket::ForwardUp (Packet &p, Ipv4Address saddr, uint16_t sport) +{ + if (!m_dummyRxCallback.IsNull ()) + { + m_dummyRxCallback (this, p.GetSize (), saddr, sport); + } + if (!m_rxCallback.IsNull ()) + { + m_rxCallback (this, p.PeekData (), p.GetSize (), saddr, sport); + } +} + +Udp * +UdpSocket::GetUdp (void) const +{ + if (m_node->GetIpv4L4Demux () != 0) + { + // udp protocol number + return static_cast (m_node->GetIpv4L4Demux ()->Lookup (17)); + } + return 0; +} + +}//namespace ns3 diff --git a/src/node/udp-socket.h b/src/node/udp-socket.h new file mode 100644 index 000000000..430c6c165 --- /dev/null +++ b/src/node/udp-socket.h @@ -0,0 +1,134 @@ +/* -*- 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 UDP_SOCKET_H +#define UDP_SOCKET_H + +#include +#include "ns3/callback.h" +#include "ipv4-address.h" + +namespace ns3 { + +class UdpEndPoint; +class Node; +class Packet; +class Udp; + +/** + * Before any data is sent, the socket must be bound with + * one of the Bind methods. + * If none of these Bind methods are called prior to + * one of the ::Send methods, the socket is implicitely + * bound to a random port and to all interfaces. + */ +class UdpSocket +{ +public: + /** + * Create an unbound udp socket. + */ + UdpSocket (Node *node); + ~UdpSocket (); + + /** + * Allocate a free port number and + * bind this socket to this port number on all + * interfaces of this system. + * + * return 0 on success, -1 on failure. + */ + int Bind (void); + /** + * Allocate a free port number and + * bind this socket to this port number on the + * specified interface. + * + * return 0 on success, -1 on failure. + */ + int Bind (Ipv4Address address); + + /** + * Bind this socket to this port number + * on all interfaces of this system. + * + * return 0 on success, -1 on failure. + */ + int Bind (uint16_t port); + + /** + * Bind this socket to this port number + * on the interface specified by address. + * + * return 0 on success, -1 on failure. + */ + int Bind (Ipv4Address address, uint16_t port); + + + /** + * Set the default destination address and port + * number for all packets outgoing from this socket. + */ + void SetDefaultDestination (Ipv4Address daddr, uint16_t dport); + + /** + * Send dummy data to default destination + */ + void SendDummy (uint32_t size); + /** + * Send dummy data to specified destination + */ + void SendDummyTo (uint32_t size, Ipv4Address daddr, uint16_t dport); + + void Send (uint8_t const*buffer, uint32_t size); + void SendTo (uint8_t const*buffer, uint32_t size, + Ipv4Address daddr, uint16_t dport); + + /** + * When a packet is received by this socket, it invokes the "dummy callback" which + * forwards to the application the number of bytes received and from who they + * were received. + */ + void SetDummyRxCallback (Callback cb); + /** + * When a packet is received by this socket, it invokes the "normal callback" which + * forwards to the application the buffer of bytes received and from who they + * were received. The application is responsible for copying that buffer if it wants + * to keep track of it. + */ + void SetRxCallback (Callback cb); + +private: + friend class Udp; + // invoked by Udp class + void ForwardUp (Packet &p, Ipv4Address saddr, uint16_t sport); + Udp *GetUdp (void) const; + + UdpEndPoint *m_endPoint; + Node *m_node; + Ipv4Address m_defaultAddress; + uint16_t m_defaultPort; + Callback m_dummyRxCallback; + Callback m_rxCallback; +}; + +}//namespace ns3 + +#endif /* UDP_SOCKET_H */ diff --git a/src/node/udp.cc b/src/node/udp.cc index 7eead89ed..9b3127174 100644 --- a/src/node/udp.cc +++ b/src/node/udp.cc @@ -25,15 +25,27 @@ #include "udp-header.h" #include "ipv4-end-point-demux.h" #include "udp-end-point.h" +#include "udp-socket.h" +#include "node.h" +#include "ipv4.h" +#include "l3-demux.h" namespace ns3 { /* see http://www.iana.org/assignments/protocol-numbers */ const uint8_t Udp::UDP_PROTOCOL = 17; -Udp::Udp () +Udp::Udp (Node *node) + : Ipv4L4Protocol (UDP_PROTOCOL, 2), + m_node (node), + m_endPoints (new Ipv4EndPointDemux ()) +{} +Udp::Udp (Udp const &o) + : Ipv4L4Protocol (UDP_PROTOCOL, 2), + m_node (o.m_node), + m_endPoints (new Ipv4EndPointDemux ()) { - m_endPoints = new Ipv4EndPoints (); + // we do not copy the udp endpoints on purpose. } Udp::~Udp () @@ -52,6 +64,11 @@ Udp::Allocate (Ipv4Address address) return m_endPoints->Allocate (address); } UdpEndPoint * +Udp::Allocate (uint16_t port) +{ + return m_endPoints->Allocate (port); +} +UdpEndPoint * Udp::Allocate (Ipv4Address address, uint16_t port) { return m_endPoints->Allocate (address, port); @@ -64,12 +81,17 @@ Udp::Allocate (Ipv4Address localAddress, uint16_t localPort, peerAddress, peerPort); } +Udp* +Udp::Copy() const +{ + return new Udp (*this); +} + void -Udp::Receive(Packet& p, +Udp::Receive(Packet& packet, Ipv4Address const &source, Ipv4Address const &destination) { - m_recvLogger (packet); UdpHeader udpHeader; packet.Peek (udpHeader); packet.Remove (udpHeader); @@ -79,7 +101,8 @@ Udp::Receive(Packet& p, { return; } - UdpSocket *socket = endPoint->GetSocket (packet, &udpHeader); + UdpSocket *socket = endPoint->GetSocket (); + socket->ForwardUp (packet, source, udpHeader.GetSource ()); assert (socket != 0); } @@ -98,9 +121,15 @@ Udp::Send (Packet packet, packet.Add (udpHeader); - //XXX // Send to ipv4 layer. - ip.Send (p, saddr, daddr, UDP_PROTOCOL); + if (m_node->GetL3Demux () != 0 ) + { + Ipv4 *ipv4 = static_cast (m_node->GetL3Demux ()->Lookup (0x0800)); + if (ipv4 != 0) + { + ipv4->Send (packet, saddr, daddr, UDP_PROTOCOL); + } + } } diff --git a/src/node/udp.h b/src/node/udp.h index 9d68ab377..9b1bfc9fb 100644 --- a/src/node/udp.h +++ b/src/node/udp.h @@ -24,34 +24,41 @@ #include -#include "ns3/ipv4-address.h" #include "ns3/packet.h" +#include "ipv4-address.h" #include "ipv4-l4-protocol.h" #include "ipv4-end-point-demux.h" #include "udp-end-point.h" namespace ns3 { +class Node; + class Udp : public Ipv4L4Protocol { public: - Udp (); + Udp (Node *node); + Udp (Udp const &o); virtual ~Udp (); UdpEndPoint *Allocate (void); UdpEndPoint *Allocate (Ipv4Address address); + UdpEndPoint *Allocate (uint16_t port); UdpEndPoint *Allocate (Ipv4Address address, uint16_t port); UdpEndPoint *Allocate (Ipv4Address localAddress, uint16_t localPort, Ipv4Address peerAddress, uint16_t peerPort); - void Send (Packet packet); + // called by UdpSocket. + void Send (Packet packet, + Ipv4Address saddr, Ipv4Address daddr, + uint16_t sport, uint16_t dport); // inherited from Ipv4L4Protocol - virtual Ipv4L4Protocol* Copy() const; + virtual Udp* Copy() const; virtual void Receive(Packet& p, Ipv4Address const &source, Ipv4Address const &destination); private: static const uint8_t UDP_PROTOCOL; - //Ipv4 *m_ipv4; + Node *m_node; Ipv4EndPointDemux *m_endPoints; };