A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ipv4-flow-probe.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 //
3 // Copyright (c) 2009 INESC Porto
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License version 2 as
7 // published by the Free Software Foundation;
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 //
18 // Author: Gustavo J. A. M. Carneiro <gjc@inescporto.pt> <gjcarneiro@gmail.com>
19 //
20 
21 #include "ns3/ipv4-flow-probe.h"
22 #include "ns3/ipv4-flow-classifier.h"
23 #include "ns3/node.h"
24 #include "ns3/packet.h"
25 #include "ns3/flow-monitor.h"
26 #include "ns3/log.h"
27 #include "ns3/pointer.h"
28 #include "ns3/config.h"
29 #include "ns3/flow-id-tag.h"
30 
31 namespace ns3 {
32 
33 NS_LOG_COMPONENT_DEFINE ("Ipv4FlowProbe");
34 
36 // Ipv4FlowProbeTag class implementation //
38 
48 class Ipv4FlowProbeTag : public Tag
49 {
50 public:
55  static TypeId GetTypeId (void);
56  virtual TypeId GetInstanceTypeId (void) const;
57  virtual uint32_t GetSerializedSize (void) const;
58  virtual void Serialize (TagBuffer buf) const;
59  virtual void Deserialize (TagBuffer buf);
60  virtual void Print (std::ostream &os) const;
68  Ipv4FlowProbeTag (uint32_t flowId, uint32_t packetId, uint32_t packetSize);
73  void SetFlowId (uint32_t flowId);
78  void SetPacketId (uint32_t packetId);
83  void SetPacketSize (uint32_t packetSize);
88  uint32_t GetFlowId (void) const;
93  uint32_t GetPacketId (void) const;
98  uint32_t GetPacketSize (void) const;
99 private:
100  uint32_t m_flowId;
101  uint32_t m_packetId;
102  uint32_t m_packetSize;
103 
104 };
105 
106 TypeId
108 {
109  static TypeId tid = TypeId ("ns3::Ipv4FlowProbeTag")
110  .SetParent<Tag> ()
111  .AddConstructor<Ipv4FlowProbeTag> ()
112  ;
113  return tid;
114 }
115 TypeId
117 {
118  return GetTypeId ();
119 }
120 uint32_t
122 {
123  return 4 + 4 + 4;
124 }
125 void
127 {
128  buf.WriteU32 (m_flowId);
129  buf.WriteU32 (m_packetId);
130  buf.WriteU32 (m_packetSize);
131 }
132 void
134 {
135  m_flowId = buf.ReadU32 ();
136  m_packetId = buf.ReadU32 ();
137  m_packetSize = buf.ReadU32 ();
138 }
139 void
140 Ipv4FlowProbeTag::Print (std::ostream &os) const
141 {
142  os << "FlowId=" << m_flowId;
143  os << "PacketId=" << m_packetId;
144  os << "PacketSize=" << m_packetSize;
145 }
147  : Tag ()
148 {
149 }
150 
151 Ipv4FlowProbeTag::Ipv4FlowProbeTag (uint32_t flowId, uint32_t packetId, uint32_t packetSize)
152  : Tag (), m_flowId (flowId), m_packetId (packetId), m_packetSize (packetSize)
153 {
154 }
155 
156 void
158 {
159  m_flowId = id;
160 }
161 void
163 {
164  m_packetId = id;
165 }
166 void
168 {
169  m_packetSize = size;
170 }
171 uint32_t
173 {
174  return m_flowId;
175 }
176 uint32_t
178 {
179  return m_packetId;
180 }
181 uint32_t
183 {
184  return m_packetSize;
185 }
186 
188 // Ipv4FlowProbe class implementation //
190 
192  Ptr<Ipv4FlowClassifier> classifier,
193  Ptr<Node> node)
194  : FlowProbe (monitor),
195  m_classifier (classifier)
196 {
197  NS_LOG_FUNCTION (this << node->GetId ());
198 
199  m_ipv4 = node->GetObject<Ipv4L3Protocol> ();
200 
201  if (!m_ipv4->TraceConnectWithoutContext ("SendOutgoing",
203  {
204  NS_FATAL_ERROR ("trace fail");
205  }
206  if (!m_ipv4->TraceConnectWithoutContext ("UnicastForward",
208  {
209  NS_FATAL_ERROR ("trace fail");
210  }
211  if (!m_ipv4->TraceConnectWithoutContext ("LocalDeliver",
213  {
214  NS_FATAL_ERROR ("trace fail");
215  }
216 
217  if (!m_ipv4->TraceConnectWithoutContext ("Drop",
219  {
220  NS_FATAL_ERROR ("trace fail");
221  }
222 
223  // code copied from point-to-point-helper.cc
224  std::ostringstream oss;
225  oss << "/NodeList/" << node->GetId () << "/DeviceList/*/TxQueue/Drop";
227 }
228 
230 {
231 }
232 
233 void
235 {
236  m_ipv4 = 0;
237  m_classifier = 0;
239 }
240 
241 void
242 Ipv4FlowProbe::SendOutgoingLogger (const Ipv4Header &ipHeader, Ptr<const Packet> ipPayload, uint32_t interface)
243 {
244  FlowId flowId;
245  FlowPacketId packetId;
246 
247  if (!m_ipv4->IsUnicast(ipHeader.GetDestination ()))
248  {
249  // we are not prepared to handle broadcast yet
250  return;
251  }
252 
253  if (m_classifier->Classify (ipHeader, ipPayload, &flowId, &packetId))
254  {
255  uint32_t size = (ipPayload->GetSize () + ipHeader.GetSerializedSize ());
256  NS_LOG_DEBUG ("ReportFirstTx ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<"); "
257  << ipHeader << *ipPayload);
258  m_flowMonitor->ReportFirstTx (this, flowId, packetId, size);
259 
260  // tag the packet with the flow id and packet id, so that the packet can be identified even
261  // when Ipv4Header is not accessible at some non-IPv4 protocol layer
262  Ipv4FlowProbeTag fTag (flowId, packetId, size);
263  ipPayload->AddPacketTag (fTag);
264  }
265 }
266 
267 void
268 Ipv4FlowProbe::ForwardLogger (const Ipv4Header &ipHeader, Ptr<const Packet> ipPayload, uint32_t interface)
269 {
270  // peek the tags that are added by Ipv4FlowProbe::SendOutgoingLogger ()
271  Ipv4FlowProbeTag fTag;
272 
273  bool found = ipPayload->PeekPacketTag (fTag);
274 
275  if (found)
276  {
277  FlowId flowId = fTag.GetFlowId ();
278  FlowPacketId packetId = fTag.GetPacketId ();
279 
280  uint32_t size = (ipPayload->GetSize () + ipHeader.GetSerializedSize ());
281  NS_LOG_DEBUG ("ReportForwarding ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<");");
282  m_flowMonitor->ReportForwarding (this, flowId, packetId, size);
283  }
284 }
285 
286 void
287 Ipv4FlowProbe::ForwardUpLogger (const Ipv4Header &ipHeader, Ptr<const Packet> ipPayload, uint32_t interface)
288 {
289  // remove the tags that are added by Ipv4FlowProbe::SendOutgoingLogger ()
290  Ipv4FlowProbeTag fTag;
291 
292  // ConstCast: see http://www.nsnam.org/bugzilla/show_bug.cgi?id=904
293  bool found = ConstCast<Packet> (ipPayload)->RemovePacketTag (fTag);
294 
295  if (found)
296  {
297  FlowId flowId = fTag.GetFlowId ();
298  FlowPacketId packetId = fTag.GetPacketId ();
299 
300  uint32_t size = (ipPayload->GetSize () + ipHeader.GetSerializedSize ());
301  NS_LOG_DEBUG ("ReportLastRx ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<");");
302  m_flowMonitor->ReportLastRx (this, flowId, packetId, size);
303  }
304 }
305 
306 void
308  Ipv4L3Protocol::DropReason reason, Ptr<Ipv4> ipv4, uint32_t ifIndex)
309 {
310 #if 0
311  switch (reason)
312  {
314  break;
315 
318  Ipv4Address addri = m_ipv4->GetAddress (ifIndex);
319  Ipv4Mask maski = m_ipv4->GetNetworkMask (ifIndex);
320  Ipv4Address bcast = addri.GetSubnetDirectedBroadcast (maski);
321  if (ipHeader.GetDestination () == bcast) // we don't want broadcast packets
322  {
323  return;
324  }
325  }
326 #endif
327 
328  // remove the tags that are added by Ipv4FlowProbe::SendOutgoingLogger ()
329  Ipv4FlowProbeTag fTag;
330 
331  // ConstCast: see http://www.nsnam.org/bugzilla/show_bug.cgi?id=904
332  bool found = ConstCast<Packet> (ipPayload)->RemovePacketTag (fTag);
333 
334  if (found)
335  {
336  FlowId flowId = fTag.GetFlowId ();
337  FlowPacketId packetId = fTag.GetPacketId ();
338 
339  uint32_t size = (ipPayload->GetSize () + ipHeader.GetSerializedSize ());
340  NS_LOG_DEBUG ("Drop ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<", " << reason
341  << ", destIp=" << ipHeader.GetDestination () << "); "
342  << "HDR: " << ipHeader << " PKT: " << *ipPayload);
343 
344  DropReason myReason;
345 
346 
347  switch (reason)
348  {
350  myReason = DROP_TTL_EXPIRE;
351  NS_LOG_DEBUG ("DROP_TTL_EXPIRE");
352  break;
354  myReason = DROP_NO_ROUTE;
355  NS_LOG_DEBUG ("DROP_NO_ROUTE");
356  break;
358  myReason = DROP_BAD_CHECKSUM;
359  NS_LOG_DEBUG ("DROP_BAD_CHECKSUM");
360  break;
362  myReason = DROP_INTERFACE_DOWN;
363  NS_LOG_DEBUG ("DROP_INTERFACE_DOWN");
364  break;
366  myReason = DROP_ROUTE_ERROR;
367  NS_LOG_DEBUG ("DROP_ROUTE_ERROR");
368  break;
370  myReason = DROP_FRAGMENT_TIMEOUT;
371  NS_LOG_DEBUG ("DROP_FRAGMENT_TIMEOUT");
372  break;
373 
374  default:
375  myReason = DROP_INVALID_REASON;
376  NS_FATAL_ERROR ("Unexpected drop reason code " << reason);
377  }
378 
379  m_flowMonitor->ReportDrop (this, flowId, packetId, size, myReason);
380  }
381 }
382 
383 void
385 {
386  // remove the tags that are added by Ipv4FlowProbe::SendOutgoingLogger ()
387  Ipv4FlowProbeTag fTag;
388 
389  // ConstCast: see http://www.nsnam.org/bugzilla/show_bug.cgi?id=904
390  bool tagFound = ConstCast<Packet> (ipPayload)->RemovePacketTag (fTag);
391  if (!tagFound)
392  {
393  return;
394  }
395 
396  FlowId flowId = fTag.GetFlowId ();
397  FlowPacketId packetId = fTag.GetPacketId ();
398  uint32_t size = fTag.GetPacketSize ();
399 
400  NS_LOG_DEBUG ("Drop ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<", " << DROP_QUEUE
401  << "); ");
402 
403  m_flowMonitor->ReportDrop (this, flowId, packetId, size, DROP_QUEUE);
404 }
405 
406 } // namespace ns3
407 
408 
uint32_t FlowPacketId
Abstract identifier of a packet within a flow.
Tag used to allow a fast identification of the packet.
void ForwardUpLogger(const Ipv4Header &ipHeader, Ptr< const Packet > ipPayload, uint32_t interface)
Log a packet being received by the destination.
uint32_t m_flowId
flow identifier
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:60
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
void SetPacketSize(uint32_t packetSize)
Set the packet size.
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:222
Ipv4FlowProbe(Ptr< FlowMonitor > monitor, Ptr< Ipv4FlowClassifier > classifier, Ptr< Node > node)
Constructor.
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:841
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
Fallback reason (no known reason)
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:744
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:95
TAG_BUFFER_INLINE uint32_t ReadU32(void)
Definition: tag-buffer.h:215
void SendOutgoingLogger(const Ipv4Header &ipHeader, Ptr< const Packet > ipPayload, uint32_t interface)
Log a packet being sent.
Ptr< FlowMonitor > m_flowMonitor
the FlowMonitor instance
Definition: flow-probe.h:102
Ipv4Address GetSubnetDirectedBroadcast(Ipv4Mask const &mask) const
Generate subnet-directed broadcast address corresponding to mask.
virtual uint32_t GetSerializedSize(void) const
DropReason
Reason why a packet has been dropped.
void ForwardLogger(const Ipv4Header &ipHeader, Ptr< const Packet > ipPayload, uint32_t interface)
Log a packet being forwarded.
Packet header for IPv4.
Definition: ipv4-header.h:31
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:863
void SetFlowId(uint32_t flowId)
Set the flow identifier.
uint32_t m_packetSize
packet size
virtual void Serialize(TagBuffer buf) const
void QueueDropLogger(Ptr< const Packet > ipPayload)
Log a packet being dropped by a queue.
TAG_BUFFER_INLINE void WriteU32(uint32_t v)
Definition: tag-buffer.h:186
void SetPacketId(uint32_t packetId)
Set the packet identifier.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1242
uint32_t GetPacketId(void) const
Set the packet identifier.
Packet dropped due to invalid checksum in the IPv4 header.
tag a set of bytes in a packet
Definition: tag.h:36
uint32_t m_packetId
packet identifier
Implement the Ipv4 layer.
virtual void Print(std::ostream &os) const
Ptr< Ipv4FlowClassifier > m_classifier
the Ipv4FlowClassifier this probe is associated with
virtual TypeId GetInstanceTypeId(void) const
virtual void Deserialize(TagBuffer buf)
uint32_t GetFlowId(void) const
Set the flow identifier.
The FlowProbe class is responsible for listening for packet events in a specific point of the simulat...
Definition: flow-probe.h:39
Packet dropped due to TTL decremented to zero during IPv4 forwarding.
uint32_t GetPacketSize(void) const
Get the packet size.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
read and write tag data
Definition: tag-buffer.h:51
uint32_t GetId(void) const
Definition: node.cc:106
Packet dropped due to queue overflow.
Interface is down so can not send packet.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:213
Packet dropped due to missing route to the destination.
Interface is down so can not send packet.
DropReason
enumeration of possible reasons why a packet may be dropped
virtual uint32_t GetSerializedSize(void) const
Definition: ipv4-header.cc:374
Ptr< T > GetObject(void) const
Definition: object.h:362
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
Ptr< Ipv4L3Protocol > m_ipv4
the Ipv4L3Protocol this probe is bound to
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition: config.cc:717
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: flow-probe.cc:39
static TypeId GetTypeId(void)
Get the type ID.
uint32_t FlowId
Abstract identifier of a packet flow.
void DropLogger(const Ipv4Header &ipHeader, Ptr< const Packet > ipPayload, Ipv4L3Protocol::DropReason reason, Ptr< Ipv4 > ipv4, uint32_t ifIndex)
Log a packet being dropped.