A Discrete-Event Network Simulator
API
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
32namespace ns3 {
33
34NS_LOG_COMPONENT_DEFINE ("Ipv6FlowProbe");
35
37// Ipv6FlowProbeTag class implementation //
39
49class Ipv6FlowProbeTag : public Tag
50{
51public:
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;
74 void SetFlowId (uint32_t flowId);
79 void SetPacketId (uint32_t packetId);
89 uint32_t GetFlowId (void) const;
94 uint32_t GetPacketId (void) const;
99 uint32_t GetPacketSize (void) const;
100private:
104
105};
106
107TypeId
109{
110 static TypeId tid = TypeId ("ns3::Ipv6FlowProbeTag")
111 .SetParent<Tag> ()
112 .SetGroupName ("FlowMonitor")
113 .AddConstructor<Ipv6FlowProbeTag> ()
114 ;
115 return tid;
116}
117TypeId
119{
120 return GetTypeId ();
121}
124{
125 return 4 + 4 + 4;
126}
127void
129{
130 buf.WriteU32 (m_flowId);
131 buf.WriteU32 (m_packetId);
133}
134void
136{
137 m_flowId = buf.ReadU32 ();
138 m_packetId = buf.ReadU32 ();
139 m_packetSize = buf.ReadU32 ();
140}
141void
142Ipv6FlowProbeTag::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
154 : Tag (), m_flowId (flowId), m_packetId (packetId), m_packetSize (packetSize)
155{
156}
157
158void
160{
161 m_flowId = id;
162}
163void
165{
166 m_packetId = id;
167}
168void
170{
171 m_packetSize = size;
172}
175{
176 return m_flowId;
177}
180{
181 return m_packetId;
182}
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 std::ostringstream qd;
226 qd << "/NodeList/" << node->GetId () << "/$ns3::TrafficControlLayer/RootQueueDiscList/*/Drop";
228
229 // code copied from point-to-point-helper.cc
230 std::ostringstream oss;
231 oss << "/NodeList/" << node->GetId () << "/DeviceList/*/TxQueue/Drop";
233}
234
235/* static */
236TypeId
238{
239 static TypeId tid = TypeId ("ns3::Ipv6FlowProbe")
241 .SetGroupName ("FlowMonitor")
242 // No AddConstructor because this class has no default constructor.
243 ;
244
245 return tid;
246}
247
249{
250}
251
252void
254{
256}
257
258void
260{
261 FlowId flowId;
262 FlowPacketId packetId;
263
264 if (m_classifier->Classify (ipHeader, ipPayload, &flowId, &packetId))
265 {
266 uint32_t size = (ipPayload->GetSize () + ipHeader.GetSerializedSize ());
267 NS_LOG_DEBUG ("ReportFirstTx ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<"); "
268 << ipHeader << *ipPayload);
269 m_flowMonitor->ReportFirstTx (this, flowId, packetId, size);
270
271 // tag the packet with the flow id and packet id, so that the packet can be identified even
272 // when Ipv6Header is not accessible at some non-IPv6 protocol layer
273 Ipv6FlowProbeTag fTag (flowId, packetId, size);
274 ipPayload->AddByteTag (fTag);
275 }
276}
277
278void
280{
281 Ipv6FlowProbeTag fTag;
282 bool found = ipPayload->FindFirstMatchingByteTag (fTag);
283
284 if (found)
285 {
286 FlowId flowId = fTag.GetFlowId ();
287 FlowPacketId packetId = fTag.GetPacketId ();
288
289 uint32_t size = (ipPayload->GetSize () + ipHeader.GetSerializedSize ());
290 NS_LOG_DEBUG ("ReportForwarding ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<");");
291 m_flowMonitor->ReportForwarding (this, flowId, packetId, size);
292 }
293}
294
295void
297{
298 Ipv6FlowProbeTag fTag;
299 bool found = ipPayload->FindFirstMatchingByteTag (fTag);
300
301 if (found)
302 {
303 FlowId flowId = fTag.GetFlowId ();
304 FlowPacketId packetId = fTag.GetPacketId ();
305
306 uint32_t size = (ipPayload->GetSize () + ipHeader.GetSerializedSize ());
307 NS_LOG_DEBUG ("ReportLastRx ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<");");
308 m_flowMonitor->ReportLastRx (this, flowId, packetId, size);
309 }
310}
311
312void
314 Ipv6L3Protocol::DropReason reason, Ptr<Ipv6> ipv6, uint32_t ifIndex)
315{
316#if 0
317 switch (reason)
318 {
320 break;
321
323 case Ipv6L3Protocol::DROP_BAD_CHECKSUM:
324 Ipv6Address addri = m_ipv6->GetAddress (ifIndex);
325 Ipv6Mask maski = m_ipv6->GetNetworkMask (ifIndex);
326 Ipv6Address bcast = addri.GetSubnetDirectedBroadcast (maski);
327 if (ipHeader.GetDestination () == bcast) // we don't want broadcast packets
328 {
329 return;
330 }
331 }
332#endif
333
334 Ipv6FlowProbeTag fTag;
335 bool found = ipPayload->FindFirstMatchingByteTag (fTag);
336
337 if (found)
338 {
339 FlowId flowId = fTag.GetFlowId ();
340 FlowPacketId packetId = fTag.GetPacketId ();
341
342 uint32_t size = (ipPayload->GetSize () + ipHeader.GetSerializedSize ());
343 NS_LOG_DEBUG ("Drop ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<", " << reason
344 << ", destIp=" << ipHeader.GetDestination () << "); "
345 << "HDR: " << ipHeader << " PKT: " << *ipPayload);
346
347 DropReason myReason;
348
349
350 switch (reason)
351 {
353 myReason = DROP_TTL_EXPIRE;
354 NS_LOG_DEBUG ("DROP_TTL_EXPIRE");
355 break;
357 myReason = DROP_NO_ROUTE;
358 NS_LOG_DEBUG ("DROP_NO_ROUTE");
359 break;
361 myReason = DROP_INTERFACE_DOWN;
362 NS_LOG_DEBUG ("DROP_INTERFACE_DOWN");
363 break;
365 myReason = DROP_ROUTE_ERROR;
366 NS_LOG_DEBUG ("DROP_ROUTE_ERROR");
367 break;
369 myReason = DROP_UNKNOWN_PROTOCOL;
370 NS_LOG_DEBUG ("DROP_UNKNOWN_PROTOCOL");
371 break;
373 myReason = DROP_UNKNOWN_OPTION;
374 NS_LOG_DEBUG ("DROP_UNKNOWN_OPTION");
375 break;
377 myReason = DROP_MALFORMED_HEADER;
378 NS_LOG_DEBUG ("DROP_MALFORMED_HEADER");
379 break;
381 myReason = DROP_FRAGMENT_TIMEOUT;
382 NS_LOG_DEBUG ("DROP_FRAGMENT_TIMEOUT");
383 break;
384 default:
385 myReason = DROP_INVALID_REASON;
386 NS_FATAL_ERROR ("Unexpected drop reason code " << reason);
387 }
388
389 m_flowMonitor->ReportDrop (this, flowId, packetId, size, myReason);
390 }
391}
392
393void
395{
396 Ipv6FlowProbeTag fTag;
397 bool tagFound = ipPayload->FindFirstMatchingByteTag (fTag);
398
399 if (!tagFound)
400 {
401 return;
402 }
403
404 FlowId flowId = fTag.GetFlowId ();
405 FlowPacketId packetId = fTag.GetPacketId ();
406 uint32_t size = fTag.GetPacketSize ();
407
408 NS_LOG_DEBUG ("Drop ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<", " << DROP_QUEUE
409 << "); ");
410
411 m_flowMonitor->ReportDrop (this, flowId, packetId, size, DROP_QUEUE);
412}
413
414void
416{
417 Ipv6FlowProbeTag fTag;
418 bool tagFound = item->GetPacket ()->FindFirstMatchingByteTag (fTag);
419
420 if (!tagFound)
421 {
422 return;
423 }
424
425 FlowId flowId = fTag.GetFlowId ();
426 FlowPacketId packetId = fTag.GetPacketId ();
427 uint32_t size = fTag.GetPacketSize ();
428
429 NS_LOG_DEBUG ("Drop ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<", " << DROP_QUEUE_DISC
430 << "); ");
431
432 m_flowMonitor->ReportDrop (this, flowId, packetId, size, DROP_QUEUE_DISC);
433}
434
435} // namespace ns3
436
437
The FlowProbe class is responsible for listening for packet events in a specific point of the simulat...
Definition: flow-probe.h:40
virtual void DoDispose(void)
Destructor implementation.
Definition: flow-probe.cc:50
Ptr< FlowMonitor > m_flowMonitor
the FlowMonitor instance
Definition: flow-probe.h:103
Describes an IPv6 address.
Definition: ipv6-address.h:50
static TypeId GetTypeId(void)
Register this type.
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.
virtual void DoDispose(void)
Destructor implementation.
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 m_flowId
flow identifier
void SetFlowId(uint32_t flowId)
Set the flow identifier.
uint32_t GetPacketSize(void) const
Get the packet size.
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
void SetPacketId(uint32_t packetId)
Set the packet identifier.
void SetPacketSize(uint32_t packetSize)
Set the packet size.
uint32_t GetPacketId(void) const
Set the packet identifier.
virtual uint32_t GetSerializedSize(void) const
virtual void Serialize(TagBuffer buf) const
uint32_t GetFlowId(void) const
Set the flow identifier.
static TypeId GetTypeId(void)
Get the type ID.
virtual void Deserialize(TagBuffer buf)
uint32_t m_packetSize
packet size
uint32_t m_packetId
packet identifier
virtual void Print(std::ostream &os) const
Packet header for IPv6.
Definition: ipv6-header.h:36
virtual uint32_t GetSerializedSize(void) const
Get the serialized size of the packet.
Definition: ipv6-header.cc:163
Ipv6Address GetDestination(void) const
Get the "Destination address" field.
Definition: ipv6-header.cc:125
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(void) const
Definition: node.cc:109
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
bool FindFirstMatchingByteTag(Tag &tag) const
Finds the first tag matching the parameter Tag type.
Definition: packet.cc:939
void AddByteTag(const Tag &tag) const
Tag each byte included in this packet with a new byte tag.
Definition: packet.cc:912
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
read and write tag data
Definition: tag-buffer.h:52
TAG_BUFFER_INLINE uint32_t ReadU32(void)
Definition: tag-buffer.h:215
TAG_BUFFER_INLINE void WriteU32(uint32_t v)
Definition: tag-buffer.h:186
tag a set of bytes in a packet
Definition: tag.h:37
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
bool ConnectWithoutContextFailSafe(std::string path, const CallbackBase &cb)
Definition: config.cc:909
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#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, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
static const uint32_t packetSize
Pcket size generated at the AP.