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  ;
35 
37 // Ipv4FlowProbeTag class implementation //
39 
49 class Ipv4FlowProbeTag : public Tag
50 {
51 public:
56  static TypeId GetTypeId (void);
57  virtual TypeId GetInstanceTypeId (void) const;
58  virtual uint32_t GetSerializedSize (void) const;
59  virtual void Serialize (TagBuffer buf) const;
60  virtual void Deserialize (TagBuffer buf);
61  virtual void Print (std::ostream &os) const;
69  Ipv4FlowProbeTag (uint32_t flowId, uint32_t packetId, uint32_t packetSize);
74  void SetFlowId (uint32_t flowId);
79  void SetPacketId (uint32_t packetId);
84  void SetPacketSize (uint32_t packetSize);
89  uint32_t GetFlowId (void) const;
94  uint32_t GetPacketId (void) const;
99  uint32_t GetPacketSize (void) const;
100 private:
101  uint32_t m_flowId;
102  uint32_t m_packetId;
103  uint32_t m_packetSize;
104 
105 };
106 
107 TypeId
109 {
110  static TypeId tid = TypeId ("ns3::Ipv4FlowProbeTag")
111  .SetParent<Tag> ()
112  .AddConstructor<Ipv4FlowProbeTag> ()
113  ;
114  return tid;
115 }
116 TypeId
118 {
119  return GetTypeId ();
120 }
121 uint32_t
123 {
124  return 4 + 4 + 4;
125 }
126 void
128 {
129  buf.WriteU32 (m_flowId);
130  buf.WriteU32 (m_packetId);
131  buf.WriteU32 (m_packetSize);
132 }
133 void
135 {
136  m_flowId = buf.ReadU32 ();
137  m_packetId = buf.ReadU32 ();
138  m_packetSize = buf.ReadU32 ();
139 }
140 void
141 Ipv4FlowProbeTag::Print (std::ostream &os) const
142 {
143  os << "FlowId=" << m_flowId;
144  os << "PacketId=" << m_packetId;
145  os << "PacketSize=" << m_packetSize;
146 }
148  : Tag ()
149 {
150 }
151 
152 Ipv4FlowProbeTag::Ipv4FlowProbeTag (uint32_t flowId, uint32_t packetId, uint32_t packetSize)
153  : Tag (), m_flowId (flowId), m_packetId (packetId), m_packetSize (packetSize)
154 {
155 }
156 
157 void
159 {
160  m_flowId = id;
161 }
162 void
164 {
165  m_packetId = id;
166 }
167 void
169 {
170  m_packetSize = size;
171 }
172 uint32_t
174 {
175  return m_flowId;
176 }
177 uint32_t
179 {
180  return m_packetId;
181 }
182 uint32_t
184 {
185  return m_packetSize;
186 }
187 
189 // Ipv4FlowProbe class implementation //
191 
193  Ptr<Ipv4FlowClassifier> classifier,
194  Ptr<Node> node)
195  : FlowProbe (monitor),
196  m_classifier (classifier)
197 {
198  NS_LOG_FUNCTION (this << node->GetId ());
199 
201 
202  if (!ipv4->TraceConnectWithoutContext ("SendOutgoing",
204  {
205  NS_FATAL_ERROR ("trace fail");
206  }
207  if (!ipv4->TraceConnectWithoutContext ("UnicastForward",
209  {
210  NS_FATAL_ERROR ("trace fail");
211  }
212  if (!ipv4->TraceConnectWithoutContext ("LocalDeliver",
214  {
215  NS_FATAL_ERROR ("trace fail");
216  }
217 
218  if (!ipv4->TraceConnectWithoutContext ("Drop",
220  {
221  NS_FATAL_ERROR ("trace fail");
222  }
223 
224  // code copied from point-to-point-helper.cc
225  std::ostringstream oss;
226  oss << "/NodeList/" << node->GetId () << "/DeviceList/*/TxQueue/Drop";
228 }
229 
231 {
232 }
233 
234 void
236 {
238 }
239 
240 void
241 Ipv4FlowProbe::SendOutgoingLogger (const Ipv4Header &ipHeader, Ptr<const Packet> ipPayload, uint32_t interface)
242 {
243  FlowId flowId;
244  FlowPacketId packetId;
245 
246  if (m_classifier->Classify (ipHeader, ipPayload, &flowId, &packetId))
247  {
248  uint32_t size = (ipPayload->GetSize () + ipHeader.GetSerializedSize ());
249  NS_LOG_DEBUG ("ReportFirstTx ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<"); "
250  << ipHeader << *ipPayload);
251  m_flowMonitor->ReportFirstTx (this, flowId, packetId, size);
252 
253  // tag the packet with the flow id and packet id, so that the packet can be identified even
254  // when Ipv4Header is not accessible at some non-IPv4 protocol layer
255  Ipv4FlowProbeTag fTag (flowId, packetId, size);
256  ipPayload->AddPacketTag (fTag);
257  }
258 }
259 
260 void
261 Ipv4FlowProbe::ForwardLogger (const Ipv4Header &ipHeader, Ptr<const Packet> ipPayload, uint32_t interface)
262 {
263  FlowId flowId;
264  FlowPacketId packetId;
265 
266  if (m_classifier->Classify (ipHeader, ipPayload, &flowId, &packetId))
267  {
268  uint32_t size = (ipPayload->GetSize () + ipHeader.GetSerializedSize ());
269  NS_LOG_DEBUG ("ReportForwarding ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<");");
270  m_flowMonitor->ReportForwarding (this, flowId, packetId, size);
271  }
272 
273 }
274 
275 void
276 Ipv4FlowProbe::ForwardUpLogger (const Ipv4Header &ipHeader, Ptr<const Packet> ipPayload, uint32_t interface)
277 {
278  FlowId flowId;
279  FlowPacketId packetId;
280 
281  if (m_classifier->Classify (ipHeader, ipPayload, &flowId, &packetId))
282  {
283  // remove the tags that are added by Ipv4FlowProbe::SendOutgoingLogger ()
284  Ipv4FlowProbeTag fTag;
285 
286  // ConstCast: see http://www.nsnam.org/bugzilla/show_bug.cgi?id=904
287  ConstCast<Packet> (ipPayload)->RemovePacketTag (fTag);
288 
289  uint32_t size = (ipPayload->GetSize () + ipHeader.GetSerializedSize ());
290  NS_LOG_DEBUG ("ReportLastRx ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<");");
291  m_flowMonitor->ReportLastRx (this, flowId, packetId, size);
292  }
293 }
294 
295 void
297  Ipv4L3Protocol::DropReason reason, Ptr<Ipv4> ipv4, uint32_t ifIndex)
298 {
299 #if 0
300  switch (reason)
301  {
303  break;
304 
307  Ipv4Address addri = m_ipv4->GetAddress (ifIndex);
308  Ipv4Mask maski = m_ipv4->GetNetworkMask (ifIndex);
309  Ipv4Address bcast = addri.GetSubnetDirectedBroadcast (maski);
310  if (ipHeader.GetDestination () == bcast) // we don't want broadcast packets
311  {
312  return;
313  }
314  }
315 #endif
316 
317  FlowId flowId;
318  FlowPacketId packetId;
319 
320  if (m_classifier->Classify (ipHeader, ipPayload, &flowId, &packetId))
321  {
322  // remove the tags that are added by Ipv4FlowProbe::SendOutgoingLogger ()
323  Ipv4FlowProbeTag fTag;
324 
325  // ConstCast: see http://www.nsnam.org/bugzilla/show_bug.cgi?id=904
326  ConstCast<Packet> (ipPayload)->RemovePacketTag (fTag);
327 
328  uint32_t size = (ipPayload->GetSize () + ipHeader.GetSerializedSize ());
329  NS_LOG_DEBUG ("Drop ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<", " << reason
330  << ", destIp=" << ipHeader.GetDestination () << "); "
331  << "HDR: " << ipHeader << " PKT: " << *ipPayload);
332 
333  DropReason myReason;
334 
335 
336  switch (reason)
337  {
339  myReason = DROP_TTL_EXPIRE;
340  NS_LOG_DEBUG ("DROP_TTL_EXPIRE");
341  break;
343  myReason = DROP_NO_ROUTE;
344  NS_LOG_DEBUG ("DROP_NO_ROUTE");
345  break;
347  myReason = DROP_BAD_CHECKSUM;
348  NS_LOG_DEBUG ("DROP_BAD_CHECKSUM");
349  break;
351  myReason = DROP_INTERFACE_DOWN;
352  NS_LOG_DEBUG ("DROP_INTERFACE_DOWN");
353  break;
355  myReason = DROP_ROUTE_ERROR;
356  NS_LOG_DEBUG ("DROP_ROUTE_ERROR");
357  break;
359  myReason = DROP_FRAGMENT_TIMEOUT;
360  NS_LOG_DEBUG ("DROP_FRAGMENT_TIMEOUT");
361  break;
362 
363  default:
364  myReason = DROP_INVALID_REASON;
365  NS_FATAL_ERROR ("Unexpected drop reason code " << reason);
366  }
367 
368  m_flowMonitor->ReportDrop (this, flowId, packetId, size, myReason);
369  }
370 }
371 
372 void
374 {
375  // remove the tags that are added by Ipv4FlowProbe::SendOutgoingLogger ()
376  Ipv4FlowProbeTag fTag;
377 
378  // ConstCast: see http://www.nsnam.org/bugzilla/show_bug.cgi?id=904
379  bool tagFound;
380  tagFound = ConstCast<Packet> (ipPayload)->RemovePacketTag (fTag);
381  if (!tagFound)
382  {
383  return;
384  }
385 
386  FlowId flowId = fTag.GetFlowId ();
387  FlowPacketId packetId = fTag.GetPacketId ();
388  uint32_t size = fTag.GetPacketSize ();
389 
390  NS_LOG_DEBUG ("Drop ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<", " << DROP_QUEUE
391  << "); ");
392 
393  m_flowMonitor->ReportDrop (this, flowId, packetId, size, DROP_QUEUE);
394 }
395 
396 } // namespace ns3
397 
398 
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:59
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
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.
NS_LOG_COMPONENT_DEFINE("GrantedTimeWindowMpiInterface")
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:210
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
Fallback reason (no known reason)
uint32_t GetSize(void) const
Definition: packet.h:650
TAG_BUFFER_INLINE uint32_t ReadU32(void)
Definition: tag-buffer.h:199
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
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
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
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:170
void SetPacketId(uint32_t packetId)
Set the packet identifier.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1238
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:104
Packet dropped due to queue overflow.
Interface is down so can not send packet.
#define NS_LOG_DEBUG(msg)
Definition: log.h:289
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:361
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
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.