--- a/SConstruct Thu Feb 08 16:01:58 2007 +0100
+++ b/SConstruct Fri Feb 09 17:54:49 2007 +0100
@@ -154,12 +154,16 @@
'ipv4-header.cc',
'udp-header.cc',
'ipv4-checksum.cc',
+ 'ipv4-route.cc',
+ 'ipv4-interface.cc',
+ 'ipv4-l3-protocol.cc',
])
node.add_headers ([
'ipv4-address.h',
'ipv4-header.h',
'udp-header.h',
'ipv4-checksum.h',
+ 'ipv4-l3-protocol.h',
])
node.add_inst_headers ([
'node.h',
@@ -172,6 +176,8 @@
'internet-node.h',
'net-device.h',
'mac-address.h',
+ 'ipv4-route.h',
+ 'ipv4-interface.h'
])
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv4-interface.cc Fri Feb 09 17:54:49 2007 +0100
@@ -0,0 +1,128 @@
+/* -*- 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>
+ */
+
+#include "ipv4-interface.h"
+#include "ipv4-address.h"
+#include "net-device.h"
+
+namespace ns3 {
+
+ /**
+ * By default, Ipv4 interface are created in the "down" state
+ * with ip address 192.168.0.1 and a matching mask. Before
+ * becoming useable, the user must invoke SetUp on them
+ * once the final Ipv4 address and mask has been set.
+ */
+Ipv4Interface::Ipv4Interface (NetDevice *nd)
+ : m_netdevice (nd),
+ m_ifup(false)
+{}
+
+Ipv4Interface::~Ipv4Interface ()
+{}
+
+NetDevice*
+Ipv4Interface::GetDevice (void) const
+{
+ return m_netdevice;
+}
+
+void
+Ipv4Interface::SetAddress (Ipv4Address a)
+{
+ m_address = a;
+}
+void
+Ipv4Interface::SetNetworkMask (Ipv4Mask mask)
+{
+ m_netmask = mask;
+}
+
+Ipv4Address
+Ipv4Interface::GetBroadcast (void) const
+{
+ uint32_t mask = m_netmask.GetHostOrder ();
+ uint32_t address = m_address.GetHostOrder ();
+ Ipv4Address broadcast = Ipv4Address (address | (~mask));
+ return broadcast;
+}
+Ipv4Mask
+Ipv4Interface::GetNetworkMask (void) const
+{
+ return m_netmask;
+}
+Ipv4Address
+Ipv4Interface::GetAddress (void) const
+{
+ return m_address;
+}
+
+uint16_t
+Ipv4Interface::GetMtu (void) const
+{
+ if (m_netdevice == 0)
+ {
+ uint32_t mtu = (1<<16) - 1;
+ return mtu;
+ }
+ return m_netdevice->GetMtu ();
+}
+
+ /**
+ * These are IP interface states and may be distinct from
+ * NetDevice states, such as found in real implementations
+ * (where the device may be down but IP interface state is still up).
+ */
+bool
+Ipv4Interface::IsUp (void) const
+{
+ return m_ifup;
+}
+
+bool
+Ipv4Interface::IsDown (void) const
+{
+ return !m_ifup;
+}
+
+void
+Ipv4Interface::SetUp (void)
+{
+ m_ifup = true;
+}
+
+void
+Ipv4Interface::SetDown (void)
+{
+ m_ifup = false;
+}
+
+// public wrapper on private virtual function
+void
+Ipv4Interface::Send(Packet p, Ipv4Address dest)
+{
+ if (IsUp()) {
+ SendTo(p, dest);
+ }
+}
+
+}; // namespace ns3
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv4-interface.h Fri Feb 09 17:54:49 2007 +0100
@@ -0,0 +1,107 @@
+/* -*- 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
+ *
+ * Authors:
+ * Mathieu Lacage <mathieu.lacage@sophia.inria.fr>,
+ * Tom Henderson <tomh@tomh.org>
+ */
+#ifndef IPV4_INTERFACE_H
+#define IPV4_INTERFACE_H
+
+#include <list>
+#include "ipv4-address.h"
+
+namespace ns3 {
+
+class NetDevice;
+class Packet;
+
+/**
+ * \brief The IPv4 representation of a network interface
+ *
+ * This class roughly corresponds to the struct in_device
+ * of Linux; the main purpose is to provide address-family
+ * specific information (addresses) about an interface.
+ *
+ * This class defines two APIs:
+ * - the public API which is expected to be used by both
+ * the IPv4 layer and the user during forwarding and
+ * configuration.
+ * - the private API which is expected to be implemented
+ * by subclasses of this base class. One such subclass
+ * will be a Loopback interface which loops every
+ * packet sent back to the ipv4 layer. Another such
+ * subclass typically contains the Ipv4 <-> MAC address
+ * translation logic which will use most of the time the
+ * ARP/RARP protocols.
+ */
+class Ipv4Interface
+{
+public:
+ /**
+ * By default, Ipv4 interface are created in the "down" state
+ * with ip address 192.168.0.1 and a matching mask. Before
+ * becoming useable, the user must invoke SetUp on them
+ * once the final Ipv4 address and mask has been set.
+ */
+ Ipv4Interface (NetDevice *nd);
+ virtual ~Ipv4Interface();
+
+ NetDevice *GetDevice (void) const;
+
+ void SetAddress (Ipv4Address a);
+ void SetNetworkMask (Ipv4Mask mask);
+
+ Ipv4Address GetBroadcast (void) const;
+ Ipv4Mask GetNetworkMask (void) const;
+ Ipv4Address GetAddress (void) const;
+
+ /**
+ * This function a pass-through to NetDevice GetMtu, modulo
+ * the LLC/SNAP header i.e., ipv4MTU = NetDeviceMtu - LLCSNAPSIZE
+ */
+ uint16_t GetMtu (void) const;
+
+ /**
+ * These are IP interface states and may be distinct from
+ * NetDevice states, such as found in real implementations
+ * (where the device may be down but IP interface state is still up).
+ */
+ bool IsUp (void) const;
+ bool IsDown (void) const;
+ void SetUp (void);
+ void SetDown (void);
+
+ /**
+ * Packet typically received from above will require some
+ * handling before calling SendTo()
+ */
+ void Send(Packet p, Ipv4Address dest);
+
+
+ private:
+ virtual void SendTo (Packet p, Ipv4Address dest) = 0;
+ NetDevice* m_netdevice;
+ bool m_ifup;
+ Ipv4Address m_address;
+ Ipv4Mask m_netmask;
+};
+
+}; // namespace ns3
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv4-l3-protocol.cc Fri Feb 09 17:54:49 2007 +0100
@@ -0,0 +1,437 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+// All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: George F. Riley<riley@ece.gatech.edu>
+//
+
+#include "ns3/packet.h"
+
+#include "ipv4-l3-protocol.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
+#include "node.h"
+#include "ipv4-l4-demux.h"
+
+#define TRACE(x)
+
+namespace ns3 {
+
+Ipv4L3Protocol::Ipv4L3Protocol()
+ : L3Protocol (0x0800, 4),
+ m_nInterfaces (0),
+ m_defaultTtl (64),
+ m_identification (0),
+ m_defaultRoute (0)
+{}
+Ipv4L3Protocol::Ipv4L3Protocol(Ipv4L3Protocol const &o)
+ : L3Protocol (o),
+ m_nInterfaces (0),
+ m_defaultTtl (o.m_defaultTtl),
+ m_identification (o.m_identification),
+ m_defaultRoute (0)
+{
+ // We do not copy the list of interfaces or the routes
+ // purposedly.
+}
+Ipv4L3Protocol::~Ipv4L3Protocol ()
+{
+ // 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++)
+ {
+ delete (*i);
+ }
+ for (HostRoutesI i = m_hostRoutes.begin ();
+ i != m_hostRoutes.end ();
+ i = m_hostRoutes.erase (i))
+ {
+ delete (*i);
+ }
+ for (NetworkRoutesI j = m_networkRoutes.begin ();
+ j != m_networkRoutes.end ();
+ j = m_networkRoutes.erase (j))
+ {
+ delete (*j);
+ }
+ delete m_defaultRoute;
+}
+
+void
+Ipv4L3Protocol::SetDefaultTtl (uint8_t ttl)
+{
+ m_defaultTtl = ttl;
+}
+
+
+void
+Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest,
+ Ipv4Address nextHop,
+ uint32_t interface)
+{
+ Ipv4Route *route = new Ipv4Route ();
+ *route = Ipv4Route::CreateHostRouteTo (dest, nextHop, interface);
+ m_hostRoutes.push_back (route);
+}
+void
+Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest,
+ uint32_t interface)
+{
+ Ipv4Route *route = new Ipv4Route ();
+ *route = Ipv4Route::CreateHostRouteTo (dest, interface);
+ m_hostRoutes.push_back (route);
+}
+void
+Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ Ipv4Address nextHop,
+ uint32_t interface)
+{
+ Ipv4Route *route = new Ipv4Route ();
+ *route = Ipv4Route::CreateNetworkRouteTo (network,
+ networkMask,
+ nextHop,
+ interface);
+ m_networkRoutes.push_back (route);
+}
+void
+Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ uint32_t interface)
+{
+ Ipv4Route *route = new Ipv4Route ();
+ *route = Ipv4Route::CreateNetworkRouteTo (network,
+ networkMask,
+ interface);
+ m_networkRoutes.push_back (route);
+}
+void
+Ipv4L3Protocol::SetDefaultRoute (Ipv4Address nextHop,
+ uint32_t interface)
+{
+ Ipv4Route *route = new Ipv4Route ();
+ *route = Ipv4Route::CreateDefaultRoute (nextHop, interface);
+ delete m_defaultRoute;
+ m_defaultRoute = route;
+}
+
+Ipv4Route *
+Ipv4L3Protocol::Lookup (Ipv4Address dest)
+{
+ for (HostRoutesCI i = m_hostRoutes.begin ();
+ i != m_hostRoutes.end ();
+ i++)
+ {
+ assert ((*i)->IsHost ());
+ if ((*i)->GetDest ().IsEqual (dest))
+ {
+ return (*i);
+ }
+ }
+ for (NetworkRoutesI j = m_networkRoutes.begin ();
+ j != m_networkRoutes.end ();
+ j++)
+ {
+ assert ((*j)->IsNetwork ());
+ Ipv4Mask mask = (*j)->GetDestNetworkMask ();
+ Ipv4Address entry = (*j)->GetDestNetwork ();
+ if (mask.IsMatch (dest, entry))
+ {
+ return (*j);
+ }
+ }
+ if (m_defaultRoute != 0)
+ {
+ assert (m_defaultRoute->IsDefault ());
+ return m_defaultRoute;
+ }
+ return 0;
+}
+
+uint32_t
+Ipv4L3Protocol::GetNRoutes (void)
+{
+ uint32_t n = 0;
+ if (m_defaultRoute != 0)
+ {
+ n++;
+ }
+ n += m_hostRoutes.size ();
+ n += m_networkRoutes.size ();
+ return n;
+}
+Ipv4Route *
+Ipv4L3Protocol::GetRoute (uint32_t index)
+{
+ if (index == 0 && m_defaultRoute != 0)
+ {
+ return m_defaultRoute;
+ }
+ index--;
+ if (index < m_hostRoutes.size ())
+ {
+ uint32_t tmp = 0;
+ for (HostRoutesCI i = m_hostRoutes.begin ();
+ i != m_hostRoutes.end ();
+ i++)
+ {
+ if (tmp == index)
+ {
+ return *i;
+ }
+ tmp++;
+ }
+ }
+ index -= m_hostRoutes.size ();
+ uint32_t tmp = 0;
+ for (NetworkRoutesI j = m_networkRoutes.begin ();
+ j != m_networkRoutes.end ();
+ j++)
+ {
+ if (tmp == index)
+ {
+ return *j;
+ }
+ tmp++;
+ }
+ assert (false);
+ // quiet compiler.
+ return 0;
+}
+void
+Ipv4L3Protocol::RemoveRoute (uint32_t index)
+{
+ if (index == 0 && m_defaultRoute != 0)
+ {
+ delete m_defaultRoute;
+ m_defaultRoute = 0;
+ }
+ index--;
+ if (index < m_hostRoutes.size ())
+ {
+ uint32_t tmp = 0;
+ for (HostRoutesI i = m_hostRoutes.begin ();
+ i != m_hostRoutes.end ();
+ i++)
+ {
+ if (tmp == index)
+ {
+ delete *i;
+ m_hostRoutes.erase (i);
+ return;
+ }
+ tmp++;
+ }
+ }
+ index -= m_hostRoutes.size ();
+ uint32_t tmp = 0;
+ for (NetworkRoutesI j = m_networkRoutes.begin ();
+ j != m_networkRoutes.end ();
+ j++)
+ {
+ if (tmp == index)
+ {
+ delete *j;
+ m_networkRoutes.erase (j);
+ return;
+ }
+ tmp++;
+ }
+ assert (false);
+}
+
+
+uint32_t
+Ipv4L3Protocol::AddInterface (Ipv4Interface *interface)
+{
+ uint32_t index = m_nInterfaces;
+ m_interfaces.push_back (interface);
+ m_nInterfaces++;
+ return index;
+}
+Ipv4Interface *
+Ipv4L3Protocol::GetInterface (uint32_t index)
+{
+ uint32_t tmp = 0;
+ for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
+ {
+ if (index == tmp)
+ {
+ return *i;
+ }
+ tmp++;
+ }
+ return 0;
+}
+uint32_t
+Ipv4L3Protocol::GetNInterfaces (void) const
+{
+ return m_nInterfaces;
+}
+
+
+
+Ipv4L3Protocol*
+Ipv4L3Protocol::Copy() const
+{
+ return new Ipv4L3Protocol (*this);
+}
+void
+Ipv4L3Protocol::Receive(Packet& packet, NetDevice &device)
+{
+ // XXX trace here.
+ Ipv4Header ipHeader;
+ packet.Peek (ipHeader);
+ packet.Remove (ipHeader);
+
+ if (!ipHeader.IsChecksumOk ())
+ {
+ return;
+ }
+
+ if (Forwarding (packet, ipHeader, device))
+ {
+ return;
+ }
+
+ ForwardUp (packet, ipHeader);
+}
+
+void
+Ipv4L3Protocol::Send (Packet const &packet,
+ Ipv4Address source,
+ Ipv4Address destination,
+ uint8_t protocol)
+{
+ Ipv4Header ipHeader;
+
+ ipHeader.SetSource (source);
+ ipHeader.SetDestination (destination);
+ ipHeader.SetProtocol (protocol);
+ ipHeader.SetPayloadSize (packet.GetSize ());
+ ipHeader.SetTtl (m_defaultTtl);
+ ipHeader.SetMayFragment ();
+ ipHeader.SetIdentification (m_identification);
+
+ m_identification ++;
+
+ // XXX Note here that in most ipv4 stacks in the world,
+ // the route calculation for an outgoing packet is not
+ // done in the ip layer. It is done within the application
+ // socket when the first packet is sent to avoid this
+ // costly lookup on a per-packet basis.
+ // That would require us to get the route from the packet,
+ // most likely with a packet tag. The higher layers do not
+ // do this yet for us.
+ Ipv4Route *route = Lookup (ipHeader.GetDestination ());
+ if (route == 0)
+ {
+ TRACE ("not for me -- forwarding but no route to host. drop.");
+ return;
+ }
+
+ SendRealOut (packet, ipHeader, *route);
+}
+
+void
+Ipv4L3Protocol::SendRealOut (Packet const &p, Ipv4Header const &ip, Ipv4Route const &route)
+{
+ Packet packet = p;
+ packet.Add (ip);
+ Ipv4Interface *outInterface = GetInterface (route.GetInterface ());
+ assert (packet.GetSize () <= outInterface->GetMtu ());
+ // XXX log trace here.
+ if (route.IsGateway ())
+ {
+ outInterface->Send (packet, route.GetGateway ());
+ }
+ else
+ {
+ outInterface->Send (packet, ip.GetDestination ());
+ }
+}
+
+
+bool
+Ipv4L3Protocol::Forwarding (Packet const &packet, Ipv4Header &ipHeader, NetDevice &device)
+{
+ for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
+ i != m_interfaces.end (); i++)
+ {
+ if ((*i)->GetAddress ().IsEqual (ipHeader.GetDestination ()))
+ {
+ TRACE ("for me 1");
+ return false;
+ }
+ }
+
+ for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
+ i != m_interfaces.end (); i++)
+ {
+ Ipv4Interface *interface = *i;
+ if (interface->GetDevice () == &device)
+ {
+ if (ipHeader.GetDestination ().IsEqual (interface->GetBroadcast ()))
+ {
+ TRACE ("for me 2");
+ return false;
+ }
+ break;
+ }
+ }
+
+ if (ipHeader.GetDestination ().IsEqual (Ipv4Address::GetBroadcast ()))
+ {
+ TRACE ("for me 3");
+ return false;
+ }
+ if (ipHeader.GetDestination ().IsEqual (Ipv4Address::GetAny ()))
+ {
+ TRACE ("for me 4");
+ return false;
+ }
+ if (ipHeader.GetTtl () == 1)
+ {
+ // Should send ttl expired here
+ // XXX
+ TRACE ("not for me -- ttl expired. drop.");
+ return true;
+ }
+ ipHeader.SetTtl (ipHeader.GetTtl () - 1);
+ Ipv4Route *route = Lookup (ipHeader.GetDestination ());
+ if (route == 0)
+ {
+ TRACE ("not for me -- forwarding but no route to host. drop.");
+ return true;
+ }
+ TRACE ("not for me -- forwarding.");
+ SendRealOut (packet, ipHeader, *route);
+ return true;
+}
+
+
+void
+Ipv4L3Protocol::ForwardUp (Packet p, Ipv4Header const&ip)
+{
+ Ipv4L4Protocol *protocol = m_node->GetIpv4L4Demux ()->Lookup (ip.GetProtocol ());
+ protocol->Receive (p, ip.GetSource (), ip.GetDestination ());
+}
+
+}//namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv4-l3-protocol.h Fri Feb 09 17:54:49 2007 +0100
@@ -0,0 +1,129 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+// All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Author: George F. Riley<riley@ece.gatech.edu>
+//
+
+#ifndef IPV4_L3_PROTOCOL_H
+#define IPV4_L3_PROTOCOL_H
+
+#include <list>
+#include <stdint.h>
+#include "l3-protocol.h"
+#include "ipv4-address.h"
+
+namespace ns3 {
+
+class Packet;
+class NetDevice;
+class Ipv4Interface;
+class Ipv4Address;
+class Ipv4Header;
+class Ipv4Route;
+class Node;
+
+
+/**
+ * ::Send is always defined in subclasses.
+ */
+class Ipv4L3Protocol : public L3Protocol {
+public:
+ Ipv4L3Protocol();
+ Ipv4L3Protocol(Ipv4L3Protocol const &o);
+ virtual ~Ipv4L3Protocol ();
+
+ void SetDefaultTtl (uint8_t ttl);
+
+ /* add route to host dest through host nextHop
+ * on interface.
+ */
+ void AddHostRouteTo (Ipv4Address dest,
+ Ipv4Address nextHop,
+ uint32_t interface);
+ /* add route to host dest on interface.
+ */
+ void AddHostRouteTo (Ipv4Address dest,
+ uint32_t interface);
+ /* add route to network dest with netmask
+ * through host nextHop on interface
+ */
+ void AddNetworkRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ Ipv4Address nextHop,
+ uint32_t interface);
+ /* add route to network dest with netmask
+ * on interface
+ */
+ void AddNetworkRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ uint32_t interface);
+ /* set the default route to host nextHop on
+ * interface.
+ */
+ void SetDefaultRoute (Ipv4Address nextHop,
+ uint32_t interface);
+
+ Ipv4Route *Lookup (Ipv4Address dest);
+
+ uint32_t GetNRoutes (void);
+ Ipv4Route *GetRoute (uint32_t i);
+ void RemoveRoute (uint32_t i);
+
+ uint32_t AddInterface (Ipv4Interface *interface);
+ Ipv4Interface * GetInterface (uint32_t i);
+ uint32_t GetNInterfaces (void) const;
+
+
+ virtual Ipv4L3Protocol* Copy() const;
+ /**
+ * 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, NetDevice &device);
+
+ private:
+ void Send (Packet const &packet, Ipv4Address source,
+ Ipv4Address destination, uint8_t protocol);
+ void SendRealOut (Packet const &packet, Ipv4Header const &ip, Ipv4Route const &route);
+ bool Forwarding (Packet const &packet, Ipv4Header &ipHeader, NetDevice &device);
+ void ForwardUp (Packet p, Ipv4Header const&ip);
+
+ typedef std::list<Ipv4Interface*> Ipv4InterfaceList;
+ typedef std::list<Ipv4Route *> HostRoutes;
+ typedef std::list<Ipv4Route *>::const_iterator HostRoutesCI;
+ typedef std::list<Ipv4Route *>::iterator HostRoutesI;
+ typedef std::list<Ipv4Route *> NetworkRoutes;
+ typedef std::list<Ipv4Route *>::const_iterator NetworkRoutesCI;
+ typedef std::list<Ipv4Route *>::iterator NetworkRoutesI;
+
+ Ipv4InterfaceList m_interfaces;
+ uint32_t m_nInterfaces;
+ uint8_t m_defaultTtl;
+ uint16_t m_identification;
+ HostRoutes m_hostRoutes;
+ NetworkRoutes m_networkRoutes;
+ Ipv4Route *m_defaultRoute;
+ Node *m_node;
+};
+
+} // Namespace ns3
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv4-route.cc Fri Feb 09 17:54:49 2007 +0100
@@ -0,0 +1,223 @@
+/* -*- 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-route.h"
+#include <cassert>
+
+namespace ns3 {
+
+/*****************************************************
+ * Network Ipv4Route
+ *****************************************************/
+
+Ipv4Route::Ipv4Route ()
+{}
+Ipv4Route::Ipv4Route (Ipv4Route const &route)
+ : m_dest (route.m_dest),
+ m_destNetworkMask (route.m_destNetworkMask),
+ m_gateway (route.m_gateway),
+ m_interface (route.m_interface)
+{}
+
+Ipv4Route::Ipv4Route (Ipv4Address dest,
+ Ipv4Address gateway,
+ uint32_t interface)
+ : m_dest (dest),
+ m_destNetworkMask (Ipv4Mask::GetZero ()),
+ m_gateway (gateway),
+ m_interface (interface)
+{}
+Ipv4Route::Ipv4Route (Ipv4Address dest,
+ uint32_t interface)
+ : m_dest (dest),
+ m_destNetworkMask (Ipv4Mask::GetZero ()),
+ m_gateway (Ipv4Address::GetZero ()),
+ m_interface (interface)
+{}
+Ipv4Route::Ipv4Route (Ipv4Address network,
+ Ipv4Mask networkMask,
+ Ipv4Address gateway,
+ uint32_t interface)
+ : m_dest (network),
+ m_destNetworkMask (networkMask),
+ m_gateway (gateway),
+ m_interface (interface)
+{}
+Ipv4Route::Ipv4Route (Ipv4Address network,
+ Ipv4Mask networkMask,
+ uint32_t interface)
+ : m_dest (network),
+ m_destNetworkMask (networkMask),
+ m_gateway (Ipv4Address::GetZero ()),
+ m_interface (interface)
+{}
+
+bool
+Ipv4Route::IsHost (void) const
+{
+ if (m_destNetworkMask.IsEqual (Ipv4Mask::GetZero ()))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+Ipv4Address
+Ipv4Route::GetDest (void) const
+{
+ return m_dest;
+}
+bool
+Ipv4Route::IsNetwork (void) const
+{
+ return !IsHost ();
+}
+bool
+Ipv4Route::IsDefault (void) const
+{
+ if (m_dest.IsEqual (Ipv4Address::GetZero ()))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+Ipv4Address
+Ipv4Route::GetDestNetwork (void) const
+{
+ return m_dest;
+}
+Ipv4Mask
+Ipv4Route::GetDestNetworkMask (void) const
+{
+ return m_destNetworkMask;
+}
+bool
+Ipv4Route::IsGateway (void) const
+{
+ if (m_gateway.IsEqual (Ipv4Address::GetZero ()))
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+}
+Ipv4Address
+Ipv4Route::GetGateway (void) const
+{
+ return m_gateway;
+}
+uint32_t
+Ipv4Route::GetInterface (void) const
+{
+ return m_interface;
+}
+
+
+Ipv4Route
+Ipv4Route::CreateHostRouteTo (Ipv4Address dest,
+ Ipv4Address nextHop,
+ uint32_t interface)
+{
+ return Ipv4Route (dest, nextHop, interface);
+}
+Ipv4Route
+Ipv4Route::CreateHostRouteTo (Ipv4Address dest,
+ uint32_t interface)
+{
+ return Ipv4Route (dest, interface);
+}
+Ipv4Route
+Ipv4Route::CreateNetworkRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ Ipv4Address nextHop,
+ uint32_t interface)
+{
+ return Ipv4Route (network, networkMask,
+ nextHop, interface);
+}
+Ipv4Route
+Ipv4Route::CreateNetworkRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ uint32_t interface)
+{
+ return Ipv4Route (network, networkMask,
+ interface);
+}
+Ipv4Route
+Ipv4Route::CreateDefaultRoute (Ipv4Address nextHop,
+ uint32_t interface)
+{
+ return Ipv4Route (Ipv4Address::GetZero (), nextHop, interface);
+}
+
+
+std::ostream& operator<< (std::ostream& os, Ipv4Route const& route)
+{
+ if (route.IsDefault ())
+ {
+ assert (route.IsGateway ());
+ os << "default out=" << route.GetInterface () << ", next hop=" << route.GetGateway ();
+ }
+ else if (route.IsHost ())
+ {
+ if (route.IsGateway ())
+ {
+ os << "host="<< route.GetDest () <<
+ ", out=" << route.GetInterface () <<
+ ", next hop=" << route.GetGateway ();
+ }
+ else
+ {
+ os << "host="<< route.GetDest () <<
+ ", out=" << route.GetInterface ();
+ }
+ }
+ else if (route.IsNetwork ())
+ {
+ if (route.IsGateway ())
+ {
+ os << "network=" << route.GetDestNetwork () <<
+ ", mask=" << route.GetDestNetworkMask () <<
+ ",out=" << route.GetInterface () <<
+ ", next hop=" << route.GetGateway ();
+ }
+ else
+ {
+ os << "network=" << route.GetDestNetwork () <<
+ ", mask=" << route.GetDestNetworkMask () <<
+ ",out=" << route.GetInterface ();
+ }
+ }
+ else
+ {
+ assert (false);
+ }
+ return os;
+}
+
+}//namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv4-route.h Fri Feb 09 17:54:49 2007 +0100
@@ -0,0 +1,89 @@
+/* -*- 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_ROUTE_H
+#define IPV4_ROUTE_H
+
+#include <list>
+#include <ostream>
+
+#include "ipv4-address.h"
+
+namespace ns3 {
+
+class Ipv4Route {
+public:
+ Ipv4Route ();
+ Ipv4Route (Ipv4Route const &route);
+
+ bool IsHost (void) const;
+ Ipv4Address GetDest (void) const;
+
+ bool IsNetwork (void) const;
+ Ipv4Address GetDestNetwork (void) const;
+ Ipv4Mask GetDestNetworkMask (void) const;
+
+ bool IsDefault (void) const;
+
+ bool IsGateway (void) const;
+ Ipv4Address GetGateway (void) const;
+
+ uint32_t GetInterface (void) const;
+
+ static Ipv4Route CreateHostRouteTo (Ipv4Address dest,
+ Ipv4Address nextHop,
+ uint32_t interface);
+ static Ipv4Route CreateHostRouteTo (Ipv4Address dest,
+ uint32_t interface);
+ static Ipv4Route CreateNetworkRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ Ipv4Address nextHop,
+ uint32_t interface);
+ static Ipv4Route CreateNetworkRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ uint32_t interface);
+ static Ipv4Route CreateDefaultRoute (Ipv4Address nextHop,
+ uint32_t interface);
+
+private:
+ Ipv4Route (Ipv4Address network,
+ Ipv4Mask mask,
+ Ipv4Address gateway,
+ uint32_t interface);
+ Ipv4Route (Ipv4Address dest,
+ Ipv4Mask mask,
+ uint32_t interface);
+ Ipv4Route (Ipv4Address dest,
+ Ipv4Address gateway,
+ uint32_t interface);
+ Ipv4Route (Ipv4Address dest,
+ uint32_t interface);
+
+ Ipv4Address m_dest;
+ Ipv4Mask m_destNetworkMask;
+ Ipv4Address m_gateway;
+ uint32_t m_interface;
+};
+
+std::ostream& operator<< (std::ostream& os, Ipv4Route const& route);
+
+}//namespace ns3
+
+#endif /* IPV4_ROUTE_H */
--- a/src/node/l3-protocol.cc Thu Feb 08 16:01:58 2007 +0100
+++ b/src/node/l3-protocol.cc Fri Feb 09 17:54:49 2007 +0100
@@ -31,6 +31,10 @@
: m_protocolNumber (protocolNumber),
m_version (version)
{}
+L3Protocol::L3Protocol (L3Protocol const &o)
+ : m_protocolNumber (o.m_protocolNumber),
+ m_version (o.m_version)
+{}
L3Protocol::~L3Protocol ()
{}
--- a/src/node/l3-protocol.h Thu Feb 08 16:01:58 2007 +0100
+++ b/src/node/l3-protocol.h Fri Feb 09 17:54:49 2007 +0100
@@ -37,6 +37,7 @@
class L3Protocol {
public:
L3Protocol(int protocolNumber, int version);
+ L3Protocol (L3Protocol const &o);
virtual ~L3Protocol ();
int GetProtocolNumber (void) const;