A Discrete-Event Network Simulator
QKDNetSim v2.0 (NS-3 v3.41) @ (+)
API
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 "ipv6-flow-probe.h"
22 
23 #include "flow-monitor.h"
24 #include "ipv6-flow-classifier.h"
25 
26 #include "ns3/config.h"
27 #include "ns3/flow-id-tag.h"
28 #include "ns3/log.h"
29 #include "ns3/node.h"
30 #include "ns3/packet.h"
31 #include "ns3/pointer.h"
32 
33 namespace ns3
34 {
35 
36 NS_LOG_COMPONENT_DEFINE("Ipv6FlowProbe");
37 
39 // Ipv6FlowProbeTag class implementation //
41 
51 class Ipv6FlowProbeTag : public Tag
52 {
53  public:
58  static TypeId GetTypeId();
59  TypeId GetInstanceTypeId() const override;
60  uint32_t GetSerializedSize() const override;
61  void Serialize(TagBuffer buf) const override;
62  void Deserialize(TagBuffer buf) override;
63  void Print(std::ostream& os) const override;
71  Ipv6FlowProbeTag(uint32_t flowId, uint32_t packetId, uint32_t packetSize);
76  void SetFlowId(uint32_t flowId);
81  void SetPacketId(uint32_t packetId);
86  void SetPacketSize(uint32_t packetSize);
91  uint32_t GetFlowId() const;
96  uint32_t GetPacketId() const;
101  uint32_t GetPacketSize() const;
102 
103  private:
104  uint32_t m_flowId;
105  uint32_t m_packetId;
106  uint32_t m_packetSize;
107 };
108 
109 TypeId
111 {
112  static TypeId tid = TypeId("ns3::Ipv6FlowProbeTag")
113  .SetParent<Tag>()
114  .SetGroupName("FlowMonitor")
115  .AddConstructor<Ipv6FlowProbeTag>();
116  return tid;
117 }
118 
119 TypeId
121 {
122  return GetTypeId();
123 }
124 
125 uint32_t
127 {
128  return 4 + 4 + 4;
129 }
130 
131 void
133 {
134  buf.WriteU32(m_flowId);
135  buf.WriteU32(m_packetId);
136  buf.WriteU32(m_packetSize);
137 }
138 
139 void
141 {
142  m_flowId = buf.ReadU32();
143  m_packetId = buf.ReadU32();
144  m_packetSize = buf.ReadU32();
145 }
146 
147 void
148 Ipv6FlowProbeTag::Print(std::ostream& os) const
149 {
150  os << "FlowId=" << m_flowId;
151  os << "PacketId=" << m_packetId;
152  os << "PacketSize=" << m_packetSize;
153 }
154 
156  : Tag()
157 {
158 }
159 
160 Ipv6FlowProbeTag::Ipv6FlowProbeTag(uint32_t flowId, uint32_t packetId, uint32_t packetSize)
161  : Tag(),
162  m_flowId(flowId),
163  m_packetId(packetId),
164  m_packetSize(packetSize)
165 {
166 }
167 
168 void
170 {
171  m_flowId = id;
172 }
173 
174 void
176 {
177  m_packetId = id;
178 }
179 
180 void
182 {
183  m_packetSize = size;
184 }
185 
186 uint32_t
188 {
189  return m_flowId;
190 }
191 
192 uint32_t
194 {
195  return m_packetId;
196 }
197 
198 uint32_t
200 {
201  return m_packetSize;
202 }
203 
205 // Ipv6FlowProbe class implementation //
207 
209  Ptr<Ipv6FlowClassifier> classifier,
210  Ptr<Node> node)
211  : FlowProbe(monitor),
212  m_classifier(classifier)
213 {
214  NS_LOG_FUNCTION(this << node->GetId());
215 
217 
218  if (!ipv6->TraceConnectWithoutContext(
219  "SendOutgoing",
221  {
222  NS_FATAL_ERROR("trace fail");
223  }
224  if (!ipv6->TraceConnectWithoutContext(
225  "UnicastForward",
227  {
228  NS_FATAL_ERROR("trace fail");
229  }
230  if (!ipv6->TraceConnectWithoutContext(
231  "LocalDeliver",
233  {
234  NS_FATAL_ERROR("trace fail");
235  }
236 
237  if (!ipv6->TraceConnectWithoutContext(
238  "Drop",
240  {
241  NS_FATAL_ERROR("trace fail");
242  }
243 
244  std::ostringstream qd;
245  qd << "/NodeList/" << node->GetId() << "/$ns3::TrafficControlLayer/RootQueueDiscList/*/Drop";
247  qd.str(),
249 
250  // code copied from point-to-point-helper.cc
251  std::ostringstream oss;
252  oss << "/NodeList/" << node->GetId() << "/DeviceList/*/TxQueue/Drop";
254  oss.str(),
256 }
257 
258 /* static */
259 TypeId
261 {
262  static TypeId tid =
263  TypeId("ns3::Ipv6FlowProbe").SetParent<FlowProbe>().SetGroupName("FlowMonitor")
264  // No AddConstructor because this class has no default constructor.
265  ;
266 
267  return tid;
268 }
269 
271 {
272 }
273 
274 void
276 {
278 }
279 
280 void
282  Ptr<const Packet> ipPayload,
283  uint32_t interface)
284 {
285  FlowId flowId;
286  FlowPacketId packetId;
287 
288  if (m_classifier->Classify(ipHeader, ipPayload, &flowId, &packetId))
289  {
290  uint32_t size = (ipPayload->GetSize() + ipHeader.GetSerializedSize());
291  NS_LOG_DEBUG("ReportFirstTx (" << this << ", " << flowId << ", " << packetId << ", " << size
292  << "); " << ipHeader << *ipPayload);
293  m_flowMonitor->ReportFirstTx(this, flowId, packetId, size);
294 
295  // tag the packet with the flow id and packet id, so that the packet can be identified even
296  // when Ipv6Header is not accessible at some non-IPv6 protocol layer
297  Ipv6FlowProbeTag fTag(flowId, packetId, size);
298  ipPayload->AddByteTag(fTag);
299  }
300 }
301 
302 void
304  Ptr<const Packet> ipPayload,
305  uint32_t interface)
306 {
307  Ipv6FlowProbeTag fTag;
308  bool found = ipPayload->FindFirstMatchingByteTag(fTag);
309 
310  if (found)
311  {
312  FlowId flowId = fTag.GetFlowId();
313  FlowPacketId packetId = fTag.GetPacketId();
314 
315  uint32_t size = (ipPayload->GetSize() + ipHeader.GetSerializedSize());
316  NS_LOG_DEBUG("ReportForwarding (" << this << ", " << flowId << ", " << packetId << ", "
317  << size << ");");
318  m_flowMonitor->ReportForwarding(this, flowId, packetId, size);
319  }
320 }
321 
322 void
324  Ptr<const Packet> ipPayload,
325  uint32_t interface)
326 {
327  Ipv6FlowProbeTag fTag;
328  bool found = ipPayload->FindFirstMatchingByteTag(fTag);
329 
330  if (found)
331  {
332  FlowId flowId = fTag.GetFlowId();
333  FlowPacketId packetId = fTag.GetPacketId();
334 
335  uint32_t size = (ipPayload->GetSize() + ipHeader.GetSerializedSize());
336  NS_LOG_DEBUG("ReportLastRx (" << this << ", " << flowId << ", " << packetId << ", " << size
337  << ");");
338  m_flowMonitor->ReportLastRx(this, flowId, packetId, size);
339  }
340 }
341 
342 void
344  Ptr<const Packet> ipPayload,
346  Ptr<Ipv6> ipv6,
347  uint32_t ifIndex)
348 {
349 #if 0
350  switch (reason)
351  {
353  break;
354 
356  case Ipv6L3Protocol::DROP_BAD_CHECKSUM:
357  Ipv6Address addri = m_ipv6->GetAddress (ifIndex);
358  Ipv6Mask maski = m_ipv6->GetNetworkMask (ifIndex);
359  Ipv6Address bcast = addri.GetSubnetDirectedBroadcast (maski);
360  if (ipHeader.GetDestination () == bcast) // we don't want broadcast packets
361  {
362  return;
363  }
364  }
365 #endif
366 
367  Ipv6FlowProbeTag fTag;
368  bool found = ipPayload->FindFirstMatchingByteTag(fTag);
369 
370  if (found)
371  {
372  FlowId flowId = fTag.GetFlowId();
373  FlowPacketId packetId = fTag.GetPacketId();
374 
375  uint32_t size = (ipPayload->GetSize() + ipHeader.GetSerializedSize());
376  NS_LOG_DEBUG("Drop (" << this << ", " << flowId << ", " << packetId << ", " << size << ", "
377  << reason << ", destIp=" << ipHeader.GetDestination() << "); "
378  << "HDR: " << ipHeader << " PKT: " << *ipPayload);
379 
380  DropReason myReason;
381 
382  switch (reason)
383  {
385  myReason = DROP_TTL_EXPIRE;
386  NS_LOG_DEBUG("DROP_TTL_EXPIRE");
387  break;
389  myReason = DROP_NO_ROUTE;
390  NS_LOG_DEBUG("DROP_NO_ROUTE");
391  break;
393  myReason = DROP_INTERFACE_DOWN;
394  NS_LOG_DEBUG("DROP_INTERFACE_DOWN");
395  break;
397  myReason = DROP_ROUTE_ERROR;
398  NS_LOG_DEBUG("DROP_ROUTE_ERROR");
399  break;
401  myReason = DROP_UNKNOWN_PROTOCOL;
402  NS_LOG_DEBUG("DROP_UNKNOWN_PROTOCOL");
403  break;
405  myReason = DROP_UNKNOWN_OPTION;
406  NS_LOG_DEBUG("DROP_UNKNOWN_OPTION");
407  break;
409  myReason = DROP_MALFORMED_HEADER;
410  NS_LOG_DEBUG("DROP_MALFORMED_HEADER");
411  break;
413  myReason = DROP_FRAGMENT_TIMEOUT;
414  NS_LOG_DEBUG("DROP_FRAGMENT_TIMEOUT");
415  break;
416  default:
417  myReason = DROP_INVALID_REASON;
418  NS_FATAL_ERROR("Unexpected drop reason code " << reason);
419  }
420 
421  m_flowMonitor->ReportDrop(this, flowId, packetId, size, myReason);
422  }
423 }
424 
425 void
427 {
428  Ipv6FlowProbeTag fTag;
429  bool tagFound = ipPayload->FindFirstMatchingByteTag(fTag);
430 
431  if (!tagFound)
432  {
433  return;
434  }
435 
436  FlowId flowId = fTag.GetFlowId();
437  FlowPacketId packetId = fTag.GetPacketId();
438  uint32_t size = fTag.GetPacketSize();
439 
440  NS_LOG_DEBUG("Drop (" << this << ", " << flowId << ", " << packetId << ", " << size << ", "
441  << DROP_QUEUE << "); ");
442 
443  m_flowMonitor->ReportDrop(this, flowId, packetId, size, DROP_QUEUE);
444 }
445 
446 void
448 {
449  Ipv6FlowProbeTag fTag;
450  bool tagFound = item->GetPacket()->FindFirstMatchingByteTag(fTag);
451 
452  if (!tagFound)
453  {
454  return;
455  }
456 
457  FlowId flowId = fTag.GetFlowId();
458  FlowPacketId packetId = fTag.GetPacketId();
459  uint32_t size = fTag.GetPacketSize();
460 
461  NS_LOG_DEBUG("Drop (" << this << ", " << flowId << ", " << packetId << ", " << size << ", "
462  << DROP_QUEUE_DISC << "); ");
463 
464  m_flowMonitor->ReportDrop(this, flowId, packetId, size, DROP_QUEUE_DISC);
465 }
466 
467 } // namespace ns3
The FlowProbe class is responsible for listening for packet events in a specific point of the simulat...
Definition: flow-probe.h:41
void DoDispose() override
Destructor implementation.
Definition: flow-probe.cc:49
Ptr< FlowMonitor > m_flowMonitor
the FlowMonitor instance
Definition: flow-probe.h:109
Describes an IPv6 address.
Definition: ipv6-address.h:49
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:35
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:861
bool FindFirstMatchingByteTag(Tag &tag) const
Finds the first tag matching the parameter Tag type.
Definition: packet.cc:943
void AddByteTag(const Tag &tag) const
Tag each byte included in this packet with a new byte tag.
Definition: packet.cc:915
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
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:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
bool ConnectWithoutContextFailSafe(std::string path, const CallbackBase &cb)
Definition: config.cc:960
#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:704
static const uint32_t packetSize
Packet size generated at the AP.