18#include "ns3/assert.h"
23#include "ns3/random-variable-stream.h"
24#include "ns3/uinteger.h"
28#define RIP_ALL_NODE "224.0.0.9"
40 m_splitHorizonStrategy(
Rip::POISON_REVERSE),
56 .SetGroupName(
"Internet")
57 .AddConstructor<
Rip>()
58 .AddAttribute(
"UnsolicitedRoutingUpdate",
59 "The time between two Unsolicited Routing Updates.",
63 .AddAttribute(
"StartupDelay",
64 "Maximum random delay for protocol startup (send route requests).",
68 .AddAttribute(
"TimeoutDelay",
69 "The delay to invalidate a route.",
73 .AddAttribute(
"GarbageCollectionDelay",
74 "The delay to delete an expired route.",
78 .AddAttribute(
"MinTriggeredCooldown",
79 "Min cooldown delay after a Triggered Update.",
83 .AddAttribute(
"MaxTriggeredCooldown",
84 "Max cooldown delay after a Triggered Update.",
88 .AddAttribute(
"SplitHorizon",
89 "Split Horizon strategy.",
98 .AddAttribute(
"LinkDownValue",
99 "Value for link down in count to infinity.",
111 m_rng->SetStream(stream);
140 m_ipv4->SetForwarding(
i,
true);
148 NS_LOG_LOGIC(
"RIP: adding socket to " << address.GetLocal());
153 socket->BindToNetDevice(
m_ipv4->GetNetDevice(
i));
158 socket->SetIpRecvTtl(
true);
159 socket->SetRecvPktInfo(
true);
274 NS_LOG_LOGIC(
"Dropping packet not for me and with dst Broadcast");
298 NS_LOG_LOGIC(
"Found unicast destination - calling unicast callback");
304 NS_LOG_LOGIC(
"Did not find unicast destination - returning false");
340 if (
iter->second ==
i)
351 m_ipv4->SetForwarding(
i,
true);
360 NS_LOG_LOGIC(
"RIP: adding sending socket to " << address.GetLocal());
365 socket->BindToNetDevice(
m_ipv4->GetNetDevice(
i));
368 socket->SetIpRecvTtl(
true);
369 socket->SetRecvPktInfo(
true);
400 if (
it->first->GetInterface() == interface)
408 NS_LOG_INFO(
"Checking socket for interface " << interface);
409 if (
iter->second == interface)
411 NS_LOG_INFO(
"Removed socket for interface " << interface);
412 iter->first->Close();
429 if (!
m_ipv4->IsUp(interface))
455 if (!
m_ipv4->IsUp(interface))
472 if (
it->first->GetInterface() ==
interface &&
it->first->IsNetwork() &&
495 for (
i = 0;
i <
m_ipv4->GetNInterfaces();
i++)
513 std::ostream* os = stream->GetStream();
518 *os << std::resetiosflags(std::ios::adjustfield) << std::setiosflags(std::ios::left);
520 *os <<
"Node: " <<
m_ipv4->GetObject<
Node>()->GetId() <<
", Time: " <<
Now().
As(unit)
521 <<
", Local time: " <<
m_ipv4->GetObject<
Node>()->GetLocalTime().As(unit)
522 <<
", IPv4 RIP table" << std::endl;
526 *os <<
"Destination Gateway Genmask Flags Metric Ref Use Iface"
535 std::ostringstream
dest;
536 std::ostringstream
gw;
537 std::ostringstream mask;
538 std::ostringstream flags;
540 *os << std::setw(16) <<
dest.str();
542 *os << std::setw(16) <<
gw.str();
543 mask <<
route->GetDestNetworkMask();
544 *os << std::setw(16) << mask.str();
550 else if (
route->IsGateway())
554 *os << std::setw(6) << flags.str();
555 *os << std::setw(7) << int(
route->GetRouteMetric());
568 *os <<
route->GetInterface();
597 iter->first->Close();
621 "Try to send on local multicast address, and no interface index is given!");
624 m_ipv4->SourceAddressSelection(
m_ipv4->GetInterfaceForDevice(interface), dst));
627 rtentry->SetOutputDevice(interface);
648 if (!interface || interface ==
m_ipv4->GetNetDevice(
j->GetInterface()))
664 if (
route->GetDest().IsAny())
687 <<
rtentry->GetGateway() <<
") at the end");
701 route->SetRouteMetric(1);
703 route->SetRouteChanged(
true);
714 route->SetRouteMetric(1);
716 route->SetRouteChanged(
true);
732 route->SetRouteChanged(
true);
733 if (
it->second.IsPending())
742 NS_ABORT_MSG(
"RIP::InvalidateRoute - cannot find the route to update");
759 NS_ABORT_MSG(
"RIP::DeleteRoute - cannot find the route to delete");
778 NS_LOG_LOGIC(
"Received a packet from the multicast socket");
782 NS_LOG_LOGIC(
"Received a packet from one of the unicast sockets");
788 NS_ABORT_MSG(
"No incoming interface on RIP message, aborting.");
798 NS_ABORT_MSG(
"No incoming Hop Count on RIP message, aborting.");
810 packet->RemoveHeader(
hdr);
826 NS_LOG_LOGIC(
"Ignoring message with unknown command: " <<
int(
hdr.GetCommand()));
848 if (
rtes.size() == 1)
851 rtes.begin()->GetSubnetMask().GetPrefixLength() == 0 &&
869 "HandleRequest - Impossible to find a socket to send the reply");
879 p->RemovePacketTag(
tag);
888 p->AddPacketTag(
tag);
899 rtIter->first->GetDestNetworkMask());
912 rte.SetSubnetMask(
rtIter->first->GetDestNetworkMask());
919 rte.SetRouteMetric(
rtIter->first->GetRouteMetric());
921 rte.SetRouteTag(
rtIter->first->GetRouteTag());
933 p->RemoveHeader(
hdr);
937 if (
hdr.GetRteNumber() > 0)
952 p->RemovePacketTag(
tag);
961 p->AddPacketTag(
tag);
973 rtIter->first->GetDestNetworkMask());
984 iter->SetRouteMetric(
rtIter->first->GetRouteMetric());
985 iter->SetRouteTag(
rtIter->first->GetRouteTag());
995 iter->SetRouteTag(0);
1016 "Ignoring an update message from an excluded interface: " <<
incomingInterface);
1020 std::list<RipRte>
rtes =
hdr.GetRteList();
1027 NS_LOG_LOGIC(
"Ignoring an update message with malformed metric: "
1028 <<
int(
iter->GetRouteMetric()));
1031 if (
iter->GetPrefix().IsLocalhost() ||
iter->GetPrefix().IsBroadcast() ||
1032 iter->GetPrefix().IsMulticast())
1034 NS_LOG_LOGIC(
"Ignoring an update message with wrong prefixes: " <<
iter->GetPrefix());
1063 if (
it->first->GetDestNetwork() ==
rteAddr &&
1080 it->first->SetRouteTag(
iter->GetRouteTag());
1081 it->first->SetRouteChanged(
true);
1082 it->second.Cancel();
1087 else if (
rteMetric ==
it->first->GetRouteMetric())
1091 it->second.Cancel();
1107 route->SetRouteTag(
iter->GetRouteTag());
1108 route->SetRouteChanged(
true);
1111 it->second.Cancel();
1120 else if (
rteMetric >
it->first->GetRouteMetric() &&
1123 it->second.Cancel();
1128 it->first->SetRouteTag(
iter->GetRouteTag());
1129 it->first->SetRouteChanged(
true);
1130 it->second.Cancel();
1146 NS_LOG_LOGIC(
"Received a RTE with new route, adding.");
1152 route->SetRouteChanged(
true);
1178 uint16_t
mtu =
m_ipv4->GetMtu(interface);
1186 p->AddPacketTag(
tag);
1196 rtIter->first->GetDestNetworkMask());
1199 <<
int(
rtIter->first->IsRouteChanged()));
1205 (
rtIter->first->GetInterface() != interface));
1208 for (
uint32_t index = 0; index <
m_ipv4->GetNAddresses(interface); index++)
1212 rtIter->first->GetDestNetwork())
1223 rte.SetSubnetMask(
rtIter->first->GetDestNetworkMask());
1230 rte.SetRouteMetric(
rtIter->first->GetRouteMetric());
1232 rte.SetRouteTag(
rtIter->first->GetRouteTag());
1244 p->RemoveHeader(
hdr);
1248 if (
hdr.GetRteNumber() > 0)
1258 rtIter->first->SetRouteChanged(
false);
1269 NS_LOG_LOGIC(
"Skipping Triggered Update due to cooldown");
1333 return iter->second;
1356 p->RemovePacketTag(
tag);
1358 p->AddPacketTag(
tag);
1398 m_status(RIP_INVALID),
1411 m_status(RIP_INVALID),
1423 m_status(RIP_INVALID),
1496 os <<
", metric: " << int(
rte.GetRouteMetric()) <<
", tag: " << int(
rte.GetRouteTag());
a polymophic address class
Hold variables of type enum.
An identifier for simulation events.
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
bool IsPending() const
This method is syntactic sugar for !IsExpired().
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
Ipv4 addresses are stored in host order in this class.
static Ipv4Address GetZero()
Ipv4Address CombineMask(const Ipv4Mask &mask) const
Combine this address with a network mask.
static Ipv4Address GetAny()
bool IsLocalMulticast() const
a class to store IPv4 address information on an interface
Ipv4Mask GetMask() const
Get the network mask.
Ipv4Address GetAddress() const
Get the local address.
Ipv4Address GetLocal() const
Get the local address.
a class to represent an Ipv4 address mask
uint16_t GetPrefixLength() const
bool IsMatch(Ipv4Address a, Ipv4Address b) const
static Ipv4Mask GetZero()
This class implements Linux struct pktinfo in order to deliver ancillary information to the socket in...
Abstract base class for IPv4 routing protocols.
A record of an IPv4 routing table entry for Ipv4GlobalRouting and Ipv4StaticRouting.
static std::string FindName(Ptr< Object > object)
Given a pointer to an object, look to see if that object has a name associated with it and,...
virtual void DoInitialize()
Initialize() implementation.
virtual void DoDispose()
Destructor implementation.
Smart pointer class similar to boost::intrusive_ptr.
RIP Routing Protocol, defined in RFC 2453.
void SetInterfaceMetric(uint32_t interface, uint8_t metric)
Set the metric for an interface.
void DoSendRouteUpdate(bool periodic)
Send Routing Updates on all interfaces.
void DoDispose() override
Dispose this object.
SplitHorizonType_e m_splitHorizonStrategy
Split Horizon strategy.
Ptr< Ipv4Route > Lookup(Ipv4Address dest, bool setSource, Ptr< NetDevice >=nullptr)
Lookup in the forwarding table for destination.
Time m_startupDelay
Random delay before protocol startup.
void NotifyInterfaceDown(uint32_t interface) override
std::map< uint32_t, uint8_t > m_interfaceMetrics
Map of interface metrics.
std::set< uint32_t > m_interfaceExclusions
Set of excluded interfaces.
std::list< std::pair< RipRoutingTableEntry *, EventId > >::iterator RoutesI
Iterator for container for the network routes.
uint32_t m_linkDown
Link down value.
void HandleRequests(RipHeader hdr, Ipv4Address senderAddress, uint16_t senderPort, uint32_t incomingInterface, uint8_t hopLimit)
Handle RIP requests.
void DeleteRoute(RipRoutingTableEntry *route)
Delete a route.
bool RouteInput(Ptr< const Packet > p, const Ipv4Header &header, Ptr< const NetDevice > idev, const UnicastForwardCallback &ucb, const MulticastForwardCallback &mcb, const LocalDeliverCallback &lcb, const ErrorCallback &ecb) override
Route an input packet (to be forwarded or locally delivered)
void InvalidateRoute(RipRoutingTableEntry *route)
Invalidate a route.
void Receive(Ptr< Socket > socket)
Receive RIP packets.
void NotifyInterfaceUp(uint32_t interface) override
EventId m_nextUnsolicitedUpdate
Next Unsolicited Update event.
void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const override
Print the Routing Table entries.
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
EventId m_nextTriggeredUpdate
Next Triggered Update event.
Ptr< Ipv4 > m_ipv4
IPv4 reference.
void DoInitialize() override
Start protocol operation.
void SendRouteRequest()
Send Routing Request on all interfaces.
Time m_timeoutDelay
Delay before invalidating a route.
void AddNetworkRouteTo(Ipv4Address network, Ipv4Mask networkPrefix, Ipv4Address nextHop, uint32_t interface)
Add route to network.
Ptr< Socket > m_multicastRecvSocket
multicast receive socket
Time m_minTriggeredUpdateDelay
Min cooldown delay after a Triggered Update.
@ SPLIT_HORIZON
Split Horizon.
@ NO_SPLIT_HORIZON
No Split Horizon.
@ POISON_REVERSE
Poison Reverse Split Horizon.
Time m_unsolicitedUpdate
time between two Unsolicited Routing Updates
std::set< uint32_t > GetInterfaceExclusions() const
Get the set of interface excluded from the protocol.
Ptr< Ipv4Route > RouteOutput(Ptr< Packet > p, const Ipv4Header &header, Ptr< NetDevice > oif, Socket::SocketErrno &sockerr) override
Query routing cache for an existing route, for an outbound packet.
uint8_t GetInterfaceMetric(uint32_t interface) const
Get the metric for an interface.
void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address) override
void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address) override
SocketList m_unicastSocketList
list of sockets for unicast messages (socket, interface index)
Time m_garbageCollectionDelay
Delay before deleting an INVALID route.
void SetIpv4(Ptr< Ipv4 > ipv4) override
static TypeId GetTypeId()
Get the type ID.
bool m_initialized
flag to allow socket's late-creation.
void SetInterfaceExclusions(std::set< uint32_t > exceptions)
Set the set of interface excluded from the protocol.
void AddDefaultRouteTo(Ipv4Address nextHop, uint32_t interface)
Add a default route to the router through the nextHop located on interface.
Routes m_routes
the forwarding table for network.
Time m_maxTriggeredUpdateDelay
Max cooldown delay after a Triggered Update.
void SendTriggeredRouteUpdate()
Send Triggered Routing Updates on all interfaces.
void SendUnsolicitedRouteUpdate()
Send Unsolicited Routing Updates on all interfaces.
void HandleResponses(RipHeader hdr, Ipv4Address senderAddress, uint32_t incomingInterface, uint8_t hopLimit)
Handle RIP responses.
Ptr< UniformRandomVariable > m_rng
Rng stream.
void SetRouteMetric(uint8_t routeMetric)
Set the route metric.
Status_e m_status
route status
bool m_changed
route has been updated
void SetRouteStatus(Status_e status)
Set the route status.
bool IsRouteChanged() const
Get the route changed status.
Status_e GetRouteStatus() const
Get the route status.
uint8_t GetRouteMetric() const
Get the route metric.
void SetRouteTag(uint16_t routeTag)
Set the route tag.
uint16_t GetRouteTag() const
Get the route tag.
void SetRouteChanged(bool changed)
Set the route as changed.
uint8_t m_metric
route metric
virtual ~RipRoutingTableEntry()
Rip v2 Routing Table Entry (RTE) - see RFC 2453.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
void SetPrefix(Ipv4Address prefix)
Set the prefix.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
void SetRecvPktInfo(bool flag)
Enable/Disable receive packet information to socket.
void SetRecvCallback(Callback< void, Ptr< Socket > > receivedData)
Notify application when new data is available to be read.
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
virtual int Close()=0
Close a socket.
SocketErrno
Enumeration of the possible errors returned by a socket.
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
void SetIpRecvTtl(bool ipv4RecvTtl)
Tells a socket to pass information about IP_TTL up the stack.
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)=0
Send data to a specified peer.
This class implements a tag that carries the socket-specific TTL of a packet to the IP layer.
void SetTtl(uint8_t ttl)
Set the tag's TTL.
Simulation virtual time values and global simulation resolution.
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Unit
The unit to use to interpret a number representing time.
AttributeValue implementation for Time.
a unique identifier for an interface.
static TypeId LookupByName(std::string name)
Get a TypeId by name.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Hold an unsigned integer type.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Time Now()
create an ns3::Time instance which contains the current simulation time.
Time Seconds(double value)
Construct a Time in the indicated unit.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
std::ostream & operator<<(std::ostream &os, const Angles &a)
Ptr< const AttributeChecker > MakeEnumChecker(T v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.