a basic untested ipv4 implementation
This commit is contained in:
128
src/node/ipv4-interface.cc
Normal file
128
src/node/ipv4-interface.cc
Normal file
@@ -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
|
||||
|
||||
107
src/node/ipv4-interface.h
Normal file
107
src/node/ipv4-interface.h
Normal file
@@ -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
|
||||
437
src/node/ipv4-l3-protocol.cc
Normal file
437
src/node/ipv4-l3-protocol.cc
Normal file
@@ -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
|
||||
129
src/node/ipv4-l3-protocol.h
Normal file
129
src/node/ipv4-l3-protocol.h
Normal file
@@ -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
|
||||
0
src/node/ipv4-l4-protocol.h
Executable file → Normal file
0
src/node/ipv4-l4-protocol.h
Executable file → Normal file
223
src/node/ipv4-route.cc
Normal file
223
src/node/ipv4-route.cc
Normal file
@@ -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
|
||||
89
src/node/ipv4-route.h
Normal file
89
src/node/ipv4-route.h
Normal file
@@ -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 */
|
||||
@@ -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 ()
|
||||
{}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ class NetDevice;
|
||||
class L3Protocol {
|
||||
public:
|
||||
L3Protocol(int protocolNumber, int version);
|
||||
L3Protocol (L3Protocol const &o);
|
||||
virtual ~L3Protocol ();
|
||||
|
||||
int GetProtocolNumber (void) const;
|
||||
|
||||
Reference in New Issue
Block a user