A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ipv6-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 // Modifications: Tommaso Pecorella <tommaso.pecorella@unifi.it>
20 //
21 
22 #include "ns3/ipv6-flow-probe.h"
23 #include "ns3/ipv6-flow-classifier.h"
24 #include "ns3/node.h"
25 #include "ns3/packet.h"
26 #include "ns3/flow-monitor.h"
27 #include "ns3/log.h"
28 #include "ns3/pointer.h"
29 #include "ns3/config.h"
30 #include "ns3/flow-id-tag.h"
31 
32 namespace ns3 {
33 
34 NS_LOG_COMPONENT_DEFINE ("Ipv6FlowProbe")
35  ;
36 
38 // Ipv6FlowProbeTag class implementation //
40 
50 class Ipv6FlowProbeTag : public Tag
51 {
52 public:
57  static TypeId GetTypeId (void);
58  virtual TypeId GetInstanceTypeId (void) const;
59  virtual uint32_t GetSerializedSize (void) const;
60  virtual void Serialize (TagBuffer buf) const;
61  virtual void Deserialize (TagBuffer buf);
62  virtual void Print (std::ostream &os) const;
70  Ipv6FlowProbeTag (uint32_t flowId, uint32_t packetId, uint32_t packetSize);
75  void SetFlowId (uint32_t flowId);
80  void SetPacketId (uint32_t packetId);
85  void SetPacketSize (uint32_t packetSize);
90  uint32_t GetFlowId (void) const;
95  uint32_t GetPacketId (void) const;
100  uint32_t GetPacketSize (void) const;
101 private:
102  uint32_t m_flowId;
103  uint32_t m_packetId;
104  uint32_t m_packetSize;
105 
106 };
107 
108 TypeId
110 {
111  static TypeId tid = TypeId ("ns3::Ipv6FlowProbeTag")
112  .SetParent<Tag> ()
113  .AddConstructor<Ipv6FlowProbeTag> ()
114  ;
115  return tid;
116 }
117 TypeId
119 {
120  return GetTypeId ();
121 }
122 uint32_t
124 {
125  return 4 + 4 + 4;
126 }
127 void
129 {
130  buf.WriteU32 (m_flowId);
131  buf.WriteU32 (m_packetId);
132  buf.WriteU32 (m_packetSize);
133 }
134 void
136 {
137  m_flowId = buf.ReadU32 ();
138  m_packetId = buf.ReadU32 ();
139  m_packetSize = buf.ReadU32 ();
140 }
141 void
142 Ipv6FlowProbeTag::Print (std::ostream &os) const
143 {
144  os << "FlowId=" << m_flowId;
145  os << "PacketId=" << m_packetId;
146  os << "PacketSize=" << m_packetSize;
147 }
149  : Tag ()
150 {
151 }
152 
153 Ipv6FlowProbeTag::Ipv6FlowProbeTag (uint32_t flowId, uint32_t packetId, uint32_t packetSize)
154  : Tag (), m_flowId (flowId), m_packetId (packetId), m_packetSize (packetSize)
155 {
156 }
157 
158 void
160 {
161  m_flowId = id;
162 }
163 void
165 {
166  m_packetId = id;
167 }
168 void
170 {
171  m_packetSize = size;
172 }
173 uint32_t
175 {
176  return m_flowId;
177 }
178 uint32_t
180 {
181  return m_packetId;
182 }
183 uint32_t
185 {
186  return m_packetSize;
187 }
188 
190 // Ipv6FlowProbe class implementation //
192 
194  Ptr<Ipv6FlowClassifier> classifier,
195  Ptr<Node> node)
196  : FlowProbe (monitor),
197  m_classifier (classifier)
198 {
199  NS_LOG_FUNCTION (this << node->GetId ());
200 
202 
203  if (!ipv6->TraceConnectWithoutContext ("SendOutgoing",
205  {
206  NS_FATAL_ERROR ("trace fail");
207  }
208  if (!ipv6->TraceConnectWithoutContext ("UnicastForward",
210  {
211  NS_FATAL_ERROR ("trace fail");
212  }
213  if (!ipv6->TraceConnectWithoutContext ("LocalDeliver",
215  {
216  NS_FATAL_ERROR ("trace fail");
217  }
218 
219  if (!ipv6->TraceConnectWithoutContext ("Drop",
221  {
222  NS_FATAL_ERROR ("trace fail");
223  }
224 
225  // code copied from point-to-point-helper.cc
226  std::ostringstream oss;
227  oss << "/NodeList/" << node->GetId () << "/DeviceList/*/TxQueue/Drop";
229 }
230 
232 {
233 }
234 
235 void
237 {
239 }
240 
241 void
242 Ipv6FlowProbe::SendOutgoingLogger (const Ipv6Header &ipHeader, Ptr<const Packet> ipPayload, uint32_t interface)
243 {
244  FlowId flowId;
245  FlowPacketId packetId;
246 
247  if (m_classifier->Classify (ipHeader, ipPayload, &flowId, &packetId))
248  {
249  uint32_t size = (ipPayload->GetSize () + ipHeader.GetSerializedSize ());
250  NS_LOG_DEBUG ("ReportFirstTx ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<"); "
251  << ipHeader << *ipPayload);
252  m_flowMonitor->ReportFirstTx (this, flowId, packetId, size);
253 
254  // tag the packet with the flow id and packet id, so that the packet can be identified even
255  // when Ipv6Header is not accessible at some non-IPv6 protocol layer
256  Ipv6FlowProbeTag fTag (flowId, packetId, size);
257  ipPayload->AddPacketTag (fTag);
258  }
259 }
260 
261 void
262 Ipv6FlowProbe::ForwardLogger (const Ipv6Header &ipHeader, Ptr<const Packet> ipPayload, uint32_t interface)
263 {
264  // peek the tags that are added by Ipv6FlowProbe::SendOutgoingLogger ()
265  Ipv6FlowProbeTag fTag;
266 
267  bool found = ipPayload->PeekPacketTag (fTag);
268 
269  if (found)
270  {
271  FlowId flowId = fTag.GetFlowId ();
272  FlowPacketId packetId = fTag.GetPacketId ();
273 
274  uint32_t size = (ipPayload->GetSize () + ipHeader.GetSerializedSize ());
275  NS_LOG_DEBUG ("ReportForwarding ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<");");
276  m_flowMonitor->ReportForwarding (this, flowId, packetId, size);
277  }
278 }
279 
280 void
281 Ipv6FlowProbe::ForwardUpLogger (const Ipv6Header &ipHeader, Ptr<const Packet> ipPayload, uint32_t interface)
282 {
283  // remove the tags that are added by Ipv6FlowProbe::SendOutgoingLogger ()
284  Ipv6FlowProbeTag fTag;
285 
286  // ConstCast: see http://www.nsnam.org/bugzilla/show_bug.cgi?id=904
287  bool found = ConstCast<Packet> (ipPayload)->RemovePacketTag (fTag);
288 
289  if (found)
290  {
291  FlowId flowId = fTag.GetFlowId ();
292  FlowPacketId packetId = fTag.GetPacketId ();
293 
294  uint32_t size = (ipPayload->GetSize () + ipHeader.GetSerializedSize ());
295  NS_LOG_DEBUG ("ReportLastRx ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<");");
296  m_flowMonitor->ReportLastRx (this, flowId, packetId, size);
297  }
298 }
299 
300 void
302  Ipv6L3Protocol::DropReason reason, Ptr<Ipv6> ipv6, uint32_t ifIndex)
303 {
304 #if 0
305  switch (reason)
306  {
308  break;
309 
311  case Ipv6L3Protocol::DROP_BAD_CHECKSUM:
312  Ipv6Address addri = m_ipv6->GetAddress (ifIndex);
313  Ipv6Mask maski = m_ipv6->GetNetworkMask (ifIndex);
314  Ipv6Address bcast = addri.GetSubnetDirectedBroadcast (maski);
315  if (ipHeader.GetDestination () == bcast) // we don't want broadcast packets
316  {
317  return;
318  }
319  }
320 #endif
321 
322  // remove the tags that are added by Ipv6FlowProbe::SendOutgoingLogger ()
323  Ipv6FlowProbeTag fTag;
324 
325  // ConstCast: see http://www.nsnam.org/bugzilla/show_bug.cgi?id=904
326  bool found = ConstCast<Packet> (ipPayload)->RemovePacketTag (fTag);
327 
328  if (found)
329  {
330  FlowId flowId = fTag.GetFlowId ();
331  FlowPacketId packetId = fTag.GetPacketId ();
332 
333  uint32_t size = (ipPayload->GetSize () + ipHeader.GetSerializedSize ());
334  NS_LOG_DEBUG ("Drop ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<", " << reason
335  << ", destIp=" << ipHeader.GetDestinationAddress () << "); "
336  << "HDR: " << ipHeader << " PKT: " << *ipPayload);
337 
338  DropReason myReason;
339 
340 
341  switch (reason)
342  {
344  myReason = DROP_TTL_EXPIRE;
345  NS_LOG_DEBUG ("DROP_TTL_EXPIRE");
346  break;
348  myReason = DROP_NO_ROUTE;
349  NS_LOG_DEBUG ("DROP_NO_ROUTE");
350  break;
352  myReason = DROP_INTERFACE_DOWN;
353  NS_LOG_DEBUG ("DROP_INTERFACE_DOWN");
354  break;
356  myReason = DROP_ROUTE_ERROR;
357  NS_LOG_DEBUG ("DROP_ROUTE_ERROR");
358  break;
360  myReason = DROP_UNKNOWN_PROTOCOL;
361  NS_LOG_DEBUG ("DROP_UNKNOWN_PROTOCOL");
362  break;
364  myReason = DROP_UNKNOWN_OPTION;
365  NS_LOG_DEBUG ("DROP_UNKNOWN_OPTION");
366  break;
368  myReason = DROP_MALFORMED_HEADER;
369  NS_LOG_DEBUG ("DROP_MALFORMED_HEADER");
370  break;
372  myReason = DROP_FRAGMENT_TIMEOUT;
373  NS_LOG_DEBUG ("DROP_FRAGMENT_TIMEOUT");
374  break;
375  default:
376  myReason = DROP_INVALID_REASON;
377  NS_FATAL_ERROR ("Unexpected drop reason code " << reason);
378  }
379 
380  m_flowMonitor->ReportDrop (this, flowId, packetId, size, myReason);
381  }
382 }
383 
384 void
386 {
387  // remove the tags that are added by Ipv6FlowProbe::SendOutgoingLogger ()
388  Ipv6FlowProbeTag fTag;
389 
390  // ConstCast: see http://www.nsnam.org/bugzilla/show_bug.cgi?id=904
391  bool tagFound = ConstCast<Packet> (ipPayload)->RemovePacketTag (fTag);
392  if (!tagFound)
393  {
394  return;
395  }
396 
397  FlowId flowId = fTag.GetFlowId ();
398  FlowPacketId packetId = fTag.GetPacketId ();
399  uint32_t size = fTag.GetPacketSize ();
400 
401  NS_LOG_DEBUG ("Drop ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<", " << DROP_QUEUE
402  << "); ");
403 
404  m_flowMonitor->ReportDrop (this, flowId, packetId, size, DROP_QUEUE);
405 }
406 
407 } // namespace ns3
408 
409 
uint32_t FlowPacketId
Abstract identifier of a packet within a flow.
virtual uint32_t GetSerializedSize(void) const
virtual uint32_t GetSerializedSize(void) const
Get the serialized size of the packet.
Definition: ipv6-header.cc:143
Doxygen introspection did not find any typical Config paths.
Definition: ipv6-header.h:33
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 "...
uint32_t m_packetSize
packet size
IPv6 layer implementation.
void SendOutgoingLogger(const Ipv6Header &ipHeader, Ptr< const Packet > ipPayload, uint32_t interface)
Log a packet being sent.
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:841
uint32_t m_flowId
flow identifier
void DropLogger(const Ipv6Header &ipHeader, Ptr< const Packet > ipPayload, Ipv6L3Protocol::DropReason reason, Ptr< Ipv6 > ipv6, uint32_t ifIndex)
Log a packet being dropped.
Interface is down so can not send packet.
Tag used to allow a fast identification of the packet.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
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
Packet dropped due to queue overflow.
uint32_t m_packetId
packet identifier
TAG_BUFFER_INLINE uint32_t ReadU32(void)
Definition: tag-buffer.h:215
void SetPacketId(uint32_t packetId)
Set the packet identifier.
static TypeId GetTypeId(void)
Get the type ID.
Ptr< FlowMonitor > m_flowMonitor
the FlowMonitor instance
Definition: flow-probe.h:102
Interface is down so can not send packet.
void SetPacketSize(uint32_t packetSize)
Set the packet size.
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:863
virtual void Serialize(TagBuffer buf) const
uint32_t GetPacketSize(void) const
Get the packet size.
DropReason
enumeration of possible reasons why a packet may be dropped
TAG_BUFFER_INLINE void WriteU32(uint32_t v)
Definition: tag-buffer.h:186
Packet dropped due to missing route to the destination.
void ForwardUpLogger(const Ipv6Header &ipHeader, Ptr< const Packet > ipPayload, uint32_t interface)
Log a packet being received by the destination.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1242
virtual TypeId GetInstanceTypeId(void) const
tag a set of bytes in a packet
Definition: tag.h:36
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
The FlowProbe class is responsible for listening for packet events in a specific point of the simulat...
Definition: flow-probe.h:39
Describes an IPv6 address.
Definition: ipv6-address.h:46
read and write tag data
Definition: tag-buffer.h:51
uint32_t GetId(void) const
Definition: node.cc:106
void SetFlowId(uint32_t flowId)
Set the flow identifier.
Packet dropped due to TTL decremented to zero during IPv4 forwarding.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:213
uint32_t GetFlowId(void) const
Set the flow identifier.
virtual void Print(std::ostream &os) const
Ipv6FlowProbe(Ptr< FlowMonitor > monitor, Ptr< Ipv6FlowClassifier > classifier, Ptr< Node > node)
Constructor.
uint32_t GetPacketId(void) const
Set the packet identifier.
Fallback reason (no known reason)
void ForwardLogger(const Ipv6Header &ipHeader, Ptr< const Packet > ipPayload, uint32_t interface)
Log a packet being forwarded.
Ptr< T > GetObject(void) const
Definition: object.h:362
Ptr< Ipv6FlowClassifier > m_classifier
the Ipv6FlowClassifier this probe is associated with
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
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
Ipv6Address GetDestinationAddress(void) const
Get the "Destination address" field.
Definition: ipv6-header.cc:111
void QueueDropLogger(Ptr< const Packet > ipPayload)
Log a packet being dropped by a queue.
DropReason
Reason why a packet has been dropped.
virtual void Deserialize(TagBuffer buf)
uint32_t FlowId
Abstract identifier of a packet flow.