A Discrete-Event Network Simulator
API
ipv6-flow-probe.cc
Go to the documentation of this file.
1 //
2 // Copyright (c) 2009 INESC Porto
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License version 2 as
6 // published by the Free Software Foundation;
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // Author: Gustavo J. A. M. Carneiro <gjc@inescporto.pt> <gjcarneiro@gmail.com>
18 // Modifications: Tommaso Pecorella <tommaso.pecorella@unifi.it>
19 //
20 
21 #include "ns3/ipv6-flow-probe.h"
22 
23 #include "ns3/config.h"
24 #include "ns3/flow-id-tag.h"
25 #include "ns3/flow-monitor.h"
26 #include "ns3/ipv6-flow-classifier.h"
27 #include "ns3/log.h"
28 #include "ns3/node.h"
29 #include "ns3/packet.h"
30 #include "ns3/pointer.h"
31 
32 namespace ns3
33 {
34 
35 NS_LOG_COMPONENT_DEFINE("Ipv6FlowProbe");
36 
38 // Ipv6FlowProbeTag class implementation //
40 
50 class Ipv6FlowProbeTag : public Tag
51 {
52  public:
57  static TypeId GetTypeId();
58  TypeId GetInstanceTypeId() const override;
59  uint32_t GetSerializedSize() const override;
60  void Serialize(TagBuffer buf) const override;
61  void Deserialize(TagBuffer buf) override;
62  void Print(std::ostream& os) const override;
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() const;
95  uint32_t GetPacketId() const;
100  uint32_t GetPacketSize() const;
101 
102  private:
103  uint32_t m_flowId;
104  uint32_t m_packetId;
105  uint32_t m_packetSize;
106 };
107 
108 TypeId
110 {
111  static TypeId tid = TypeId("ns3::Ipv6FlowProbeTag")
112  .SetParent<Tag>()
113  .SetGroupName("FlowMonitor")
114  .AddConstructor<Ipv6FlowProbeTag>();
115  return tid;
116 }
117 
118 TypeId
120 {
121  return GetTypeId();
122 }
123 
124 uint32_t
126 {
127  return 4 + 4 + 4;
128 }
129 
130 void
132 {
133  buf.WriteU32(m_flowId);
134  buf.WriteU32(m_packetId);
135  buf.WriteU32(m_packetSize);
136 }
137 
138 void
140 {
141  m_flowId = buf.ReadU32();
142  m_packetId = buf.ReadU32();
143  m_packetSize = buf.ReadU32();
144 }
145 
146 void
147 Ipv6FlowProbeTag::Print(std::ostream& os) const
148 {
149  os << "FlowId=" << m_flowId;
150  os << "PacketId=" << m_packetId;
151  os << "PacketSize=" << m_packetSize;
152 }
153 
155  : Tag()
156 {
157 }
158 
159 Ipv6FlowProbeTag::Ipv6FlowProbeTag(uint32_t flowId, uint32_t packetId, uint32_t packetSize)
160  : Tag(),
161  m_flowId(flowId),
162  m_packetId(packetId),
163  m_packetSize(packetSize)
164 {
165 }
166 
167 void
169 {
170  m_flowId = id;
171 }
172 
173 void
175 {
176  m_packetId = id;
177 }
178 
179 void
181 {
182  m_packetSize = size;
183 }
184 
185 uint32_t
187 {
188  return m_flowId;
189 }
190 
191 uint32_t
193 {
194  return m_packetId;
195 }
196 
197 uint32_t
199 {
200  return m_packetSize;
201 }
202 
204 // Ipv6FlowProbe class implementation //
206 
208  Ptr<Ipv6FlowClassifier> classifier,
209  Ptr<Node> node)
210  : FlowProbe(monitor),
211  m_classifier(classifier)
212 {
213  NS_LOG_FUNCTION(this << node->GetId());
214 
216 
217  if (!ipv6->TraceConnectWithoutContext(
218  "SendOutgoing",
220  {
221  NS_FATAL_ERROR("trace fail");
222  }
223  if (!ipv6->TraceConnectWithoutContext(
224  "UnicastForward",
226  {
227  NS_FATAL_ERROR("trace fail");
228  }
229  if (!ipv6->TraceConnectWithoutContext(
230  "LocalDeliver",
232  {
233  NS_FATAL_ERROR("trace fail");
234  }
235 
236  if (!ipv6->TraceConnectWithoutContext(
237  "Drop",
239  {
240  NS_FATAL_ERROR("trace fail");
241  }
242 
243  std::ostringstream qd;
244  qd << "/NodeList/" << node->GetId() << "/$ns3::TrafficControlLayer/RootQueueDiscList/*/Drop";
246  qd.str(),
248 
249  // code copied from point-to-point-helper.cc
250  std::ostringstream oss;
251  oss << "/NodeList/" << node->GetId() << "/DeviceList/*/TxQueue/Drop";
253  oss.str(),
255 }
256 
257 /* static */
258 TypeId
260 {
261  static TypeId tid =
262  TypeId("ns3::Ipv6FlowProbe").SetParent<FlowProbe>().SetGroupName("FlowMonitor")
263  // No AddConstructor because this class has no default constructor.
264  ;
265 
266  return tid;
267 }
268 
270 {
271 }
272 
273 void
275 {
277 }
278 
279 void
281  Ptr<const Packet> ipPayload,
282  uint32_t interface)
283 {
284  FlowId flowId;
285  FlowPacketId packetId;
286 
287  if (m_classifier->Classify(ipHeader, ipPayload, &flowId, &packetId))
288  {
289  uint32_t size = (ipPayload->GetSize() + ipHeader.GetSerializedSize());
290  NS_LOG_DEBUG("ReportFirstTx (" << this << ", " << flowId << ", " << packetId << ", " << size
291  << "); " << ipHeader << *ipPayload);
292  m_flowMonitor->ReportFirstTx(this, flowId, packetId, size);
293 
294  // tag the packet with the flow id and packet id, so that the packet can be identified even
295  // when Ipv6Header is not accessible at some non-IPv6 protocol layer
296  Ipv6FlowProbeTag fTag(flowId, packetId, size);
297  ipPayload->AddByteTag(fTag);
298  }
299 }
300 
301 void
303  Ptr<const Packet> ipPayload,
304  uint32_t interface)
305 {
306  Ipv6FlowProbeTag fTag;
307  bool found = ipPayload->FindFirstMatchingByteTag(fTag);
308 
309  if (found)
310  {
311  FlowId flowId = fTag.GetFlowId();
312  FlowPacketId packetId = fTag.GetPacketId();
313 
314  uint32_t size = (ipPayload->GetSize() + ipHeader.GetSerializedSize());
315  NS_LOG_DEBUG("ReportForwarding (" << this << ", " << flowId << ", " << packetId << ", "
316  << size << ");");
317  m_flowMonitor->ReportForwarding(this, flowId, packetId, size);
318  }
319 }
320 
321 void
323  Ptr<const Packet> ipPayload,
324  uint32_t interface)
325 {
326  Ipv6FlowProbeTag fTag;
327  bool found = ipPayload->FindFirstMatchingByteTag(fTag);
328 
329  if (found)
330  {
331  FlowId flowId = fTag.GetFlowId();
332  FlowPacketId packetId = fTag.GetPacketId();
333 
334  uint32_t size = (ipPayload->GetSize() + ipHeader.GetSerializedSize());
335  NS_LOG_DEBUG("ReportLastRx (" << this << ", " << flowId << ", " << packetId << ", " << size
336  << ");");
337  m_flowMonitor->ReportLastRx(this, flowId, packetId, size);
338  }
339 }
340 
341 void
343  Ptr<const Packet> ipPayload,
345  Ptr<Ipv6> ipv6,
346  uint32_t ifIndex)
347 {
348 #if 0
349  switch (reason)
350  {
352  break;
353 
355  case Ipv6L3Protocol::DROP_BAD_CHECKSUM:
356  Ipv6Address addri = m_ipv6->GetAddress (ifIndex);
357  Ipv6Mask maski = m_ipv6->GetNetworkMask (ifIndex);
358  Ipv6Address bcast = addri.GetSubnetDirectedBroadcast (maski);
359  if (ipHeader.GetDestination () == bcast) // we don't want broadcast packets
360  {
361  return;
362  }
363  }
364 #endif
365 
366  Ipv6FlowProbeTag fTag;
367  bool found = ipPayload->FindFirstMatchingByteTag(fTag);
368 
369  if (found)
370  {
371  FlowId flowId = fTag.GetFlowId();
372  FlowPacketId packetId = fTag.GetPacketId();
373 
374  uint32_t size = (ipPayload->GetSize() + ipHeader.GetSerializedSize());
375  NS_LOG_DEBUG("Drop (" << this << ", " << flowId << ", " << packetId << ", " << size << ", "
376  << reason << ", destIp=" << ipHeader.GetDestination() << "); "
377  << "HDR: " << ipHeader << " PKT: " << *ipPayload);
378 
379  DropReason myReason;
380 
381  switch (reason)
382  {
384  myReason = DROP_TTL_EXPIRE;
385  NS_LOG_DEBUG("DROP_TTL_EXPIRE");
386  break;
388  myReason = DROP_NO_ROUTE;
389  NS_LOG_DEBUG("DROP_NO_ROUTE");
390  break;
392  myReason = DROP_INTERFACE_DOWN;
393  NS_LOG_DEBUG("DROP_INTERFACE_DOWN");
394  break;
396  myReason = DROP_ROUTE_ERROR;
397  NS_LOG_DEBUG("DROP_ROUTE_ERROR");
398  break;
400  myReason = DROP_UNKNOWN_PROTOCOL;
401  NS_LOG_DEBUG("DROP_UNKNOWN_PROTOCOL");
402  break;
404  myReason = DROP_UNKNOWN_OPTION;
405  NS_LOG_DEBUG("DROP_UNKNOWN_OPTION");
406  break;
408  myReason = DROP_MALFORMED_HEADER;
409  NS_LOG_DEBUG("DROP_MALFORMED_HEADER");
410  break;
412  myReason = DROP_FRAGMENT_TIMEOUT;
413  NS_LOG_DEBUG("DROP_FRAGMENT_TIMEOUT");
414  break;
415  default:
416  myReason = DROP_INVALID_REASON;
417  NS_FATAL_ERROR("Unexpected drop reason code " << reason);
418  }
419 
420  m_flowMonitor->ReportDrop(this, flowId, packetId, size, myReason);
421  }
422 }
423 
424 void
426 {
427  Ipv6FlowProbeTag fTag;
428  bool tagFound = ipPayload->FindFirstMatchingByteTag(fTag);
429 
430  if (!tagFound)
431  {
432  return;
433  }
434 
435  FlowId flowId = fTag.GetFlowId();
436  FlowPacketId packetId = fTag.GetPacketId();
437  uint32_t size = fTag.GetPacketSize();
438 
439  NS_LOG_DEBUG("Drop (" << this << ", " << flowId << ", " << packetId << ", " << size << ", "
440  << DROP_QUEUE << "); ");
441 
442  m_flowMonitor->ReportDrop(this, flowId, packetId, size, DROP_QUEUE);
443 }
444 
445 void
447 {
448  Ipv6FlowProbeTag fTag;
449  bool tagFound = item->GetPacket()->FindFirstMatchingByteTag(fTag);
450 
451  if (!tagFound)
452  {
453  return;
454  }
455 
456  FlowId flowId = fTag.GetFlowId();
457  FlowPacketId packetId = fTag.GetPacketId();
458  uint32_t size = fTag.GetPacketSize();
459 
460  NS_LOG_DEBUG("Drop (" << this << ", " << flowId << ", " << packetId << ", " << size << ", "
461  << DROP_QUEUE_DISC << "); ");
462 
463  m_flowMonitor->ReportDrop(this, flowId, packetId, size, DROP_QUEUE_DISC);
464 }
465 
466 } // namespace ns3
The FlowProbe class is responsible for listening for packet events in a specific point of the simulat...
Definition: flow-probe.h:40
void DoDispose() override
Destructor implementation.
Definition: flow-probe.cc:49
Ptr< FlowMonitor > m_flowMonitor
the FlowMonitor instance
Definition: flow-probe.h:108
Describes an IPv6 address.
Definition: ipv6-address.h:50
void DoDispose() override
Destructor implementation.
void QueueDiscDropLogger(Ptr< const QueueDiscItem > item)
Log a packet being dropped by a queue disc.
void QueueDropLogger(Ptr< const Packet > ipPayload)
Log a packet being dropped by a queue.
static TypeId GetTypeId()
Register this type.
Ptr< Ipv6FlowClassifier > m_classifier
the Ipv6FlowClassifier this probe is associated with
void DropLogger(const Ipv6Header &ipHeader, Ptr< const Packet > ipPayload, Ipv6L3Protocol::DropReason reason, Ptr< Ipv6 > ipv6, uint32_t ifIndex)
Log a packet being dropped.
void ForwardLogger(const Ipv6Header &ipHeader, Ptr< const Packet > ipPayload, uint32_t interface)
Log a packet being forwarded.
Ipv6FlowProbe(Ptr< FlowMonitor > monitor, Ptr< Ipv6FlowClassifier > classifier, Ptr< Node > node)
Constructor.
void ForwardUpLogger(const Ipv6Header &ipHeader, Ptr< const Packet > ipPayload, uint32_t interface)
Log a packet being received by the destination.
DropReason
enumeration of possible reasons why a packet may be dropped
@ DROP_TTL_EXPIRE
Packet dropped due to TTL decremented to zero during IPv4 forwarding.
@ DROP_FRAGMENT_TIMEOUT
Fragment timeout exceeded.
@ DROP_NO_ROUTE
Packet dropped due to missing route to the destination.
@ DROP_UNKNOWN_OPTION
Unknown option.
@ DROP_QUEUE_DISC
Packet dropped by the queue disc.
@ DROP_INTERFACE_DOWN
Interface is down so can not send packet.
@ DROP_MALFORMED_HEADER
Malformed header.
@ DROP_ROUTE_ERROR
Route error.
@ DROP_UNKNOWN_PROTOCOL
Unknown L4 protocol.
@ DROP_INVALID_REASON
Fallback reason (no known reason)
@ DROP_QUEUE
Packet dropped due to queue overflow.
void SendOutgoingLogger(const Ipv6Header &ipHeader, Ptr< const Packet > ipPayload, uint32_t interface)
Log a packet being sent.
Tag used to allow a fast identification of the packet.
uint32_t GetFlowId() const
Set the flow identifier.
uint32_t m_flowId
flow identifier
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
void SetFlowId(uint32_t flowId)
Set the flow identifier.
void SetPacketId(uint32_t packetId)
Set the packet identifier.
void Deserialize(TagBuffer buf) override
void SetPacketSize(uint32_t packetSize)
Set the packet size.
uint32_t GetPacketSize() const
Get the packet size.
static TypeId GetTypeId()
Get the type ID.
uint32_t GetPacketId() const
Set the packet identifier.
uint32_t GetSerializedSize() const override
void Print(std::ostream &os) const override
void Serialize(TagBuffer buf) const override
uint32_t m_packetSize
packet size
uint32_t m_packetId
packet identifier
Packet header for IPv6.
Definition: ipv6-header.h:36
Ipv6Address GetDestination() const
Get the "Destination address" field.
Definition: ipv6-header.cc:124
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
Definition: ipv6-header.cc:159
IPv6 layer implementation.
DropReason
Reason why a packet has been dropped.
@ DROP_FRAGMENT_TIMEOUT
Fragment timeout.
@ DROP_ROUTE_ERROR
Route error.
@ DROP_TTL_EXPIRED
Packet TTL has expired.
@ DROP_INTERFACE_DOWN
Interface is down so can not send packet.
@ DROP_UNKNOWN_OPTION
Unknown option.
@ DROP_NO_ROUTE
No route to host.
@ DROP_UNKNOWN_PROTOCOL
Unknown L4 protocol.
@ DROP_MALFORMED_HEADER
Malformed header.
uint32_t GetId() const
Definition: node.cc:117
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:863
bool FindFirstMatchingByteTag(Tag &tag) const
Finds the first tag matching the parameter Tag type.
Definition: packet.cc:962
void AddByteTag(const Tag &tag) const
Tag each byte included in this packet with a new byte tag.
Definition: packet.cc:934
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
read and write tag data
Definition: tag-buffer.h:52
TAG_BUFFER_INLINE uint32_t ReadU32()
Definition: tag-buffer.h:217
TAG_BUFFER_INLINE void WriteU32(uint32_t v)
Definition: tag-buffer.h:187
tag a set of bytes in a packet
Definition: tag.h:39
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
bool ConnectWithoutContextFailSafe(std::string path, const CallbackBase &cb)
Definition: config.cc:961
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
uint32_t FlowId
Abstract identifier of a packet flow.
uint32_t FlowPacketId
Abstract identifier of a packet within a flow.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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...
Definition: callback.h:707
static const uint32_t packetSize
Packet size generated at the AP.