A Discrete-Event Network Simulator
API
ipv4-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//
19
20#include "ns3/ipv4-flow-probe.h"
21
22#include "ns3/config.h"
23#include "ns3/flow-id-tag.h"
24#include "ns3/flow-monitor.h"
25#include "ns3/ipv4-flow-classifier.h"
26#include "ns3/log.h"
27#include "ns3/node.h"
28#include "ns3/packet.h"
29#include "ns3/pointer.h"
30
31namespace ns3
32{
33
34NS_LOG_COMPONENT_DEFINE("Ipv4FlowProbe");
35
37// Ipv4FlowProbeTag class implementation //
39
49class Ipv4FlowProbeTag : public Tag
50{
51 public:
56 static TypeId GetTypeId();
57 TypeId GetInstanceTypeId() const override;
58 uint32_t GetSerializedSize() const override;
59 void Serialize(TagBuffer buf) const override;
60 void Deserialize(TagBuffer buf) override;
61 void Print(std::ostream& os) const override;
72 uint32_t packetId,
74 Ipv4Address src,
75 Ipv4Address dst);
80 void SetFlowId(uint32_t flowId);
85 void SetPacketId(uint32_t packetId);
95 uint32_t GetFlowId() const;
100 uint32_t GetPacketId() const;
105 uint32_t GetPacketSize() const;
116 bool IsSrcDstValid(Ipv4Address src, Ipv4Address dst) const;
117
118 private:
124};
125
126TypeId
128{
129 static TypeId tid = TypeId("ns3::Ipv4FlowProbeTag")
130 .SetParent<Tag>()
131 .SetGroupName("FlowMonitor")
132 .AddConstructor<Ipv4FlowProbeTag>();
133 return tid;
134}
135
136TypeId
138{
139 return GetTypeId();
140}
141
144{
145 return 4 + 4 + 4 + 8;
146}
147
148void
150{
151 buf.WriteU32(m_flowId);
152 buf.WriteU32(m_packetId);
154
155 uint8_t tBuf[4];
156 m_src.Serialize(tBuf);
157 buf.Write(tBuf, 4);
158 m_dst.Serialize(tBuf);
159 buf.Write(tBuf, 4);
160}
161
162void
164{
165 m_flowId = buf.ReadU32();
166 m_packetId = buf.ReadU32();
167 m_packetSize = buf.ReadU32();
168
169 uint8_t tBuf[4];
170 buf.Read(tBuf, 4);
172 buf.Read(tBuf, 4);
174}
175
176void
177Ipv4FlowProbeTag::Print(std::ostream& os) const
178{
179 os << "FlowId=" << m_flowId;
180 os << " PacketId=" << m_packetId;
181 os << " PacketSize=" << m_packetSize;
182}
183
185 : Tag()
186{
187}
188
190 uint32_t packetId,
192 Ipv4Address src,
193 Ipv4Address dst)
194 : Tag(),
195 m_flowId(flowId),
196 m_packetId(packetId),
197 m_packetSize(packetSize),
198 m_src(src),
199 m_dst(dst)
200{
201}
202
203void
205{
206 m_flowId = id;
207}
208
209void
211{
212 m_packetId = id;
213}
214
215void
217{
218 m_packetSize = size;
219}
220
223{
224 return m_flowId;
225}
226
229{
230 return m_packetId;
231}
232
235{
236 return m_packetSize;
237}
238
239bool
241{
242 return ((m_src == src) && (m_dst == dst));
243}
244
246// Ipv4FlowProbe class implementation //
248
250 Ptr<Ipv4FlowClassifier> classifier,
251 Ptr<Node> node)
252 : FlowProbe(monitor),
253 m_classifier(classifier)
254{
255 NS_LOG_FUNCTION(this << node->GetId());
256
258
259 if (!m_ipv4->TraceConnectWithoutContext(
260 "SendOutgoing",
262 {
263 NS_FATAL_ERROR("trace fail");
264 }
265 if (!m_ipv4->TraceConnectWithoutContext(
266 "UnicastForward",
268 {
269 NS_FATAL_ERROR("trace fail");
270 }
271 if (!m_ipv4->TraceConnectWithoutContext(
272 "LocalDeliver",
274 {
275 NS_FATAL_ERROR("trace fail");
276 }
277
278 if (!m_ipv4->TraceConnectWithoutContext(
279 "Drop",
281 {
282 NS_FATAL_ERROR("trace fail");
283 }
284
285 std::ostringstream qd;
286 qd << "/NodeList/" << node->GetId() << "/$ns3::TrafficControlLayer/RootQueueDiscList/*/Drop";
288 qd.str(),
290
291 // code copied from point-to-point-helper.cc
292 std::ostringstream oss;
293 oss << "/NodeList/" << node->GetId() << "/DeviceList/*/TxQueue/Drop";
295 oss.str(),
297}
298
300{
301}
302
303/* static */
304TypeId
306{
307 static TypeId tid =
308 TypeId("ns3::Ipv4FlowProbe").SetParent<FlowProbe>().SetGroupName("FlowMonitor")
309 // No AddConstructor because this class has no default constructor.
310 ;
311
312 return tid;
313}
314
315void
317{
318 m_ipv4 = nullptr;
319 m_classifier = nullptr;
321}
322
323void
325 Ptr<const Packet> ipPayload,
326 uint32_t interface)
327{
328 FlowId flowId;
329 FlowPacketId packetId;
330
331 if (!m_ipv4->IsUnicast(ipHeader.GetDestination()))
332 {
333 // we are not prepared to handle broadcast yet
334 return;
335 }
336
337 Ipv4FlowProbeTag fTag;
338 bool found = ipPayload->FindFirstMatchingByteTag(fTag);
339 if (found)
340 {
341 return;
342 }
343
344 if (m_classifier->Classify(ipHeader, ipPayload, &flowId, &packetId))
345 {
346 uint32_t size = (ipPayload->GetSize() + ipHeader.GetSerializedSize());
347 NS_LOG_DEBUG("ReportFirstTx (" << this << ", " << flowId << ", " << packetId << ", " << size
348 << "); " << ipHeader << *ipPayload);
349 m_flowMonitor->ReportFirstTx(this, flowId, packetId, size);
350
351 // tag the packet with the flow id and packet id, so that the packet can be identified even
352 // when Ipv4Header is not accessible at some non-IPv4 protocol layer
353 Ipv4FlowProbeTag fTag(flowId,
354 packetId,
355 size,
356 ipHeader.GetSource(),
357 ipHeader.GetDestination());
358 ipPayload->AddByteTag(fTag);
359 }
360}
361
362void
364 Ptr<const Packet> ipPayload,
365 uint32_t interface)
366{
367 Ipv4FlowProbeTag fTag;
368 bool found = ipPayload->FindFirstMatchingByteTag(fTag);
369
370 if (found)
371 {
372 if (!ipHeader.IsLastFragment() || ipHeader.GetFragmentOffset() != 0)
373 {
374 NS_LOG_WARN("Not counting fragmented packets");
375 return;
376 }
377 if (!fTag.IsSrcDstValid(ipHeader.GetSource(), ipHeader.GetDestination()))
378 {
379 NS_LOG_LOGIC("Not reporting encapsulated packet");
380 return;
381 }
382
383 FlowId flowId = fTag.GetFlowId();
384 FlowPacketId packetId = fTag.GetPacketId();
385
386 uint32_t size = (ipPayload->GetSize() + ipHeader.GetSerializedSize());
387 NS_LOG_DEBUG("ReportForwarding (" << this << ", " << flowId << ", " << packetId << ", "
388 << size << ");");
389 m_flowMonitor->ReportForwarding(this, flowId, packetId, size);
390 }
391}
392
393void
395 Ptr<const Packet> ipPayload,
396 uint32_t interface)
397{
398 Ipv4FlowProbeTag fTag;
399 bool found = ipPayload->FindFirstMatchingByteTag(fTag);
400
401 if (found)
402 {
403 if (!fTag.IsSrcDstValid(ipHeader.GetSource(), ipHeader.GetDestination()))
404 {
405 NS_LOG_LOGIC("Not reporting encapsulated packet");
406 return;
407 }
408
409 FlowId flowId = fTag.GetFlowId();
410 FlowPacketId packetId = fTag.GetPacketId();
411
412 uint32_t size = (ipPayload->GetSize() + ipHeader.GetSerializedSize());
413 NS_LOG_DEBUG("ReportLastRx (" << this << ", " << flowId << ", " << packetId << ", " << size
414 << "); " << ipHeader << *ipPayload);
415 m_flowMonitor->ReportLastRx(this, flowId, packetId, size);
416 }
417}
418
419void
421 Ptr<const Packet> ipPayload,
423 Ptr<Ipv4> ipv4,
424 uint32_t ifIndex)
425{
426#if 0
427 switch (reason)
428 {
430 break;
431
434 Ipv4Address addri = m_ipv4->GetAddress (ifIndex);
435 Ipv4Mask maski = m_ipv4->GetNetworkMask (ifIndex);
436 Ipv4Address bcast = addri.GetSubnetDirectedBroadcast (maski);
437 if (ipHeader.GetDestination () == bcast) // we don't want broadcast packets
438 {
439 return;
440 }
441 }
442#endif
443
444 Ipv4FlowProbeTag fTag;
445 bool found = ipPayload->FindFirstMatchingByteTag(fTag);
446
447 if (found)
448 {
449 FlowId flowId = fTag.GetFlowId();
450 FlowPacketId packetId = fTag.GetPacketId();
451
452 uint32_t size = (ipPayload->GetSize() + ipHeader.GetSerializedSize());
453 NS_LOG_DEBUG("Drop (" << this << ", " << flowId << ", " << packetId << ", " << size << ", "
454 << reason << ", destIp=" << ipHeader.GetDestination() << "); "
455 << "HDR: " << ipHeader << " PKT: " << *ipPayload);
456
457 DropReason myReason;
458
459 switch (reason)
460 {
462 myReason = DROP_TTL_EXPIRE;
463 NS_LOG_DEBUG("DROP_TTL_EXPIRE");
464 break;
466 myReason = DROP_NO_ROUTE;
467 NS_LOG_DEBUG("DROP_NO_ROUTE");
468 break;
470 myReason = DROP_BAD_CHECKSUM;
471 NS_LOG_DEBUG("DROP_BAD_CHECKSUM");
472 break;
474 myReason = DROP_INTERFACE_DOWN;
475 NS_LOG_DEBUG("DROP_INTERFACE_DOWN");
476 break;
478 myReason = DROP_ROUTE_ERROR;
479 NS_LOG_DEBUG("DROP_ROUTE_ERROR");
480 break;
482 myReason = DROP_FRAGMENT_TIMEOUT;
483 NS_LOG_DEBUG("DROP_FRAGMENT_TIMEOUT");
484 break;
485
486 default:
487 myReason = DROP_INVALID_REASON;
488 NS_FATAL_ERROR("Unexpected drop reason code " << reason);
489 }
490
491 m_flowMonitor->ReportDrop(this, flowId, packetId, size, myReason);
492 }
493}
494
495void
497{
498 Ipv4FlowProbeTag fTag;
499 bool tagFound = ipPayload->FindFirstMatchingByteTag(fTag);
500
501 if (!tagFound)
502 {
503 return;
504 }
505
506 FlowId flowId = fTag.GetFlowId();
507 FlowPacketId packetId = fTag.GetPacketId();
508 uint32_t size = fTag.GetPacketSize();
509
510 NS_LOG_DEBUG("Drop (" << this << ", " << flowId << ", " << packetId << ", " << size << ", "
511 << DROP_QUEUE << "); ");
512
513 m_flowMonitor->ReportDrop(this, flowId, packetId, size, DROP_QUEUE);
514}
515
516void
518{
519 Ipv4FlowProbeTag fTag;
520 bool tagFound = item->GetPacket()->FindFirstMatchingByteTag(fTag);
521
522 if (!tagFound)
523 {
524 return;
525 }
526
527 FlowId flowId = fTag.GetFlowId();
528 FlowPacketId packetId = fTag.GetPacketId();
529 uint32_t size = fTag.GetPacketSize();
530
531 NS_LOG_DEBUG("Drop (" << this << ", " << flowId << ", " << packetId << ", " << size << ", "
532 << DROP_QUEUE_DISC << "); ");
533
534 m_flowMonitor->ReportDrop(this, flowId, packetId, size, DROP_QUEUE_DISC);
535}
536
537} // 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
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:43
Ipv4Address GetSubnetDirectedBroadcast(const Ipv4Mask &mask) const
Generate subnet-directed broadcast address corresponding to mask.
void Serialize(uint8_t buf[4]) const
Serialize this address to a 4-byte buffer.
static Ipv4Address Deserialize(const uint8_t buf[4])
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.
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
static TypeId GetTypeId()
Register this type.
void DoDispose() override
Destructor implementation.
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
Tag used to allow a fast identification of the packet.
uint32_t GetPacketId() const
Set the packet identifier.
void Deserialize(TagBuffer buf) override
uint32_t m_packetSize
packet size
void Print(std::ostream &os) const override
uint32_t GetPacketSize() const
Get the packet size.
bool IsSrcDstValid(Ipv4Address src, Ipv4Address dst) const
Checks if the addresses stored in tag are matching the arguments.
Ipv4Address m_dst
IP destination.
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
static TypeId GetTypeId()
Get the type ID.
void SetPacketSize(uint32_t packetSize)
Set the packet size.
uint32_t m_packetId
packet identifier
uint32_t GetSerializedSize() const override
void Serialize(TagBuffer buf) const override
void SetFlowId(uint32_t flowId)
Set the flow identifier.
uint32_t m_flowId
flow identifier
uint32_t GetFlowId() const
Set the flow identifier.
void SetPacketId(uint32_t packetId)
Set the packet identifier.
Ipv4Address m_src
IP source.
Packet header for IPv4.
Definition: ipv4-header.h:34
Ipv4Address GetSource() const
Definition: ipv4-header.cc:302
bool IsLastFragment() const
Definition: ipv4-header.cc:217
Ipv4Address GetDestination() const
Definition: ipv4-header.cc:316
uint32_t GetSerializedSize() const override
Definition: ipv4-header.cc:384
uint16_t GetFragmentOffset() const
Definition: ipv4-header.cc:254
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:258
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
void Read(uint8_t *buffer, uint32_t size)
Definition: tag-buffer.cc:183
TAG_BUFFER_INLINE void WriteU32(uint32_t v)
Definition: tag-buffer.h:187
void Write(const uint8_t *buffer, uint32_t size)
Definition: tag-buffer.cc:129
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:160
#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_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#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:261
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:691
static const uint32_t packetSize
Packet size generated at the AP.