A Discrete-Event Network Simulator
API
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
31namespace ns3 {
32
33NS_LOG_COMPONENT_DEFINE ("Ipv4FlowProbe");
34
36// Ipv4FlowProbeTag class implementation //
38
48class Ipv4FlowProbeTag : public Tag
49{
50public:
55 static TypeId GetTypeId (void);
56 virtual TypeId GetInstanceTypeId (void) const;
57 virtual uint32_t GetSerializedSize (void) const;
58 virtual void Serialize (TagBuffer buf) const;
59 virtual void Deserialize (TagBuffer buf);
60 virtual void Print (std::ostream &os) const;
75 void SetFlowId (uint32_t flowId);
80 void SetPacketId (uint32_t packetId);
90 uint32_t GetFlowId (void) const;
95 uint32_t GetPacketId (void) const;
100 uint32_t GetPacketSize (void) const;
111 bool IsSrcDstValid (Ipv4Address src, Ipv4Address dst) const;
112private:
118};
119
120TypeId
122{
123 static TypeId tid = TypeId ("ns3::Ipv4FlowProbeTag")
124 .SetParent<Tag> ()
125 .SetGroupName ("FlowMonitor")
126 .AddConstructor<Ipv4FlowProbeTag> ()
127 ;
128 return tid;
129}
130TypeId
132{
133 return GetTypeId ();
134}
137{
138 return 4 + 4 + 4 + 8;
139}
140void
142{
143 buf.WriteU32 (m_flowId);
144 buf.WriteU32 (m_packetId);
146
147 uint8_t tBuf[4];
148 m_src.Serialize (tBuf);
149 buf.Write (tBuf, 4);
150 m_dst.Serialize (tBuf);
151 buf.Write (tBuf, 4);
152}
153void
155{
156 m_flowId = buf.ReadU32 ();
157 m_packetId = buf.ReadU32 ();
158 m_packetSize = buf.ReadU32 ();
159
160 uint8_t tBuf[4];
161 buf.Read (tBuf, 4);
163 buf.Read (tBuf, 4);
165}
166void
167Ipv4FlowProbeTag::Print (std::ostream &os) const
168{
169 os << "FlowId=" << m_flowId;
170 os << " PacketId=" << m_packetId;
171 os << " PacketSize=" << m_packetSize;
172}
174 : Tag ()
175{
176}
177
179 : Tag (), m_flowId (flowId), m_packetId (packetId), m_packetSize (packetSize), m_src (src), m_dst (dst)
180{
181}
182
183void
185{
186 m_flowId = id;
187}
188void
190{
191 m_packetId = id;
192}
193void
195{
196 m_packetSize = size;
197}
200{
201 return m_flowId;
202}
205{
206 return m_packetId;
207}
210{
211 return m_packetSize;
212}
213bool
215{
216 return ((m_src == src) && (m_dst == dst));
217}
218
220// Ipv4FlowProbe class implementation //
222
224 Ptr<Ipv4FlowClassifier> classifier,
225 Ptr<Node> node)
226 : FlowProbe (monitor),
227 m_classifier (classifier)
228{
229 NS_LOG_FUNCTION (this << node->GetId ());
230
231 m_ipv4 = node->GetObject<Ipv4L3Protocol> ();
232
233 if (!m_ipv4->TraceConnectWithoutContext ("SendOutgoing",
235 {
236 NS_FATAL_ERROR ("trace fail");
237 }
238 if (!m_ipv4->TraceConnectWithoutContext ("UnicastForward",
240 {
241 NS_FATAL_ERROR ("trace fail");
242 }
243 if (!m_ipv4->TraceConnectWithoutContext ("LocalDeliver",
245 {
246 NS_FATAL_ERROR ("trace fail");
247 }
248
249 if (!m_ipv4->TraceConnectWithoutContext ("Drop",
251 {
252 NS_FATAL_ERROR ("trace fail");
253 }
254
255 std::ostringstream qd;
256 qd << "/NodeList/" << node->GetId () << "/$ns3::TrafficControlLayer/RootQueueDiscList/*/Drop";
258
259 // code copied from point-to-point-helper.cc
260 std::ostringstream oss;
261 oss << "/NodeList/" << node->GetId () << "/DeviceList/*/TxQueue/Drop";
263}
264
266{
267}
268
269/* static */
270TypeId
272{
273 static TypeId tid = TypeId ("ns3::Ipv4FlowProbe")
275 .SetGroupName ("FlowMonitor")
276 // No AddConstructor because this class has no default constructor.
277 ;
278
279 return tid;
280}
281
282void
284{
285 m_ipv4 = 0;
286 m_classifier = 0;
288}
289
290void
292{
293 FlowId flowId;
294 FlowPacketId packetId;
295
296 if (!m_ipv4->IsUnicast(ipHeader.GetDestination ()))
297 {
298 // we are not prepared to handle broadcast yet
299 return;
300 }
301
302 Ipv4FlowProbeTag fTag;
303 bool found = ipPayload->FindFirstMatchingByteTag (fTag);
304 if (found)
305 {
306 return;
307 }
308
309 if (m_classifier->Classify (ipHeader, ipPayload, &flowId, &packetId))
310 {
311 uint32_t size = (ipPayload->GetSize () + ipHeader.GetSerializedSize ());
312 NS_LOG_DEBUG ("ReportFirstTx ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<"); "
313 << ipHeader << *ipPayload);
314 m_flowMonitor->ReportFirstTx (this, flowId, packetId, size);
315
316 // tag the packet with the flow id and packet id, so that the packet can be identified even
317 // when Ipv4Header is not accessible at some non-IPv4 protocol layer
318 Ipv4FlowProbeTag fTag (flowId, packetId, size, ipHeader.GetSource (), ipHeader.GetDestination ());
319 ipPayload->AddByteTag (fTag);
320 }
321}
322
323void
325{
326 Ipv4FlowProbeTag fTag;
327 bool found = ipPayload->FindFirstMatchingByteTag (fTag);
328
329 if (found)
330 {
331 if (!ipHeader.IsLastFragment () || ipHeader.GetFragmentOffset () != 0)
332 {
333 NS_LOG_WARN ("Not counting fragmented packets");
334 return;
335 }
336 if (!fTag.IsSrcDstValid (ipHeader.GetSource (), ipHeader.GetDestination ()))
337 {
338 NS_LOG_LOGIC ("Not reporting encapsulated packet");
339 return;
340 }
341
342 FlowId flowId = fTag.GetFlowId ();
343 FlowPacketId packetId = fTag.GetPacketId ();
344
345 uint32_t size = (ipPayload->GetSize () + ipHeader.GetSerializedSize ());
346 NS_LOG_DEBUG ("ReportForwarding ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<");");
347 m_flowMonitor->ReportForwarding (this, flowId, packetId, size);
348 }
349}
350
351void
353{
354 Ipv4FlowProbeTag fTag;
355 bool found = ipPayload->FindFirstMatchingByteTag (fTag);
356
357 if (found)
358 {
359 if (!fTag.IsSrcDstValid (ipHeader.GetSource (), ipHeader.GetDestination ()))
360 {
361 NS_LOG_LOGIC ("Not reporting encapsulated packet");
362 return;
363 }
364
365 FlowId flowId = fTag.GetFlowId ();
366 FlowPacketId packetId = fTag.GetPacketId ();
367
368 uint32_t size = (ipPayload->GetSize () + ipHeader.GetSerializedSize ());
369 NS_LOG_DEBUG ("ReportLastRx ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<"); "
370 << ipHeader << *ipPayload);
371 m_flowMonitor->ReportLastRx (this, flowId, packetId, size);
372 }
373}
374
375void
377 Ipv4L3Protocol::DropReason reason, Ptr<Ipv4> ipv4, uint32_t ifIndex)
378{
379#if 0
380 switch (reason)
381 {
383 break;
384
387 Ipv4Address addri = m_ipv4->GetAddress (ifIndex);
388 Ipv4Mask maski = m_ipv4->GetNetworkMask (ifIndex);
389 Ipv4Address bcast = addri.GetSubnetDirectedBroadcast (maski);
390 if (ipHeader.GetDestination () == bcast) // we don't want broadcast packets
391 {
392 return;
393 }
394 }
395#endif
396
397 Ipv4FlowProbeTag fTag;
398 bool found = ipPayload->FindFirstMatchingByteTag (fTag);
399
400 if (found)
401 {
402 FlowId flowId = fTag.GetFlowId ();
403 FlowPacketId packetId = fTag.GetPacketId ();
404
405 uint32_t size = (ipPayload->GetSize () + ipHeader.GetSerializedSize ());
406 NS_LOG_DEBUG ("Drop ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<", " << reason
407 << ", destIp=" << ipHeader.GetDestination () << "); "
408 << "HDR: " << ipHeader << " PKT: " << *ipPayload);
409
410 DropReason myReason;
411
412
413 switch (reason)
414 {
416 myReason = DROP_TTL_EXPIRE;
417 NS_LOG_DEBUG ("DROP_TTL_EXPIRE");
418 break;
420 myReason = DROP_NO_ROUTE;
421 NS_LOG_DEBUG ("DROP_NO_ROUTE");
422 break;
424 myReason = DROP_BAD_CHECKSUM;
425 NS_LOG_DEBUG ("DROP_BAD_CHECKSUM");
426 break;
428 myReason = DROP_INTERFACE_DOWN;
429 NS_LOG_DEBUG ("DROP_INTERFACE_DOWN");
430 break;
432 myReason = DROP_ROUTE_ERROR;
433 NS_LOG_DEBUG ("DROP_ROUTE_ERROR");
434 break;
436 myReason = DROP_FRAGMENT_TIMEOUT;
437 NS_LOG_DEBUG ("DROP_FRAGMENT_TIMEOUT");
438 break;
439
440 default:
441 myReason = DROP_INVALID_REASON;
442 NS_FATAL_ERROR ("Unexpected drop reason code " << reason);
443 }
444
445 m_flowMonitor->ReportDrop (this, flowId, packetId, size, myReason);
446 }
447}
448
449void
451{
452 Ipv4FlowProbeTag fTag;
453 bool tagFound = ipPayload->FindFirstMatchingByteTag (fTag);
454
455 if (!tagFound)
456 {
457 return;
458 }
459
460 FlowId flowId = fTag.GetFlowId ();
461 FlowPacketId packetId = fTag.GetPacketId ();
462 uint32_t size = fTag.GetPacketSize ();
463
464 NS_LOG_DEBUG ("Drop ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<", " << DROP_QUEUE
465 << "); ");
466
467 m_flowMonitor->ReportDrop (this, flowId, packetId, size, DROP_QUEUE);
468}
469
470void
472{
473 Ipv4FlowProbeTag fTag;
474 bool tagFound = item->GetPacket ()->FindFirstMatchingByteTag (fTag);
475
476 if (!tagFound)
477 {
478 return;
479 }
480
481 FlowId flowId = fTag.GetFlowId ();
482 FlowPacketId packetId = fTag.GetPacketId ();
483 uint32_t size = fTag.GetPacketSize ();
484
485 NS_LOG_DEBUG ("Drop ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<", " << DROP_QUEUE_DISC
486 << "); ");
487
488 m_flowMonitor->ReportDrop (this, flowId, packetId, size, DROP_QUEUE_DISC);
489}
490
491} // namespace ns3
492
493
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
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
void Serialize(uint8_t buf[4]) const
Serialize this address to a 4-byte buffer.
static Ipv4Address Deserialize(const uint8_t buf[4])
Ipv4Address GetSubnetDirectedBroadcast(Ipv4Mask const &mask) const
Generate subnet-directed broadcast address corresponding to mask.
DropReason
enumeration of possible reasons why a packet may be dropped
@ DROP_ROUTE_ERROR
Route error.
@ DROP_BAD_CHECKSUM
Packet dropped due to invalid checksum in the IPv4 header.
@ DROP_TTL_EXPIRE
Packet dropped due to TTL decremented to zero during IPv4 forwarding.
@ DROP_INTERFACE_DOWN
Interface is down so can not send packet.
@ DROP_NO_ROUTE
Packet dropped due to missing route to the destination.
@ DROP_INVALID_REASON
Fallback reason (no known reason)
@ DROP_QUEUE_DISC
Packet dropped by the queue disc.
@ DROP_FRAGMENT_TIMEOUT
Fragment timeout exceeded.
@ DROP_QUEUE
Packet dropped due to queue overflow.
static TypeId GetTypeId(void)
Register this type.
void SendOutgoingLogger(const Ipv4Header &ipHeader, Ptr< const Packet > ipPayload, uint32_t interface)
Log a packet being sent.
void DropLogger(const Ipv4Header &ipHeader, Ptr< const Packet > ipPayload, Ipv4L3Protocol::DropReason reason, Ptr< Ipv4 > ipv4, uint32_t ifIndex)
Log a packet being dropped.
void QueueDropLogger(Ptr< const Packet > ipPayload)
Log a packet being dropped by a queue.
void ForwardUpLogger(const Ipv4Header &ipHeader, Ptr< const Packet > ipPayload, uint32_t interface)
Log a packet being received by the destination.
Ptr< Ipv4L3Protocol > m_ipv4
the Ipv4L3Protocol this probe is bound to
Ipv4FlowProbe(Ptr< FlowMonitor > monitor, Ptr< Ipv4FlowClassifier > classifier, Ptr< Node > node)
Constructor.
void QueueDiscDropLogger(Ptr< const QueueDiscItem > item)
Log a packet being dropped by a queue disc.
void ForwardLogger(const Ipv4Header &ipHeader, Ptr< const Packet > ipPayload, uint32_t interface)
Log a packet being forwarded.
Ptr< Ipv4FlowClassifier > m_classifier
the Ipv4FlowClassifier this probe is associated with
virtual void DoDispose(void)
Destructor implementation.
Tag used to allow a fast identification of the packet.
uint32_t m_packetSize
packet size
virtual void Deserialize(TagBuffer buf)
bool IsSrcDstValid(Ipv4Address src, Ipv4Address dst) const
Checks if the addresses stored in tag are matching the arguments.
Ipv4Address m_dst
IP destination.
virtual void Serialize(TagBuffer buf) const
static TypeId GetTypeId(void)
Get the type ID.
uint32_t GetPacketId(void) const
Set the packet identifier.
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
void SetPacketSize(uint32_t packetSize)
Set the packet size.
uint32_t m_packetId
packet identifier
void SetFlowId(uint32_t flowId)
Set the flow identifier.
uint32_t m_flowId
flow identifier
virtual uint32_t GetSerializedSize(void) const
uint32_t GetPacketSize(void) const
Get the packet size.
uint32_t GetFlowId(void) const
Set the flow identifier.
void SetPacketId(uint32_t packetId)
Set the packet identifier.
virtual void Print(std::ostream &os) const
Ipv4Address m_src
IP source.
Packet header for IPv4.
Definition: ipv4-header.h:34
virtual uint32_t GetSerializedSize(void) const
Definition: ipv4-header.cc:375
uint16_t GetFragmentOffset(void) const
Definition: ipv4-header.cc:246
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
bool IsLastFragment(void) const
Definition: ipv4-header.cc:212
Implement the IPv4 layer.
DropReason
Reason why a packet has been dropped.
@ DROP_BAD_CHECKSUM
Bad checksum.
@ DROP_NO_ROUTE
No route to host.
@ DROP_INTERFACE_DOWN
Interface is down so can not send packet.
@ DROP_TTL_EXPIRED
Packet TTL has expired.
@ DROP_ROUTE_ERROR
Route error.
@ DROP_FRAGMENT_TIMEOUT
Fragment timeout exceeded.
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:256
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
void Read(uint8_t *buffer, uint32_t size)
Definition: tag-buffer.cc:176
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
void Write(const uint8_t *buffer, uint32_t size)
Definition: tag-buffer.cc:125
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_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:265
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.