add start of udp stack
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Fri, 09 Feb 2007 19:40:19 +0100
changeset 238 2f09fd9cf32e
parent 237 6562b2679455
child 239 e194d619534b
add start of udp stack
SConstruct
src/node/ipv4-end-point-demux.h
src/node/ipv4-end-point.cc
src/node/ipv4-end-point.h
src/node/udp-end-point.cc
src/node/udp-end-point.h
src/node/udp.cc
src/node/udp.h
--- a/SConstruct	Fri Feb 09 19:40:12 2007 +0100
+++ b/SConstruct	Fri Feb 09 19:40:19 2007 +0100
@@ -157,6 +157,8 @@
     'ipv4-route.cc',
     'ipv4-interface.cc',
     'ipv4-l3-protocol.cc',
+    'ipv4-end-point.cc',
+    'udp-end-point.cc',
     ])
 node.add_headers ([
     'ipv4-address.h',
@@ -177,7 +179,7 @@
     'net-device.h',
     'mac-address.h',
     'ipv4-route.h',
-    'ipv4-interface.h'
+    'ipv4-interface.h',
     ])
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv4-end-point-demux.h	Fri Feb 09 19:40:19 2007 +0100
@@ -0,0 +1,249 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#ifndef IPV4_END_POINT_DEMUX_H
+#define IPV4_END_POINT_DEMUX_H
+
+#include <stdint.h>
+#include <list>
+#include "ns3/ipv4-address.h"
+
+namespace ns3 {
+
+class Ipv4EndPoint;
+
+template <typename T>
+class Ipv4EndPointDemux {
+public:
+  Ipv4EndPointDemux ();
+  ~Ipv4EndPointDemux ();
+
+  bool LookupPortLocal (uint16_t port);
+  bool LookupLocal (Ipv4Address addr, uint16_t port);
+  T *Lookup (Ipv4Address daddr, 
+             uint16_t dport, 
+             Ipv4Address saddr, 
+             uint16_t sport);
+
+  T *Allocate (void);
+  T *Allocate (Ipv4Address address);
+  T *Allocate (Ipv4Address address, uint16_t port);
+  T *Allocate (Ipv4Address localAddress, 
+               uint16_t localPort,
+               Ipv4Address peerAddress, 
+               uint16_t peerPort);
+
+ private:
+  uint16_t AllocateEphemeralPort (void);
+  typedef std::list<T *> EndPoints;
+  typedef std::list<T *>::iterator EndPointsI;
+
+  uint16_t m_ephemeral;
+  EndPoints m_endPoints;
+};
+
+}; // namespace ns3
+
+namespace ns3{
+
+template <typename T>
+Ipv4EndPointDemux<T>::Ipv4EndPointDemux ()
+  : m_ephemeral (1025)
+{}
+
+template <typename T>
+Ipv4EndPointDemux<T>::~Ipv4EndPointDemux ()
+{}
+
+template <typename T>
+bool
+Ipv4EndPointDemux<T>::LookupPortLocal (uint16_t port)
+{
+  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
+    {
+      if ((*i)->GetLocalPort  () == port) 
+        {
+          return true;
+        }
+    }
+  return false;
+}
+
+template <typename T>
+bool
+Ipv4EndPointDemux<T>::LookupLocal (Ipv4Address addr, uint16_t port)
+{
+  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
+    {
+      if ((*i)->GetLocalPort () == port &&
+          (*i)->GetLocalAddress () == addr) 
+        {
+          return true;
+        }
+    }
+  return false;
+}
+
+template <typename T>
+T *
+Ipv4EndPointDemux<T>::Allocate (void)
+{
+  uint16_t port = AllocateEphemeralPort ();
+  if (port == 0) 
+    {
+      return 0;
+    }
+  T *endPoint = new T (Ipv4Address::GetAny (), port);
+  m_endPoints.push_back (endPoint);
+  return endPoint;
+}
+template <typename T>
+T *
+Ipv4EndPointDemux<T>::Allocate (Ipv4Address address)
+{
+  uint16_t port = AllocateEphemeralPort ();
+  if (port == 0) 
+    {
+      return 0;
+    }
+  T *endPoint = new T (address, port);
+  endPoint->SetDestroyCallback (MakeCallback (&Ipv4EndPointDemux::DestroyEndPoint, this));
+  m_endPoints.push_back (endPoint);
+  return endPoint;
+}
+template <typename T>
+T *
+Ipv4EndPointDemux<T>::Allocate (Ipv4Address address, uint16_t port)
+{
+  if (LookupLocal (address, port)) 
+    {
+      return 0;
+    }
+  T *endPoint = new T (address, port);
+  endPoint->SetDestroyCallback (MakeCallback (&Ipv4EndPointDemux::DestroyEndPoint, this));
+  m_endPoints.push_back (endPoint);
+  return endPoint;
+}
+
+template <typename T>
+T *
+Ipv4EndPointDemux<T>::Allocate (Ipv4Address localAddress, uint16_t localPort,
+                                Ipv4Address peerAddress, uint16_t peerPort)
+{
+  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
+    {
+      if ((*i)->GetLocalPort () == localPort &&
+          (*i)->GetLocalAddress () == localAddress &&
+          (*i)->GetPeerPort () == peerPort &&
+          (*i)->GetPeerAddress () == peerAddress) 
+        {
+          /* no way we can allocate this end-point. */
+          return 0;
+        }
+    }
+  T *endPoint = new T (localAddress, localPort);
+  endPoint->SetPeer (peerAddress, peerPort);
+  endPoint->SetDestroyCallback (MakeCallback (&Ipv4EndPointDemux::DestroyEndPoint, this));
+  m_endPoints.push_back (endPoint);
+  return endPoint;
+}
+
+
+/*
+ * If we have an exact match, we return it.
+ * Otherwise, if we find a generic match, we return it.
+ * Otherwise, we return 0.
+ */
+template <typename T>
+T *
+Ipv4EndPointDemux<T>::Lookup (Ipv4Address daddr, uint16_t dport, 
+                              Ipv4Address saddr, uint16_t sport)
+{
+  uint32_t genericity = 3;
+  T *generic = 0;
+  //TRACE ("lookup " << daddr << ":" << dport << " " << saddr << ":" << sport);
+  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
+    {
+#if 0
+      TRACE ("against " << 
+             (*i)->GetLocalAddress ()
+             << ":" << 
+             (*i)->GetLocalPort () 
+             << " " << 
+             (*i)->GetPeerAddress () 
+             << ":" 
+             << (*i)->GetPeerPort ());
+#endif
+      if ((*i)->GetLocalPort () != dport) 
+        {
+          continue;
+        }
+      if ((*i)->GetLocalAddress () == daddr &&
+          (*i)->GetPeerPort () == sport &&
+          (*i)->GetPeerAddress () == saddr) 
+        {
+          /* this is an exact match. */
+          return *i;
+        }
+      uint32_t tmp = 0;
+      if ((*i)->GetLocalAddress () == Ipv4Address::GetAny ()) 
+        {
+          tmp ++;
+        }
+      if ((*i)->GetPeerAddress () == Ipv4Address::GetAny ()) 
+        {
+          tmp ++;
+        }
+      if (tmp < genericity) 
+        {
+          generic = (*i);
+          genericity = tmp;
+        }
+    }
+  return generic;
+}
+
+template <typename T>
+uint16_t
+Ipv4EndPointDemux<T>::AllocateEphemeralPort (void)
+{
+  uint16_t port = m_ephemeral;
+  do 
+    {
+      port++;
+      if (port > 5000) 
+        {
+          port = 1024;
+        }
+      if (!LookupPortLocal (port)) 
+        {
+          return port;
+        }
+  } while (port != m_ephemeral);
+  return 0;
+}
+
+
+
+}//namespace ns3
+
+
+#endif /* IPV4_END_POINTS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv4-end-point.cc	Fri Feb 09 19:40:19 2007 +0100
@@ -0,0 +1,63 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "ipv4-end-point.h"
+
+namespace ns3 {
+
+Ipv4EndPoint::Ipv4EndPoint (Ipv4Address address, uint16_t port)
+  : m_localAddr (address), 
+    m_localPort (port),
+    m_peerAddr (Ipv4Address::GetAny ()),
+    m_peerPort (0)
+{}
+Ipv4EndPoint::~Ipv4EndPoint ()
+{}
+
+Ipv4Address 
+Ipv4EndPoint::GetLocalAddress (void)
+{
+  return m_localAddr;
+}
+uint16_t 
+Ipv4EndPoint::GetLocalPort (void)
+{
+  return m_localPort;
+}
+Ipv4Address 
+Ipv4EndPoint::GetPeerAddress (void)
+{
+  return m_peerAddr;
+}
+uint16_t 
+Ipv4EndPoint::GetPeerPort (void)
+{
+  return m_peerPort;
+}
+void 
+Ipv4EndPoint::SetPeer (Ipv4Address address, uint16_t port)
+{
+  m_peerAddr = address;
+  m_peerPort = port;
+}
+
+
+}; // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv4-end-point.h	Fri Feb 09 19:40:19 2007 +0100
@@ -0,0 +1,54 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#ifndef IPV4_END_POINT_H
+#define IPV4_END_POINT_H
+
+#include <stdint.h>
+#include "ipv4-address.h"
+
+namespace ns3 {
+
+class Header;
+
+class Ipv4EndPoint {
+public:
+  Ipv4EndPoint (Ipv4Address address, uint16_t port);
+  ~Ipv4EndPoint ();
+
+  Ipv4Address GetLocalAddress (void);
+  uint16_t GetLocalPort (void);
+  Ipv4Address GetPeerAddress (void);
+  uint16_t GetPeerPort (void);
+
+  void SetPeer (Ipv4Address address, uint16_t port);
+
+private:
+  Ipv4Address m_localAddr;
+  uint16_t m_localPort;
+  Ipv4Address m_peerAddr;
+  uint16_t m_peerPort;
+};
+
+}; // namespace ns3
+
+
+#endif /* IPV4_END_POINT_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/udp-end-point.cc	Fri Feb 09 19:40:19 2007 +0100
@@ -0,0 +1,41 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "udp-end-point.h"
+
+namespace ns3 {
+
+UdpEndPoint::UdpEndPoint (Ipv4Address address, uint16_t port)
+  : Ipv4EndPoint (address, port),
+    m_socket (0)
+{}
+
+void 
+UdpEndPoint::SetSocket (UdpSocket *socket)
+{
+  m_socket = socket;
+}
+UdpSocket *
+UdpEndPoint::GetSocket (void) const
+{
+  return m_socket;
+}
+
+}//namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/udp-end-point.h	Fri Feb 09 19:40:19 2007 +0100
@@ -0,0 +1,45 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef UDP_END_POINT_H
+#define UDP_END_POINT_H
+
+#include <stdint.h>
+#include "ipv4-end-point.h"
+#include "ipv4-address.h"
+
+namespace ns3 {
+
+class UdpSocket;
+
+class UdpEndPoint : public Ipv4EndPoint
+{
+public:
+  UdpEndPoint (Ipv4Address address, uint16_t port);
+
+  void SetSocket (UdpSocket *socket);
+  UdpSocket *GetSocket (void) const;
+private:
+  UdpSocket *m_socket;
+};
+
+}//namespace ns3
+
+#endif /* UDP_END_POINT_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/udp.cc	Fri Feb 09 19:40:19 2007 +0100
@@ -0,0 +1,108 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include <cassert>
+#include "ns3/packet.h"
+#include "udp.h"
+#include "udp-header.h"
+#include "ipv4-end-point-demux.h"
+#include "udp-end-point.h"
+
+namespace ns3 {
+
+/* see http://www.iana.org/assignments/protocol-numbers */
+const uint8_t Udp::UDP_PROTOCOL = 17;
+
+Udp::Udp ()
+{
+  m_endPoints = new Ipv4EndPoints ();
+}
+
+Udp::~Udp ()
+{
+  delete m_endPoints;
+}
+
+UdpEndPoint *
+Udp::Allocate (void)
+{
+  return m_endPoints->Allocate ();
+}
+UdpEndPoint *
+Udp::Allocate (Ipv4Address address)
+{
+  return m_endPoints->Allocate (address);
+}
+UdpEndPoint *
+Udp::Allocate (Ipv4Address address, uint16_t port)
+{
+  return m_endPoints->Allocate (address, port);
+}
+UdpEndPoint *
+Udp::Allocate (Ipv4Address localAddress, uint16_t localPort,
+               Ipv4Address peerAddress, uint16_t peerPort)
+{
+  return m_endPoints->Allocate (localAddress, localPort,
+                                peerAddress, peerPort);
+}
+
+void 
+Udp::Receive(Packet& p, 
+             Ipv4Address const &source,
+             Ipv4Address const &destination)
+{
+  m_recvLogger (packet);
+  UdpHeader udpHeader;
+  packet.Peek (udpHeader);
+  packet.Remove (udpHeader);
+  UdpEndPoint *endPoint = m_endPoints->Lookup (destination, udpHeader.GetDestination (),
+                                               source, udpHeader.GetSource ());
+  if (endPoint == 0)
+    {
+      return;
+    }
+  UdpSocket *socket = endPoint->GetSocket (packet, &udpHeader);
+  assert (socket != 0);
+}
+
+void
+Udp::Send (Packet packet, 
+           Ipv4Address saddr, Ipv4Address daddr, 
+           uint16_t sport, uint16_t dport)
+{
+  UdpHeader udpHeader;
+  udpHeader.SetDestination (dport);
+  udpHeader.SetSource (sport);
+  udpHeader.SetPayloadSize (packet.GetSize ());
+  udpHeader.InitializeChecksum (saddr,
+                               daddr,
+                               UDP_PROTOCOL);
+
+  packet.Add (udpHeader);
+
+  //XXX
+  // Send to ipv4 layer.
+  ip.Send (p, saddr, daddr, UDP_PROTOCOL);
+}
+
+
+}; // namespace ns3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/udp.h	Fri Feb 09 19:40:19 2007 +0100
@@ -0,0 +1,60 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006,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 <mathieu.lacage@sophia.inria.fr>
+ */
+
+#ifndef UDP_H
+#define UDP_H
+
+#include <stdint.h>
+
+#include "ns3/ipv4-address.h"
+#include "ns3/packet.h"
+#include "ipv4-l4-protocol.h"
+#include "ipv4-end-point-demux.h"
+#include "udp-end-point.h"
+
+namespace ns3 {
+
+class Udp : public Ipv4L4Protocol {
+public:
+  Udp ();
+  virtual ~Udp ();
+
+  UdpEndPoint *Allocate (void);
+  UdpEndPoint *Allocate (Ipv4Address address);
+  UdpEndPoint *Allocate (Ipv4Address address, uint16_t port);
+  UdpEndPoint *Allocate (Ipv4Address localAddress, uint16_t localPort,
+                         Ipv4Address peerAddress, uint16_t peerPort);
+
+  void Send (Packet packet);
+  // inherited from Ipv4L4Protocol
+  virtual Ipv4L4Protocol* Copy() const;
+  virtual void Receive(Packet& p, 
+                       Ipv4Address const &source,
+                       Ipv4Address const &destination);
+ private:
+  static const uint8_t UDP_PROTOCOL;
+  //Ipv4 *m_ipv4;
+  Ipv4EndPointDemux<UdpEndPoint> *m_endPoints;
+};
+
+}; // namespace ns3
+
+#endif /* UDP_H */