diff --git a/SConstruct b/SConstruct index 1c06f59c7..cbd353723 100644 --- a/SConstruct +++ b/SConstruct @@ -154,12 +154,16 @@ node.add_sources ([ '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 @@ node.add_inst_headers ([ 'internet-node.h', 'net-device.h', 'mac-address.h', + 'ipv4-route.h', + 'ipv4-interface.h' ]) diff --git a/src/node/ipv4-interface.cc b/src/node/ipv4-interface.cc new file mode 100644 index 000000000..1f4f01e5e --- /dev/null +++ b/src/node/ipv4-interface.cc @@ -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 + */ + +#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 + diff --git a/src/node/ipv4-interface.h b/src/node/ipv4-interface.h new file mode 100644 index 000000000..c74b57890 --- /dev/null +++ b/src/node/ipv4-interface.h @@ -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 , + * Tom Henderson + */ +#ifndef IPV4_INTERFACE_H +#define IPV4_INTERFACE_H + +#include +#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 diff --git a/src/node/ipv4-l3-protocol.cc b/src/node/ipv4-l3-protocol.cc new file mode 100644 index 000000000..407bff183 --- /dev/null +++ b/src/node/ipv4-l3-protocol.cc @@ -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 +// + +#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 diff --git a/src/node/ipv4-l3-protocol.h b/src/node/ipv4-l3-protocol.h new file mode 100644 index 000000000..9596eb2b1 --- /dev/null +++ b/src/node/ipv4-l3-protocol.h @@ -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 +// + +#ifndef IPV4_L3_PROTOCOL_H +#define IPV4_L3_PROTOCOL_H + +#include +#include +#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 Ipv4InterfaceList; + typedef std::list HostRoutes; + typedef std::list::const_iterator HostRoutesCI; + typedef std::list::iterator HostRoutesI; + typedef std::list NetworkRoutes; + typedef std::list::const_iterator NetworkRoutesCI; + typedef std::list::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 diff --git a/src/node/ipv4-l4-protocol.h b/src/node/ipv4-l4-protocol.h old mode 100755 new mode 100644 diff --git a/src/node/ipv4-route.cc b/src/node/ipv4-route.cc new file mode 100644 index 000000000..35afc4a88 --- /dev/null +++ b/src/node/ipv4-route.cc @@ -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 + */ + +#include "ipv4-route.h" +#include + +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 diff --git a/src/node/ipv4-route.h b/src/node/ipv4-route.h new file mode 100644 index 000000000..ce24357ef --- /dev/null +++ b/src/node/ipv4-route.h @@ -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 + */ +#ifndef IPV4_ROUTE_H +#define IPV4_ROUTE_H + +#include +#include + +#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 */ diff --git a/src/node/l3-protocol.cc b/src/node/l3-protocol.cc index 241647bb9..f4f7da6ae 100644 --- a/src/node/l3-protocol.cc +++ b/src/node/l3-protocol.cc @@ -31,6 +31,10 @@ L3Protocol::L3Protocol(int protocolNumber, int version) : m_protocolNumber (protocolNumber), m_version (version) {} +L3Protocol::L3Protocol (L3Protocol const &o) + : m_protocolNumber (o.m_protocolNumber), + m_version (o.m_version) +{} L3Protocol::~L3Protocol () {} diff --git a/src/node/l3-protocol.h b/src/node/l3-protocol.h index 4dd3f8470..8148b3c73 100644 --- a/src/node/l3-protocol.h +++ b/src/node/l3-protocol.h @@ -37,6 +37,7 @@ class NetDevice; class L3Protocol { public: L3Protocol(int protocolNumber, int version); + L3Protocol (L3Protocol const &o); virtual ~L3Protocol (); int GetProtocolNumber (void) const;